@earendil-works/pi-durable 1.1.0 → 1.2.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 (184) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.md +147 -11
  3. package/dist/codemode/codemode.d.ts +173 -0
  4. package/dist/codemode/codemode.d.ts.map +1 -0
  5. package/dist/codemode/codemode.js +886 -0
  6. package/dist/codemode/codemode.js.map +1 -0
  7. package/dist/codemode/describe.d.ts +38 -0
  8. package/dist/codemode/describe.d.ts.map +1 -0
  9. package/dist/codemode/describe.js +119 -0
  10. package/dist/codemode/describe.js.map +1 -0
  11. package/dist/codemode/index.d.ts +3 -0
  12. package/dist/codemode/index.d.ts.map +1 -0
  13. package/dist/codemode/index.js +3 -0
  14. package/dist/codemode/index.js.map +1 -0
  15. package/dist/codemode/models.d.ts +28 -0
  16. package/dist/codemode/models.d.ts.map +1 -0
  17. package/dist/codemode/models.js +231 -0
  18. package/dist/codemode/models.js.map +1 -0
  19. package/dist/codemode/output.d.ts +41 -0
  20. package/dist/codemode/output.d.ts.map +1 -0
  21. package/dist/codemode/output.js +167 -0
  22. package/dist/codemode/output.js.map +1 -0
  23. package/dist/env/index.d.ts +42 -0
  24. package/dist/env/index.d.ts.map +1 -1
  25. package/dist/env/index.js.map +1 -1
  26. package/dist/errors.d.ts +20 -3
  27. package/dist/errors.d.ts.map +1 -1
  28. package/dist/errors.js +34 -5
  29. package/dist/errors.js.map +1 -1
  30. package/dist/harness/agent.d.ts +5 -2
  31. package/dist/harness/agent.d.ts.map +1 -1
  32. package/dist/harness/agent.js +69 -25
  33. package/dist/harness/agent.js.map +1 -1
  34. package/dist/harness/compaction.d.ts +6 -1
  35. package/dist/harness/compaction.d.ts.map +1 -1
  36. package/dist/harness/compaction.js +10 -7
  37. package/dist/harness/compaction.js.map +1 -1
  38. package/dist/harness/events.d.ts +35 -15
  39. package/dist/harness/events.d.ts.map +1 -1
  40. package/dist/harness/events.js +77 -23
  41. package/dist/harness/events.js.map +1 -1
  42. package/dist/harness/generation.d.ts +2 -0
  43. package/dist/harness/generation.d.ts.map +1 -1
  44. package/dist/harness/generation.js +31 -8
  45. package/dist/harness/generation.js.map +1 -1
  46. package/dist/harness/harness.d.ts +7 -0
  47. package/dist/harness/harness.d.ts.map +1 -1
  48. package/dist/harness/harness.js +53 -26
  49. package/dist/harness/harness.js.map +1 -1
  50. package/dist/harness/inbox.d.ts +16 -4
  51. package/dist/harness/inbox.d.ts.map +1 -1
  52. package/dist/harness/inbox.js +26 -3
  53. package/dist/harness/inbox.js.map +1 -1
  54. package/dist/harness/live.d.ts +74 -17
  55. package/dist/harness/live.d.ts.map +1 -1
  56. package/dist/harness/live.js +66 -14
  57. package/dist/harness/live.js.map +1 -1
  58. package/dist/harness/scheduler.d.ts +18 -5
  59. package/dist/harness/scheduler.d.ts.map +1 -1
  60. package/dist/harness/scheduler.js +696 -163
  61. package/dist/harness/scheduler.js.map +1 -1
  62. package/dist/harness/submissions.d.ts +7 -4
  63. package/dist/harness/submissions.d.ts.map +1 -1
  64. package/dist/harness/submissions.js +32 -13
  65. package/dist/harness/submissions.js.map +1 -1
  66. package/dist/harness/task-graph.d.ts +1 -1
  67. package/dist/harness/task-graph.d.ts.map +1 -1
  68. package/dist/harness/task-graph.js +15 -10
  69. package/dist/harness/task-graph.js.map +1 -1
  70. package/dist/harness/tool.d.ts +45 -5
  71. package/dist/harness/tool.d.ts.map +1 -1
  72. package/dist/harness/tool.js +377 -62
  73. package/dist/harness/tool.js.map +1 -1
  74. package/dist/harness/types.d.ts +153 -13
  75. package/dist/harness/types.d.ts.map +1 -1
  76. package/dist/harness/types.js.map +1 -1
  77. package/dist/harness/util.d.ts +6 -1
  78. package/dist/harness/util.d.ts.map +1 -1
  79. package/dist/harness/util.js +5 -2
  80. package/dist/harness/util.js.map +1 -1
  81. package/dist/harness/view.d.ts +6 -2
  82. package/dist/harness/view.d.ts.map +1 -1
  83. package/dist/harness/view.js +22 -12
  84. package/dist/harness/view.js.map +1 -1
  85. package/dist/images/cloudflare.d.ts +4 -0
  86. package/dist/images/cloudflare.d.ts.map +1 -0
  87. package/dist/images/cloudflare.js +9 -0
  88. package/dist/images/cloudflare.js.map +1 -0
  89. package/dist/images/exif.d.ts +3 -0
  90. package/dist/images/exif.d.ts.map +1 -0
  91. package/dist/images/exif.js +71 -0
  92. package/dist/images/exif.js.map +1 -0
  93. package/dist/images/index.d.ts +18 -0
  94. package/dist/images/index.d.ts.map +1 -0
  95. package/dist/images/index.js +125 -0
  96. package/dist/images/index.js.map +1 -0
  97. package/dist/images/node-worker.d.ts +17 -0
  98. package/dist/images/node-worker.d.ts.map +1 -0
  99. package/dist/images/node-worker.js +16 -0
  100. package/dist/images/node-worker.js.map +1 -0
  101. package/dist/images/node.d.ts +21 -0
  102. package/dist/images/node.d.ts.map +1 -0
  103. package/dist/images/node.js +121 -0
  104. package/dist/images/node.js.map +1 -0
  105. package/dist/index.d.ts +6 -6
  106. package/dist/index.d.ts.map +1 -1
  107. package/dist/index.js +3 -3
  108. package/dist/index.js.map +1 -1
  109. package/dist/search.d.ts +13 -0
  110. package/dist/search.d.ts.map +1 -0
  111. package/dist/search.js +85 -0
  112. package/dist/search.js.map +1 -0
  113. package/dist/session/observation.d.ts +10 -3
  114. package/dist/session/observation.d.ts.map +1 -1
  115. package/dist/session/observation.js +24 -34
  116. package/dist/session/observation.js.map +1 -1
  117. package/dist/session/session.d.ts +68 -5
  118. package/dist/session/session.d.ts.map +1 -1
  119. package/dist/session/session.js +461 -49
  120. package/dist/session/session.js.map +1 -1
  121. package/dist/session/transaction.d.ts.map +1 -1
  122. package/dist/session/transaction.js +1 -0
  123. package/dist/session/transaction.js.map +1 -1
  124. package/dist/storage/jsonl/storage.d.ts +4 -0
  125. package/dist/storage/jsonl/storage.d.ts.map +1 -1
  126. package/dist/storage/jsonl/storage.js +2 -1
  127. package/dist/storage/jsonl/storage.js.map +1 -1
  128. package/dist/storage/memory.d.ts.map +1 -1
  129. package/dist/storage/memory.js +8 -10
  130. package/dist/storage/memory.js.map +1 -1
  131. package/dist/storage/scan.d.ts.map +1 -1
  132. package/dist/storage/scan.js +5 -4
  133. package/dist/storage/scan.js.map +1 -1
  134. package/dist/storage/sqlite/storage.d.ts.map +1 -1
  135. package/dist/storage/sqlite/storage.js +10 -12
  136. package/dist/storage/sqlite/storage.js.map +1 -1
  137. package/dist/testing/env-conformance.d.ts.map +1 -1
  138. package/dist/testing/env-conformance.js +100 -0
  139. package/dist/testing/env-conformance.js.map +1 -1
  140. package/dist/testing/runner.d.ts +1 -1
  141. package/dist/testing/runner.d.ts.map +1 -1
  142. package/dist/testing/runner.js.map +1 -1
  143. package/dist/testing/storage-conformance.d.ts.map +1 -1
  144. package/dist/testing/storage-conformance.js +3 -2
  145. package/dist/testing/storage-conformance.js.map +1 -1
  146. package/dist/testing/types.d.ts +2 -0
  147. package/dist/testing/types.d.ts.map +1 -1
  148. package/dist/testing/types.js.map +1 -1
  149. package/dist/tool-search/index.d.ts +2 -0
  150. package/dist/tool-search/index.d.ts.map +1 -0
  151. package/dist/tool-search/index.js +2 -0
  152. package/dist/tool-search/index.js.map +1 -0
  153. package/dist/tool-search/tool-search.d.ts +23 -0
  154. package/dist/tool-search/tool-search.d.ts.map +1 -0
  155. package/dist/tool-search/tool-search.js +84 -0
  156. package/dist/tool-search/tool-search.js.map +1 -0
  157. package/dist/tools/bash.d.ts +10 -2
  158. package/dist/tools/bash.d.ts.map +1 -1
  159. package/dist/tools/bash.js +27 -9
  160. package/dist/tools/bash.js.map +1 -1
  161. package/dist/tools/edit.js +1 -1
  162. package/dist/tools/edit.js.map +1 -1
  163. package/dist/tools/image-processor.d.ts +47 -0
  164. package/dist/tools/image-processor.d.ts.map +1 -0
  165. package/dist/tools/image-processor.js +30 -0
  166. package/dist/tools/image-processor.js.map +1 -0
  167. package/dist/tools/image.d.ts +8 -0
  168. package/dist/tools/image.d.ts.map +1 -1
  169. package/dist/tools/image.js +47 -0
  170. package/dist/tools/image.js.map +1 -1
  171. package/dist/tools/index.d.ts +25 -2
  172. package/dist/tools/index.d.ts.map +1 -1
  173. package/dist/tools/index.js +13 -5
  174. package/dist/tools/index.js.map +1 -1
  175. package/dist/tools/read.d.ts +10 -2
  176. package/dist/tools/read.d.ts.map +1 -1
  177. package/dist/tools/read.js +87 -28
  178. package/dist/tools/read.js.map +1 -1
  179. package/dist/tools/write.js +1 -1
  180. package/dist/tools/write.js.map +1 -1
  181. package/dist/types.d.ts +59 -5
  182. package/dist/types.d.ts.map +1 -1
  183. package/dist/types.js.map +1 -1
  184. package/package.json +43 -4
