@langchain/langgraph-sdk
Version:
Client library for interacting with the LangGraph API
1 lines • 7.15 kB
Source Map (JSON)
{"version":3,"file":"media.cjs","names":["namespaceKey","isRootNamespace","openProjectionSubscription","MediaAssembler"],"sources":["../../../src/stream/projections/media.ts"],"sourcesContent":["/**\n * Namespace-scoped media projections.\n *\n * Each factory opens `thread.subscribe({ channels: [\"messages\"],\n * namespaces: [ns] })`, runs the events through a {@link MediaAssembler},\n * filters to one media block type, and surfaces an array of handles\n * that grows as messages with that type are observed.\n *\n * Behaviour mirrors the iterables on `ThreadStream` / `SubgraphHandle` /\n * `SubagentHandle`:\n * - One handle per `(messageId, blockType)`.\n * - Yielded on the first matching `content-block-start` — messages\n * with no matching blocks never appear.\n * - Errors propagate through `handle.error` / rejected `blob` /\n * rejected `objectURL`, not through the projection itself.\n *\n * `objectURL`s minted from these handles are caller-owned. The\n * companion `useMediaURL` React hook revokes on unmount; non-React\n * consumers should call `media.revoke()` when done.\n */\nimport type { Event, MessagesEvent } from \"@langchain/protocol\";\nimport { MediaAssembler } from \"../../client/stream/media.js\";\nimport type {\n AudioMedia,\n FileMedia,\n ImageMedia,\n VideoMedia,\n} from \"../../client/stream/media.js\";\nimport type { ProjectionRuntime, ProjectionSpec } from \"../types.js\";\nimport { isRootNamespace, namespaceKey } from \"../namespace.js\";\nimport { openProjectionSubscription } from \"./runtime.js\";\n\ninterface MediaProjectionOptions {\n /**\n * Optional `fetch` for URL-sourced blocks. Forwarded into the\n * underlying {@link MediaAssembler}.\n */\n fetch?: typeof fetch;\n}\n\nfunction createMediaProjection<\n T extends AudioMedia | ImageMedia | VideoMedia | FileMedia,\n>(\n kind: \"audio\" | \"images\" | \"video\" | \"files\",\n namespace: readonly string[],\n buildAssembler: (\n push: (m: T) => void,\n options?: MediaProjectionOptions\n ) => MediaAssembler,\n options?: MediaProjectionOptions\n): ProjectionSpec<T[]> {\n const ns = [...namespace];\n const key = `${kind}|${namespaceKey(ns)}`;\n\n return {\n key,\n namespace: ns,\n initial: [],\n open({ thread, store, rootBus }): ProjectionRuntime {\n const assembler = buildAssembler((media) => {\n store.setValue([...store.getSnapshot(), media]);\n }, options);\n\n // The root pump is already subscribed to `messages` at root depth 1.\n // Root-scoped projections attach to it instead of opening a second\n // server subscription.\n const rootShortCircuit =\n isRootNamespace(ns) && rootBus.channels.includes(\"messages\");\n\n if (rootShortCircuit) {\n const unsubscribe = rootBus.subscribe((event) => {\n if (event.method !== \"messages\") return;\n const matches = isRootNamespace(event.params.namespace);\n if (!matches) return;\n assembler.consume(event as MessagesEvent);\n });\n return {\n async dispose() {\n unsubscribe();\n for (const media of store.getSnapshot()) {\n try {\n media.revoke();\n } catch {\n // best-effort\n }\n }\n assembler.close();\n },\n };\n }\n\n const runtime = openProjectionSubscription({\n thread,\n channels: [\"messages\"],\n namespace: ns,\n onEvent(event: Event) {\n if (event.method !== \"messages\") return;\n assembler.consume(event as MessagesEvent);\n },\n onFinally() {\n assembler.close();\n },\n });\n\n return {\n async dispose() {\n // Revoke object URLs minted by handles owned by this\n // projection so unmount cleans up regardless of whether\n // individual hooks called `revoke()` themselves.\n for (const media of store.getSnapshot()) {\n try {\n media.revoke();\n } catch {\n // best-effort\n }\n }\n assembler.close();\n await runtime.dispose();\n },\n };\n },\n };\n}\n\nexport function audioProjection(\n namespace: readonly string[],\n options?: MediaProjectionOptions\n): ProjectionSpec<AudioMedia[]> {\n return createMediaProjection<AudioMedia>(\n \"audio\",\n namespace,\n (push, opts) =>\n new MediaAssembler({ fetch: opts?.fetch, onAudio: (m) => push(m) }),\n options\n );\n}\n\nexport function imagesProjection(\n namespace: readonly string[],\n options?: MediaProjectionOptions\n): ProjectionSpec<ImageMedia[]> {\n return createMediaProjection<ImageMedia>(\n \"images\",\n namespace,\n (push, opts) =>\n new MediaAssembler({ fetch: opts?.fetch, onImage: (m) => push(m) }),\n options\n );\n}\n\nexport function videoProjection(\n namespace: readonly string[],\n options?: MediaProjectionOptions\n): ProjectionSpec<VideoMedia[]> {\n return createMediaProjection<VideoMedia>(\n \"video\",\n namespace,\n (push, opts) =>\n new MediaAssembler({ fetch: opts?.fetch, onVideo: (m) => push(m) }),\n options\n );\n}\n\nexport function filesProjection(\n namespace: readonly string[],\n options?: MediaProjectionOptions\n): ProjectionSpec<FileMedia[]> {\n return createMediaProjection<FileMedia>(\n \"files\",\n namespace,\n (push, opts) =>\n new MediaAssembler({ fetch: opts?.fetch, onFile: (m) => push(m) }),\n options\n );\n}\n\nexport type { MediaProjectionOptions };\n"],"mappings":";;;;AAwCA,SAAS,sBAGP,MACA,WACA,gBAIA,SACqB;CACrB,MAAM,KAAK,CAAC,GAAG,UAAU;AAGzB,QAAO;EACL,KAHU,GAAG,KAAK,GAAGA,kBAAAA,aAAa,GAAG;EAIrC,WAAW;EACX,SAAS,EAAE;EACX,KAAK,EAAE,QAAQ,OAAO,WAA8B;GAClD,MAAM,YAAY,gBAAgB,UAAU;AAC1C,UAAM,SAAS,CAAC,GAAG,MAAM,aAAa,EAAE,MAAM,CAAC;MAC9C,QAAQ;AAQX,OAFEC,kBAAAA,gBAAgB,GAAG,IAAI,QAAQ,SAAS,SAAS,WAAW,EAExC;IACpB,MAAM,cAAc,QAAQ,WAAW,UAAU;AAC/C,SAAI,MAAM,WAAW,WAAY;AAEjC,SAAI,CADYA,kBAAAA,gBAAgB,MAAM,OAAO,UAAU,CACzC;AACd,eAAU,QAAQ,MAAuB;MACzC;AACF,WAAO,EACL,MAAM,UAAU;AACd,kBAAa;AACb,UAAK,MAAM,SAAS,MAAM,aAAa,CACrC,KAAI;AACF,YAAM,QAAQ;aACR;AAIV,eAAU,OAAO;OAEpB;;GAGH,MAAM,UAAUC,gBAAAA,2BAA2B;IACzC;IACA,UAAU,CAAC,WAAW;IACtB,WAAW;IACX,QAAQ,OAAc;AACpB,SAAI,MAAM,WAAW,WAAY;AACjC,eAAU,QAAQ,MAAuB;;IAE3C,YAAY;AACV,eAAU,OAAO;;IAEpB,CAAC;AAEF,UAAO,EACL,MAAM,UAAU;AAId,SAAK,MAAM,SAAS,MAAM,aAAa,CACrC,KAAI;AACF,WAAM,QAAQ;YACR;AAIV,cAAU,OAAO;AACjB,UAAM,QAAQ,SAAS;MAE1B;;EAEJ;;AAGH,SAAgB,gBACd,WACA,SAC8B;AAC9B,QAAO,sBACL,SACA,YACC,MAAM,SACL,IAAIC,cAAAA,eAAe;EAAE,OAAO,MAAM;EAAO,UAAU,MAAM,KAAK,EAAE;EAAE,CAAC,EACrE,QACD;;AAGH,SAAgB,iBACd,WACA,SAC8B;AAC9B,QAAO,sBACL,UACA,YACC,MAAM,SACL,IAAIA,cAAAA,eAAe;EAAE,OAAO,MAAM;EAAO,UAAU,MAAM,KAAK,EAAE;EAAE,CAAC,EACrE,QACD;;AAGH,SAAgB,gBACd,WACA,SAC8B;AAC9B,QAAO,sBACL,SACA,YACC,MAAM,SACL,IAAIA,cAAAA,eAAe;EAAE,OAAO,MAAM;EAAO,UAAU,MAAM,KAAK,EAAE;EAAE,CAAC,EACrE,QACD;;AAGH,SAAgB,gBACd,WACA,SAC6B;AAC7B,QAAO,sBACL,SACA,YACC,MAAM,SACL,IAAIA,cAAAA,eAAe;EAAE,OAAO,MAAM;EAAO,SAAS,MAAM,KAAK,EAAE;EAAE,CAAC,EACpE,QACD"}