@langchain/angular 1.0.21 → 1.0.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -69,6 +69,7 @@ Object.defineProperty(exports, "headlessToolResumeCommand", {
69
69
  });
70
70
  exports.injectAudio = require_selectors.injectAudio;
71
71
  exports.injectChannel = require_selectors.injectChannel;
72
+ exports.injectChannelEffect = require_selectors.injectChannelEffect;
72
73
  exports.injectExtension = require_selectors.injectExtension;
73
74
  exports.injectFiles = require_selectors.injectFiles;
74
75
  exports.injectImages = require_selectors.injectImages;
package/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { AgentServerOptions, AnyStream, CustomAdapterOptions, STREAM_CONTROLLER, StreamApi, ThreadStream, UseStreamOptions, UseStreamResult, UseStreamReturn, useStream } from "./use-stream.cjs";
2
2
  import { injectStream } from "./inject-stream.cjs";
3
3
  import { injectProjection } from "./inject-projection.cjs";
4
- import { SelectorTarget, injectAudio, injectChannel, injectExtension, injectFiles, injectImages, injectMessages, injectToolCalls, injectValues, injectVideo } from "./selectors.cjs";
4
+ import { InjectChannelEffectOptions, SelectorTarget, injectAudio, injectChannel, injectChannelEffect, injectExtension, injectFiles, injectImages, injectMessages, injectToolCalls, injectValues, injectVideo } from "./selectors.cjs";
5
5
  import { InjectSubmissionQueueReturn, SubmissionQueueEntry, SubmissionQueueSnapshot, injectSubmissionQueue } from "./selectors-queue.cjs";
6
6
  import { MessageMetadata, MessageMetadataMap, injectMessageMetadata } from "./selectors-metadata.cjs";
7
7
  import { injectMediaUrl } from "./inject-media-url.cjs";
