@earendil-works/pi-durable 1.0.4 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/README.md +2 -0
- package/dist/harness/agent.d.ts.map +1 -1
- package/dist/harness/agent.js +3 -0
- package/dist/harness/agent.js.map +1 -1
- package/dist/harness/compaction.js +1 -1
- package/dist/harness/compaction.js.map +1 -1
- package/dist/harness/context.d.ts +29 -1
- package/dist/harness/context.d.ts.map +1 -1
- package/dist/harness/context.js +125 -24
- package/dist/harness/context.js.map +1 -1
- package/dist/harness/generation.d.ts.map +1 -1
- package/dist/harness/generation.js +3 -3
- package/dist/harness/generation.js.map +1 -1
- package/dist/harness/harness.d.ts.map +1 -1
- package/dist/harness/harness.js +4 -3
- package/dist/harness/harness.js.map +1 -1
- package/dist/harness/scheduler.d.ts.map +1 -1
- package/dist/harness/scheduler.js +98 -5
- package/dist/harness/scheduler.js.map +1 -1
- package/dist/harness/tool.d.ts +1 -1
- package/dist/harness/tool.d.ts.map +1 -1
- package/dist/harness/tool.js +15 -5
- package/dist/harness/tool.js.map +1 -1
- package/dist/harness/types.d.ts +18 -2
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/session/session.d.ts +5 -3
- package/dist/session/session.d.ts.map +1 -1
- package/dist/session/session.js +5 -4
- package/dist/session/session.js.map +1 -1
- package/dist/session/transaction.d.ts +2 -0
- package/dist/session/transaction.d.ts.map +1 -1
- package/dist/session/transaction.js +18 -1
- package/dist/session/transaction.js.map +1 -1
- package/dist/storage/jsonl/storage.d.ts +4 -0
- package/dist/storage/jsonl/storage.d.ts.map +1 -1
- package/dist/storage/memory.d.ts +2 -0
- package/dist/storage/memory.d.ts.map +1 -1
- package/dist/storage/memory.js +72 -18
- package/dist/storage/memory.js.map +1 -1
- package/dist/storage/scan.d.ts +18 -0
- package/dist/storage/scan.d.ts.map +1 -0
- package/dist/storage/scan.js +28 -0
- package/dist/storage/scan.js.map +1 -0
- package/dist/storage/sqlite/cloudflare.d.ts +46 -0
- package/dist/storage/sqlite/cloudflare.d.ts.map +1 -0
- package/dist/storage/sqlite/cloudflare.js +106 -0
- package/dist/storage/sqlite/cloudflare.js.map +1 -0
- package/dist/storage/sqlite/storage.d.ts +2 -0
- package/dist/storage/sqlite/storage.d.ts.map +1 -1
- package/dist/storage/sqlite/storage.js +68 -16
- package/dist/storage/sqlite/storage.js.map +1 -1
- package/dist/testing/storage-conformance.d.ts.map +1 -1
- package/dist/testing/storage-conformance.js +58 -0
- package/dist/testing/storage-conformance.js.map +1 -1
- package/dist/types.d.ts +30 -7
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +10 -4
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { apply } from "@earendil-works/chord/delta";
|
|
2
2
|
import { StorageRejected } from "../../errors.js";
|
|
3
3
|
import { idFromNumber, seqFromNumber } from "../../ids.js";
|
|
4
|
+
import { nextCursor, scanStart } from "../scan.js";
|
|
4
5
|
import { applySqliteMigrations } from "./migrations.js";
|
|
5
6
|
const parseJson = (value) => JSON.parse(value);
|
|
6
7
|
const encodeJson = (value) => JSON.stringify(value);
|
|
@@ -14,12 +15,16 @@ const cursorId = (cursor) => {
|
|
|
14
15
|
throw new TypeError("Invalid storage cursor");
|
|
15
16
|
return idFromNumber(after);
|
|
16
17
|
};
|
|
17
|
-
const page = (values, limit) => {
|
|
18
|
+
const page = (values, limit, order = "ascending") => {
|
|
18
19
|
const items = values.slice(0, limit);
|
|
19
20
|
if (values.length <= limit)
|
|
20
21
|
return { items };
|
|
21
|
-
return { items, next:
|
|
22
|
+
return { items, next: nextCursor(items.at(-1).id, order) };
|
|
22
23
|
};
|
|
24
|
+
/** The ID condition, its parameter, and the `ORDER BY` direction of a table scan. */
|
|
25
|
+
const scanSql = (start) => start.order === "ascending"
|
|
26
|
+
? { clause: "id > ?", param: start.after ?? -1, direction: "ASC" }
|
|
27
|
+
: { clause: "id < ?", param: start.after ?? Number.MAX_SAFE_INTEGER, direction: "DESC" };
|
|
23
28
|
const scopeColumns = (scope) => {
|
|
24
29
|
switch (scope.kind) {
|
|
25
30
|
case "session":
|
|
@@ -128,8 +133,10 @@ export class SqliteStorage {
|
|
|
128
133
|
}
|
|
129
134
|
async scanConversations(query, limit, cursor, _context) {
|
|
130
135
|
this.assertOpen();
|
|
131
|
-
const
|
|
132
|
-
const
|
|
136
|
+
const start = scanStart(query.order, cursor, "ascending");
|
|
137
|
+
const scan = scanSql(start);
|
|
138
|
+
const clauses = [scan.clause];
|
|
139
|
+
const params = [scan.param];
|
|
133
140
|
if (query.ownerConversationId !== undefined) {
|
|
134
141
|
clauses.push("owner_conversation_id = ?");
|
|
135
142
|
params.push(query.ownerConversationId);
|
|
@@ -139,8 +146,8 @@ export class SqliteStorage {
|
|
|
139
146
|
params.push(query.ownerTaskId);
|
|
140
147
|
}
|
|
141
148
|
params.push(limit + 1);
|
|
142
|
-
const rows = await this.db.all(`SELECT record FROM conversations WHERE ${clauses.join(" AND ")} ORDER BY id LIMIT ?`, ...params);
|
|
143
|
-
return page(rows.map((row) => parseJson(row.record)), limit);
|
|
149
|
+
const rows = await this.db.all(`SELECT record FROM conversations WHERE ${clauses.join(" AND ")} ORDER BY id ${scan.direction} LIMIT ?`, ...params);
|
|
150
|
+
return page(rows.map((row) => parseJson(row.record)), limit, start.order);
|
|
144
151
|
}
|
|
145
152
|
entry(idOrConversationId, idOrContext, context) {
|
|
146
153
|
return this.admitRead(() => this.readEntry(idOrConversationId, idOrContext, context));
|
|
@@ -201,10 +208,12 @@ export class SqliteStorage {
|
|
|
201
208
|
}
|
|
202
209
|
}
|
|
203
210
|
async readEntries(query, limit, cursor) {
|
|
211
|
+
const { order, after } = scanStart(query.order, cursor, "descending");
|
|
212
|
+
if (order === "ascending")
|
|
213
|
+
return this.readEntriesAscending(query, limit, after);
|
|
204
214
|
let conversation = await this.readConversation(query.conversationId);
|
|
205
215
|
if (conversation === undefined)
|
|
206
216
|
throw new Error(`Unknown conversation: ${query.conversationId}`);
|
|
207
|
-
const after = cursorId(cursor);
|
|
208
217
|
let upper = query.maxEntryId;
|
|
209
218
|
if (after !== undefined)
|
|
210
219
|
upper = Math.min(upper ?? Number.MAX_SAFE_INTEGER, after - 1);
|
|
@@ -230,7 +239,46 @@ export class SqliteStorage {
|
|
|
230
239
|
break;
|
|
231
240
|
conversation = (await this.readConversation(conversation.parent.conversationId));
|
|
232
241
|
}
|
|
233
|
-
return page(values, limit);
|
|
242
|
+
return page(values, limit, "descending");
|
|
243
|
+
}
|
|
244
|
+
/** Oldest first: the fork chain's segments from the root conversation forward, each up to its fork point. */
|
|
245
|
+
async readEntriesAscending(query, limit, after) {
|
|
246
|
+
const segments = [];
|
|
247
|
+
let conversation = await this.readConversation(query.conversationId);
|
|
248
|
+
if (conversation === undefined)
|
|
249
|
+
throw new Error(`Unknown conversation: ${query.conversationId}`);
|
|
250
|
+
let upper = query.maxEntryId;
|
|
251
|
+
while (true) {
|
|
252
|
+
segments.push({ conversationId: conversation.id, upper });
|
|
253
|
+
if (conversation.parent === undefined)
|
|
254
|
+
break;
|
|
255
|
+
upper = upper === undefined ? conversation.parent.at : Math.min(upper, conversation.parent.at);
|
|
256
|
+
if (query.minEntryId !== undefined && upper < query.minEntryId)
|
|
257
|
+
break;
|
|
258
|
+
conversation = (await this.readConversation(conversation.parent.conversationId));
|
|
259
|
+
}
|
|
260
|
+
let lower = query.minEntryId;
|
|
261
|
+
if (after !== undefined)
|
|
262
|
+
lower = Math.max(lower ?? after + 1, after + 1);
|
|
263
|
+
const values = [];
|
|
264
|
+
for (const segment of segments.reverse()) {
|
|
265
|
+
const clauses = ["conversation_id = ?"];
|
|
266
|
+
const params = [segment.conversationId];
|
|
267
|
+
if (lower !== undefined) {
|
|
268
|
+
clauses.push("id >= ?");
|
|
269
|
+
params.push(lower);
|
|
270
|
+
}
|
|
271
|
+
if (segment.upper !== undefined) {
|
|
272
|
+
clauses.push("id <= ?");
|
|
273
|
+
params.push(segment.upper);
|
|
274
|
+
}
|
|
275
|
+
params.push(limit + 1 - values.length);
|
|
276
|
+
const rows = await this.db.all(`SELECT record FROM entries WHERE ${clauses.join(" AND ")} ORDER BY id ASC LIMIT ?`, ...params);
|
|
277
|
+
values.push(...rows.map((row) => parseJson(row.record)));
|
|
278
|
+
if (values.length > limit)
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
return page(values, limit, "ascending");
|
|
234
282
|
}
|
|
235
283
|
async task(id, _context) {
|
|
236
284
|
this.assertOpen();
|
|
@@ -239,8 +287,10 @@ export class SqliteStorage {
|
|
|
239
287
|
}
|
|
240
288
|
async scanTasks(query, limit, cursor, _context) {
|
|
241
289
|
this.assertOpen();
|
|
242
|
-
const
|
|
243
|
-
const
|
|
290
|
+
const start = scanStart(query.order, cursor, "ascending");
|
|
291
|
+
const scan = scanSql(start);
|
|
292
|
+
const clauses = [scan.clause];
|
|
293
|
+
const params = [scan.param];
|
|
244
294
|
if (query.conversationId !== undefined) {
|
|
245
295
|
clauses.push("conversation_id = ?");
|
|
246
296
|
params.push(query.conversationId);
|
|
@@ -262,8 +312,8 @@ export class SqliteStorage {
|
|
|
262
312
|
params.push(query.background ? 1 : 0);
|
|
263
313
|
}
|
|
264
314
|
params.push(limit + 1);
|
|
265
|
-
const rows = await this.db.all(`SELECT record FROM tasks WHERE ${clauses.join(" AND ")} ORDER BY id LIMIT ?`, ...params);
|
|
266
|
-
return page(rows.map((row) => parseJson(row.record)), limit);
|
|
315
|
+
const rows = await this.db.all(`SELECT record FROM tasks WHERE ${clauses.join(" AND ")} ORDER BY id ${scan.direction} LIMIT ?`, ...params);
|
|
316
|
+
return page(rows.map((row) => parseJson(row.record)), limit, start.order);
|
|
267
317
|
}
|
|
268
318
|
async submission(id, _context) {
|
|
269
319
|
this.assertOpen();
|
|
@@ -272,8 +322,10 @@ export class SqliteStorage {
|
|
|
272
322
|
}
|
|
273
323
|
async scanSubmissions(query, limit, cursor, _context) {
|
|
274
324
|
this.assertOpen();
|
|
275
|
-
const
|
|
276
|
-
const
|
|
325
|
+
const start = scanStart(query.order, cursor, "ascending");
|
|
326
|
+
const scan = scanSql(start);
|
|
327
|
+
const clauses = [scan.clause];
|
|
328
|
+
const params = [scan.param];
|
|
277
329
|
if (query.conversationId !== undefined) {
|
|
278
330
|
clauses.push("conversation_id = ?");
|
|
279
331
|
params.push(query.conversationId);
|
|
@@ -283,8 +335,8 @@ export class SqliteStorage {
|
|
|
283
335
|
params.push(query.status);
|
|
284
336
|
}
|
|
285
337
|
params.push(limit + 1);
|
|
286
|
-
const rows = await this.db.all(`SELECT record FROM submissions WHERE ${clauses.join(" AND ")} ORDER BY id LIMIT ?`, ...params);
|
|
287
|
-
return page(rows.map((row) => parseJson(row.record)), limit);
|
|
338
|
+
const rows = await this.db.all(`SELECT record FROM submissions WHERE ${clauses.join(" AND ")} ORDER BY id ${scan.direction} LIMIT ?`, ...params);
|
|
339
|
+
return page(rows.map((row) => parseJson(row.record)), limit, start.order);
|
|
288
340
|
}
|
|
289
341
|
async submissionByRequest(conversationId, requestId, _context) {
|
|
290
342
|
this.assertOpen();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../src/storage/sqlite/storage.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Context, JsonValue } from \"@earendil-works/chord\";\nimport { apply, type Op } from \"@earendil-works/chord/delta\";\nimport { StorageRejected } from \"../../errors.ts\";\nimport { idFromNumber, seqFromNumber } from \"../../ids.ts\";\nimport type {\n\tConversationId,\n\tConversationQuery,\n\tConversationRecord,\n\tCursor,\n\tDocumentAddress,\n\tDocumentContent,\n\tDocumentCreate,\n\tDocumentId,\n\tDocumentPoint,\n\tDocumentQuery,\n\tDocumentRecord,\n\tEntryId,\n\tEntryQuery,\n\tEntryRecord,\n\tId,\n\tJsonObject,\n\tPage,\n\tSeq,\n\tStorage,\n\tStorageWrite,\n\tStoredDocument,\n\tSubmissionId,\n\tSubmissionQuery,\n\tSubmissionRecord,\n\tTaskId,\n\tTaskQuery,\n\tTaskRecord,\n} from \"../../types.ts\";\nimport type { SqliteDatabase, SqliteExecutor, SqliteValue } from \"./database.ts\";\nimport { applySqliteMigrations } from \"./migrations.ts\";\n\ntype StoredTask = TaskRecord<JsonValue, JsonValue, JsonValue>;\ntype TableName = \"conversation\" | \"entry\" | \"task\" | \"submission\" | \"document\";\ntype RecordIdRow = { readonly record_type: TableName };\ntype JsonRow = { readonly record: string };\ntype EntryJsonRow = { readonly record: string; readonly commit_seq: number };\ntype RevisionRow = {\n\treadonly seq: number;\n\treadonly kind: DocumentContent[\"kind\"];\n\treadonly version: number;\n\treadonly content: string;\n};\ntype IdRow = { readonly id: number };\ntype MetadataRow = { readonly next_id: string; readonly next_seq: number };\ntype DocumentAction = {\n\tcreate?: DocumentCreate;\n\tcopy?: Extract<StorageWrite, { readonly type: \"document.copy\" }>[\"source\"];\n\tcontent?: DocumentContent;\n\tretire: boolean;\n};\ntype ScopeColumns = {\n\treadonly scopeKind: DocumentRecord[\"scope\"][\"kind\"];\n\treadonly ownerId: number;\n};\n\nconst parseJson = <T>(value: string): T => JSON.parse(value) as T;\nconst encodeJson = (value: unknown): string => JSON.stringify(value) as string;\n// Some SQLite bindings replace lone UTF-16 surrogates. JSON encoding keeps indexed identities lossless.\nconst encodeIndexedString = (value: string): string => JSON.stringify(value);\n\nconst cursorId = <I extends Id<string>>(cursor: Cursor | undefined): I | undefined => {\n\tconst after = cursor?.after;\n\tif (after === undefined) return undefined;\n\tif (typeof after !== \"number\" || !Number.isSafeInteger(after)) throw new TypeError(\"Invalid storage cursor\");\n\treturn idFromNumber<I>(after);\n};\n\nconst page = <T extends { readonly id: Id<string> }>(values: readonly T[], limit: number): Page<T, Cursor> => {\n\tconst items = values.slice(0, limit);\n\tif (values.length <= limit) return { items };\n\treturn { items, next: { after: items.at(-1)!.id } };\n};\n\nconst scopeColumns = (scope: DocumentRecord[\"scope\"]): ScopeColumns => {\n\tswitch (scope.kind) {\n\t\tcase \"session\":\n\t\t\treturn { scopeKind: \"session\", ownerId: 0 };\n\t\tcase \"conversation\":\n\t\t\treturn { scopeKind: \"conversation\", ownerId: scope.conversationId };\n\t\tcase \"task\":\n\t\t\treturn { scopeKind: \"task\", ownerId: scope.taskId };\n\t}\n};\n\nconst addressParts = (address: DocumentAddress | DocumentCreate | DocumentRecord) => {\n\tconst scope = scopeColumns(address.scope);\n\treturn {\n\t\tkind: encodeIndexedString(address.kind),\n\t\t...scope,\n\t\tfamily: address.key === undefined ? 0 : 1,\n\t\tkeyValue: encodeIndexedString(address.key ?? \"\"),\n\t};\n};\n\nconst addressKey = (address: DocumentAddress | DocumentCreate | DocumentRecord): string => {\n\tconst parts = addressParts(address);\n\treturn JSON.stringify([parts.kind, parts.scopeKind, parts.ownerId, parts.family, parts.keyValue]);\n};\n\nconst isAliveAt = (record: DocumentRecord, at: DocumentPoint): boolean => {\n\tif (at === \"current\") return record.retiredAt === undefined;\n\treturn record.createdAt <= at && (record.retiredAt === undefined || at < record.retiredAt);\n};\n\nconst isCurrentOnly = (record: DocumentRecord): boolean =>\n\trecord.scope.kind !== \"conversation\" || record.history === \"latest\";\n\nconst writeId = (write: StorageWrite): Id<string> | undefined => {\n\tswitch (write.type) {\n\t\tcase \"conversation\":\n\t\tcase \"entry\":\n\t\tcase \"task\":\n\t\tcase \"submission\":\n\t\t\treturn write.value.id;\n\t\tcase \"document.create\":\n\t\tcase \"document.copy\":\n\t\t\treturn write.record.id;\n\t\tcase \"document.change\":\n\t\tcase \"document.retire\":\n\t\t\treturn undefined;\n\t}\n};\n\n/** Portable SQLite implementation of the Pico storage contract. */\nexport class SqliteStorage implements Storage {\n\tprivate readonly db: SqliteDatabase;\n\tprivate nextId: number;\n\tprivate closed = false;\n\tprivate closing: Promise<void> | undefined;\n\tprivate admittedReads = 0;\n\tprivate readsDrained: (() => void) | undefined;\n\n\tprivate constructor(db: SqliteDatabase, nextId: number) {\n\t\tthis.db = db;\n\t\tthis.nextId = nextId;\n\t}\n\n\t/** Initialize storage over an owned SQLite database facade. */\n\tstatic async open(db: SqliteDatabase): Promise<SqliteStorage> {\n\t\ttry {\n\t\t\tawait applySqliteMigrations(db);\n\t\t\tconst metadata = await db.get<MetadataRow>(\n\t\t\t\t\"SELECT next_id, next_seq FROM durable_metadata WHERE singleton = 1\",\n\t\t\t);\n\t\t\tif (metadata === undefined) throw new Error(\"Durable SQLite metadata is missing\");\n\t\t\treturn new SqliteStorage(db, Number(metadata.next_id));\n\t\t} catch (error) {\n\t\t\ttry {\n\t\t\t\tawait db.close();\n\t\t\t} catch {\n\t\t\t\t// Preserve the initialization failure.\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync commit(writes: readonly StorageWrite[], _context: Context): Promise<Seq> {\n\t\tthis.assertOpen();\n\t\tconst documentActions = this.prepareDocumentActions(writes);\n\t\tconst candidateNextId = this.candidateNextId(writes);\n\t\tconst seq = await this.db.transaction(async (transaction) => {\n\t\t\tconst metadata = await transaction.get<MetadataRow>(\n\t\t\t\t\"SELECT next_id, next_seq FROM durable_metadata WHERE singleton = 1\",\n\t\t\t);\n\t\t\tif (metadata === undefined) throw new Error(\"Durable SQLite metadata is missing\");\n\t\t\tconst committedSeq = seqFromNumber(metadata.next_seq);\n\t\t\tawait this.checkGlobalIds(transaction, writes);\n\t\t\tawait this.checkDocumentActions(transaction, documentActions);\n\t\t\tfor (const write of writes) await this.applyTableWrite(transaction, write, committedSeq);\n\t\t\tawait this.applyDocumentActions(transaction, documentActions, committedSeq);\n\t\t\tawait transaction.run(\n\t\t\t\t\"UPDATE durable_metadata SET next_id = ?, next_seq = ? WHERE singleton = 1\",\n\t\t\t\tString(Math.max(Number(metadata.next_id), candidateNextId)),\n\t\t\t\tcommittedSeq + 1,\n\t\t\t);\n\t\t\treturn committedSeq;\n\t\t});\n\t\tthis.nextId = Math.max(this.nextId, candidateNextId);\n\t\treturn seq;\n\t}\n\n\tasync mintId<I extends Id<string>>(): Promise<I> {\n\t\tthis.assertOpen();\n\t\tif (!Number.isSafeInteger(this.nextId)) throw new Error(\"ID space is exhausted\");\n\t\treturn idFromNumber<I>(this.nextId++);\n\t}\n\n\tasync conversation(id: ConversationId, _context: Context): Promise<ConversationRecord | undefined> {\n\t\tthis.assertOpen();\n\t\tconst row = await this.db.get<JsonRow>(\"SELECT record FROM conversations WHERE id = ?\", id);\n\t\treturn row === undefined ? undefined : parseJson<ConversationRecord>(row.record);\n\t}\n\n\tasync scanConversations(\n\t\tquery: ConversationQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<ConversationRecord, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst clauses = [\"id > ?\"];\n\t\tconst params: SqliteValue[] = [cursorId(cursor) ?? -1];\n\t\tif (query.ownerConversationId !== undefined) {\n\t\t\tclauses.push(\"owner_conversation_id = ?\");\n\t\t\tparams.push(query.ownerConversationId);\n\t\t}\n\t\tif (query.ownerTaskId !== undefined) {\n\t\t\tclauses.push(\"owner_task_id = ?\");\n\t\t\tparams.push(query.ownerTaskId);\n\t\t}\n\t\tparams.push(limit + 1);\n\t\tconst rows = await this.db.all<JsonRow>(\n\t\t\t`SELECT record FROM conversations WHERE ${clauses.join(\" AND \")} ORDER BY id LIMIT ?`,\n\t\t\t...params,\n\t\t);\n\t\treturn page(\n\t\t\trows.map((row) => parseJson<ConversationRecord>(row.record)),\n\t\t\tlimit,\n\t\t);\n\t}\n\n\tentry(id: EntryId, context: Context): Promise<{ readonly entry: EntryRecord; readonly commitSeq: Seq } | undefined>;\n\tentry(\n\t\tconversationId: ConversationId,\n\t\tid: EntryId,\n\t\tcontext: Context,\n\t): Promise<{ readonly entry: EntryRecord; readonly commitSeq: Seq } | undefined>;\n\tentry(\n\t\tidOrConversationId: EntryId | ConversationId,\n\t\tidOrContext: EntryId | Context,\n\t\tcontext?: Context,\n\t): Promise<{ readonly entry: EntryRecord; readonly commitSeq: Seq } | undefined> {\n\t\treturn this.admitRead(() => this.readEntry(idOrConversationId, idOrContext, context));\n\t}\n\n\tfindLatestHeadMarker(\n\t\tconversationId: ConversationId,\n\t\tatOrBeforeEntryId: EntryId | undefined,\n\t\t_context: Context,\n\t): Promise<(EntryRecord & { readonly head: EntryId }) | undefined> {\n\t\treturn this.admitRead(() => this.readLatestHeadMarker(conversationId, atOrBeforeEntryId));\n\t}\n\n\tscanEntries(\n\t\tquery: EntryQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<EntryRecord, Cursor>> {\n\t\treturn this.admitRead(() => this.readEntries(query, limit, cursor));\n\t}\n\n\tprivate async readEntry(\n\t\tidOrConversationId: EntryId | ConversationId,\n\t\tidOrContext: EntryId | Context,\n\t\tcontext?: Context,\n\t): Promise<{ readonly entry: EntryRecord; readonly commitSeq: Seq } | undefined> {\n\t\tconst id =\n\t\t\tcontext === undefined\n\t\t\t\t? idFromNumber<EntryId>(idOrConversationId)\n\t\t\t\t: typeof idOrContext === \"number\"\n\t\t\t\t\t? idFromNumber<EntryId>(idOrContext)\n\t\t\t\t\t: undefined;\n\t\tif (id === undefined) throw new TypeError(\"Storage.entry() requires an entry ID\");\n\t\tlet conversation: ConversationRecord | undefined;\n\t\tif (context !== undefined) {\n\t\t\tconst conversationId = idFromNumber<ConversationId>(idOrConversationId);\n\t\t\tconversation = await this.readConversation(conversationId);\n\t\t\tif (conversation === undefined) throw new Error(`Unknown conversation: ${conversationId}`);\n\t\t}\n\t\tconst row = await this.db.get<EntryJsonRow>(\"SELECT record, commit_seq FROM entries WHERE id = ?\", id);\n\t\tif (row === undefined) return undefined;\n\t\tconst entry = parseJson<EntryRecord>(row.record);\n\t\tif (conversation !== undefined) {\n\t\t\tlet upperEntryId = Number.POSITIVE_INFINITY;\n\t\t\twhile (conversation.id !== entry.conversationId) {\n\t\t\t\tif (conversation.parent === undefined) return undefined;\n\t\t\t\tupperEntryId = Math.min(upperEntryId, conversation.parent.at);\n\t\t\t\tconversation = (await this.readConversation(conversation.parent.conversationId))!;\n\t\t\t}\n\t\t\tif (entry.id > upperEntryId) return undefined;\n\t\t}\n\t\treturn { entry, commitSeq: seqFromNumber(row.commit_seq) };\n\t}\n\n\tprivate async readLatestHeadMarker(\n\t\tconversationId: ConversationId,\n\t\tatOrBeforeEntryId: EntryId | undefined,\n\t): Promise<(EntryRecord & { readonly head: EntryId }) | undefined> {\n\t\tlet conversation = await this.readConversation(conversationId);\n\t\tif (conversation === undefined) throw new Error(`Unknown conversation: ${conversationId}`);\n\t\tlet upper: number | undefined = atOrBeforeEntryId;\n\t\twhile (true) {\n\t\t\tconst row =\n\t\t\t\tupper === undefined\n\t\t\t\t\t? await this.db.get<JsonRow>(\n\t\t\t\t\t\t\t\"SELECT record FROM entries WHERE conversation_id = ? AND head IS NOT NULL ORDER BY id DESC LIMIT 1\",\n\t\t\t\t\t\t\tconversation.id,\n\t\t\t\t\t\t)\n\t\t\t\t\t: await this.db.get<JsonRow>(\n\t\t\t\t\t\t\t\"SELECT record FROM entries WHERE conversation_id = ? AND head IS NOT NULL AND id <= ? ORDER BY id DESC LIMIT 1\",\n\t\t\t\t\t\t\tconversation.id,\n\t\t\t\t\t\t\tupper,\n\t\t\t\t\t\t);\n\t\t\tif (row !== undefined) return parseJson<EntryRecord & { readonly head: EntryId }>(row.record);\n\t\t\tif (conversation.parent === undefined) return undefined;\n\t\t\tupper = upper === undefined ? conversation.parent.at : Math.min(upper, conversation.parent.at);\n\t\t\tconversation = (await this.readConversation(conversation.parent.conversationId))!;\n\t\t}\n\t}\n\n\tprivate async readEntries(\n\t\tquery: EntryQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t): Promise<Page<EntryRecord, Cursor>> {\n\t\tlet conversation = await this.readConversation(query.conversationId);\n\t\tif (conversation === undefined) throw new Error(`Unknown conversation: ${query.conversationId}`);\n\t\tconst after = cursorId(cursor);\n\t\tlet upper: number | undefined = query.maxEntryId;\n\t\tif (after !== undefined) upper = Math.min(upper ?? Number.MAX_SAFE_INTEGER, after - 1);\n\t\tconst values: EntryRecord[] = [];\n\t\twhile (true) {\n\t\t\tconst clauses = [\"conversation_id = ?\"];\n\t\t\tconst params: SqliteValue[] = [conversation.id];\n\t\t\tif (query.minEntryId !== undefined) {\n\t\t\t\tclauses.push(\"id >= ?\");\n\t\t\t\tparams.push(query.minEntryId);\n\t\t\t}\n\t\t\tif (upper !== undefined) {\n\t\t\t\tclauses.push(\"id <= ?\");\n\t\t\t\tparams.push(upper);\n\t\t\t}\n\t\t\tparams.push(limit + 1 - values.length);\n\t\t\tconst rows = await this.db.all<JsonRow>(\n\t\t\t\t`SELECT record FROM entries WHERE ${clauses.join(\" AND \")} ORDER BY id DESC LIMIT ?`,\n\t\t\t\t...params,\n\t\t\t);\n\t\t\tvalues.push(...rows.map((row) => parseJson<EntryRecord>(row.record)));\n\t\t\tif (values.length > limit || conversation.parent === undefined) break;\n\t\t\tupper = upper === undefined ? conversation.parent.at : Math.min(upper, conversation.parent.at);\n\t\t\tif (query.minEntryId !== undefined && upper < query.minEntryId) break;\n\t\t\tconversation = (await this.readConversation(conversation.parent.conversationId))!;\n\t\t}\n\t\treturn page(values, limit);\n\t}\n\n\tasync task(id: TaskId, _context: Context): Promise<StoredTask | undefined> {\n\t\tthis.assertOpen();\n\t\tconst row = await this.db.get<JsonRow>(\"SELECT record FROM tasks WHERE id = ?\", id);\n\t\treturn row === undefined ? undefined : parseJson<StoredTask>(row.record);\n\t}\n\n\tasync scanTasks(\n\t\tquery: TaskQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<StoredTask, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst clauses = [\"id > ?\"];\n\t\tconst params: SqliteValue[] = [cursorId(cursor) ?? -1];\n\t\tif (query.conversationId !== undefined) {\n\t\t\tclauses.push(\"conversation_id = ?\");\n\t\t\tparams.push(query.conversationId);\n\t\t}\n\t\tif (query.kind !== undefined) {\n\t\t\tclauses.push(\"kind = ?\");\n\t\t\tparams.push(encodeIndexedString(query.kind));\n\t\t}\n\t\tif (query.status !== undefined) {\n\t\t\tclauses.push(\"status = ?\");\n\t\t\tparams.push(query.status);\n\t\t}\n\t\tif (query.abortRequested !== undefined) {\n\t\t\tclauses.push(\"abort_requested = ?\");\n\t\t\tparams.push(query.abortRequested ? 1 : 0);\n\t\t}\n\t\tif (query.background !== undefined) {\n\t\t\tclauses.push(\"background = ?\");\n\t\t\tparams.push(query.background ? 1 : 0);\n\t\t}\n\t\tparams.push(limit + 1);\n\t\tconst rows = await this.db.all<JsonRow>(\n\t\t\t`SELECT record FROM tasks WHERE ${clauses.join(\" AND \")} ORDER BY id LIMIT ?`,\n\t\t\t...params,\n\t\t);\n\t\treturn page(\n\t\t\trows.map((row) => parseJson<StoredTask>(row.record)),\n\t\t\tlimit,\n\t\t);\n\t}\n\n\tasync submission(id: SubmissionId, _context: Context): Promise<SubmissionRecord | undefined> {\n\t\tthis.assertOpen();\n\t\tconst row = await this.db.get<JsonRow>(\"SELECT record FROM submissions WHERE id = ?\", id);\n\t\treturn row === undefined ? undefined : parseJson<SubmissionRecord>(row.record);\n\t}\n\n\tasync scanSubmissions(\n\t\tquery: SubmissionQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<SubmissionRecord, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst clauses = [\"id > ?\"];\n\t\tconst params: SqliteValue[] = [cursorId(cursor) ?? -1];\n\t\tif (query.conversationId !== undefined) {\n\t\t\tclauses.push(\"conversation_id = ?\");\n\t\t\tparams.push(query.conversationId);\n\t\t}\n\t\tif (query.status !== undefined) {\n\t\t\tclauses.push(\"status = ?\");\n\t\t\tparams.push(query.status);\n\t\t}\n\t\tparams.push(limit + 1);\n\t\tconst rows = await this.db.all<JsonRow>(\n\t\t\t`SELECT record FROM submissions WHERE ${clauses.join(\" AND \")} ORDER BY id LIMIT ?`,\n\t\t\t...params,\n\t\t);\n\t\treturn page(\n\t\t\trows.map((row) => parseJson<SubmissionRecord>(row.record)),\n\t\t\tlimit,\n\t\t);\n\t}\n\n\tasync submissionByRequest(\n\t\tconversationId: ConversationId,\n\t\trequestId: string,\n\t\t_context: Context,\n\t): Promise<SubmissionRecord | undefined> {\n\t\tthis.assertOpen();\n\t\tconst row = await this.db.get<JsonRow>(\n\t\t\t\"SELECT record FROM submissions WHERE conversation_id = ? AND request_id = ?\",\n\t\t\tconversationId,\n\t\t\tencodeIndexedString(requestId),\n\t\t);\n\t\treturn row === undefined ? undefined : parseJson<SubmissionRecord>(row.record);\n\t}\n\n\tasync findDocument(\n\t\taddress: DocumentAddress,\n\t\tat: DocumentPoint,\n\t\t_context: Context,\n\t): Promise<DocumentRecord | undefined> {\n\t\tthis.assertOpen();\n\t\tconst parts = addressParts(address);\n\t\tconst sql =\n\t\t\tat === \"current\"\n\t\t\t\t? `SELECT record FROM documents\n\t\t\t\t\tWHERE kind = ? AND scope_kind = ? AND owner_id = ? AND family = ? AND key_value = ?\n\t\t\t\t\tAND retired_at IS NULL ORDER BY created_at DESC LIMIT 1`\n\t\t\t\t: `SELECT record FROM documents\n\t\t\t\t\tWHERE kind = ? AND scope_kind = ? AND owner_id = ? AND family = ? AND key_value = ?\n\t\t\t\t\tAND created_at <= ? AND (retired_at IS NULL OR retired_at > ?)\n\t\t\t\t\tORDER BY created_at DESC LIMIT 1`;\n\t\tconst params: SqliteValue[] = [parts.kind, parts.scopeKind, parts.ownerId, parts.family, parts.keyValue];\n\t\tif (at !== \"current\") params.push(at, at);\n\t\tconst row = await this.db.get<JsonRow>(sql, ...params);\n\t\treturn row === undefined ? undefined : parseJson<DocumentRecord>(row.record);\n\t}\n\n\tasync document(id: DocumentId, at: DocumentPoint, _context: Context): Promise<StoredDocument | undefined> {\n\t\tthis.assertOpen();\n\t\t// The record and revision queries must observe one committed state; a commit between them can replace the base.\n\t\treturn this.db.transaction((transaction) => this.materializeDocument(transaction, id, at));\n\t}\n\n\tasync scanDocuments(\n\t\tquery: DocumentQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<DocumentRecord, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst scope = scopeColumns(query.scope);\n\t\tconst clauses = [\"scope_kind = ?\", \"owner_id = ?\", \"id > ?\"];\n\t\tconst params: SqliteValue[] = [scope.scopeKind, scope.ownerId, cursorId(cursor) ?? -1];\n\t\tif (query.kind !== undefined) {\n\t\t\tclauses.push(\"kind = ?\");\n\t\t\tparams.push(encodeIndexedString(query.kind));\n\t\t}\n\t\tif (query.at === \"current\") {\n\t\t\tclauses.push(\"retired_at IS NULL\");\n\t\t} else {\n\t\t\tclauses.push(\"created_at <= ?\", \"(retired_at IS NULL OR retired_at > ?)\");\n\t\t\tparams.push(query.at, query.at);\n\t\t}\n\t\tparams.push(limit + 1);\n\t\tconst rows = await this.db.all<JsonRow>(\n\t\t\t`SELECT record FROM documents WHERE ${clauses.join(\" AND \")} ORDER BY id LIMIT ?`,\n\t\t\t...params,\n\t\t);\n\t\treturn page(\n\t\t\trows.map((row) => parseJson<DocumentRecord>(row.record)),\n\t\t\tlimit,\n\t\t);\n\t}\n\n\tclose(_context: Context): Promise<void> {\n\t\tif (this.closing === undefined) {\n\t\t\tthis.closed = true;\n\t\t\tthis.closing = this.closeDatabase();\n\t\t}\n\t\treturn this.closing;\n\t}\n\n\tprivate async closeDatabase(): Promise<void> {\n\t\tif (this.admittedReads > 0) {\n\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\tthis.readsDrained = resolve;\n\t\t\t});\n\t\t}\n\t\tawait this.db.close();\n\t}\n\n\t/**\n\t * Run a read that issues several queries. Close waits for admitted reads, so their later queries never reach a\n\t * closed database. Single-query reads and transactions are already ordered before close by the database.\n\t */\n\tprivate async admitRead<T>(read: () => Promise<T>): Promise<T> {\n\t\tthis.assertOpen();\n\t\tthis.admittedReads++;\n\t\ttry {\n\t\t\treturn await read();\n\t\t} finally {\n\t\t\tif (--this.admittedReads === 0) this.readsDrained?.();\n\t\t}\n\t}\n\n\tprivate async readConversation(id: ConversationId): Promise<ConversationRecord | undefined> {\n\t\tconst row = await this.db.get<JsonRow>(\"SELECT record FROM conversations WHERE id = ?\", id);\n\t\treturn row === undefined ? undefined : parseJson<ConversationRecord>(row.record);\n\t}\n\n\tprivate async materializeDocument(\n\t\texecutor: SqliteExecutor,\n\t\tid: DocumentId,\n\t\tat: DocumentPoint,\n\t): Promise<StoredDocument | undefined> {\n\t\tconst row = await executor.get<JsonRow>(\"SELECT record FROM documents WHERE id = ?\", id);\n\t\tif (row === undefined) return undefined;\n\t\tconst record = parseJson<DocumentRecord>(row.record);\n\t\tif (at !== \"current\" && isCurrentOnly(record)) {\n\t\t\tthrow new Error(`Document ${id} does not retain historical content`);\n\t\t}\n\t\tif (!isAliveAt(record, at)) return undefined;\n\t\tconst upper = at === \"current\" ? Number.MAX_SAFE_INTEGER : at;\n\t\tconst base = await executor.get<RevisionRow>(\n\t\t\t`SELECT seq, kind, version, content FROM document_revisions\n\t\t\t\tWHERE document_id = ? AND kind = 'base' AND seq <= ? ORDER BY seq DESC LIMIT 1`,\n\t\t\tid,\n\t\t\tupper,\n\t\t);\n\t\tif (base === undefined) throw new Error(`Document ${id} is missing a required base`);\n\t\tlet value = parseJson<JsonObject>(base.content);\n\t\tconst tail = await executor.all<RevisionRow>(\n\t\t\t`SELECT seq, kind, version, content FROM document_revisions\n\t\t\t\tWHERE document_id = ? AND seq > ? AND seq <= ? ORDER BY seq`,\n\t\t\tid,\n\t\t\tbase.seq,\n\t\t\tupper,\n\t\t);\n\t\tfor (const revision of tail) {\n\t\t\tif (revision.kind !== \"delta\" || revision.version !== base.version) {\n\t\t\t\tthrow new Error(`Document ${id} crosses a stored version boundary without a base`);\n\t\t\t}\n\t\t\tvalue = apply(value, parseJson<readonly Op[]>(revision.content)) as JsonObject;\n\t\t}\n\t\treturn { record, version: base.version, value, deltasSinceBase: tail.length };\n\t}\n\n\tprivate candidateNextId(writes: readonly StorageWrite[]): number {\n\t\tlet nextId = this.nextId;\n\t\tfor (const write of writes) {\n\t\t\tconst id = writeId(write);\n\t\t\tif (id !== undefined) nextId = Math.max(nextId, id + 1);\n\t\t}\n\t\treturn nextId;\n\t}\n\n\tprivate async checkGlobalIds(executor: SqliteExecutor, writes: readonly StorageWrite[]): Promise<void> {\n\t\tconst claimed = new Map<Id<string>, TableName>();\n\t\tfor (const write of writes) {\n\t\t\tif (write.type === \"document.change\" || write.type === \"document.retire\") continue;\n\t\t\tconst document = write.type === \"document.create\" || write.type === \"document.copy\";\n\t\t\tconst table: TableName = document ? \"document\" : write.type;\n\t\t\tconst id = document ? write.record.id : write.value.id;\n\t\t\tconst existing = (await executor.get<RecordIdRow>(\"SELECT record_type FROM record_ids WHERE id = ?\", id))\n\t\t\t\t?.record_type;\n\t\t\tconst earlier = claimed.get(id);\n\t\t\tif (table === \"conversation\" || table === \"entry\" || table === \"document\") {\n\t\t\t\tif (existing !== undefined) throw new Error(`ID ${id} already belongs to ${existing}`);\n\t\t\t\tif (earlier !== undefined) throw new Error(`ID ${id} is written more than once`);\n\t\t\t} else {\n\t\t\t\tif (existing !== undefined && existing !== table)\n\t\t\t\t\tthrow new Error(`ID ${id} already belongs to ${existing}`);\n\t\t\t\tif (earlier !== undefined && earlier !== table) throw new Error(`ID ${id} is written as two record types`);\n\t\t\t}\n\t\t\tclaimed.set(id, table);\n\t\t}\n\t}\n\n\tprivate prepareDocumentActions(writes: readonly StorageWrite[]): Map<DocumentId, DocumentAction> {\n\t\tconst actions = new Map<DocumentId, DocumentAction>();\n\t\tfor (const write of writes) {\n\t\t\tif (\n\t\t\t\twrite.type !== \"document.create\" &&\n\t\t\t\twrite.type !== \"document.copy\" &&\n\t\t\t\twrite.type !== \"document.change\" &&\n\t\t\t\twrite.type !== \"document.retire\"\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst id = write.type === \"document.create\" || write.type === \"document.copy\" ? write.record.id : write.id;\n\t\t\tlet action = actions.get(id);\n\t\t\tif (action === undefined) {\n\t\t\t\taction = { retire: false };\n\t\t\t\tactions.set(id, action);\n\t\t\t}\n\t\t\tswitch (write.type) {\n\t\t\t\tcase \"document.create\":\n\t\t\t\t\tif (action.create !== undefined || action.content !== undefined || action.copy !== undefined) {\n\t\t\t\t\t\tthrow new Error(`Document ${id} has more than one content command`);\n\t\t\t\t\t}\n\t\t\t\t\taction.create = write.record;\n\t\t\t\t\taction.content = write.content;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"document.copy\":\n\t\t\t\t\tif (action.create !== undefined || action.content !== undefined || action.copy !== undefined) {\n\t\t\t\t\t\tthrow new Error(`Document ${id} has more than one content command`);\n\t\t\t\t\t}\n\t\t\t\t\taction.create = write.record;\n\t\t\t\t\taction.copy = write.source;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"document.change\":\n\t\t\t\t\tif (action.content !== undefined || action.copy !== undefined) {\n\t\t\t\t\t\tthrow new Error(`Document ${id} has more than one content command`);\n\t\t\t\t\t}\n\t\t\t\t\taction.content = write.content;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"document.retire\":\n\t\t\t\t\tif (action.retire) throw new Error(`Document ${id} is retired more than once`);\n\t\t\t\t\taction.retire = true;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn actions;\n\t}\n\n\tprivate async checkDocumentActions(\n\t\texecutor: SqliteExecutor,\n\t\tactions: ReadonlyMap<DocumentId, DocumentAction>,\n\t): Promise<void> {\n\t\tconst liveCounts = new Map<string, number>();\n\t\tfor (const [id, action] of actions) {\n\t\t\tif (action.copy !== undefined && actions.has(action.copy.id)) {\n\t\t\t\tthrow new StorageRejected(`Document copy ${id} source is changed in the copy batch`);\n\t\t\t}\n\t\t\tconst row = await executor.get<JsonRow>(\"SELECT record FROM documents WHERE id = ?\", id);\n\t\t\tconst existing = row === undefined ? undefined : parseJson<DocumentRecord>(row.record);\n\t\t\tif (action.create === undefined && existing === undefined) throw new Error(`Unknown document: ${id}`);\n\t\t\tif (action.create !== undefined && existing !== undefined) throw new Error(`Document ${id} already exists`);\n\t\t\tif (existing?.retiredAt !== undefined) throw new Error(`Document ${id} is retired`);\n\t\t\tif (action.content?.kind === \"delta\") {\n\t\t\t\tconst previous = await executor.get<{ readonly version: number }>(\n\t\t\t\t\t\"SELECT version FROM document_revisions WHERE document_id = ? ORDER BY seq DESC LIMIT 1\",\n\t\t\t\t\tid,\n\t\t\t\t);\n\t\t\t\tif (previous === undefined) throw new Error(`Document ${id} delta has no base`);\n\t\t\t\tif (previous.version !== action.content.version) {\n\t\t\t\t\tthrow new Error(`Document ${id} version transition requires a base`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst record = action.create ?? existing!;\n\t\t\tconst key = addressKey(record);\n\t\t\tlet live = liveCounts.get(key);\n\t\t\tif (live === undefined) live = (await this.currentDocumentId(executor, record)) === undefined ? 0 : 1;\n\t\t\tif (action.retire && existing !== undefined) live--;\n\t\t\tif (action.create !== undefined && !action.retire) live++;\n\t\t\tliveCounts.set(key, live);\n\t\t}\n\t\tfor (const live of liveCounts.values()) {\n\t\t\tif (live > 1) throw new Error(\"Document address already has a current incarnation\");\n\t\t}\n\t}\n\n\tprivate async currentDocumentId(\n\t\texecutor: SqliteExecutor,\n\t\taddress: DocumentAddress | DocumentCreate | DocumentRecord,\n\t): Promise<DocumentId | undefined> {\n\t\tconst parts = addressParts(address);\n\t\tconst id = (\n\t\t\tawait executor.get<IdRow>(\n\t\t\t\t`SELECT id FROM documents\n\t\t\t\tWHERE kind = ? AND scope_kind = ? AND owner_id = ? AND family = ? AND key_value = ? AND retired_at IS NULL\n\t\t\t\tLIMIT 1`,\n\t\t\t\tparts.kind,\n\t\t\t\tparts.scopeKind,\n\t\t\t\tparts.ownerId,\n\t\t\t\tparts.family,\n\t\t\t\tparts.keyValue,\n\t\t\t)\n\t\t)?.id;\n\t\treturn id === undefined ? undefined : idFromNumber<DocumentId>(id);\n\t}\n\n\tprivate async applyTableWrite(executor: SqliteExecutor, write: StorageWrite, seq: Seq): Promise<void> {\n\t\tswitch (write.type) {\n\t\t\tcase \"conversation\":\n\t\t\t\tawait this.claimId(executor, write.value.id, \"conversation\");\n\t\t\t\tawait executor.run(\n\t\t\t\t\t\"INSERT INTO conversations (id, owner_conversation_id, owner_task_id, record) VALUES (?, ?, ?, ?)\",\n\t\t\t\t\twrite.value.id,\n\t\t\t\t\twrite.value.owner?.conversationId ?? null,\n\t\t\t\t\twrite.value.owner?.taskId ?? null,\n\t\t\t\t\tencodeJson(write.value),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"entry\":\n\t\t\t\tawait this.claimId(executor, write.value.id, \"entry\");\n\t\t\t\tawait executor.run(\n\t\t\t\t\t\"INSERT INTO entries (id, conversation_id, head, commit_seq, record) VALUES (?, ?, ?, ?, ?)\",\n\t\t\t\t\twrite.value.id,\n\t\t\t\t\twrite.value.conversationId,\n\t\t\t\t\twrite.value.head ?? null,\n\t\t\t\t\tseq,\n\t\t\t\t\tencodeJson(write.value),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"task\":\n\t\t\t\tawait this.claimId(executor, write.value.id, \"task\");\n\t\t\t\tawait executor.run(\n\t\t\t\t\t`INSERT INTO tasks (id, conversation_id, kind, status, abort_requested, background, record)\n\t\t\t\t\t\tVALUES (?, ?, ?, ?, ?, ?, ?)\n\t\t\t\t\t\tON CONFLICT(id) DO UPDATE SET conversation_id = excluded.conversation_id, kind = excluded.kind,\n\t\t\t\t\t\tstatus = excluded.status, abort_requested = excluded.abort_requested,\n\t\t\t\t\t\tbackground = excluded.background, record = excluded.record`,\n\t\t\t\t\twrite.value.id,\n\t\t\t\t\twrite.value.conversationId,\n\t\t\t\t\tencodeIndexedString(write.value.kind),\n\t\t\t\t\twrite.value.state.status,\n\t\t\t\t\twrite.value.abortRequested ? 1 : 0,\n\t\t\t\t\twrite.value.background ? 1 : 0,\n\t\t\t\t\tencodeJson(write.value),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"submission\":\n\t\t\t\tawait this.claimId(executor, write.value.id, \"submission\");\n\t\t\t\tawait executor.run(\n\t\t\t\t\t`INSERT INTO submissions (id, conversation_id, request_id, status, record) VALUES (?, ?, ?, ?, ?)\n\t\t\t\t\t\tON CONFLICT(id) DO UPDATE SET conversation_id = excluded.conversation_id,\n\t\t\t\t\t\trequest_id = excluded.request_id, status = excluded.status, record = excluded.record`,\n\t\t\t\t\twrite.value.id,\n\t\t\t\t\twrite.value.conversationId,\n\t\t\t\t\twrite.value.requestId === undefined ? null : encodeIndexedString(write.value.requestId),\n\t\t\t\t\twrite.value.status,\n\t\t\t\t\tencodeJson(write.value),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"document.create\":\n\t\t\tcase \"document.copy\":\n\t\t\tcase \"document.change\":\n\t\t\tcase \"document.retire\":\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprivate async claimId(executor: SqliteExecutor, id: Id<string>, table: TableName): Promise<void> {\n\t\tawait executor.run(\"INSERT OR IGNORE INTO record_ids (id, record_type) VALUES (?, ?)\", id, table);\n\t}\n\n\tprivate async applyDocumentActions(\n\t\texecutor: SqliteExecutor,\n\t\tactions: ReadonlyMap<DocumentId, DocumentAction>,\n\t\tseq: Seq,\n\t): Promise<void> {\n\t\tfor (const [id, action] of actions) {\n\t\t\tlet content = action.content;\n\t\t\tif (action.copy !== undefined) {\n\t\t\t\ttry {\n\t\t\t\t\tconst stored = await this.materializeDocument(executor, action.copy.id, action.copy.at);\n\t\t\t\t\tif (stored === undefined) throw new Error(`Fork source document ${action.copy.id} cannot be read`);\n\t\t\t\t\tconst create = action.create!;\n\t\t\t\t\tif (\n\t\t\t\t\t\tstored.record.scope.kind !== \"conversation\" ||\n\t\t\t\t\t\tcreate.scope.kind !== \"conversation\" ||\n\t\t\t\t\t\tstored.record.kind !== create.kind ||\n\t\t\t\t\t\tstored.record.key !== create.key ||\n\t\t\t\t\t\tstored.record.history !== create.history ||\n\t\t\t\t\t\tstored.record.fork !== create.fork\n\t\t\t\t\t) {\n\t\t\t\t\t\tthrow new Error(`Fork source document ${action.copy.id} does not match the copied record`);\n\t\t\t\t\t}\n\t\t\t\t\tcontent = { kind: \"base\", version: stored.version, value: stored.value };\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (error instanceof StorageRejected) throw error;\n\t\t\t\t\tthrow new StorageRejected(`Document copy ${id} was rejected`, { cause: error });\n\t\t\t\t}\n\t\t\t}\n\t\t\tlet record: DocumentRecord;\n\t\t\tif (action.create !== undefined) {\n\t\t\t\trecord = {\n\t\t\t\t\t...action.create,\n\t\t\t\t\tcreatedAt: seq,\n\t\t\t\t\t...(action.retire ? { retiredAt: seq } : {}),\n\t\t\t\t};\n\t\t\t\tconst parts = addressParts(record);\n\t\t\t\tawait this.claimId(executor, id, \"document\");\n\t\t\t\tawait executor.run(\n\t\t\t\t\t`INSERT INTO documents\n\t\t\t\t\t\t(id, kind, family, key_value, scope_kind, owner_id, created_at, retired_at, record)\n\t\t\t\t\t\tVALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n\t\t\t\t\tid,\n\t\t\t\t\tparts.kind,\n\t\t\t\t\tparts.family,\n\t\t\t\t\tparts.keyValue,\n\t\t\t\t\tparts.scopeKind,\n\t\t\t\t\tparts.ownerId,\n\t\t\t\t\tseq,\n\t\t\t\t\taction.retire ? seq : null,\n\t\t\t\t\tencodeJson(record),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tconst row = (await executor.get<JsonRow>(\"SELECT record FROM documents WHERE id = ?\", id))!;\n\t\t\t\trecord = parseJson<DocumentRecord>(row.record);\n\t\t\t}\n\n\t\t\tif (content !== undefined) {\n\t\t\t\tif (content.kind === \"base\" && isCurrentOnly(record)) {\n\t\t\t\t\tawait executor.run(\"DELETE FROM document_revisions WHERE document_id = ?\", id);\n\t\t\t\t}\n\t\t\t\tconst encodedContent = content.kind === \"base\" ? encodeJson(content.value) : encodeJson(content.ops);\n\t\t\t\tawait executor.run(\n\t\t\t\t\t\"INSERT INTO document_revisions (document_id, seq, kind, version, content) VALUES (?, ?, ?, ?, ?)\",\n\t\t\t\t\tid,\n\t\t\t\t\tseq,\n\t\t\t\t\tcontent.kind,\n\t\t\t\t\tcontent.version,\n\t\t\t\t\tencodedContent,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (action.retire) {\n\t\t\t\tif (action.create === undefined) {\n\t\t\t\t\trecord = { ...record, retiredAt: seq };\n\t\t\t\t\tawait executor.run(\n\t\t\t\t\t\t\"UPDATE documents SET retired_at = ?, record = ? WHERE id = ?\",\n\t\t\t\t\t\tseq,\n\t\t\t\t\t\tencodeJson(record),\n\t\t\t\t\t\tid,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (isCurrentOnly(record)) {\n\t\t\t\t\tawait executor.run(\"DELETE FROM document_revisions WHERE document_id = ?\", id);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate assertOpen(): void {\n\t\tif (this.closed) throw new Error(\"SqliteStorage is closed\");\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../src/storage/sqlite/storage.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Context, JsonValue } from \"@earendil-works/chord\";\nimport { apply, type Op } from \"@earendil-works/chord/delta\";\nimport { StorageRejected } from \"../../errors.ts\";\nimport { idFromNumber, seqFromNumber } from \"../../ids.ts\";\nimport type {\n\tConversationId,\n\tConversationQuery,\n\tConversationRecord,\n\tCursor,\n\tDocumentAddress,\n\tDocumentContent,\n\tDocumentCreate,\n\tDocumentId,\n\tDocumentPoint,\n\tDocumentQuery,\n\tDocumentRecord,\n\tEntryId,\n\tEntryQuery,\n\tEntryRecord,\n\tId,\n\tJsonObject,\n\tPage,\n\tScanOrder,\n\tSeq,\n\tStorage,\n\tStorageWrite,\n\tStoredDocument,\n\tSubmissionId,\n\tSubmissionQuery,\n\tSubmissionRecord,\n\tTaskId,\n\tTaskQuery,\n\tTaskRecord,\n} from \"../../types.ts\";\nimport { nextCursor, type ScanStart, scanStart } from \"../scan.ts\";\nimport type { SqliteDatabase, SqliteExecutor, SqliteValue } from \"./database.ts\";\nimport { applySqliteMigrations } from \"./migrations.ts\";\n\ntype StoredTask = TaskRecord<JsonValue, JsonValue, JsonValue>;\ntype TableName = \"conversation\" | \"entry\" | \"task\" | \"submission\" | \"document\";\ntype RecordIdRow = { readonly record_type: TableName };\ntype JsonRow = { readonly record: string };\ntype EntryJsonRow = { readonly record: string; readonly commit_seq: number };\ntype RevisionRow = {\n\treadonly seq: number;\n\treadonly kind: DocumentContent[\"kind\"];\n\treadonly version: number;\n\treadonly content: string;\n};\ntype IdRow = { readonly id: number };\ntype MetadataRow = { readonly next_id: string; readonly next_seq: number };\ntype DocumentAction = {\n\tcreate?: DocumentCreate;\n\tcopy?: Extract<StorageWrite, { readonly type: \"document.copy\" }>[\"source\"];\n\tcontent?: DocumentContent;\n\tretire: boolean;\n};\ntype ScopeColumns = {\n\treadonly scopeKind: DocumentRecord[\"scope\"][\"kind\"];\n\treadonly ownerId: number;\n};\n\nconst parseJson = <T>(value: string): T => JSON.parse(value) as T;\nconst encodeJson = (value: unknown): string => JSON.stringify(value) as string;\n// Some SQLite bindings replace lone UTF-16 surrogates. JSON encoding keeps indexed identities lossless.\nconst encodeIndexedString = (value: string): string => JSON.stringify(value);\n\nconst cursorId = <I extends Id<string>>(cursor: Cursor | undefined): I | undefined => {\n\tconst after = cursor?.after;\n\tif (after === undefined) return undefined;\n\tif (typeof after !== \"number\" || !Number.isSafeInteger(after)) throw new TypeError(\"Invalid storage cursor\");\n\treturn idFromNumber<I>(after);\n};\n\nconst page = <T extends { readonly id: Id<string> }>(\n\tvalues: readonly T[],\n\tlimit: number,\n\torder: ScanOrder = \"ascending\",\n): Page<T, Cursor> => {\n\tconst items = values.slice(0, limit);\n\tif (values.length <= limit) return { items };\n\treturn { items, next: nextCursor(items.at(-1)!.id, order) };\n};\n\n/** The ID condition, its parameter, and the `ORDER BY` direction of a table scan. */\nconst scanSql = (start: ScanStart): { readonly clause: string; readonly param: number; readonly direction: string } =>\n\tstart.order === \"ascending\"\n\t\t? { clause: \"id > ?\", param: start.after ?? -1, direction: \"ASC\" }\n\t\t: { clause: \"id < ?\", param: start.after ?? Number.MAX_SAFE_INTEGER, direction: \"DESC\" };\n\nconst scopeColumns = (scope: DocumentRecord[\"scope\"]): ScopeColumns => {\n\tswitch (scope.kind) {\n\t\tcase \"session\":\n\t\t\treturn { scopeKind: \"session\", ownerId: 0 };\n\t\tcase \"conversation\":\n\t\t\treturn { scopeKind: \"conversation\", ownerId: scope.conversationId };\n\t\tcase \"task\":\n\t\t\treturn { scopeKind: \"task\", ownerId: scope.taskId };\n\t}\n};\n\nconst addressParts = (address: DocumentAddress | DocumentCreate | DocumentRecord) => {\n\tconst scope = scopeColumns(address.scope);\n\treturn {\n\t\tkind: encodeIndexedString(address.kind),\n\t\t...scope,\n\t\tfamily: address.key === undefined ? 0 : 1,\n\t\tkeyValue: encodeIndexedString(address.key ?? \"\"),\n\t};\n};\n\nconst addressKey = (address: DocumentAddress | DocumentCreate | DocumentRecord): string => {\n\tconst parts = addressParts(address);\n\treturn JSON.stringify([parts.kind, parts.scopeKind, parts.ownerId, parts.family, parts.keyValue]);\n};\n\nconst isAliveAt = (record: DocumentRecord, at: DocumentPoint): boolean => {\n\tif (at === \"current\") return record.retiredAt === undefined;\n\treturn record.createdAt <= at && (record.retiredAt === undefined || at < record.retiredAt);\n};\n\nconst isCurrentOnly = (record: DocumentRecord): boolean =>\n\trecord.scope.kind !== \"conversation\" || record.history === \"latest\";\n\nconst writeId = (write: StorageWrite): Id<string> | undefined => {\n\tswitch (write.type) {\n\t\tcase \"conversation\":\n\t\tcase \"entry\":\n\t\tcase \"task\":\n\t\tcase \"submission\":\n\t\t\treturn write.value.id;\n\t\tcase \"document.create\":\n\t\tcase \"document.copy\":\n\t\t\treturn write.record.id;\n\t\tcase \"document.change\":\n\t\tcase \"document.retire\":\n\t\t\treturn undefined;\n\t}\n};\n\n/** Portable SQLite implementation of the Pico storage contract. */\nexport class SqliteStorage implements Storage {\n\tprivate readonly db: SqliteDatabase;\n\tprivate nextId: number;\n\tprivate closed = false;\n\tprivate closing: Promise<void> | undefined;\n\tprivate admittedReads = 0;\n\tprivate readsDrained: (() => void) | undefined;\n\n\tprivate constructor(db: SqliteDatabase, nextId: number) {\n\t\tthis.db = db;\n\t\tthis.nextId = nextId;\n\t}\n\n\t/** Initialize storage over an owned SQLite database facade. */\n\tstatic async open(db: SqliteDatabase): Promise<SqliteStorage> {\n\t\ttry {\n\t\t\tawait applySqliteMigrations(db);\n\t\t\tconst metadata = await db.get<MetadataRow>(\n\t\t\t\t\"SELECT next_id, next_seq FROM durable_metadata WHERE singleton = 1\",\n\t\t\t);\n\t\t\tif (metadata === undefined) throw new Error(\"Durable SQLite metadata is missing\");\n\t\t\treturn new SqliteStorage(db, Number(metadata.next_id));\n\t\t} catch (error) {\n\t\t\ttry {\n\t\t\t\tawait db.close();\n\t\t\t} catch {\n\t\t\t\t// Preserve the initialization failure.\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync commit(writes: readonly StorageWrite[], _context: Context): Promise<Seq> {\n\t\tthis.assertOpen();\n\t\tconst documentActions = this.prepareDocumentActions(writes);\n\t\tconst candidateNextId = this.candidateNextId(writes);\n\t\tconst seq = await this.db.transaction(async (transaction) => {\n\t\t\tconst metadata = await transaction.get<MetadataRow>(\n\t\t\t\t\"SELECT next_id, next_seq FROM durable_metadata WHERE singleton = 1\",\n\t\t\t);\n\t\t\tif (metadata === undefined) throw new Error(\"Durable SQLite metadata is missing\");\n\t\t\tconst committedSeq = seqFromNumber(metadata.next_seq);\n\t\t\tawait this.checkGlobalIds(transaction, writes);\n\t\t\tawait this.checkDocumentActions(transaction, documentActions);\n\t\t\tfor (const write of writes) await this.applyTableWrite(transaction, write, committedSeq);\n\t\t\tawait this.applyDocumentActions(transaction, documentActions, committedSeq);\n\t\t\tawait transaction.run(\n\t\t\t\t\"UPDATE durable_metadata SET next_id = ?, next_seq = ? WHERE singleton = 1\",\n\t\t\t\tString(Math.max(Number(metadata.next_id), candidateNextId)),\n\t\t\t\tcommittedSeq + 1,\n\t\t\t);\n\t\t\treturn committedSeq;\n\t\t});\n\t\tthis.nextId = Math.max(this.nextId, candidateNextId);\n\t\treturn seq;\n\t}\n\n\tasync mintId<I extends Id<string>>(): Promise<I> {\n\t\tthis.assertOpen();\n\t\tif (!Number.isSafeInteger(this.nextId)) throw new Error(\"ID space is exhausted\");\n\t\treturn idFromNumber<I>(this.nextId++);\n\t}\n\n\tasync conversation(id: ConversationId, _context: Context): Promise<ConversationRecord | undefined> {\n\t\tthis.assertOpen();\n\t\tconst row = await this.db.get<JsonRow>(\"SELECT record FROM conversations WHERE id = ?\", id);\n\t\treturn row === undefined ? undefined : parseJson<ConversationRecord>(row.record);\n\t}\n\n\tasync scanConversations(\n\t\tquery: ConversationQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<ConversationRecord, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst start = scanStart(query.order, cursor, \"ascending\");\n\t\tconst scan = scanSql(start);\n\t\tconst clauses = [scan.clause];\n\t\tconst params: SqliteValue[] = [scan.param];\n\t\tif (query.ownerConversationId !== undefined) {\n\t\t\tclauses.push(\"owner_conversation_id = ?\");\n\t\t\tparams.push(query.ownerConversationId);\n\t\t}\n\t\tif (query.ownerTaskId !== undefined) {\n\t\t\tclauses.push(\"owner_task_id = ?\");\n\t\t\tparams.push(query.ownerTaskId);\n\t\t}\n\t\tparams.push(limit + 1);\n\t\tconst rows = await this.db.all<JsonRow>(\n\t\t\t`SELECT record FROM conversations WHERE ${clauses.join(\" AND \")} ORDER BY id ${scan.direction} LIMIT ?`,\n\t\t\t...params,\n\t\t);\n\t\treturn page(\n\t\t\trows.map((row) => parseJson<ConversationRecord>(row.record)),\n\t\t\tlimit,\n\t\t\tstart.order,\n\t\t);\n\t}\n\n\tentry(id: EntryId, context: Context): Promise<{ readonly entry: EntryRecord; readonly commitSeq: Seq } | undefined>;\n\tentry(\n\t\tconversationId: ConversationId,\n\t\tid: EntryId,\n\t\tcontext: Context,\n\t): Promise<{ readonly entry: EntryRecord; readonly commitSeq: Seq } | undefined>;\n\tentry(\n\t\tidOrConversationId: EntryId | ConversationId,\n\t\tidOrContext: EntryId | Context,\n\t\tcontext?: Context,\n\t): Promise<{ readonly entry: EntryRecord; readonly commitSeq: Seq } | undefined> {\n\t\treturn this.admitRead(() => this.readEntry(idOrConversationId, idOrContext, context));\n\t}\n\n\tfindLatestHeadMarker(\n\t\tconversationId: ConversationId,\n\t\tatOrBeforeEntryId: EntryId | undefined,\n\t\t_context: Context,\n\t): Promise<(EntryRecord & { readonly head: EntryId }) | undefined> {\n\t\treturn this.admitRead(() => this.readLatestHeadMarker(conversationId, atOrBeforeEntryId));\n\t}\n\n\tscanEntries(\n\t\tquery: EntryQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<EntryRecord, Cursor>> {\n\t\treturn this.admitRead(() => this.readEntries(query, limit, cursor));\n\t}\n\n\tprivate async readEntry(\n\t\tidOrConversationId: EntryId | ConversationId,\n\t\tidOrContext: EntryId | Context,\n\t\tcontext?: Context,\n\t): Promise<{ readonly entry: EntryRecord; readonly commitSeq: Seq } | undefined> {\n\t\tconst id =\n\t\t\tcontext === undefined\n\t\t\t\t? idFromNumber<EntryId>(idOrConversationId)\n\t\t\t\t: typeof idOrContext === \"number\"\n\t\t\t\t\t? idFromNumber<EntryId>(idOrContext)\n\t\t\t\t\t: undefined;\n\t\tif (id === undefined) throw new TypeError(\"Storage.entry() requires an entry ID\");\n\t\tlet conversation: ConversationRecord | undefined;\n\t\tif (context !== undefined) {\n\t\t\tconst conversationId = idFromNumber<ConversationId>(idOrConversationId);\n\t\t\tconversation = await this.readConversation(conversationId);\n\t\t\tif (conversation === undefined) throw new Error(`Unknown conversation: ${conversationId}`);\n\t\t}\n\t\tconst row = await this.db.get<EntryJsonRow>(\"SELECT record, commit_seq FROM entries WHERE id = ?\", id);\n\t\tif (row === undefined) return undefined;\n\t\tconst entry = parseJson<EntryRecord>(row.record);\n\t\tif (conversation !== undefined) {\n\t\t\tlet upperEntryId = Number.POSITIVE_INFINITY;\n\t\t\twhile (conversation.id !== entry.conversationId) {\n\t\t\t\tif (conversation.parent === undefined) return undefined;\n\t\t\t\tupperEntryId = Math.min(upperEntryId, conversation.parent.at);\n\t\t\t\tconversation = (await this.readConversation(conversation.parent.conversationId))!;\n\t\t\t}\n\t\t\tif (entry.id > upperEntryId) return undefined;\n\t\t}\n\t\treturn { entry, commitSeq: seqFromNumber(row.commit_seq) };\n\t}\n\n\tprivate async readLatestHeadMarker(\n\t\tconversationId: ConversationId,\n\t\tatOrBeforeEntryId: EntryId | undefined,\n\t): Promise<(EntryRecord & { readonly head: EntryId }) | undefined> {\n\t\tlet conversation = await this.readConversation(conversationId);\n\t\tif (conversation === undefined) throw new Error(`Unknown conversation: ${conversationId}`);\n\t\tlet upper: number | undefined = atOrBeforeEntryId;\n\t\twhile (true) {\n\t\t\tconst row =\n\t\t\t\tupper === undefined\n\t\t\t\t\t? await this.db.get<JsonRow>(\n\t\t\t\t\t\t\t\"SELECT record FROM entries WHERE conversation_id = ? AND head IS NOT NULL ORDER BY id DESC LIMIT 1\",\n\t\t\t\t\t\t\tconversation.id,\n\t\t\t\t\t\t)\n\t\t\t\t\t: await this.db.get<JsonRow>(\n\t\t\t\t\t\t\t\"SELECT record FROM entries WHERE conversation_id = ? AND head IS NOT NULL AND id <= ? ORDER BY id DESC LIMIT 1\",\n\t\t\t\t\t\t\tconversation.id,\n\t\t\t\t\t\t\tupper,\n\t\t\t\t\t\t);\n\t\t\tif (row !== undefined) return parseJson<EntryRecord & { readonly head: EntryId }>(row.record);\n\t\t\tif (conversation.parent === undefined) return undefined;\n\t\t\tupper = upper === undefined ? conversation.parent.at : Math.min(upper, conversation.parent.at);\n\t\t\tconversation = (await this.readConversation(conversation.parent.conversationId))!;\n\t\t}\n\t}\n\n\tprivate async readEntries(\n\t\tquery: EntryQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t): Promise<Page<EntryRecord, Cursor>> {\n\t\tconst { order, after } = scanStart(query.order, cursor, \"descending\");\n\t\tif (order === \"ascending\") return this.readEntriesAscending(query, limit, after);\n\t\tlet conversation = await this.readConversation(query.conversationId);\n\t\tif (conversation === undefined) throw new Error(`Unknown conversation: ${query.conversationId}`);\n\t\tlet upper: number | undefined = query.maxEntryId;\n\t\tif (after !== undefined) upper = Math.min(upper ?? Number.MAX_SAFE_INTEGER, after - 1);\n\t\tconst values: EntryRecord[] = [];\n\t\twhile (true) {\n\t\t\tconst clauses = [\"conversation_id = ?\"];\n\t\t\tconst params: SqliteValue[] = [conversation.id];\n\t\t\tif (query.minEntryId !== undefined) {\n\t\t\t\tclauses.push(\"id >= ?\");\n\t\t\t\tparams.push(query.minEntryId);\n\t\t\t}\n\t\t\tif (upper !== undefined) {\n\t\t\t\tclauses.push(\"id <= ?\");\n\t\t\t\tparams.push(upper);\n\t\t\t}\n\t\t\tparams.push(limit + 1 - values.length);\n\t\t\tconst rows = await this.db.all<JsonRow>(\n\t\t\t\t`SELECT record FROM entries WHERE ${clauses.join(\" AND \")} ORDER BY id DESC LIMIT ?`,\n\t\t\t\t...params,\n\t\t\t);\n\t\t\tvalues.push(...rows.map((row) => parseJson<EntryRecord>(row.record)));\n\t\t\tif (values.length > limit || conversation.parent === undefined) break;\n\t\t\tupper = upper === undefined ? conversation.parent.at : Math.min(upper, conversation.parent.at);\n\t\t\tif (query.minEntryId !== undefined && upper < query.minEntryId) break;\n\t\t\tconversation = (await this.readConversation(conversation.parent.conversationId))!;\n\t\t}\n\t\treturn page(values, limit, \"descending\");\n\t}\n\n\t/** Oldest first: the fork chain's segments from the root conversation forward, each up to its fork point. */\n\tprivate async readEntriesAscending(\n\t\tquery: EntryQuery,\n\t\tlimit: number,\n\t\tafter: number | undefined,\n\t): Promise<Page<EntryRecord, Cursor>> {\n\t\tconst segments: { readonly conversationId: ConversationId; readonly upper: number | undefined }[] = [];\n\t\tlet conversation = await this.readConversation(query.conversationId);\n\t\tif (conversation === undefined) throw new Error(`Unknown conversation: ${query.conversationId}`);\n\t\tlet upper: number | undefined = query.maxEntryId;\n\t\twhile (true) {\n\t\t\tsegments.push({ conversationId: conversation.id, upper });\n\t\t\tif (conversation.parent === undefined) break;\n\t\t\tupper = upper === undefined ? conversation.parent.at : Math.min(upper, conversation.parent.at);\n\t\t\tif (query.minEntryId !== undefined && upper < query.minEntryId) break;\n\t\t\tconversation = (await this.readConversation(conversation.parent.conversationId))!;\n\t\t}\n\t\tlet lower: number | undefined = query.minEntryId;\n\t\tif (after !== undefined) lower = Math.max(lower ?? after + 1, after + 1);\n\t\tconst values: EntryRecord[] = [];\n\t\tfor (const segment of segments.reverse()) {\n\t\t\tconst clauses = [\"conversation_id = ?\"];\n\t\t\tconst params: SqliteValue[] = [segment.conversationId];\n\t\t\tif (lower !== undefined) {\n\t\t\t\tclauses.push(\"id >= ?\");\n\t\t\t\tparams.push(lower);\n\t\t\t}\n\t\t\tif (segment.upper !== undefined) {\n\t\t\t\tclauses.push(\"id <= ?\");\n\t\t\t\tparams.push(segment.upper);\n\t\t\t}\n\t\t\tparams.push(limit + 1 - values.length);\n\t\t\tconst rows = await this.db.all<JsonRow>(\n\t\t\t\t`SELECT record FROM entries WHERE ${clauses.join(\" AND \")} ORDER BY id ASC LIMIT ?`,\n\t\t\t\t...params,\n\t\t\t);\n\t\t\tvalues.push(...rows.map((row) => parseJson<EntryRecord>(row.record)));\n\t\t\tif (values.length > limit) break;\n\t\t}\n\t\treturn page(values, limit, \"ascending\");\n\t}\n\n\tasync task(id: TaskId, _context: Context): Promise<StoredTask | undefined> {\n\t\tthis.assertOpen();\n\t\tconst row = await this.db.get<JsonRow>(\"SELECT record FROM tasks WHERE id = ?\", id);\n\t\treturn row === undefined ? undefined : parseJson<StoredTask>(row.record);\n\t}\n\n\tasync scanTasks(\n\t\tquery: TaskQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<StoredTask, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst start = scanStart(query.order, cursor, \"ascending\");\n\t\tconst scan = scanSql(start);\n\t\tconst clauses = [scan.clause];\n\t\tconst params: SqliteValue[] = [scan.param];\n\t\tif (query.conversationId !== undefined) {\n\t\t\tclauses.push(\"conversation_id = ?\");\n\t\t\tparams.push(query.conversationId);\n\t\t}\n\t\tif (query.kind !== undefined) {\n\t\t\tclauses.push(\"kind = ?\");\n\t\t\tparams.push(encodeIndexedString(query.kind));\n\t\t}\n\t\tif (query.status !== undefined) {\n\t\t\tclauses.push(\"status = ?\");\n\t\t\tparams.push(query.status);\n\t\t}\n\t\tif (query.abortRequested !== undefined) {\n\t\t\tclauses.push(\"abort_requested = ?\");\n\t\t\tparams.push(query.abortRequested ? 1 : 0);\n\t\t}\n\t\tif (query.background !== undefined) {\n\t\t\tclauses.push(\"background = ?\");\n\t\t\tparams.push(query.background ? 1 : 0);\n\t\t}\n\t\tparams.push(limit + 1);\n\t\tconst rows = await this.db.all<JsonRow>(\n\t\t\t`SELECT record FROM tasks WHERE ${clauses.join(\" AND \")} ORDER BY id ${scan.direction} LIMIT ?`,\n\t\t\t...params,\n\t\t);\n\t\treturn page(\n\t\t\trows.map((row) => parseJson<StoredTask>(row.record)),\n\t\t\tlimit,\n\t\t\tstart.order,\n\t\t);\n\t}\n\n\tasync submission(id: SubmissionId, _context: Context): Promise<SubmissionRecord | undefined> {\n\t\tthis.assertOpen();\n\t\tconst row = await this.db.get<JsonRow>(\"SELECT record FROM submissions WHERE id = ?\", id);\n\t\treturn row === undefined ? undefined : parseJson<SubmissionRecord>(row.record);\n\t}\n\n\tasync scanSubmissions(\n\t\tquery: SubmissionQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<SubmissionRecord, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst start = scanStart(query.order, cursor, \"ascending\");\n\t\tconst scan = scanSql(start);\n\t\tconst clauses = [scan.clause];\n\t\tconst params: SqliteValue[] = [scan.param];\n\t\tif (query.conversationId !== undefined) {\n\t\t\tclauses.push(\"conversation_id = ?\");\n\t\t\tparams.push(query.conversationId);\n\t\t}\n\t\tif (query.status !== undefined) {\n\t\t\tclauses.push(\"status = ?\");\n\t\t\tparams.push(query.status);\n\t\t}\n\t\tparams.push(limit + 1);\n\t\tconst rows = await this.db.all<JsonRow>(\n\t\t\t`SELECT record FROM submissions WHERE ${clauses.join(\" AND \")} ORDER BY id ${scan.direction} LIMIT ?`,\n\t\t\t...params,\n\t\t);\n\t\treturn page(\n\t\t\trows.map((row) => parseJson<SubmissionRecord>(row.record)),\n\t\t\tlimit,\n\t\t\tstart.order,\n\t\t);\n\t}\n\n\tasync submissionByRequest(\n\t\tconversationId: ConversationId,\n\t\trequestId: string,\n\t\t_context: Context,\n\t): Promise<SubmissionRecord | undefined> {\n\t\tthis.assertOpen();\n\t\tconst row = await this.db.get<JsonRow>(\n\t\t\t\"SELECT record FROM submissions WHERE conversation_id = ? AND request_id = ?\",\n\t\t\tconversationId,\n\t\t\tencodeIndexedString(requestId),\n\t\t);\n\t\treturn row === undefined ? undefined : parseJson<SubmissionRecord>(row.record);\n\t}\n\n\tasync findDocument(\n\t\taddress: DocumentAddress,\n\t\tat: DocumentPoint,\n\t\t_context: Context,\n\t): Promise<DocumentRecord | undefined> {\n\t\tthis.assertOpen();\n\t\tconst parts = addressParts(address);\n\t\tconst sql =\n\t\t\tat === \"current\"\n\t\t\t\t? `SELECT record FROM documents\n\t\t\t\t\tWHERE kind = ? AND scope_kind = ? AND owner_id = ? AND family = ? AND key_value = ?\n\t\t\t\t\tAND retired_at IS NULL ORDER BY created_at DESC LIMIT 1`\n\t\t\t\t: `SELECT record FROM documents\n\t\t\t\t\tWHERE kind = ? AND scope_kind = ? AND owner_id = ? AND family = ? AND key_value = ?\n\t\t\t\t\tAND created_at <= ? AND (retired_at IS NULL OR retired_at > ?)\n\t\t\t\t\tORDER BY created_at DESC LIMIT 1`;\n\t\tconst params: SqliteValue[] = [parts.kind, parts.scopeKind, parts.ownerId, parts.family, parts.keyValue];\n\t\tif (at !== \"current\") params.push(at, at);\n\t\tconst row = await this.db.get<JsonRow>(sql, ...params);\n\t\treturn row === undefined ? undefined : parseJson<DocumentRecord>(row.record);\n\t}\n\n\tasync document(id: DocumentId, at: DocumentPoint, _context: Context): Promise<StoredDocument | undefined> {\n\t\tthis.assertOpen();\n\t\t// The record and revision queries must observe one committed state; a commit between them can replace the base.\n\t\treturn this.db.transaction((transaction) => this.materializeDocument(transaction, id, at));\n\t}\n\n\tasync scanDocuments(\n\t\tquery: DocumentQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\t_context: Context,\n\t): Promise<Page<DocumentRecord, Cursor>> {\n\t\tthis.assertOpen();\n\t\tconst scope = scopeColumns(query.scope);\n\t\tconst clauses = [\"scope_kind = ?\", \"owner_id = ?\", \"id > ?\"];\n\t\tconst params: SqliteValue[] = [scope.scopeKind, scope.ownerId, cursorId(cursor) ?? -1];\n\t\tif (query.kind !== undefined) {\n\t\t\tclauses.push(\"kind = ?\");\n\t\t\tparams.push(encodeIndexedString(query.kind));\n\t\t}\n\t\tif (query.at === \"current\") {\n\t\t\tclauses.push(\"retired_at IS NULL\");\n\t\t} else {\n\t\t\tclauses.push(\"created_at <= ?\", \"(retired_at IS NULL OR retired_at > ?)\");\n\t\t\tparams.push(query.at, query.at);\n\t\t}\n\t\tparams.push(limit + 1);\n\t\tconst rows = await this.db.all<JsonRow>(\n\t\t\t`SELECT record FROM documents WHERE ${clauses.join(\" AND \")} ORDER BY id LIMIT ?`,\n\t\t\t...params,\n\t\t);\n\t\treturn page(\n\t\t\trows.map((row) => parseJson<DocumentRecord>(row.record)),\n\t\t\tlimit,\n\t\t);\n\t}\n\n\tclose(_context: Context): Promise<void> {\n\t\tif (this.closing === undefined) {\n\t\t\tthis.closed = true;\n\t\t\tthis.closing = this.closeDatabase();\n\t\t}\n\t\treturn this.closing;\n\t}\n\n\tprivate async closeDatabase(): Promise<void> {\n\t\tif (this.admittedReads > 0) {\n\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\tthis.readsDrained = resolve;\n\t\t\t});\n\t\t}\n\t\tawait this.db.close();\n\t}\n\n\t/**\n\t * Run a read that issues several queries. Close waits for admitted reads, so their later queries never reach a\n\t * closed database. Single-query reads and transactions are already ordered before close by the database.\n\t */\n\tprivate async admitRead<T>(read: () => Promise<T>): Promise<T> {\n\t\tthis.assertOpen();\n\t\tthis.admittedReads++;\n\t\ttry {\n\t\t\treturn await read();\n\t\t} finally {\n\t\t\tif (--this.admittedReads === 0) this.readsDrained?.();\n\t\t}\n\t}\n\n\tprivate async readConversation(id: ConversationId): Promise<ConversationRecord | undefined> {\n\t\tconst row = await this.db.get<JsonRow>(\"SELECT record FROM conversations WHERE id = ?\", id);\n\t\treturn row === undefined ? undefined : parseJson<ConversationRecord>(row.record);\n\t}\n\n\tprivate async materializeDocument(\n\t\texecutor: SqliteExecutor,\n\t\tid: DocumentId,\n\t\tat: DocumentPoint,\n\t): Promise<StoredDocument | undefined> {\n\t\tconst row = await executor.get<JsonRow>(\"SELECT record FROM documents WHERE id = ?\", id);\n\t\tif (row === undefined) return undefined;\n\t\tconst record = parseJson<DocumentRecord>(row.record);\n\t\tif (at !== \"current\" && isCurrentOnly(record)) {\n\t\t\tthrow new Error(`Document ${id} does not retain historical content`);\n\t\t}\n\t\tif (!isAliveAt(record, at)) return undefined;\n\t\tconst upper = at === \"current\" ? Number.MAX_SAFE_INTEGER : at;\n\t\tconst base = await executor.get<RevisionRow>(\n\t\t\t`SELECT seq, kind, version, content FROM document_revisions\n\t\t\t\tWHERE document_id = ? AND kind = 'base' AND seq <= ? ORDER BY seq DESC LIMIT 1`,\n\t\t\tid,\n\t\t\tupper,\n\t\t);\n\t\tif (base === undefined) throw new Error(`Document ${id} is missing a required base`);\n\t\tlet value = parseJson<JsonObject>(base.content);\n\t\tconst tail = await executor.all<RevisionRow>(\n\t\t\t`SELECT seq, kind, version, content FROM document_revisions\n\t\t\t\tWHERE document_id = ? AND seq > ? AND seq <= ? ORDER BY seq`,\n\t\t\tid,\n\t\t\tbase.seq,\n\t\t\tupper,\n\t\t);\n\t\tfor (const revision of tail) {\n\t\t\tif (revision.kind !== \"delta\" || revision.version !== base.version) {\n\t\t\t\tthrow new Error(`Document ${id} crosses a stored version boundary without a base`);\n\t\t\t}\n\t\t\tvalue = apply(value, parseJson<readonly Op[]>(revision.content)) as JsonObject;\n\t\t}\n\t\treturn { record, version: base.version, value, deltasSinceBase: tail.length };\n\t}\n\n\tprivate candidateNextId(writes: readonly StorageWrite[]): number {\n\t\tlet nextId = this.nextId;\n\t\tfor (const write of writes) {\n\t\t\tconst id = writeId(write);\n\t\t\tif (id !== undefined) nextId = Math.max(nextId, id + 1);\n\t\t}\n\t\treturn nextId;\n\t}\n\n\tprivate async checkGlobalIds(executor: SqliteExecutor, writes: readonly StorageWrite[]): Promise<void> {\n\t\tconst claimed = new Map<Id<string>, TableName>();\n\t\tfor (const write of writes) {\n\t\t\tif (write.type === \"document.change\" || write.type === \"document.retire\") continue;\n\t\t\tconst document = write.type === \"document.create\" || write.type === \"document.copy\";\n\t\t\tconst table: TableName = document ? \"document\" : write.type;\n\t\t\tconst id = document ? write.record.id : write.value.id;\n\t\t\tconst existing = (await executor.get<RecordIdRow>(\"SELECT record_type FROM record_ids WHERE id = ?\", id))\n\t\t\t\t?.record_type;\n\t\t\tconst earlier = claimed.get(id);\n\t\t\tif (table === \"conversation\" || table === \"entry\" || table === \"document\") {\n\t\t\t\tif (existing !== undefined) throw new Error(`ID ${id} already belongs to ${existing}`);\n\t\t\t\tif (earlier !== undefined) throw new Error(`ID ${id} is written more than once`);\n\t\t\t} else {\n\t\t\t\tif (existing !== undefined && existing !== table)\n\t\t\t\t\tthrow new Error(`ID ${id} already belongs to ${existing}`);\n\t\t\t\tif (earlier !== undefined && earlier !== table) throw new Error(`ID ${id} is written as two record types`);\n\t\t\t}\n\t\t\tclaimed.set(id, table);\n\t\t}\n\t}\n\n\tprivate prepareDocumentActions(writes: readonly StorageWrite[]): Map<DocumentId, DocumentAction> {\n\t\tconst actions = new Map<DocumentId, DocumentAction>();\n\t\tfor (const write of writes) {\n\t\t\tif (\n\t\t\t\twrite.type !== \"document.create\" &&\n\t\t\t\twrite.type !== \"document.copy\" &&\n\t\t\t\twrite.type !== \"document.change\" &&\n\t\t\t\twrite.type !== \"document.retire\"\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst id = write.type === \"document.create\" || write.type === \"document.copy\" ? write.record.id : write.id;\n\t\t\tlet action = actions.get(id);\n\t\t\tif (action === undefined) {\n\t\t\t\taction = { retire: false };\n\t\t\t\tactions.set(id, action);\n\t\t\t}\n\t\t\tswitch (write.type) {\n\t\t\t\tcase \"document.create\":\n\t\t\t\t\tif (action.create !== undefined || action.content !== undefined || action.copy !== undefined) {\n\t\t\t\t\t\tthrow new Error(`Document ${id} has more than one content command`);\n\t\t\t\t\t}\n\t\t\t\t\taction.create = write.record;\n\t\t\t\t\taction.content = write.content;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"document.copy\":\n\t\t\t\t\tif (action.create !== undefined || action.content !== undefined || action.copy !== undefined) {\n\t\t\t\t\t\tthrow new Error(`Document ${id} has more than one content command`);\n\t\t\t\t\t}\n\t\t\t\t\taction.create = write.record;\n\t\t\t\t\taction.copy = write.source;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"document.change\":\n\t\t\t\t\tif (action.content !== undefined || action.copy !== undefined) {\n\t\t\t\t\t\tthrow new Error(`Document ${id} has more than one content command`);\n\t\t\t\t\t}\n\t\t\t\t\taction.content = write.content;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"document.retire\":\n\t\t\t\t\tif (action.retire) throw new Error(`Document ${id} is retired more than once`);\n\t\t\t\t\taction.retire = true;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn actions;\n\t}\n\n\tprivate async checkDocumentActions(\n\t\texecutor: SqliteExecutor,\n\t\tactions: ReadonlyMap<DocumentId, DocumentAction>,\n\t): Promise<void> {\n\t\tconst liveCounts = new Map<string, number>();\n\t\tfor (const [id, action] of actions) {\n\t\t\tif (action.copy !== undefined && actions.has(action.copy.id)) {\n\t\t\t\tthrow new StorageRejected(`Document copy ${id} source is changed in the copy batch`);\n\t\t\t}\n\t\t\tconst row = await executor.get<JsonRow>(\"SELECT record FROM documents WHERE id = ?\", id);\n\t\t\tconst existing = row === undefined ? undefined : parseJson<DocumentRecord>(row.record);\n\t\t\tif (action.create === undefined && existing === undefined) throw new Error(`Unknown document: ${id}`);\n\t\t\tif (action.create !== undefined && existing !== undefined) throw new Error(`Document ${id} already exists`);\n\t\t\tif (existing?.retiredAt !== undefined) throw new Error(`Document ${id} is retired`);\n\t\t\tif (action.content?.kind === \"delta\") {\n\t\t\t\tconst previous = await executor.get<{ readonly version: number }>(\n\t\t\t\t\t\"SELECT version FROM document_revisions WHERE document_id = ? ORDER BY seq DESC LIMIT 1\",\n\t\t\t\t\tid,\n\t\t\t\t);\n\t\t\t\tif (previous === undefined) throw new Error(`Document ${id} delta has no base`);\n\t\t\t\tif (previous.version !== action.content.version) {\n\t\t\t\t\tthrow new Error(`Document ${id} version transition requires a base`);\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst record = action.create ?? existing!;\n\t\t\tconst key = addressKey(record);\n\t\t\tlet live = liveCounts.get(key);\n\t\t\tif (live === undefined) live = (await this.currentDocumentId(executor, record)) === undefined ? 0 : 1;\n\t\t\tif (action.retire && existing !== undefined) live--;\n\t\t\tif (action.create !== undefined && !action.retire) live++;\n\t\t\tliveCounts.set(key, live);\n\t\t}\n\t\tfor (const live of liveCounts.values()) {\n\t\t\tif (live > 1) throw new Error(\"Document address already has a current incarnation\");\n\t\t}\n\t}\n\n\tprivate async currentDocumentId(\n\t\texecutor: SqliteExecutor,\n\t\taddress: DocumentAddress | DocumentCreate | DocumentRecord,\n\t): Promise<DocumentId | undefined> {\n\t\tconst parts = addressParts(address);\n\t\tconst id = (\n\t\t\tawait executor.get<IdRow>(\n\t\t\t\t`SELECT id FROM documents\n\t\t\t\tWHERE kind = ? AND scope_kind = ? AND owner_id = ? AND family = ? AND key_value = ? AND retired_at IS NULL\n\t\t\t\tLIMIT 1`,\n\t\t\t\tparts.kind,\n\t\t\t\tparts.scopeKind,\n\t\t\t\tparts.ownerId,\n\t\t\t\tparts.family,\n\t\t\t\tparts.keyValue,\n\t\t\t)\n\t\t)?.id;\n\t\treturn id === undefined ? undefined : idFromNumber<DocumentId>(id);\n\t}\n\n\tprivate async applyTableWrite(executor: SqliteExecutor, write: StorageWrite, seq: Seq): Promise<void> {\n\t\tswitch (write.type) {\n\t\t\tcase \"conversation\":\n\t\t\t\tawait this.claimId(executor, write.value.id, \"conversation\");\n\t\t\t\tawait executor.run(\n\t\t\t\t\t\"INSERT INTO conversations (id, owner_conversation_id, owner_task_id, record) VALUES (?, ?, ?, ?)\",\n\t\t\t\t\twrite.value.id,\n\t\t\t\t\twrite.value.owner?.conversationId ?? null,\n\t\t\t\t\twrite.value.owner?.taskId ?? null,\n\t\t\t\t\tencodeJson(write.value),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"entry\":\n\t\t\t\tawait this.claimId(executor, write.value.id, \"entry\");\n\t\t\t\tawait executor.run(\n\t\t\t\t\t\"INSERT INTO entries (id, conversation_id, head, commit_seq, record) VALUES (?, ?, ?, ?, ?)\",\n\t\t\t\t\twrite.value.id,\n\t\t\t\t\twrite.value.conversationId,\n\t\t\t\t\twrite.value.head ?? null,\n\t\t\t\t\tseq,\n\t\t\t\t\tencodeJson(write.value),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"task\":\n\t\t\t\tawait this.claimId(executor, write.value.id, \"task\");\n\t\t\t\tawait executor.run(\n\t\t\t\t\t`INSERT INTO tasks (id, conversation_id, kind, status, abort_requested, background, record)\n\t\t\t\t\t\tVALUES (?, ?, ?, ?, ?, ?, ?)\n\t\t\t\t\t\tON CONFLICT(id) DO UPDATE SET conversation_id = excluded.conversation_id, kind = excluded.kind,\n\t\t\t\t\t\tstatus = excluded.status, abort_requested = excluded.abort_requested,\n\t\t\t\t\t\tbackground = excluded.background, record = excluded.record`,\n\t\t\t\t\twrite.value.id,\n\t\t\t\t\twrite.value.conversationId,\n\t\t\t\t\tencodeIndexedString(write.value.kind),\n\t\t\t\t\twrite.value.state.status,\n\t\t\t\t\twrite.value.abortRequested ? 1 : 0,\n\t\t\t\t\twrite.value.background ? 1 : 0,\n\t\t\t\t\tencodeJson(write.value),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"submission\":\n\t\t\t\tawait this.claimId(executor, write.value.id, \"submission\");\n\t\t\t\tawait executor.run(\n\t\t\t\t\t`INSERT INTO submissions (id, conversation_id, request_id, status, record) VALUES (?, ?, ?, ?, ?)\n\t\t\t\t\t\tON CONFLICT(id) DO UPDATE SET conversation_id = excluded.conversation_id,\n\t\t\t\t\t\trequest_id = excluded.request_id, status = excluded.status, record = excluded.record`,\n\t\t\t\t\twrite.value.id,\n\t\t\t\t\twrite.value.conversationId,\n\t\t\t\t\twrite.value.requestId === undefined ? null : encodeIndexedString(write.value.requestId),\n\t\t\t\t\twrite.value.status,\n\t\t\t\t\tencodeJson(write.value),\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"document.create\":\n\t\t\tcase \"document.copy\":\n\t\t\tcase \"document.change\":\n\t\t\tcase \"document.retire\":\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprivate async claimId(executor: SqliteExecutor, id: Id<string>, table: TableName): Promise<void> {\n\t\tawait executor.run(\"INSERT OR IGNORE INTO record_ids (id, record_type) VALUES (?, ?)\", id, table);\n\t}\n\n\tprivate async applyDocumentActions(\n\t\texecutor: SqliteExecutor,\n\t\tactions: ReadonlyMap<DocumentId, DocumentAction>,\n\t\tseq: Seq,\n\t): Promise<void> {\n\t\tfor (const [id, action] of actions) {\n\t\t\tlet content = action.content;\n\t\t\tif (action.copy !== undefined) {\n\t\t\t\ttry {\n\t\t\t\t\tconst stored = await this.materializeDocument(executor, action.copy.id, action.copy.at);\n\t\t\t\t\tif (stored === undefined) throw new Error(`Fork source document ${action.copy.id} cannot be read`);\n\t\t\t\t\tconst create = action.create!;\n\t\t\t\t\tif (\n\t\t\t\t\t\tstored.record.scope.kind !== \"conversation\" ||\n\t\t\t\t\t\tcreate.scope.kind !== \"conversation\" ||\n\t\t\t\t\t\tstored.record.kind !== create.kind ||\n\t\t\t\t\t\tstored.record.key !== create.key ||\n\t\t\t\t\t\tstored.record.history !== create.history ||\n\t\t\t\t\t\tstored.record.fork !== create.fork\n\t\t\t\t\t) {\n\t\t\t\t\t\tthrow new Error(`Fork source document ${action.copy.id} does not match the copied record`);\n\t\t\t\t\t}\n\t\t\t\t\tcontent = { kind: \"base\", version: stored.version, value: stored.value };\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (error instanceof StorageRejected) throw error;\n\t\t\t\t\tthrow new StorageRejected(`Document copy ${id} was rejected`, { cause: error });\n\t\t\t\t}\n\t\t\t}\n\t\t\tlet record: DocumentRecord;\n\t\t\tif (action.create !== undefined) {\n\t\t\t\trecord = {\n\t\t\t\t\t...action.create,\n\t\t\t\t\tcreatedAt: seq,\n\t\t\t\t\t...(action.retire ? { retiredAt: seq } : {}),\n\t\t\t\t};\n\t\t\t\tconst parts = addressParts(record);\n\t\t\t\tawait this.claimId(executor, id, \"document\");\n\t\t\t\tawait executor.run(\n\t\t\t\t\t`INSERT INTO documents\n\t\t\t\t\t\t(id, kind, family, key_value, scope_kind, owner_id, created_at, retired_at, record)\n\t\t\t\t\t\tVALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n\t\t\t\t\tid,\n\t\t\t\t\tparts.kind,\n\t\t\t\t\tparts.family,\n\t\t\t\t\tparts.keyValue,\n\t\t\t\t\tparts.scopeKind,\n\t\t\t\t\tparts.ownerId,\n\t\t\t\t\tseq,\n\t\t\t\t\taction.retire ? seq : null,\n\t\t\t\t\tencodeJson(record),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tconst row = (await executor.get<JsonRow>(\"SELECT record FROM documents WHERE id = ?\", id))!;\n\t\t\t\trecord = parseJson<DocumentRecord>(row.record);\n\t\t\t}\n\n\t\t\tif (content !== undefined) {\n\t\t\t\tif (content.kind === \"base\" && isCurrentOnly(record)) {\n\t\t\t\t\tawait executor.run(\"DELETE FROM document_revisions WHERE document_id = ?\", id);\n\t\t\t\t}\n\t\t\t\tconst encodedContent = content.kind === \"base\" ? encodeJson(content.value) : encodeJson(content.ops);\n\t\t\t\tawait executor.run(\n\t\t\t\t\t\"INSERT INTO document_revisions (document_id, seq, kind, version, content) VALUES (?, ?, ?, ?, ?)\",\n\t\t\t\t\tid,\n\t\t\t\t\tseq,\n\t\t\t\t\tcontent.kind,\n\t\t\t\t\tcontent.version,\n\t\t\t\t\tencodedContent,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (action.retire) {\n\t\t\t\tif (action.create === undefined) {\n\t\t\t\t\trecord = { ...record, retiredAt: seq };\n\t\t\t\t\tawait executor.run(\n\t\t\t\t\t\t\"UPDATE documents SET retired_at = ?, record = ? WHERE id = ?\",\n\t\t\t\t\t\tseq,\n\t\t\t\t\t\tencodeJson(record),\n\t\t\t\t\t\tid,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (isCurrentOnly(record)) {\n\t\t\t\t\tawait executor.run(\"DELETE FROM document_revisions WHERE document_id = ?\", id);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate assertOpen(): void {\n\t\tif (this.closed) throw new Error(\"SqliteStorage is closed\");\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-conformance.d.ts","sourceRoot":"","sources":["../../src/testing/storage-conformance.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"storage-conformance.d.ts","sourceRoot":"","sources":["../../src/testing/storage-conformance.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAgC,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAsElH,8GAA8G;AAC9G,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,yBAAyB,GAAG,SAAS,sBAAsB,EAAE,CA+hD9G"}
|
|
@@ -298,6 +298,17 @@ export function createStorageConformance(options) {
|
|
|
298
298
|
const third = await storage.scanEntries({ conversationId: grandchildId }, 2, second.next, context);
|
|
299
299
|
expect(third.items.map(({ id }) => id)).toEqual([rootFirst]);
|
|
300
300
|
expect(third.next).toBeUndefined();
|
|
301
|
+
// Oldest first: the root's segment, then each fork's, each capped at the next fork point.
|
|
302
|
+
const ascending = { conversationId: grandchildId, order: "ascending" };
|
|
303
|
+
const firstUp = await storage.scanEntries(ascending, 2, undefined, context);
|
|
304
|
+
expect(firstUp.items.map(({ id }) => id)).toEqual([rootFirst, rootForkPoint]);
|
|
305
|
+
const secondUp = await storage.scanEntries(ascending, 2, firstUp.next, context);
|
|
306
|
+
expect(secondUp.items.map(({ id }) => id)).toEqual([childForkPoint, grandchildHead]);
|
|
307
|
+
const thirdUp = await storage.scanEntries({ conversationId: grandchildId }, 2, secondUp.next, context);
|
|
308
|
+
expect(thirdUp.items.map(({ id }) => id)).toEqual([grandchildTail]);
|
|
309
|
+
expect(thirdUp.next).toBeUndefined();
|
|
310
|
+
expect((await storage.scanEntries({ ...ascending, minEntryId: rootForkPoint, maxEntryId: childForkPoint }, 10, undefined, context)).items.map(({ id }) => id)).toEqual([rootForkPoint, childForkPoint]);
|
|
311
|
+
await expect(storage.scanEntries({ conversationId: grandchildId, order: "descending" }, 2, firstUp.next, context)).rejects.toThrow("cursor");
|
|
301
312
|
const currentMarker = await storage.findLatestHeadMarker(grandchildId, undefined, context);
|
|
302
313
|
expect(currentMarker?.id).toBe(grandchildHead);
|
|
303
314
|
expect(currentMarker?.head).toBe(grandchildHead);
|
|
@@ -339,6 +350,53 @@ export function createStorageConformance(options) {
|
|
|
339
350
|
await expect(storage.entry(idFromNumber(999_999), rootFirst, context)).rejects.toThrow("Unknown conversation");
|
|
340
351
|
await expect(storage.scanEntries({ conversationId: idFromNumber(999_999) }, 10, undefined, context)).rejects.toThrow("Unknown conversation");
|
|
341
352
|
}),
|
|
353
|
+
createCase(options, "scans tables in either ID order and continues a cursor in its order", async (storage) => {
|
|
354
|
+
const rootId = await createRoot(storage);
|
|
355
|
+
const conversationIds = [rootId];
|
|
356
|
+
const taskIds = [];
|
|
357
|
+
const submissionIds = [];
|
|
358
|
+
for (let index = 0; index < 3; index++) {
|
|
359
|
+
const conversationId = await storage.mintId();
|
|
360
|
+
const taskId = await storage.mintId();
|
|
361
|
+
const submissionId = await storage.mintId();
|
|
362
|
+
await storage.commit([
|
|
363
|
+
{ type: "conversation", value: { id: conversationId } },
|
|
364
|
+
{ type: "task", value: pendingTask(taskId, rootId) },
|
|
365
|
+
{
|
|
366
|
+
type: "submission",
|
|
367
|
+
value: { id: submissionId, conversationId: rootId, type: "input", status: "queued" },
|
|
368
|
+
},
|
|
369
|
+
], context);
|
|
370
|
+
conversationIds.push(conversationId);
|
|
371
|
+
taskIds.push(taskId);
|
|
372
|
+
submissionIds.push(submissionId);
|
|
373
|
+
}
|
|
374
|
+
const scans = [
|
|
375
|
+
[(order, cursor) => storage.scanConversations({ order }, 2, cursor, context), conversationIds],
|
|
376
|
+
[(order, cursor) => storage.scanTasks({ order }, 2, cursor, context), taskIds],
|
|
377
|
+
[(order, cursor) => storage.scanSubmissions({ order }, 2, cursor, context), submissionIds],
|
|
378
|
+
];
|
|
379
|
+
const all = async (scan, order) => {
|
|
380
|
+
const found = [];
|
|
381
|
+
let page = await scan(order, undefined);
|
|
382
|
+
found.push(...page.items.map(({ id }) => id));
|
|
383
|
+
while (page.next !== undefined) {
|
|
384
|
+
// A cursor carries its order; the query may omit it.
|
|
385
|
+
page = await scan(undefined, JSON.parse(JSON.stringify(page.next)));
|
|
386
|
+
found.push(...page.items.map(({ id }) => id));
|
|
387
|
+
}
|
|
388
|
+
return found;
|
|
389
|
+
};
|
|
390
|
+
for (const [scan, ids] of scans) {
|
|
391
|
+
const reversed = [...ids].reverse();
|
|
392
|
+
expect(await all(scan, undefined)).toEqual(ids);
|
|
393
|
+
expect(await all(scan, "ascending")).toEqual(ids);
|
|
394
|
+
expect(await all(scan, "descending")).toEqual(reversed);
|
|
395
|
+
const descending = await scan("descending", undefined);
|
|
396
|
+
expect((await scan("descending", descending.next)).items.map(({ id }) => id)).toEqual(reversed.slice(2, 4));
|
|
397
|
+
await expect(scan("ascending", descending.next)).rejects.toThrow("cursor");
|
|
398
|
+
}
|
|
399
|
+
}),
|
|
342
400
|
createCase(options, "replaces complete task records and pages filtered task scans", async (storage) => {
|
|
343
401
|
const rootId = await createRoot(storage);
|
|
344
402
|
const firstId = await storage.mintId();
|