@loomwork/ui-hydration 0.0.0-stage → 0.1.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 (179) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +8 -0
  3. package/README.md +398 -2
  4. package/dist/cache.d.ts +71 -0
  5. package/dist/cache.d.ts.map +1 -0
  6. package/dist/cache.js +157 -0
  7. package/dist/cache.js.map +1 -0
  8. package/dist/chatSource.d.ts +105 -0
  9. package/dist/chatSource.d.ts.map +1 -0
  10. package/dist/chatSource.js +259 -0
  11. package/dist/chatSource.js.map +1 -0
  12. package/dist/client.d.ts +17 -0
  13. package/dist/client.d.ts.map +1 -0
  14. package/dist/client.js +36 -0
  15. package/dist/client.js.map +1 -0
  16. package/dist/contentRefs.d.ts +78 -0
  17. package/dist/contentRefs.d.ts.map +1 -0
  18. package/dist/contentRefs.js +129 -0
  19. package/dist/contentRefs.js.map +1 -0
  20. package/dist/controller.d.ts +228 -0
  21. package/dist/controller.d.ts.map +1 -0
  22. package/dist/controller.js +454 -0
  23. package/dist/controller.js.map +1 -0
  24. package/dist/dataProvider.d.ts +53 -0
  25. package/dist/dataProvider.d.ts.map +1 -0
  26. package/dist/dataProvider.js +77 -0
  27. package/dist/dataProvider.js.map +1 -0
  28. package/dist/esm/cache.js +151 -0
  29. package/dist/esm/cache.js.map +1 -0
  30. package/dist/esm/chatSource.js +254 -0
  31. package/dist/esm/chatSource.js.map +1 -0
  32. package/dist/esm/client.js +15 -0
  33. package/dist/esm/client.js.map +1 -0
  34. package/dist/esm/contentRefs.js +119 -0
  35. package/dist/esm/contentRefs.js.map +1 -0
  36. package/dist/esm/controller.js +449 -0
  37. package/dist/esm/controller.js.map +1 -0
  38. package/dist/esm/dataProvider.js +72 -0
  39. package/dist/esm/dataProvider.js.map +1 -0
  40. package/dist/esm/index.js +15 -0
  41. package/dist/esm/index.js.map +1 -0
  42. package/dist/esm/invoker.js +2 -0
  43. package/dist/esm/invoker.js.map +1 -0
  44. package/dist/esm/invokers.js +310 -0
  45. package/dist/esm/invokers.js.map +1 -0
  46. package/dist/esm/loomEffectProvider.js +96 -0
  47. package/dist/esm/loomEffectProvider.js.map +1 -0
  48. package/dist/esm/params.js +207 -0
  49. package/dist/esm/params.js.map +1 -0
  50. package/dist/esm/path.js +24 -0
  51. package/dist/esm/path.js.map +1 -0
  52. package/dist/esm/plan.js +190 -0
  53. package/dist/esm/plan.js.map +1 -0
  54. package/dist/esm/projection.js +230 -0
  55. package/dist/esm/projection.js.map +1 -0
  56. package/dist/esm/provider.js +416 -0
  57. package/dist/esm/provider.js.map +1 -0
  58. package/dist/esm/repair.js +53 -0
  59. package/dist/esm/repair.js.map +1 -0
  60. package/dist/esm/reshape.js +156 -0
  61. package/dist/esm/reshape.js.map +1 -0
  62. package/dist/esm/restricted.js +54 -0
  63. package/dist/esm/restricted.js.map +1 -0
  64. package/dist/esm/scheduler.js +247 -0
  65. package/dist/esm/scheduler.js.map +1 -0
  66. package/dist/esm/select.js +18 -0
  67. package/dist/esm/select.js.map +1 -0
  68. package/dist/esm/shape.js +34 -0
  69. package/dist/esm/shape.js.map +1 -0
  70. package/dist/esm/split/client.js +309 -0
  71. package/dist/esm/split/client.js.map +1 -0
  72. package/dist/esm/split/index.js +3 -0
  73. package/dist/esm/split/index.js.map +1 -0
  74. package/dist/esm/split/server.js +488 -0
  75. package/dist/esm/split/server.js.map +1 -0
  76. package/dist/esm/split/shared.js +13 -0
  77. package/dist/esm/split/shared.js.map +1 -0
  78. package/dist/index.d.ts +29 -0
  79. package/dist/index.d.ts.map +1 -0
  80. package/dist/index.js +63 -0
  81. package/dist/index.js.map +1 -0
  82. package/dist/invoker.d.ts +10 -0
  83. package/dist/invoker.d.ts.map +1 -0
  84. package/dist/invoker.js +3 -0
  85. package/dist/invoker.js.map +1 -0
  86. package/dist/invokers.d.ts +36 -0
  87. package/dist/invokers.d.ts.map +1 -0
  88. package/dist/invokers.js +315 -0
  89. package/dist/invokers.js.map +1 -0
  90. package/dist/loomEffectProvider.d.ts +67 -0
  91. package/dist/loomEffectProvider.d.ts.map +1 -0
  92. package/dist/loomEffectProvider.js +101 -0
  93. package/dist/loomEffectProvider.js.map +1 -0
  94. package/dist/params.d.ts +103 -0
  95. package/dist/params.d.ts.map +1 -0
  96. package/dist/params.js +221 -0
  97. package/dist/params.js.map +1 -0
  98. package/dist/path.d.ts +12 -0
  99. package/dist/path.d.ts.map +1 -0
  100. package/dist/path.js +28 -0
  101. package/dist/path.js.map +1 -0
  102. package/dist/plan.d.ts +56 -0
  103. package/dist/plan.d.ts.map +1 -0
  104. package/dist/plan.js +199 -0
  105. package/dist/plan.js.map +1 -0
  106. package/dist/projection.d.ts +122 -0
  107. package/dist/projection.d.ts.map +1 -0
  108. package/dist/projection.js +238 -0
  109. package/dist/projection.js.map +1 -0
  110. package/dist/provider.d.ts +152 -0
  111. package/dist/provider.d.ts.map +1 -0
  112. package/dist/provider.js +421 -0
  113. package/dist/provider.js.map +1 -0
  114. package/dist/repair.d.ts +18 -0
  115. package/dist/repair.d.ts.map +1 -0
  116. package/dist/repair.js +57 -0
  117. package/dist/repair.js.map +1 -0
  118. package/dist/reshape.d.ts +32 -0
  119. package/dist/reshape.d.ts.map +1 -0
  120. package/dist/reshape.js +164 -0
  121. package/dist/reshape.js.map +1 -0
  122. package/dist/restricted.d.ts +21 -0
  123. package/dist/restricted.d.ts.map +1 -0
  124. package/dist/restricted.js +61 -0
  125. package/dist/restricted.js.map +1 -0
  126. package/dist/scheduler.d.ts +82 -0
  127. package/dist/scheduler.d.ts.map +1 -0
  128. package/dist/scheduler.js +254 -0
  129. package/dist/scheduler.js.map +1 -0
  130. package/dist/select.d.ts +34 -0
  131. package/dist/select.d.ts.map +1 -0
  132. package/dist/select.js +21 -0
  133. package/dist/select.js.map +1 -0
  134. package/dist/shape.d.ts +3 -0
  135. package/dist/shape.d.ts.map +1 -0
  136. package/dist/shape.js +37 -0
  137. package/dist/shape.js.map +1 -0
  138. package/dist/split/client.d.ts +132 -0
  139. package/dist/split/client.d.ts.map +1 -0
  140. package/dist/split/client.js +313 -0
  141. package/dist/split/client.js.map +1 -0
  142. package/dist/split/index.d.ts +5 -0
  143. package/dist/split/index.d.ts.map +1 -0
  144. package/dist/split/index.js +14 -0
  145. package/dist/split/index.js.map +1 -0
  146. package/dist/split/server.d.ts +160 -0
  147. package/dist/split/server.d.ts.map +1 -0
  148. package/dist/split/server.js +496 -0
  149. package/dist/split/server.js.map +1 -0
  150. package/dist/split/shared.d.ts +6 -0
  151. package/dist/split/shared.d.ts.map +1 -0
  152. package/dist/split/shared.js +19 -0
  153. package/dist/split/shared.js.map +1 -0
  154. package/package.json +77 -3
  155. package/src/cache.ts +211 -0
  156. package/src/chatSource.ts +374 -0
  157. package/src/client.ts +46 -0
  158. package/src/contentRefs.ts +195 -0
  159. package/src/controller.ts +708 -0
  160. package/src/dataProvider.ts +141 -0
  161. package/src/index.ts +86 -0
  162. package/src/invoker.ts +14 -0
  163. package/src/invokers.ts +348 -0
  164. package/src/loomEffectProvider.ts +136 -0
  165. package/src/params.ts +314 -0
  166. package/src/path.ts +26 -0
  167. package/src/plan.ts +197 -0
  168. package/src/projection.ts +297 -0
  169. package/src/provider.ts +657 -0
  170. package/src/repair.ts +70 -0
  171. package/src/reshape.ts +193 -0
  172. package/src/restricted.ts +69 -0
  173. package/src/scheduler.ts +284 -0
  174. package/src/select.ts +59 -0
  175. package/src/shape.ts +39 -0
  176. package/src/split/client.ts +449 -0
  177. package/src/split/index.ts +18 -0
  178. package/src/split/server.ts +746 -0
  179. package/src/split/shared.ts +18 -0