package/dist/search.js ADDED
@@ -0,0 +1,85 @@
1
+ /**
2
+ * BM25 tool search for code mode's `searchTools()` and the `tool_search` tool, a copy of the coding agent's tool search
3
+ * ranking: durable keeps its own copy of what it needs from the coding agent.
4
+ */
5
+ const STOP_WORDS = new Set([
6
+ "a",
7
+ "an",
8
+ "and",
9
+ "are",
10
+ "as",
11
+ "at",
12
+ "be",
13
+ "by",
14
+ "for",
15
+ "from",
16
+ "in",
17
+ "is",
18
+ "it",
19
+ "of",
20
+ "on",
21
+ "or",
22
+ "that",
23
+ "the",
24
+ "this",
25
+ "to",
26
+ "with",
27
+ ]);
28
+ /** Naive singular form, so `issues` matches `issue` and `searches` matches `search`. */
29
+ function stem(term) {
30
+ if (term.length > 4 && term.endsWith("ies"))
31
+ return `${term.slice(0, -3)}y`;
32
+ if (term.length > 4 && /(ches|shes|sses|xes|zes)$/.test(term))
33
+ return term.slice(0, -2);
34
+ if (term.length > 3 && term.endsWith("s") && !term.endsWith("ss"))
35
+ return term.slice(0, -1);
36
+ return term;
37
+ }
38
+ /** Lowercase terms, split at camelCase boundaries and non-alphanumerics, without stop words. */
39
+ export function tokenize(text) {
40
+ return text
41
+ .replace(/([a-z0-9])([A-Z])/g, "$1 $2")
42
+ .replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2")
43
+ .toLowerCase()
44
+ .split(/[^a-z0-9]+/)
45
+ .filter((term) => term.length > 0 && !STOP_WORDS.has(term))
46
+ .map(stem);
47
+ }
48
+ /** Okapi BM25 (k1 1.2, b 0.75): the names of the best matches, best first; ties keep document order. */
49
+ export function rankDocuments(query, documents, limit) {
50
+ const k1 = 1.2;
51
+ const b = 0.75;
52
+ const queryTerms = [...new Set(tokenize(query))];
53
+ if (queryTerms.length === 0 || documents.length === 0 || limit <= 0)
54
+ return [];
55
+ const termCounts = documents.map((document) => {
56
+ const counts = new Map();
57
+ for (const term of tokenize(document.text))
58
+ counts.set(term, (counts.get(term) ?? 0) + 1);
59
+ return counts;
60
+ });
61
+ const lengths = termCounts.map((counts) => [...counts.values()].reduce((sum, count) => sum + count, 0));
62
+ const averageLength = lengths.reduce((sum, length) => sum + length, 0) / documents.length || 1;
63
+ const idf = new Map(queryTerms.map((term) => {
64
+ const frequency = termCounts.filter((counts) => counts.has(term)).length;
65
+ return [term, Math.log(1 + (documents.length - frequency + 0.5) / (frequency + 0.5))];
66
+ }));
67
+ const matches = [];
68
+ documents.forEach((document, index) => {
69
+ let score = 0;
70
+ for (const term of queryTerms) {
71
+ const count = termCounts[index].get(term);
72
+ if (!count)
73
+ continue;
74
+ const norm = k1 * (1 - b + (b * lengths[index]) / averageLength);
75
+ score += (idf.get(term) ?? 0) * ((count * (k1 + 1)) / (count + norm));
76
+ }
77
+ if (score > 0)
78
+ matches.push({ name: document.name, score });
79
+ });
80
+ return matches
81
+ .sort((left, right) => right.score - left.score)
82
+ .slice(0, limit)
83
+ .map((match) => match.name);
84
+ }
85
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * BM25 tool search for code mode's `searchTools()` and the `tool_search` tool, a copy of the coding agent's tool search\n * ranking: durable keeps its own copy of what it needs from the coding agent.\n */\n\nexport type SearchDocument = { readonly name: string; readonly text: string };\n\nconst STOP_WORDS: ReadonlySet<string> = new Set([\n\t\"a\",\n\t\"an\",\n\t\"and\",\n\t\"are\",\n\t\"as\",\n\t\"at\",\n\t\"be\",\n\t\"by\",\n\t\"for\",\n\t\"from\",\n\t\"in\",\n\t\"is\",\n\t\"it\",\n\t\"of\",\n\t\"on\",\n\t\"or\",\n\t\"that\",\n\t\"the\",\n\t\"this\",\n\t\"to\",\n\t\"with\",\n]);\n\n/** Naive singular form, so `issues` matches `issue` and `searches` matches `search`. */\nfunction stem(term: string): string {\n\tif (term.length > 4 && term.endsWith(\"ies\")) return `${term.slice(0, -3)}y`;\n\tif (term.length > 4 && /(ches|shes|sses|xes|zes)$/.test(term)) return term.slice(0, -2);\n\tif (term.length > 3 && term.endsWith(\"s\") && !term.endsWith(\"ss\")) return term.slice(0, -1);\n\treturn term;\n}\n\n/** Lowercase terms, split at camelCase boundaries and non-alphanumerics, without stop words. */\nexport function tokenize(text: string): string[] {\n\treturn text\n\t\t.replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n\t\t.replace(/([A-Z]+)([A-Z][a-z])/g, \"$1 $2\")\n\t\t.toLowerCase()\n\t\t.split(/[^a-z0-9]+/)\n\t\t.filter((term) => term.length > 0 && !STOP_WORDS.has(term))\n\t\t.map(stem);\n}\n\n/** Okapi BM25 (k1 1.2, b 0.75): the names of the best matches, best first; ties keep document order. */\nexport function rankDocuments(query: string, documents: readonly SearchDocument[], limit: number): string[] {\n\tconst k1 = 1.2;\n\tconst b = 0.75;\n\tconst queryTerms = [...new Set(tokenize(query))];\n\tif (queryTerms.length === 0 || documents.length === 0 || limit <= 0) return [];\n\tconst termCounts = documents.map((document) => {\n\t\tconst counts = new Map<string, number>();\n\t\tfor (const term of tokenize(document.text)) counts.set(term, (counts.get(term) ?? 0) + 1);\n\t\treturn counts;\n\t});\n\tconst lengths = termCounts.map((counts) => [...counts.values()].reduce((sum, count) => sum + count, 0));\n\tconst averageLength = lengths.reduce((sum, length) => sum + length, 0) / documents.length || 1;\n\tconst idf = new Map(\n\t\tqueryTerms.map((term) => {\n\t\t\tconst frequency = termCounts.filter((counts) => counts.has(term)).length;\n\t\t\treturn [term, Math.log(1 + (documents.length - frequency + 0.5) / (frequency + 0.5))] as const;\n\t\t}),\n\t);\n\tconst matches: { name: string; score: number }[] = [];\n\tdocuments.forEach((document, index) => {\n\t\tlet score = 0;\n\t\tfor (const term of queryTerms) {\n\t\t\tconst count = termCounts[index]!.get(term);\n\t\t\tif (!count) continue;\n\t\t\tconst norm = k1 * (1 - b + (b * lengths[index]!) / averageLength);\n\t\t\tscore += (idf.get(term) ?? 0) * ((count * (k1 + 1)) / (count + norm));\n\t\t}\n\t\tif (score > 0) matches.push({ name: document.name, score });\n\t});\n\treturn matches\n\t\t.sort((left, right) => right.score - left.score)\n\t\t.slice(0, limit)\n\t\t.map((match) => match.name);\n}\n"]}
@@ -13,6 +13,7 @@ export declare class CommittedStateSource<T = ObservedDocumentValue> implements
13
13
  constructor(value: T, release: () => void);
