@earendil-works/pi-durable 0.99.1 → 0.99.2

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 (172) hide show
  1. package/README.md +435 -46
  2. package/dist/entries.d.ts +20 -2
  3. package/dist/entries.d.ts.map +1 -1
  4. package/dist/entries.js +14 -1
  5. package/dist/entries.js.map +1 -1
  6. package/dist/env/index.d.ts +13 -38
  7. package/dist/env/index.d.ts.map +1 -1
  8. package/dist/env/index.js +2 -0
  9. package/dist/env/index.js.map +1 -1
  10. package/dist/env/node.d.ts.map +1 -1
  11. package/dist/env/node.js +51 -58
  12. package/dist/env/node.js.map +1 -1
  13. package/dist/harness/compaction.d.ts +56 -0
  14. package/dist/harness/compaction.d.ts.map +1 -0
  15. package/dist/harness/compaction.js +385 -0
  16. package/dist/harness/compaction.js.map +1 -0
  17. package/dist/harness/config.d.ts +10 -1
  18. package/dist/harness/config.d.ts.map +1 -1
  19. package/dist/harness/config.js +6 -0
  20. package/dist/harness/config.js.map +1 -1
  21. package/dist/harness/context.d.ts +8 -0
  22. package/dist/harness/context.d.ts.map +1 -1
  23. package/dist/harness/context.js +32 -21
  24. package/dist/harness/context.js.map +1 -1
  25. package/dist/harness/events.d.ts +166 -0
  26. package/dist/harness/events.d.ts.map +1 -0
  27. package/dist/harness/events.js +319 -0
  28. package/dist/harness/events.js.map +1 -0
  29. package/dist/harness/generation.d.ts +37 -6
  30. package/dist/harness/generation.d.ts.map +1 -1
  31. package/dist/harness/generation.js +350 -72
  32. package/dist/harness/generation.js.map +1 -1
  33. package/dist/harness/harness.d.ts.map +1 -1
  34. package/dist/harness/harness.js +124 -3
  35. package/dist/harness/harness.js.map +1 -1
  36. package/dist/harness/inbox.d.ts +57 -0
  37. package/dist/harness/inbox.d.ts.map +1 -0
  38. package/dist/harness/inbox.js +99 -0
  39. package/dist/harness/inbox.js.map +1 -0
  40. package/dist/harness/json.d.ts +10 -0
  41. package/dist/harness/json.d.ts.map +1 -0
  42. package/dist/harness/json.js +33 -0
  43. package/dist/harness/json.js.map +1 -0
  44. package/dist/harness/live.d.ts +66 -7
  45. package/dist/harness/live.d.ts.map +1 -1
  46. package/dist/harness/live.js +71 -7
  47. package/dist/harness/live.js.map +1 -1
  48. package/dist/harness/output.d.ts +62 -0
  49. package/dist/harness/output.d.ts.map +1 -0
  50. package/dist/harness/output.js +261 -0
  51. package/dist/harness/output.js.map +1 -0
  52. package/dist/harness/prompt.d.ts +10 -5
  53. package/dist/harness/prompt.d.ts.map +1 -1
  54. package/dist/harness/prompt.js +66 -13
  55. package/dist/harness/prompt.js.map +1 -1
  56. package/dist/harness/registry.d.ts.map +1 -1
  57. package/dist/harness/registry.js +11 -2
  58. package/dist/harness/registry.js.map +1 -1
  59. package/dist/harness/scheduler.d.ts +37 -12
  60. package/dist/harness/scheduler.d.ts.map +1 -1
  61. package/dist/harness/scheduler.js +632 -72
  62. package/dist/harness/scheduler.js.map +1 -1
  63. package/dist/harness/submissions.d.ts +12 -7
  64. package/dist/harness/submissions.d.ts.map +1 -1
  65. package/dist/harness/submissions.js +72 -33
  66. package/dist/harness/submissions.js.map +1 -1
  67. package/dist/harness/tool.d.ts +36 -0
  68. package/dist/harness/tool.d.ts.map +1 -0
  69. package/dist/harness/tool.js +412 -0
  70. package/dist/harness/tool.js.map +1 -0
  71. package/dist/harness/types.d.ts +185 -11
  72. package/dist/harness/types.d.ts.map +1 -1
  73. package/dist/harness/types.js.map +1 -1
  74. package/dist/harness/usage.d.ts +18 -0
  75. package/dist/harness/usage.d.ts.map +1 -0
  76. package/dist/harness/usage.js +57 -0
  77. package/dist/harness/usage.js.map +1 -0
  78. package/dist/harness/view.d.ts +43 -0
  79. package/dist/harness/view.d.ts.map +1 -0
  80. package/dist/harness/view.js +194 -0
  81. package/dist/harness/view.js.map +1 -0
  82. package/dist/index.d.ts +10 -4
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +6 -1
  85. package/dist/index.js.map +1 -1
  86. package/dist/session/observation.d.ts +18 -11
  87. package/dist/session/observation.d.ts.map +1 -1
  88. package/dist/session/observation.js +24 -13
  89. package/dist/session/observation.js.map +1 -1
  90. package/dist/session/session.d.ts +10 -1
  91. package/dist/session/session.d.ts.map +1 -1
  92. package/dist/session/session.js +18 -4
  93. package/dist/session/session.js.map +1 -1
  94. package/dist/session/transaction.d.ts +10 -1
  95. package/dist/session/transaction.d.ts.map +1 -1
  96. package/dist/session/transaction.js +83 -27
  97. package/dist/session/transaction.js.map +1 -1
  98. package/dist/storage/jsonl/storage.d.ts +22 -2
  99. package/dist/storage/jsonl/storage.d.ts.map +1 -1
  100. package/dist/storage/jsonl/storage.js +1 -1
  101. package/dist/storage/jsonl/storage.js.map +1 -1
  102. package/dist/storage/memory.js +1 -1
  103. package/dist/storage/memory.js.map +1 -1
  104. package/dist/storage/sqlite/migrations.js +1 -1
  105. package/dist/storage/sqlite/migrations.js.map +1 -1
  106. package/dist/testing/storage-benchmark.d.ts.map +1 -1
  107. package/dist/testing/storage-benchmark.js +0 -1
  108. package/dist/testing/storage-benchmark.js.map +1 -1
  109. package/dist/testing/storage-conformance.d.ts.map +1 -1
  110. package/dist/testing/storage-conformance.js +34 -2
  111. package/dist/testing/storage-conformance.js.map +1 -1
  112. package/dist/tools/bash.d.ts +28 -0
  113. package/dist/tools/bash.d.ts.map +1 -0
  114. package/dist/tools/bash.js +69 -0
  115. package/dist/tools/bash.js.map +1 -0
  116. package/dist/tools/edit-diff.d.ts +89 -0
  117. package/dist/tools/edit-diff.d.ts.map +1 -0
  118. package/dist/tools/edit-diff.js +386 -0
  119. package/dist/tools/edit-diff.js.map +1 -0
  120. package/dist/tools/edit.d.ts +18 -0
  121. package/dist/tools/edit.d.ts.map +1 -0
  122. package/dist/tools/edit.js +116 -0
  123. package/dist/tools/edit.js.map +1 -0
  124. package/dist/tools/env.d.ts +5 -0
  125. package/dist/tools/env.d.ts.map +1 -0
  126. package/dist/tools/env.js +7 -0
  127. package/dist/tools/env.js.map +1 -0
  128. package/dist/tools/file-mutation-queue.d.ts +5 -0
  129. package/dist/tools/file-mutation-queue.d.ts.map +1 -0
  130. package/dist/tools/file-mutation-queue.js +46 -0
  131. package/dist/tools/file-mutation-queue.js.map +1 -0
  132. package/dist/tools/image.d.ts +2 -0
  133. package/dist/tools/image.d.ts.map +1 -0
  134. package/dist/tools/image.js +92 -0
  135. package/dist/tools/image.js.map +1 -0
  136. package/dist/tools/index.d.ts +5 -0
  137. package/dist/tools/index.d.ts.map +1 -0
  138. package/dist/tools/index.js +5 -0
  139. package/dist/tools/index.js.map +1 -0
  140. package/dist/tools/path-utils.d.ts +5 -0
  141. package/dist/tools/path-utils.d.ts.map +1 -0
  142. package/dist/tools/path-utils.js +26 -0
  143. package/dist/tools/path-utils.js.map +1 -0
  144. package/dist/tools/read.d.ts +17 -0
  145. package/dist/tools/read.d.ts.map +1 -0
  146. package/dist/tools/read.js +100 -0
  147. package/dist/tools/read.js.map +1 -0
  148. package/dist/tools/write.d.ts +10 -0
  149. package/dist/tools/write.d.ts.map +1 -0
  150. package/dist/tools/write.js +30 -0
  151. package/dist/tools/write.js.map +1 -0
  152. package/dist/{env/utils/truncate.d.ts → truncate.d.ts} +1 -17
  153. package/dist/truncate.d.ts.map +1 -0
  154. package/dist/truncate.js +146 -0
  155. package/dist/truncate.js.map +1 -0
  156. package/dist/types.d.ts +86 -19
  157. package/dist/types.d.ts.map +1 -1
  158. package/dist/types.js.map +1 -1
  159. package/docs/pico-v5-handoff.md +366 -86
  160. package/docs/pico-v5.md +1373 -283
  161. package/package.json +11 -3
  162. package/dist/env/utils/adaptive-publisher.d.ts +0 -24
  163. package/dist/env/utils/adaptive-publisher.d.ts.map +0 -1
  164. package/dist/env/utils/adaptive-publisher.js +0 -79
  165. package/dist/env/utils/adaptive-publisher.js.map +0 -1
  166. package/dist/env/utils/output-capture.d.ts +0 -31
  167. package/dist/env/utils/output-capture.d.ts.map +0 -1
  168. package/dist/env/utils/output-capture.js +0 -238
  169. package/dist/env/utils/output-capture.js.map +0 -1
  170. package/dist/env/utils/truncate.d.ts.map +0 -1
  171. package/dist/env/utils/truncate.js +0 -294
  172. package/dist/env/utils/truncate.js.map +0 -1