@@ -0,0 +1,71 @@
1
+ import type { ContractRegistry, ProviderSpec } from "@loomwork/ui-core";
2
+ import type { LoadParams } from "./params";
3
+ /**
4
+ * The content fingerprint of a provider spec — the identity both the cache key and the
5
+ * controller's "have I already loaded THIS spec?" check are taken over, so the two can never
6
+ * disagree about what "the same provider" means.
7
+ *
8
+ * Total: `canonicalJson` throws on a spec carrying a non-finite number, a bigint or a nest past
9
+ * its depth cap. Such a spec gets a fingerprint unique to the OBJECT, which is conservative in
10
+ * both directions — the same object is still recognised as itself (no reload storm), and two
11
+ * structurally identical unhashable specs are treated as different (no cache hit).
12
+ */
13
+ export declare function specFingerprint(spec: ProviderSpec): string;
14
+ /**
15
+ * What else, besides the spec, decides a cached answer.
16
+ *
17
+ * `params` are the load's params AS DECLARED — relative-time tokens (`$now-7d`) UNRESOLVED. That
18
+ * is deliberate: resolving first would give every load a fresh instant and so a fresh key, and the
19
+ * cache would never hit. `$now-7d` is therefore one key for the entry's TTL; freshness comes from
20
+ * `cachePolicy.ttlSeconds`, and a provider whose answer must track the clock more closely than
21
+ * that sets a shorter TTL (or 0, never cached).
22
+ *
23
+ * `kinds` are the kinds a `"contract"` value was checked against. They are keyed ONLY for a spec
24
+ * whose `outputCheck` is `"contract"`, sorted and de-duplicated (`normaliseKinds`). A value that
25
+ * passed for `[Kpi]` was never checked against `MetricCard` — serving it for `[Kpi, MetricCard]`
26
+ * would publish a value no check ever cleared for the kind now reading it. A shape-mode key
27
+ * ignores `kinds` entirely.
28
+ */
29
+ export interface CacheVariant {
30
+ readonly params?: LoadParams;
31
+ readonly kinds?: readonly string[];
32
+ /**
33
+ * The host's value contracts. The `version` of each BOUND kind's contract (only those that
34
+ * declare one) is folded into the key, so a changed contract is a different question. A contract
35
+ * with no `version` adds nothing — such a host calls `invalidate()` after changing it.
36
+ */
37
+ readonly contracts?: ContractRegistry;
38
+ }
39
+ /**
40
+ * The one normal form of a kinds list — sorted, de-duplicated. The cache key and the controller's
41
+ * load fingerprint both use it, so they can never disagree about whether two kinds lists are the
42
+ * same question.
43
+ */
44
+ export declare function normaliseKinds(kinds: readonly string[]): string[];
45
+ /** The default cap on cached results (U17). Generous: a surface with fewer live questions never notices it. */
46
+ export declare const DEFAULT_CACHE_MAX_ENTRIES = 10000;
47
+ export interface HydrationCacheOptions {
48
+ /**
49
+ * The most results held at once (default {@link DEFAULT_CACHE_MAX_ENTRIES}). Past it the LEAST
50
+ * RECENTLY USED entry is evicted (a `get` hit or a `set` makes an entry most recent). An evicted
51
+ * entry is simply a miss: the next load for it calls the provider again, exactly as an expired one
52
+ * does. Before U17 the map grew without bound in a long-lived host, since an entry never re-read was
53
+ * never dropped.
54
+ */
55
+ readonly maxEntries?: number;
56
+ }
57
+ export declare class HydrationCache {
58
+ private readonly clock;
59
+ private readonly entries;
60
+ private readonly maxEntries;
61
+ constructor(clock?: () => number, opts?: HydrationCacheOptions);
62
+ /** How many results are held now (expired ones count until they are read or evicted). */
63
+ get size(): number;
64
+ private key;
65
+ get(spec: ProviderSpec, principalId: string | undefined, variant?: CacheVariant): {
66
+ value: unknown;
67
+ } | undefined;
68
+ set(spec: ProviderSpec, principalId: string | undefined, value: unknown, variant?: CacheVariant): void;
69
+ invalidate(handle?: string): void;
70
+ }
71
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAqB3C;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAY1D;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,gBAAgB,CAAC;CACvC;AAoBD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAEjE;AAmBD,+GAA+G;AAC/G,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAEhD,MAAM,WAAW,qBAAqB;IACpC;;;;;;OAMG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,qBAAa,cAAc;IAMvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAHxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4D;IACpF,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAEjB,KAAK,GAAE,MAAM,MAAiB,EAC/C,IAAI,GAAE,qBAA0B;IAQlC,yFAAyF;IACzF,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,OAAO,CAAC,GAAG;IAgBX,GAAG,CACD,IAAI,EAAE,YAAY,EAClB,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,OAAO,GAAE,YAAiB,GACzB;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,GAAG,SAAS;IAejC,GAAG,CACD,IAAI,EAAE,YAAY,EAClB,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,YAAiB,GACzB,IAAI;IAYP,UAAU,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;CAOlC"}
package/dist/cache.js ADDED
@@ -0,0 +1,157 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HydrationCache = exports.DEFAULT_CACHE_MAX_ENTRIES = void 0;
4
+ exports.specFingerprint = specFingerprint;
5
+ exports.normaliseKinds = normaliseKinds;
6
+ const core_1 = require("@loomwork/core");
7
+ // ── Result cache ──────────────────────────────────────────────────────────────
8
+ // `scope: "global"` shares one entry per handle; `scope: "principal"` keys on (principal, handle)
9
+ // and refuses to cache when no principal is known — a per-viewer result must never leak to the
10
+ // next viewer. TTL is against an injected clock so tests never sleep.
11
+ //
12
+ // The key also carries the SPEC's fingerprint: a handle whose provider was repaired (a remapped
13
+ // schema pin, a different tool, a new reshaping) is a different question, and must not be
14
+ // answered from the entry the old spec left behind. `invalidate(handle)` still drops every
15
+ // spec-generation of that handle, so the fingerprint never makes a stale entry unreachable.
16
+ // NUL: cannot appear in a handle, so `invalidate(handle)`'s suffix match can never mis-hit
17
+ // another handle whose name happens to contain the delimiter (e.g. a handle literally named "h").
18
+ const SEP = String.fromCharCode(0);
19
+ // Memoized per spec OBJECT: the controller fingerprints the same spec on every `schedule`, and
20
+ // `canonicalJson` walks the whole graph. A WeakMap keeps that O(1) without pinning specs alive.
21
+ const fingerprints = new WeakMap();
22
+ let unhashable = 0;
23
+ /**
24
+ * The content fingerprint of a provider spec — the identity both the cache key and the
25
+ * controller's "have I already loaded THIS spec?" check are taken over, so the two can never
26
+ * disagree about what "the same provider" means.
27
+ *
28
+ * Total: `canonicalJson` throws on a spec carrying a non-finite number, a bigint or a nest past
29
+ * its depth cap. Such a spec gets a fingerprint unique to the OBJECT, which is conservative in
30
+ * both directions — the same object is still recognised as itself (no reload storm), and two
31
+ * structurally identical unhashable specs are treated as different (no cache hit).
32
+ */
33
+ function specFingerprint(spec) {
34
+ const memo = fingerprints.get(spec);
35
+ if (memo !== undefined)
36
+ return memo;
37
+ let fp;
38
+ try {
39
+ fp = (0, core_1.fnv1a64)((0, core_1.canonicalJson)(spec));
40
+ }
41
+ catch {
42
+ unhashable += 1;
43
+ fp = `unhashable-${unhashable}`;
44
+ }
45
+ fingerprints.set(spec, fp);
46
+ return fp;
47
+ }
48
+ /** `{kind: version}` for the bound kinds whose contract declares a version; `undefined` if none. */
49
+ function contractVersions(kinds, contracts) {
50
+ if (contracts === undefined)
51
+ return undefined;
52
+ let out;
53
+ for (const k of kinds) {
54
+ if (!Object.hasOwn(contracts, k))
55
+ continue;
56
+ const v = contracts[k]?.version;
57
+ if (typeof v !== "string")
58
+ continue;
59
+ // Null-prototype-safe: a kind named `__proto__` must not set a prototype.
60
+ out ??= Object.create(null);
61
+ out[k] = v;
62
+ }
63
+ return out;
64
+ }
65
+ /**
66
+ * The one normal form of a kinds list — sorted, de-duplicated. The cache key and the controller's
67
+ * load fingerprint both use it, so they can never disagree about whether two kinds lists are the
68
+ * same question.
69
+ */
70
+ function normaliseKinds(kinds) {
71
+ return [...new Set(kinds)].sort();
72
+ }
73
+ /** `""` for the plain variant; `undefined` for one that cannot be keyed (never cached). */
74
+ function variantKey(params, kinds, versions) {
75
+ if (Object.keys(params).length === 0 && kinds.length === 0)
76
+ return "";
77
+ try {
78
+ // `versions` is added ONLY when present, so every key without one is what it always was.
79
+ return (0, core_1.fnv1a64)((0, core_1.canonicalJson)(versions === undefined ? { params, kinds } : { params, kinds, versions }));
80
+ }
81
+ catch {
82
+ return undefined;
83
+ }
84
+ }
85
+ /** The default cap on cached results (U17). Generous: a surface with fewer live questions never notices it. */
86
+ exports.DEFAULT_CACHE_MAX_ENTRIES = 10_000;
87
+ class HydrationCache {
88
+ clock;
89
+ // A Map iterates in insertion order, so re-inserting on use keeps the least recently used entry
90
+ // FIRST: eviction and promotion are both O(1).
91
+ entries = new Map();
92
+ maxEntries;
93
+ constructor(clock = Date.now, opts = {}) {
94
+ this.clock = clock;
95
+ const max = opts.maxEntries ?? exports.DEFAULT_CACHE_MAX_ENTRIES;
96
+ if (!Number.isInteger(max) || max < 1)
97
+ throw new RangeError(`HydrationCache maxEntries must be a positive integer, got ${max}`);
98
+ this.maxEntries = max;
99
+ }
100
+ /** How many results are held now (expired ones count until they are read or evicted). */
101
+ get size() {
102
+ return this.entries.size;
103
+ }
104
+ key(spec, principalId, variant) {
105
+ const kinds = spec.outputCheck === "contract" ? normaliseKinds(variant.kinds ?? []) : [];
106
+ const v = variantKey(variant.params ?? {}, kinds, contractVersions(kinds, variant.contracts));
107
+ if (v === undefined)
108
+ return undefined;
109
+ const fp = specFingerprint(spec);
110
+ // The handle stays LAST: `invalidate(handle)` suffix-matches it across every variant.
111
+ if (spec.cachePolicy.scope === "global")
112
+ return `g${SEP}${fp}${SEP}${v}${SEP}${spec.handle}`;
113
+ return principalId === undefined
114
+ ? undefined
115
+ : `p${SEP}${principalId}${SEP}${fp}${SEP}${v}${SEP}${spec.handle}`;
116
+ }
117
+ get(spec, principalId, variant = {}) {
118
+ const k = this.key(spec, principalId, variant);
119
+ if (k === undefined)
120
+ return undefined;
121
+ const e = this.entries.get(k);
122
+ if (!e)
123
+ return undefined;
124
+ if (e.expiresAt <= this.clock()) {
125
+ this.entries.delete(k);
126
+ return undefined;
127
+ }
128
+ // Promote: most recently used goes to the back of the iteration order.
129
+ this.entries.delete(k);
130
+ this.entries.set(k, e);
131
+ return { value: e.value };
132
+ }
133
+ set(spec, principalId, value, variant = {}) {
134
+ const k = this.key(spec, principalId, variant);
135
+ if (k === undefined || spec.cachePolicy.ttlSeconds <= 0)
136
+ return;
137
+ this.entries.delete(k);
138
+ this.entries.set(k, { value, expiresAt: this.clock() + spec.cachePolicy.ttlSeconds * 1000 });
139
+ while (this.entries.size > this.maxEntries) {
140
+ const oldest = this.entries.keys().next();
141
+ if (oldest.done === true)
142
+ break;
143
+ this.entries.delete(oldest.value);
144
+ }
145
+ }
146
+ invalidate(handle) {
147
+ if (handle === undefined) {
148
+ this.entries.clear();
149
+ return;
150
+ }
151
+ for (const k of [...this.entries.keys()])
152
+ if (k.endsWith(SEP + handle))
153
+ this.entries.delete(k);
154
+ }
155
+ }
156
+ exports.HydrationCache = HydrationCache;
157
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,105 @@
1
+ import type { Finding } from "@loomwork/ui-core/browser";
2
+ import type { ChatFeed } from "@loomwork/ui-core/chat";
3
+ /** The slice of the platform's `EventSource` this uses. */
4
+ export interface EventSourceLike {
5
+ addEventListener(type: string, listener: (event: {
6
+ readonly data?: unknown;
7
+ }) => void): void;
8
+ close(): void;
9
+ /** 2 = CLOSED: the platform gave up reconnecting and we must reopen. */
10
+ readonly readyState?: number;
11
+ }
12
+ export interface FetchResponseLike {
13
+ readonly ok: boolean;
14
+ /** The HTTP status, when the host's `fetch` has one: a 403/404 on the reasoning route means "none for you". */
15
+ readonly status?: number;
16
+ json(): Promise<unknown>;
17
+ /**
18
+ * The body as text, when the host's fetch has it. The reasoning read prefers it: the size is checked
19
+ * before `JSON.parse`. Without it the read falls back to `json()`, which the host's own fetch must bound.
20
+ */
21
+ text?(): Promise<string>;
22
+ /** Response headers, when the host exposes them: a declared `Content-Length` over the limit refuses the read. */
23
+ readonly headers?: {
24
+ get(name: string): string | null;
25
+ };
26
+ }
27
+ /**
28
+ * The most a durable reasoning response may weigh (bytes, or characters for the `text()` check). loom's
29
+ * route caps the readable text at 1 MiB, so 2 MiB leaves room for the JSON envelope and escaping.
30
+ * Residual: a host `fetch` that only offers `json()` and sends no `Content-Length` is not bounded here.
31
+ */
32
+ export declare const MAX_REASONING_RESPONSE_BYTES: number;
33
+ export interface ConversationConnectionOptions {
34
+ /** `/conversations/<id>` (or absolute). The id was minted by the server; this appends `/history` and `/events`. */
35
+ readonly baseUrl: string;
36
+ readonly fetch: (url: string, init: {
37
+ readonly signal: AbortSignal;
38
+ }) => Promise<FetchResponseLike>;
39
+ /** Open the SSE stream at `url` (the host owns credentials). */
40
+ readonly openStream: (url: string) => EventSourceLike;
41
+ readonly feed: Pick<ChatFeed, "applyHistory" | "applyEvent" | "resumeCursor" | "olderCursor" | "value" | "streaming"> & Partial<Pick<ChatFeed, "beginReasoning" | "applyReasoning" | "reasoningFailed" | "reasoningUnavailable">>;
42
+ /**
43
+ * The server serves `/reasoning` (loom's `reasoning: { store }`) and the feed is `reasoning: { durable: true }`:
44
+ * `loadReasoning` then fetches. Default false: `loadReasoning` does nothing.
45
+ */
46
+ readonly reasoning?: boolean;
47
+ /** Called with the new value after every change. Deltas arrive fast: throttle here if the host wants. */
48
+ readonly publish: (value: ReturnType<ChatFeed["value"]>, meta: {
49
+ readonly streaming: boolean;
50
+ }) => void;
51
+ /** Fixed-text findings (a failed load, a bad frame). */
52
+ readonly onFinding?: (finding: Finding) => void;
53
+ /** Entries per history page (default 50, loom caps it at 500). */
54
+ readonly pageLimit?: number;
55
+ /** Largest SSE frame parsed, bytes of text (default 256 KiB). */
56
+ readonly maxFrameBytes?: number;
57
+ /** First delay after a failure, ms (default 2 000); it doubles per consecutive failure up to `maxReconnectMs`. */
58
+ readonly reconnectMs?: number;
59
+ /** The longest delay between attempts, ms (default 30 000). */
60
+ readonly maxReconnectMs?: number;
61
+ /**
62
+ * The shortest delay before reopening a stream the server asked to recycle (`reconnect`), ms
63
+ * (default 250). Never 0: a server that answered `reconnect` at once would be a hot loop.
64
+ */
65
+ readonly reconnectFloorMs?: number;
66
+ readonly now?: () => number;
67
+ readonly setTimer?: (fn: () => void, ms: number) => () => void;
68
+ }
69
+ export interface ConversationConnection {
70
+ /** Load the newest page, then open the stream from where it ended. Resolves when the first page is in. */
71
+ start(): Promise<void>;
72
+ /** Load the page before the window (no-op when there is none or one is in flight). */
73
+ loadOlder(): Promise<void>;
74
+ /**
75
+ * Fetch the stored reasoning of the reply at `cursor` (the entry's own cursor), once: a no-op unless
76
+ * `reasoning` is on, the feed offers that reply, and it is not already loaded or loading.
77
+ */
78
+ loadReasoning(cursor: string): Promise<void>;
79
+ /** Stop everything. Idempotent. */
80
+ close(): void;
81
+ }
82
+ export declare function connectConversation(options: ConversationConnectionOptions): ConversationConnection;
83
+ /** What a hydration controller offers for a value no loader serves (`publishValue`): its viewer / inventory gate and contract check. */
84
+ export interface ValuePublisher {
85
+ publishValue(handle: string, value: unknown, options: {
86
+ readonly state: "ready" | "pending";
87
+ readonly kind: string;
88
+ }): {
89
+ readonly ok: true;
90
+ } | {
91
+ readonly ok: false;
92
+ readonly finding: Finding;
93
+ };
94
+ }
95
+ /**
96
+ * A `publish` that writes the transcript to a handle THROUGH a controller's gate (`publishValue`):
97
+ * refused (a finding, nothing written) for a handle the experience does not bind, one that is
98
+ * restricted for the viewer, one that is not a `Chat`, or a value that fails the `ChatValue`
99
+ * contract. `pending` while a reply streams (a screen reader holds its announcements), `ready` once
100
+ * it is durable. Writing the store directly would bypass all of that.
101
+ */
102
+ export declare function publishChat(controller: ValuePublisher, handle: string, onFinding?: (finding: Finding) => void): (value: unknown, meta: {
103
+ readonly streaming: boolean;
104
+ }) => void;
105
+ //# sourceMappingURL=chatSource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chatSource.d.ts","sourceRoot":"","sources":["../src/chatSource.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,259 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MAX_REASONING_RESPONSE_BYTES = void 0;
4
+ exports.connectConversation = connectConversation;
5
+ exports.publishChat = publishChat;
6
+ /**
7
+ * The most a durable reasoning response may weigh (bytes, or characters for the `text()` check). loom's
8
+ * route caps the readable text at 1 MiB, so 2 MiB leaves room for the JSON envelope and escaping.
9
+ * Residual: a host `fetch` that only offers `json()` and sends no `Content-Length` is not bounded here.
10
+ */
11
+ exports.MAX_REASONING_RESPONSE_BYTES = 2 * 1024 * 1024;
12
+ /** A stream open at least this long (ms) was healthy: its end is not a failure streak. */
13
+ const HEALTHY_MS = 5000;
14
+ const EVENTS = [
15
+ "status",
16
+ "partial",
17
+ "delta",
18
+ "reasoning",
19
+ "reasoning-partial",
20
+ "reset",
21
+ "message",
22
+ "closed",
23
+ "reconnect",
24
+ "error",
25
+ ];
26
+ const changedBy = (r) => r?.ok === true && r.changed === true;
27
+ const finding = (code, message) => ({ code, severity: "error", message });
28
+ const defaultTimer = (fn, ms) => {
29
+ const id = setTimeout(fn, ms);
30
+ return () => clearTimeout(id);
31
+ };
32
+ function connectConversation(options) {
33
+ const { feed, baseUrl } = options;
34
+ const pageLimit = Math.max(1, Math.min(options.pageLimit ?? 50, 500));
35
+ const maxFrame = options.maxFrameBytes ?? 256 * 1024;
36
+ const timer = options.setTimer ?? defaultTimer;
37
+ const ac = new AbortController();
38
+ let source;
39
+ let cancelReopen;
40
+ let closed = false;
41
+ let loadingOlder = false;
42
+ let failures = 0;
43
+ let openedAt = 0;
44
+ const now = options.now ?? Date.now;
45
+ const base = Math.max(1, options.reconnectMs ?? 2000);
46
+ const ceiling = Math.max(base, options.maxReconnectMs ?? 30_000);
47
+ const floor = Math.max(1, options.reconnectFloorMs ?? 250);
48
+ /** Consecutive failures double the wait, capped; the first is the base. */
49
+ const backoff = () => Math.min(ceiling, base * 2 ** Math.min(failures, 16));
50
+ const report = (code, message) => options.onFinding?.(finding(code, message));
51
+ const publish = () => options.publish(feed.value(), { streaming: feed.streaming });
52
+ async function page(cursor) {
53
+ const q = `direction=backward&limit=${pageLimit}${cursor === undefined ? "" : `&cursor=${encodeURIComponent(cursor)}`}`;
54
+ let body;
55
+ try {
56
+ const res = await options.fetch(`${baseUrl}/history?${q}`, { signal: ac.signal });
57
+ if (!res.ok)
58
+ throw new Error("not ok");
59
+ body = await res.json();
60
+ }
61
+ catch {
62
+ if (!ac.signal.aborted)
63
+ report("history-unavailable", "the conversation history could not be loaded");
64
+ return false;
65
+ }
66
+ if (closed)
67
+ return false;
68
+ const r = feed.applyHistory(body, "backward");
69
+ if (!r.ok) {
70
+ report(r.finding.code, r.finding.message);
71
+ return false;
72
+ }
73
+ if (r.changed)
74
+ publish();
75
+ return true;
76
+ }
77
+ function open() {
78
+ if (closed)
79
+ return;
80
+ const cursor = feed.resumeCursor();
81
+ const url = `${baseUrl}/events${cursor === undefined ? "" : `?cursor=${encodeURIComponent(cursor)}`}`;
82
+ const es = options.openStream(url);
83
+ source = es;
84
+ openedAt = now();
85
+ for (const name of EVENTS)
86
+ es.addEventListener(name, (ev) => {
87
+ if (closed || source !== es)
88
+ return;
89
+ const raw = ev.data;
90
+ let data;
91
+ if (typeof raw === "string") {
92
+ if (raw.length > maxFrame)
93
+ return report("frame-too-large", "a conversation event was too large and was ignored");
94
+ try {
95
+ data = JSON.parse(raw);
96
+ }
97
+ catch {
98
+ return report("frame-invalid", "a conversation event was not understood and was ignored");
99
+ }
100
+ }
101
+ const r = feed.applyEvent(name, data);
102
+ if (!r.ok) {
103
+ // The feed's finding text is fixed; an `error` event's body was never read.
104
+ report(r.finding.code, r.finding.message);
105
+ return;
106
+ }
107
+ if (r.reconnect !== true)
108
+ failures = 0; // a frame the feed understood: the connection works
109
+ if (r.changed)
110
+ publish();
111
+ if (r.reconnect === true) {
112
+ // Asked to recycle. A server that does so right after opening is looping: back off like a failure.
113
+ const healthy = now() - openedAt >= HEALTHY_MS;
114
+ if (healthy)
115
+ failures = 0;
116
+ reopen(failures === 0 ? floor : Math.max(floor, backoff()));
117
+ if (!healthy)
118
+ failures++;
119
+ }
120
+ });
121
+ // A stream the platform has given up on (it keeps trying by itself while CONNECTING).
122
+ es.onerror = () => {
123
+ if (es.readyState === 2) {
124
+ // A stream that stayed up long enough was healthy: its end starts the backoff afresh, and the
125
+ // first wait is the documented base.
126
+ if (now() - openedAt >= HEALTHY_MS)
127
+ failures = 0;
128
+ const delay = backoff();
129
+ failures++;
130
+ reopen(delay);
131
+ }
132
+ };
133
+ }
134
+ function reopen(delay) {
135
+ if (closed)
136
+ return;
137
+ source?.close();
138
+ source = undefined;
139
+ cancelReopen?.();
140
+ cancelReopen = timer(() => {
141
+ cancelReopen = undefined;
142
+ open();
143
+ }, delay);
144
+ }
145
+ /** The first page; on failure (and nothing to show) try again after a backoff instead of giving up. */
146
+ async function begin() {
147
+ const ok = await page();
148
+ if (closed)
149
+ return;
150
+ if (ok || feed.value().entries.length > 0) {
151
+ if (ok)
152
+ failures = 0;
153
+ open();
154
+ return;
155
+ }
156
+ const delay = backoff();
157
+ failures++;
158
+ cancelReopen?.();
159
+ cancelReopen = timer(() => {
160
+ cancelReopen = undefined;
161
+ void begin();
162
+ }, delay);
163
+ }
164
+ const loadingReasoning = new Set();
165
+ async function reasoningFor(cursor) {
166
+ const { feed: f } = options;
167
+ if (options.reasoning !== true || closed || loadingReasoning.has(cursor))
168
+ return;
169
+ if (f.beginReasoning === undefined || !changedBy(f.beginReasoning(cursor)))
170
+ return;
171
+ loadingReasoning.add(cursor);
172
+ publish(); // the entry now reads "loading"
173
+ try {
174
+ let body;
175
+ let gone = false;
176
+ try {
177
+ const res = await options.fetch(`${baseUrl}/reasoning?cursor=${encodeURIComponent(cursor)}`, {
178
+ signal: ac.signal,
179
+ });
180
+ if (!res.ok) {
181
+ gone = res.status === 404 || res.status === 403;
182
+ throw new Error("not ok");
183
+ }
184
+ const declared = Number(res.headers?.get("content-length"));
185
+ if (Number.isFinite(declared) && declared > exports.MAX_REASONING_RESPONSE_BYTES)
186
+ throw new Error("too large");
187
+ if (res.text !== undefined) {
188
+ const raw = await res.text();
189
+ if (raw.length > exports.MAX_REASONING_RESPONSE_BYTES)
190
+ throw new Error("too large");
191
+ body = JSON.parse(raw);
192
+ }
193
+ else
194
+ body = await res.json();
195
+ }
196
+ catch {
197
+ if (closed)
198
+ return;
199
+ // A refusal is a settled "none for you" (no retry); anything else is a failure the reader can retry.
200
+ if (gone)
201
+ f.reasoningUnavailable?.(cursor);
202
+ else {
203
+ f.reasoningFailed?.(cursor);
204
+ report("reasoning-unavailable", "the reasoning could not be loaded");
205
+ }
206
+ publish();
207
+ return;
208
+ }
209
+ if (closed)
210
+ return;
211
+ if (changedBy(f.applyReasoning?.(cursor, body)))
212
+ publish();
213
+ }
214
+ finally {
215
+ loadingReasoning.delete(cursor);
216
+ }
217
+ }
218
+ return {
219
+ start: begin,
220
+ loadReasoning: reasoningFor,
221
+ async loadOlder() {
222
+ const cursor = feed.olderCursor();
223
+ if (cursor === undefined || loadingOlder || closed)
224
+ return;
225
+ loadingOlder = true;
226
+ try {
227
+ await page(cursor);
228
+ }
229
+ finally {
230
+ loadingOlder = false;
231
+ }
232
+ },
233
+ close() {
234
+ closed = true;
235
+ ac.abort();
236
+ cancelReopen?.();
237
+ source?.close();
238
+ source = undefined;
239
+ },
240
+ };
241
+ }
242
+ /**
243
+ * A `publish` that writes the transcript to a handle THROUGH a controller's gate (`publishValue`):
244
+ * refused (a finding, nothing written) for a handle the experience does not bind, one that is
245
+ * restricted for the viewer, one that is not a `Chat`, or a value that fails the `ChatValue`
246
+ * contract. `pending` while a reply streams (a screen reader holds its announcements), `ready` once
247
+ * it is durable. Writing the store directly would bypass all of that.
248
+ */
249
+ function publishChat(controller, handle, onFinding) {
250
+ return (value, meta) => {
251
+ const r = controller.publishValue(handle, value, {
252
+ state: meta.streaming ? "pending" : "ready",
253
+ kind: "Chat",
254
+ });
255
+ if (!r.ok)
256
+ onFinding?.(r.finding);
257
+ };
258
+ }
259
+ //# sourceMappingURL=chatSource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chatSource.js","sourceRoot":"","sources":["../src/chatSource.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export { HYDRATION_PROJECTION_ID, HYDRATION_PROJECTION_VERSION, HYDRATION_SET_EVENT, HydrationStore, hydrationProjection, isReservedHandle, } from "./projection";
2
+ export type { HandleSlice, HandleState, HandleStatus, HydrationScope, HydrationState, } from "./projection";
3
+ export { HYDRATION_VALUES_PREFIX, handleOfPath } from "./path";
4
+ export { DEFAULT_TIME_RANGE, checkParams } from "./params";
5
+ export type { LoadParams } from "./params";
6
+ export type { HandleLoadResult } from "./scheduler";
7
+ export { stepReferences, terminalSteps, topoWaves } from "./plan";
8
+ export { jsonPathSelect } from "./select";
9
+ export type { ReshapeFailureKind, ReshapeResult } from "./select";
10
+ export { outputShapeHashOf } from "./shape";
11
+ export type { TransientInvoker } from "./invoker";
12
+ export type { DriftRecord } from "./provider";
13
+ export { SplitHydrationController } from "./split/client";
14
+ export type { HandleInventory, HandleLoadRequest, HandleLoader, HandleRef, SplitControllerOptions, } from "./split/client";
15
+ export { connectConversation, publishChat } from "./chatSource";
16
+ export type { ConversationConnection, ConversationConnectionOptions, EventSourceLike, FetchResponseLike, } from "./chatSource";
17
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,uBAAuB,EACvB,4BAA4B,EAC5B,mBAAmB,EACnB,cAAc,EACd,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,WAAW,EACX,WAAW,EACX,YAAY,EACZ,cAAc,EACd,cAAc,GACf,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,uBAAuB,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC3D,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,YAAY,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAC5C,YAAY,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAClD,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,SAAS,EACT,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChE,YAAY,EACV,sBAAsB,EACtB,6BAA6B,EAC7B,eAAe,EACf,iBAAiB,GAClB,MAAM,cAAc,CAAC"}