Skip to content

effect@4.0.0-beta.103

Pre-release
Pre-release

Choose a tag to compare

@effect-bot effect-bot released this 04 Aug 00:09
dff2544

Minor Changes

  • #6793 b2f95a9 Thanks @tim-smart! - Add Semaphore.takeIfAvailable for non-blocking manual permit acquisition.

  • #6693 aeba0c8 Thanks @lloydrichards! - Expose object-shaped Toolkit success schemas as MCP tool output schemas.

  • #6807 d0f1a22 Thanks @alecbuffi! - Separate wall-clock timestamps from monotonic elapsed time.

    Clock.Clock now requires monotonicTimeNanosUnsafe() and monotonicTimeNanos for measuring elapsed time. Custom Clock implementations must provide both members. The live clock's currentTimeNanos now re-anchors its high-resolution Unix wall-clock timestamp when it drifts from Date.now(), while Effect.timed, duration metric tracking, and Sink.withDuration use monotonic time so wall-clock corrections do not distort elapsed durations.

Patch Changes

  • #6697 e56cd8f Thanks @schickling-assistant! - Add a configurable filter for HTTP client request and response header span attributes.

  • #6883 f77c120 Thanks @gcanti! - Add support for converting JSON Schema documents to Draft-04, preserve literal $ref values, $ref sibling constraints, not, readOnly, and writeOnly in Draft-07 conversions, correct the Draft-07 meta-schema URI, and prevent OpenAPI component-key collisions during conversion.

  • #6564 04fd44a Thanks @AVtheking! - Run shared-table SQL persistence expiration cleanup in indexed, bounded background batches.

  • #6911 b74333d Thanks @fubhy! - Update existing HashRing nodes when adding a value with the same primary key.

  • #6909 1c40b28 Thanks @AlfGoto! - Add DateTime.toEpochSeconds and DateTime.fromEpochSeconds for converting date-time values to and from Unix epoch seconds.

  • #6693 aeba0c8 Thanks @lloydrichards! - MCP tool handler defects now return a stable internal error without exposing defect details.

  • #6874 b3901d2 Thanks @fubhy! - Fix Equal.equals and Hash.hash to handle invalid dates and DataView values without throwing.

  • #6869 4a0984a Thanks @fubhy! - Fix SQL-backed Persistence getMany to preserve duplicate key positions.

  • #6868 fffd88b Thanks @fubhy! - Ensure clearing an empty Redis-backed persistence store succeeds.

  • #6903 f3f6c1e Thanks @fubhy! - Preserve equals signs in inline CLI option values after the first separator.

  • #6876 ef07642 Thanks @fubhy! - Fix Sink.reduceWhileArray applying its reducer more than once per input array.

  • #6802 f1bc827 Thanks @tim-smart! - Cap incomplete RPC frames buffered by the NDJSON and MessagePack streaming decoders, and close socket transports when the limit is exceeded.

  • #6693 aeba0c8 Thanks @lloydrichards! - RPC servers now suppress responses after a client cancels an in-flight request.

  • #6723 081f4d8 Thanks @tim-smart! - add platform literal to HttpPlatform

  • #6788 5287b24 Thanks @gcanti! - Refine the ConfigProvider interface so lookup absence uses undefined and
    path transformation is provider behavior.

    ConfigProvider.load and the lookup function accepted by
    ConfigProvider.make now return Node | undefined. Use undefined when a path
    does not exist and return the Node directly when it does.

    ConfigProvider now exposes mapInput as a capability. The exported
    ConfigProvider.mapInput combinator delegates to it, preserving transformation
    order and composition through orElse without requiring provider
    representation state.

  • #6863 13d31cf Thanks @fubhy! - Decode percent-encoded OTLP environment header values.

  • #6781 acee269 Thanks @gcanti! - Deduplicate equivalent fallback definitions when compiling JSON Schema, and reconstruct only definitions reachable from multi-document roots.

    Remove SchemaMultiDocument and fromSchemaMultiDocument; multi-document import and revival now return the ordered root schemas directly.

    Stop the OpenAPI generator from emitting component schemas that are not reachable from a generated root.

  • #6717 31170c1 Thanks @IMax153! - Document that CommandOptions.extendEnv defaults to false and that providing env without enabling it replaces the inherited child environment.

  • #6657 205ebc7 Thanks @tim-smart! - Use cancellable microtasks when dispatching yielded work from synchronous Effect runs.

  • #6661 ed0ebf8 Thanks @tim-smart! - Fix hydrated atoms with Atom.withReactivity to refresh after reactive mutations.

  • #6665 a3fd084 Thanks @tim-smart! - Fix HttpRouter.toWebHandler context inference for services provided by the application layer.

  • #6681 ee29ddf Thanks @tim-smart! - Add Web Stream interoperability for Channel and Sink, plus byte limiting and ArrayBuffer collection for Stream.

  • #6730 6086309 Thanks @tim-smart! - Support replaying initial WebSocket messages and normalize ArrayBuffer frames to Uint8Array.

  • #6763 4a57af2 Thanks @tim-smart! - Validate cookie names, domains, and paths before constructing or serializing cookies.

  • #6771 660875b Thanks @tim-smart! - Strip credential headers on cross-origin HTTP redirects and align redirected request methods with fetch.

  • #6777 8e7c706 Thanks @tim-smart! - Bound pending SSE decoder state with a configurable maximum event size.

  • #6772 5f63adb Thanks @tim-smart! - Reject empty, . and .. keys in file-backed key-value stores.

  • #6773 053bc42 Thanks @tim-smart! - Escape terminal control characters in unstable CLI error output.

  • #6898 c0a1534 Thanks @tim-smart! - Add HTTP response compression support. Node.js, Bun, and Deno use asynchronous
    node:zlib one-shot compression for byte-array bodies, preserving an exact
    Content-Length; stream and raw bodies remain streaming transforms.

  • #6859 f1e3a37 Thanks @fubhy! - Fix String.snakeToCamel and String.snakeToPascal to return an empty string for empty input.

  • #6746 cedb01a Thanks @fubhy! - Prefer explicit OTLP resource configuration over environment configuration.

  • #6677 1747440 Thanks @tim-smart! - Expose runtime schemas for AI prompt parts and message-specific part unions.

  • #6693 aeba0c8 Thanks @lloydrichards! - MCP servers now advertise logging and honor each client's selected log level when sending log notifications.

  • #6693 aeba0c8 Thanks @lloydrichards! - Preserve MCP sampling request preferences and response content.

  • #6878 b4f1ee2 Thanks @fubhy! - Fix Array index operations handling NaN and fractional indexes.

  • #6751 a4757f1 Thanks @tim-smart! - Fix Atom dependency tracking and re-entrant invalidation during batch rebuilds.

  • #6870 cd122b9 Thanks @fubhy! - Ensure BigInt.gcd and BigInt.lcm return non-negative values and handle zero operands in BigInt.lcm.

  • #6844 5de588b Thanks @fubhy! - Prevent an interrupted cache lookup from removing a newer value written with Cache.set.

  • #6879 3895b9c Thanks @fubhy! - Preserve failure annotations when mapping errors with Cause.map.

  • #6820 89ce5f3 Thanks @fubhy! - Fix ChannelSchema.decodeUnknown to accept unknown input chunks while keeping ChannelSchema.decode typed to the schema's encoded input.

  • #6899 985de09 Thanks @fubhy! - Ensure Chunk.take and Chunk.drop produce valid chunks for fractional counts.

  • #6579 9800e3a Thanks @marbemac! - Scope cluster reply serialization failures and peer-delivered defects to their own request instead of the whole runner connection

  • #6800 4dc35f6 Thanks @tim-smart! - Fix persisted cluster stream recovery when SQL drivers return a null reply kind.

  • #6814 e8eb62b Thanks @gcanti! - Preserve provider input evidence when Config.orElse recovers a configuration failure.

  • #6873 ecd9993 Thanks @fubhy! - Propagate the FiberSet.runtime interruption option when registering managed fibers.

  • #6872 5ab9c08 Thanks @fubhy! - Fix Formatter.format handling of shared references and ensure Formatter.formatJson always returns valid JSON.

  • #6867 f5cf965 Thanks @fubhy! - Remove stale content-length headers when replacing an HTTP client request body with one of unknown length.

  • #6924 a94cbed Thanks @fubhy! - Ignore uniqueItems when set to false while importing JSON Schema documents.

  • #6871 9160ad7 Thanks @fubhy! - Fix LayerMap preload options so configured entries are acquired during construction.

  • #6693 aeba0c8 Thanks @lloydrichards! - MCP completion handlers now receive resolved argument context, and completion responses are limited to one hundred values.

  • #6693 aeba0c8 Thanks @lloydrichards! - MCP servers now return protocol errors for invalid tool, prompt, completion, resource, and logging requests.

  • #6901 52494be Thanks @fubhy! - Prevent distinct metric attribute sets from sharing registry state.

  • #6822 5441c8e Thanks @fubhy! - Fix Metric.isMetric to recognize metrics using their current runtime brand.

  • #6821 c9b56ab Thanks @fubhy! - Fix Metric.linearBoundaries to space boundaries by the configured width.

  • #6847 8ef7257 Thanks @fubhy! - Fix MutableList.prepend on empty lists and handle non-positive toArrayN bounds.

  • #6865 1519406 Thanks @fubhy! - Fix OtlpResource to decode percent-encoded environment attributes and preserve bigint precision.

  • #6805 9716990 Thanks @tim-smart! - Prevent replay-enabled PubSubs from retaining values beyond each subscription's replay window.

  • #6711 733f75b Thanks @andrskr! - Preserve serialization and retention metadata on reactive AtomRpc and AtomHttpApi queries.

  • #6855 48155c8 Thanks @fubhy! - Fix Schedule.during to recur until the configured duration has elapsed.

  • #6712 951d06b Thanks @gcanti! - Make Schema.isPattern deterministic for regular expressions with global or sticky flags.

  • #6782 d767b65 Thanks @gcanti! - SchemaRepresentation: generate references from encoded AST identity, suffix colliding identifiers instead of throwing, and preserve sharing across property-key context. This avoids false-positive duplicate identifier errors while keeping referentially distinct schemas addressable; generated fallback definitions now use the clearer Encoded suffix.

  • #6704 5d52d9d Thanks @gcanti! - Fix Union candidate selection for recovering middleware and suspended members.

  • #6848 f4151e1 Thanks @fubhy! - Keep the current ScopedRef resource alive when acquiring its replacement fails.

  • #6910 e02fbb6 Thanks @z4p5a9! - Fix Semaphore.withPermits leaking permits when interrupted between acquiring them and installing their release.

  • #6877 724ce09 Thanks @tim-smart! - Fix Stream.aggregateWithin and Stream.groupedWithin retaining fiber continuations on every schedule tick while upstream is idle.

  • #6889 dbe91f6 Thanks @tim-smart! - Fix Stream.withExecutionPlan retry limits resetting after partial stream emissions.

  • #6823 4c008d2 Thanks @fubhy! - Fix data-first dispatch for Stream.mapAccumArrayEffect.

  • #6900 b650832 Thanks @fubhy! - Ensure Stream.range emits the full range when the chunk size is zero.

  • #6849 b46c92f Thanks @fubhy! - Fix SubscriptionRef.getAndUpdateSome to return the current value when no update is selected.

  • #6808 5335797 Thanks @fubhy! - Fix SubscriptionRef.getAndUpdateEffect to execute the effectful update.

  • #6862 4b3460d Thanks @fubhy! - Fix Trie.longestPrefixOf returning a valued sibling that does not match the input key.

  • #6856 6301fd7 Thanks @fubhy! - Fix Trie to preserve entries whose value is undefined.

  • #6850 aebc5c6 Thanks @fubhy! - Fix TxPubSub.publishAll dropping values from one-shot iterables when a transaction retries.

  • #6851 52b2d7b Thanks @fubhy! - Ensure TxQueue.poll and TxQueue.clear complete a closing queue after draining its buffered items.

  • #6853 eec5744 Thanks @fubhy! - Fix TxQueue.offerAll to preserve one-shot iterables across transaction retries and repeated runs.

  • #6783 24e0e93 Thanks @tim-smart! - Propagate trace context through persisted cluster workflow requests.

  • #6693 aeba0c8 Thanks @lloydrichards! - MCP servers now return standard JSON-RPC errors for malformed requests, unknown methods, and invalid parameters.

  • #6693 aeba0c8 Thanks @lloydrichards! - MCP servers now enforce revision-specific JSON-RPC batch and protocol-version header requirements.

  • #6707 1a7ce81 Thanks @gcanti! - Mark Schema.UnknownFromJsonString as internal and remove its type-level interface. Use Schema.fromJsonString(Schema.Unknown) instead. Add reviver, callback or array replacer, and space options to Schema.fromJsonString, and make SchemaTransformation.fromJsonString a configurable factory.

  • #6828 48f22a7 Thanks @tim-smart! - Use layered storage for Context, making Context.add O(1) and eliminating per-request service map clones in the HTTP servers. Docgen now omits @internal option properties from generated signatures.

  • #6780 c96b7f6 Thanks @tim-smart! - Include typed tool output schemas in MCP tools/list responses.

  • #6733 6d2a942 Thanks @gcanti! - Avoid validating Schema.Class fields twice when decoding.

  • #6659 cc27b19 Thanks @tim-smart! - Preserve prototype accessors when code is compiled with loose object spread transforms.

  • #6912 8f9499f Thanks @gcanti! - Remove actual fields from every SchemaIssue variant, together with
    SchemaIssue.getActual, SchemaIssue.redact, and Schema.redact. Built-in
    formatters now use static messages that do not interpolate rejected input,
    while paths, AST metadata, union successes, and user-provided messages and
    annotations are preserved unchanged.

    Runtime performance was measured across the 16 Effect fixtures in the
    schema-benchmarks suite. These are the scenarios used for the cross-library
    comparison with Valibot and Zod. The paired HEAD-versus-main run classified 3
    fixtures as improvements, 0 as regressions, and 13 as inconclusive. Negative
    changes are faster. Absolute library values are medians from the same
    cross-library run; means that the corresponding adapter does not expose
    that scenario.

    Scenario Effect (ns/op) Valibot (ns/op) Zod (ns/op) HEAD vs main Classification
    initialization-schema 108191.30 30549.81 212715.66 -0.92% inconclusive
    initialization-decoder 109796.34 +1.98% inconclusive
    validation-valid 5221.80 5070.81 +2.06% inconclusive
    validation-invalid 1279.77 234.92 +0.59% inconclusive
    parsing-all-valid 5144.58 5192.19 7176.19 -3.79% inconclusive
    parsing-all-invalid 7594.49 15236.82 37780.35 -5.94% improvement
    parsing-first-valid 5188.33 5135.75 -1.49% inconclusive
    parsing-first-invalid 1330.82 243.64 +1.01% inconclusive
    standard-all-valid 5722.01 5200.05 3801.26 -1.78% inconclusive
    standard-all-invalid 12024.65 15528.50 30982.17 -7.78% improvement
    standard-first-valid 5655.33 +3.84% inconclusive
    standard-first-invalid 2001.69 -4.56% inconclusive
    codec-typed-encode 342.59 39.29 -7.62% inconclusive
    codec-typed-decode 418.78 50.14 -10.89% improvement
    codec-unknown-encode 328.38 -5.55% inconclusive
    codec-unknown-decode 347.35 -5.25% inconclusive
  • #6692 3eeea73 Thanks @schickling-assistant! - Fix unstable CLI subcommands dropping operands after the -- end-of-options terminator.

  • #6625 0a532e5 Thanks @lloydrichards! - Add adapter-valued MCP server protocol declarations, route requests through the selected protocol before schema decoding, and add built-in support for MCP 2025-06-18.

  • #6864 f398149 Thanks @fubhy! - Honor HTTP-date Retry-After values when retrying OTLP exports.

  • #6693 aeba0c8 Thanks @lloydrichards! - MCP Streamable HTTP servers now validate content negotiation, session lifecycle, negotiated protocol versions, and browser Origins before dispatching requests.

  • #6824 ace903e Thanks @tim-smart! - Skip HTTP server span attribute collection when the span is not sampled.

  • #6814 e8eb62b Thanks @gcanti! - Refine Config loading and absence semantics. Config.schema now derives a provider loading policy from the encoded StringTree schema, materializes mixed-shape union members independently, and leaves separated scalar parsing to Config.Array and Config.Record. Schemas whose canonical StringTree encoding remains opaque, such as Schema.Any, Schema.Unknown, or Schema.Json, are rejected when the config is constructed; use a concrete shape or Schema.fromJsonString(Schema.Json) for scalar JSON. Missing or unavailable representations are decoded as undefined before Config.withDefault and Config.option decide absence. Partially supplied Config.all groups are rejected, successful values such as undefined and explicitly present empty structures are preserved, and the internal path prefix is removed from the public Config.parse signature.

  • #6693 aeba0c8 Thanks @lloydrichards! - MCP servers now refresh roots after capable clients report that their root list changed.

  • #6828 48f22a7 Thanks @tim-smart! - Remove Context.mutate and Context.getReferenceUnsafe. Context updates now use overlays, and Context.get resolves reference defaults.

  • #6649 d48506d Thanks @gcanti! - Remove the keyValueCombiner option from Schema.Record and the corresponding
    SchemaAST.KeyValueCombiner and SchemaAST.IndexSignature.merge APIs.
    For transformed key collisions, sequential parsing keeps the later selected
    value, while concurrent parsing keeps the value applied last in completion
    order.

  • #6693 aeba0c8 Thanks @lloydrichards! - MCP servers now support session-scoped resource subscriptions on transports that can deliver server notifications and filter resource updates by each client's subscribed URIs.

  • #6649 d48506d Thanks @gcanti! - Preserve untouched Result branches by identity in Result.map and
    Result.mapError.

  • #6649 d48506d Thanks @gcanti! - Improve Schema parsing, schema construction and adapter runtime performance
    while preserving current parsing behavior.

    Runtime performance

    The effect@beta, Valibot and Zod timing cases from
    open-circle/schema-benchmarks
    were reproduced as a dedicated runtimeperf suite. The table includes every
    case exposed by each upstream adapter; means that the adapter does not
    provide that benchmark.

    Effect main (45e781088) and the branch based on d775bf4b2 were compared
    with five paired processes per case, 150 ms measurement time and 50 ms warmup.
    The two initially inconclusive Effect cases were repeated with 15 paired
    processes, 500 ms measurement time and 150 ms warmup. Valibot and Zod values
    use five processes, 300 ms measurement time and 100 ms warmup. Environment:
    Node v24.12.0, macOS arm64, Apple M3.

    Zod parsing uses safeParse with { jitless: true }; its Standard Schema and
    codec cases use the corresponding native adapter APIs. All values are median
    microseconds per operation (µs/op), lower is better. Cross-library values are
    diagnostic because they are independent rather than paired measurements.

    Scenario Effect main Effect branch Valibot Zod 4 Delta 95% CI Classification
    Initialize schema 137.28 118.23 40.24 318.56 -12.69% -21.02% to -5.35% improvement
    Initialize schema and decoder 144.81 130.50 -10.88% -14.22% to -3.29% improvement
    Validate valid product 8.478 5.415 5.63 -35.18% -41.65% to -32.83% improvement
    Validate invalid product 1.516 1.348 0.2431 -11.59% -13.81% to -6.31% improvement
    Parse valid product, all errors 8.360 5.366 5.22 7.16 -36.28% -54.41% to -31.67% improvement
    Parse invalid product, all errors 11.302 9.100 15.70 41.58 -19.42% -21.32% to -13.12% improvement
    Parse valid product, first error 8.201 5.294 5.37 -35.44% -37.75% to -34.59% improvement
    Parse invalid product, first error 1.510 1.352 0.2572 -10.51% -12.52% to -9.53% improvement
    Standard Schema valid, all errors 9.284 5.935 5.35 3.83 -35.96% -53.29% to -33.49% improvement
    Standard Schema invalid, all errors 16.718 15.203 16.51 32.85 -11.31% -13.97% to -7.65% improvement
    Standard Schema valid, first error 8.889 5.843 -34.17% -35.13% to -33.94% improvement
    Standard Schema invalid, first error 2.435 2.244 -8.44% -12.76% to -4.82% improvement
    Typed codec encode 0.4692 0.3420 0.0405 -27.60% -32.35% to -22.50% improvement
    Typed codec decode 0.5191 0.3762 0.0463 -27.19% -34.75% to -22.71% improvement
    Unknown codec encode 0.4910 0.3472 -28.58% -30.42% to -27.59% improvement
    Unknown codec decode 0.5061 0.3637 -29.26% -29.82% to -21.70% improvement

    Overall Effect classification: 16 improvements and no regressions.

  • #6896 52262be Thanks @tim-smart! - Bind event-log read and write requests to the identities authenticated on their RPC connection.

  • #6735 1284aa1 Thanks @gcanti! - Fix three issues in the public Optic API:

    • Composed Iso and Prism setters no longer try to read a source value before writing.
    • Calling notUndefined on an Optional now returns an Optional, because writing can still fail.
    • The internal node property is no longer exposed by public optic types.
  • #6701 9867b9f Thanks @fubhy! - Removed explicit ./index entrypoints

  • #6875 979ce39 Thanks @fubhy! - Fix protobuf serialization of negative signed integers to use ten-byte two's-complement varints.

  • #6696 b6d3e67 Thanks @tim-smart! - remove file descriptor type

  • #6860 adf6c6c Thanks @fubhy! - Honor custom split and strip regular expressions passed to String.noCase.

  • #6866 7314d60 Thanks @fubhy! - Fix partial file-backed HTTP bodies to report the selected byte range as their content length.

  • #6693 aeba0c8 Thanks @lloydrichards! - MCP HTTP servers now reject requests sent before initialization with the required lifecycle response.

  • #6759 1acbd8b Thanks @tim-smart! - Harden JSON-RPC wire message classification against inherited properties.

  • #6705 7bde6cc Thanks @tylergibbs1! - Restore the recursive option for FileSystem.watch, with non-recursive watching as the default.

  • #6798 a959a8b Thanks @tim-smart! - Namespace PostgreSQL advisory shard locks by the SqlRunnerStorage table prefix.

    This changes the advisory-lock protocol. PostgreSQL clusters using advisory locks require a full cluster stop before upgrading; a rolling deploy is unsafe because old and new runners use different lock keys and can both acquire the same shard.