Skip to content

All versions since 4.0.0-beta.78

4.0.0-beta.78

Patch Changes

  • #2333 7836b8e Thanks @tim-smart! - Fix Schema.Defect JSON encoding for Error values whose message property is not a string.

  • #2329 35d49a3 Thanks @alvarosevilla95! - Retry Redis scripts after NOSCRIPT and declare the token bucket refill key

  • #2334 4093258 Thanks @tim-smart! - clean up otlp config

4.0.0-beta.79

Patch Changes

  • #2364 b9704dc Thanks @mikearnaldi! - Fix module-level side effects that defeated bundler tree-shaking.

    Bare top-level statements cannot be #__PURE__-annotated by the build, so bundlers must retain them and everything they reference, even in bundles that never use the code:

    • Option: the standalone Object.defineProperty(SomeProto, "valueOrUndefined", ...) statement anchored the whole Option proto chain into every bundle. It is now folded into the SomeProto initializer.
    • Headers: same pattern with Object.defineProperties(Proto, ...), folded into the initializer.
    • Logger: module-level process.stdout.isTTY property reads (potential getters, never droppable) moved inside consolePretty.
    • Utils: when internalCall was unused, its dropped binding left behind a retained initializer tail (standard/forced probe with computed property reads). The selection is now wrapped in a single pure-annotated call.

    A minimal Effect.succeed(123).pipe(Effect.runFork) bundle shrinks by ~1.3% gzipped; bundles that don’t use Option or Headers no longer pay for them.

  • #2339 a207113 Thanks @tim-smart! - Fix EntityManager defect restarts so in-flight requests are replayed instead of being dropped when the old entity scope is interrupted.

  • #2362 5e9b9e2 Thanks @fubhy! - Fix Graph traversal and shortest-path algorithms to traverse undirected edges independently of their stored source/target orientation.

  • #2366 7c128ae Thanks @IMax153! - Fix string seed encoding in Random.withSeed so short, trailing, and astral UTF-8 bytes affect deterministic streams.

  • #2352 0ada457 Thanks @alvarosevilla95! - Fix the Redis RateLimiterStore token-bucket failing with opaque errors under memory pressure: it now writes its keys with a TTL and guards against a missing refill timestamp.

  • #2359 d7cc5a2 Thanks @gcanti! - Fix Struct key renaming and Schema.encodeKeys to support symbol keys, and reject duplicate encoded keys.

  • #2365 aad63be Thanks @gcanti! - Fix Schema encoding so container-level checks are validated against the decoded value instead of the encoded output.

    Disallow adding checks directly to Schema.suspend(...); add the checks to the suspended schema instead.

    Fix StructWithRest so index signatures do not re-parse or overwrite fixed properties.

  • #2342 09809f6 Thanks @gcanti! - Use generic ordered constraints for schema arbitrary derivation.

    Range checks such as isGreaterThan, isLessThan, and isBetween now populate ctx.constraints.ordered instead of type-specific range fields on number, date, or bigint constraints. Custom toArbitrary annotations that read range constraints should migrate to ctx.constraints.ordered.

    This also fixes BigDecimal arbitrary generation by adapting decimal bounds to the generated scale, avoiding invalid fast-check bigint ranges for narrow decimal intervals.

  • #2368 2fddda5 Thanks @IMax153! - Encode HTTP API client path parameters when building request URLs.

  • #2348 5f21768 Thanks @gcanti! - Update Schema arbitrary derivation to use the new filter metadata, candidate generation, optional derivation reports, recursion-aware generation, and the renamed OrderedConstraint<T> model.

    Migration from the previous v4 API:

    • Replace filter annotations from toArbitraryConstraint: constraint to arbitrary: { constraint }. When a filter cannot be described as a constraint, use arbitrary: { candidate } to add a weighted source that is still checked by the filter.
    • Replace bucketed constraints with the flat Schema.Annotations.ToArbitrary.Constraint shape:
      • string.minLength, array.minLength, object property counts, collection sizes -> minLength
      • string.maxLength, array.maxLength, object property counts, collection sizes -> maxLength
      • string.patterns -> patterns
      • number.isInteger -> integer
      • number.noNaN -> noNaN
      • number.noDefaultInfinity -> noInfinity
      • date.noInvalidDate -> valid
      • array.comparator for uniqueness -> unique using Effect equality
      • ordered.min / minExcluded / max / maxExcluded -> ordered.minimum / exclusiveMinimum / maximum / exclusiveMaximum
    • In arbitrary hooks, read context.constraint instead of context.constraints. Replace context.isSuspend with context.recursion; when combining finite and recursive branches, pass context.recursion to fc.oneof with the finite branch first.
    • Generic declaration hooks now receive type parameters as { arbitrary, terminal }. Atomic declarations may still return a bare FastCheck.Arbitrary<T>, but generic declarations should return { arbitrary, terminal } when they can preserve a finite terminal branch.
    • Schema.toArbitrary(schema, { report: true }) now returns { value, report }; without { report: true }, it keeps returning the arbitrary directly. Schema.toArbitraryLazy always returns a lazy arbitrary.
  • #2343 f27003e Thanks @MohanedMashaly! - Add meta-var that shows log level and bash options in command line.