@@ -0,0 +1,43 @@
1
+ import { type AttachedReplicatedState, type Context } from "@earendil-works/chord";
2
+ import { type Op } from "@earendil-works/chord/delta";
3
+ import type { SessionImpl } from "../session/session.ts";
4
+ import type { CommitPublication, ConversationId, ConversationRecord, EntryRecord, JsonObject, Storage, WatchHandle } from "../types.ts";
5
+ /** Structural mount of one conversation's active transcript and built-in documents (spec §9.3). */
6
+ export type ConversationView = {
7
+ readonly conversation: ConversationRecord;
8
+ /** Raw active entries, as `ContextView.entries`: the head marker, then the non-head entries from its head. */
9
+ readonly entries: readonly EntryRecord[];
10
+ /** `pi.conversation.config`, `pi.live`, `pi.inbox`, and `pi.usage`, keyed by kind; absent documents are absent. */
11
+ readonly docs: Readonly<Record<string, JsonObject>>;
12
+ };
13
+ /** Receives each next revision of a mount, and the Session's close. */
14
+ export type ViewObserver = {
15
+ advance?(value: ConversationView, ops: readonly Op[], context: Context): void;
16
+ /** Every publication, after the mount took it; `ops` are the mount's, possibly none. */
17
+ publication?(before: ConversationView, after: ConversationView, ops: readonly Op[], publication: CommitPublication, context: Context): void;
18
+ closeSession(): void;
19
+ };
20
+ /** The view mounts of a Harness, for adapters built on them. */
21
+ export declare function conversationViews(harness: object): ConversationViews;
22
+ /**
23
+ * The Harness's conversation view mounts: at most one per conversation, built on the Session line by its first
24
+ * observer and dropped with its last. Each mount advances from the Session's commit publications, which are durable.
25
+ */
26
+ export declare class ConversationViews {
27
+ #private;
28
+ constructor(session: SessionImpl, storage: Storage);
29
+ /** A disposable read-only Chord state of the view. */
30
+ state(id: ConversationId, context: Context): Promise<AttachedReplicatedState<ConversationView>>;
31
+ /** A serialized exact-frame watch of the view; cancelling `context` stops it. */
32
+ watch(id: ConversationId, context: Context): Promise<WatchHandle<ConversationView>>;
33
+ /**
34
+ * Register an observer created from the current revision, atomically on the Session line: it sees every later
35
+ * publication and nothing earlier. `create` may read committed Storage, still on the line. `release` drops it, and
36
+ * the mount with its last observer.
37
+ */
38
+ attach<O extends ViewObserver>(id: ConversationId, create: (value: ConversationView, release: () => void, storage: Storage) => O | Promise<O>, context: Context): Promise<{
39
+ observer: O;
40
+ detach: () => void;
41
+ }>;
42
+ }
43
+ //# sourceMappingURL=view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../src/harness/view.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,uBAAuB,EAAE,KAAK,OAAO,EAAmC,MAAM,uBAAuB,CAAC;AAEpH,OAAO,EAAqC,KAAK,EAAE,EAAa,MAAM,6BAA6B,CAAC;AAEpG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EACX,iBAAiB,EAEjB,cAAc,EACd,kBAAkB,EAElB,WAAW,EACX,UAAU,EACV,OAAO,EACP,WAAW,EACX,MAAM,aAAa,CAAC;AAQrB,mGAAmG;AACnG,MAAM,MAAM,gBAAgB,GAAG;IAC9B,QAAQ,CAAC,YAAY,EAAE,kBAAkB,CAAC;IAC1C,8GAA8G;IAC9G,QAAQ,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAC;IACzC,mHAAmH;IACnH,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;CACpD,CAAC;AAEF,uEAAuE;AACvE,MAAM,MAAM,YAAY,GAAG;IAC1B,OAAO,CAAC,CAAC,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9E,wFAAwF;IACxF,WAAW,CAAC,CACX,MAAM,EAAE,gBAAgB,EACxB,KAAK,EAAE,gBAAgB,EACvB,GAAG,EAAE,SAAS,EAAE,EAAE,EAClB,WAAW,EAAE,iBAAiB,EAC9B,OAAO,EAAE,OAAO,GACd,IAAI,CAAC;IACR,YAAY,IAAI,IAAI,CAAC;CACrB,CAAC;AAoBF,gEAAgE;AAChE,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAIpE;AAED;;;GAGG;AACH,qBAAa,iBAAiB;;IAM7B,YAAY,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAajD;IAED,sDAAsD;IAChD,KAAK,CAAC,EAAE,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,uBAAuB,CAAC,gBAAgB,CAAC,CAAC,CAYpG;IAED,iFAAiF;IAC3E,KAAK,CAAC,EAAE,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC,CAaxF;IAED;;;;OAIG;IACH,MAAM,CAAC,CAAC,SAAS,YAAY,EAC5B,EAAE,EAAE,cAAc,EAClB,MAAM,EAAE,CAAC,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,IAAI,EAAE,OAAO,EAAE,OAAO,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAC1F,OAAO,EAAE,OAAO,GACd,OAAO,CAAC;QAAE,QAAQ,EAAE,CAAC,CAAC;QAAC,MAAM,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC,CAe9C;CAiBD"}
@@ -0,0 +1,194 @@
1
+ import { replicatedState } from "@earendil-works/chord";
2
+ import { withoutAbortSignal } from "@earendil-works/chord/context";
3
+ import { applyImmutable } from "@earendil-works/chord/delta";
4
+ import { CommittedStateSource, CommittedWatch } from "../session/observation.js";
5
+ import { ConversationConfig } from "./config.js";
6
+ import { activeEntries, captureContextBounds } from "./context.js";
7
+ import { InboxDoc } from "./inbox.js";
8
+ import { LiveDoc } from "./live.js";
9
+ import { UsageDoc } from "./usage.js";
10
+ import { closedError } from "./util.js";
11
+ const MOUNTED = [
12
+ ConversationConfig,
13
+ LiveDoc,
14
+ InboxDoc,
15
+ UsageDoc,
16
+ ];
17
+ const MOUNTED_KINDS = new Set(MOUNTED.map((token) => token.definition.kind));
18
+ const VIEWS = new WeakMap();
19
+ /** The view mounts of a Harness, for adapters built on them. */
20
+ export function conversationViews(harness) {
21
+ const views = VIEWS.get(harness);
22
+ if (views === undefined)
23
+ throw new Error("Not a Harness");
24
+ return views;
25
+ }
26
+ /**
27
+ * The Harness's conversation view mounts: at most one per conversation, built on the Session line by its first
28
+ * observer and dropped with its last. Each mount advances from the Session's commit publications, which are durable.
29
+ */
30
+ export class ConversationViews {
31
+ #session;
32
+ #storage;
33
+ #mounts = new Map();
34
+ #closed = false;
35
+ constructor(session, storage) {
36
+ this.#session = session;
37
+ this.#storage = storage;
38
+ VIEWS.set(session, this);
39
+ session.subscribeCommits((publication, context) => {
40
+ for (const [id, mount] of this.#mounts)
41
+ advance(id, mount, publication, context);
42
+ });
43
+ session.subscribeClose(() => {
44
+ this.#closed = true;
45
+ for (const mount of this.#mounts.values())
46
+ for (const observer of [...mount.observers])
47
+ observer.closeSession();
48
+ this.#mounts.clear();
49
+ });
50
+ }
51
+ /** A disposable read-only Chord state of the view. */
52
+ async state(id, context) {
53
+ const { observer, detach } = await this.attach(id, (value, release) => new CommittedStateSource(value, release), context);
54
+ try {
55
+ return replicatedState(observer);
56
+ }
57
+ catch (error) {
58
+ detach();
59
+ throw error;
60
+ }
61
+ }
62
+ /** A serialized exact-frame watch of the view; cancelling `context` stops it. */
63
+ async watch(id, context) {
64
+ const { observer } = await this.attach(id, (value, release) => new CommittedWatch(value, release), context);
65
+ const signal = context.abortSignal;
66
+ if (signal?.aborted) {
67
+ observer.cancel();
68
+ throw signal.reason;
69
+ }
70
+ if (signal !== undefined)
71
+ observer.observeCancellation(signal);
72
+ return observer;
73
+ }
74
+ /**
75
+ * Register an observer created from the current revision, atomically on the Session line: it sees every later
76
+ * publication and nothing earlier. `create` may read committed Storage, still on the line. `release` drops it, and
77
+ * the mount with its last observer.
78
+ */
79
+ attach(id, create, context) {
80
+ return this.#session.readOnLine(async () => {
81
+ const mount = this.#mounts.get(id) ?? (await this.#build(id, context));
82
+ const detach = () => {
83
+ mount.observers.delete(observer);
84
+ if (mount.observers.size === 0 && this.#mounts.get(id) === mount)
85
+ this.#mounts.delete(id);
86
+ };
87
+ const observer = await create(mount.value, detach, this.#storage);
88
+ // Close or cancellation may begin while the mount hydrates; register nothing then.
89
+ if (this.#closed)
90
+ throw closedError();
91
+ context.abortSignal?.throwIfAborted();
92
+ this.#mounts.set(id, mount);
93
+ mount.observers.add(observer);
94
+ return { observer, detach };
95
+ });
96
+ }
97
+ async #build(id, context) {
98
+ const conversation = await this.#storage.conversation(id, context);
99
+ if (conversation === undefined)
100
+ throw new Error(`Conversation ${id} does not exist`);
101
+ const bounds = await captureContextBounds(this.#storage, id, context);
102
+ const entries = await activeEntries(this.#storage, id, bounds, context);
103
+ const docs = {};
104
+ const incarnations = new Map();
105
+ for (const token of MOUNTED) {
106
+ const loaded = await this.#session.conversationDocumentOnLine(token, id, context);
107
+ if (loaded === undefined)
108
+ continue;
109
+ docs[token.definition.kind] = loaded.value;
110
+ incarnations.set(token.definition.kind, { id: loaded.record.id, version: loaded.version });
111
+ }
112
+ return { value: { conversation, entries, docs }, docs: incarnations, observers: new Set() };
113
+ }
114
+ }
115
+ /** Derive the mount's operations from one publication, apply them, and hand the revision to every observer. */
116
+ function advance(id, mount, publication, context) {
117
+ const docOps = [];
118
+ const entryOps = [];
119
+ let entries = mount.value.entries;
120
+ // Entry writes are published in ID order.
121
+ for (const change of publication.changes) {
122
+ if (change.type === "entry" && change.value.conversationId === id) {
123
+ const entry = change.value;
124
+ const value = entry;
125
+ if (entry.head === undefined) {
126
+ entryOps.push(["p", ["entries"], entries.length, 0, [value]]);
127
+ entries = [...entries, entry];
128
+ continue;
129
+ }
130
+ // A head marker keeps the non-head entries from its head, which are always a suffix, and goes in front.
131
+ const target = entry.head;
132
+ let kept = entries.findIndex((candidate) => candidate.head === undefined && candidate.id >= target);
133
+ if (kept < 0)
134
+ kept = entries.length;
135
+ entryOps.push(["p", ["entries"], 0, kept, [value]]);
136
+ entries = [entry, ...entries.slice(kept)];
137
+ continue;
138
+ }
139
+ if (change.type !== "document" || change.conversationId !== id)
140
+ continue;
141
+ const kind = change.record.kind;
142
+ if (!MOUNTED_KINDS.has(kind) || change.record.key !== undefined)
143
+ continue;
144
+ const path = ["docs", kind];
145
+ const mounted = mount.docs.get(kind);
146
+ if (change.value === null) {
147
+ if (mounted?.id !== change.record.id)
148
+ continue;
149
+ mount.docs.delete(kind);
150
+ docOps.push(["d", path]);
151
+ }
152
+ else if (mounted?.id === change.record.id && mounted.version === change.version) {
153
+ for (const op of change.ops)
154
+ docOps.push(prefixed(op, path));
155
+ }
156
+ else {
157
+ mount.docs.set(kind, { id: change.record.id, version: change.version });
158
+ docOps.push(["s", path, change.value]);
159
+ }
160
+ }
161
+ const before = mount.value;
162
+ const ops = [...docOps, ...entryOps];
163
+ const frameContext = withoutAbortSignal(context);
164
+ if (ops.length > 0) {
165
+ const value = docOps.length === 0 ? mount.value : applyImmutable(mount.value, docOps);
166
+ mount.value = entries === value.entries ? value : { ...value, entries };
167
+ for (const observer of [...mount.observers])
168
+ observer.advance?.(mount.value, ops, frameContext);
169
+ }
170
+ for (const observer of [...mount.observers]) {
171
+ observer.publication?.(before, mount.value, ops, publication, frameContext);
172
+ }
173
+ }
174
+ /** `op` moved under `prefix`; a root replacement becomes a set of the prefix. */
175
+ function prefixed(op, prefix) {
176
+ const at = (path) => [...prefix, ...path];
177
+ switch (op[0]) {
178
+ case "r":
179
+ return ["s", prefix, op[1]];
180
+ case "p":
181
+ return ["p", at(op[1]), op[2], op[3], op[4]];
182
+ case "m":
183
+ return ["m", at(op[1]), op[2]];
184
+ case "s":
185
+ return ["s", at(op[1]), op[2]];
186
+ case "d":
187
+ return ["d", at(op[1])];
188
+ case "a":
189
+ return ["a", at(op[1]), op[2]];
190
+ case "t":
191
+ return ["t", at(op[1]), op[2]];
192
+ }
193
+ }
194
+ //# sourceMappingURL=view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view.js","sourceRoot":"","sources":["../../src/harness/view.ts"],"names":[],"mappings":"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","sourcesContent":["import { type AttachedReplicatedState, type Context, type JsonValue, replicatedState } from \"@earendil-works/chord\";\nimport { withoutAbortSignal } from \"@earendil-works/chord/context\";\nimport { applyImmutable, type NonEmptyPath, type Op, type Path } from \"@earendil-works/chord/delta\";\nimport { CommittedStateSource, CommittedWatch } from \"../session/observation.ts\";\nimport type { SessionImpl } from \"../session/session.ts\";\nimport type {\n\tCommitPublication,\n\tConversationDocToken,\n\tConversationId,\n\tConversationRecord,\n\tDocumentId,\n\tEntryRecord,\n\tJsonObject,\n\tStorage,\n\tWatchHandle,\n} from \"../types.ts\";\nimport { ConversationConfig } from \"./config.ts\";\nimport { activeEntries, captureContextBounds } from \"./context.ts\";\nimport { InboxDoc } from \"./inbox.ts\";\nimport { LiveDoc } from \"./live.ts\";\nimport { UsageDoc } from \"./usage.ts\";\nimport { closedError } from \"./util.ts\";\n\n/** Structural mount of one conversation's active transcript and built-in documents (spec §9.3). */\nexport type ConversationView = {\n\treadonly conversation: ConversationRecord;\n\t/** Raw active entries, as `ContextView.entries`: the head marker, then the non-head entries from its head. */\n\treadonly entries: readonly EntryRecord[];\n\t/** `pi.conversation.config`, `pi.live`, `pi.inbox`, and `pi.usage`, keyed by kind; absent documents are absent. */\n\treadonly docs: Readonly<Record<string, JsonObject>>;\n};\n\n/** Receives each next revision of a mount, and the Session's close. */\nexport type ViewObserver = {\n\tadvance?(value: ConversationView, ops: readonly Op[], context: Context): void;\n\t/** Every publication, after the mount took it; `ops` are the mount's, possibly none. */\n\tpublication?(\n\t\tbefore: ConversationView,\n\t\tafter: ConversationView,\n\t\tops: readonly Op[],\n\t\tpublication: CommitPublication,\n\t\tcontext: Context,\n\t): void;\n\tcloseSession(): void;\n};\n\nconst MOUNTED = [\n\tConversationConfig,\n\tLiveDoc,\n\tInboxDoc,\n\tUsageDoc,\n] as unknown as readonly ConversationDocToken<JsonObject>[];\nconst MOUNTED_KINDS: ReadonlySet<string> = new Set(MOUNTED.map((token) => token.definition.kind));\n\n/** One conversation's mount: its current revision, the document incarnations it shows, and its observers. */\ntype Mount = {\n\tvalue: ConversationView;\n\t/** Mounted incarnation and definition version per kind; another incarnation or version is set whole. */\n\treadonly docs: Map<string, { id: DocumentId; version: number }>;\n\treadonly observers: Set<ViewObserver>;\n};\n\nconst VIEWS = new WeakMap<object, ConversationViews>();\n\n/** The view mounts of a Harness, for adapters built on them. */\nexport function conversationViews(harness: object): ConversationViews {\n\tconst views = VIEWS.get(harness);\n\tif (views === undefined) throw new Error(\"Not a Harness\");\n\treturn views;\n}\n\n/**\n * The Harness's conversation view mounts: at most one per conversation, built on the Session line by its first\n * observer and dropped with its last. Each mount advances from the Session's commit publications, which are durable.\n */\nexport class ConversationViews {\n\treadonly #session: SessionImpl;\n\treadonly #storage: Storage;\n\treadonly #mounts = new Map<ConversationId, Mount>();\n\t#closed = false;\n\n\tconstructor(session: SessionImpl, storage: Storage) {\n\t\tthis.#session = session;\n\t\tthis.#storage = storage;\n\t\tVIEWS.set(session, this);\n\t\tsession.subscribeCommits((publication, context) => {\n\t\t\tfor (const [id, mount] of this.#mounts) advance(id, mount, publication, context);\n\t\t});\n\t\tsession.subscribeClose(() => {\n\t\t\tthis.#closed = true;\n\t\t\tfor (const mount of this.#mounts.values())\n\t\t\t\tfor (const observer of [...mount.observers]) observer.closeSession();\n\t\t\tthis.#mounts.clear();\n\t\t});\n\t}\n\n\t/** A disposable read-only Chord state of the view. */\n\tasync state(id: ConversationId, context: Context): Promise<AttachedReplicatedState<ConversationView>> {\n\t\tconst { observer, detach } = await this.attach(\n\t\t\tid,\n\t\t\t(value, release) => new CommittedStateSource<ConversationView>(value, release),\n\t\t\tcontext,\n\t\t);\n\t\ttry {\n\t\t\treturn replicatedState(observer);\n\t\t} catch (error) {\n\t\t\tdetach();\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/** A serialized exact-frame watch of the view; cancelling `context` stops it. */\n\tasync watch(id: ConversationId, context: Context): Promise<WatchHandle<ConversationView>> {\n\t\tconst { observer } = await this.attach(\n\t\t\tid,\n\t\t\t(value, release) => new CommittedWatch<ConversationView>(value, release),\n\t\t\tcontext,\n\t\t);\n\t\tconst signal = context.abortSignal;\n\t\tif (signal?.aborted) {\n\t\t\tobserver.cancel();\n\t\t\tthrow signal.reason;\n\t\t}\n\t\tif (signal !== undefined) observer.observeCancellation(signal);\n\t\treturn observer;\n\t}\n\n\t/**\n\t * Register an observer created from the current revision, atomically on the Session line: it sees every later\n\t * publication and nothing earlier. `create` may read committed Storage, still on the line. `release` drops it, and\n\t * the mount with its last observer.\n\t */\n\tattach<O extends ViewObserver>(\n\t\tid: ConversationId,\n\t\tcreate: (value: ConversationView, release: () => void, storage: Storage) => O | Promise<O>,\n\t\tcontext: Context,\n\t): Promise<{ observer: O; detach: () => void }> {\n\t\treturn this.#session.readOnLine(async () => {\n\t\t\tconst mount = this.#mounts.get(id) ?? (await this.#build(id, context));\n\t\t\tconst detach = (): void => {\n\t\t\t\tmount.observers.delete(observer);\n\t\t\t\tif (mount.observers.size === 0 && this.#mounts.get(id) === mount) this.#mounts.delete(id);\n\t\t\t};\n\t\t\tconst observer = await create(mount.value, detach, this.#storage);\n\t\t\t// Close or cancellation may begin while the mount hydrates; register nothing then.\n\t\t\tif (this.#closed) throw closedError();\n\t\t\tcontext.abortSignal?.throwIfAborted();\n\t\t\tthis.#mounts.set(id, mount);\n\t\t\tmount.observers.add(observer);\n\t\t\treturn { observer, detach };\n\t\t});\n\t}\n\n\tasync #build(id: ConversationId, context: Context): Promise<Mount> {\n\t\tconst conversation = await this.#storage.conversation(id, context);\n\t\tif (conversation === undefined) throw new Error(`Conversation ${id} does not exist`);\n\t\tconst bounds = await captureContextBounds(this.#storage, id, context);\n\t\tconst entries = await activeEntries(this.#storage, id, bounds, context);\n\t\tconst docs: Record<string, JsonObject> = {};\n\t\tconst incarnations = new Map<string, { id: DocumentId; version: number }>();\n\t\tfor (const token of MOUNTED) {\n\t\t\tconst loaded = await this.#session.conversationDocumentOnLine(token, id, context);\n\t\t\tif (loaded === undefined) continue;\n\t\t\tdocs[token.definition.kind] = loaded.value;\n\t\t\tincarnations.set(token.definition.kind, { id: loaded.record.id, version: loaded.version });\n\t\t}\n\t\treturn { value: { conversation, entries, docs }, docs: incarnations, observers: new Set() };\n\t}\n}\n\n/** Derive the mount's operations from one publication, apply them, and hand the revision to every observer. */\nfunction advance(id: ConversationId, mount: Mount, publication: CommitPublication, context: Context): void {\n\tconst docOps: Op[] = [];\n\tconst entryOps: Op[] = [];\n\tlet entries = mount.value.entries;\n\t// Entry writes are published in ID order.\n\tfor (const change of publication.changes) {\n\t\tif (change.type === \"entry\" && change.value.conversationId === id) {\n\t\t\tconst entry = change.value;\n\t\t\tconst value = entry as unknown as JsonValue;\n\t\t\tif (entry.head === undefined) {\n\t\t\t\tentryOps.push([\"p\", [\"entries\"], entries.length, 0, [value]]);\n\t\t\t\tentries = [...entries, entry];\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// A head marker keeps the non-head entries from its head, which are always a suffix, and goes in front.\n\t\t\tconst target = entry.head;\n\t\t\tlet kept = entries.findIndex((candidate) => candidate.head === undefined && candidate.id >= target);\n\t\t\tif (kept < 0) kept = entries.length;\n\t\t\tentryOps.push([\"p\", [\"entries\"], 0, kept, [value]]);\n\t\t\tentries = [entry, ...entries.slice(kept)];\n\t\t\tcontinue;\n\t\t}\n\t\tif (change.type !== \"document\" || change.conversationId !== id) continue;\n\t\tconst kind = change.record.kind;\n\t\tif (!MOUNTED_KINDS.has(kind) || change.record.key !== undefined) continue;\n\t\tconst path: NonEmptyPath = [\"docs\", kind];\n\t\tconst mounted = mount.docs.get(kind);\n\t\tif (change.value === null) {\n\t\t\tif (mounted?.id !== change.record.id) continue;\n\t\t\tmount.docs.delete(kind);\n\t\t\tdocOps.push([\"d\", path]);\n\t\t} else if (mounted?.id === change.record.id && mounted.version === change.version) {\n\t\t\tfor (const op of change.ops) docOps.push(prefixed(op, path));\n\t\t} else {\n\t\t\tmount.docs.set(kind, { id: change.record.id, version: change.version! });\n\t\t\tdocOps.push([\"s\", path, change.value]);\n\t\t}\n\t}\n\tconst before = mount.value;\n\tconst ops = [...docOps, ...entryOps];\n\tconst frameContext = withoutAbortSignal(context);\n\tif (ops.length > 0) {\n\t\tconst value = docOps.length === 0 ? mount.value : applyImmutable(mount.value, docOps);\n\t\tmount.value = entries === value.entries ? value : { ...value, entries };\n\t\tfor (const observer of [...mount.observers]) observer.advance?.(mount.value, ops, frameContext);\n\t}\n\tfor (const observer of [...mount.observers]) {\n\t\tobserver.publication?.(before, mount.value, ops, publication, frameContext);\n\t}\n}\n\n/** `op` moved under `prefix`; a root replacement becomes a set of the prefix. */\nfunction prefixed(op: Op, prefix: NonEmptyPath): Op {\n\tconst at = (path: Path): NonEmptyPath => [...prefix, ...path] as unknown as NonEmptyPath;\n\tswitch (op[0]) {\n\t\tcase \"r\":\n\t\t\treturn [\"s\", prefix, op[1]];\n\t\tcase \"p\":\n\t\t\treturn [\"p\", at(op[1]), op[2], op[3], op[4]];\n\t\tcase \"m\":\n\t\t\treturn [\"m\", at(op[1]), op[2]];\n\t\tcase \"s\":\n\t\t\treturn [\"s\", at(op[1]), op[2]];\n\t\tcase \"d\":\n\t\t\treturn [\"d\", at(op[1])];\n\t\tcase \"a\":\n\t\t\treturn [\"a\", at(op[1]), op[2]];\n\t\tcase \"t\":\n\t\t\treturn [\"t\", at(op[1]), op[2]];\n\t}\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -1,15 +1,21 @@
1
1
  export { defineDoc, defineDocFamily } from "./documents.ts";
2
- export { AssistantEntry, defineEntry, SystemEntry, ToolResultEntry, UserEntry } from "./entries.ts";
2
+ export { AssistantEntry, CompactionEntry, defineEntry, ResetEntry, SystemEntry, ToolResultEntry, UserEntry, } from "./entries.ts";
3
3
  export { ConversationBusy, ReadAfterWrite, StorageRejected } from "./errors.ts";
4
+ export { type CompactionCheckpoint, type CompactionInput, CompactionTask, type SummaryRequest, } from "./harness/compaction.ts";
4
5
  export { ConversationConfig, type ConversationConfigState } from "./harness/config.ts";
6
+ export { type AgentEvent, type AgentEventStream, type MessageChange, type SnapshotEvent, watchEvents, } from "./harness/events.ts";
5
7
  export { type GenerationCheckpoint, type GenerationInput, type GenerationResult, GenerationTask, } from "./harness/generation.ts";
6
8
  export { Harness } from "./harness/harness.ts";
7
- export { LiveDoc, type LiveState } from "./harness/live.ts";
9
+ export { InboxDoc, type InboxItem, type InboxState } from "./harness/inbox.ts";
10
+ export { type CompactionStatus, LiveDoc, type LiveState, type ToolSlot } from "./harness/live.ts";
8
11
  export { createRegistry } from "./harness/registry.ts";
9
- export type { AnyTask, ContextView, Conversation, ConversationCreateOptions, ConversationHandle, ConversationInit, ConversationRetryPolicy, ConversationSetup, ConversationStreamOptions, HarnessInspection, HarnessOptions, HookRegistration, HookScope, HooksOf, InputSubmissionDraft, ModelRef, PromptInput, PromptSection, PromptSectionWrapper, Registration, Registry, RegistryFailure, RegistryReader, RegistrySnapshot, SettledSubmissionRecord, SettledTask, Submission, SubmissionDraft, TaskInspection, ToolControl, ToolExecutionApi, ToolExecutionResult, ToolRegistration, ToolWrapper, UserInput, } from "./harness/types.ts";
12
+ export { ToolTask, type ToolTaskCheckpoint, type ToolTaskInput, type ToolTaskResult } from "./harness/tool.ts";
13
+ export type { AnyTask, CompactionHooks, CompactionPolicy, CompactionReason, CompactionResult, ContextView, Conversation, ConversationAbortOptions, ConversationCreateOptions, ConversationHandle, ConversationInit, ConversationRetryPolicy, ConversationSetup, ConversationStreamOptions, GenerationHooks, HarnessInspection, HarnessOptions, HookApi, HookRegistration, HookResult, HookScope, HooksOf, InputSubmissionDraft, ModelRef, PromptInput, PromptSection, PromptSectionWrapper, QueueMode, Registration, Registry, RegistryFailure, RegistryReader, RegistrySnapshot, SettledSubmissionRecord, SettledTask, Submission, SubmissionDraft, TaskInspection, ToolControl, ToolDiagnostic, ToolExecutionApi, ToolExecutionMode, ToolExecutionResult, ToolHooks, ToolRegistration, ToolWrapper, UserInput, } from "./harness/types.ts";
14
+ export { UsageDoc, type UsageState } from "./harness/usage.ts";
15
+ export type { ConversationView } from "./harness/view.ts";
10
16
  export { createSession } from "./session/session.ts";
11
17
  export { MemoryStorage } from "./storage/memory.ts";
12
18
  export { defineTask } from "./tasks.ts";
13
- export type { CheckpointInfo, CommitChange, CommitPublication, CommonDocDefinition, ContextEdit, ConversationDocFamilyToken, ConversationDocToken, ConversationId, ConversationOwnership, ConversationQuery, ConversationRecord, Cursor, DocDefinition, DocFamilyDefinition, DocFamilyToken, DocToken, DocumentAddress, DocumentCommitChange, DocumentContent, DocumentCopySource, DocumentCreate, DocumentId, DocumentObserver, DocumentPoint, DocumentQuery, DocumentReader, DocumentRecord, DocumentSemantics, DocumentState, DocumentWatch, Entry, EntryDraft, EntryId, EntryQuery, EntryRecord, Id, JsonObject, LatestConversationSemantics, NextTaskState, Page, PhaseHandler, RewindableConversationDocFamilyToken, RewindableConversationDocToken, RewindableConversationSemantics, RunningTask, Seq, Session, SessionDocFamilyToken, SessionDocToken, Storage, StorageWrite, StoredDocument, SubmissionCreate, SubmissionId, SubmissionQuery, SubmissionRecord, SubmissionSettlement, TableCommitChange, Task, TaskDefinition, TaskDocFamilyToken, TaskDocToken, TaskId, TaskOptions, TaskOutcome, TaskOutcomeError, TaskQuery, TaskRecord, TaskRuntime, TaskState, Tx, TypedEntry, TypedEntryDraft, WatchEnd, WatchHandle, } from "./types.ts";
19
+ export type { CheckpointInfo, CommitChange, CommitPublication, CommonDocDefinition, ContextEdit, ConversationDocFamilyToken, ConversationDocToken, ConversationId, ConversationOwnership, ConversationQuery, ConversationRecord, Cursor, DocDefinition, DocFamilyDefinition, DocFamilyToken, DocToken, DocumentAddress, DocumentCommitChange, DocumentContent, DocumentCopySource, DocumentCreate, DocumentId, DocumentObserver, DocumentPoint, DocumentQuery, DocumentReader, DocumentRecord, DocumentSemantics, DocumentState, DocumentWatch, Entry, EntryDraft, EntryId, EntryQuery, EntryRecord, HookRunner, Id, JoinPolicy, JsonObject, LatestConversationSemantics, NextTaskState, Page, PhaseHandler, RewindableConversationDocFamilyToken, RewindableConversationDocToken, RewindableConversationSemantics, RunningTask, Seq, Session, SessionDocFamilyToken, SessionDocToken, Storage, StorageWrite, StoredDocument, SubmissionCreate, SubmissionId, SubmissionQuery, SubmissionRecord, SubmissionSettlement, TableCommitChange, Task, TaskDefinition, TaskDocFamilyToken, TaskDocToken, TaskId, TaskOptions, TaskOutcome, TaskOutcomeError, TaskOwnership, TaskQuery, TaskRecord, TaskRuntime, TaskState, Tx, TypedEntry, TypedEntryDraft, WatchEnd, WatchHandle, } from "./types.ts";
14
20
  export { ROOT_CONVERSATION_ID } from "./types.ts";
15
21
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACpG,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,KAAK,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AACvF,OAAO,EACN,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,cAAc,GACd,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,YAAY,EACX,OAAO,EACP,WAAW,EACX,YAAY,EACZ,yBAAyB,EACzB,kBAAkB,EAClB,gBAAgB,EAChB,uBAAuB,EACvB,iBAAiB,EACjB,yBAAyB,EACzB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,SAAS,EACT,OAAO,EACP,oBAAoB,EACpB,QAAQ,EACR,WAAW,EACX,aAAa,EACb,oBAAoB,EACpB,YAAY,EACZ,QAAQ,EACR,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,uBAAuB,EACvB,WAAW,EACX,UAAU,EACV,eAAe,EACf,cAAc,EACd,WAAW,EACX,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,EACX,SAAS,GACT,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,YAAY,EACX,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,EACnB,WAAW,EACX,0BAA0B,EAC1B,oBAAoB,EACpB,cAAc,EACd,qBAAqB,EACrB,iBAAiB,EACjB,kBAAkB,EAClB,MAAM,EACN,aAAa,EACb,mBAAmB,EACnB,cAAc,EACd,QAAQ,EACR,eAAe,EACf,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,KAAK,EACL,UAAU,EACV,OAAO,EACP,UAAU,EACV,WAAW,EACX,EAAE,EACF,UAAU,EACV,2BAA2B,EAC3B,aAAa,EACb,IAAI,EACJ,YAAY,EACZ,oCAAoC,EACpC,8BAA8B,EAC9B,+BAA+B,EAC/B,WAAW,EACX,GAAG,EACH,OAAO,EACP,qBAAqB,EACrB,eAAe,EACf,OAAO,EACP,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EACjB,IAAI,EACJ,cAAc,EACd,kBAAkB,EAClB,YAAY,EACZ,MAAM,EACN,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,SAAS,EACT,UAAU,EACV,WAAW,EACX,SAAS,EACT,EAAE,EACF,UAAU,EACV,eAAe,EACf,QAAQ,EACR,WAAW,GACX,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,11 +1,16 @@
1
1
  export { defineDoc, defineDocFamily } from "./documents.js";
2
- export { AssistantEntry, defineEntry, SystemEntry, ToolResultEntry, UserEntry } from "./entries.js";
2
+ export { AssistantEntry, CompactionEntry, defineEntry, ResetEntry, SystemEntry, ToolResultEntry, UserEntry, } from "./entries.js";
3
3
  export { ConversationBusy, ReadAfterWrite, StorageRejected } from "./errors.js";
4
+ export { CompactionTask, } from "./harness/compaction.js";
4
5
  export { ConversationConfig } from "./harness/config.js";
6
+ export { watchEvents, } from "./harness/events.js";
5
7
  export { GenerationTask, } from "./harness/generation.js";
6
8
  export { Harness } from "./harness/harness.js";
9
+ export { InboxDoc } from "./harness/inbox.js";
7
10
  export { LiveDoc } from "./harness/live.js";
8
11
  export { createRegistry } from "./harness/registry.js";
12
+ export { ToolTask } from "./harness/tool.js";
13
+ export { UsageDoc } from "./harness/usage.js";
9
14
  export { createSession } from "./session/session.js";
10
15
  export { MemoryStorage } from "./storage/memory.js";
11
16
  export { defineTask } from "./tasks.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACpG,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAgC,MAAM,qBAAqB,CAAC;AACvF,OAAO,EAIN,cAAc,GACd,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAkB,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAsCvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AA8ExC,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC","sourcesContent":["export { defineDoc, defineDocFamily } from \"./documents.ts\";\nexport { AssistantEntry, defineEntry, SystemEntry, ToolResultEntry, UserEntry } from \"./entries.ts\";\nexport { ConversationBusy, ReadAfterWrite, StorageRejected } from \"./errors.ts\";\nexport { ConversationConfig, type ConversationConfigState } from \"./harness/config.ts\";\nexport {\n\ttype GenerationCheckpoint,\n\ttype GenerationInput,\n\ttype GenerationResult,\n\tGenerationTask,\n} from \"./harness/generation.ts\";\nexport { Harness } from \"./harness/harness.ts\";\nexport { LiveDoc, type LiveState } from \"./harness/live.ts\";\nexport { createRegistry } from \"./harness/registry.ts\";\nexport type {\n\tAnyTask,\n\tContextView,\n\tConversation,\n\tConversationCreateOptions,\n\tConversationHandle,\n\tConversationInit,\n\tConversationRetryPolicy,\n\tConversationSetup,\n\tConversationStreamOptions,\n\tHarnessInspection,\n\tHarnessOptions,\n\tHookRegistration,\n\tHookScope,\n\tHooksOf,\n\tInputSubmissionDraft,\n\tModelRef,\n\tPromptInput,\n\tPromptSection,\n\tPromptSectionWrapper,\n\tRegistration,\n\tRegistry,\n\tRegistryFailure,\n\tRegistryReader,\n\tRegistrySnapshot,\n\tSettledSubmissionRecord,\n\tSettledTask,\n\tSubmission,\n\tSubmissionDraft,\n\tTaskInspection,\n\tToolControl,\n\tToolExecutionApi,\n\tToolExecutionResult,\n\tToolRegistration,\n\tToolWrapper,\n\tUserInput,\n} from \"./harness/types.ts\";\nexport { createSession } from \"./session/session.ts\";\nexport { MemoryStorage } from \"./storage/memory.ts\";\nexport { defineTask } from \"./tasks.ts\";\nexport type {\n\tCheckpointInfo,\n\tCommitChange,\n\tCommitPublication,\n\tCommonDocDefinition,\n\tContextEdit,\n\tConversationDocFamilyToken,\n\tConversationDocToken,\n\tConversationId,\n\tConversationOwnership,\n\tConversationQuery,\n\tConversationRecord,\n\tCursor,\n\tDocDefinition,\n\tDocFamilyDefinition,\n\tDocFamilyToken,\n\tDocToken,\n\tDocumentAddress,\n\tDocumentCommitChange,\n\tDocumentContent,\n\tDocumentCopySource,\n\tDocumentCreate,\n\tDocumentId,\n\tDocumentObserver,\n\tDocumentPoint,\n\tDocumentQuery,\n\tDocumentReader,\n\tDocumentRecord,\n\tDocumentSemantics,\n\tDocumentState,\n\tDocumentWatch,\n\tEntry,\n\tEntryDraft,\n\tEntryId,\n\tEntryQuery,\n\tEntryRecord,\n\tId,\n\tJsonObject,\n\tLatestConversationSemantics,\n\tNextTaskState,\n\tPage,\n\tPhaseHandler,\n\tRewindableConversationDocFamilyToken,\n\tRewindableConversationDocToken,\n\tRewindableConversationSemantics,\n\tRunningTask,\n\tSeq,\n\tSession,\n\tSessionDocFamilyToken,\n\tSessionDocToken,\n\tStorage,\n\tStorageWrite,\n\tStoredDocument,\n\tSubmissionCreate,\n\tSubmissionId,\n\tSubmissionQuery,\n\tSubmissionRecord,\n\tSubmissionSettlement,\n\tTableCommitChange,\n\tTask,\n\tTaskDefinition,\n\tTaskDocFamilyToken,\n\tTaskDocToken,\n\tTaskId,\n\tTaskOptions,\n\tTaskOutcome,\n\tTaskOutcomeError,\n\tTaskQuery,\n\tTaskRecord,\n\tTaskRuntime,\n\tTaskState,\n\tTx,\n\tTypedEntry,\n\tTypedEntryDraft,\n\tWatchEnd,\n\tWatchHandle,\n} from \"./types.ts\";\nexport { ROOT_CONVERSATION_ID } from \"./types.ts\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EACN,cAAc,EACd,eAAe,EACf,WAAW,EACX,UAAU,EACV,WAAW,EACX,eAAe,EACf,SAAS,GACT,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAChF,OAAO,EAGN,cAAc,GAEd,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAgC,MAAM,qBAAqB,CAAC;AACvF,OAAO,EAKN,WAAW,GACX,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAIN,cAAc,GACd,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAmC,MAAM,oBAAoB,CAAC;AAC/E,OAAO,EAAyB,OAAO,EAAiC,MAAM,mBAAmB,CAAC;AAClG,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAoE,MAAM,mBAAmB,CAAC;AAkD/G,OAAO,EAAE,QAAQ,EAAmB,MAAM,oBAAoB,CAAC;AAE/D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAiFxC,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC","sourcesContent":["export { defineDoc, defineDocFamily } from \"./documents.ts\";\nexport {\n\tAssistantEntry,\n\tCompactionEntry,\n\tdefineEntry,\n\tResetEntry,\n\tSystemEntry,\n\tToolResultEntry,\n\tUserEntry,\n} from \"./entries.ts\";\nexport { ConversationBusy, ReadAfterWrite, StorageRejected } from \"./errors.ts\";\nexport {\n\ttype CompactionCheckpoint,\n\ttype CompactionInput,\n\tCompactionTask,\n\ttype SummaryRequest,\n} from \"./harness/compaction.ts\";\nexport { ConversationConfig, type ConversationConfigState } from \"./harness/config.ts\";\nexport {\n\ttype AgentEvent,\n\ttype AgentEventStream,\n\ttype MessageChange,\n\ttype SnapshotEvent,\n\twatchEvents,\n} from \"./harness/events.ts\";\nexport {\n\ttype GenerationCheckpoint,\n\ttype GenerationInput,\n\ttype GenerationResult,\n\tGenerationTask,\n} from \"./harness/generation.ts\";\nexport { Harness } from \"./harness/harness.ts\";\nexport { InboxDoc, type InboxItem, type InboxState } from \"./harness/inbox.ts\";\nexport { type CompactionStatus, LiveDoc, type LiveState, type ToolSlot } from \"./harness/live.ts\";\nexport { createRegistry } from \"./harness/registry.ts\";\nexport { ToolTask, type ToolTaskCheckpoint, type ToolTaskInput, type ToolTaskResult } from \"./harness/tool.ts\";\nexport type {\n\tAnyTask,\n\tCompactionHooks,\n\tCompactionPolicy,\n\tCompactionReason,\n\tCompactionResult,\n\tContextView,\n\tConversation,\n\tConversationAbortOptions,\n\tConversationCreateOptions,\n\tConversationHandle,\n\tConversationInit,\n\tConversationRetryPolicy,\n\tConversationSetup,\n\tConversationStreamOptions,\n\tGenerationHooks,\n\tHarnessInspection,\n\tHarnessOptions,\n\tHookApi,\n\tHookRegistration,\n\tHookResult,\n\tHookScope,\n\tHooksOf,\n\tInputSubmissionDraft,\n\tModelRef,\n\tPromptInput,\n\tPromptSection,\n\tPromptSectionWrapper,\n\tQueueMode,\n\tRegistration,\n\tRegistry,\n\tRegistryFailure,\n\tRegistryReader,\n\tRegistrySnapshot,\n\tSettledSubmissionRecord,\n\tSettledTask,\n\tSubmission,\n\tSubmissionDraft,\n\tTaskInspection,\n\tToolControl,\n\tToolDiagnostic,\n\tToolExecutionApi,\n\tToolExecutionMode,\n\tToolExecutionResult,\n\tToolHooks,\n\tToolRegistration,\n\tToolWrapper,\n\tUserInput,\n} from \"./harness/types.ts\";\nexport { UsageDoc, type UsageState } from \"./harness/usage.ts\";\nexport type { ConversationView } from \"./harness/view.ts\";\nexport { createSession } from \"./session/session.ts\";\nexport { MemoryStorage } from \"./storage/memory.ts\";\nexport { defineTask } from \"./tasks.ts\";\nexport type {\n\tCheckpointInfo,\n\tCommitChange,\n\tCommitPublication,\n\tCommonDocDefinition,\n\tContextEdit,\n\tConversationDocFamilyToken,\n\tConversationDocToken,\n\tConversationId,\n\tConversationOwnership,\n\tConversationQuery,\n\tConversationRecord,\n\tCursor,\n\tDocDefinition,\n\tDocFamilyDefinition,\n\tDocFamilyToken,\n\tDocToken,\n\tDocumentAddress,\n\tDocumentCommitChange,\n\tDocumentContent,\n\tDocumentCopySource,\n\tDocumentCreate,\n\tDocumentId,\n\tDocumentObserver,\n\tDocumentPoint,\n\tDocumentQuery,\n\tDocumentReader,\n\tDocumentRecord,\n\tDocumentSemantics,\n\tDocumentState,\n\tDocumentWatch,\n\tEntry,\n\tEntryDraft,\n\tEntryId,\n\tEntryQuery,\n\tEntryRecord,\n\tHookRunner,\n\tId,\n\tJoinPolicy,\n\tJsonObject,\n\tLatestConversationSemantics,\n\tNextTaskState,\n\tPage,\n\tPhaseHandler,\n\tRewindableConversationDocFamilyToken,\n\tRewindableConversationDocToken,\n\tRewindableConversationSemantics,\n\tRunningTask,\n\tSeq,\n\tSession,\n\tSessionDocFamilyToken,\n\tSessionDocToken,\n\tStorage,\n\tStorageWrite,\n\tStoredDocument,\n\tSubmissionCreate,\n\tSubmissionId,\n\tSubmissionQuery,\n\tSubmissionRecord,\n\tSubmissionSettlement,\n\tTableCommitChange,\n\tTask,\n\tTaskDefinition,\n\tTaskDocFamilyToken,\n\tTaskDocToken,\n\tTaskId,\n\tTaskOptions,\n\tTaskOutcome,\n\tTaskOutcomeError,\n\tTaskOwnership,\n\tTaskQuery,\n\tTaskRecord,\n\tTaskRuntime,\n\tTaskState,\n\tTx,\n\tTypedEntry,\n\tTypedEntryDraft,\n\tWatchEnd,\n\tWatchHandle,\n} from \"./types.ts\";\nexport { ROOT_CONVERSATION_ID } from \"./types.ts\";\n"]}
@@ -4,25 +4,32 @@ import type { JsonObject, WatchEnd, WatchHandle } from "../types.ts";
4
4
  export type ObservedDocumentValue = Readonly<JsonObject> | null;
5
5
  /** Canonical terminal update for a retired document incarnation. */
6
6
  export declare const RETIREMENT_OPERATIONS: readonly Op[];
7
- /** Session-to-Chord bridge owned one-to-one by one attached document state. @internal */
8
- export declare class SessionDocumentSource implements ReplicatedStateSource<ObservedDocumentValue> {
7
+ /**
8
+ * Session-to-Chord bridge owned one-to-one by one attached state: a document, or a conversation view. A `null` value
9
+ * retires it. @internal
10
+ */
11
+ export declare class CommittedStateSource<T = ObservedDocumentValue> implements ReplicatedStateSource<T> {
9
12
  #private;
10
- constructor(value: Readonly<JsonObject>, release: () => void);
11
- attach(): ReplicatedStateSourceAttachment<ObservedDocumentValue>;
12
- advance(value: ObservedDocumentValue, ops: readonly Op[], context: Context): void;
13
+ constructor(value: T, release: () => void);
14
+ attach(): ReplicatedStateSourceAttachment<T>;
15
+ advance(value: T, ops: readonly Op[], context: Context): void;
13
16
  closeSession(): void;
14
17
  }
15
- /** Serialized exact-frame watch bound to one concrete document incarnation. @internal */
16
- export declare class SessionDocumentWatch implements WatchHandle<ObservedDocumentValue> {
18
+ /**
19
+ * Serialized exact-frame watch bound to one document incarnation or conversation view. A `null` value retires it.
20
+ * @internal
21
+ */
22
+ export declare class CommittedWatch<T = ObservedDocumentValue> implements WatchHandle<T> {
17
23
  #private;
18
- constructor(value: Readonly<JsonObject>, detach: () => void);
19
- get value(): ObservedDocumentValue;
24
+ /** `replace` gives the value an overflow delivers; by default the newest value. */
25
+ constructor(value: T, detach: () => void, replace?: () => T);
26
+ get value(): T;
20
27
  get closed(): Promise<WatchEnd>;
21
- start(listener: (value: ObservedDocumentValue, ops: readonly Op[], context: Context) => Promise<void>): void;
28
+ start(listener: (value: T, ops: readonly Op[], context: Context) => Promise<void>): void;
22
29
  stop(): Promise<WatchEnd>;
23
30
  observeCancellation(signal: AbortSignal): void;
24
31
  cancel(): void;
25
32
  closeSession(): void;
26
- advance(value: ObservedDocumentValue, ops: readonly Op[], context: Context): void;
33
+ advance(value: T, ops: readonly Op[], context: Context): void;
27
34
  }
28
35
  //# sourceMappingURL=observation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"observation.d.ts","sourceRoot":"","sources":["../../src/session/observation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,OAAO,EACP,qBAAqB,EACrB,+BAA+B,EAE/B,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,6BAA6B,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAErE,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC;AAKhE,oEAAoE;AACpE,eAAO,MAAM,qBAAqB,EAAE,SAAS,EAAE,EAAkB,CAAC;AAElE,yFAAyF;AACzF,qBAAa,qBAAsB,YAAW,qBAAqB,CAAC,qBAAqB,CAAC;;IAQzF,YAAY,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,MAAM,IAAI,EAG3D;IAED,MAAM,IAAI,+BAA+B,CAAC,qBAAqB,CAAC,CAQ/D;IAED,OAAO,CAAC,KAAK,EAAE,qBAAqB,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAYhF;IAED,YAAY,IAAI,IAAI,CAInB;CAUD;AA2ED,yFAAyF;AACzF,qBAAa,oBAAqB,YAAW,WAAW,CAAC,qBAAqB,CAAC;;IAiB9E,YAAY,KAAK,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,IAAI,EAM1D;IAED,IAAI,KAAK,IAAI,qBAAqB,CAEjC;IAED,IAAI,MAAM,IAAI,OAAO,CAAC,QAAQ,CAAC,CAE9B;IAED,KAAK,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,qBAAqB,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAM3G;IAED,IAAI,IAAI,OAAO,CAAC,QAAQ,CAAC,CAGxB;IAED,mBAAmB,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAO7C;IAED,MAAM,IAAI,IAAI,CAEb;IAED,YAAY,IAAI,IAAI,CAEnB;IAED,OAAO,CAAC,KAAK,EAAE,qBAAqB,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAUhF;CAiED"}
1
+ {"version":3,"file":"observation.d.ts","sourceRoot":"","sources":["../../src/session/observation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,OAAO,EAEP,qBAAqB,EACrB,+BAA+B,EAE/B,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,6BAA6B,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAErE,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC;AAKhE,oEAAoE;AACpE,eAAO,MAAM,qBAAqB,EAAE,SAAS,EAAE,EAAkB,CAAC;AAElE;;;GAGG;AACH,qBAAa,oBAAoB,CAAC,CAAC,GAAG,qBAAqB,CAAE,YAAW,qBAAqB,CAAC,CAAC,CAAC;;IAS/F,YAAY,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,IAAI,EAGxC;IAED,MAAM,IAAI,+BAA+B,CAAC,CAAC,CAAC,CAQ3C;IAED,OAAO,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAY5D;IAED,YAAY,IAAI,IAAI,CAInB;CAUD;AA2ED;;;GAGG;AACH,qBAAa,cAAc,CAAC,CAAC,GAAG,qBAAqB,CAAE,YAAW,WAAW,CAAC,CAAC,CAAC;;IAkB/E,mFAAmF;IACnF,YAAY,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,IAAI,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,EAO1D;IAED,IAAI,KAAK,IAAI,CAAC,CAEb;IAED,IAAI,MAAM,IAAI,OAAO,CAAC,QAAQ,CAAC,CAE9B;IAED,KAAK,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAMvF;IAED,IAAI,IAAI,OAAO,CAAC,QAAQ,CAAC,CAGxB;IAED,mBAAmB,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAO7C;IAED,MAAM,IAAI,IAAI,CAEb;IAED,YAAY,IAAI,IAAI,CAEnB;IAED,OAAO,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAW5D;CAiED"}
@@ -3,10 +3,14 @@ import { withoutAbortSignal } from "@earendil-works/chord/context";
3
3
  const MAX_PENDING_WATCH_FRAMES = 100;
4
4
  /** Canonical terminal update for a retired document incarnation. */
5
5
  export const RETIREMENT_OPERATIONS = [["r", null]];
6
- /** Session-to-Chord bridge owned one-to-one by one attached document state. @internal */
7
- export class SessionDocumentSource {
6
+ /**
7
+ * Session-to-Chord bridge owned one-to-one by one attached state: a document, or a conversation view. A `null` value
8
+ * retires it. @internal
9
+ */
10
+ export class CommittedStateSource {
8
11
  #attachments = new Set();
9
12
  #release;
13
+ /** Released on disposal. */
10
14
  #value;
11
15
  #cursor = 0;
12
16
  #retired = false;
@@ -17,7 +21,7 @@ export class SessionDocumentSource {
17
21
  }
18
22
  attach() {
19
23
  if (this.#closed)
20
- throw new Error("Document state source is closed");
24
+ throw new Error("State source is closed");
21
25
  const attachment = new SessionSourceAttachment({ value: this.#value, cursor: this.#cursor }, () => {
22
26
  this.#attachments.delete(attachment);
23
27
  if (this.#attachments.size === 0)
@@ -53,7 +57,7 @@ export class SessionDocumentSource {
53
57
  if (this.#closed)
54
58
  return;
55
59
  this.#closed = true;
56
- this.#value = null;
60
+ this.#value = undefined;
57
61
  const release = this.#release;
58
62
  this.#release = undefined;
59
63
  release?.();
@@ -74,9 +78,9 @@ class SessionSourceAttachment {
74
78
  }
75
79
  activate(listener) {
76
80
  if (this.#activated)
77
- throw new Error("Document state attachment is already active");
81
+ throw new Error("State attachment is already active");
78
82
  if (this.#disposed)
79
- throw new Error("Document state attachment is disposed");
83
+ throw new Error("State attachment is disposed");
80
84
  this.#activated = true;
81
85
  this.#listener = listener;
82
86
  this.#drain();
@@ -130,9 +134,13 @@ class SessionSourceAttachment {
130
134
  }
131
135
  }
132
136
  }
133
- /** Serialized exact-frame watch bound to one concrete document incarnation. @internal */
134
- export class SessionDocumentWatch {
137
+ /**
138
+ * Serialized exact-frame watch bound to one document incarnation or conversation view. A `null` value retires it.
139
+ * @internal
140
+ */
141
+ export class CommittedWatch {
135
142
  #detach;
143
+ #replace;
136
144
  #closedPromise;
137
145
  #pending = [];
138
146
  #resolveClosed;
@@ -147,9 +155,11 @@ export class SessionDocumentWatch {
147
155
  #resolved = false;
148
156
  #cancellationSignal;
149
157
  #cancellationListener;
150
- constructor(value, detach) {
158
+ /** `replace` gives the value an overflow delivers; by default the newest value. */
159
+ constructor(value, detach, replace) {
151
160
  this.#value = value;
152
161
  this.#detach = detach;
162
+ this.#replace = replace;
153
163
  this.#closedPromise = new Promise((resolve) => {
154
164
  this.#resolveClosed = resolve;
155
165
  });
@@ -162,9 +172,9 @@ export class SessionDocumentWatch {
162
172
  }
163
173
  start(listener) {
164
174
  if (this.#started)
165
- throw new Error("Document watch is already started");
175
+ throw new Error("Watch is already started");
166
176
  if (this.#end !== undefined)
167
- throw new Error("Document watch is stopped");
177
+ throw new Error("Watch is stopped");
168
178
  this.#started = true;
169
179
  this.#listener = listener;
170
180
  if (this.#pending.length > 0)
@@ -176,7 +186,7 @@ export class SessionDocumentWatch {
176
186
  }
177
187
  observeCancellation(signal) {
178
188
  if (this.#cancellationSignal !== undefined)
179
- throw new Error("Document watch cancellation is already installed");
189
+ throw new Error("Watch cancellation is already installed");
180
190
  if (this.#end !== undefined)
181
191
  return;
182
192
  this.#cancellationSignal = signal;
@@ -198,7 +208,8 @@ export class SessionDocumentWatch {
198
208
  this.#retired = true;
199
209
  if (this.#pending.length >= MAX_PENDING_WATCH_FRAMES) {
200
210
  this.#pending.length = 0;
201
- this.#pending.push({ value, ops: [["r", value]], context });
211
+ const replacement = this.#replace?.() ?? value;
212
+ this.#pending.push({ value: replacement, ops: [["r", replacement]], context });
202
213
  }
203
214
  else {
204
215
  this.#pending.push({ value, ops, context });