@earendil-works/pi-durable 1.4.0 → 1.5.1

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 (270) hide show
  1. package/CHANGELOG.md +204 -0
  2. package/README.md +195 -85
  3. package/dist/codemode/codemode.d.ts +6 -5
  4. package/dist/codemode/codemode.d.ts.map +1 -1
  5. package/dist/codemode/codemode.js +10 -49
  6. package/dist/codemode/codemode.js.map +1 -1
  7. package/dist/codemode/models.d.ts +2 -1
  8. package/dist/codemode/models.d.ts.map +1 -1
  9. package/dist/codemode/models.js +4 -4
  10. package/dist/codemode/models.js.map +1 -1
  11. package/dist/documents.d.ts +1 -1
  12. package/dist/documents.d.ts.map +1 -1
  13. package/dist/documents.js +1 -1
  14. package/dist/documents.js.map +1 -1
  15. package/dist/entries.d.ts +1 -1
  16. package/dist/entries.d.ts.map +1 -1
  17. package/dist/entries.js.map +1 -1
  18. package/dist/env/index.d.ts +13 -11
  19. package/dist/env/index.d.ts.map +1 -1
  20. package/dist/env/index.js.map +1 -1
  21. package/dist/env/node-watch.d.ts +4 -4
  22. package/dist/env/node-watch.d.ts.map +1 -1
  23. package/dist/env/node-watch.js +18 -16
  24. package/dist/env/node-watch.js.map +1 -1
  25. package/dist/env/node.d.ts +3 -3
  26. package/dist/env/node.d.ts.map +1 -1
  27. package/dist/env/node.js +1 -1
  28. package/dist/env/node.js.map +1 -1
  29. package/dist/errors.d.ts +18 -2
  30. package/dist/errors.d.ts.map +1 -1
  31. package/dist/errors.js +26 -3
  32. package/dist/errors.js.map +1 -1
  33. package/dist/harness/agent.d.ts.map +1 -1
  34. package/dist/harness/agent.js +37 -3
  35. package/dist/harness/agent.js.map +1 -1
  36. package/dist/harness/compaction.d.ts +8 -3
  37. package/dist/harness/compaction.d.ts.map +1 -1
  38. package/dist/harness/compaction.js +40 -11
  39. package/dist/harness/compaction.js.map +1 -1
  40. package/dist/harness/context.d.ts +24 -8
  41. package/dist/harness/context.d.ts.map +1 -1
  42. package/dist/harness/context.js +71 -25
  43. package/dist/harness/context.js.map +1 -1
  44. package/dist/harness/define.d.ts +8 -4
  45. package/dist/harness/define.d.ts.map +1 -1
  46. package/dist/harness/define.js +4 -0
  47. package/dist/harness/define.js.map +1 -1
  48. package/dist/harness/generation.d.ts +39 -6
  49. package/dist/harness/generation.d.ts.map +1 -1
  50. package/dist/harness/generation.js +451 -100
  51. package/dist/harness/generation.js.map +1 -1
  52. package/dist/harness/harness.d.ts +3 -1
  53. package/dist/harness/harness.d.ts.map +1 -1
  54. package/dist/harness/harness.js +87 -62
  55. package/dist/harness/harness.js.map +1 -1
  56. package/dist/harness/inbox.d.ts +7 -2
  57. package/dist/harness/inbox.d.ts.map +1 -1
  58. package/dist/harness/inbox.js +5 -2
  59. package/dist/harness/inbox.js.map +1 -1
  60. package/dist/harness/json.d.ts +21 -5
  61. package/dist/harness/json.d.ts.map +1 -1
  62. package/dist/harness/json.js +23 -5
  63. package/dist/harness/json.js.map +1 -1
  64. package/dist/harness/live.d.ts +124 -17
  65. package/dist/harness/live.d.ts.map +1 -1
  66. package/dist/harness/live.js +93 -12
  67. package/dist/harness/live.js.map +1 -1
  68. package/dist/harness/partial-changes.d.ts +54 -0
  69. package/dist/harness/partial-changes.d.ts.map +1 -0
  70. package/dist/harness/partial-changes.js +163 -0
  71. package/dist/harness/partial-changes.js.map +1 -0
  72. package/dist/harness/prompt.d.ts +1 -1
  73. package/dist/harness/prompt.d.ts.map +1 -1
  74. package/dist/harness/prompt.js.map +1 -1
  75. package/dist/harness/provider.d.ts +1 -1
  76. package/dist/harness/provider.d.ts.map +1 -1
  77. package/dist/harness/provider.js.map +1 -1
  78. package/dist/harness/registry-reader.d.ts +11 -0
  79. package/dist/harness/registry-reader.d.ts.map +1 -0
  80. package/dist/harness/registry-reader.js +25 -0
  81. package/dist/harness/registry-reader.js.map +1 -0
  82. package/dist/harness/scheduler.d.ts +48 -20
  83. package/dist/harness/scheduler.d.ts.map +1 -1
  84. package/dist/harness/scheduler.js +1006 -380
  85. package/dist/harness/scheduler.js.map +1 -1
  86. package/dist/harness/submissions.d.ts +18 -11
  87. package/dist/harness/submissions.d.ts.map +1 -1
  88. package/dist/harness/submissions.js +63 -26
  89. package/dist/harness/submissions.js.map +1 -1
  90. package/dist/harness/task-graph.d.ts +14 -9
  91. package/dist/harness/task-graph.d.ts.map +1 -1
  92. package/dist/harness/task-graph.js +38 -28
  93. package/dist/harness/task-graph.js.map +1 -1
  94. package/dist/harness/telemetry.d.ts +11 -11
  95. package/dist/harness/telemetry.d.ts.map +1 -1
  96. package/dist/harness/telemetry.js +7 -7
  97. package/dist/harness/telemetry.js.map +1 -1
  98. package/dist/harness/tool.d.ts +3 -1
  99. package/dist/harness/tool.d.ts.map +1 -1
  100. package/dist/harness/tool.js +172 -56
  101. package/dist/harness/tool.js.map +1 -1
  102. package/dist/harness/transcript.d.ts +72 -0
  103. package/dist/harness/transcript.d.ts.map +1 -0
  104. package/dist/harness/transcript.js +264 -0
  105. package/dist/harness/transcript.js.map +1 -0
  106. package/dist/harness/types.d.ts +237 -61
  107. package/dist/harness/types.d.ts.map +1 -1
  108. package/dist/harness/types.js.map +1 -1
  109. package/dist/harness/usage.d.ts +2 -1
  110. package/dist/harness/usage.d.ts.map +1 -1
  111. package/dist/harness/usage.js +1 -1
  112. package/dist/harness/usage.js.map +1 -1
  113. package/dist/harness/util.d.ts +4 -2
  114. package/dist/harness/util.d.ts.map +1 -1
  115. package/dist/harness/util.js +9 -0
  116. package/dist/harness/util.js.map +1 -1
  117. package/dist/harness/view.d.ts +44 -22
  118. package/dist/harness/view.d.ts.map +1 -1
  119. package/dist/harness/view.js +130 -71
  120. package/dist/harness/view.js.map +1 -1
  121. package/dist/index.d.ts +9 -7
  122. package/dist/index.d.ts.map +1 -1
  123. package/dist/index.js +4 -3
  124. package/dist/index.js.map +1 -1
  125. package/dist/search.d.ts +19 -3
  126. package/dist/search.d.ts.map +1 -1
  127. package/dist/search.js +107 -44
  128. package/dist/search.js.map +1 -1
  129. package/dist/session/cached-storage.d.ts +72 -0
  130. package/dist/session/cached-storage.d.ts.map +1 -0
  131. package/dist/session/cached-storage.js +269 -0
  132. package/dist/session/cached-storage.js.map +1 -0
  133. package/dist/session/conversation-tails.d.ts +33 -0
  134. package/dist/session/conversation-tails.d.ts.map +1 -0
  135. package/dist/session/conversation-tails.js +101 -0
  136. package/dist/session/conversation-tails.js.map +1 -0
  137. package/dist/session/forks.d.ts +1 -1
  138. package/dist/session/forks.d.ts.map +1 -1
  139. package/dist/session/forks.js.map +1 -1
  140. package/dist/session/keys.d.ts +69 -0
  141. package/dist/session/keys.d.ts.map +1 -0
  142. package/dist/session/keys.js +161 -0
  143. package/dist/session/keys.js.map +1 -0
  144. package/dist/session/session.d.ts +169 -26
  145. package/dist/session/session.d.ts.map +1 -1
  146. package/dist/session/session.js +1029 -171
  147. package/dist/session/session.js.map +1 -1
  148. package/dist/session/transaction.d.ts +84 -5
  149. package/dist/session/transaction.d.ts.map +1 -1
  150. package/dist/session/transaction.js +227 -40
  151. package/dist/session/transaction.js.map +1 -1
  152. package/dist/session/writer.d.ts +74 -0
  153. package/dist/session/writer.d.ts.map +1 -0
  154. package/dist/session/writer.js +294 -0
  155. package/dist/session/writer.js.map +1 -0
  156. package/dist/storage/indexeddb.d.ts +12 -3
  157. package/dist/storage/indexeddb.d.ts.map +1 -1
  158. package/dist/storage/indexeddb.js +91 -41
  159. package/dist/storage/indexeddb.js.map +1 -1
  160. package/dist/storage/jsonl/index.d.ts +1 -1
  161. package/dist/storage/jsonl/index.d.ts.map +1 -1
  162. package/dist/storage/jsonl/index.js +1 -1
  163. package/dist/storage/jsonl/index.js.map +1 -1
  164. package/dist/storage/jsonl/node.d.ts +3 -3
  165. package/dist/storage/jsonl/node.d.ts.map +1 -1
  166. package/dist/storage/jsonl/node.js +2 -2
  167. package/dist/storage/jsonl/node.js.map +1 -1
  168. package/dist/storage/jsonl/storage.d.ts +46 -5
  169. package/dist/storage/jsonl/storage.d.ts.map +1 -1
  170. package/dist/storage/jsonl/storage.js +158 -43
  171. package/dist/storage/jsonl/storage.js.map +1 -1
  172. package/dist/storage/memory.d.ts +9 -3
  173. package/dist/storage/memory.d.ts.map +1 -1
  174. package/dist/storage/memory.js +28 -2
  175. package/dist/storage/memory.js.map +1 -1
  176. package/dist/storage/sqlite/commit.d.ts +52 -0
  177. package/dist/storage/sqlite/commit.d.ts.map +1 -0
  178. package/dist/storage/sqlite/commit.js +371 -0
  179. package/dist/storage/sqlite/commit.js.map +1 -0
  180. package/dist/storage/sqlite/rows.d.ts +33 -0
  181. package/dist/storage/sqlite/rows.d.ts.map +1 -0
  182. package/dist/storage/sqlite/rows.js +53 -0
  183. package/dist/storage/sqlite/rows.js.map +1 -0
  184. package/dist/storage/sqlite/statements.d.ts +13 -0
  185. package/dist/storage/sqlite/statements.d.ts.map +1 -0
  186. package/dist/storage/sqlite/statements.js +88 -0
  187. package/dist/storage/sqlite/statements.js.map +1 -0
  188. package/dist/storage/sqlite/storage.d.ts +23 -10
  189. package/dist/storage/sqlite/storage.d.ts.map +1 -1
  190. package/dist/storage/sqlite/storage.js +120 -261
  191. package/dist/storage/sqlite/storage.js.map +1 -1
  192. package/dist/storage/store/commit.d.ts +33 -0
  193. package/dist/storage/store/commit.d.ts.map +1 -0
  194. package/dist/storage/store/commit.js +286 -0
  195. package/dist/storage/store/commit.js.map +1 -0
  196. package/dist/storage/store/documents.d.ts +43 -0
  197. package/dist/storage/store/documents.d.ts.map +1 -0
  198. package/dist/storage/store/documents.js +102 -0
  199. package/dist/storage/store/documents.js.map +1 -0
  200. package/dist/storage/store/index.d.ts +2 -0
  201. package/dist/storage/store/index.d.ts.map +1 -0
  202. package/dist/storage/store/index.js +2 -0
  203. package/dist/storage/store/index.js.map +1 -0
  204. package/dist/storage/store/queries.d.ts +49 -0
  205. package/dist/storage/store/queries.d.ts.map +1 -0
  206. package/dist/storage/store/queries.js +93 -0
  207. package/dist/storage/store/queries.js.map +1 -0
  208. package/dist/storage/store/storage.d.ts +60 -0
  209. package/dist/storage/store/storage.d.ts.map +1 -0
  210. package/dist/storage/store/storage.js +438 -0
  211. package/dist/storage/store/storage.js.map +1 -0
  212. package/dist/storage/store/tables.d.ts +54 -0
  213. package/dist/storage/store/tables.d.ts.map +1 -0
  214. package/dist/storage/store/tables.js +108 -0
  215. package/dist/storage/store/tables.js.map +1 -0
  216. package/dist/testing/commit-writes.d.ts +5 -0
  217. package/dist/testing/commit-writes.d.ts.map +1 -0
  218. package/dist/testing/commit-writes.js +12 -0
  219. package/dist/testing/commit-writes.js.map +1 -0
  220. package/dist/testing/env-conformance.js +7 -7
  221. package/dist/testing/env-conformance.js.map +1 -1
  222. package/dist/testing/index.d.ts +1 -0
  223. package/dist/testing/index.d.ts.map +1 -1
  224. package/dist/testing/index.js +1 -0
  225. package/dist/testing/index.js.map +1 -1
  226. package/dist/testing/storage-benchmark.d.ts.map +1 -1
  227. package/dist/testing/storage-benchmark.js +18 -17
  228. package/dist/testing/storage-benchmark.js.map +1 -1
  229. package/dist/testing/storage-conformance.d.ts.map +1 -1
  230. package/dist/testing/storage-conformance.js +354 -69
  231. package/dist/testing/storage-conformance.js.map +1 -1
  232. package/dist/tool-search/tool-search.d.ts +8 -14
  233. package/dist/tool-search/tool-search.d.ts.map +1 -1
  234. package/dist/tool-search/tool-search.js +25 -13
  235. package/dist/tool-search/tool-search.js.map +1 -1
  236. package/dist/tools/bash.d.ts +13 -13
  237. package/dist/tools/bash.d.ts.map +1 -1
  238. package/dist/tools/bash.js +16 -15
  239. package/dist/tools/bash.js.map +1 -1
  240. package/dist/tools/edit.d.ts +7 -7
  241. package/dist/tools/edit.d.ts.map +1 -1
  242. package/dist/tools/edit.js +9 -9
  243. package/dist/tools/edit.js.map +1 -1
  244. package/dist/tools/file-mutation-queue.d.ts +1 -1
  245. package/dist/tools/file-mutation-queue.d.ts.map +1 -1
  246. package/dist/tools/file-mutation-queue.js.map +1 -1
  247. package/dist/tools/index.d.ts +32 -32
  248. package/dist/tools/path-utils.d.ts +1 -1
  249. package/dist/tools/path-utils.d.ts.map +1 -1
  250. package/dist/tools/path-utils.js.map +1 -1
  251. package/dist/tools/read.d.ts +6 -6
  252. package/dist/tools/read.d.ts.map +1 -1
  253. package/dist/tools/read.js +19 -8
  254. package/dist/tools/read.js.map +1 -1
  255. package/dist/tools/write.d.ts +4 -4
  256. package/dist/tools/write.d.ts.map +1 -1
  257. package/dist/tools/write.js +5 -5
  258. package/dist/tools/write.js.map +1 -1
  259. package/dist/types.d.ts +228 -78
  260. package/dist/types.d.ts.map +1 -1
  261. package/dist/types.js.map +1 -1
  262. package/package.json +19 -12
  263. package/dist/harness/events.d.ts +0 -186
  264. package/dist/harness/events.d.ts.map +0 -1
  265. package/dist/harness/events.js +0 -373
  266. package/dist/harness/events.js.map +0 -1
  267. package/dist/session/observation.d.ts +0 -42
  268. package/dist/session/observation.d.ts.map +0 -1
  269. package/dist/session/observation.js +0 -281
  270. package/dist/session/observation.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/storage/jsonl/storage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/storage/jsonl/storage.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,8 @@ import { MemoryStorage } from "../memory.js";
