@langchain/svelte 0.4.6 → 1.0.0

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.
Files changed (74) hide show
  1. package/README.md +37 -443
  2. package/dist/context.cjs +72 -0
  3. package/dist/context.cjs.map +1 -0
  4. package/dist/context.d.cts +72 -0
  5. package/dist/context.d.cts.map +1 -0
  6. package/dist/context.d.ts +72 -0
  7. package/dist/context.d.ts.map +1 -0
  8. package/dist/context.js +70 -0
  9. package/dist/context.js.map +1 -0
  10. package/dist/index.cjs +32 -316
  11. package/dist/index.d.cts +11 -97
  12. package/dist/index.d.ts +11 -97
  13. package/dist/index.js +10 -290
  14. package/dist/selectors.svelte.cjs +214 -0
  15. package/dist/selectors.svelte.cjs.map +1 -0
  16. package/dist/selectors.svelte.d.cts +146 -0
  17. package/dist/selectors.svelte.d.cts.map +1 -0
  18. package/dist/selectors.svelte.d.ts +146 -0
  19. package/dist/selectors.svelte.d.ts.map +1 -0
  20. package/dist/selectors.svelte.js +204 -0
  21. package/dist/selectors.svelte.js.map +1 -0
  22. package/dist/use-audio-player.svelte.cjs +608 -0
  23. package/dist/use-audio-player.svelte.cjs.map +1 -0
  24. package/dist/use-audio-player.svelte.d.cts +70 -0
  25. package/dist/use-audio-player.svelte.d.cts.map +1 -0
  26. package/dist/use-audio-player.svelte.d.ts +70 -0
  27. package/dist/use-audio-player.svelte.d.ts.map +1 -0
  28. package/dist/use-audio-player.svelte.js +608 -0
  29. package/dist/use-audio-player.svelte.js.map +1 -0
  30. package/dist/use-media-url.svelte.cjs +54 -0
  31. package/dist/use-media-url.svelte.cjs.map +1 -0
  32. package/dist/use-media-url.svelte.d.cts +29 -0
  33. package/dist/use-media-url.svelte.d.cts.map +1 -0
  34. package/dist/use-media-url.svelte.d.ts +29 -0
  35. package/dist/use-media-url.svelte.d.ts.map +1 -0
  36. package/dist/use-media-url.svelte.js +54 -0
  37. package/dist/use-media-url.svelte.js.map +1 -0
  38. package/dist/use-projection.svelte.cjs +62 -0
  39. package/dist/use-projection.svelte.cjs.map +1 -0
  40. package/dist/use-projection.svelte.d.cts +65 -0
  41. package/dist/use-projection.svelte.d.cts.map +1 -0
  42. package/dist/use-projection.svelte.d.ts +65 -0
  43. package/dist/use-projection.svelte.d.ts.map +1 -0
  44. package/dist/use-projection.svelte.js +62 -0
  45. package/dist/use-projection.svelte.js.map +1 -0
  46. package/dist/use-stream.svelte.cjs +193 -0
  47. package/dist/use-stream.svelte.cjs.map +1 -0
  48. package/dist/use-stream.svelte.d.cts +116 -0
  49. package/dist/use-stream.svelte.d.cts.map +1 -0
  50. package/dist/use-stream.svelte.d.ts +116 -0
  51. package/dist/use-stream.svelte.d.ts.map +1 -0
  52. package/dist/use-stream.svelte.js +191 -0
  53. package/dist/use-stream.svelte.js.map +1 -0
  54. package/dist/use-video-player.svelte.cjs +233 -0
  55. package/dist/use-video-player.svelte.cjs.map +1 -0
  56. package/dist/use-video-player.svelte.d.cts +66 -0
  57. package/dist/use-video-player.svelte.d.cts.map +1 -0
  58. package/dist/use-video-player.svelte.d.ts +66 -0
  59. package/dist/use-video-player.svelte.d.ts.map +1 -0
  60. package/dist/use-video-player.svelte.js +233 -0
  61. package/dist/use-video-player.svelte.js.map +1 -0
  62. package/package.json +9 -8
  63. package/dist/index.cjs.map +0 -1
  64. package/dist/index.d.cts.map +0 -1
  65. package/dist/index.d.ts.map +0 -1
  66. package/dist/index.js.map +0 -1
  67. package/dist/stream.custom.cjs +0 -122
  68. package/dist/stream.custom.cjs.map +0 -1
  69. package/dist/stream.custom.js +0 -122
  70. package/dist/stream.custom.js.map +0 -1
  71. package/dist/subagents.cjs +0 -81
  72. package/dist/subagents.cjs.map +0 -1
  73. package/dist/subagents.js +0 -81
  74. package/dist/subagents.js.map +0 -1
