{"version":3,"file":"mux.cjs","names":["StreamChannel","#transformers","#channels","#streamMap","#latestValues","#interrupts","#finalValues","#closed","#error","isStreamChannel","#nextEmitSeq","#currentNamespace","#interrupted","isInterrupted","INTERRUPT","convertToProtocolEvent"],"sources":["../../src/stream/mux.ts"],"sourcesContent":["/**\n * StreamMux — central dispatcher with transformer pipeline.\n *\n * Routes raw stream chunks through registered StreamTransformers, then appends\n * the resulting ProtocolEvents to the main local channel.  Also tracks\n * namespace discovery for SubgraphRunStream creation.\n *\n * lifecycle:\n *   graph.streamEvents(input, { version: \"v3\" })\n *     ├─ StreamMux starts pumping from graph.stream(…, { subgraphs: true })\n *     ├─ For each ProtocolEvent:\n *     │   ├─ transformer_1.process(event)\n *     │   ├─ transformer_2.process(event)\n *     │   └─ event appended to _events (unless suppressed)\n *     └─ On close: transformer_n.finalize() called in registration order\n */\n\nimport type { StreamChunk } from \"../pregel/stream.js\";\nimport { INTERRUPT, isInterrupted, type Interrupt } from \"../constants.js\";\nimport { convertToProtocolEvent, STREAM_EVENTS_V3_MODES } from \"./convert.js\";\nimport { StreamChannel, isStreamChannel } from \"./stream-channel.js\";\nimport type {\n  InterruptPayload,\n  Namespace,\n  ProtocolEvent,\n  StreamEmitter,\n  StreamTransformer,\n} from \"./types.js\";\n\nexport { STREAM_EVENTS_V3_MODES };\n\n/** Wire prefix for user-defined {@link StreamChannel} auto-forwards. */\nconst EXTENSION_CHANNEL_PREFIX = \"custom:\";\n\n/**\n * Protocol method for a user-defined (extension) {@link StreamChannel}.\n * Matches Python's `StreamMux._bind_and_wire` (`f\"custom:{value.name}\"`).\n */\nfunction extensionChannelMethod(channelName: string): ProtocolEvent[\"method\"] {\n  return `${EXTENSION_CHANNEL_PREFIX}${channelName}`;\n}\n\n/**\n * Structural `PromiseLike<T>` predicate — true for thenables including\n * native promises, user-constructed `{ then }` objects, and helper\n * wrappers. Used by {@link StreamMux.wireChannels} to detect final-value\n * projections distinctly from streaming `StreamChannel` values.\n */\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n  return (\n    value != null &&\n    (typeof value === \"object\" || typeof value === \"function\") &&\n    typeof (value as { then?: unknown }).then === \"function\"\n  );\n}\n\n/**\n * Symbol key used by {@link StreamMux} to resolve the values promise on a\n * stream handle. Using a symbol keeps this off the public autocomplete surface.\n */\nexport const RESOLVE_VALUES: unique symbol = Symbol(\"resolveValues\");\n\n/**\n * Symbol key used by {@link StreamMux} to reject the values promise on a\n * stream handle. Using a symbol keeps this off the public autocomplete surface.\n */\nexport const REJECT_VALUES: unique symbol = Symbol(\"rejectValues\");\n\n/**\n * Minimal interface that {@link StreamMux} requires from stream handles\n * for lifecycle resolution. This avoids a direct dependency on\n * `GraphRunStream` / `SubgraphRunStream`.\n */\nexport interface StreamHandle {\n  [RESOLVE_VALUES](values: unknown): void;\n  [REJECT_VALUES](err: unknown): void;\n}\n\n/**\n * Factory function that creates a subgraph stream handle for a newly\n * discovered namespace.\n *\n * Historically consumed by {@link StreamMux} at construction time;\n * today factories are consumed by\n * `createSubgraphDiscoveryTransformer` (via its `createStream`\n * option).  This shape is retained for consumers that still thread a\n * mux reference through the factory — the narrower transformer\n * option omits `mux` because it captures the mux in a closure.\n */\nexport type SubgraphStreamFactory = (\n  path: Namespace,\n  mux: StreamMux,\n  discoveryStart: number,\n  eventStart: number\n) => StreamHandle;\n\n/**\n * A discovered subgraph namespace paired with its run stream handle.\n */\nexport type SubgraphDiscovery = {\n  ns: Namespace;\n  stream: StreamHandle;\n};\n\n/**\n * Central event dispatcher that routes {@link ProtocolEvent}s through a\n * pipeline of {@link StreamTransformer}s, manages namespace discovery for\n * subgraph streams, and exposes async iteration over filtered event\n * sequences.\n *\n * One `StreamMux` instance exists per top-level\n * `streamEvents(..., { version: \"v3\" })` invocation.\n */\nexport class StreamMux {\n  /** @internal All protocol events in arrival order (after reducer pipeline). */\n  readonly _events = StreamChannel.local<ProtocolEvent>();\n\n  /** @internal New-namespace discovery notifications. */\n  readonly _discoveries = StreamChannel.local<SubgraphDiscovery>();\n\n  /** Monotonic counter for auto-forwarded channel events. */\n  #nextEmitSeq = 0;\n\n  /** Whether the mux has been closed or failed. */\n  #closed = false;\n\n  /** The error passed to {@link fail}, if any. */\n  #error: unknown;\n\n  /** Whether the run was interrupted. */\n  #interrupted = false;\n\n  /**\n   * Namespace of the event currently being processed by\n   * {@link push}.  Read by {@link StreamChannel} wiring callbacks so\n   * auto-forwarded events inherit the triggering event's namespace.\n   */\n  #currentNamespace: Namespace = [];\n\n  readonly #transformers: StreamTransformer<unknown>[] = [];\n  readonly #channels: StreamChannel<unknown>[] = [];\n  readonly #streamMap = new Map<string, StreamHandle>();\n  readonly #latestValues = new Map<string, Record<string, unknown>>();\n  readonly #interrupts: InterruptPayload[] = [];\n\n  /**\n   * Final-value projection keys tracked for remote surfacing. Populated\n   * by {@link wireChannels} when a transformer's projection contains a\n   * `PromiseLike` value. Each entry is flushed as a `custom:<name>`\n   * protocol event during {@link close} so that remote clients can\n   * observe final-value transformers via `thread.extensions.<name>`.\n   */\n  readonly #finalValues: Array<{ name: string; promise: Promise<unknown> }> =\n    [];\n\n  /**\n   * Associates a pre-existing stream handle with a namespace so that\n   * {@link close} can resolve its values promise later.\n   *\n   * @param path - The namespace path to register.\n   * @param stream - The run stream handle for that namespace.\n   */\n  register(path: Namespace, stream: StreamHandle): void {\n    this.#streamMap.set(nsKey(path), stream);\n  }\n\n  /**\n   * Registers a transformer and replays all buffered events through it so\n   * it catches up with events already processed by the mux.  When the event\n   * log is empty (typical at construction time) the replay is a no-op.\n   *\n   * The transformer must already have been initialised (i.e. `init()` called\n   * and any projection wired).  The sequence is:\n   *\n   *   1. Snapshot the current event log length.\n   *   2. Append the transformer so future {@link push} calls reach it.\n   *   3. Replay events `[0, snapshot)` through `process()`.\n   *   4. If the mux is already closed, call `finalize()` (or `fail()`)\n   *      immediately so the transformer's log/channel terminates cleanly.\n   *\n   * @param transformer - An already-initialised transformer to register.\n   */\n  addTransformer(transformer: StreamTransformer<unknown>): void {\n    const snapshot = this._events.size;\n    this.#transformers.push(transformer);\n\n    // Hand the transformer a narrow emitter handle *before* replay so\n    // synthetic-emission transformers (e.g. deepagents\n    // `SubagentTransformer`) can inject events into the mux during\n    // their own `process()` calls — including the initial replay\n    // triggered just below.\n    if (transformer.onRegister) {\n      const emitter: StreamEmitter = {\n        // Transformer-originated events use a placeholder `seq` of\n        // `0`.  `push()` is the single authority for sequence numbers\n        // and will re-stamp this event with the next monotonically\n        // increasing value.\n        push: (ns, event) => this.push(ns, event),\n      };\n      transformer.onRegister(emitter);\n    }\n\n    for (let i = 0; i < snapshot; i += 1) {\n      transformer.process(this._events.get(i));\n    }\n\n    if (this.#closed) {\n      if (this.#error !== undefined) {\n        transformer.fail?.(this.#error);\n      } else {\n        transformer.finalize?.();\n      }\n    }\n  }\n\n  /**\n   * Scans a transformer projection for streaming and final-value primitives.\n   * Remote stream channels are wired to auto-forward to the protocol event\n   * stream; local stream channels are tracked for lifecycle only.\n   *\n   * Two projection shapes are recognised:\n   *\n   *   - {@link StreamChannel} values — named channels forward each `push()`\n   *     immediately as a `custom:<channelName>` protocol event. Unnamed\n   *     channels remain in-process-only.\n   *\n   *   - `PromiseLike<unknown>` values — tracked as final-value\n   *     projections and flushed on {@link close} as a single\n   *     `custom:<key>` event, where `<key>` is the projection key.\n   *     This mirrors the in-process `await run.extensions.<key>`\n   *     ergonomics on remote clients via\n   *     `await thread.extensions.<key>`.\n   *\n   * Plain values that are neither are ignored — they remain in-process-only,\n   * matching prior behaviour.\n   *\n   * @param projection - The object returned by `transformer.init()`.\n   */\n  wireChannels(projection: Record<string, unknown>): void {\n    for (const [key, value] of Object.entries(projection)) {\n      if (isStreamChannel(value)) {\n        this.#channels.push(value);\n        if (typeof value.channelName !== \"string\") {\n          continue;\n        }\n        const method = extensionChannelMethod(value.channelName);\n        value._wire((item: unknown) => {\n          this._events.push({\n            type: \"event\",\n            seq: this.#nextEmitSeq++,\n            method,\n            params: {\n              namespace: this.#currentNamespace,\n              timestamp: Date.now(),\n              data: item,\n            },\n          });\n        });\n        continue;\n      }\n      if (isPromiseLike(value)) {\n        this.#finalValues.push({\n          name: key,\n          promise: Promise.resolve(value),\n        });\n      }\n    }\n  }\n\n  /**\n   * Distributes an event through the transformer pipeline, then appends it to\n   * the main event log.\n   *\n   * Subgraph discovery (materializing a {@link StreamHandle} for each\n   * newly observed top-level namespace) is handled by the\n   * {@link createSubgraphDiscoveryTransformer} when installed, not here.\n   *\n   * @param ns - The namespace path that produced the event.\n   * @param event - The protocol event to process and store.\n   */\n  push(ns: Namespace, event: ProtocolEvent): void {\n    if (event.method === \"values\") {\n      this.#latestValues.set(\n        nsKey(ns),\n        event.params.data as Record<string, unknown>\n      );\n    }\n\n    // Save the outer namespace so re-entrant `push()` calls (e.g. from\n    // `StreamTransformer.onRegister` emitters synthesizing events\n    // inside a transformer's `process()`) can set their own namespace\n    // without clobbering the outer scope's `StreamChannel` routing\n    // when control returns to the outer transformer loop.\n    const outerNamespace = this.#currentNamespace;\n    this.#currentNamespace = ns;\n\n    let keep = true;\n    for (const transformer of this.#transformers) {\n      if (!transformer.process(event)) {\n        keep = false;\n      }\n    }\n\n    this.#currentNamespace = outerNamespace;\n\n    if (keep) {\n      // The mux is the single authority for sequence numbers.  Callers\n      // (the `pump`, transformer emitters, channel forwarders) pass a\n      // placeholder `seq`; we re-stamp every event here so the log is\n      // strictly monotonic across all origination paths.  Stamping\n      // happens *after* `process()` so that any channel-forwarded\n      // events pushed during processing get earlier sequence numbers\n      // than the triggering event, matching their in-order appearance\n      // in `_events`.\n      this._events.push({ ...event, seq: this.#nextEmitSeq++ });\n    }\n  }\n\n  /**\n   * Gracefully ends the stream: resolves values promises on all known\n   * streams, finalizes every transformer, auto-closes streaming\n   * channels, flushes any final-value projections as `custom:<name>`\n   * events, and closes both event logs.\n   *\n   * When final-value projections are present, `_events.close()` is\n   * deferred until every tracked projection promise has settled so\n   * remote consumers observe the flushed values before their event\n   * stream ends. Callers do not need to await — `close()` returns\n   * synchronously and any downstream consumer iterating\n   * {@link _events} naturally waits for the final events.\n   */\n  close(): void {\n    this.#closed = true;\n    for (const [key, values] of this.#latestValues.entries()) {\n      const ns = key ? key.split(\"\\x00\") : [];\n      const stream = this.#streamMap.get(nsKey(ns));\n      stream?.[RESOLVE_VALUES](values);\n    }\n\n    const finalizePromises: PromiseLike<void>[] = [];\n    for (const transformer of this.#transformers) {\n      const result = transformer.finalize?.();\n      if (\n        result != null &&\n        typeof (result as PromiseLike<void>).then === \"function\"\n      ) {\n        finalizePromises.push(result as PromiseLike<void>);\n      }\n    }\n\n    for (const channel of this.#channels) {\n      channel._close();\n    }\n\n    const finalValues = this.#finalValues;\n    if (finalValues.length === 0 && finalizePromises.length === 0) {\n      this._events.close();\n      this._discoveries.close();\n    } else {\n      void Promise.allSettled([\n        ...finalizePromises,\n        ...finalValues.map(async ({ name, promise }) => {\n          try {\n            const resolved = await promise;\n            if (!this._events.done) {\n              this._events.push({\n                type: \"event\",\n                seq: this.#nextEmitSeq++,\n                method: \"custom\",\n                params: {\n                  namespace: [],\n                  timestamp: Date.now(),\n                  data: { name, payload: resolved },\n                },\n              });\n            }\n          } catch {\n            // Rejected final-value projections are intentionally dropped\n            // so a single failing extension can't poison the protocol\n            // stream. The corresponding in-process Promise still\n            // surfaces the rejection to its direct awaiters via the\n            // transformer's own `fail()` hook.\n          }\n        }),\n      ]).then(() => {\n        this._events.close();\n        this._discoveries.close();\n      });\n    }\n\n    for (const stream of this.#streamMap.values()) {\n      stream[RESOLVE_VALUES](undefined);\n    }\n  }\n\n  /**\n   * Propagates a failure to all transformers, channels, event logs, and\n   * stream handles.\n   *\n   * @param err - The error that caused the run to fail.\n   */\n  fail(err: unknown): void {\n    this.#closed = true;\n    this.#error = err;\n    for (const transformer of this.#transformers) {\n      transformer.fail?.(err);\n    }\n    for (const channel of this.#channels) {\n      channel._fail(err);\n    }\n    this._events.fail(err);\n    this._discoveries.fail(err);\n    for (const stream of this.#streamMap.values()) {\n      stream[REJECT_VALUES](err);\n    }\n  }\n\n  /**\n   * Records that the run was interrupted, appending the supplied payloads\n   * for later retrieval.\n   *\n   * @param interrupts - The interrupt payloads to store.\n   */\n  markInterrupted(interrupts: InterruptPayload[]): void {\n    this.#interrupted = true;\n    this.#interrupts.push(...interrupts);\n  }\n\n  /**\n   * Whether the run ended due to an interrupt.\n   *\n   * @returns `true` if {@link markInterrupted} was called.\n   */\n  get interrupted(): boolean {\n    return this.#interrupted;\n  }\n\n  /**\n   * All interrupt payloads collected during the run.\n   *\n   * @returns A readonly view of the accumulated interrupt payloads.\n   */\n  get interrupts(): readonly InterruptPayload[] {\n    return this.#interrupts;\n  }\n\n  /**\n   * Returns an async iterator that yields only events whose namespace\n   * starts with {@link path}.\n   *\n   * @param path - Namespace prefix to filter on.\n   * @param startAt - Zero-based index into the event log to begin from.\n   * @returns An async iterator over matching {@link ProtocolEvent}s.\n   */\n  subscribeEvents(path: Namespace, startAt = 0): AsyncIterator<ProtocolEvent> {\n    const base = this._events.iterate(startAt);\n    return {\n      async next(): Promise<IteratorResult<ProtocolEvent>> {\n        // eslint-disable-next-line no-constant-condition\n        while (true) {\n          const result = await base.next();\n          if (result.done) return result;\n          if (hasPrefix(result.value.params.namespace, path)) {\n            return result;\n          }\n        }\n      },\n    };\n  }\n}\n\n/**\n * Background consumer that drains a raw `graph.stream()` source into a\n * {@link StreamMux}.  Converts each chunk to a {@link ProtocolEvent} and\n * pushes it; calls {@link StreamMux.close} on normal completion or\n * {@link StreamMux.fail} on error.\n *\n * @param source - The async iterable of raw stream chunks from the engine.\n * @param mux - The mux instance to feed.\n * @returns A promise that resolves when the source is fully consumed.\n */\nexport async function pump(\n  source: AsyncIterable<StreamChunk>,\n  mux: StreamMux\n): Promise<void> {\n  let seq = 0;\n  try {\n    for await (const chunk of source) {\n      const [ns, mode, payload] = chunk;\n\n      // Detect interrupt payloads attached to values-mode chunks.\n      if (mode === \"values\" && isInterrupted(payload)) {\n        const interrupts = (payload as { [INTERRUPT]: Interrupt[] })[INTERRUPT];\n        mux.markInterrupted(\n          interrupts.map((i) => ({\n            interruptId: i.id ?? \"\",\n            payload: i.value,\n          }))\n        );\n      }\n\n      const events = convertToProtocolEvent({\n        namespace: ns,\n        mode,\n        payload,\n        seq,\n      });\n      seq += events.length;\n      for (const event of events) {\n        mux.push(ns, event);\n      }\n    }\n  } catch (err) {\n    mux.fail(err);\n    return;\n  }\n  mux.close();\n}\n\n/**\n * Serialises a {@link Namespace} array into a single string key using the\n * null byte (`\\x00`) as separator, suitable for `Map`/`Set` lookups.\n *\n * @param ns - The namespace segments to join.\n * @returns A null-byte-joined string key.\n */\nexport function nsKey(ns: Namespace): string {\n  return ns.join(\"\\x00\");\n}\n\n/**\n * Tests whether {@link ns} starts with every segment in {@link prefix}.\n *\n * @param ns - The full namespace to check.\n * @param prefix - The prefix to match against.\n * @returns `true` if `ns` begins with `prefix` segment-by-segment.\n */\nexport function hasPrefix(ns: Namespace, prefix: Namespace): boolean {\n  if (prefix.length > ns.length) return false;\n  for (let i = 0; i < prefix.length; i += 1) {\n    if (ns[i] !== prefix[i]) return false;\n  }\n  return true;\n}\n"],"mappings":"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"}