4.0.0-beta.80

Patch Changes

  • #2205 d944330 Thanks @lloydrichards! - add support for merging external events into Prompt.custom render loops via an optional events dequeue and receive handler.

    The prompt races user input against events from the dequeue, allowing background events to trigger re-renders without waiting for a keypress:

    const eventQueue = yield * Queue.make<number>();
    const prompt = Prompt.custom(
    { count: 0 },
    Queue.asDequeue(eventQueue), // <-- provide the event queue as a dequeue to the prompt
    {
    render: (state) => Effect.succeed(`Count: ${state.count}`),
    process: (input, state) =>
    Effect.succeed(
    Match.value(input).pipe(
    // handle user input
    Match.tag("Input", () => Action.Submit({ value: state.count })),
    // handle external events from the queue
    Match.tag("Event", (input) =>
    Action.NextFrame({ state: { count: state.count + input.value } }),
    ),
    Match.exhaustive,
    ),
    ),
    clear: () => Effect.succeed(""),
    },
    );
  • #2369 f48659f Thanks @gcanti! - Round fractional durations symmetrically when normalizing to nanoseconds.

  • #2373 7652aaa Thanks @StarpTech! - Stream.fromReadableStream: swallow the reader.cancel() rejection in the finalizer. Cancelling the reader of an already-errored ReadableStream rejects with the stored error, which turned the typed onError failure into a defect.

  • #2371 98630b7 Thanks @gcanti! - Emit Schema.ObjectKeyword as an object-or-array JSON Schema union.

  • #2376 90ae23c Thanks @fubhy! - Add Graph.successors and Graph.predecessors, deprecate Graph.neighborsDirected, and fix graph algorithm edge cases around reversal, undirected edge queries, shortest-path weight validation, topological sort initials, and strongly connected components.

4.0.0-beta.81

Patch Changes

  • #2387 93cb4f8 Thanks @gcanti! - Config.withDefault now only recovers from missing data for literal/union schemas. Invalid present values now propagate validation errors instead of using the default, closes #2384.

  • #2388 60341d9 Thanks @gcanti! - Config.withDefault no longer recovers from schema filter failures. A filter failure means a present value reached refinement checks, so using the default could hide invalid configuration values.

  • #2389 1105ab5 Thanks @gcanti! - Fix Schema.toTaggedUnion(...).isAnyOf narrowing for custom discriminant keys, closes #2386.

    Previously, the type predicate always extracted union members by _tag, even when toTaggedUnion was created with a different discriminant key. Runtime behavior already used the supplied key, so this aligns the type-level narrowing with the existing runtime behavior.

  • #2270 4500fbf Thanks @IMax153! - Add HTTP API streaming response support

4.0.0-beta.82

Patch Changes

  • #2391 193690b Thanks @IMax153! - Fix HttpApiEndpoint endpoint error inference when success schemas include streams.

4.0.0-beta.83

Patch Changes

  • #2394 1f2e8ce Thanks @IMax153! - Fix published HttpApi declaration files by exporting schema metadata types referenced by public declarations.

4.0.0-beta.84