14
14
  attach(): ReplicatedStateSourceAttachment<T>;
15
15
  advance(value: T, ops: readonly Op[], context: Context): void;
16
+ /** Stop publishing; the attached states keep their last value. A failure ends them the same way. */
16
17
  closeSession(): void;
17
18
  }
18
19
  /**
@@ -21,15 +22,21 @@ export declare class CommittedStateSource<T = ObservedDocumentValue> implements
21
22
  */
22
23
  export declare class CommittedWatch<T = ObservedDocumentValue> implements WatchHandle<T> {
23
24
  #private;
24
- /** `replace` gives the value an overflow delivers; by default the newest value. */
25
- constructor(value: T, detach: () => void, replace?: () => T);
25
+ /**
26
+ * `report` gets a listener's throw, which also ends the watch. `replace` gives the value an overflow delivers; by
27
+ * default the newest value.
28
+ */
29
+ constructor(value: T, detach: () => void, report: (error: unknown) => void, replace?: () => T);
26
30
  get value(): T;
27
31
  get closed(): Promise<WatchEnd>;
28
32
  start(listener: (value: T, ops: readonly Op[], context: Context) => Promise<void>): void;
29
33
  stop(): Promise<WatchEnd>;
30
34
  observeCancellation(signal: AbortSignal): void;
31
35
  cancel(): void;
32
- closeSession(): void;
36
+ /** End with `session_closed`, or with `session_failed` and the error when the Session failed. */
37
+ closeSession(failure?: {
38
+ readonly error: unknown;
39
+ }): void;
33
40
  advance(value: T, ops: readonly Op[], context: Context): void;
34
41
  }
35
42
  //# 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,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"}
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;AAEtD,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,oGAAoG;IACpG,YAAY,IAAI,IAAI,CAInB;CAUD;AA2ED;;;GAGG;AACH,qBAAa,cAAc,CAAC,CAAC,GAAG,qBAAqB,CAAE,YAAW,WAAW,CAAC,CAAC,CAAC;;IAiB/E;;;OAGG;IACH,YAAY,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,IAAI,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,EAK5F;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,iGAAiG;IACjG,YAAY,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAIxD;IAED,OAAO,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAW5D;CAmDD"}
@@ -1,4 +1,5 @@
1
1
  import { withoutAbortSignal } from "@earendil-works/chord/context";
2
+ import { errorMessage } from "../errors.js";
2
3
  /** Maximum exact committed frames retained behind one unavailable watch listener. */
3
4
  const MAX_PENDING_WATCH_FRAMES = 100;
4
5
  /** Canonical terminal update for a retired document incarnation. */