@@ -9,4 +9,4 @@ import { STREAM_DEFAULTS, STREAM_INSTANCE, StreamDefaults, provideStream, provid
9
9
  import { StreamService } from "./stream-service.cjs";
10
10
  import { AgentServerAdapter, AnyMediaHandle, AssembledToolCall, AssembledToolCallFromTool as ToolCallFromTool, AudioMedia, Channel, Event, FileMedia, ImageMedia, InferStateType, InferSubagentStates, InferToolCalls, MediaAssemblyError, MediaAssemblyErrorKind, MediaBase, MediaBlockType, StreamStopOptions, StreamSubmitOptions, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, ToolCallStatus, VideoMedia, WidenUpdateMessages } from "@langchain/langgraph-sdk/stream";
11
11
  import { AnyHeadlessToolImplementation, DefaultToolCall, FlushPendingHeadlessToolInterruptsOptions, HeadlessToolImplementation, HeadlessToolInterrupt, HttpAgentServerAdapter, HttpAgentServerAdapterOptions, OnToolCallback, ToolCallState, ToolCallsFromTools, ToolEvent, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, handleHeadlessToolInterrupt, headlessToolResumeCommand, isHeadlessToolInterrupt, parseHeadlessToolInterruptPayload } from "@langchain/langgraph-sdk";
12
- export { type AgentServerAdapter, type AgentServerOptions, type AnyHeadlessToolImplementation, type AnyMediaHandle, type AnyStream, type AssembledToolCall, type AudioMedia, type Channel, type CustomAdapterOptions, type DefaultToolCall, type Event, type FileMedia, type FlushPendingHeadlessToolInterruptsOptions, type HeadlessToolImplementation, type HeadlessToolInterrupt, HttpAgentServerAdapter, type HttpAgentServerAdapterOptions, type ImageMedia, type InferStateType, type InferSubagentStates, type InferToolCalls, type InjectSubmissionQueueReturn, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, type MessageMetadata, type MessageMetadataMap, type OnToolCallback, STREAM_CONTROLLER, STREAM_DEFAULTS, STREAM_INSTANCE, type SelectorTarget, type StreamApi, type StreamDefaults, StreamService, type StreamStopOptions, type StreamSubmitOptions, type SubagentDiscoverySnapshot, type SubgraphDiscoverySnapshot, type SubmissionQueueEntry, type SubmissionQueueSnapshot, type ThreadStream, type ToolCallFromTool, type ToolCallState, type ToolCallStatus, type ToolCallsFromTools, type ToolEvent, type UseStreamOptions, type UseStreamResult, type UseStreamReturn, type VideoMedia, type WidenUpdateMessages, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, handleHeadlessToolInterrupt, headlessToolResumeCommand, injectAudio, injectChannel, injectExtension, injectFiles, injectImages, injectMediaUrl, injectMessageMetadata, injectMessages, injectProjection, injectStream, injectSubmissionQueue, injectToolCalls, injectValues, injectVideo, isHeadlessToolInterrupt, parseHeadlessToolInterruptPayload, provideStream, provideStreamDefaults, useStream };
12
+ export { type AgentServerAdapter, type AgentServerOptions, type AnyHeadlessToolImplementation, type AnyMediaHandle, type AnyStream, type AssembledToolCall, type AudioMedia, type Channel, type CustomAdapterOptions, type DefaultToolCall, type Event, type FileMedia, type FlushPendingHeadlessToolInterruptsOptions, type HeadlessToolImplementation, type HeadlessToolInterrupt, HttpAgentServerAdapter, type HttpAgentServerAdapterOptions, type ImageMedia, type InferStateType, type InferSubagentStates, type InferToolCalls, type InjectChannelEffectOptions, type InjectSubmissionQueueReturn, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, type MessageMetadata, type MessageMetadataMap, type OnToolCallback, STREAM_CONTROLLER, STREAM_DEFAULTS, STREAM_INSTANCE, type SelectorTarget, type StreamApi, type StreamDefaults, StreamService, type StreamStopOptions, type StreamSubmitOptions, type SubagentDiscoverySnapshot, type SubgraphDiscoverySnapshot, type SubmissionQueueEntry, type SubmissionQueueSnapshot, type ThreadStream, type ToolCallFromTool, type ToolCallState, type ToolCallStatus, type ToolCallsFromTools, type ToolEvent, type UseStreamOptions, type UseStreamResult, type UseStreamReturn, type VideoMedia, type WidenUpdateMessages, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, handleHeadlessToolInterrupt, headlessToolResumeCommand, injectAudio, injectChannel, injectChannelEffect, injectExtension, injectFiles, injectImages, injectMediaUrl, injectMessageMetadata, injectMessages, injectProjection, injectStream, injectSubmissionQueue, injectToolCalls, injectValues, injectVideo, isHeadlessToolInterrupt, parseHeadlessToolInterruptPayload, provideStream, provideStreamDefaults, useStream };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { AgentServerOptions, AnyStream, CustomAdapterOptions, STREAM_CONTROLLER, StreamApi, ThreadStream, UseStreamOptions, UseStreamResult, UseStreamReturn, useStream } from "./use-stream.js";
2
2
  import { injectStream } from "./inject-stream.js";
3
3
  import { injectProjection } from "./inject-projection.js";
4
- import { SelectorTarget, injectAudio, injectChannel, injectExtension, injectFiles, injectImages, injectMessages, injectToolCalls, injectValues, injectVideo } from "./selectors.js";
4
+ import { InjectChannelEffectOptions, SelectorTarget, injectAudio, injectChannel, injectChannelEffect, injectExtension, injectFiles, injectImages, injectMessages, injectToolCalls, injectValues, injectVideo } from "./selectors.js";
5
5
  import { InjectSubmissionQueueReturn, SubmissionQueueEntry, SubmissionQueueSnapshot, injectSubmissionQueue } from "./selectors-queue.js";
6
6
  import { MessageMetadata, MessageMetadataMap, injectMessageMetadata } from "./selectors-metadata.js";
7
7
  import { injectMediaUrl } from "./inject-media-url.js";
@@ -9,4 +9,4 @@ import { STREAM_DEFAULTS, STREAM_INSTANCE, StreamDefaults, provideStream, provid
9
9
  import { StreamService } from "./stream-service.js";
10
10
  import { AnyHeadlessToolImplementation, DefaultToolCall, FlushPendingHeadlessToolInterruptsOptions, HeadlessToolImplementation, HeadlessToolInterrupt, HttpAgentServerAdapter, HttpAgentServerAdapterOptions, OnToolCallback, ToolCallState, ToolCallsFromTools, ToolEvent, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, handleHeadlessToolInterrupt, headlessToolResumeCommand, isHeadlessToolInterrupt, parseHeadlessToolInterruptPayload } from "@langchain/langgraph-sdk";
11
11
  import { AgentServerAdapter, AnyMediaHandle, AssembledToolCall, AssembledToolCallFromTool as ToolCallFromTool, AudioMedia, Channel, Event, FileMedia, ImageMedia, InferStateType, InferSubagentStates, InferToolCalls, MediaAssemblyError, MediaAssemblyErrorKind, MediaBase, MediaBlockType, StreamStopOptions, StreamSubmitOptions, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, ToolCallStatus, VideoMedia, WidenUpdateMessages } from "@langchain/langgraph-sdk/stream";
12
- export { type AgentServerAdapter, type AgentServerOptions, type AnyHeadlessToolImplementation, type AnyMediaHandle, type AnyStream, type AssembledToolCall, type AudioMedia, type Channel, type CustomAdapterOptions, type DefaultToolCall, type Event, type FileMedia, type FlushPendingHeadlessToolInterruptsOptions, type HeadlessToolImplementation, type HeadlessToolInterrupt, HttpAgentServerAdapter, type HttpAgentServerAdapterOptions, type ImageMedia, type InferStateType, type InferSubagentStates, type InferToolCalls, type InjectSubmissionQueueReturn, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, type MessageMetadata, type MessageMetadataMap, type OnToolCallback, STREAM_CONTROLLER, STREAM_DEFAULTS, STREAM_INSTANCE, type SelectorTarget, type StreamApi, type StreamDefaults, StreamService, type StreamStopOptions, type StreamSubmitOptions, type SubagentDiscoverySnapshot, type SubgraphDiscoverySnapshot, type SubmissionQueueEntry, type SubmissionQueueSnapshot, type ThreadStream, type ToolCallFromTool, type ToolCallState, type ToolCallStatus, type ToolCallsFromTools, type ToolEvent, type UseStreamOptions, type UseStreamResult, type UseStreamReturn, type VideoMedia, type WidenUpdateMessages, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, handleHeadlessToolInterrupt, headlessToolResumeCommand, injectAudio, injectChannel, injectExtension, injectFiles, injectImages, injectMediaUrl, injectMessageMetadata, injectMessages, injectProjection, injectStream, injectSubmissionQueue, injectToolCalls, injectValues, injectVideo, isHeadlessToolInterrupt, parseHeadlessToolInterruptPayload, provideStream, provideStreamDefaults, useStream };
12
+ export { type AgentServerAdapter, type AgentServerOptions, type AnyHeadlessToolImplementation, type AnyMediaHandle, type AnyStream, type AssembledToolCall, type AudioMedia, type Channel, type CustomAdapterOptions, type DefaultToolCall, type Event, type FileMedia, type FlushPendingHeadlessToolInterruptsOptions, type HeadlessToolImplementation, type HeadlessToolInterrupt, HttpAgentServerAdapter, type HttpAgentServerAdapterOptions, type ImageMedia, type InferStateType, type InferSubagentStates, type InferToolCalls, type InjectChannelEffectOptions, type InjectSubmissionQueueReturn, MediaAssemblyError, type MediaAssemblyErrorKind, type MediaBase, type MediaBlockType, type MessageMetadata, type MessageMetadataMap, type OnToolCallback, STREAM_CONTROLLER, STREAM_DEFAULTS, STREAM_INSTANCE, type SelectorTarget, type StreamApi, type StreamDefaults, StreamService, type StreamStopOptions, type StreamSubmitOptions, type SubagentDiscoverySnapshot, type SubgraphDiscoverySnapshot, type SubmissionQueueEntry, type SubmissionQueueSnapshot, type ThreadStream, type ToolCallFromTool, type ToolCallState, type ToolCallStatus, type ToolCallsFromTools, type ToolEvent, type UseStreamOptions, type UseStreamResult, type UseStreamReturn, type VideoMedia, type WidenUpdateMessages, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, handleHeadlessToolInterrupt, headlessToolResumeCommand, injectAudio, injectChannel, injectChannelEffect, injectExtension, injectFiles, injectImages, injectMediaUrl, injectMessageMetadata, injectMessages, injectProjection, injectStream, injectSubmissionQueue, injectToolCalls, injectValues, injectVideo, isHeadlessToolInterrupt, parseHeadlessToolInterruptPayload, provideStream, provideStreamDefaults, useStream };
package/dist/index.js CHANGED
@@ -2,11 +2,11 @@ import { STREAM_CONTROLLER, useStream } from "./use-stream.js";
2
2
  import { STREAM_DEFAULTS, STREAM_INSTANCE, provideStream, provideStreamDefaults } from "./context.js";
3
3
  import { injectStream } from "./inject-stream.js";
4
4
  import { injectProjection } from "./inject-projection.js";
5
- import { injectAudio, injectChannel, injectExtension, injectFiles, injectImages, injectMessages, injectToolCalls, injectValues, injectVideo } from "./selectors.js";
5
+ import { injectAudio, injectChannel, injectChannelEffect, injectExtension, injectFiles, injectImages, injectMessages, injectToolCalls, injectValues, injectVideo } from "./selectors.js";
6
6
  import { injectSubmissionQueue } from "./selectors-queue.js";
7
7
  import { injectMessageMetadata } from "./selectors-metadata.js";
8
8
  import { injectMediaUrl } from "./inject-media-url.js";
9
9
  import { StreamService } from "./stream-service.js";
10
10
  import { HttpAgentServerAdapter, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, handleHeadlessToolInterrupt, headlessToolResumeCommand, isHeadlessToolInterrupt, parseHeadlessToolInterruptPayload } from "@langchain/langgraph-sdk";
11
11
  import { MediaAssemblyError } from "@langchain/langgraph-sdk/stream";
12
- export { HttpAgentServerAdapter, MediaAssemblyError, STREAM_CONTROLLER, STREAM_DEFAULTS, STREAM_INSTANCE, StreamService, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, handleHeadlessToolInterrupt, headlessToolResumeCommand, injectAudio, injectChannel, injectExtension, injectFiles, injectImages, injectMediaUrl, injectMessageMetadata, injectMessages, injectProjection, injectStream, injectSubmissionQueue, injectToolCalls, injectValues, injectVideo, isHeadlessToolInterrupt, parseHeadlessToolInterruptPayload, provideStream, provideStreamDefaults, useStream };
12
+ export { HttpAgentServerAdapter, MediaAssemblyError, STREAM_CONTROLLER, STREAM_DEFAULTS, STREAM_INSTANCE, StreamService, executeHeadlessTool, filterOutHeadlessToolInterrupts, findHeadlessTool, flushPendingHeadlessToolInterrupts, handleHeadlessToolInterrupt, headlessToolResumeCommand, injectAudio, injectChannel, injectChannelEffect, injectExtension, injectFiles, injectImages, injectMediaUrl, injectMessageMetadata, injectMessages, injectProjection, injectStream, injectSubmissionQueue, injectToolCalls, injectValues, injectVideo, isHeadlessToolInterrupt, parseHeadlessToolInterruptPayload, provideStream, provideStreamDefaults, useStream };
@@ -124,6 +124,74 @@ function injectChannel(stream, channels, target, options) {
124
124
  }
125
125
  const EMPTY_EVENTS = [];
126
126
  /**
127
+ * Side-effect counterpart to {@link injectChannel}. Instead of
128
+ * returning a signal of buffered events, it invokes `onEvent` once per
129
+ * event for as long as the owning component / service is alive — the
130
+ * idiomatic place for analytics, logging, and other fire-and-forget
131
+ * side effects.
132
+ *
133
+ * ```ts
134
+ * injectChannelEffect(this.stream, ["lifecycle", "tools"], {
135
+ * replay: false,
136
+ * onEvent: (event) => sendAnalytics(event),
137
+ * onError: (error) => logger.error(error),
138
+ * });
139
+ * ```
140
+ *
141
+ * Reactive `channels` / `target` / `enabled` signals re-bind the
142
+ * subscription when they change. The underlying subscription is shared
143
+ * (ref-counted) with any matching {@link injectChannel} consumer.
144
+ * `replay` defaults to `false` (live-only); events buffered before the
145
+ * effect attaches are not re-delivered.
146
+ *
147
+ * Must be called from an injection context (component / directive /
148
+ * service field initializer, or `runInInjectionContext(...)`).
149
+ */
150
+ function injectChannelEffect(stream, channels, options) {
151
+ const target = options.target;
152
+ resolveSubagentNamespaceFor(stream, target);
153
+ const destroyRef = (0, _angular_core.inject)(_angular_core.DestroyRef);
154
+ const enabledOf = () => {
155
+ const value = options.enabled;
156
+ if (value == null) return true;
157
+ return (0, _angular_core.isSignal)(value) ? value() : value;
158
+ };
159
+ const channelsOf = () => (0, _angular_core.isSignal)(channels) ? channels() : channels;
160
+ const targetOf = () => (0, _angular_core.isSignal)(target) ? target() : target;
161
+ const keyOf = () => {
162
+ const enabled = enabledOf();
163
+ const sortedChannels = [...channelsOf()].sort().join(",");
164
+ const namespace = resolveNamespace(targetOf());
165
+ return `${enabled ? "on" : "off"}|${sortedChannels}|${namespaceKey(namespace)}`;
166
+ };
167
+ let dispose;
168
+ let currentKey;
169
+ const detach = () => {
170
+ dispose?.();
171
+ dispose = void 0;
172
+ };
173
+ const attach = (nextKey) => {
174
+ if (nextKey === currentKey) return;
175
+ detach();
176
+ currentKey = nextKey;
177
+ if (!enabledOf()) return;
178
+ const registry = require_use_stream.getRegistry(stream);
179
+ if (registry == null) return;
180
+ dispose = (0, _langchain_langgraph_sdk_stream.acquireChannelEffect)(registry, channelsOf(), resolveNamespace(targetOf()), {
181
+ replay: options.replay,
182
+ bufferSize: options.bufferSize,
183
+ onEvent: (event) => options.onEvent(event),
184
+ onError: options.onError ? (error) => options.onError?.(error) : void 0
185
+ });
186
+ };
187
+ attach(keyOf());
188
+ destroyRef.onDestroy(detach);
189
+ (0, _angular_core.effect)(() => {
190
+ const nextKey = keyOf();
191
+ (0, _angular_core.untracked)(() => attach(nextKey));
192
+ });
193
+ }
194
+ /**
127
195
  * Subscribe to a scoped audio-media stream. Each handle is yielded
128
196
  * on its first matching `content-block-start`, exposes
129
197
  * `.partialBytes` for live access, settles `.blob` / `.objectURL` /
@@ -167,6 +235,7 @@ const EMPTY_FILES = [];
167
235
  //#endregion
168
236
  exports.injectAudio = injectAudio;
169
237
  exports.injectChannel = injectChannel;
238
+ exports.injectChannelEffect = injectChannelEffect;
170
239
  exports.injectExtension = injectExtension;
171
240
  exports.injectFiles = injectFiles;
172
241
  exports.injectImages = injectImages;
@@ -1 +1 @@
1
- {"version":3,"file":"selectors.cjs","names":["STREAM_CONTROLLER","NAMESPACE_SEPARATOR","injectProjection","getRegistry"],"sources":["../src/selectors.ts"],"sourcesContent":["import { computed, effect, isSignal, type Signal } from \"@angular/core\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport {\n NAMESPACE_SEPARATOR,\n audioProjection,\n channelProjection,\n extensionProjection,\n filesProjection,\n imagesProjection,\n messagesProjection,\n toolCallsProjection,\n valuesProjection,\n videoProjection,\n type AssembledToolCall,\n type AudioMedia,\n type Channel,\n type ChannelProjectionOptions,\n type Event,\n type FileMedia,\n type ImageMedia,\n type InferToolCalls,\n type InferStateType,\n type SubagentDiscoverySnapshot,\n type SubgraphDiscoverySnapshot,\n type VideoMedia,\n} from \"@langchain/langgraph-sdk/stream\";\nimport {\n getRegistry,\n STREAM_CONTROLLER,\n type AnyStream,\n type UseStreamReturn,\n} from \"./use-stream.js\";\nimport { injectProjection } from \"./inject-projection.js\";\n\n/**\n * Selector primitives don't need to carry `InterruptType` /\n * `ConfigurableType`. Parameterising on `StateType` alone lets\n * callers with a full `injectStream<S, I, C>()` handle pass it in\n * without redeclaring those generics at every call site.\n */\ntype StreamHandle<StateType extends object> = UseStreamReturn<\n StateType,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any\n>;\n\n/**\n * What a selector primitive can be targeted at. Callers can pass:\n * - `undefined` / `null` — root namespace (served by the always-on\n * root store — no extra subscription);\n * - a {@link SubagentDiscoverySnapshot} (`stream.subagents().get(...)`);\n * - a {@link SubgraphDiscoverySnapshot} (`stream.subgraphs().get(...)`);\n * - an explicit `{ namespace: string[] }`;\n * - a raw `string[]` escape hatch.\n *\n * Selectors also accept a `Signal<SelectorTarget>` so callers can\n * feed a `computed(() => ...)` and have the projection rebind\n * automatically.\n */\nexport type SelectorTarget =\n | undefined\n | null\n | readonly string[]\n | { namespace: readonly string[] }\n | SubagentDiscoverySnapshot\n | SubgraphDiscoverySnapshot;\n\nconst EMPTY_NAMESPACE: readonly string[] = [];\n\nfunction resolveNamespace(target: SelectorTarget): readonly string[] {\n if (target == null) return EMPTY_NAMESPACE;\n if (Array.isArray(target)) return target as readonly string[];\n const obj = target as { namespace?: readonly string[] };\n return obj.namespace ?? EMPTY_NAMESPACE;\n}\n\nfunction isRoot(namespace: readonly string[]): boolean {\n return namespace.length === 0;\n}\n\n/**\n * If `target` is a subagent snapshot still on its default\n * `tools:<toolCallId>` namespace, return that tool-call id. See the\n * React selectors for the rationale (deep-agent subagents execute under\n * a distinct `tools:<uuid>` namespace resolved lazily from history).\n */\nfunction subagentNeedingNamespace(target: SelectorTarget): string | null {\n if (target == null || Array.isArray(target)) return null;\n const obj = target as { id?: unknown; namespace?: readonly string[] };\n if (typeof obj.id !== \"string\" || !Array.isArray(obj.namespace)) return null;\n if (obj.namespace.length === 1 && obj.namespace[0] === `tools:${obj.id}`) {\n return obj.id;\n }\n return null;\n}\n\n/**\n * Lazily resolve a subagent's execution namespace on first scoped use.\n * Must be called from an injection context (as the selector primitives\n * are). A `Signal` target re-evaluates via an `effect`; a static target\n * resolves once. The controller de-dupes and skips already-promoted\n * ids.\n */\nfunction resolveSubagentNamespaceFor(\n stream: AnyStream,\n target: SelectorTarget | Signal<SelectorTarget>\n): void {\n const controller = stream[STREAM_CONTROLLER];\n if (isSignal(target)) {\n effect(() => {\n const id = subagentNeedingNamespace((target as Signal<SelectorTarget>)());\n if (id != null) void controller.resolveSubagentNamespace(id);\n });\n return;\n }\n const id = subagentNeedingNamespace(target as SelectorTarget);\n if (id != null) void controller.resolveSubagentNamespace(id);\n}\n\nfunction namespaceKey(namespace: readonly string[]): string {\n return namespace.join(NAMESPACE_SEPARATOR);\n}\n\n/**\n * Resolve a target or target-signal into a reactive\n * `[namespace, key]` pair. The helper returns plain signals so\n * `injectProjection` can track them via its internal effect.\n */\nfunction normalizeTarget(\n target: SelectorTarget | Signal<SelectorTarget>,\n prefix: string\n): {\n namespace: Signal<readonly string[]>;\n key: Signal<string>;\n isRootSignal: Signal<boolean>;\n} {\n if (isSignal(target)) {\n const namespace = computed(() =>\n resolveNamespace((target as Signal<SelectorTarget>)())\n );\n const key = computed(() => `${prefix}|${namespaceKey(namespace())}`);\n const isRootSignal = computed(() => isRoot(namespace()));\n return { namespace, key, isRootSignal };\n }\n const ns = resolveNamespace(target as SelectorTarget);\n const staticKey = `${prefix}|${namespaceKey(ns)}`;\n return {\n namespace: computed(() => ns),\n key: computed(() => staticKey),\n isRootSignal: computed(() => isRoot(ns)),\n };\n}\n\n/**\n * Subscribe to a scoped `messages` stream.\n *\n * Contract:\n * - At the root (no `target`) this returns `stream.messages` — the\n * always-on root projection; no extra subscription is opened.\n * - For any non-root namespace, call-time triggers a ref-counted\n * `messages` subscription scoped to that namespace. The\n * subscription is released automatically when the calling\n * component / service is destroyed (and the registry closes the\n * underlying server subscription when the last consumer leaves).\n *\n * Messages are always `BaseMessage` class instances from\n * `@langchain/core/messages`.\n */\nexport function injectMessages(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<BaseMessage[]> {\n resolveSubagentNamespaceFor(\n stream,\n target as SelectorTarget | Signal<SelectorTarget>\n );\n const { namespace, key, isRootSignal } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"messages\"\n );\n const registry = computed(() =>\n isRootSignal() ? null : getRegistry(stream)\n );\n const scoped = injectProjection<BaseMessage[]>(\n registry,\n () => messagesProjection(namespace()),\n key,\n EMPTY_MESSAGES\n );\n return computed(() => (isRootSignal() ? stream.messages() : scoped()));\n}\n\nconst EMPTY_MESSAGES: BaseMessage[] = [];\n\n/**\n * Subscribe to a scoped `tools` (tool-call) stream. Same target and\n * lifecycle rules as {@link injectMessages}; at the root this returns\n * `stream.toolCalls` directly.\n */\nexport function injectToolCalls(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<AssembledToolCall[]>;\nexport function injectToolCalls<T>(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<InferToolCalls<T>[]>;\nexport function injectToolCalls(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<AssembledToolCall[]> {\n resolveSubagentNamespaceFor(\n stream,\n target as SelectorTarget | Signal<SelectorTarget>\n );\n const { namespace, key, isRootSignal } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"toolCalls\"\n );\n const registry = computed(() =>\n isRootSignal() ? null : getRegistry(stream)\n );\n const scoped = injectProjection<AssembledToolCall[]>(\n registry,\n () => toolCallsProjection(namespace()),\n key,\n EMPTY_TOOLCALLS\n );\n return computed(() => (isRootSignal() ? stream.toolCalls() : scoped()));\n}\n\nconst EMPTY_TOOLCALLS: AssembledToolCall[] = [];\n\n/**\n * Subscribe to a scoped `values` stream — the most recent state\n * payload for a namespace. At the root returns `stream.values`.\n *\n * Typing:\n * - **Root** (`injectValues(stream)`): returns the `StateType`\n * declared on `injectStream<State>()` — non-nullable (the root\n * snapshot always has values, falling back to `initialValues ??\n * {}`).\n * - **Scoped** (`injectValues(stream, target)`): scoped payloads can\n * differ from the root state; callers should annotate the expected\n * shape explicitly (`injectValues<SubagentState>(stream, sub)`).\n * Defaults to `unknown` when not annotated.\n */\nexport function injectValues<StateType extends object>(\n stream: StreamHandle<StateType>\n): Signal<StateType>;\nexport function injectValues<T>(stream: AnyStream): Signal<InferStateType<T>>;\nexport function injectValues<T = unknown>(\n stream: AnyStream,\n target: SelectorTarget | Signal<SelectorTarget>,\n options?: { messagesKey?: string }\n): Signal<T | undefined>;\nexport function injectValues(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>,\n options?: { messagesKey?: string }\n): Signal<unknown> {\n const messagesKey = options?.messagesKey ?? \"messages\";\n const { namespace, key, isRootSignal } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n `values|${messagesKey}`\n );\n const registry = computed(() =>\n isRootSignal() ? null : getRegistry(stream)\n );\n const scoped = injectProjection<unknown>(\n registry,\n () => valuesProjection<unknown>(namespace(), messagesKey),\n key,\n undefined\n );\n return computed(() => (isRootSignal() ? stream.values() : scoped()));\n}\n\n/**\n * Subscribe to a `custom:<name>` stream extension — the most recent\n * payload emitted by the transformer, scoped to the target namespace.\n *\n * Returns only the latest value and resumes across serial runs, so it is\n * ideal for \"current state\" panels (progress, score, status). When you\n * need the full history of events rather than just the latest payload,\n * use {@link injectChannel} instead.\n */\nexport function injectExtension<T = unknown>(\n stream: AnyStream,\n name: string,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<T | undefined> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n `extension|${name}`\n );\n return injectProjection<T | undefined>(\n getRegistry(stream),\n () => extensionProjection<T>(name, namespace()),\n key,\n undefined\n );\n}\n\n/**\n * Raw-events escape hatch. Subscribes to one or more channels at a\n * namespace and returns a bounded buffer of raw protocol events.\n *\n * The buffer keeps accumulating across serial runs for the lifetime of\n * the thread, so this is the hook to use for an event log / stream of a\n * custom channel (e.g. `[\"custom:redaction-stats\"]`). When you only need\n * the latest payload of a single `custom:<name>` channel, prefer\n * {@link injectExtension}. For the common message/tool/value cases prefer\n * {@link injectMessages} / {@link injectToolCalls} / {@link injectValues}.\n */\nexport type InjectChannelOptions = ChannelProjectionOptions;\n\nexport function injectChannel(\n stream: AnyStream,\n channels: readonly Channel[],\n target?: SelectorTarget | Signal<SelectorTarget>,\n options?: InjectChannelOptions\n): Signal<Event[]> {\n const sortedChannels = [...channels].sort().join(\",\");\n const prefix = `channel|${options?.bufferSize ?? \"default\"}|${(options?.replay ?? true) ? \"replay\" : \"live\"}|${sortedChannels}`;\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n prefix\n );\n return injectProjection<Event[]>(\n getRegistry(stream),\n () => channelProjection(channels, namespace(), options),\n key,\n EMPTY_EVENTS\n );\n}\n\nconst EMPTY_EVENTS: Event[] = [];\n\n/**\n * Subscribe to a scoped audio-media stream. Each handle is yielded\n * on its first matching `content-block-start`, exposes\n * `.partialBytes` for live access, settles `.blob` / `.objectURL` /\n * `.transcript` on `message-finish`, and surfaces errors via\n * `.error`.\n *\n * Pair with `injectMediaUrl` to turn a handle into an `<audio src>`.\n */\nexport function injectAudio(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<AudioMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"audio\"\n );\n return injectProjection<AudioMedia[]>(\n getRegistry(stream),\n () => audioProjection(namespace()),\n key,\n EMPTY_AUDIO\n );\n}\n\nconst EMPTY_AUDIO: AudioMedia[] = [];\n\n/**\n * Subscribe to a scoped image-media stream. Pair with\n * `injectMediaUrl` for `<img src>`.\n */\nexport function injectImages(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<ImageMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"images\"\n );\n return injectProjection<ImageMedia[]>(\n getRegistry(stream),\n () => imagesProjection(namespace()),\n key,\n EMPTY_IMAGES\n );\n}\n\nconst EMPTY_IMAGES: ImageMedia[] = [];\n\n/**\n * Subscribe to a scoped video-media stream. Pair with\n * `injectMediaUrl` for `<video src>`.\n */\nexport function injectVideo(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<VideoMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"video\"\n );\n return injectProjection<VideoMedia[]>(\n getRegistry(stream),\n () => videoProjection(namespace()),\n key,\n EMPTY_VIDEO\n );\n}\n\nconst EMPTY_VIDEO: VideoMedia[] = [];\n\n/**\n * Subscribe to a scoped file-media stream. Pair with\n * `injectMediaUrl` for an `<a download href>` target.\n */\nexport function injectFiles(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<FileMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"files\"\n );\n return injectProjection<FileMedia[]>(\n getRegistry(stream),\n () => filesProjection(namespace()),\n key,\n EMPTY_FILES\n );\n}\n\nconst EMPTY_FILES: FileMedia[] = [];\n"],"mappings":"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"}
1
+ {"version":3,"file":"selectors.cjs","names":["STREAM_CONTROLLER","NAMESPACE_SEPARATOR","injectProjection","getRegistry","DestroyRef"],"sources":["../src/selectors.ts"],"sourcesContent":["import {\n DestroyRef,\n computed,\n effect,\n inject,\n isSignal,\n untracked,\n type Signal,\n} from \"@angular/core\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport {\n NAMESPACE_SEPARATOR,\n acquireChannelEffect,\n audioProjection,\n channelProjection,\n extensionProjection,\n filesProjection,\n imagesProjection,\n messagesProjection,\n toolCallsProjection,\n valuesProjection,\n videoProjection,\n type AssembledToolCall,\n type AudioMedia,\n type Channel,\n type ChannelEffectOptions,\n type ChannelProjectionOptions,\n type Event,\n type FileMedia,\n type ImageMedia,\n type InferToolCalls,\n type InferStateType,\n type SubagentDiscoverySnapshot,\n type SubgraphDiscoverySnapshot,\n type VideoMedia,\n} from \"@langchain/langgraph-sdk/stream\";\nimport {\n getRegistry,\n STREAM_CONTROLLER,\n type AnyStream,\n type UseStreamReturn,\n} from \"./use-stream.js\";\nimport { injectProjection } from \"./inject-projection.js\";\n\n/**\n * Selector primitives don't need to carry `InterruptType` /\n * `ConfigurableType`. Parameterising on `StateType` alone lets\n * callers with a full `injectStream<S, I, C>()` handle pass it in\n * without redeclaring those generics at every call site.\n */\ntype StreamHandle<StateType extends object> = UseStreamReturn<\n StateType,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any\n>;\n\n/**\n * What a selector primitive can be targeted at. Callers can pass:\n * - `undefined` / `null` — root namespace (served by the always-on\n * root store — no extra subscription);\n * - a {@link SubagentDiscoverySnapshot} (`stream.subagents().get(...)`);\n * - a {@link SubgraphDiscoverySnapshot} (`stream.subgraphs().get(...)`);\n * - an explicit `{ namespace: string[] }`;\n * - a raw `string[]` escape hatch.\n *\n * Selectors also accept a `Signal<SelectorTarget>` so callers can\n * feed a `computed(() => ...)` and have the projection rebind\n * automatically.\n */\nexport type SelectorTarget =\n | undefined\n | null\n | readonly string[]\n | { namespace: readonly string[] }\n | SubagentDiscoverySnapshot\n | SubgraphDiscoverySnapshot;\n\nconst EMPTY_NAMESPACE: readonly string[] = [];\n\nfunction resolveNamespace(target: SelectorTarget): readonly string[] {\n if (target == null) return EMPTY_NAMESPACE;\n if (Array.isArray(target)) return target as readonly string[];\n const obj = target as { namespace?: readonly string[] };\n return obj.namespace ?? EMPTY_NAMESPACE;\n}\n\nfunction isRoot(namespace: readonly string[]): boolean {\n return namespace.length === 0;\n}\n\n/**\n * If `target` is a subagent snapshot still on its default\n * `tools:<toolCallId>` namespace, return that tool-call id. See the\n * React selectors for the rationale (deep-agent subagents execute under\n * a distinct `tools:<uuid>` namespace resolved lazily from history).\n */\nfunction subagentNeedingNamespace(target: SelectorTarget): string | null {\n if (target == null || Array.isArray(target)) return null;\n const obj = target as { id?: unknown; namespace?: readonly string[] };\n if (typeof obj.id !== \"string\" || !Array.isArray(obj.namespace)) return null;\n if (obj.namespace.length === 1 && obj.namespace[0] === `tools:${obj.id}`) {\n return obj.id;\n }\n return null;\n}\n\n/**\n * Lazily resolve a subagent's execution namespace on first scoped use.\n * Must be called from an injection context (as the selector primitives\n * are). A `Signal` target re-evaluates via an `effect`; a static target\n * resolves once. The controller de-dupes and skips already-promoted\n * ids.\n */\nfunction resolveSubagentNamespaceFor(\n stream: AnyStream,\n target: SelectorTarget | Signal<SelectorTarget>\n): void {\n const controller = stream[STREAM_CONTROLLER];\n if (isSignal(target)) {\n effect(() => {\n const id = subagentNeedingNamespace((target as Signal<SelectorTarget>)());\n if (id != null) void controller.resolveSubagentNamespace(id);\n });\n return;\n }\n const id = subagentNeedingNamespace(target as SelectorTarget);\n if (id != null) void controller.resolveSubagentNamespace(id);\n}\n\nfunction namespaceKey(namespace: readonly string[]): string {\n return namespace.join(NAMESPACE_SEPARATOR);\n}\n\n/**\n * Resolve a target or target-signal into a reactive\n * `[namespace, key]` pair. The helper returns plain signals so\n * `injectProjection` can track them via its internal effect.\n */\nfunction normalizeTarget(\n target: SelectorTarget | Signal<SelectorTarget>,\n prefix: string\n): {\n namespace: Signal<readonly string[]>;\n key: Signal<string>;\n isRootSignal: Signal<boolean>;\n} {\n if (isSignal(target)) {\n const namespace = computed(() =>\n resolveNamespace((target as Signal<SelectorTarget>)())\n );\n const key = computed(() => `${prefix}|${namespaceKey(namespace())}`);\n const isRootSignal = computed(() => isRoot(namespace()));\n return { namespace, key, isRootSignal };\n }\n const ns = resolveNamespace(target as SelectorTarget);\n const staticKey = `${prefix}|${namespaceKey(ns)}`;\n return {\n namespace: computed(() => ns),\n key: computed(() => staticKey),\n isRootSignal: computed(() => isRoot(ns)),\n };\n}\n\n/**\n * Subscribe to a scoped `messages` stream.\n *\n * Contract:\n * - At the root (no `target`) this returns `stream.messages` — the\n * always-on root projection; no extra subscription is opened.\n * - For any non-root namespace, call-time triggers a ref-counted\n * `messages` subscription scoped to that namespace. The\n * subscription is released automatically when the calling\n * component / service is destroyed (and the registry closes the\n * underlying server subscription when the last consumer leaves).\n *\n * Messages are always `BaseMessage` class instances from\n * `@langchain/core/messages`.\n */\nexport function injectMessages(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<BaseMessage[]> {\n resolveSubagentNamespaceFor(\n stream,\n target as SelectorTarget | Signal<SelectorTarget>\n );\n const { namespace, key, isRootSignal } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"messages\"\n );\n const registry = computed(() =>\n isRootSignal() ? null : getRegistry(stream)\n );\n const scoped = injectProjection<BaseMessage[]>(\n registry,\n () => messagesProjection(namespace()),\n key,\n EMPTY_MESSAGES\n );\n return computed(() => (isRootSignal() ? stream.messages() : scoped()));\n}\n\nconst EMPTY_MESSAGES: BaseMessage[] = [];\n\n/**\n * Subscribe to a scoped `tools` (tool-call) stream. Same target and\n * lifecycle rules as {@link injectMessages}; at the root this returns\n * `stream.toolCalls` directly.\n */\nexport function injectToolCalls(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<AssembledToolCall[]>;\nexport function injectToolCalls<T>(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<InferToolCalls<T>[]>;\nexport function injectToolCalls(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<AssembledToolCall[]> {\n resolveSubagentNamespaceFor(\n stream,\n target as SelectorTarget | Signal<SelectorTarget>\n );\n const { namespace, key, isRootSignal } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"toolCalls\"\n );\n const registry = computed(() =>\n isRootSignal() ? null : getRegistry(stream)\n );\n const scoped = injectProjection<AssembledToolCall[]>(\n registry,\n () => toolCallsProjection(namespace()),\n key,\n EMPTY_TOOLCALLS\n );\n return computed(() => (isRootSignal() ? stream.toolCalls() : scoped()));\n}\n\nconst EMPTY_TOOLCALLS: AssembledToolCall[] = [];\n\n/**\n * Subscribe to a scoped `values` stream — the most recent state\n * payload for a namespace. At the root returns `stream.values`.\n *\n * Typing:\n * - **Root** (`injectValues(stream)`): returns the `StateType`\n * declared on `injectStream<State>()` — non-nullable (the root\n * snapshot always has values, falling back to `initialValues ??\n * {}`).\n * - **Scoped** (`injectValues(stream, target)`): scoped payloads can\n * differ from the root state; callers should annotate the expected\n * shape explicitly (`injectValues<SubagentState>(stream, sub)`).\n * Defaults to `unknown` when not annotated.\n */\nexport function injectValues<StateType extends object>(\n stream: StreamHandle<StateType>\n): Signal<StateType>;\nexport function injectValues<T>(stream: AnyStream): Signal<InferStateType<T>>;\nexport function injectValues<T = unknown>(\n stream: AnyStream,\n target: SelectorTarget | Signal<SelectorTarget>,\n options?: { messagesKey?: string }\n): Signal<T | undefined>;\nexport function injectValues(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>,\n options?: { messagesKey?: string }\n): Signal<unknown> {\n const messagesKey = options?.messagesKey ?? \"messages\";\n const { namespace, key, isRootSignal } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n `values|${messagesKey}`\n );\n const registry = computed(() =>\n isRootSignal() ? null : getRegistry(stream)\n );\n const scoped = injectProjection<unknown>(\n registry,\n () => valuesProjection<unknown>(namespace(), messagesKey),\n key,\n undefined\n );\n return computed(() => (isRootSignal() ? stream.values() : scoped()));\n}\n\n/**\n * Subscribe to a `custom:<name>` stream extension — the most recent\n * payload emitted by the transformer, scoped to the target namespace.\n *\n * Returns only the latest value and resumes across serial runs, so it is\n * ideal for \"current state\" panels (progress, score, status). When you\n * need the full history of events rather than just the latest payload,\n * use {@link injectChannel} instead.\n */\nexport function injectExtension<T = unknown>(\n stream: AnyStream,\n name: string,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<T | undefined> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n `extension|${name}`\n );\n return injectProjection<T | undefined>(\n getRegistry(stream),\n () => extensionProjection<T>(name, namespace()),\n key,\n undefined\n );\n}\n\n/**\n * Raw-events escape hatch. Subscribes to one or more channels at a\n * namespace and returns a bounded buffer of raw protocol events.\n *\n * The buffer keeps accumulating across serial runs for the lifetime of\n * the thread, so this is the hook to use for an event log / stream of a\n * custom channel (e.g. `[\"custom:redaction-stats\"]`). When you only need\n * the latest payload of a single `custom:<name>` channel, prefer\n * {@link injectExtension}. For the common message/tool/value cases prefer\n * {@link injectMessages} / {@link injectToolCalls} / {@link injectValues}.\n */\nexport type InjectChannelOptions = ChannelProjectionOptions;\n\nexport function injectChannel(\n stream: AnyStream,\n channels: readonly Channel[],\n target?: SelectorTarget | Signal<SelectorTarget>,\n options?: InjectChannelOptions\n): Signal<Event[]> {\n const sortedChannels = [...channels].sort().join(\",\");\n const prefix = `channel|${options?.bufferSize ?? \"default\"}|${(options?.replay ?? true) ? \"replay\" : \"live\"}|${sortedChannels}`;\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n prefix\n );\n return injectProjection<Event[]>(\n getRegistry(stream),\n () => channelProjection(channels, namespace(), options),\n key,\n EMPTY_EVENTS\n );\n}\n\nconst EMPTY_EVENTS: Event[] = [];\n\n/**\n * Options for {@link injectChannelEffect}. Extends the projection\n * options (`bufferSize`, `replay`) with the per-event callback, an\n * optional error sink, a `target` scope, and an `enabled` gate.\n */\nexport interface InjectChannelEffectOptions extends ChannelEffectOptions {\n /**\n * Scope events to a subagent / subgraph / explicit namespace.\n * Defaults to the root namespace. Accepts a `Signal` so a `computed`\n * scope re-binds the subscription automatically.\n */\n target?: SelectorTarget | Signal<SelectorTarget>;\n /**\n * Gate the subscription. When `false`, no subscription is opened and\n * no events are delivered. Defaults to `true`. Accepts a `Signal`.\n */\n enabled?: boolean | Signal<boolean>;\n}\n\n/**\n * Side-effect counterpart to {@link injectChannel}. Instead of\n * returning a signal of buffered events, it invokes `onEvent` once per\n * event for as long as the owning component / service is alive — the\n * idiomatic place for analytics, logging, and other fire-and-forget\n * side effects.\n *\n * ```ts\n * injectChannelEffect(this.stream, [\"lifecycle\", \"tools\"], {\n * replay: false,\n * onEvent: (event) => sendAnalytics(event),\n * onError: (error) => logger.error(error),\n * });\n * ```\n *\n * Reactive `channels` / `target` / `enabled` signals re-bind the\n * subscription when they change. The underlying subscription is shared\n * (ref-counted) with any matching {@link injectChannel} consumer.\n * `replay` defaults to `false` (live-only); events buffered before the\n * effect attaches are not re-delivered.\n *\n * Must be called from an injection context (component / directive /\n * service field initializer, or `runInInjectionContext(...)`).\n */\nexport function injectChannelEffect(\n stream: AnyStream,\n channels: readonly Channel[] | Signal<readonly Channel[]>,\n options: InjectChannelEffectOptions\n): void {\n const target = options.target as SelectorTarget | Signal<SelectorTarget>;\n resolveSubagentNamespaceFor(stream, target);\n const destroyRef = inject(DestroyRef);\n\n const enabledOf = (): boolean => {\n const value = options.enabled;\n if (value == null) return true;\n return isSignal(value) ? (value as Signal<boolean>)() : value;\n };\n const channelsOf = (): readonly Channel[] =>\n isSignal(channels)\n ? (channels as Signal<readonly Channel[]>)()\n : (channels as readonly Channel[]);\n const targetOf = (): SelectorTarget =>\n isSignal(target) ? (target as Signal<SelectorTarget>)() : target;\n\n const keyOf = (): string => {\n const enabled = enabledOf();\n const sortedChannels = [...channelsOf()].sort().join(\",\");\n const namespace = resolveNamespace(targetOf());\n return `${enabled ? \"on\" : \"off\"}|${sortedChannels}|${namespaceKey(namespace)}`;\n };\n\n let dispose: (() => void) | undefined;\n let currentKey: string | undefined;\n\n const detach = () => {\n dispose?.();\n dispose = undefined;\n };\n\n const attach = (nextKey: string): void => {\n if (nextKey === currentKey) return;\n detach();\n currentKey = nextKey;\n if (!enabledOf()) return;\n const registry = getRegistry(stream);\n if (registry == null) return;\n dispose = acquireChannelEffect(\n registry,\n channelsOf(),\n resolveNamespace(targetOf()),\n {\n replay: options.replay,\n bufferSize: options.bufferSize,\n // Read callbacks lazily so a fresh closure never re-acquires.\n onEvent: (event) => options.onEvent(event),\n onError: options.onError\n ? (error) => options.onError?.(error)\n : undefined,\n }\n );\n };\n\n // Acquire synchronously so the subscription is live before a user can\n // submit and emit short-lived events.\n attach(keyOf());\n destroyRef.onDestroy(detach);\n\n effect(() => {\n const nextKey = keyOf();\n untracked(() => attach(nextKey));\n });\n}\n\n/**\n * Subscribe to a scoped audio-media stream. Each handle is yielded\n * on its first matching `content-block-start`, exposes\n * `.partialBytes` for live access, settles `.blob` / `.objectURL` /\n * `.transcript` on `message-finish`, and surfaces errors via\n * `.error`.\n *\n * Pair with `injectMediaUrl` to turn a handle into an `<audio src>`.\n */\nexport function injectAudio(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<AudioMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"audio\"\n );\n return injectProjection<AudioMedia[]>(\n getRegistry(stream),\n () => audioProjection(namespace()),\n key,\n EMPTY_AUDIO\n );\n}\n\nconst EMPTY_AUDIO: AudioMedia[] = [];\n\n/**\n * Subscribe to a scoped image-media stream. Pair with\n * `injectMediaUrl` for `<img src>`.\n */\nexport function injectImages(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<ImageMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"images\"\n );\n return injectProjection<ImageMedia[]>(\n getRegistry(stream),\n () => imagesProjection(namespace()),\n key,\n EMPTY_IMAGES\n );\n}\n\nconst EMPTY_IMAGES: ImageMedia[] = [];\n\n/**\n * Subscribe to a scoped video-media stream. Pair with\n * `injectMediaUrl` for `<video src>`.\n */\nexport function injectVideo(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<VideoMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"video\"\n );\n return injectProjection<VideoMedia[]>(\n getRegistry(stream),\n () => videoProjection(namespace()),\n key,\n EMPTY_VIDEO\n );\n}\n\nconst EMPTY_VIDEO: VideoMedia[] = [];\n\n/**\n * Subscribe to a scoped file-media stream. Pair with\n * `injectMediaUrl` for an `<a download href>` target.\n */\nexport function injectFiles(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<FileMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"files\"\n );\n return injectProjection<FileMedia[]>(\n getRegistry(stream),\n () => filesProjection(namespace()),\n key,\n EMPTY_FILES\n );\n}\n\nconst EMPTY_FILES: FileMedia[] = [];\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { AnyStream, UseStreamReturn } from "./use-stream.cjs";
2
- import { AssembledToolCall, AudioMedia, Channel, ChannelProjectionOptions, Event, FileMedia, ImageMedia, InferStateType, InferToolCalls, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, VideoMedia } from "@langchain/langgraph-sdk/stream";
2
+ import { AssembledToolCall, AudioMedia, Channel, ChannelEffectOptions, ChannelProjectionOptions, Event, FileMedia, ImageMedia, InferStateType, InferToolCalls, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, VideoMedia } from "@langchain/langgraph-sdk/stream";
3
3
  import { Signal } from "@angular/core";
4
4
  import { BaseMessage } from "@langchain/core/messages";
5
5
 
@@ -92,6 +92,49 @@ declare function injectExtension<T = unknown>(stream: AnyStream, name: string, t
92
92
  */
93
93
  type InjectChannelOptions = ChannelProjectionOptions;
94
94
  declare function injectChannel(stream: AnyStream, channels: readonly Channel[], target?: SelectorTarget | Signal<SelectorTarget>, options?: InjectChannelOptions): Signal<Event[]>;
95
+ /**
96
+ * Options for {@link injectChannelEffect}. Extends the projection
97
+ * options (`bufferSize`, `replay`) with the per-event callback, an
98
+ * optional error sink, a `target` scope, and an `enabled` gate.
99
+ */
100
+ interface InjectChannelEffectOptions extends ChannelEffectOptions {
101
+ /**
102
+ * Scope events to a subagent / subgraph / explicit namespace.
103
+ * Defaults to the root namespace. Accepts a `Signal` so a `computed`
104
+ * scope re-binds the subscription automatically.
105
+ */
106
+ target?: SelectorTarget | Signal<SelectorTarget>;
107
+ /**
108
+ * Gate the subscription. When `false`, no subscription is opened and
109
+ * no events are delivered. Defaults to `true`. Accepts a `Signal`.
110
+ */
111
+ enabled?: boolean | Signal<boolean>;
112
+ }
113
+ /**
114
+ * Side-effect counterpart to {@link injectChannel}. Instead of
115
+ * returning a signal of buffered events, it invokes `onEvent` once per
116
+ * event for as long as the owning component / service is alive — the
117
+ * idiomatic place for analytics, logging, and other fire-and-forget
118
+ * side effects.
119
+ *
120
+ * ```ts
121
+ * injectChannelEffect(this.stream, ["lifecycle", "tools"], {
122
+ * replay: false,
123
+ * onEvent: (event) => sendAnalytics(event),
124
+ * onError: (error) => logger.error(error),
125
+ * });
126
+ * ```
127
+ *
128
+ * Reactive `channels` / `target` / `enabled` signals re-bind the
129
+ * subscription when they change. The underlying subscription is shared
130
+ * (ref-counted) with any matching {@link injectChannel} consumer.
131
+ * `replay` defaults to `false` (live-only); events buffered before the
132
+ * effect attaches are not re-delivered.
133
+ *
134
+ * Must be called from an injection context (component / directive /
135
+ * service field initializer, or `runInInjectionContext(...)`).
136
+ */
137
+ declare function injectChannelEffect(stream: AnyStream, channels: readonly Channel[] | Signal<readonly Channel[]>, options: InjectChannelEffectOptions): void;
95
138
  /**
96
139
  * Subscribe to a scoped audio-media stream. Each handle is yielded
97
140
  * on its first matching `content-block-start`, exposes
@@ -118,5 +161,5 @@ declare function injectVideo(stream: AnyStream, target?: SelectorTarget | Signal
118
161
  */
119
162
  declare function injectFiles(stream: AnyStream, target?: SelectorTarget | Signal<SelectorTarget>): Signal<FileMedia[]>;
120
163
  //#endregion
121
- export { SelectorTarget, injectAudio, injectChannel, injectExtension, injectFiles, injectImages, injectMessages, injectToolCalls, injectValues, injectVideo };
164
+ export { InjectChannelEffectOptions, SelectorTarget, injectAudio, injectChannel, injectChannelEffect, injectExtension, injectFiles, injectImages, injectMessages, injectToolCalls, injectValues, injectVideo };
122
165
  //# sourceMappingURL=selectors.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"selectors.d.cts","names":[],"sources":["../src/selectors.ts"],"mappings":";;;;;;;;AA+ByB;;;;KASpB,YAAA,6BAAyC,eAAA,CAC5C,SAAA;;;;;AAoBF;;;;;;;;;KAAY,cAAA;EAIN,SAAA;AAAA,IACF,yBAAA,GACA,yBAAA;;;;;;;;;;;;;;;;iBAuGY,cAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,WAAA;;;AA4BV;;;iBAAgB,eAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,iBAAA;AAAA,iBACM,eAAA,GAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,cAAA,CAAe,CAAA;;;;;;;;;;;;;;;iBAyCT,YAAA,0BAAA,CACd,MAAA,EAAQ,YAAA,CAAa,SAAA,IACpB,MAAA,CAAO,SAAA;AAAA,iBACM,YAAA,GAAA,CAAgB,MAAA,EAAQ,SAAA,GAAY,MAAA,CAAO,cAAA,CAAe,CAAA;AAAA,iBAC1D,YAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,EAAQ,cAAA,GAAiB,MAAA,CAAO,cAAA,GAChC,OAAA;EAAY,WAAA;AAAA,IACX,MAAA,CAAO,CAAA;;;;;;;;;;iBAgCM,eAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,IAAA,UACA,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,CAAA;;;;;;;;;;;;KAwBE,oBAAA,GAAuB,wBAAA;AAAA,iBAEnB,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,QAAA,WAAmB,OAAA,IACnB,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,GACjC,OAAA,GAAU,oBAAA,GACT,MAAA,CAAO,KAAA;;;;;;;;;;iBA0BM,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,UAAA;;;;;iBAmBM,YAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,UAAA;AA3HV;;;;AAAA,iBA8IgB,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,UAAA;;;;;iBAmBM,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,SAAA"}
1
+ {"version":3,"file":"selectors.d.cts","names":[],"sources":["../src/selectors.ts"],"mappings":";;;;;;;;AAyCyB;;;;KASpB,YAAA,6BAAyC,eAAA,CAC5C,SAAA;;;;;AAoBF;;;;;;;;;KAAY,cAAA;EAIN,SAAA;AAAA,IACF,yBAAA,GACA,yBAAA;;;;;;;;;;;;;;;;iBAuGY,cAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,WAAA;;;AA4BV;;;iBAAgB,eAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,iBAAA;AAAA,iBACM,eAAA,GAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,cAAA,CAAe,CAAA;;;;;;;;;;;;;;;iBAyCT,YAAA,0BAAA,CACd,MAAA,EAAQ,YAAA,CAAa,SAAA,IACpB,MAAA,CAAO,SAAA;AAAA,iBACM,YAAA,GAAA,CAAgB,MAAA,EAAQ,SAAA,GAAY,MAAA,CAAO,cAAA,CAAe,CAAA;AAAA,iBAC1D,YAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,EAAQ,cAAA,GAAiB,MAAA,CAAO,cAAA,GAChC,OAAA;EAAY,WAAA;AAAA,IACX,MAAA,CAAO,CAAA;;;;;;;;;;iBAgCM,eAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,IAAA,UACA,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,CAAA;;;;;;;;;;;;KAwBE,oBAAA,GAAuB,wBAAA;AAAA,iBAEnB,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,QAAA,WAAmB,OAAA,IACnB,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,GACjC,OAAA,GAAU,oBAAA,GACT,MAAA,CAAO,KAAA;;;;;;UAsBO,0BAAA,SAAmC,oBAAA;EA/F3C;;;;;EAqGP,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA;EArGzB;;;AACV;EAyGE,OAAA,aAAoB,MAAA;AAAA;;;;;;;;;;;;;;;AAxGtB;;;;;;;;;;iBAmIgB,mBAAA,CACd,MAAA,EAAQ,SAAA,EACR,QAAA,WAAmB,OAAA,KAAY,MAAA,UAAgB,OAAA,KAC/C,OAAA,EAAS,0BAAA;;;;;;;;;;iBA4EK,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,UAAA;;;;AAjLV;iBAoMgB,YAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,UAAA;;;;;iBAmBM,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,UAAA;;;;;iBAmBM,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,SAAA"}
@@ -1,6 +1,6 @@
1
1
  import { AnyStream, UseStreamReturn } from "./use-stream.js";
2
2
  import { Signal } from "@angular/core";
3
- import { AssembledToolCall, AudioMedia, Channel, ChannelProjectionOptions, Event, FileMedia, ImageMedia, InferStateType, InferToolCalls, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, VideoMedia } from "@langchain/langgraph-sdk/stream";
3
+ import { AssembledToolCall, AudioMedia, Channel, ChannelEffectOptions, ChannelProjectionOptions, Event, FileMedia, ImageMedia, InferStateType, InferToolCalls, SubagentDiscoverySnapshot, SubgraphDiscoverySnapshot, VideoMedia } from "@langchain/langgraph-sdk/stream";
4
4
  import { BaseMessage } from "@langchain/core/messages";
5
5
 
6
6
  //#region src/selectors.d.ts
@@ -92,6 +92,49 @@ declare function injectExtension<T = unknown>(stream: AnyStream, name: string, t
92
92
  */
93
93
  type InjectChannelOptions = ChannelProjectionOptions;
94
94
  declare function injectChannel(stream: AnyStream, channels: readonly Channel[], target?: SelectorTarget | Signal<SelectorTarget>, options?: InjectChannelOptions): Signal<Event[]>;
95
+ /**
96
+ * Options for {@link injectChannelEffect}. Extends the projection
97
+ * options (`bufferSize`, `replay`) with the per-event callback, an
98
+ * optional error sink, a `target` scope, and an `enabled` gate.
99
+ */
100
+ interface InjectChannelEffectOptions extends ChannelEffectOptions {
101
+ /**
102
+ * Scope events to a subagent / subgraph / explicit namespace.
103
+ * Defaults to the root namespace. Accepts a `Signal` so a `computed`
104
+ * scope re-binds the subscription automatically.
105
+ */
106
+ target?: SelectorTarget | Signal<SelectorTarget>;
107
+ /**
108
+ * Gate the subscription. When `false`, no subscription is opened and
109
+ * no events are delivered. Defaults to `true`. Accepts a `Signal`.
110
+ */
111
+ enabled?: boolean | Signal<boolean>;
112
+ }
113
+ /**
114
+ * Side-effect counterpart to {@link injectChannel}. Instead of
115
+ * returning a signal of buffered events, it invokes `onEvent` once per
116
+ * event for as long as the owning component / service is alive — the
117
+ * idiomatic place for analytics, logging, and other fire-and-forget
118
+ * side effects.
119
+ *
120
+ * ```ts
121
+ * injectChannelEffect(this.stream, ["lifecycle", "tools"], {
122
+ * replay: false,
123
+ * onEvent: (event) => sendAnalytics(event),
124
+ * onError: (error) => logger.error(error),
125
+ * });
126
+ * ```
127
+ *
128
+ * Reactive `channels` / `target` / `enabled` signals re-bind the
129
+ * subscription when they change. The underlying subscription is shared
130
+ * (ref-counted) with any matching {@link injectChannel} consumer.
131
+ * `replay` defaults to `false` (live-only); events buffered before the
132
+ * effect attaches are not re-delivered.
133
+ *
134
+ * Must be called from an injection context (component / directive /
135
+ * service field initializer, or `runInInjectionContext(...)`).
136
+ */
137
+ declare function injectChannelEffect(stream: AnyStream, channels: readonly Channel[] | Signal<readonly Channel[]>, options: InjectChannelEffectOptions): void;
95
138
  /**
96
139
  * Subscribe to a scoped audio-media stream. Each handle is yielded
97
140
  * on its first matching `content-block-start`, exposes
@@ -118,5 +161,5 @@ declare function injectVideo(stream: AnyStream, target?: SelectorTarget | Signal
118
161
  */
119
162
  declare function injectFiles(stream: AnyStream, target?: SelectorTarget | Signal<SelectorTarget>): Signal<FileMedia[]>;
120
163
  //#endregion
121
- export { SelectorTarget, injectAudio, injectChannel, injectExtension, injectFiles, injectImages, injectMessages, injectToolCalls, injectValues, injectVideo };
164
+ export { InjectChannelEffectOptions, SelectorTarget, injectAudio, injectChannel, injectChannelEffect, injectExtension, injectFiles, injectImages, injectMessages, injectToolCalls, injectValues, injectVideo };
122
165
  //# sourceMappingURL=selectors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"selectors.d.ts","names":[],"sources":["../src/selectors.ts"],"mappings":";;;;;;;;AA+ByB;;;;KASpB,YAAA,6BAAyC,eAAA,CAC5C,SAAA;;;;;AAoBF;;;;;;;;;KAAY,cAAA;EAIN,SAAA;AAAA,IACF,yBAAA,GACA,yBAAA;;;;;;;;;;;;;;;;iBAuGY,cAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,WAAA;;;AA4BV;;;iBAAgB,eAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,iBAAA;AAAA,iBACM,eAAA,GAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,cAAA,CAAe,CAAA;;;;;;;;;;;;;;;iBAyCT,YAAA,0BAAA,CACd,MAAA,EAAQ,YAAA,CAAa,SAAA,IACpB,MAAA,CAAO,SAAA;AAAA,iBACM,YAAA,GAAA,CAAgB,MAAA,EAAQ,SAAA,GAAY,MAAA,CAAO,cAAA,CAAe,CAAA;AAAA,iBAC1D,YAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,EAAQ,cAAA,GAAiB,MAAA,CAAO,cAAA,GAChC,OAAA;EAAY,WAAA;AAAA,IACX,MAAA,CAAO,CAAA;;;;;;;;;;iBAgCM,eAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,IAAA,UACA,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,CAAA;;;;;;;;;;;;KAwBE,oBAAA,GAAuB,wBAAA;AAAA,iBAEnB,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,QAAA,WAAmB,OAAA,IACnB,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,GACjC,OAAA,GAAU,oBAAA,GACT,MAAA,CAAO,KAAA;;;;;;;;;;iBA0BM,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,UAAA;;;;;iBAmBM,YAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,UAAA;AA3HV;;;;AAAA,iBA8IgB,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,UAAA;;;;;iBAmBM,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,SAAA"}
1
+ {"version":3,"file":"selectors.d.ts","names":[],"sources":["../src/selectors.ts"],"mappings":";;;;;;;;AAyCyB;;;;KASpB,YAAA,6BAAyC,eAAA,CAC5C,SAAA;;;;;AAoBF;;;;;;;;;KAAY,cAAA;EAIN,SAAA;AAAA,IACF,yBAAA,GACA,yBAAA;;;;;;;;;;;;;;;;iBAuGY,cAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,WAAA;;;AA4BV;;;iBAAgB,eAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,iBAAA;AAAA,iBACM,eAAA,GAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,cAAA,CAAe,CAAA;;;;;;;;;;;;;;;iBAyCT,YAAA,0BAAA,CACd,MAAA,EAAQ,YAAA,CAAa,SAAA,IACpB,MAAA,CAAO,SAAA;AAAA,iBACM,YAAA,GAAA,CAAgB,MAAA,EAAQ,SAAA,GAAY,MAAA,CAAO,cAAA,CAAe,CAAA;AAAA,iBAC1D,YAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,EAAQ,cAAA,GAAiB,MAAA,CAAO,cAAA,GAChC,OAAA;EAAY,WAAA;AAAA,IACX,MAAA,CAAO,CAAA;;;;;;;;;;iBAgCM,eAAA,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,IAAA,UACA,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,CAAA;;;;;;;;;;;;KAwBE,oBAAA,GAAuB,wBAAA;AAAA,iBAEnB,aAAA,CACd,MAAA,EAAQ,SAAA,EACR,QAAA,WAAmB,OAAA,IACnB,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,GACjC,OAAA,GAAU,oBAAA,GACT,MAAA,CAAO,KAAA;;;;;;UAsBO,0BAAA,SAAmC,oBAAA;EA/F3C;;;;;EAqGP,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA;EArGzB;;;AACV;EAyGE,OAAA,aAAoB,MAAA;AAAA;;;;;;;;;;;;;;;AAxGtB;;;;;;;;;;iBAmIgB,mBAAA,CACd,MAAA,EAAQ,SAAA,EACR,QAAA,WAAmB,OAAA,KAAY,MAAA,UAAgB,OAAA,KAC/C,OAAA,EAAS,0BAAA;;;;;;;;;;iBA4EK,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,UAAA;;;;AAjLV;iBAoMgB,YAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,UAAA;;;;;iBAmBM,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,UAAA;;;;;iBAmBM,WAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,GAAS,cAAA,GAAiB,MAAA,CAAO,cAAA,IAChC,MAAA,CAAO,SAAA"}
package/dist/selectors.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { STREAM_CONTROLLER, getRegistry } from "./use-stream.js";
2
2
  import { injectProjection } from "./inject-projection.js";
3
- import { computed, effect, isSignal } from "@angular/core";
4
- import { NAMESPACE_SEPARATOR, audioProjection, channelProjection, extensionProjection, filesProjection, imagesProjection, messagesProjection, toolCallsProjection, valuesProjection, videoProjection } from "@langchain/langgraph-sdk/stream";
3
+ import { DestroyRef, computed, effect, inject, isSignal, untracked } from "@angular/core";
4
+ import { NAMESPACE_SEPARATOR, acquireChannelEffect, audioProjection, channelProjection, extensionProjection, filesProjection, imagesProjection, messagesProjection, toolCallsProjection, valuesProjection, videoProjection } from "@langchain/langgraph-sdk/stream";
5
5
  //#region src/selectors.ts
6
6
  const EMPTY_NAMESPACE = [];
7
7
  function resolveNamespace(target) {
@@ -124,6 +124,74 @@ function injectChannel(stream, channels, target, options) {
124
124
  }
125
125
  const EMPTY_EVENTS = [];
126
126
  /**
127
+ * Side-effect counterpart to {@link injectChannel}. Instead of
128
+ * returning a signal of buffered events, it invokes `onEvent` once per
129
+ * event for as long as the owning component / service is alive — the
130
+ * idiomatic place for analytics, logging, and other fire-and-forget
131
+ * side effects.
132
+ *
133
+ * ```ts
134
+ * injectChannelEffect(this.stream, ["lifecycle", "tools"], {
135
+ * replay: false,
136
+ * onEvent: (event) => sendAnalytics(event),
137
+ * onError: (error) => logger.error(error),
138
+ * });
139
+ * ```
140
+ *
141
+ * Reactive `channels` / `target` / `enabled` signals re-bind the
142
+ * subscription when they change. The underlying subscription is shared
143
+ * (ref-counted) with any matching {@link injectChannel} consumer.
144
+ * `replay` defaults to `false` (live-only); events buffered before the
145
+ * effect attaches are not re-delivered.
146
+ *
147
+ * Must be called from an injection context (component / directive /
148
+ * service field initializer, or `runInInjectionContext(...)`).
149
+ */
150
+ function injectChannelEffect(stream, channels, options) {
151
+ const target = options.target;
152
+ resolveSubagentNamespaceFor(stream, target);
153
+ const destroyRef = inject(DestroyRef);
154
+ const enabledOf = () => {
155
+ const value = options.enabled;
156
+ if (value == null) return true;
157
+ return isSignal(value) ? value() : value;
158
+ };
159
+ const channelsOf = () => isSignal(channels) ? channels() : channels;
160
+ const targetOf = () => isSignal(target) ? target() : target;
161
+ const keyOf = () => {
162
+ const enabled = enabledOf();
163
+ const sortedChannels = [...channelsOf()].sort().join(",");
164
+ const namespace = resolveNamespace(targetOf());
165
+ return `${enabled ? "on" : "off"}|${sortedChannels}|${namespaceKey(namespace)}`;
166
+ };
167
+ let dispose;
168
+ let currentKey;
169
+ const detach = () => {
170
+ dispose?.();
171
+ dispose = void 0;
172
+ };
173
+ const attach = (nextKey) => {
174
+ if (nextKey === currentKey) return;
175
+ detach();
176
+ currentKey = nextKey;
177
+ if (!enabledOf()) return;
178
+ const registry = getRegistry(stream);
179
+ if (registry == null) return;
180
+ dispose = acquireChannelEffect(registry, channelsOf(), resolveNamespace(targetOf()), {
181
+ replay: options.replay,
182
+ bufferSize: options.bufferSize,
183
+ onEvent: (event) => options.onEvent(event),
184
+ onError: options.onError ? (error) => options.onError?.(error) : void 0
185
+ });
186
+ };
187
+ attach(keyOf());
188
+ destroyRef.onDestroy(detach);
189
+ effect(() => {
190
+ const nextKey = keyOf();
191
+ untracked(() => attach(nextKey));
192
+ });
193
+ }
194
+ /**
127
195
  * Subscribe to a scoped audio-media stream. Each handle is yielded
128
196
  * on its first matching `content-block-start`, exposes
129
197
  * `.partialBytes` for live access, settles `.blob` / `.objectURL` /
@@ -165,6 +233,6 @@ function injectFiles(stream, target) {
165
233
  }
166
234
  const EMPTY_FILES = [];
167
235
  //#endregion
168
- export { injectAudio, injectChannel, injectExtension, injectFiles, injectImages, injectMessages, injectToolCalls, injectValues, injectVideo };
236
+ export { injectAudio, injectChannel, injectChannelEffect, injectExtension, injectFiles, injectImages, injectMessages, injectToolCalls, injectValues, injectVideo };
169
237
 
170
238
  //# sourceMappingURL=selectors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"selectors.js","names":[],"sources":["../src/selectors.ts"],"sourcesContent":["import { computed, effect, isSignal, type Signal } from \"@angular/core\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport {\n NAMESPACE_SEPARATOR,\n audioProjection,\n channelProjection,\n extensionProjection,\n filesProjection,\n imagesProjection,\n messagesProjection,\n toolCallsProjection,\n valuesProjection,\n videoProjection,\n type AssembledToolCall,\n type AudioMedia,\n type Channel,\n type ChannelProjectionOptions,\n type Event,\n type FileMedia,\n type ImageMedia,\n type InferToolCalls,\n type InferStateType,\n type SubagentDiscoverySnapshot,\n type SubgraphDiscoverySnapshot,\n type VideoMedia,\n} from \"@langchain/langgraph-sdk/stream\";\nimport {\n getRegistry,\n STREAM_CONTROLLER,\n type AnyStream,\n type UseStreamReturn,\n} from \"./use-stream.js\";\nimport { injectProjection } from \"./inject-projection.js\";\n\n/**\n * Selector primitives don't need to carry `InterruptType` /\n * `ConfigurableType`. Parameterising on `StateType` alone lets\n * callers with a full `injectStream<S, I, C>()` handle pass it in\n * without redeclaring those generics at every call site.\n */\ntype StreamHandle<StateType extends object> = UseStreamReturn<\n StateType,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any\n>;\n\n/**\n * What a selector primitive can be targeted at. Callers can pass:\n * - `undefined` / `null` — root namespace (served by the always-on\n * root store — no extra subscription);\n * - a {@link SubagentDiscoverySnapshot} (`stream.subagents().get(...)`);\n * - a {@link SubgraphDiscoverySnapshot} (`stream.subgraphs().get(...)`);\n * - an explicit `{ namespace: string[] }`;\n * - a raw `string[]` escape hatch.\n *\n * Selectors also accept a `Signal<SelectorTarget>` so callers can\n * feed a `computed(() => ...)` and have the projection rebind\n * automatically.\n */\nexport type SelectorTarget =\n | undefined\n | null\n | readonly string[]\n | { namespace: readonly string[] }\n | SubagentDiscoverySnapshot\n | SubgraphDiscoverySnapshot;\n\nconst EMPTY_NAMESPACE: readonly string[] = [];\n\nfunction resolveNamespace(target: SelectorTarget): readonly string[] {\n if (target == null) return EMPTY_NAMESPACE;\n if (Array.isArray(target)) return target as readonly string[];\n const obj = target as { namespace?: readonly string[] };\n return obj.namespace ?? EMPTY_NAMESPACE;\n}\n\nfunction isRoot(namespace: readonly string[]): boolean {\n return namespace.length === 0;\n}\n\n/**\n * If `target` is a subagent snapshot still on its default\n * `tools:<toolCallId>` namespace, return that tool-call id. See the\n * React selectors for the rationale (deep-agent subagents execute under\n * a distinct `tools:<uuid>` namespace resolved lazily from history).\n */\nfunction subagentNeedingNamespace(target: SelectorTarget): string | null {\n if (target == null || Array.isArray(target)) return null;\n const obj = target as { id?: unknown; namespace?: readonly string[] };\n if (typeof obj.id !== \"string\" || !Array.isArray(obj.namespace)) return null;\n if (obj.namespace.length === 1 && obj.namespace[0] === `tools:${obj.id}`) {\n return obj.id;\n }\n return null;\n}\n\n/**\n * Lazily resolve a subagent's execution namespace on first scoped use.\n * Must be called from an injection context (as the selector primitives\n * are). A `Signal` target re-evaluates via an `effect`; a static target\n * resolves once. The controller de-dupes and skips already-promoted\n * ids.\n */\nfunction resolveSubagentNamespaceFor(\n stream: AnyStream,\n target: SelectorTarget | Signal<SelectorTarget>\n): void {\n const controller = stream[STREAM_CONTROLLER];\n if (isSignal(target)) {\n effect(() => {\n const id = subagentNeedingNamespace((target as Signal<SelectorTarget>)());\n if (id != null) void controller.resolveSubagentNamespace(id);\n });\n return;\n }\n const id = subagentNeedingNamespace(target as SelectorTarget);\n if (id != null) void controller.resolveSubagentNamespace(id);\n}\n\nfunction namespaceKey(namespace: readonly string[]): string {\n return namespace.join(NAMESPACE_SEPARATOR);\n}\n\n/**\n * Resolve a target or target-signal into a reactive\n * `[namespace, key]` pair. The helper returns plain signals so\n * `injectProjection` can track them via its internal effect.\n */\nfunction normalizeTarget(\n target: SelectorTarget | Signal<SelectorTarget>,\n prefix: string\n): {\n namespace: Signal<readonly string[]>;\n key: Signal<string>;\n isRootSignal: Signal<boolean>;\n} {\n if (isSignal(target)) {\n const namespace = computed(() =>\n resolveNamespace((target as Signal<SelectorTarget>)())\n );\n const key = computed(() => `${prefix}|${namespaceKey(namespace())}`);\n const isRootSignal = computed(() => isRoot(namespace()));\n return { namespace, key, isRootSignal };\n }\n const ns = resolveNamespace(target as SelectorTarget);\n const staticKey = `${prefix}|${namespaceKey(ns)}`;\n return {\n namespace: computed(() => ns),\n key: computed(() => staticKey),\n isRootSignal: computed(() => isRoot(ns)),\n };\n}\n\n/**\n * Subscribe to a scoped `messages` stream.\n *\n * Contract:\n * - At the root (no `target`) this returns `stream.messages` — the\n * always-on root projection; no extra subscription is opened.\n * - For any non-root namespace, call-time triggers a ref-counted\n * `messages` subscription scoped to that namespace. The\n * subscription is released automatically when the calling\n * component / service is destroyed (and the registry closes the\n * underlying server subscription when the last consumer leaves).\n *\n * Messages are always `BaseMessage` class instances from\n * `@langchain/core/messages`.\n */\nexport function injectMessages(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<BaseMessage[]> {\n resolveSubagentNamespaceFor(\n stream,\n target as SelectorTarget | Signal<SelectorTarget>\n );\n const { namespace, key, isRootSignal } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"messages\"\n );\n const registry = computed(() =>\n isRootSignal() ? null : getRegistry(stream)\n );\n const scoped = injectProjection<BaseMessage[]>(\n registry,\n () => messagesProjection(namespace()),\n key,\n EMPTY_MESSAGES\n );\n return computed(() => (isRootSignal() ? stream.messages() : scoped()));\n}\n\nconst EMPTY_MESSAGES: BaseMessage[] = [];\n\n/**\n * Subscribe to a scoped `tools` (tool-call) stream. Same target and\n * lifecycle rules as {@link injectMessages}; at the root this returns\n * `stream.toolCalls` directly.\n */\nexport function injectToolCalls(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<AssembledToolCall[]>;\nexport function injectToolCalls<T>(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<InferToolCalls<T>[]>;\nexport function injectToolCalls(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<AssembledToolCall[]> {\n resolveSubagentNamespaceFor(\n stream,\n target as SelectorTarget | Signal<SelectorTarget>\n );\n const { namespace, key, isRootSignal } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"toolCalls\"\n );\n const registry = computed(() =>\n isRootSignal() ? null : getRegistry(stream)\n );\n const scoped = injectProjection<AssembledToolCall[]>(\n registry,\n () => toolCallsProjection(namespace()),\n key,\n EMPTY_TOOLCALLS\n );\n return computed(() => (isRootSignal() ? stream.toolCalls() : scoped()));\n}\n\nconst EMPTY_TOOLCALLS: AssembledToolCall[] = [];\n\n/**\n * Subscribe to a scoped `values` stream — the most recent state\n * payload for a namespace. At the root returns `stream.values`.\n *\n * Typing:\n * - **Root** (`injectValues(stream)`): returns the `StateType`\n * declared on `injectStream<State>()` — non-nullable (the root\n * snapshot always has values, falling back to `initialValues ??\n * {}`).\n * - **Scoped** (`injectValues(stream, target)`): scoped payloads can\n * differ from the root state; callers should annotate the expected\n * shape explicitly (`injectValues<SubagentState>(stream, sub)`).\n * Defaults to `unknown` when not annotated.\n */\nexport function injectValues<StateType extends object>(\n stream: StreamHandle<StateType>\n): Signal<StateType>;\nexport function injectValues<T>(stream: AnyStream): Signal<InferStateType<T>>;\nexport function injectValues<T = unknown>(\n stream: AnyStream,\n target: SelectorTarget | Signal<SelectorTarget>,\n options?: { messagesKey?: string }\n): Signal<T | undefined>;\nexport function injectValues(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>,\n options?: { messagesKey?: string }\n): Signal<unknown> {\n const messagesKey = options?.messagesKey ?? \"messages\";\n const { namespace, key, isRootSignal } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n `values|${messagesKey}`\n );\n const registry = computed(() =>\n isRootSignal() ? null : getRegistry(stream)\n );\n const scoped = injectProjection<unknown>(\n registry,\n () => valuesProjection<unknown>(namespace(), messagesKey),\n key,\n undefined\n );\n return computed(() => (isRootSignal() ? stream.values() : scoped()));\n}\n\n/**\n * Subscribe to a `custom:<name>` stream extension — the most recent\n * payload emitted by the transformer, scoped to the target namespace.\n *\n * Returns only the latest value and resumes across serial runs, so it is\n * ideal for \"current state\" panels (progress, score, status). When you\n * need the full history of events rather than just the latest payload,\n * use {@link injectChannel} instead.\n */\nexport function injectExtension<T = unknown>(\n stream: AnyStream,\n name: string,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<T | undefined> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n `extension|${name}`\n );\n return injectProjection<T | undefined>(\n getRegistry(stream),\n () => extensionProjection<T>(name, namespace()),\n key,\n undefined\n );\n}\n\n/**\n * Raw-events escape hatch. Subscribes to one or more channels at a\n * namespace and returns a bounded buffer of raw protocol events.\n *\n * The buffer keeps accumulating across serial runs for the lifetime of\n * the thread, so this is the hook to use for an event log / stream of a\n * custom channel (e.g. `[\"custom:redaction-stats\"]`). When you only need\n * the latest payload of a single `custom:<name>` channel, prefer\n * {@link injectExtension}. For the common message/tool/value cases prefer\n * {@link injectMessages} / {@link injectToolCalls} / {@link injectValues}.\n */\nexport type InjectChannelOptions = ChannelProjectionOptions;\n\nexport function injectChannel(\n stream: AnyStream,\n channels: readonly Channel[],\n target?: SelectorTarget | Signal<SelectorTarget>,\n options?: InjectChannelOptions\n): Signal<Event[]> {\n const sortedChannels = [...channels].sort().join(\",\");\n const prefix = `channel|${options?.bufferSize ?? \"default\"}|${(options?.replay ?? true) ? \"replay\" : \"live\"}|${sortedChannels}`;\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n prefix\n );\n return injectProjection<Event[]>(\n getRegistry(stream),\n () => channelProjection(channels, namespace(), options),\n key,\n EMPTY_EVENTS\n );\n}\n\nconst EMPTY_EVENTS: Event[] = [];\n\n/**\n * Subscribe to a scoped audio-media stream. Each handle is yielded\n * on its first matching `content-block-start`, exposes\n * `.partialBytes` for live access, settles `.blob` / `.objectURL` /\n * `.transcript` on `message-finish`, and surfaces errors via\n * `.error`.\n *\n * Pair with `injectMediaUrl` to turn a handle into an `<audio src>`.\n */\nexport function injectAudio(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<AudioMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"audio\"\n );\n return injectProjection<AudioMedia[]>(\n getRegistry(stream),\n () => audioProjection(namespace()),\n key,\n EMPTY_AUDIO\n );\n}\n\nconst EMPTY_AUDIO: AudioMedia[] = [];\n\n/**\n * Subscribe to a scoped image-media stream. Pair with\n * `injectMediaUrl` for `<img src>`.\n */\nexport function injectImages(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<ImageMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"images\"\n );\n return injectProjection<ImageMedia[]>(\n getRegistry(stream),\n () => imagesProjection(namespace()),\n key,\n EMPTY_IMAGES\n );\n}\n\nconst EMPTY_IMAGES: ImageMedia[] = [];\n\n/**\n * Subscribe to a scoped video-media stream. Pair with\n * `injectMediaUrl` for `<video src>`.\n */\nexport function injectVideo(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<VideoMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"video\"\n );\n return injectProjection<VideoMedia[]>(\n getRegistry(stream),\n () => videoProjection(namespace()),\n key,\n EMPTY_VIDEO\n );\n}\n\nconst EMPTY_VIDEO: VideoMedia[] = [];\n\n/**\n * Subscribe to a scoped file-media stream. Pair with\n * `injectMediaUrl` for an `<a download href>` target.\n */\nexport function injectFiles(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<FileMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"files\"\n );\n return injectProjection<FileMedia[]>(\n getRegistry(stream),\n () => filesProjection(namespace()),\n key,\n EMPTY_FILES\n );\n}\n\nconst EMPTY_FILES: FileMedia[] = [];\n"],"mappings":"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"}
1
+ {"version":3,"file":"selectors.js","names":[],"sources":["../src/selectors.ts"],"sourcesContent":["import {\n DestroyRef,\n computed,\n effect,\n inject,\n isSignal,\n untracked,\n type Signal,\n} from \"@angular/core\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport {\n NAMESPACE_SEPARATOR,\n acquireChannelEffect,\n audioProjection,\n channelProjection,\n extensionProjection,\n filesProjection,\n imagesProjection,\n messagesProjection,\n toolCallsProjection,\n valuesProjection,\n videoProjection,\n type AssembledToolCall,\n type AudioMedia,\n type Channel,\n type ChannelEffectOptions,\n type ChannelProjectionOptions,\n type Event,\n type FileMedia,\n type ImageMedia,\n type InferToolCalls,\n type InferStateType,\n type SubagentDiscoverySnapshot,\n type SubgraphDiscoverySnapshot,\n type VideoMedia,\n} from \"@langchain/langgraph-sdk/stream\";\nimport {\n getRegistry,\n STREAM_CONTROLLER,\n type AnyStream,\n type UseStreamReturn,\n} from \"./use-stream.js\";\nimport { injectProjection } from \"./inject-projection.js\";\n\n/**\n * Selector primitives don't need to carry `InterruptType` /\n * `ConfigurableType`. Parameterising on `StateType` alone lets\n * callers with a full `injectStream<S, I, C>()` handle pass it in\n * without redeclaring those generics at every call site.\n */\ntype StreamHandle<StateType extends object> = UseStreamReturn<\n StateType,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n any\n>;\n\n/**\n * What a selector primitive can be targeted at. Callers can pass:\n * - `undefined` / `null` — root namespace (served by the always-on\n * root store — no extra subscription);\n * - a {@link SubagentDiscoverySnapshot} (`stream.subagents().get(...)`);\n * - a {@link SubgraphDiscoverySnapshot} (`stream.subgraphs().get(...)`);\n * - an explicit `{ namespace: string[] }`;\n * - a raw `string[]` escape hatch.\n *\n * Selectors also accept a `Signal<SelectorTarget>` so callers can\n * feed a `computed(() => ...)` and have the projection rebind\n * automatically.\n */\nexport type SelectorTarget =\n | undefined\n | null\n | readonly string[]\n | { namespace: readonly string[] }\n | SubagentDiscoverySnapshot\n | SubgraphDiscoverySnapshot;\n\nconst EMPTY_NAMESPACE: readonly string[] = [];\n\nfunction resolveNamespace(target: SelectorTarget): readonly string[] {\n if (target == null) return EMPTY_NAMESPACE;\n if (Array.isArray(target)) return target as readonly string[];\n const obj = target as { namespace?: readonly string[] };\n return obj.namespace ?? EMPTY_NAMESPACE;\n}\n\nfunction isRoot(namespace: readonly string[]): boolean {\n return namespace.length === 0;\n}\n\n/**\n * If `target` is a subagent snapshot still on its default\n * `tools:<toolCallId>` namespace, return that tool-call id. See the\n * React selectors for the rationale (deep-agent subagents execute under\n * a distinct `tools:<uuid>` namespace resolved lazily from history).\n */\nfunction subagentNeedingNamespace(target: SelectorTarget): string | null {\n if (target == null || Array.isArray(target)) return null;\n const obj = target as { id?: unknown; namespace?: readonly string[] };\n if (typeof obj.id !== \"string\" || !Array.isArray(obj.namespace)) return null;\n if (obj.namespace.length === 1 && obj.namespace[0] === `tools:${obj.id}`) {\n return obj.id;\n }\n return null;\n}\n\n/**\n * Lazily resolve a subagent's execution namespace on first scoped use.\n * Must be called from an injection context (as the selector primitives\n * are). A `Signal` target re-evaluates via an `effect`; a static target\n * resolves once. The controller de-dupes and skips already-promoted\n * ids.\n */\nfunction resolveSubagentNamespaceFor(\n stream: AnyStream,\n target: SelectorTarget | Signal<SelectorTarget>\n): void {\n const controller = stream[STREAM_CONTROLLER];\n if (isSignal(target)) {\n effect(() => {\n const id = subagentNeedingNamespace((target as Signal<SelectorTarget>)());\n if (id != null) void controller.resolveSubagentNamespace(id);\n });\n return;\n }\n const id = subagentNeedingNamespace(target as SelectorTarget);\n if (id != null) void controller.resolveSubagentNamespace(id);\n}\n\nfunction namespaceKey(namespace: readonly string[]): string {\n return namespace.join(NAMESPACE_SEPARATOR);\n}\n\n/**\n * Resolve a target or target-signal into a reactive\n * `[namespace, key]` pair. The helper returns plain signals so\n * `injectProjection` can track them via its internal effect.\n */\nfunction normalizeTarget(\n target: SelectorTarget | Signal<SelectorTarget>,\n prefix: string\n): {\n namespace: Signal<readonly string[]>;\n key: Signal<string>;\n isRootSignal: Signal<boolean>;\n} {\n if (isSignal(target)) {\n const namespace = computed(() =>\n resolveNamespace((target as Signal<SelectorTarget>)())\n );\n const key = computed(() => `${prefix}|${namespaceKey(namespace())}`);\n const isRootSignal = computed(() => isRoot(namespace()));\n return { namespace, key, isRootSignal };\n }\n const ns = resolveNamespace(target as SelectorTarget);\n const staticKey = `${prefix}|${namespaceKey(ns)}`;\n return {\n namespace: computed(() => ns),\n key: computed(() => staticKey),\n isRootSignal: computed(() => isRoot(ns)),\n };\n}\n\n/**\n * Subscribe to a scoped `messages` stream.\n *\n * Contract:\n * - At the root (no `target`) this returns `stream.messages` — the\n * always-on root projection; no extra subscription is opened.\n * - For any non-root namespace, call-time triggers a ref-counted\n * `messages` subscription scoped to that namespace. The\n * subscription is released automatically when the calling\n * component / service is destroyed (and the registry closes the\n * underlying server subscription when the last consumer leaves).\n *\n * Messages are always `BaseMessage` class instances from\n * `@langchain/core/messages`.\n */\nexport function injectMessages(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<BaseMessage[]> {\n resolveSubagentNamespaceFor(\n stream,\n target as SelectorTarget | Signal<SelectorTarget>\n );\n const { namespace, key, isRootSignal } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"messages\"\n );\n const registry = computed(() =>\n isRootSignal() ? null : getRegistry(stream)\n );\n const scoped = injectProjection<BaseMessage[]>(\n registry,\n () => messagesProjection(namespace()),\n key,\n EMPTY_MESSAGES\n );\n return computed(() => (isRootSignal() ? stream.messages() : scoped()));\n}\n\nconst EMPTY_MESSAGES: BaseMessage[] = [];\n\n/**\n * Subscribe to a scoped `tools` (tool-call) stream. Same target and\n * lifecycle rules as {@link injectMessages}; at the root this returns\n * `stream.toolCalls` directly.\n */\nexport function injectToolCalls(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<AssembledToolCall[]>;\nexport function injectToolCalls<T>(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<InferToolCalls<T>[]>;\nexport function injectToolCalls(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<AssembledToolCall[]> {\n resolveSubagentNamespaceFor(\n stream,\n target as SelectorTarget | Signal<SelectorTarget>\n );\n const { namespace, key, isRootSignal } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"toolCalls\"\n );\n const registry = computed(() =>\n isRootSignal() ? null : getRegistry(stream)\n );\n const scoped = injectProjection<AssembledToolCall[]>(\n registry,\n () => toolCallsProjection(namespace()),\n key,\n EMPTY_TOOLCALLS\n );\n return computed(() => (isRootSignal() ? stream.toolCalls() : scoped()));\n}\n\nconst EMPTY_TOOLCALLS: AssembledToolCall[] = [];\n\n/**\n * Subscribe to a scoped `values` stream — the most recent state\n * payload for a namespace. At the root returns `stream.values`.\n *\n * Typing:\n * - **Root** (`injectValues(stream)`): returns the `StateType`\n * declared on `injectStream<State>()` — non-nullable (the root\n * snapshot always has values, falling back to `initialValues ??\n * {}`).\n * - **Scoped** (`injectValues(stream, target)`): scoped payloads can\n * differ from the root state; callers should annotate the expected\n * shape explicitly (`injectValues<SubagentState>(stream, sub)`).\n * Defaults to `unknown` when not annotated.\n */\nexport function injectValues<StateType extends object>(\n stream: StreamHandle<StateType>\n): Signal<StateType>;\nexport function injectValues<T>(stream: AnyStream): Signal<InferStateType<T>>;\nexport function injectValues<T = unknown>(\n stream: AnyStream,\n target: SelectorTarget | Signal<SelectorTarget>,\n options?: { messagesKey?: string }\n): Signal<T | undefined>;\nexport function injectValues(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>,\n options?: { messagesKey?: string }\n): Signal<unknown> {\n const messagesKey = options?.messagesKey ?? \"messages\";\n const { namespace, key, isRootSignal } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n `values|${messagesKey}`\n );\n const registry = computed(() =>\n isRootSignal() ? null : getRegistry(stream)\n );\n const scoped = injectProjection<unknown>(\n registry,\n () => valuesProjection<unknown>(namespace(), messagesKey),\n key,\n undefined\n );\n return computed(() => (isRootSignal() ? stream.values() : scoped()));\n}\n\n/**\n * Subscribe to a `custom:<name>` stream extension — the most recent\n * payload emitted by the transformer, scoped to the target namespace.\n *\n * Returns only the latest value and resumes across serial runs, so it is\n * ideal for \"current state\" panels (progress, score, status). When you\n * need the full history of events rather than just the latest payload,\n * use {@link injectChannel} instead.\n */\nexport function injectExtension<T = unknown>(\n stream: AnyStream,\n name: string,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<T | undefined> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n `extension|${name}`\n );\n return injectProjection<T | undefined>(\n getRegistry(stream),\n () => extensionProjection<T>(name, namespace()),\n key,\n undefined\n );\n}\n\n/**\n * Raw-events escape hatch. Subscribes to one or more channels at a\n * namespace and returns a bounded buffer of raw protocol events.\n *\n * The buffer keeps accumulating across serial runs for the lifetime of\n * the thread, so this is the hook to use for an event log / stream of a\n * custom channel (e.g. `[\"custom:redaction-stats\"]`). When you only need\n * the latest payload of a single `custom:<name>` channel, prefer\n * {@link injectExtension}. For the common message/tool/value cases prefer\n * {@link injectMessages} / {@link injectToolCalls} / {@link injectValues}.\n */\nexport type InjectChannelOptions = ChannelProjectionOptions;\n\nexport function injectChannel(\n stream: AnyStream,\n channels: readonly Channel[],\n target?: SelectorTarget | Signal<SelectorTarget>,\n options?: InjectChannelOptions\n): Signal<Event[]> {\n const sortedChannels = [...channels].sort().join(\",\");\n const prefix = `channel|${options?.bufferSize ?? \"default\"}|${(options?.replay ?? true) ? \"replay\" : \"live\"}|${sortedChannels}`;\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n prefix\n );\n return injectProjection<Event[]>(\n getRegistry(stream),\n () => channelProjection(channels, namespace(), options),\n key,\n EMPTY_EVENTS\n );\n}\n\nconst EMPTY_EVENTS: Event[] = [];\n\n/**\n * Options for {@link injectChannelEffect}. Extends the projection\n * options (`bufferSize`, `replay`) with the per-event callback, an\n * optional error sink, a `target` scope, and an `enabled` gate.\n */\nexport interface InjectChannelEffectOptions extends ChannelEffectOptions {\n /**\n * Scope events to a subagent / subgraph / explicit namespace.\n * Defaults to the root namespace. Accepts a `Signal` so a `computed`\n * scope re-binds the subscription automatically.\n */\n target?: SelectorTarget | Signal<SelectorTarget>;\n /**\n * Gate the subscription. When `false`, no subscription is opened and\n * no events are delivered. Defaults to `true`. Accepts a `Signal`.\n */\n enabled?: boolean | Signal<boolean>;\n}\n\n/**\n * Side-effect counterpart to {@link injectChannel}. Instead of\n * returning a signal of buffered events, it invokes `onEvent` once per\n * event for as long as the owning component / service is alive — the\n * idiomatic place for analytics, logging, and other fire-and-forget\n * side effects.\n *\n * ```ts\n * injectChannelEffect(this.stream, [\"lifecycle\", \"tools\"], {\n * replay: false,\n * onEvent: (event) => sendAnalytics(event),\n * onError: (error) => logger.error(error),\n * });\n * ```\n *\n * Reactive `channels` / `target` / `enabled` signals re-bind the\n * subscription when they change. The underlying subscription is shared\n * (ref-counted) with any matching {@link injectChannel} consumer.\n * `replay` defaults to `false` (live-only); events buffered before the\n * effect attaches are not re-delivered.\n *\n * Must be called from an injection context (component / directive /\n * service field initializer, or `runInInjectionContext(...)`).\n */\nexport function injectChannelEffect(\n stream: AnyStream,\n channels: readonly Channel[] | Signal<readonly Channel[]>,\n options: InjectChannelEffectOptions\n): void {\n const target = options.target as SelectorTarget | Signal<SelectorTarget>;\n resolveSubagentNamespaceFor(stream, target);\n const destroyRef = inject(DestroyRef);\n\n const enabledOf = (): boolean => {\n const value = options.enabled;\n if (value == null) return true;\n return isSignal(value) ? (value as Signal<boolean>)() : value;\n };\n const channelsOf = (): readonly Channel[] =>\n isSignal(channels)\n ? (channels as Signal<readonly Channel[]>)()\n : (channels as readonly Channel[]);\n const targetOf = (): SelectorTarget =>\n isSignal(target) ? (target as Signal<SelectorTarget>)() : target;\n\n const keyOf = (): string => {\n const enabled = enabledOf();\n const sortedChannels = [...channelsOf()].sort().join(\",\");\n const namespace = resolveNamespace(targetOf());\n return `${enabled ? \"on\" : \"off\"}|${sortedChannels}|${namespaceKey(namespace)}`;\n };\n\n let dispose: (() => void) | undefined;\n let currentKey: string | undefined;\n\n const detach = () => {\n dispose?.();\n dispose = undefined;\n };\n\n const attach = (nextKey: string): void => {\n if (nextKey === currentKey) return;\n detach();\n currentKey = nextKey;\n if (!enabledOf()) return;\n const registry = getRegistry(stream);\n if (registry == null) return;\n dispose = acquireChannelEffect(\n registry,\n channelsOf(),\n resolveNamespace(targetOf()),\n {\n replay: options.replay,\n bufferSize: options.bufferSize,\n // Read callbacks lazily so a fresh closure never re-acquires.\n onEvent: (event) => options.onEvent(event),\n onError: options.onError\n ? (error) => options.onError?.(error)\n : undefined,\n }\n );\n };\n\n // Acquire synchronously so the subscription is live before a user can\n // submit and emit short-lived events.\n attach(keyOf());\n destroyRef.onDestroy(detach);\n\n effect(() => {\n const nextKey = keyOf();\n untracked(() => attach(nextKey));\n });\n}\n\n/**\n * Subscribe to a scoped audio-media stream. Each handle is yielded\n * on its first matching `content-block-start`, exposes\n * `.partialBytes` for live access, settles `.blob` / `.objectURL` /\n * `.transcript` on `message-finish`, and surfaces errors via\n * `.error`.\n *\n * Pair with `injectMediaUrl` to turn a handle into an `<audio src>`.\n */\nexport function injectAudio(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<AudioMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"audio\"\n );\n return injectProjection<AudioMedia[]>(\n getRegistry(stream),\n () => audioProjection(namespace()),\n key,\n EMPTY_AUDIO\n );\n}\n\nconst EMPTY_AUDIO: AudioMedia[] = [];\n\n/**\n * Subscribe to a scoped image-media stream. Pair with\n * `injectMediaUrl` for `<img src>`.\n */\nexport function injectImages(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<ImageMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"images\"\n );\n return injectProjection<ImageMedia[]>(\n getRegistry(stream),\n () => imagesProjection(namespace()),\n key,\n EMPTY_IMAGES\n );\n}\n\nconst EMPTY_IMAGES: ImageMedia[] = [];\n\n/**\n * Subscribe to a scoped video-media stream. Pair with\n * `injectMediaUrl` for `<video src>`.\n */\nexport function injectVideo(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<VideoMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"video\"\n );\n return injectProjection<VideoMedia[]>(\n getRegistry(stream),\n () => videoProjection(namespace()),\n key,\n EMPTY_VIDEO\n );\n}\n\nconst EMPTY_VIDEO: VideoMedia[] = [];\n\n/**\n * Subscribe to a scoped file-media stream. Pair with\n * `injectMediaUrl` for an `<a download href>` target.\n */\nexport function injectFiles(\n stream: AnyStream,\n target?: SelectorTarget | Signal<SelectorTarget>\n): Signal<FileMedia[]> {\n const { namespace, key } = normalizeTarget(\n target as SelectorTarget | Signal<SelectorTarget>,\n \"files\"\n );\n return injectProjection<FileMedia[]>(\n getRegistry(stream),\n () => filesProjection(namespace()),\n key,\n EMPTY_FILES\n );\n}\n\nconst EMPTY_FILES: FileMedia[] = [];\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/angular",
3
- "version": "1.0.21",
3
+ "version": "1.0.23",
4
4
  "description": "Angular integration for LangGraph & LangChain",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -10,7 +10,7 @@
10
10
  "directory": "libs/sdk-angular"
11
11
  },
12
12
  "dependencies": {
13
- "@langchain/langgraph-sdk": "1.9.20"
13
+ "@langchain/langgraph-sdk": "1.9.22"
14
14
  },
15
15
  "devDependencies": {
16
16
  "@analogjs/vite-plugin-angular": "^2.6.0",
@@ -37,9 +37,9 @@
37
37
  "vitest-browser-angular": "^0.4.0",
38
38
  "webdriverio": "^9.27.0",
39
39
  "zod": "^4.3.6",
40
- "@langchain/langgraph": "^1.4.0",
41
- "@langchain/langgraph-api": "^1.3.0",
42
- "@langchain/langgraph-checkpoint": "^1.1.0"
40
+ "@langchain/langgraph": "^1.4.2",
41
+ "@langchain/langgraph-api": "^1.3.1",
42
+ "@langchain/langgraph-checkpoint": "^1.1.1"
43
43
  },
44
44
  "peerDependencies": {
45
45
  "@angular/core": "^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0",