Patch Changes

  • #2420 87f52ba Thanks @tim-smart! - Add Effect.transposeOption for converting an Option<Effect<A, E, R>> into an Effect<Option<A>, E, R>.

  • #2374 b8ee07f Thanks @gcanti! - Import unconstrained JSON Schema nodes as Schema.Json instead of Schema.Unknown.

  • #2407 867c0d7 Thanks @gcanti! - Normalize error behavior for Schema and SchemaParser boundary APIs.

    SchemaError now extends Data.TaggedError, so it is also a native Error. SchemaParser Promise APIs now reject an Error whose cause is the SchemaIssue.Issue for schema failures.

    Schema and SchemaParser Effect and Exit adapters now preserve full causes while mapping schema issue failures to their public error type. The is, asserts, Promise, Sync, Result, Option, make, and makeOption adapters now distinguish schema issues from non-schema causes. Schema-only failures are converted to the adapter’s normal representation (false, rejected or thrown schema error, Result.fail, or None), while non-schema causes throw or reject with an Error whose cause is the underlying Cause.

  • #2409 b93bc6c Thanks @tim-smart! - Fix Stream.runForEachWhile so it continues across chunk boundaries while the predicate returns true and stops when the predicate returns false.

  • #2424 57d387f Thanks @tim-smart! - Fix cluster workflow activity defect hydration

  • #2403 bacca41 Thanks @lloydrichards! - align ProcessInput.Input runtime field name with type definition on Prompt.custom

  • #2423 0f8ac79 Thanks @tim-smart! - RpcGroup.toHandlers is definition first

  • #2383 25b4482 Thanks @gcanti! - Fix config path composition and directory-backed lookup behavior.

    ConfigProvider.orElse now keeps each side’s own nested and mapInput behavior. Applying nested or mapInput to a combined provider now applies the same transformation to both sides.

    ConfigProvider path transformations now compose as a single path function. This makes nested and mapInput behave consistently with normal function composition.

    Config.nested now tracks the logical config path in Config itself instead of wrapping the provider. This keeps lookup paths and schema error paths aligned. The low-level Config.make constructor is no longer exported; use config constructors and combinators, or implement custom lookup behavior with ConfigProvider.make.

    ConfigProvider.fromDir now returns undefined when neither a file nor a directory exists at the requested path, so orElse can fall back instead of failing with SourceError.

  • #2415 9cf3a25 Thanks @gcanti! - Fix Effect.try thunk usage and Effect.tryPromise mapper and signal handling defects.

    Effect.try now supports passing a thunk directly, matching Effect.tryPromise. Thrown values from direct-thunk usage are mapped to Cause.UnknownError.

    When a promise handled by Effect.tryPromise rejected and the custom catch mapper threw while mapping that rejection, the effect could remain pending and produce an unhandled rejection. The mapper is now guarded consistently with the synchronous throw path, so a thrown mapper error becomes an Effect defect. The JSDoc for Effect.try and Effect.tryPromise was also corrected.

    Effect.tryPromise now also only creates an AbortController when the wrapped thunk declares an AbortSignal parameter.

  • #2417 8def767 Thanks @tim-smart! - deduplicate SqlResolver.findById requests

4.0.0-beta.85

Patch Changes

  • #2436 328d97c Thanks @MohanedMashaly! - change default operation in redis from LPUSH TO RPUSH

  • #2431 8441836 Thanks @gcanti! - Derive template literal arbitraries from encoded parts, closes #2414.

  • #2439 074e436 Thanks @gcanti! - Allow schema class .extend to accept a Struct and preserve checks from the extension schema, closes #2419.

  • #2444 c1dfd60 Thanks @bweis! - Avoid throwing when Error.stackTraceLimit is non-writable (frozen intrinsics / SES / deterministic sandboxes such as Temporal).

    Effect manipulates Error.stackTraceLimit in several internal spots to capture short or empty stack traces cheaply. In hardened environments where Error is frozen and stackTraceLimit is read-only, assigning to it throws, which broke Effect entirely. Stack-trace-limit manipulation is now best-effort and silently no-ops when the property cannot be modified, mirroring Node’s own internal guard. Behavior in normal (writable) environments is unchanged.

  • #2425 2ba316b Thanks @tim-smart! - Add Random.choice for selecting a random element from an iterable.

  • #2434 7ce7344 Thanks @gcanti! - Use semantic matching for TemplateLiteral parsing and index signature keys

    Replace regex-based TemplateLiteral parsing with backtracking segmentation over template literal parts, applying part checks during matching.

    Use schema membership when selecting Record index signature keys, including checked string, number, symbol, and TemplateLiteral parameters. Tighten valid index signature parameters on both type and encoded sides, and preserve key parameter semantics in codec transformations.