@@ -46,6 +47,7 @@ export class CommittedStateSource {
46
47
  for (const attachment of [...this.#attachments])
47
48
  attachment.publish(frame);
48
49
  }
50
+ /** Stop publishing; the attached states keep their last value. A failure ends them the same way. */
49
51
  closeSession() {
50
52
  if (this.#closed)
51
53
  return;
@@ -140,35 +142,35 @@ class SessionSourceAttachment {
140
142
  */
141
143
  export class CommittedWatch {
142
144
  #detach;
145
+ #report;
143
146
  #replace;
144
- #closedPromise;
147
+ #closed = Promise.withResolvers();
145
148
  #pending = [];
146
- #resolveClosed;
147
149
  #value;
148
150
  #listener;
149
151
  #started = false;
150
152
  #scheduled = false;
151
153
  #running = false;
152
- #detached = false;
153
154
  #retired = false;
155
+ /** Set once, by `#terminate()`. */
154
156
  #end;
155
- #resolved = false;
156
157
  #cancellationSignal;
157
158
  #cancellationListener;
158
- /** `replace` gives the value an overflow delivers; by default the newest value. */
159
- constructor(value, detach, replace) {
159
+ /**
160
+ * `report` gets a listener's throw, which also ends the watch. `replace` gives the value an overflow delivers; by
161
+ * default the newest value.
162
+ */
163
+ constructor(value, detach, report, replace) {
160
164
  this.#value = value;
161
165
  this.#detach = detach;
166
+ this.#report = report;
162
167
  this.#replace = replace;
163
- this.#closedPromise = new Promise((resolve) => {
164
- this.#resolveClosed = resolve;
165
- });
166
168
  }
167
169
  get value() {
168
170
  return this.#value;
169
171
  }
170
172
  get closed() {
171
- return this.#closedPromise;
173
+ return this.#closed.promise;
172
174
  }
173
175
  start(listener) {
174
176
  if (this.#started)
@@ -182,7 +184,7 @@ export class CommittedWatch {
182
184
  }
183
185
  stop() {
184
186
  this.#terminate({ reason: "stopped" });
185
- return this.#closedPromise;
187
+ return this.#closed.promise;
186
188
  }
187
189
  observeCancellation(signal) {
188
190
  if (this.#cancellationSignal !== undefined)
@@ -198,8 +200,9 @@ export class CommittedWatch {
198
200
  cancel() {
199
201
  this.#terminate({ reason: "cancelled" });
200
202
  }
201
- closeSession() {
202
- this.#terminate({ reason: "session_closed" });
203
+ /** End with `session_closed`, or with `session_failed` and the error when the Session failed. */
204
+ closeSession(failure) {
205
+ this.#terminate(failure === undefined ? { reason: "session_closed" } : { reason: "session_failed", error: failure.error });
203
206
  }
204
207
  advance(value, ops, context) {
205
208
  if (this.#end !== undefined || this.#retired)
@@ -227,10 +230,8 @@ export class CommittedWatch {
227
230
  });
228
231
  }
229
232
  async #drain() {
230
- if (this.#running || this.#end !== undefined || !this.#started) {
231
- this.#finishIfReady();
233
+ if (this.#running || this.#end !== undefined || !this.#started)
232
234
  return;
233
- }
234
235
  this.#running = true;
235
236
  try {
236
237
  while (this.#end === undefined) {
@@ -244,6 +245,7 @@ export class CommittedWatch {
244
245
  }
245
246
  catch (error) {
246
247
  if (this.#end === undefined) {
248
+ this.#report(error);
247
249
  this.#terminate({ reason: "listener_error", error: toError(error) });
248
250
  }
249
251
  break;
@@ -258,34 +260,22 @@ export class CommittedWatch {
258
260
  this.#running = false;
259
261
  if (this.#end === undefined && this.#pending.length > 0)
260
262
  this.#schedule();
261
- this.#finishIfReady();
262
263
  }
263
264
  }
265
+ /** End the watch, once: detach, drop pending frames, and settle `closed`. A callback already running keeps running. */
264
266
  #terminate(end) {
265
267
  if (this.#end !== undefined)
266
268
  return;
267
269
  this.#end = end;
268
- this.#detachNow();
269
- this.#pending.length = 0;
270
- this.#finishIfReady();
271
- }
272
- #detachNow() {
273
- if (this.#detached)
274
- return;
275
- this.#detached = true;
276
270
  this.#detach();
277
- }
278
- #finishIfReady() {
279
- if (this.#resolved || this.#end === undefined)
280
- return;
281
- this.#resolved = true;
282
- if (this.#cancellationSignal !== undefined && this.#cancellationListener !== undefined) {
283
- this.#cancellationSignal.removeEventListener("abort", this.#cancellationListener);
271
+ this.#pending.length = 0;
272
+ if (this.#cancellationListener !== undefined) {
273
+ this.#cancellationSignal?.removeEventListener("abort", this.#cancellationListener);
284
274
  }
285
- this.#resolveClosed(this.#end);
275
+ this.#closed.resolve(end);
286
276
  }
287
277
  }
288
278
  function toError(error) {
289
- return error instanceof Error ? error : new Error(String(error));
279
+ return error instanceof Error ? error : new Error(errorMessage(error));
290
280
  }
291
281
  //# sourceMappingURL=observation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"observation.js","sourceRoot":"","sources":["../../src/session/observation.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tContext,\n\tJsonValue,\n\tReplicatedStateSource,\n\tReplicatedStateSourceAttachment,\n\tReplicatedStateSourceFrame,\n} from \"@earendil-works/chord\";\nimport { withoutAbortSignal } from \"@earendil-works/chord/context\";\nimport type { Op } from \"@earendil-works/chord/delta\";\nimport type { JsonObject, WatchEnd, WatchHandle } from \"../types.ts\";\n\nexport type ObservedDocumentValue = Readonly<JsonObject> | null;\n\n/** Maximum exact committed frames retained behind one unavailable watch listener. */\nconst MAX_PENDING_WATCH_FRAMES = 100;\n\n/** Canonical terminal update for a retired document incarnation. */\nexport const RETIREMENT_OPERATIONS: readonly Op[] = [[\"r\", null]];\n\n/**\n * Session-to-Chord bridge owned one-to-one by one attached state: a document, or a conversation view. A `null` value\n * retires it. @internal\n */\nexport class CommittedStateSource<T = ObservedDocumentValue> implements ReplicatedStateSource<T> {\n\treadonly #attachments = new Set<SessionSourceAttachment<T>>();\n\t#release: (() => void) | undefined;\n\t/** Released on disposal. */\n\t#value: T | undefined;\n\t#cursor = 0;\n\t#retired = false;\n\t#closed = false;\n\n\tconstructor(value: T, release: () => void) {\n\t\tthis.#value = value;\n\t\tthis.#release = release;\n\t}\n\n\tattach(): ReplicatedStateSourceAttachment<T> {\n\t\tif (this.#closed) throw new Error(\"State source is closed\");\n\t\tconst attachment = new SessionSourceAttachment({ value: this.#value as T, cursor: this.#cursor }, () => {\n\t\t\tthis.#attachments.delete(attachment);\n\t\t\tif (this.#attachments.size === 0) this.#finishDisposal();\n\t\t});\n\t\tthis.#attachments.add(attachment);\n\t\treturn attachment;\n\t}\n\n\tadvance(value: T, ops: readonly Op[], context: Context): void {\n\t\tif (this.#closed || this.#retired) return;\n\t\tthis.#value = value;\n\t\tthis.#cursor += 1;\n\t\tif (value === null) this.#retired = true;\n\t\tconst frame: ReplicatedStateSourceFrame<T> = {\n\t\t\tcursor: this.#cursor,\n\t\t\tvalue,\n\t\t\tops,\n\t\t\tcontext,\n\t\t};\n\t\tfor (const attachment of [...this.#attachments]) attachment.publish(frame);\n\t}\n\n\tcloseSession(): void {\n\t\tif (this.#closed) return;\n\t\tfor (const attachment of [...this.#attachments]) attachment.dispose();\n\t\tthis.#finishDisposal();\n\t}\n\n\t#finishDisposal(): void {\n\t\tif (this.#closed) return;\n\t\tthis.#closed = true;\n\t\tthis.#value = undefined;\n\t\tconst release = this.#release;\n\t\tthis.#release = undefined;\n\t\trelease?.();\n\t}\n}\n\nclass SessionSourceAttachment<T> implements ReplicatedStateSourceAttachment<T> {\n\treadonly snapshot: { readonly value: T; readonly cursor: number };\n\t#release: (() => void) | undefined;\n\treadonly #frames: ReplicatedStateSourceFrame<T>[] = [];\n\t#listener: ((frame: ReplicatedStateSourceFrame<T>) => void) | undefined;\n\t#activated = false;\n\t#disposed = false;\n\t#scheduled = false;\n\t#delivering = false;\n\n\tconstructor(snapshot: { readonly value: T; readonly cursor: number }, release: () => void) {\n\t\tthis.snapshot = snapshot;\n\t\tthis.#release = release;\n\t}\n\n\tactivate(listener: (frame: ReplicatedStateSourceFrame<T>) => void): void {\n\t\tif (this.#activated) throw new Error(\"State attachment is already active\");\n\t\tif (this.#disposed) throw new Error(\"State attachment is disposed\");\n\t\tthis.#activated = true;\n\t\tthis.#listener = listener;\n\t\tthis.#drain();\n\t}\n\n\tpublish(frame: ReplicatedStateSourceFrame<T>): void {\n\t\tif (this.#disposed) return;\n\t\tthis.#frames.push(frame);\n\t\tif (!this.#activated || this.#delivering || this.#scheduled) return;\n\t\tthis.#scheduled = true;\n\t\tqueueMicrotask(() => {\n\t\t\tthis.#scheduled = false;\n\t\t\tif (this.#disposed) return;\n\t\t\ttry {\n\t\t\t\tthis.#drain();\n\t\t\t} catch {\n\t\t\t\t// Chord's frame listener contains source-contract failures. Isolate an\n\t\t\t\t// unexpected direct listener failure to this attachment as well.\n\t\t\t\tthis.dispose();\n\t\t\t}\n\t\t});\n\t}\n\n\tdispose(): void {\n\t\tif (this.#disposed) return;\n\t\tthis.#disposed = true;\n\t\tthis.#frames.length = 0;\n\t\tthis.#listener = undefined;\n\t\tconst release = this.#release;\n\t\tthis.#release = undefined;\n\t\trelease?.();\n\t}\n\n\t#drain(): void {\n\t\tconst listener = this.#listener;\n\t\tif (listener === undefined || this.#delivering || this.#disposed) return;\n\t\tthis.#delivering = true;\n\t\ttry {\n\t\t\twhile (!this.#disposed) {\n\t\t\t\tconst frame = this.#frames.shift();\n\t\t\t\tif (frame === undefined) break;\n\t\t\t\tlistener(frame);\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.#delivering = false;\n\t\t}\n\t}\n}\n\ntype WatchFrame<T> = {\n\treadonly value: T;\n\treadonly ops: readonly Op[];\n\treadonly context: Context;\n};\n\n/**\n * Serialized exact-frame watch bound to one document incarnation or conversation view. A `null` value retires it.\n * @internal\n */\nexport class CommittedWatch<T = ObservedDocumentValue> implements WatchHandle<T> {\n\treadonly #detach: () => void;\n\treadonly #replace: (() => T) | undefined;\n\treadonly #closedPromise: Promise<WatchEnd>;\n\treadonly #pending: WatchFrame<T>[] = [];\n\t#resolveClosed!: (end: WatchEnd) => void;\n\t#value: T;\n\t#listener: ((value: T, ops: readonly Op[], context: Context) => Promise<void>) | undefined;\n\t#started = false;\n\t#scheduled = false;\n\t#running = false;\n\t#detached = false;\n\t#retired = false;\n\t#end: WatchEnd | undefined;\n\t#resolved = false;\n\t#cancellationSignal: AbortSignal | undefined;\n\t#cancellationListener: (() => void) | undefined;\n\n\t/** `replace` gives the value an overflow delivers; by default the newest value. */\n\tconstructor(value: T, detach: () => void, replace?: () => T) {\n\t\tthis.#value = value;\n\t\tthis.#detach = detach;\n\t\tthis.#replace = replace;\n\t\tthis.#closedPromise = new Promise((resolve) => {\n\t\t\tthis.#resolveClosed = resolve;\n\t\t});\n\t}\n\n\tget value(): T {\n\t\treturn this.#value;\n\t}\n\n\tget closed(): Promise<WatchEnd> {\n\t\treturn this.#closedPromise;\n\t}\n\n\tstart(listener: (value: T, ops: readonly Op[], context: Context) => Promise<void>): void {\n\t\tif (this.#started) throw new Error(\"Watch is already started\");\n\t\tif (this.#end !== undefined) throw new Error(\"Watch is stopped\");\n\t\tthis.#started = true;\n\t\tthis.#listener = listener;\n\t\tif (this.#pending.length > 0) this.#schedule();\n\t}\n\n\tstop(): Promise<WatchEnd> {\n\t\tthis.#terminate({ reason: \"stopped\" });\n\t\treturn this.#closedPromise;\n\t}\n\n\tobserveCancellation(signal: AbortSignal): void {\n\t\tif (this.#cancellationSignal !== undefined) throw new Error(\"Watch cancellation is already installed\");\n\t\tif (this.#end !== undefined) return;\n\t\tthis.#cancellationSignal = signal;\n\t\tthis.#cancellationListener = () => this.cancel();\n\t\tsignal.addEventListener(\"abort\", this.#cancellationListener, { once: true });\n\t\tif (signal.aborted) this.cancel();\n\t}\n\n\tcancel(): void {\n\t\tthis.#terminate({ reason: \"cancelled\" });\n\t}\n\n\tcloseSession(): void {\n\t\tthis.#terminate({ reason: \"session_closed\" });\n\t}\n\n\tadvance(value: T, ops: readonly Op[], context: Context): void {\n\t\tif (this.#end !== undefined || this.#retired) return;\n\t\tif (value === null) this.#retired = true;\n\t\tif (this.#pending.length >= MAX_PENDING_WATCH_FRAMES) {\n\t\t\tthis.#pending.length = 0;\n\t\t\tconst replacement = this.#replace?.() ?? value;\n\t\t\tthis.#pending.push({ value: replacement, ops: [[\"r\", replacement as JsonValue]], context });\n\t\t} else {\n\t\t\tthis.#pending.push({ value, ops, context });\n\t\t}\n\t\tif (this.#started) this.#schedule();\n\t}\n\n\t#schedule(): void {\n\t\tif (this.#scheduled || this.#running || this.#end !== undefined) return;\n\t\tthis.#scheduled = true;\n\t\tqueueMicrotask(() => {\n\t\t\tthis.#scheduled = false;\n\t\t\tvoid this.#drain();\n\t\t});\n\t}\n\n\tasync #drain(): Promise<void> {\n\t\tif (this.#running || this.#end !== undefined || !this.#started) {\n\t\t\tthis.#finishIfReady();\n\t\t\treturn;\n\t\t}\n\t\tthis.#running = true;\n\t\ttry {\n\t\t\twhile (this.#end === undefined) {\n\t\t\t\tconst frame = this.#pending.shift();\n\t\t\t\tif (frame === undefined) break;\n\t\t\t\tthis.#value = frame.value;\n\t\t\t\tconst deliveryContext = withoutAbortSignal(frame.context);\n\t\t\t\ttry {\n\t\t\t\t\tawait this.#listener!(frame.value, frame.ops, deliveryContext);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (this.#end === undefined) {\n\t\t\t\t\t\tthis.#terminate({ reason: \"listener_error\", error: toError(error) });\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (frame.value === null) {\n\t\t\t\t\tthis.#terminate({ reason: \"retired\" });\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.#running = false;\n\t\t\tif (this.#end === undefined && this.#pending.length > 0) this.#schedule();\n\t\t\tthis.#finishIfReady();\n\t\t}\n\t}\n\n\t#terminate(end: WatchEnd): void {\n\t\tif (this.#end !== undefined) return;\n\t\tthis.#end = end;\n\t\tthis.#detachNow();\n\t\tthis.#pending.length = 0;\n\t\tthis.#finishIfReady();\n\t}\n\n\t#detachNow(): void {\n\t\tif (this.#detached) return;\n\t\tthis.#detached = true;\n\t\tthis.#detach();\n\t}\n\n\t#finishIfReady(): void {\n\t\tif (this.#resolved || this.#end === undefined) return;\n\t\tthis.#resolved = true;\n\t\tif (this.#cancellationSignal !== undefined && this.#cancellationListener !== undefined) {\n\t\t\tthis.#cancellationSignal.removeEventListener(\"abort\", this.#cancellationListener);\n\t\t}\n\t\tthis.#resolveClosed(this.#end);\n\t}\n}\n\nfunction toError(error: unknown): Error {\n\treturn error instanceof Error ? error : new Error(String(error));\n}\n"]}
1
+ {"version":3,"file":"observation.js","sourceRoot":"","sources":["../../src/session/observation.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tContext,\n\tJsonValue,\n\tReplicatedStateSource,\n\tReplicatedStateSourceAttachment,\n\tReplicatedStateSourceFrame,\n} from \"@earendil-works/chord\";\nimport { withoutAbortSignal } from \"@earendil-works/chord/context\";\nimport type { Op } from \"@earendil-works/chord/delta\";\nimport { errorMessage } from \"../errors.ts\";\nimport type { JsonObject, WatchEnd, WatchHandle } from \"../types.ts\";\n\nexport type ObservedDocumentValue = Readonly<JsonObject> | null;\n\n/** Maximum exact committed frames retained behind one unavailable watch listener. */\nconst MAX_PENDING_WATCH_FRAMES = 100;\n\n/** Canonical terminal update for a retired document incarnation. */\nexport const RETIREMENT_OPERATIONS: readonly Op[] = [[\"r\", null]];\n\n/**\n * Session-to-Chord bridge owned one-to-one by one attached state: a document, or a conversation view. A `null` value\n * retires it. @internal\n */\nexport class CommittedStateSource<T = ObservedDocumentValue> implements ReplicatedStateSource<T> {\n\treadonly #attachments = new Set<SessionSourceAttachment<T>>();\n\t#release: (() => void) | undefined;\n\t/** Released on disposal. */\n\t#value: T | undefined;\n\t#cursor = 0;\n\t#retired = false;\n\t#closed = false;\n\n\tconstructor(value: T, release: () => void) {\n\t\tthis.#value = value;\n\t\tthis.#release = release;\n\t}\n\n\tattach(): ReplicatedStateSourceAttachment<T> {\n\t\tif (this.#closed) throw new Error(\"State source is closed\");\n\t\tconst attachment = new SessionSourceAttachment({ value: this.#value as T, cursor: this.#cursor }, () => {\n\t\t\tthis.#attachments.delete(attachment);\n\t\t\tif (this.#attachments.size === 0) this.#finishDisposal();\n\t\t});\n\t\tthis.#attachments.add(attachment);\n\t\treturn attachment;\n\t}\n\n\tadvance(value: T, ops: readonly Op[], context: Context): void {\n\t\tif (this.#closed || this.#retired) return;\n\t\tthis.#value = value;\n\t\tthis.#cursor += 1;\n\t\tif (value === null) this.#retired = true;\n\t\tconst frame: ReplicatedStateSourceFrame<T> = {\n\t\t\tcursor: this.#cursor,\n\t\t\tvalue,\n\t\t\tops,\n\t\t\tcontext,\n\t\t};\n\t\tfor (const attachment of [...this.#attachments]) attachment.publish(frame);\n\t}\n\n\t/** Stop publishing; the attached states keep their last value. A failure ends them the same way. */\n\tcloseSession(): void {\n\t\tif (this.#closed) return;\n\t\tfor (const attachment of [...this.#attachments]) attachment.dispose();\n\t\tthis.#finishDisposal();\n\t}\n\n\t#finishDisposal(): void {\n\t\tif (this.#closed) return;\n\t\tthis.#closed = true;\n\t\tthis.#value = undefined;\n\t\tconst release = this.#release;\n\t\tthis.#release = undefined;\n\t\trelease?.();\n\t}\n}\n\nclass SessionSourceAttachment<T> implements ReplicatedStateSourceAttachment<T> {\n\treadonly snapshot: { readonly value: T; readonly cursor: number };\n\t#release: (() => void) | undefined;\n\treadonly #frames: ReplicatedStateSourceFrame<T>[] = [];\n\t#listener: ((frame: ReplicatedStateSourceFrame<T>) => void) | undefined;\n\t#activated = false;\n\t#disposed = false;\n\t#scheduled = false;\n\t#delivering = false;\n\n\tconstructor(snapshot: { readonly value: T; readonly cursor: number }, release: () => void) {\n\t\tthis.snapshot = snapshot;\n\t\tthis.#release = release;\n\t}\n\n\tactivate(listener: (frame: ReplicatedStateSourceFrame<T>) => void): void {\n\t\tif (this.#activated) throw new Error(\"State attachment is already active\");\n\t\tif (this.#disposed) throw new Error(\"State attachment is disposed\");\n\t\tthis.#activated = true;\n\t\tthis.#listener = listener;\n\t\tthis.#drain();\n\t}\n\n\tpublish(frame: ReplicatedStateSourceFrame<T>): void {\n\t\tif (this.#disposed) return;\n\t\tthis.#frames.push(frame);\n\t\tif (!this.#activated || this.#delivering || this.#scheduled) return;\n\t\tthis.#scheduled = true;\n\t\tqueueMicrotask(() => {\n\t\t\tthis.#scheduled = false;\n\t\t\tif (this.#disposed) return;\n\t\t\ttry {\n\t\t\t\tthis.#drain();\n\t\t\t} catch {\n\t\t\t\t// Chord's frame listener contains source-contract failures. Isolate an\n\t\t\t\t// unexpected direct listener failure to this attachment as well.\n\t\t\t\tthis.dispose();\n\t\t\t}\n\t\t});\n\t}\n\n\tdispose(): void {\n\t\tif (this.#disposed) return;\n\t\tthis.#disposed = true;\n\t\tthis.#frames.length = 0;\n\t\tthis.#listener = undefined;\n\t\tconst release = this.#release;\n\t\tthis.#release = undefined;\n\t\trelease?.();\n\t}\n\n\t#drain(): void {\n\t\tconst listener = this.#listener;\n\t\tif (listener === undefined || this.#delivering || this.#disposed) return;\n\t\tthis.#delivering = true;\n\t\ttry {\n\t\t\twhile (!this.#disposed) {\n\t\t\t\tconst frame = this.#frames.shift();\n\t\t\t\tif (frame === undefined) break;\n\t\t\t\tlistener(frame);\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.#delivering = false;\n\t\t}\n\t}\n}\n\ntype WatchFrame<T> = {\n\treadonly value: T;\n\treadonly ops: readonly Op[];\n\treadonly context: Context;\n};\n\n/**\n * Serialized exact-frame watch bound to one document incarnation or conversation view. A `null` value retires it.\n * @internal\n */\nexport class CommittedWatch<T = ObservedDocumentValue> implements WatchHandle<T> {\n\treadonly #detach: () => void;\n\treadonly #report: (error: unknown) => void;\n\treadonly #replace: (() => T) | undefined;\n\treadonly #closed = Promise.withResolvers<WatchEnd>();\n\treadonly #pending: WatchFrame<T>[] = [];\n\t#value: T;\n\t#listener: ((value: T, ops: readonly Op[], context: Context) => Promise<void>) | undefined;\n\t#started = false;\n\t#scheduled = false;\n\t#running = false;\n\t#retired = false;\n\t/** Set once, by `#terminate()`. */\n\t#end: WatchEnd | undefined;\n\t#cancellationSignal: AbortSignal | undefined;\n\t#cancellationListener: (() => void) | undefined;\n\n\t/**\n\t * `report` gets a listener's throw, which also ends the watch. `replace` gives the value an overflow delivers; by\n\t * default the newest value.\n\t */\n\tconstructor(value: T, detach: () => void, report: (error: unknown) => void, replace?: () => T) {\n\t\tthis.#value = value;\n\t\tthis.#detach = detach;\n\t\tthis.#report = report;\n\t\tthis.#replace = replace;\n\t}\n\n\tget value(): T {\n\t\treturn this.#value;\n\t}\n\n\tget closed(): Promise<WatchEnd> {\n\t\treturn this.#closed.promise;\n\t}\n\n\tstart(listener: (value: T, ops: readonly Op[], context: Context) => Promise<void>): void {\n\t\tif (this.#started) throw new Error(\"Watch is already started\");\n\t\tif (this.#end !== undefined) throw new Error(\"Watch is stopped\");\n\t\tthis.#started = true;\n\t\tthis.#listener = listener;\n\t\tif (this.#pending.length > 0) this.#schedule();\n\t}\n\n\tstop(): Promise<WatchEnd> {\n\t\tthis.#terminate({ reason: \"stopped\" });\n\t\treturn this.#closed.promise;\n\t}\n\n\tobserveCancellation(signal: AbortSignal): void {\n\t\tif (this.#cancellationSignal !== undefined) throw new Error(\"Watch cancellation is already installed\");\n\t\tif (this.#end !== undefined) return;\n\t\tthis.#cancellationSignal = signal;\n\t\tthis.#cancellationListener = () => this.cancel();\n\t\tsignal.addEventListener(\"abort\", this.#cancellationListener, { once: true });\n\t\tif (signal.aborted) this.cancel();\n\t}\n\n\tcancel(): void {\n\t\tthis.#terminate({ reason: \"cancelled\" });\n\t}\n\n\t/** End with `session_closed`, or with `session_failed` and the error when the Session failed. */\n\tcloseSession(failure?: { readonly error: unknown }): void {\n\t\tthis.#terminate(\n\t\t\tfailure === undefined ? { reason: \"session_closed\" } : { reason: \"session_failed\", error: failure.error },\n\t\t);\n\t}\n\n\tadvance(value: T, ops: readonly Op[], context: Context): void {\n\t\tif (this.#end !== undefined || this.#retired) return;\n\t\tif (value === null) this.#retired = true;\n\t\tif (this.#pending.length >= MAX_PENDING_WATCH_FRAMES) {\n\t\t\tthis.#pending.length = 0;\n\t\t\tconst replacement = this.#replace?.() ?? value;\n\t\t\tthis.#pending.push({ value: replacement, ops: [[\"r\", replacement as JsonValue]], context });\n\t\t} else {\n\t\t\tthis.#pending.push({ value, ops, context });\n\t\t}\n\t\tif (this.#started) this.#schedule();\n\t}\n\n\t#schedule(): void {\n\t\tif (this.#scheduled || this.#running || this.#end !== undefined) return;\n\t\tthis.#scheduled = true;\n\t\tqueueMicrotask(() => {\n\t\t\tthis.#scheduled = false;\n\t\t\tvoid this.#drain();\n\t\t});\n\t}\n\n\tasync #drain(): Promise<void> {\n\t\tif (this.#running || this.#end !== undefined || !this.#started) return;\n\t\tthis.#running = true;\n\t\ttry {\n\t\t\twhile (this.#end === undefined) {\n\t\t\t\tconst frame = this.#pending.shift();\n\t\t\t\tif (frame === undefined) break;\n\t\t\t\tthis.#value = frame.value;\n\t\t\t\tconst deliveryContext = withoutAbortSignal(frame.context);\n\t\t\t\ttry {\n\t\t\t\t\tawait this.#listener!(frame.value, frame.ops, deliveryContext);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (this.#end === undefined) {\n\t\t\t\t\t\tthis.#report(error);\n\t\t\t\t\t\tthis.#terminate({ reason: \"listener_error\", error: toError(error) });\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (frame.value === null) {\n\t\t\t\t\tthis.#terminate({ reason: \"retired\" });\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.#running = false;\n\t\t\tif (this.#end === undefined && this.#pending.length > 0) this.#schedule();\n\t\t}\n\t}\n\n\t/** End the watch, once: detach, drop pending frames, and settle `closed`. A callback already running keeps running. */\n\t#terminate(end: WatchEnd): void {\n\t\tif (this.#end !== undefined) return;\n\t\tthis.#end = end;\n\t\tthis.#detach();\n\t\tthis.#pending.length = 0;\n\t\tif (this.#cancellationListener !== undefined) {\n\t\t\tthis.#cancellationSignal?.removeEventListener(\"abort\", this.#cancellationListener);\n\t\t}\n\t\tthis.#closed.resolve(end);\n\t}\n}\n\nfunction toError(error: unknown): Error {\n\treturn error instanceof Error ? error : new Error(errorMessage(error));\n}\n"]}
@@ -1,20 +1,56 @@
1
1
  import { type Context, type JsonValue } from "@earendil-works/chord";
2
- import type { CommitPublication, ConversationDocFamilyToken, ConversationDocToken, ConversationId, ConversationRecord, DocumentRecord, DocumentState, DocumentWatch, EntryId, JsonObject, RewindableConversationDocFamilyToken, RewindableConversationDocToken, Session, SessionDocFamilyToken, SessionDocToken, Storage, TaskDocFamilyToken, TaskDocToken, TaskId, Tx } from "../types.ts";
2
+ import type { CommitPublication, ConversationDocFamilyToken, ConversationDocToken, ConversationId, ConversationRecord, DocumentRecord, DocumentState, DocumentWatch, EntryId, JsonObject, RewindableConversationDocFamilyToken, RewindableConversationDocToken, Session, SessionDocFamilyToken, SessionDocToken, SessionEnd, Storage, TaskDocFamilyToken, TaskDocToken, TaskId, Tx } from "../types.ts";
3
3
  import { Transaction, type TransactionScope } from "./transaction.ts";
4
- /** Open a Session kernel over one storage backend. `now` is the wall clock for task times; default `Date.now`. */
4
+ /**
5
+ * Open a Session kernel over one storage backend. `now` is the wall clock for task times; default `Date.now`. The first
6
+ * error a Storage method throws fails the Session (`SessionFailed`); see `SessionImpl`.
7
+ */
5
8
  export declare function createSession(storage: Storage, options?: {
6
9
  readonly now?: () => number;
10
+ readonly documentRetentionMs?: number;
7
11
  }): Session;
12
+ /** Internal, for tests: the retention of every Session that keeps the default, as a suite run with eviction at once. */
13
+ export declare function setDefaultDocumentRetention(ms: number): void;
14
+ /**
15
+ * A retention as given, when it is a number of milliseconds, `0` or more (`Infinity` keeps documents); otherwise the
16
+ * default.
17
+ */
18
+ export declare function documentRetention(ms: number | undefined): number;
8
19
  /**
9
20
  * Session kernel: one mutation line, the loaded document tracker cache, and committed publication.
10
21
  *
22
+ * The cache is bounded by use: a document with no watch or document state attached leaves it once it was not read or
23
+ * written for the retention period, and the next access loads it from Storage. Eviction runs as a job on the mutation
24
+ * line, so no transaction ever holds a tracker that leaves.
25
+ *
11
26
  * Only committed state is observable. Every commit callback, preparation, Storage settlement, adoption, and
12
27
  * publication enqueue runs while the line is held; listeners run later.
28
+ *
29
+ * Storage failures are final. Every Storage call goes through one guard: the first error a Storage method throws, other
30
+ * than for a cancelled caller, fails the Session, as does a commit it cannot adopt. That call gets the error; every later
31
+ * call and every Storage call still underway gets `SessionFailed`; close listeners run at once with the error, and the
32
+ * Session then closes itself, Storage included, and `closed` settles. Nothing retries: transient errors are the
33
+ * Storage's to retry. Reopening recovers from what was committed.
13
34
  */
14
35
  export declare class SessionImpl implements Session {
15
36
  #private;
16
- constructor(storage: Storage, now?: () => number);
37
+ get closed(): Promise<SessionEnd>;
38
+ /** Internal: the error that failed the Session, if one did. */
39
+ get failure(): {
40
+ readonly error: unknown;
41
+ } | undefined;
42
+ /** Internal: rejects with `SessionFailed` the moment the Session fails, before work underway has ended; never resolves. */
43
+ get failed(): Promise<never>;
44
+ constructor(storage: Storage, now?: () => number, documentRetentionMs?: () => number | undefined);
45
+ /** The Storage behind the failure guard; every component reads and writes through it. */
46
+ protected get storage(): Storage;
17
47
  commit<T>(change: (tx: Tx) => T | Promise<T>, context: Context): Promise<T>;
48
+ /**
49
+ * Internal: fail the Session with `error`, the first wins, and report it once. Admission ends, and close listeners run
50
+ * now; they read the error from `failure`. The Storage guard calls this; the Harness also calls it for a throw in its
51
+ * scheduler's own commits.
52
+ */
53
+ fail(error: unknown): void;
18
54
  /**
19
55
  * Internal commit exposing the concrete transaction and its internal operations, such as the reserved-ID root
20
56
  * bootstrap and task replacement. `scope` sets the default `tx.createTask()` conversation and the task attributed to
@@ -53,6 +89,8 @@ export declare class SessionImpl implements Session {
53
89
  snapshotAsOf<T extends JsonObject>(token: RewindableConversationDocToken<T>, conversationId: ConversationId, at: EntryId, context: Context): Promise<Readonly<T> | undefined>;
54
90
  snapshotAsOf<T extends JsonObject, I extends JsonValue>(token: RewindableConversationDocFamilyToken<T, I>, conversationId: ConversationId, key: string, at: EntryId, context: Context): Promise<Readonly<T> | undefined>;
55
91
  close(context: Context): Promise<void>;
92
+ /** Internal: the Session's failure, and errors of listeners, which never fail what ran them. A plain Session drops them. */
93
+ report(_error: unknown): void;
56
94
  /**
57
95
  * Runs inside every transaction that creates or forks a conversation, after the conversation record is staged. A
58
96
  * plain Session stages nothing; a Harness stages its built-in documents.
@@ -60,11 +98,36 @@ export declare class SessionImpl implements Session {
60
98
  protected conversationCreated(_tx: Transaction, _record: ConversationRecord): Promise<void>;
61
99
  /** Runs after close seals admission and before the line closes Storage; must not reject. */
62
100
  protected beforeClose(): Promise<void>;
63
- /** Register a synchronous post-adoption listener. It must not throw, block, or call Session operations. */
101
+ /** Register a synchronous post-adoption listener. It must not block or call Session operations; a throw is reported. */
64
102
  subscribeCommits(listener: (publication: CommitPublication, context: Context) => void): () => void;
65
- /** Register a listener called synchronously when close begins. It must not throw, block, or call Session operations. */
103
+ /**
104
+ * Internal: `subscribeCommits()` for the Session's own components, whose state follows each commit. A throw leaves
105
+ * that state behind storage, so it fails the Session instead of being reported. They run before host listeners.
106
+ */
107
+ observeCommits(listener: (publication: CommitPublication, context: Context) => void): () => void;
108
+ /**
109
+ * Register a listener called synchronously when close begins, also when a failure closes the Session (`failure` is
110
+ * then set). It must not block or call Session operations; a throw is reported.
111
+ */
66
112
  subscribeClose(listener: () => void): () => void;
67
113
  /** Drop every loaded tracker on the mutation line; later access cold-loads from Storage. */
68
114
  unloadDocuments(): Promise<void>;
115
+ /**
116
+ * Internal, for tests: how many documents the cache holds, how many are idle, how many incarnations are pinned, and how
117
+ * many sweep jobs were queued on the line so far.
118
+ */
119
+ get documentCacheSizes(): {
120
+ readonly cached: number;
121
+ readonly idle: number;
122
+ readonly attached: number;
123
+ readonly sweeps: number;
124
+ };
125
+ /** Internal: throw `SessionFailed` when failed, else an error when closing. */
126
+ assertUsable(): void;
69
127
  }
128
+ /**
129
+ * Run a host callback that must not fail its caller: a throw, or a promise it returns that rejects, goes to `onError`,
130
+ * which is not awaited.
131
+ */
132
+ export declare function contained(callback: () => unknown, onError: (error: unknown) => void): void;
70
133
  //# sourceMappingURL=session.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/session/session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/session/session.ts"],"names":[],"mappings":"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"}