github Effect-TS/effect effect@4.0.0-beta.104

Minor Changes

Patch Changes

  • #6934 1001bcc Thanks @tim-smart! - httpapi: add typed response headers across handlers, generated clients (including HttpApiTest), streaming responses, and OpenAPI with HttpApiSchema.WithHeaders. Add HttpApiSchema.encodeToWithHeaders for folding response headers into domain types such as error classes. Explicit content-type and content-length values applied with HttpServerResponse.setHeader or setHeaders now override body-derived values.

  • #7044 993ba60 Thanks @fubhy! - Commit SQL event journal entries only after their write callback succeeds.

  • #6957 67faacd Thanks @fubhy! - Select Bash completions for the active positional argument.

  • #6941 b78acdf Thanks @fubhy! - Generate even and odd safe integers in Crypto random APIs.

  • #6965 fbb9ce5 Thanks @fubhy! - Correct the runtime tag spelling for CliError.UnknownSubcommand.

  • #6963 722ea48 Thanks @fubhy! - Exclude disabled choices from multi-select prompt selection and submission.

  • #7001 3058fd5 Thanks @fubhy! - Keep ordered SQL resolver results aligned when batched request encoding fails.

  • #6937 62d0575 Thanks @fubhy! - Fix the encoded output type of TestSchema.Encoding.encodeUnknownEffect.

  • #7014 99dd6b5 Thanks @tim-smart! - Add lightweight INI, YAML, and TOML parsers under effect/unstable/encoding and remove their runtime dependencies.

  • #7053 7963ce1 Thanks @fubhy! - Fix arbitrary generation for tuples with multiple optional elements.

  • #7047 af14e75 Thanks @fubhy! - Fix Tuple.pick return types to preserve the requested index order and duplicate indices.

  • #7066 24e22d2 Thanks @fubhy! - Close ResourceMap acquisition scopes when a lookup fails.

  • #7036 647d14e Thanks @fubhy! - Fix scoped reentrant lock finalizers releasing under the wrong fiber owner.

  • #6983 1434eec Thanks @fubhy! - Apply byte range and chunk size options to default Web file responses.

  • #7071 a5278b1 Thanks @fubhy! - Fix MCP sampling metadata optionality and validate it as an object.

  • #6946 6af04a5 Thanks @fubhy! - Defer memoized Layer state installation until Effect execution.

  • #6943 cb6c837 Thanks @fubhy! - Reject zero execution attempts in ExecutionPlan steps.

  • #7026 d44cead Thanks @tim-smart! - Add execution-plan lifecycle events via an optional onEvent handler on Effect.withExecutionPlan and Stream.withExecutionPlan.

    The handler receives an ExecutionPlan.Event, a tagged union of AttemptStart, AttemptSuccess, and AttemptFailure, allowing attempt outcomes to be observed from outside the effect for logging and metrics:

    import { Effect } from "effect"
    
    Effect.withExecutionPlan(program, plan, {
      onEvent: (event) => Effect.log("execution plan event", event)
    })

    Every AttemptStart is followed by exactly one terminal event. AttemptFailure carries the full failure Cause, so defects and interruption are reported as well as expected errors, and terminal events run like finalizers so they are emitted even when the attempt is interrupted. Event numbering matches ExecutionPlan.CurrentMetadata: attempt is cumulative across steps, while stepAttempt is 1-based within the current step.

  • #7077 88c7632 Thanks @tim-smart! - Rename Schedule.andThen and Schedule.andThenResult to Schedule.concat and Schedule.concatResult.

  • #6975 abcbb2a Thanks @fubhy! - Encode SSE events with empty data as dispatchable events.

  • #7037 8f63cce Thanks @fubhy! - Preserve OTLP metric delta checkpoints when an export fails.

  • #7057 d56dfcf Thanks @fubhy! - Fix the error type exposed by the curried Sink.catch overload.

  • #6947 a98cda9 Thanks @fubhy! - Check symbol-keyed properties in Match object patterns.

  • #6956 6704bb8 Thanks @fubhy! - Emit valid CSI sequences from the unstable CLI cursorTo helper.

  • #7008 6143de2 Thanks @tim-smart! - Prevent Bash completions from treating flag values as subcommands.

  • #7032 936b135 Thanks @marbemac! - Fix a @effect/cluster shutdown deadlock on single-runner topologies (e.g. single-node deployments and TestRunner), where Sharding.sendOutgoing retried EntityNotAssignedToRunner forever during teardown.

  • #6940 1bbae84 Thanks @fubhy! - Omit services removed by Context.addOrOmit from the returned context type.

  • #7065 d795ee7 Thanks @tim-smart! - Fix DevTools span requests to preserve their state when queued for sending.

  • #7016 0a82d88 Thanks @brandon-julio-t! - Normalize cluster durable clock wake-up timestamps to whole milliseconds.

  • #6945 9215bc5 Thanks @fubhy! - Preserve integral precision when parsing decimal nano and micro duration inputs

  • #7050 a1b5df2 Thanks @fubhy! - Include schedule errors in the error channel of Effect.schedule and Effect.scheduleFrom.

  • #7062 92a9ac5 Thanks @fubhy! - Fix the inspectable JSON identity of FiberSet.

  • #6959 6bde7f2 Thanks @fubhy! - Match Fish completions against the full nested command path.

  • #6951 a712131 Thanks @fubhy! - Use the supplied hash for HashMap.modifyHash insertions, updates, and removals.

  • #6989 2e6f760 Thanks @fubhy! - Support standard BodyInit values when reading converted client request bodies through HttpServerRequest.

  • #6986 aa05804 Thanks @fubhy! - Synchronize HTTP server response content headers when replacing the body.

  • #6944 badd3bf Thanks @fubhy! - Make Iterable.flatten stack safe across empty iterables.

  • #6968 02b0265 Thanks @fubhy! - Allow MCP tool calls to omit optional arguments.

  • #7033 3437e21 Thanks @fubhy! - Fix memory journal conflict detection skipping the first newer entry.

  • #7034 41a550d Thanks @fubhy! - Return the first unused remote sequence from the in-memory event journal.

  • #7042 17b5d50 Thanks @fubhy! - Relay entries imported into an in-memory event journal to other remotes.

  • #7074 96e5e95 Thanks @fubhy! - Preserve and update runner health in the in-memory cluster runner storage.

  • #7038 e4d589e Thanks @fubhy! - Clear in-memory message primary-key indexes when clearing an entity address.

  • #7005 ae4cf7b Thanks @fubhy! - Generate valid MSSQL upserts for multi-table persistence.

  • #6998 6ef5f1a Thanks @fubhy! - Decode split UTF-8 sequences correctly in NDJSON streams.

  • #6972 2235a29 Thanks @tim-smart! - Persist a serializable defect when a cluster reply cannot be encoded, preventing persisted entity callers from hanging.

  • #6962 b32f4cb Thanks @fubhy! - Support empty records and non-array iterables in Prompt.all.

  • #7023 7f4c095 Thanks @tim-smart! - Rename RateLimiter.makeSleep to RateLimiter.sleep and support self-first partially applied and uncurried usage.

  • #7041 5f3fb81 Thanks @fubhy! - End runner streams after emitting their terminal replies.

  • #7020 17f0b91 Thanks @gcanti! - Fix Schema.make to preserve existing nested Schema.Class instances, including in array fields, while recursively constructing plain class inputs provided at runtime inside unions. Constructor defaults remain scoped to structural field and element occurrences, with SchemaAST.Context.constructorDefault representing the single default link for each occurrence.

    Optimize Function.memoize to use a single WeakMap lookup for cached values. Its callback no longer accepts undefined as a return type because undefined represents a cache miss.

    The performance of the two array paths can be reproduced by saving the following program as
    scratchpad/schema-make-6890-benchmark.ts and running node scratchpad/schema-make-6890-benchmark.ts from the repository
    root:

    import { Schema } from "effect"
    import { performance } from "node:perf_hooks"
    
    class Row extends Schema.Class<Row>("Row")({ value: Schema.String }) {}
    class DirectTable extends Schema.Class<DirectTable>("DirectTable")({ rows: Schema.Array(Row) }) {}
    class UnionTable extends Schema.Class<UnionTable>("UnionTable")({ rows: Schema.Array(Schema.Union([Row])) }) {}
    
    const rows = Array.from({ length: 30_000 }, (_, value) => Row.make({ value: String(value) }))
    
    function benchmark(label: string, make: () => { readonly rows: ReadonlyArray<Row> }) {
      const samples: Array<number> = []
      for (let i = 0; i < 6; i++) {
        const start = performance.now()
        const result = make()
        samples.push(performance.now() - start)
        if (result.rows[0] !== rows[0] || result.rows.at(-1) !== rows.at(-1)) {
          throw new Error(`${label} did not preserve Row identity`)
        }
      }
      console.log(`${label}: ${samples.slice(1).map((n) => n.toFixed(3)).join(", ")} ms`)
    }
    
    benchmark("Array(Class)", () => DirectTable.make({ rows }))
    benchmark("Array(Union([Class]))", () => UnionTable.make({ rows }))

    Representative local results on Node 24.12.0 (six runs, with the first discarded):

    Array(Class): 0.639, 0.498, 0.447, 0.448, 0.451 ms
    Array(Union([Class])): 3.141, 2.195, 2.126, 2.108, 2.057 ms
    
  • #7055 0cdadd7 Thanks @fubhy! - Fix Stream.slidingSize to produce the same windows regardless of upstream chunk boundaries.

  • #6978 39b57d7 Thanks @fubhy! - Retain the last SSE event ID across dispatched events.

  • #6976 5a6a573 Thanks @fubhy! - Recognize and ignore a leading UTF-8 byte order mark in server-sent event streams.

  • #7048 59f5e99 Thanks @fubhy! - Ignore malformed retry directives when parsing server-sent event streams.

  • #7028 45379d6 Thanks @fubhy! - Fix Trie.insert to replace existing values without mutating the original trie or increasing its size.

  • #6973 1949439 Thanks @fubhy! - Separate the default VariantSchema cache from named variant entries.

  • #7072 e443403 Thanks @fubhy! - Keep MCP tool calls that return void successful.

  • #7000 03af7e8 Thanks @fubhy! - Close suspended workflow scopes after resumed completion.

  • #7027 130b28d Thanks @pawelblaszczyk5! - Prevent Effect.updateService and Effect.updateServiceScoped supertype widening

  • #6948 c987a12 Thanks @fubhy! - Honor numeric zero time-to-live values in Cache.make and ScopedCache.make.

  • #6974 4158562 Thanks @fubhy! - Handle accepted undefined fields during variant extraction.

  • #7013 306014a Thanks @tim-smart! - Fix several edge cases in the vendored FindMyWay router.

  • #6949 729a663 Thanks @fubhy! - Keep TestClock nanosecond access total after infinite adjustments.

  • #6997 caf84b6 Thanks @fubhy! - Isolate compiled SQL fragment caches by compiler instance.

  • #6960 ce067f7 Thanks @fubhy! - Mark omittable CLI flags and arguments as optional in structured help.

  • #7025 7a41f5a Thanks @pawelblaszczyk5! - Prevent Effect.provideServiceEffect supertype widening

  • #7056 781022a Thanks @fubhy! - Fix Map and Set equality allowing a right-side entry to match multiple left-side entries.

  • #7063 39f1297 Thanks @fubhy! - Preserve literal element types in Tuple.make.

  • #6955 2db266b Thanks @fubhy! - Include plain variant structs in the default variant union.

  • #6954 2141e28 Thanks @fubhy! - Preserve CRLF state across SSE input chunk boundaries.

  • #6950 3c5e429 Thanks @fubhy! - Preserve nanosecond precision for large TestClock wall-clock timestamps.

  • #6958 20ddc63 Thanks @fubhy! - Preserve hidden command metadata when adding subcommands or shared flags.

  • #6939 841b3ea Thanks @fubhy! - Preserve sibling provider input evidence when Config.all evaluates a failing child.

  • #6836 82a3fbf Thanks @mkdynamic! - Route provider-executed tool results into the assistant message in Prompt.fromResponseParts

  • #7003 eb9ee83 Thanks @fubhy! - Persist permanent entries in KVS setMany operations.

  • #7039 64dc7c7 Thanks @fubhy! - Fix failed ResourceRef rebuilds permanently blocking waiters.

  • #6971 84dc8ab Thanks @tim-smart! - Serialize concurrent nested SQL transactions to prevent savepoint collisions. Cross-dependent sibling nested
    transactions now deadlock instead of interleaving and risking silent data corruption.

  • #6952 b4463f4 Thanks @fubhy! - Register alternate flags used by Param.orElse and Param.orElseResult.

  • #6732 592dd36 Thanks @tim-smart! - Rename the Schema error constructors to align with their Data counterparts.

    • Schema.ErrorClass is now Schema.Error.
    • Schema.TaggedErrorClass is now Schema.TaggedError.
    • The JavaScript Error instance schema is now Schema.ErrorInstance.
    • Schema.ErrorReviver is now Schema.ErrorInstanceReviver.
  • #7068 85d2b44 Thanks @tim-smart! - Report retried RPC socket open failures through the onTransientError protocol hook and fail in-flight requests when the retry policy is exhausted.

  • #7006 32e4a69 Thanks @fubhy! - Scope custom persisted queue ID deduplication to each named queue.

  • #6938 13c5872 Thanks @fubhy! - Honor populated variables before dotenv expansion defaults in ConfigProvider.

  • #7040 3454cdb Thanks @fubhy! - Fix SynchronizedRef.getAndUpdateSome to update its backing ref.

  • #7018 e930804 Thanks @tim-smart! - Hold persisted cluster messages while entity layers are still registering, while retaining a bounded failure when
    registration never begins.

  • #6987 7f12d4b Thanks @fubhy! - Map WebSocket send exceptions and transform stream write rejections to typed SocketError failures.

  • #6977 181c9ef Thanks @fubhy! - Default empty Server-Sent Event types to message.

  • #7010 dd9f891 Thanks @tim-smart! - Rename Command.withHidden to Command.unlisted, along with the hidden command property which is now unlisted.

  • #7054 433fb81 Thanks @fubhy! - Fix the return type of Channel.runCount to expose its numeric result.

  • #7012 8459cdb Thanks @tim-smart! - Vendor the multipart parser as effect/unstable/http/MultipartParser, add the Node.js adapter at @effect/platform-node/NodeMultipartParser, and remove the external multipasta dependency.

  • #6953 6124ab3 Thanks @fubhy! - Reject truncated MessagePack frames at the end of a stream.

  • #6961 01bd954 Thanks @fubhy! - Preserve file and directory semantics in CLI completion descriptors.

  • #6990 ba2c3aa Thanks @fubhy! - Generate unique persisted paths for multipart files with duplicate filenames.

  • #7019 0a45ef3 Thanks @tim-smart! - Round Redis persistence TTLs up to whole milliseconds before passing them to integer-only expiration commands.

  • #7012 8459cdb Thanks @tim-smart! - Prevent malformed encoded multipart filenames from throwing during parsing.

  • #7029 eaa7e71 Thanks @fubhy! - Fix unencrypted event log conflict scanning to inspect the newer history suffix.

  • #6988 db4c2cc Thanks @fubhy! - Preserve lexical ordering in streaming template interpolation.

  • #6964 22f150a Thanks @fubhy! - Correct year, ordinal, and meridiem date-mask formatting.

  • #6966 90ffb08 Thanks @fubhy! - Preserve fractional leading zeros while editing float prompts.

  • #6982 d517692 Thanks @fubhy! - Reject NDJSON values without a JSON representation.

  • #6942 01af079 Thanks @fubhy! - Validate object-based DateTime instants before construction.

  • #6985 32a59e8 Thanks @fubhy! - Preserve original HTTP response bytes when reading response text first.

Don't miss a new effect release

NewReleases is sending notifications on new releases.