4.0.0-beta.86

Patch Changes

  • #2462 0b5795a Thanks @tim-smart! - Add Statement.valuesUnprepared for returning unprepared SQL statement rows as arrays.

  • #2455 3e3a859 Thanks @fubhy! - Fix Cron.next skipping earlier matching days when the upcoming day-of-month does not exist in the current month.

  • #2454 7dbec24 Thanks @StarpTech! - Exclude response metadata from HTTP server span failures after response headers have been sent.

  • #2449 d8c00a1 Thanks @gcanti! - Fix Schema handling of encoded-side checks for container ASTs.

    Checks added after flip are now preserved as encodingChecks across Declaration, Arrays, Objects, and Union, even when rebuilding the AST does not change child nodes. toType now projects those checks consistently, and parsing applies encoded-side checks to the local encoded value when an encoding chain is present without allowing encoded-side parseOptions annotations to affect the current parser side.

  • #2446 85b6317 Thanks @IMax153! - Allow schemas provided to CLI flags / arguments to utilize the environment required by the CLI

  • #2452 6d0fda0 Thanks @gcanti! - Remove the keepDeclarations option from Schema.toCodecStringTree.

  • #2461 108a933 Thanks @tim-smart! - Fail RpcClient HTTP requests with a defect when the response stream closes before the request receives a terminal response.

  • #2442 7e1f455 Thanks @gcanti! - Improve Schema type-level performance by lazily computing schema views, specializing common struct projections, and using lighter schema constraints at API boundaries that do not need the full schema protocol.

    This also adds the Schema type-performance benchmark suite, introduces Schema.toCodecArrayFromSingle, preserves canonical StringTree array codecs, renames the arbitrary-generation annotation constraint for clarity, and updates affected codec, parser, channel, SQL, HTTP API, persistence, RPC, AI, OpenAPI, and workflow typings to match the refined Schema surface.

  • #2464 46b3e79 Thanks @tim-smart! - do not use performance.timeOrigin and calculate origins lazily

4.0.0-beta.87

Patch Changes

  • #2468 5a0c1a4 Thanks @gcanti! - Expose the original input schema on Schema.toType, Schema.toEncoded, Schema.toCodecJson, and Schema.toCodecStringTree results via the schema property. This aligns these schema wrappers with other wrappers that retain their source schema for type-level and runtime introspection.

  • #2466 1eea2ea Thanks @gcanti! - Use URL.canParse to validate URL string schema decoding before constructing a URL. This avoids relying on thrown exceptions for routine validation while preserving the same invalid URL issue and successful decode output.

4.0.0-beta.88

Patch Changes

  • #2472 911f1b8 Thanks @tim-smart! - Add adaptive consume and feedback operations to the unstable persistent RateLimiterStore API, including in-memory and Redis-backed bounded cooldown, learning, learned pacing, and expiry behavior for 429 Retry-After feedback.

  • #2457 8beeeea Thanks @P0lip! - Localize missing rpc method errors to the provided request id

  • #2428 c306fcf Thanks @MrGovindan! - Add isOpen to Latch to allow querying the latch’s open state

4.0.0-beta.89

Patch Changes

  • #2475 b7d46ab Thanks @tim-smart! - Update Schema.Void to model ignored void return values.

    Runtime parsing now accepts any present value and discards it as undefined. This matches TypeScript void return values, where callers do not observe the returned value. Use Schema.Undefined when the input must be exactly undefined.

  • #2479 7777e15 Thanks @tim-smart! - Add custom error callbacks to Effect.fromOption.

  • #2480 5376197 Thanks @tim-smart! - render causes in OtlpTracer exception events

4.0.0-beta.90

Patch Changes

  • #2483 d237fdf Thanks @tim-smart! - Fix Config.schema so missing array values are treated as missing data, allowing Config.withDefault to apply.

4.0.0-beta.91 Latest

Patch Changes

  • #2498 b135b25 Thanks @gcanti! - Fix Schedule.andThenResult to emit self outputs as Failure and other outputs as Success, closes #2497.

  • #2488 aaa21a3 Thanks @fubhy! - Fix String.camelCase and String.pascalCase handling of numeric word segments, and add String.configCase for configuration key casing.

  • #2485 3475ee6 Thanks @tim-smart! - fix RequestResolver interruption