4
4
  const FORMAT_VERSION = 1;
5
5
  const MAIN_FILE = "main.jsonl";
6
6
  const RECLAIM_SUFFIX = ".reclaim";
7
+ /** Read-only opens retried after racing a writer's commits; each retry means another commit landed meanwhile. */
8
+ const READ_ONLY_OPEN_ATTEMPTS = 5;
7
9
  const textDecoder = new TextDecoder("utf-8", { fatal: true });
8
10
  export class JsonlCorruptionError extends Error {
9
11
  constructor(message, cause) {
@@ -11,6 +13,13 @@ export class JsonlCorruptionError extends Error {
11
13
  this.name = "JsonlCorruptionError";
12
14
  }
13
15
  }
16
+ /** `commit()` on a storage opened with `readOnly: true`. Nothing was written. */
17
+ export class JsonlStorageReadOnlyError extends Error {
18
+ constructor() {
19
+ super("JSONL storage is open read-only");
20
+ this.name = "JsonlStorageReadOnlyError";
21
+ }
22
+ }
14
23
  export class JsonlStoragePoisonedError extends Error {
15
24
  constructor(cause) {
16
25
  super("JSONL storage is poisoned and must be reopened", { cause });
@@ -147,38 +156,122 @@ export class JsonlStorage {
147
156
  directory;
148
157
  mainPath;
149
158
  fsync;
159
+ readOnly;
150
160
  memory = new MemoryStorage();
151
161
  currentOnlyDocuments = new Set();
152
162
  liveTaskSidecars = new Set();
153
163
  closed = false;
164
+ /** Bytes of `main.jsonl` recovery read (`mainChanged()`). */
165
+ mainSize = 0;
154
166
  poisonError;
167
+ /** Settles once the batch being appended is; its batches are in memory already (`commit()`). */
168
+ writing;
155
169
  constructor(fs, directory, mainPath, options) {
156
170
  this.fs = fs;
157
171
  this.directory = directory;
158
172
  this.mainPath = mainPath;
159
173
  this.fsync = options.fsync ?? false;
174
+ this.readOnly = options.readOnly ?? false;
160
175
  }
161
- /** Open or create a JSONL storage directory using the supplied filesystem. */
176
+ /**
177
+ * Open or create a JSONL storage directory using the supplied filesystem. With `readOnly`, open an existing one
178
+ * without writing; a recovery that fails while `main.jsonl` changes raced a writer's commit and is retried.
179
+ */
162
180
  static async open(directory, fs, context, options = {}) {
163
181
  const absolute = await fs.absolutePath(directory, context);
164
182
  if (!absolute.ok)
165
183
  throw errorFromFile("path resolution", absolute.error);
166
- const created = await fs.createDir(absolute.value, { recursive: true }, context);
167
- if (!created.ok)
168
- throw errorFromFile("directory creation", created.error);
184
+ if (options.readOnly !== true) {
185
+ const created = await fs.createDir(absolute.value, { recursive: true }, context);
186
+ if (!created.ok)
187
+ throw errorFromFile("directory creation", created.error);
188
+ }
169
189
  const mainPathResult = await fs.joinPath([absolute.value, MAIN_FILE], context);
170
190
  if (!mainPathResult.ok)
171
191
  throw errorFromFile("path join", mainPathResult.error);
172
- const storage = new JsonlStorage(fs, absolute.value, mainPathResult.value, options);
173
- await storage.recover(context);
174
- return storage;
192
+ for (let attempt = 1;; attempt++) {
193
+ const storage = new JsonlStorage(fs, absolute.value, mainPathResult.value, options);
194
+ try {
195
+ await storage.recover(context);
196
+ return storage;
197
+ }
198
+ catch (error) {
199
+ if (!storage.readOnly ||
200
+ attempt === READ_ONLY_OPEN_ATTEMPTS ||
201
+ !(error instanceof JsonlCorruptionError) ||
202
+ !(await storage.mainChanged(context))) {
203
+ throw error;
204
+ }
205
+ }
206
+ }
175
207
  }
176
- async commit(writes, context) {
208
+ /**
209
+ * Commit `batches` with one append per affected file: every batch's sidecar records first, then their markers in one
210
+ * write of `main.jsonl`. Each batch is checked against the state the earlier ones left, so memory applies each one
211
+ * as it passes, and reads wait until the appends are done; the first batch refused ends the batch. A torn append of
212
+ * the markers recovers a shorter complete prefix; any failure once a batch applied poisons the storage.
213
+ */
214
+ async commit(batches, receive, context) {
177
215
  this.assertUsable();
178
- const prepared = this.memory.prepareCommit(writes);
179
- const encoded = this.encodeCommit(prepared.seq, prepared.writes);
180
- const reclamations = this.planReclamations(prepared.writes, encoded);
181
- const sidecars = await Promise.all([...encoded.sidecars].map(async ([file, content]) => ({
216
+ if (this.readOnly)
217
+ throw new JsonlStorageReadOnlyError();
218
+ const seqs = [];
219
+ const encoded = [];
220
+ const reclamations = new Map();
221
+ let refused;
222
+ const writing = Promise.withResolvers();
223
+ this.writing = writing.promise;
224
+ try {
225
+ for (const writes of batches) {
226
+ let prepared;
227
+ try {
228
+ prepared = this.memory.prepareCommit(writes);
229
+ }
230
+ catch (error) {
231
+ refused = { error };
232
+ break;
233
+ }
234
+ const commit = this.encodeCommit(prepared.seq, prepared.writes);
235
+ // A sidecar an earlier batch replaces keeps what the later ones append, unless they replace it again.
236
+ for (const [file, content] of commit.sidecars) {
237
+ const replacement = reclamations.get(file);
238
+ if (replacement !== undefined)
239
+ reclamations.set(file, replacement + content);
240
+ }
241
+ for (const [file, content] of this.planReclamations(prepared.writes, commit))
242
+ reclamations.set(file, content);
243
+ seqs.push(prepared.apply());
244
+ this.adoptSidecarState(prepared.writes);
245
+ encoded.push(commit);
246
+ }
247
+ if (encoded.length > 0)
248
+ await this.append(encoded, context);
249
+ }
250
+ catch (error) {
251
+ // Memory runs ahead of the file: once a batch applied, any failure poisons the storage before the reads
252
+ // waiting on the append go on, so none of them returns what is not stored.
253
+ if (seqs.length === 0)
254
+ throw error;
255
+ throw this.poison(error instanceof Error ? error : new Error("JSONL commit failed", { cause: error }));
256
+ }
257
+ finally {
258
+ this.writing = undefined;
259
+ writing.resolve();
260
+ }
261
+ // The markers are appended: the batches are durable. Reclaiming sidecars comes after the receipts.
262
+ for (const [index, seq] of seqs.entries())
263
+ receive(index, seq);
264
+ await this.reclaimSidecars(reclamations, context);
265
+ return refused === undefined ? { stored: seqs.length } : { stored: seqs.length, refused: refused.error };
266
+ }
267
+ /** Append the sidecar records of `commits`, flushed with `fsync`, then their markers in one write of `main.jsonl`. */
268
+ async append(commits, context) {
269
+ const contents = new Map();
270
+ for (const commit of commits) {
271
+ for (const [file, content] of commit.sidecars)
272
+ contents.set(file, (contents.get(file) ?? "") + content);
273
+ }
274
+ const sidecars = await Promise.all([...contents].map(async ([file, content]) => ({
182
275
  file,
183
276
  content,
184
277
  path: await this.resolveFile(file, context),
@@ -195,59 +288,56 @@ export class JsonlStorage {
195
288
  throw this.poison(errorFromFile(`flush of ${sidecar.file}`, result.error));
196
289
  }
197
290
  }
198
- const marker = await this.fs.appendFile(this.mainPath, encoded.marker, context);
291
+ const markers = commits.length === 1 ? commits[0].marker : commits.map((commit) => commit.marker).join("");
292
+ const marker = await this.fs.appendFile(this.mainPath, markers, context);
199
293
  if (!marker.ok)
200
294
  throw this.poison(errorFromFile(`append to ${MAIN_FILE}`, marker.error));
201
- const seq = prepared.apply();
202
- this.adoptSidecarState(prepared.writes);
203
- await this.reclaimSidecars(reclamations, context);
204
- return seq;
205
295
  }
206
296
  async mintId() {
207
297
  return this.store.mintId();
208
298
  }
209
299
  async conversation(id, context) {
210
- return this.store.conversation(id, context);
300
+ return (await this.readable()).conversation(id, context);
211
301
  }
212
302
  async scanConversations(query, limit, cursor, context) {
213
- return this.store.scanConversations(query, limit, cursor, context);
303
+ return (await this.readable()).scanConversations(query, limit, cursor, context);
214
304
  }
215
305
  async entry(idOrConversationId, idOrContext, context) {
216
306
  if (context === undefined)
217
- return this.store.entry(idFromNumber(idOrConversationId), idOrContext);
307
+ return (await this.readable()).entry(idFromNumber(idOrConversationId), idOrContext);
218
308
  if (typeof idOrContext !== "number")
219
309
  throw new StorageRequestError("Storage.entry() requires an entry ID");
220
- return this.store.entry(idFromNumber(idOrConversationId), idFromNumber(idOrContext), context);
310
+ return (await this.readable()).entry(idFromNumber(idOrConversationId), idFromNumber(idOrContext), context);
221
311
  }
222
312
  async findLatestHeadMarker(conversationId, atOrBeforeEntryId, context) {
223
- return this.store.findLatestHeadMarker(conversationId, atOrBeforeEntryId, context);
313
+ return (await this.readable()).findLatestHeadMarker(conversationId, atOrBeforeEntryId, context);
224
314
  }
225
315
  async scanEntries(query, limit, cursor, context) {
226
- return this.store.scanEntries(query, limit, cursor, context);
316
+ return (await this.readable()).scanEntries(query, limit, cursor, context);
227
317
  }
228
318
  async task(id, context) {
229
- return this.store.task(id, context);
319
+ return (await this.readable()).task(id, context);
230
320
  }
231
321
  async scanTasks(query, limit, cursor, context) {
232
- return this.store.scanTasks(query, limit, cursor, context);
322
+ return (await this.readable()).scanTasks(query, limit, cursor, context);
233
323
  }
234
324
  async submission(id, context) {
235
- return this.store.submission(id, context);
325
+ return (await this.readable()).submission(id, context);
236
326
  }
237
327
  async scanSubmissions(query, limit, cursor, context) {
238
- return this.store.scanSubmissions(query, limit, cursor, context);
328
+ return (await this.readable()).scanSubmissions(query, limit, cursor, context);
239
329
  }
240
330
  async submissionByRequest(conversationId, requestId, context) {
241
- return this.store.submissionByRequest(conversationId, requestId, context);
331
+ return (await this.readable()).submissionByRequest(conversationId, requestId, context);
242
332
  }
243
333
  async findDocument(address, at, context) {
244
- return this.store.findDocument(address, at, context);
334
+ return (await this.readable()).findDocument(address, at, context);
245
335
  }
246
336
  async document(id, at, context) {
247
- return this.store.document(id, at, context);
337
+ return (await this.readable()).document(id, at, context);
248
338
  }
249
339
  async scanDocuments(query, limit, cursor, context) {
250
- return this.store.scanDocuments(query, limit, cursor, context);
340
+ return (await this.readable()).scanDocuments(query, limit, cursor, context);
251
341
  }
252
342
  async close(context) {
253
343
  if (this.closed)
@@ -412,11 +502,17 @@ export class JsonlStorage {
412
502
  }
413
503
  await this.fs.renameFile(temporaryPath.value, path.value, context);
414
504
  }
505
+ /**
506
+ * Load the confirmed state. A writable open also repairs the files: it truncates torn lines and unconfirmed sidecar
507
+ * tails, removes leftover reclaim files, and reclaims sidecar records later commits made unnecessary. A read-only
508
+ * open skips the same records in memory only.
509
+ */
415
510
  async recover(context) {
416
511
  const fs = this.fs;
417
512
  const directory = this.directory;
418
513
  const memory = this.memory;
419
- const main = await JsonlStorage.readLines(fs, this.mainPath, MAIN_FILE, context, (text, line) => parseMainMarker(text, line));
514
+ const main = await this.readLines(this.mainPath, MAIN_FILE, context, (text, line) => parseMainMarker(text, line));
515
+ this.mainSize = main.size;
420
516
  let previousSeq = 0;
421
517
  for (const marker of main.lines) {
422
518
  if (marker.value.seq <= previousSeq) {
@@ -428,7 +524,7 @@ export class JsonlStorage {
428
524
  if (!listed.ok)
429
525
  throw errorFromFile("directory listing", listed.error);
430
526
  for (const info of listed.value) {
431
- if (info.kind === "file" && isReclaimFileName(info.name)) {
527
+ if (!this.readOnly && info.kind === "file" && isReclaimFileName(info.name)) {
432
528
  await fs.remove(info.path, { force: true }, context);
433
529
  }
434
530
  }
@@ -442,7 +538,7 @@ export class JsonlStorage {
442
538
  const pathResult = await fs.joinPath([directory, file], context);
443
539
  if (!pathResult.ok)
444
540
  throw errorFromFile("path join", pathResult.error);
445
- const parsed = await JsonlStorage.readLines(fs, pathResult.value, file, context, (text, line) => parseSidecarRecord(text, file, line));
541
+ const parsed = await this.readLines(pathResult.value, file, context, (text, line) => parseSidecarRecord(text, file, line));
446
542
  parsedFiles.set(file, parsed);
447
543
  let previous;
448
544
  for (const line of parsed.lines) {
@@ -578,7 +674,7 @@ export class JsonlStorage {
578
674
  unconfirmedAt = line.start;
579
675
  }
580
676
  }
581
- if (unconfirmedAt !== undefined) {
677
+ if (unconfirmedAt !== undefined && !this.readOnly) {
582
678
  const truncated = await fs.truncateFile(parsed.path, unconfirmedAt, context);
583
679
  if (!truncated.ok)
584
680
  throw errorFromFile(`tail truncation of ${file}`, truncated.error);
@@ -603,7 +699,8 @@ export class JsonlStorage {
603
699
  reclamations.set(file, retainedLines.map((line) => jsonLine(line.value)).join(""));
604
700
  }
605
701
  }
606
- await this.reclaimSidecars(reclamations, context);
702
+ if (!this.readOnly)
703
+ await this.reclaimSidecars(reclamations, context);
607
704
  for (const id of currentOnlyDocuments)
608
705
  this.currentOnlyDocuments.add(id);
609
706
  for (const [id, live] of finalTaskIsLive) {
@@ -624,20 +721,23 @@ export class JsonlStorage {
624
721
  confirmed.add(key);
625
722
  return line.value;
626
723
  }
627
- static async readLines(fs, path, name, context, parse) {
628
- const read = await fs.readBinaryFile(path, context);
724
+ /** Parse the complete lines of `path`; a torn final line is truncated, or only skipped when read-only. */
725
+ async readLines(path, name, context, parse) {
726
+ const read = await this.fs.readBinaryFile(path, context);
629
727
  if (!read.ok) {
630
728
  if (read.error.code === "not_found")
631
- return { path, lines: [] };
729
+ return { path, lines: [], size: 0 };
632
730
  throw errorFromFile(`read of ${name}`, read.error);
633
731
  }
634
732
  const bytes = read.value;
635
733
  let completeSize = bytes.length;
636
734
  if (completeSize > 0 && bytes[completeSize - 1] !== 0x0a) {
637
735
  completeSize = bytes.lastIndexOf(0x0a) + 1;
638
- const truncated = await fs.truncateFile(path, completeSize, context);
639
- if (!truncated.ok)
640
- throw errorFromFile(`torn-line truncation of ${name}`, truncated.error);
736
+ if (!this.readOnly) {
737
+ const truncated = await this.fs.truncateFile(path, completeSize, context);
738
+ if (!truncated.ok)
739
+ throw errorFromFile(`torn-line truncation of ${name}`, truncated.error);
740
+ }
641
741
  }
642
742
  const lines = [];
643
743
  let start = 0;
@@ -656,7 +756,16 @@ export class JsonlStorage {
656
756
  start = end + 1;
657
757
  lineNumber++;
658
758
  }
659
- return { path, lines };
759
+ return { path, lines, size: bytes.length };
760
+ }
761
+ /**
762
+ * Whether `main.jsonl` changed size since recovery read it. A writer reclaims a sidecar only after appending the
763
+ * marker that allows it, so sidecars read while `main.jsonl` stayed the same match its markers; a recovery that
764
+ * failed while it changed may have read a sidecar a newer commit reclaimed.
765
+ */
766
+ async mainChanged(context) {
767
+ const info = await this.fs.fileInfo(this.mainPath, context);
768
+ return info.ok && info.value.size !== this.mainSize;
660
769
  }
661
770
  async resolveFile(file, context) {
662
771
  const path = await this.fs.joinPath([this.directory, file], context);
@@ -668,6 +777,12 @@ export class JsonlStorage {
668
777
  this.assertUsable();
669
778
  return this.memory;
670
779
  }
780
+ /** The state to read once no batch is being appended: memory runs ahead of the file while one is. */
781
+ async readable() {
782
+ while (this.writing !== undefined)
783
+ await this.writing;
784
+ return this.store;
785
+ }
671
786
  poison(cause) {
672
787
  this.poisonError ??= new JsonlStoragePoisonedError(cause);
673
788
  return this.poisonError;