@@ -0,0 +1,54 @@
1
+ //#region src/use-media-url.svelte.ts
2
+ function unwrap(input) {
3
+ if (typeof input === "function") return input();
4
+ return input;
5
+ }
6
+ /**
7
+ * Resolve the lazy {@link MediaBase.objectURL} promise into a
8
+ * reactive string suitable for `<audio src>`, `<img src>`,
9
+ * `<video src>`, or `<a download href>`. Reads `.current` for the
10
+ * latest URL, or `undefined` until the promise settles.
11
+ *
12
+ * Lifecycle:
13
+ * - On first `$effect` (or whenever the supplied `media` value
14
+ * changes), awaits `media.objectURL` and commits the resolved
15
+ * string to state.
16
+ * - On cleanup (or when `media` changes), calls `media.revoke()` to
17
+ * free the blob-URL slot. The next consumer that accesses
18
+ * `media.objectURL` mints a fresh URL from the same `Blob`, so
19
+ * live re-renders just work.
20
+ * - If the underlying handle errored before settling, the URL stays
21
+ * `undefined`. Surface the failure via `media.error`.
22
+ *
23
+ * `media` accepts a raw handle or a getter so the composable rebinds
24
+ * automatically to the latest media without a manual effect at the
25
+ * call site.
26
+ */
27
+ function useMediaURL(media) {
28
+ let url = $state(void 0);
29
+ $effect(() => {
30
+ const next = unwrap(media);
31
+ if (next == null) {
32
+ url = void 0;
33
+ return;
34
+ }
35
+ let cancelled = false;
36
+ next.objectURL.then((resolved) => {
37
+ if (!cancelled) url = resolved;
38
+ }, () => {});
39
+ return () => {
40
+ cancelled = true;
41
+ url = void 0;
42
+ try {
43
+ next.revoke();
44
+ } catch {}
45
+ };
46
+ });
47
+ return { get current() {
48
+ return url;
49
+ } };
50
+ }
51
+ //#endregion
52
+ exports.useMediaURL = useMediaURL;
53
+
54
+ //# sourceMappingURL=use-media-url.svelte.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-media-url.svelte.cjs","names":[],"sources":["../src/use-media-url.svelte.ts"],"sourcesContent":["import type { MediaBase } from \"@langchain/langgraph-sdk/stream\";\nimport type { ReactiveValue, ValueOrGetter } from \"./use-projection.svelte.js\";\n\nfunction unwrap<T>(input: ValueOrGetter<T>): T {\n if (typeof input === \"function\") return (input as () => T)();\n return input;\n}\n\n/**\n * Resolve the lazy {@link MediaBase.objectURL} promise into a\n * reactive string suitable for `<audio src>`, `<img src>`,\n * `<video src>`, or `<a download href>`. Reads `.current` for the\n * latest URL, or `undefined` until the promise settles.\n *\n * Lifecycle:\n * - On first `$effect` (or whenever the supplied `media` value\n * changes), awaits `media.objectURL` and commits the resolved\n * string to state.\n * - On cleanup (or when `media` changes), calls `media.revoke()` to\n * free the blob-URL slot. The next consumer that accesses\n * `media.objectURL` mints a fresh URL from the same `Blob`, so\n * live re-renders just work.\n * - If the underlying handle errored before settling, the URL stays\n * `undefined`. Surface the failure via `media.error`.\n *\n * `media` accepts a raw handle or a getter so the composable rebinds\n * automatically to the latest media without a manual effect at the\n * call site.\n */\nexport function useMediaURL(\n media: ValueOrGetter<MediaBase | undefined>\n): ReactiveValue<string | undefined> {\n let url = $state<string | undefined>(undefined);\n\n $effect(() => {\n const next = unwrap(media);\n if (next == null) {\n url = undefined;\n return;\n }\n let cancelled = false;\n next.objectURL.then(\n (resolved) => {\n if (!cancelled) url = resolved;\n },\n () => {\n // Errors surface via `media.error`; keep `url` undefined so\n // consumers fall through to a no-src render.\n }\n );\n return () => {\n cancelled = true;\n url = undefined;\n try {\n next.revoke();\n } catch {\n // best-effort\n }\n };\n });\n\n return {\n get current() {\n return url;\n },\n };\n}\n"],"mappings":";AAGA,SAAS,OAAU,OAA4B;AAC7C,KAAI,OAAO,UAAU,WAAY,QAAQ,OAAmB;AAC5D,QAAO;;;;;;;;;;;;;;;;;;;;;;;AAwBT,SAAgB,YACd,OACmC;CACnC,IAAI,MAAM,OAA2B,KAAA,EAAU;AAE/C,eAAc;EACZ,MAAM,OAAO,OAAO,MAAM;AAC1B,MAAI,QAAQ,MAAM;AAChB,SAAM,KAAA;AACN;;EAEF,IAAI,YAAY;AAChB,OAAK,UAAU,MACZ,aAAa;AACZ,OAAI,CAAC,UAAW,OAAM;WAElB,GAIP;AACD,eAAa;AACX,eAAY;AACZ,SAAM,KAAA;AACN,OAAI;AACF,SAAK,QAAQ;WACP;;GAIV;AAEF,QAAO,EACL,IAAI,UAAU;AACZ,SAAO;IAEV"}
@@ -0,0 +1,29 @@
1
+ import { ReactiveValue, ValueOrGetter } from "./use-projection.svelte.cjs";
2
+ import { MediaBase } from "@langchain/langgraph-sdk/stream";
3
+
4
+ //#region src/use-media-url.svelte.d.ts
5
+ /**
6
+ * Resolve the lazy {@link MediaBase.objectURL} promise into a
7
+ * reactive string suitable for `<audio src>`, `<img src>`,
8
+ * `<video src>`, or `<a download href>`. Reads `.current` for the
9
+ * latest URL, or `undefined` until the promise settles.
10
+ *
11
+ * Lifecycle:
12
+ * - On first `$effect` (or whenever the supplied `media` value
13
+ * changes), awaits `media.objectURL` and commits the resolved
14
+ * string to state.
15
+ * - On cleanup (or when `media` changes), calls `media.revoke()` to
16
+ * free the blob-URL slot. The next consumer that accesses
17
+ * `media.objectURL` mints a fresh URL from the same `Blob`, so
18
+ * live re-renders just work.
19
+ * - If the underlying handle errored before settling, the URL stays
20
+ * `undefined`. Surface the failure via `media.error`.
21
+ *
22
+ * `media` accepts a raw handle or a getter so the composable rebinds
23
+ * automatically to the latest media without a manual effect at the
24
+ * call site.
25
+ */
26
+ declare function useMediaURL(media: ValueOrGetter<MediaBase | undefined>): ReactiveValue<string | undefined>;
27
+ //#endregion
28
+ export { useMediaURL };
29
+ //# sourceMappingURL=use-media-url.svelte.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-media-url.svelte.d.cts","names":[],"sources":["../src/use-media-url.svelte.ts"],"mappings":";;;;;;AA6BA;;;;;;;;;;;;;;;;;;;iBAAgB,WAAA,CACd,KAAA,EAAO,aAAA,CAAc,SAAA,gBACpB,aAAA"}
@@ -0,0 +1,29 @@
1
+ import { ReactiveValue, ValueOrGetter } from "./use-projection.svelte.js";
2
+ import { MediaBase } from "@langchain/langgraph-sdk/stream";
3
+
4
+ //#region src/use-media-url.svelte.d.ts
5
+ /**
6
+ * Resolve the lazy {@link MediaBase.objectURL} promise into a
7
+ * reactive string suitable for `<audio src>`, `<img src>`,
8
+ * `<video src>`, or `<a download href>`. Reads `.current` for the
9
+ * latest URL, or `undefined` until the promise settles.
10
+ *
11
+ * Lifecycle:
12
+ * - On first `$effect` (or whenever the supplied `media` value
13
+ * changes), awaits `media.objectURL` and commits the resolved
14
+ * string to state.
15
+ * - On cleanup (or when `media` changes), calls `media.revoke()` to
16
+ * free the blob-URL slot. The next consumer that accesses
17
+ * `media.objectURL` mints a fresh URL from the same `Blob`, so
18
+ * live re-renders just work.
19
+ * - If the underlying handle errored before settling, the URL stays
20
+ * `undefined`. Surface the failure via `media.error`.
21
+ *
22
+ * `media` accepts a raw handle or a getter so the composable rebinds
23
+ * automatically to the latest media without a manual effect at the
24
+ * call site.
25
+ */
26
+ declare function useMediaURL(media: ValueOrGetter<MediaBase | undefined>): ReactiveValue<string | undefined>;
27
+ //#endregion
28
+ export { useMediaURL };
29
+ //# sourceMappingURL=use-media-url.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-media-url.svelte.d.ts","names":[],"sources":["../src/use-media-url.svelte.ts"],"mappings":";;;;;;AA6BA;;;;;;;;;;;;;;;;;;;iBAAgB,WAAA,CACd,KAAA,EAAO,aAAA,CAAc,SAAA,gBACpB,aAAA"}
@@ -0,0 +1,54 @@
1
+ //#region src/use-media-url.svelte.ts
2
+ function unwrap(input) {
3
+ if (typeof input === "function") return input();
4
+ return input;
5
+ }
6
+ /**
7
+ * Resolve the lazy {@link MediaBase.objectURL} promise into a
8
+ * reactive string suitable for `<audio src>`, `<img src>`,
9
+ * `<video src>`, or `<a download href>`. Reads `.current` for the
10
+ * latest URL, or `undefined` until the promise settles.
11
+ *
12
+ * Lifecycle:
13
+ * - On first `$effect` (or whenever the supplied `media` value
14
+ * changes), awaits `media.objectURL` and commits the resolved
15
+ * string to state.
16
+ * - On cleanup (or when `media` changes), calls `media.revoke()` to
17
+ * free the blob-URL slot. The next consumer that accesses
18
+ * `media.objectURL` mints a fresh URL from the same `Blob`, so
19
+ * live re-renders just work.
20
+ * - If the underlying handle errored before settling, the URL stays
21
+ * `undefined`. Surface the failure via `media.error`.
22
+ *
23
+ * `media` accepts a raw handle or a getter so the composable rebinds
24
+ * automatically to the latest media without a manual effect at the
25
+ * call site.
26
+ */
27
+ function useMediaURL(media) {
28
+ let url = $state(void 0);
29
+ $effect(() => {
30
+ const next = unwrap(media);
31
+ if (next == null) {
32
+ url = void 0;
33
+ return;
34
+ }
35
+ let cancelled = false;
36
+ next.objectURL.then((resolved) => {
37
+ if (!cancelled) url = resolved;
38
+ }, () => {});
39
+ return () => {
40
+ cancelled = true;
41
+ url = void 0;
42
+ try {
43
+ next.revoke();
44
+ } catch {}
45
+ };
46
+ });
47
+ return { get current() {
48
+ return url;
49
+ } };
50
+ }
51
+ //#endregion
52
+ export { useMediaURL };
53
+
54
+ //# sourceMappingURL=use-media-url.svelte.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-media-url.svelte.js","names":[],"sources":["../src/use-media-url.svelte.ts"],"sourcesContent":["import type { MediaBase } from \"@langchain/langgraph-sdk/stream\";\nimport type { ReactiveValue, ValueOrGetter } from \"./use-projection.svelte.js\";\n\nfunction unwrap<T>(input: ValueOrGetter<T>): T {\n if (typeof input === \"function\") return (input as () => T)();\n return input;\n}\n\n/**\n * Resolve the lazy {@link MediaBase.objectURL} promise into a\n * reactive string suitable for `<audio src>`, `<img src>`,\n * `<video src>`, or `<a download href>`. Reads `.current` for the\n * latest URL, or `undefined` until the promise settles.\n *\n * Lifecycle:\n * - On first `$effect` (or whenever the supplied `media` value\n * changes), awaits `media.objectURL` and commits the resolved\n * string to state.\n * - On cleanup (or when `media` changes), calls `media.revoke()` to\n * free the blob-URL slot. The next consumer that accesses\n * `media.objectURL` mints a fresh URL from the same `Blob`, so\n * live re-renders just work.\n * - If the underlying handle errored before settling, the URL stays\n * `undefined`. Surface the failure via `media.error`.\n *\n * `media` accepts a raw handle or a getter so the composable rebinds\n * automatically to the latest media without a manual effect at the\n * call site.\n */\nexport function useMediaURL(\n media: ValueOrGetter<MediaBase | undefined>\n): ReactiveValue<string | undefined> {\n let url = $state<string | undefined>(undefined);\n\n $effect(() => {\n const next = unwrap(media);\n if (next == null) {\n url = undefined;\n return;\n }\n let cancelled = false;\n next.objectURL.then(\n (resolved) => {\n if (!cancelled) url = resolved;\n },\n () => {\n // Errors surface via `media.error`; keep `url` undefined so\n // consumers fall through to a no-src render.\n }\n );\n return () => {\n cancelled = true;\n url = undefined;\n try {\n next.revoke();\n } catch {\n // best-effort\n }\n };\n });\n\n return {\n get current() {\n return url;\n },\n };\n}\n"],"mappings":";AAGA,SAAS,OAAU,OAA4B;AAC7C,KAAI,OAAO,UAAU,WAAY,QAAQ,OAAmB;AAC5D,QAAO;;;;;;;;;;;;;;;;;;;;;;;AAwBT,SAAgB,YACd,OACmC;CACnC,IAAI,MAAM,OAA2B,KAAA,EAAU;AAE/C,eAAc;EACZ,MAAM,OAAO,OAAO,MAAM;AAC1B,MAAI,QAAQ,MAAM;AAChB,SAAM,KAAA;AACN;;EAEF,IAAI,YAAY;AAChB,OAAK,UAAU,MACZ,aAAa;AACZ,OAAI,CAAC,UAAW,OAAM;WAElB,GAIP;AACD,eAAa;AACX,eAAY;AACZ,SAAM,KAAA;AACN,OAAI;AACF,SAAK,QAAQ;WACP;;GAIV;AAEF,QAAO,EACL,IAAI,UAAU;AACZ,SAAO;IAEV"}
@@ -0,0 +1,62 @@
1
+ //#region src/use-projection.svelte.ts
2
+ function unwrap(input) {
3
+ if (typeof input === "function") return input();
4
+ return input;
5
+ }
6
+ /**
7
+ * Svelte binding over {@link ChannelRegistry.acquire}. Mirrors the
8
+ * React and Vue `useProjection` primitives with an idiomatic Svelte
9
+ * shape:
10
+ *
11
+ * - On the first `$effect` run the composable acquires a ref-counted
12
+ * projection from the registry, seeds the returned `current` with
13
+ * the current snapshot, and subscribes to the store so templates
14
+ * auto-update on subsequent snapshots.
15
+ * - The `$effect` cleanup returned from the effect body runs on both
16
+ * scope teardown and before the next run, releasing the previous
17
+ * acquisition (and letting the registry close the underlying
18
+ * server subscription once the last consumer leaves).
19
+ * - When the resolved `registry` is `null` / `undefined` the
20
+ * composable stays at `initialValue`. This is the happy path for
21
+ * selector composables that short-circuit the root namespace by
22
+ * reading `stream.messages` / `stream.values` directly — they
23
+ * don't call `useProjection` at all at the root. Dynamic inputs
24
+ * that flip from root to scoped can pass `null` for the root case
25
+ * and fall back to `initialValue`.
26
+ *
27
+ * `registry` and `key` accept plain values or getters. Reading the
28
+ * getter inside `$effect` auto-tracks any `$state` the getter
29
+ * references, so the effect re-runs and re-acquires whenever the
30
+ * resolved target changes.
31
+ *
32
+ * Must be called from a reactive context (a `.svelte` component
33
+ * script or inside `$effect.root`). Calls outside a reactive scope
34
+ * will not receive store updates because `$effect` never fires.
35
+ */
36
+ function useProjection(registry, specFactory, key, initialValue) {
37
+ let snapshot = $state(initialValue);
38
+ $effect(() => {
39
+ const reg = unwrap(registry);
40
+ unwrap(key);
41
+ if (reg == null) {
42
+ snapshot = initialValue;
43
+ return;
44
+ }
45
+ const acquired = reg.acquire(specFactory());
46
+ snapshot = acquired.store.getSnapshot();
47
+ const unsubscribe = acquired.store.subscribe(() => {
48
+ snapshot = acquired.store.getSnapshot();
49
+ });
50
+ return () => {
51
+ unsubscribe();
52
+ acquired.release();
53
+ };
54
+ });
55
+ return { get current() {
56
+ return snapshot;
57
+ } };
58
+ }
59
+ //#endregion
60
+ exports.useProjection = useProjection;
61
+
62
+ //# sourceMappingURL=use-projection.svelte.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-projection.svelte.cjs","names":[],"sources":["../src/use-projection.svelte.ts"],"sourcesContent":["import type {\n ChannelRegistry,\n ProjectionSpec,\n} from \"@langchain/langgraph-sdk/stream\";\n\n/**\n * Accepts either a plain `T` or a getter `() => T`. Selector\n * composables use this to support both static inputs (the common\n * case — `useMessages(stream, subagent)`) and reactive inputs\n * driven by component-level `$state`\n * (`useMessages(stream, () => activeSubagent)`).\n */\nexport type ValueOrGetter<T> = T | (() => T);\n\nfunction unwrap<T>(input: ValueOrGetter<T>): T {\n if (typeof input === \"function\") return (input as () => T)();\n return input;\n}\n\n/**\n * Svelte-side handle returned by {@link useProjection} and all\n * single-value selector composables. Consumers read the reactive\n * payload via `proj.current`.\n *\n * Why an object with a `current` getter instead of a bare reactive\n * value:\n * - Matches Svelte 5's `fromStore(...)` shape — users already know\n * this pattern.\n * - Portable across `.svelte` components and `.svelte.ts` modules.\n * Returning a bare `$state` from a module function loses\n * reactivity at the module boundary; a stable object with a\n * getter keeps `$derived` tracking intact.\n * - Templates read `{messages.current}` as data, not as a function\n * call (`{messages()}` would be ambiguous in Svelte's template\n * grammar).\n */\nexport interface ReactiveValue<T> {\n readonly current: T;\n}\n\n/**\n * Svelte binding over {@link ChannelRegistry.acquire}. Mirrors the\n * React and Vue `useProjection` primitives with an idiomatic Svelte\n * shape:\n *\n * - On the first `$effect` run the composable acquires a ref-counted\n * projection from the registry, seeds the returned `current` with\n * the current snapshot, and subscribes to the store so templates\n * auto-update on subsequent snapshots.\n * - The `$effect` cleanup returned from the effect body runs on both\n * scope teardown and before the next run, releasing the previous\n * acquisition (and letting the registry close the underlying\n * server subscription once the last consumer leaves).\n * - When the resolved `registry` is `null` / `undefined` the\n * composable stays at `initialValue`. This is the happy path for\n * selector composables that short-circuit the root namespace by\n * reading `stream.messages` / `stream.values` directly — they\n * don't call `useProjection` at all at the root. Dynamic inputs\n * that flip from root to scoped can pass `null` for the root case\n * and fall back to `initialValue`.\n *\n * `registry` and `key` accept plain values or getters. Reading the\n * getter inside `$effect` auto-tracks any `$state` the getter\n * references, so the effect re-runs and re-acquires whenever the\n * resolved target changes.\n *\n * Must be called from a reactive context (a `.svelte` component\n * script or inside `$effect.root`). Calls outside a reactive scope\n * will not receive store updates because `$effect` never fires.\n */\nexport function useProjection<T>(\n registry: ValueOrGetter<ChannelRegistry | null | undefined>,\n specFactory: () => ProjectionSpec<T>,\n key: ValueOrGetter<string>,\n initialValue: T\n): ReactiveValue<T> {\n let snapshot = $state<T>(initialValue);\n\n $effect(() => {\n const reg = unwrap(registry);\n // Reading `key` inside the effect auto-tracks any `$state` the\n // getter references so the effect re-runs when it changes.\n // The resolved value itself is not used beyond this read because\n // the registry is content-addressed by spec; the key is purely a\n // reactivity anchor for Svelte.\n unwrap(key);\n\n if (reg == null) {\n snapshot = initialValue;\n return;\n }\n\n const acquired = reg.acquire(specFactory());\n snapshot = acquired.store.getSnapshot();\n const unsubscribe = acquired.store.subscribe(() => {\n snapshot = acquired.store.getSnapshot();\n });\n\n return () => {\n unsubscribe();\n acquired.release();\n };\n });\n\n return {\n get current() {\n return snapshot;\n },\n };\n}\n"],"mappings":";AAcA,SAAS,OAAU,OAA4B;AAC7C,KAAI,OAAO,UAAU,WAAY,QAAQ,OAAmB;AAC5D,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsDT,SAAgB,cACd,UACA,aACA,KACA,cACkB;CAClB,IAAI,WAAW,OAAU,aAAa;AAEtC,eAAc;EACZ,MAAM,MAAM,OAAO,SAAS;AAM5B,SAAO,IAAI;AAEX,MAAI,OAAO,MAAM;AACf,cAAW;AACX;;EAGF,MAAM,WAAW,IAAI,QAAQ,aAAa,CAAC;AAC3C,aAAW,SAAS,MAAM,aAAa;EACvC,MAAM,cAAc,SAAS,MAAM,gBAAgB;AACjD,cAAW,SAAS,MAAM,aAAa;IACvC;AAEF,eAAa;AACX,gBAAa;AACb,YAAS,SAAS;;GAEpB;AAEF,QAAO,EACL,IAAI,UAAU;AACZ,SAAO;IAEV"}
@@ -0,0 +1,65 @@
1
+ import { ChannelRegistry, ProjectionSpec } from "@langchain/langgraph-sdk/stream";
2
+
3
+ //#region src/use-projection.svelte.d.ts
4
+ /**
5
+ * Accepts either a plain `T` or a getter `() => T`. Selector
6
+ * composables use this to support both static inputs (the common
7
+ * case — `useMessages(stream, subagent)`) and reactive inputs
8
+ * driven by component-level `$state`
9
+ * (`useMessages(stream, () => activeSubagent)`).
10
+ */
11
+ type ValueOrGetter<T> = T | (() => T);
12
+ /**
13
+ * Svelte-side handle returned by {@link useProjection} and all
14
+ * single-value selector composables. Consumers read the reactive
15
+ * payload via `proj.current`.
16
+ *
17
+ * Why an object with a `current` getter instead of a bare reactive
18
+ * value:
19
+ * - Matches Svelte 5's `fromStore(...)` shape — users already know
20
+ * this pattern.
21
+ * - Portable across `.svelte` components and `.svelte.ts` modules.
22
+ * Returning a bare `$state` from a module function loses
23
+ * reactivity at the module boundary; a stable object with a
24
+ * getter keeps `$derived` tracking intact.
25
+ * - Templates read `{messages.current}` as data, not as a function
26
+ * call (`{messages()}` would be ambiguous in Svelte's template
27
+ * grammar).
28
+ */
29
+ interface ReactiveValue<T> {
30
+ readonly current: T;
31
+ }
32
+ /**
33
+ * Svelte binding over {@link ChannelRegistry.acquire}. Mirrors the
34
+ * React and Vue `useProjection` primitives with an idiomatic Svelte
35
+ * shape:
36
+ *
37
+ * - On the first `$effect` run the composable acquires a ref-counted
38
+ * projection from the registry, seeds the returned `current` with
39
+ * the current snapshot, and subscribes to the store so templates
40
+ * auto-update on subsequent snapshots.
41
+ * - The `$effect` cleanup returned from the effect body runs on both
42
+ * scope teardown and before the next run, releasing the previous
43
+ * acquisition (and letting the registry close the underlying
44
+ * server subscription once the last consumer leaves).
45
+ * - When the resolved `registry` is `null` / `undefined` the
46
+ * composable stays at `initialValue`. This is the happy path for
47
+ * selector composables that short-circuit the root namespace by
48
+ * reading `stream.messages` / `stream.values` directly — they
49
+ * don't call `useProjection` at all at the root. Dynamic inputs
50
+ * that flip from root to scoped can pass `null` for the root case
51
+ * and fall back to `initialValue`.
52
+ *
53
+ * `registry` and `key` accept plain values or getters. Reading the
54
+ * getter inside `$effect` auto-tracks any `$state` the getter
55
+ * references, so the effect re-runs and re-acquires whenever the
56
+ * resolved target changes.
57
+ *
58
+ * Must be called from a reactive context (a `.svelte` component
59
+ * script or inside `$effect.root`). Calls outside a reactive scope
60
+ * will not receive store updates because `$effect` never fires.
61
+ */
62
+ declare function useProjection<T>(registry: ValueOrGetter<ChannelRegistry | null | undefined>, specFactory: () => ProjectionSpec<T>, key: ValueOrGetter<string>, initialValue: T): ReactiveValue<T>;
63
+ //#endregion
64
+ export { ReactiveValue, ValueOrGetter, useProjection };
65
+ //# sourceMappingURL=use-projection.svelte.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-projection.svelte.d.cts","names":[],"sources":["../src/use-projection.svelte.ts"],"mappings":";;;;;AAYA;;;;;KAAY,aAAA,MAAmB,CAAA,UAAW,CAAA;;;;AAwB1C;;;;;;;;;AAkCA;;;;;UAlCiB,aAAA;EAAA,SACN,OAAA,EAAS,CAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiCJ,aAAA,GAAA,CACd,QAAA,EAAU,aAAA,CAAc,eAAA,sBACxB,WAAA,QAAmB,cAAA,CAAe,CAAA,GAClC,GAAA,EAAK,aAAA,UACL,YAAA,EAAc,CAAA,GACb,aAAA,CAAc,CAAA"}
@@ -0,0 +1,65 @@
1
+ import { ChannelRegistry, ProjectionSpec } from "@langchain/langgraph-sdk/stream";
2
+
3
+ //#region src/use-projection.svelte.d.ts
4
+ /**
5
+ * Accepts either a plain `T` or a getter `() => T`. Selector
6
+ * composables use this to support both static inputs (the common
7
+ * case — `useMessages(stream, subagent)`) and reactive inputs
8
+ * driven by component-level `$state`
9
+ * (`useMessages(stream, () => activeSubagent)`).
10
+ */
11
+ type ValueOrGetter<T> = T | (() => T);
12
+ /**
13
+ * Svelte-side handle returned by {@link useProjection} and all
14
+ * single-value selector composables. Consumers read the reactive
15
+ * payload via `proj.current`.
16
+ *
17
+ * Why an object with a `current` getter instead of a bare reactive
18
+ * value:
19
+ * - Matches Svelte 5's `fromStore(...)` shape — users already know
20
+ * this pattern.
21
+ * - Portable across `.svelte` components and `.svelte.ts` modules.
22
+ * Returning a bare `$state` from a module function loses
23
+ * reactivity at the module boundary; a stable object with a
24
+ * getter keeps `$derived` tracking intact.
25
+ * - Templates read `{messages.current}` as data, not as a function
26
+ * call (`{messages()}` would be ambiguous in Svelte's template
27
+ * grammar).
28
+ */
29
+ interface ReactiveValue<T> {
30
+ readonly current: T;
31
+ }
32
+ /**
33
+ * Svelte binding over {@link ChannelRegistry.acquire}. Mirrors the
34
+ * React and Vue `useProjection` primitives with an idiomatic Svelte
35
+ * shape:
36
+ *
37
+ * - On the first `$effect` run the composable acquires a ref-counted
38
+ * projection from the registry, seeds the returned `current` with
39
+ * the current snapshot, and subscribes to the store so templates
40
+ * auto-update on subsequent snapshots.
41
+ * - The `$effect` cleanup returned from the effect body runs on both
42
+ * scope teardown and before the next run, releasing the previous
43
+ * acquisition (and letting the registry close the underlying
44
+ * server subscription once the last consumer leaves).
45
+ * - When the resolved `registry` is `null` / `undefined` the
46
+ * composable stays at `initialValue`. This is the happy path for
47
+ * selector composables that short-circuit the root namespace by
48
+ * reading `stream.messages` / `stream.values` directly — they
49
+ * don't call `useProjection` at all at the root. Dynamic inputs
50
+ * that flip from root to scoped can pass `null` for the root case
51
+ * and fall back to `initialValue`.
52
+ *
53
+ * `registry` and `key` accept plain values or getters. Reading the
54
+ * getter inside `$effect` auto-tracks any `$state` the getter
55
+ * references, so the effect re-runs and re-acquires whenever the
56
+ * resolved target changes.
57
+ *
58
+ * Must be called from a reactive context (a `.svelte` component
59
+ * script or inside `$effect.root`). Calls outside a reactive scope
60
+ * will not receive store updates because `$effect` never fires.
61
+ */
62
+ declare function useProjection<T>(registry: ValueOrGetter<ChannelRegistry | null | undefined>, specFactory: () => ProjectionSpec<T>, key: ValueOrGetter<string>, initialValue: T): ReactiveValue<T>;
63
+ //#endregion
64
+ export { ReactiveValue, ValueOrGetter, useProjection };
65
+ //# sourceMappingURL=use-projection.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-projection.svelte.d.ts","names":[],"sources":["../src/use-projection.svelte.ts"],"mappings":";;;;;AAYA;;;;;KAAY,aAAA,MAAmB,CAAA,UAAW,CAAA;;;;AAwB1C;;;;;;;;;AAkCA;;;;;UAlCiB,aAAA;EAAA,SACN,OAAA,EAAS,CAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiCJ,aAAA,GAAA,CACd,QAAA,EAAU,aAAA,CAAc,eAAA,sBACxB,WAAA,QAAmB,cAAA,CAAe,CAAA,GAClC,GAAA,EAAK,aAAA,UACL,YAAA,EAAc,CAAA,GACb,aAAA,CAAc,CAAA"}
@@ -0,0 +1,62 @@
1
+ //#region src/use-projection.svelte.ts
2
+ function unwrap(input) {
3
+ if (typeof input === "function") return input();
4
+ return input;
5
+ }
6
+ /**
7
+ * Svelte binding over {@link ChannelRegistry.acquire}. Mirrors the
8
+ * React and Vue `useProjection` primitives with an idiomatic Svelte
9
+ * shape:
10
+ *
11
+ * - On the first `$effect` run the composable acquires a ref-counted
12
+ * projection from the registry, seeds the returned `current` with
13
+ * the current snapshot, and subscribes to the store so templates
14
+ * auto-update on subsequent snapshots.
15
+ * - The `$effect` cleanup returned from the effect body runs on both
16
+ * scope teardown and before the next run, releasing the previous
17
+ * acquisition (and letting the registry close the underlying
18
+ * server subscription once the last consumer leaves).
19
+ * - When the resolved `registry` is `null` / `undefined` the
20
+ * composable stays at `initialValue`. This is the happy path for
21
+ * selector composables that short-circuit the root namespace by
22
+ * reading `stream.messages` / `stream.values` directly — they
23
+ * don't call `useProjection` at all at the root. Dynamic inputs
24
+ * that flip from root to scoped can pass `null` for the root case
25
+ * and fall back to `initialValue`.
26
+ *
27
+ * `registry` and `key` accept plain values or getters. Reading the
28
+ * getter inside `$effect` auto-tracks any `$state` the getter
29
+ * references, so the effect re-runs and re-acquires whenever the
30
+ * resolved target changes.
31
+ *
32
+ * Must be called from a reactive context (a `.svelte` component
33
+ * script or inside `$effect.root`). Calls outside a reactive scope
34
+ * will not receive store updates because `$effect` never fires.
35
+ */
36
+ function useProjection(registry, specFactory, key, initialValue) {
37
+ let snapshot = $state(initialValue);
38
+ $effect(() => {
39
+ const reg = unwrap(registry);
40
+ unwrap(key);
41
+ if (reg == null) {
42
+ snapshot = initialValue;
43
+ return;
44
+ }
45
+ const acquired = reg.acquire(specFactory());
46
+ snapshot = acquired.store.getSnapshot();
47
+ const unsubscribe = acquired.store.subscribe(() => {
48
+ snapshot = acquired.store.getSnapshot();
49
+ });
50
+ return () => {
51
+ unsubscribe();
52
+ acquired.release();
53
+ };
54
+ });
55
+ return { get current() {
56
+ return snapshot;
57
+ } };
58
+ }
59
+ //#endregion
60
+ export { useProjection };
61
+
62
+ //# sourceMappingURL=use-projection.svelte.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-projection.svelte.js","names":[],"sources":["../src/use-projection.svelte.ts"],"sourcesContent":["import type {\n ChannelRegistry,\n ProjectionSpec,\n} from \"@langchain/langgraph-sdk/stream\";\n\n/**\n * Accepts either a plain `T` or a getter `() => T`. Selector\n * composables use this to support both static inputs (the common\n * case — `useMessages(stream, subagent)`) and reactive inputs\n * driven by component-level `$state`\n * (`useMessages(stream, () => activeSubagent)`).\n */\nexport type ValueOrGetter<T> = T | (() => T);\n\nfunction unwrap<T>(input: ValueOrGetter<T>): T {\n if (typeof input === \"function\") return (input as () => T)();\n return input;\n}\n\n/**\n * Svelte-side handle returned by {@link useProjection} and all\n * single-value selector composables. Consumers read the reactive\n * payload via `proj.current`.\n *\n * Why an object with a `current` getter instead of a bare reactive\n * value:\n * - Matches Svelte 5's `fromStore(...)` shape — users already know\n * this pattern.\n * - Portable across `.svelte` components and `.svelte.ts` modules.\n * Returning a bare `$state` from a module function loses\n * reactivity at the module boundary; a stable object with a\n * getter keeps `$derived` tracking intact.\n * - Templates read `{messages.current}` as data, not as a function\n * call (`{messages()}` would be ambiguous in Svelte's template\n * grammar).\n */\nexport interface ReactiveValue<T> {\n readonly current: T;\n}\n\n/**\n * Svelte binding over {@link ChannelRegistry.acquire}. Mirrors the\n * React and Vue `useProjection` primitives with an idiomatic Svelte\n * shape:\n *\n * - On the first `$effect` run the composable acquires a ref-counted\n * projection from the registry, seeds the returned `current` with\n * the current snapshot, and subscribes to the store so templates\n * auto-update on subsequent snapshots.\n * - The `$effect` cleanup returned from the effect body runs on both\n * scope teardown and before the next run, releasing the previous\n * acquisition (and letting the registry close the underlying\n * server subscription once the last consumer leaves).\n * - When the resolved `registry` is `null` / `undefined` the\n * composable stays at `initialValue`. This is the happy path for\n * selector composables that short-circuit the root namespace by\n * reading `stream.messages` / `stream.values` directly — they\n * don't call `useProjection` at all at the root. Dynamic inputs\n * that flip from root to scoped can pass `null` for the root case\n * and fall back to `initialValue`.\n *\n * `registry` and `key` accept plain values or getters. Reading the\n * getter inside `$effect` auto-tracks any `$state` the getter\n * references, so the effect re-runs and re-acquires whenever the\n * resolved target changes.\n *\n * Must be called from a reactive context (a `.svelte` component\n * script or inside `$effect.root`). Calls outside a reactive scope\n * will not receive store updates because `$effect` never fires.\n */\nexport function useProjection<T>(\n registry: ValueOrGetter<ChannelRegistry | null | undefined>,\n specFactory: () => ProjectionSpec<T>,\n key: ValueOrGetter<string>,\n initialValue: T\n): ReactiveValue<T> {\n let snapshot = $state<T>(initialValue);\n\n $effect(() => {\n const reg = unwrap(registry);\n // Reading `key` inside the effect auto-tracks any `$state` the\n // getter references so the effect re-runs when it changes.\n // The resolved value itself is not used beyond this read because\n // the registry is content-addressed by spec; the key is purely a\n // reactivity anchor for Svelte.\n unwrap(key);\n\n if (reg == null) {\n snapshot = initialValue;\n return;\n }\n\n const acquired = reg.acquire(specFactory());\n snapshot = acquired.store.getSnapshot();\n const unsubscribe = acquired.store.subscribe(() => {\n snapshot = acquired.store.getSnapshot();\n });\n\n return () => {\n unsubscribe();\n acquired.release();\n };\n });\n\n return {\n get current() {\n return snapshot;\n },\n };\n}\n"],"mappings":";AAcA,SAAS,OAAU,OAA4B;AAC7C,KAAI,OAAO,UAAU,WAAY,QAAQ,OAAmB;AAC5D,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsDT,SAAgB,cACd,UACA,aACA,KACA,cACkB;CAClB,IAAI,WAAW,OAAU,aAAa;AAEtC,eAAc;EACZ,MAAM,MAAM,OAAO,SAAS;AAM5B,SAAO,IAAI;AAEX,MAAI,OAAO,MAAM;AACf,cAAW;AACX;;EAGF,MAAM,WAAW,IAAI,QAAQ,aAAa,CAAC;AAC3C,aAAW,SAAS,MAAM,aAAa;EACvC,MAAM,cAAc,SAAS,MAAM,gBAAgB;AACjD,cAAW,SAAS,MAAM,aAAa;IACvC;AAEF,eAAa;AACX,gBAAa;AACb,YAAS,SAAS;;GAEpB;AAEF,QAAO,EACL,IAAI,UAAU;AACZ,SAAO;IAEV"}