@earendil-works/pi-durable 1.4.0 → 1.5.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 +186 -0
- package/README.md +181 -84
- package/dist/codemode/codemode.d.ts +4 -4
- package/dist/codemode/codemode.d.ts.map +1 -1
- package/dist/codemode/codemode.js +9 -12
- package/dist/codemode/codemode.js.map +1 -1
- package/dist/codemode/models.js +4 -4
- package/dist/codemode/models.js.map +1 -1
- package/dist/env/index.d.ts +12 -10
- package/dist/env/index.d.ts.map +1 -1
- package/dist/env/index.js.map +1 -1
- package/dist/env/node-watch.d.ts +3 -3
- package/dist/env/node-watch.d.ts.map +1 -1
- package/dist/env/node-watch.js +18 -16
- package/dist/env/node-watch.js.map +1 -1
- package/dist/env/node.d.ts +2 -2
- package/dist/env/node.d.ts.map +1 -1
- package/dist/env/node.js +1 -1
- package/dist/env/node.js.map +1 -1
- package/dist/errors.d.ts +18 -2
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +26 -3
- package/dist/errors.js.map +1 -1
- package/dist/harness/agent.d.ts.map +1 -1
- package/dist/harness/agent.js +10 -2
- package/dist/harness/agent.js.map +1 -1
- package/dist/harness/compaction.d.ts.map +1 -1
- package/dist/harness/compaction.js +19 -2
- package/dist/harness/compaction.js.map +1 -1
- package/dist/harness/context.d.ts +23 -7
- package/dist/harness/context.d.ts.map +1 -1
- package/dist/harness/context.js +71 -25
- package/dist/harness/context.js.map +1 -1
- package/dist/harness/define.d.ts +7 -3
- package/dist/harness/define.d.ts.map +1 -1
- package/dist/harness/define.js +4 -0
- package/dist/harness/define.js.map +1 -1
- package/dist/harness/generation.d.ts +38 -5
- package/dist/harness/generation.d.ts.map +1 -1
- package/dist/harness/generation.js +445 -96
- package/dist/harness/generation.js.map +1 -1
- package/dist/harness/harness.d.ts +2 -0
- package/dist/harness/harness.d.ts.map +1 -1
- package/dist/harness/harness.js +87 -62
- package/dist/harness/harness.js.map +1 -1
- package/dist/harness/inbox.d.ts +5 -1
- package/dist/harness/inbox.d.ts.map +1 -1
- package/dist/harness/inbox.js +4 -1
- package/dist/harness/inbox.js.map +1 -1
- package/dist/harness/json.d.ts +20 -4
- package/dist/harness/json.d.ts.map +1 -1
- package/dist/harness/json.js +23 -5
- package/dist/harness/json.js.map +1 -1
- package/dist/harness/live.d.ts +122 -16
- package/dist/harness/live.d.ts.map +1 -1
- package/dist/harness/live.js +93 -12
- package/dist/harness/live.js.map +1 -1
- package/dist/harness/partial-changes.d.ts +54 -0
- package/dist/harness/partial-changes.d.ts.map +1 -0
- package/dist/harness/partial-changes.js +162 -0
- package/dist/harness/partial-changes.js.map +1 -0
- package/dist/harness/registry-reader.d.ts +11 -0
- package/dist/harness/registry-reader.d.ts.map +1 -0
- package/dist/harness/registry-reader.js +25 -0
- package/dist/harness/registry-reader.js.map +1 -0
- package/dist/harness/scheduler.d.ts +46 -19
- package/dist/harness/scheduler.d.ts.map +1 -1
- package/dist/harness/scheduler.js +973 -376
- package/dist/harness/scheduler.js.map +1 -1
- package/dist/harness/submissions.d.ts +17 -10
- package/dist/harness/submissions.d.ts.map +1 -1
- package/dist/harness/submissions.js +62 -25
- package/dist/harness/submissions.js.map +1 -1
- package/dist/harness/task-graph.d.ts +12 -9
- package/dist/harness/task-graph.d.ts.map +1 -1
- package/dist/harness/task-graph.js +38 -28
- package/dist/harness/task-graph.js.map +1 -1
- package/dist/harness/telemetry.d.ts +11 -11
- package/dist/harness/telemetry.d.ts.map +1 -1
- package/dist/harness/telemetry.js +7 -7
- package/dist/harness/telemetry.js.map +1 -1
- package/dist/harness/tool.d.ts +2 -0
- package/dist/harness/tool.d.ts.map +1 -1
- package/dist/harness/tool.js +171 -55
- package/dist/harness/tool.js.map +1 -1
- package/dist/harness/transcript.d.ts +72 -0
- package/dist/harness/transcript.d.ts.map +1 -0
- package/dist/harness/transcript.js +264 -0
- package/dist/harness/transcript.js.map +1 -0
- package/dist/harness/types.d.ts +218 -59
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/harness/util.d.ts +3 -1
- package/dist/harness/util.d.ts.map +1 -1
- package/dist/harness/util.js +9 -0
- package/dist/harness/util.js.map +1 -1
- package/dist/harness/view.d.ts +43 -22
- package/dist/harness/view.d.ts.map +1 -1
- package/dist/harness/view.js +130 -71
- package/dist/harness/view.js.map +1 -1
- package/dist/index.d.ts +9 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/search.d.ts +19 -3
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +107 -44
- package/dist/search.js.map +1 -1
- package/dist/session/cached-storage.d.ts +71 -0
- package/dist/session/cached-storage.d.ts.map +1 -0
- package/dist/session/cached-storage.js +269 -0
- package/dist/session/cached-storage.js.map +1 -0
- package/dist/session/conversation-tails.d.ts +33 -0
- package/dist/session/conversation-tails.d.ts.map +1 -0
- package/dist/session/conversation-tails.js +101 -0
- package/dist/session/conversation-tails.js.map +1 -0
- package/dist/session/keys.d.ts +68 -0
- package/dist/session/keys.d.ts.map +1 -0
- package/dist/session/keys.js +161 -0
- package/dist/session/keys.js.map +1 -0
- package/dist/session/session.d.ts +167 -26
- package/dist/session/session.d.ts.map +1 -1
- package/dist/session/session.js +1029 -171
- package/dist/session/session.js.map +1 -1
- package/dist/session/transaction.d.ts +81 -3
- package/dist/session/transaction.d.ts.map +1 -1
- package/dist/session/transaction.js +224 -37
- package/dist/session/transaction.js.map +1 -1
- package/dist/session/writer.d.ts +74 -0
- package/dist/session/writer.d.ts.map +1 -0
- package/dist/session/writer.js +294 -0
- package/dist/session/writer.js.map +1 -0
- package/dist/storage/indexeddb.d.ts +10 -2
- package/dist/storage/indexeddb.d.ts.map +1 -1
- package/dist/storage/indexeddb.js +91 -41
- package/dist/storage/indexeddb.js.map +1 -1
- package/dist/storage/jsonl/storage.d.ts +14 -2
- package/dist/storage/jsonl/storage.d.ts.map +1 -1
- package/dist/storage/jsonl/storage.js +88 -24
- package/dist/storage/jsonl/storage.js.map +1 -1
- package/dist/storage/memory.d.ts +7 -2
- package/dist/storage/memory.d.ts.map +1 -1
- package/dist/storage/memory.js +28 -2
- package/dist/storage/memory.js.map +1 -1
- package/dist/storage/sqlite/storage.d.ts +14 -2
- package/dist/storage/sqlite/storage.d.ts.map +1 -1
- package/dist/storage/sqlite/storage.js +110 -36
- package/dist/storage/sqlite/storage.js.map +1 -1
- package/dist/storage/store/commit.d.ts +33 -0
- package/dist/storage/store/commit.d.ts.map +1 -0
- package/dist/storage/store/commit.js +286 -0
- package/dist/storage/store/commit.js.map +1 -0
- package/dist/storage/store/documents.d.ts +43 -0
- package/dist/storage/store/documents.d.ts.map +1 -0
- package/dist/storage/store/documents.js +102 -0
- package/dist/storage/store/documents.js.map +1 -0
- package/dist/storage/store/index.d.ts +2 -0
- package/dist/storage/store/index.d.ts.map +1 -0
- package/dist/storage/store/index.js +2 -0
- package/dist/storage/store/index.js.map +1 -0
- package/dist/storage/store/queries.d.ts +49 -0
- package/dist/storage/store/queries.d.ts.map +1 -0
- package/dist/storage/store/queries.js +93 -0
- package/dist/storage/store/queries.js.map +1 -0
- package/dist/storage/store/storage.d.ts +59 -0
- package/dist/storage/store/storage.d.ts.map +1 -0
- package/dist/storage/store/storage.js +438 -0
- package/dist/storage/store/storage.js.map +1 -0
- package/dist/storage/store/tables.d.ts +54 -0
- package/dist/storage/store/tables.d.ts.map +1 -0
- package/dist/storage/store/tables.js +108 -0
- package/dist/storage/store/tables.js.map +1 -0
- package/dist/testing/commit-writes.d.ts +5 -0
- package/dist/testing/commit-writes.d.ts.map +1 -0
- package/dist/testing/commit-writes.js +12 -0
- package/dist/testing/commit-writes.js.map +1 -0
- package/dist/testing/env-conformance.js +7 -7
- package/dist/testing/env-conformance.js.map +1 -1
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +1 -0
- package/dist/testing/index.js.map +1 -1
- package/dist/testing/storage-benchmark.d.ts.map +1 -1
- package/dist/testing/storage-benchmark.js +18 -17
- package/dist/testing/storage-benchmark.js.map +1 -1
- package/dist/testing/storage-conformance.d.ts.map +1 -1
- package/dist/testing/storage-conformance.js +354 -69
- package/dist/testing/storage-conformance.js.map +1 -1
- package/dist/tool-search/tool-search.d.ts +6 -12
- package/dist/tool-search/tool-search.d.ts.map +1 -1
- package/dist/tool-search/tool-search.js +7 -7
- package/dist/tool-search/tool-search.js.map +1 -1
- package/dist/tools/bash.d.ts +12 -12
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +16 -15
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/edit.d.ts +7 -7
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/edit.js +9 -9
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/index.d.ts +32 -32
- package/dist/tools/read.d.ts +6 -6
- package/dist/tools/read.d.ts.map +1 -1
- package/dist/tools/read.js +19 -8
- package/dist/tools/read.js.map +1 -1
- package/dist/tools/write.d.ts +4 -4
- package/dist/tools/write.d.ts.map +1 -1
- package/dist/tools/write.js +5 -5
- package/dist/tools/write.js.map +1 -1
- package/dist/types.d.ts +223 -77
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +19 -12
- package/dist/harness/events.d.ts +0 -186
- package/dist/harness/events.d.ts.map +0 -1
- package/dist/harness/events.js +0 -373
- package/dist/harness/events.js.map +0 -1
- package/dist/session/observation.d.ts +0 -42
- package/dist/session/observation.d.ts.map +0 -1
- package/dist/session/observation.js +0 -281
- package/dist/session/observation.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../src/storage/store/storage.ts"],"names":[],"mappings":"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","sourcesContent":["// Durable's `Storage` on Chord's store (slice 6b D1, D2, §2): opening under an owner name (claims, tables, the\n// allocator), commits as one composite write of the store's commit step, and the reads, each one guarded read of the\n// store (several queries at one state in a read transaction), its request errors in a tagged result told after it.\n\nimport type { Context, JsonValue } from \"@earendil-works/chord\";\nimport {\n\ttype ChordStore,\n\ttype Claimant,\n\tfindDocumentEntry,\n\tlistDocumentEntries,\n\ttype SeriesCommit,\n\ttype Store,\n\tStoreOwnerTables,\n} from \"@earendil-works/chord/next\";\nimport type { SqliteExecutor } from \"@earendil-works/chord/sqlite\";\nimport { StorageRequestError } from \"../../errors.ts\";\nimport { idFromNumber, seqFromNumber } from \"../../ids.ts\";\nimport type {\n\tCommitResult,\n\tConversationId,\n\tConversationQuery,\n\tConversationRecord,\n\tCursor,\n\tDocumentAddress,\n\tDocumentId,\n\tDocumentPoint,\n\tDocumentQuery,\n\tDocumentRecord,\n\tEntryId,\n\tEntryQuery,\n\tEntryRecord,\n\tId,\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 CommitTables, DurableCommit } from \"./commit.ts\";\nimport { addressOf, type DocumentRead, namespaceOf, readAt, recordOfEntry, SCOPE_NAMESPACES } from \"./documents.ts\";\nimport { type Condition, type StorageQueries, storageQueries, type TableQueries } from \"./queries.ts\";\nimport { Conversations, Entries, EntryHeads, encodeIndexed, RecordIds, Submissions, Tasks } from \"./tables.ts\";\n\ntype StoredTask = TaskRecord<JsonValue, JsonValue, JsonValue>;\ntype StoredEntry = { readonly entry: EntryRecord; readonly commitSeq: Seq };\n\n/**\n * A guarded read's result: its data, or its request error, which is thrown after the guarded read (slice 6b §1.4),\n * never inside it.\n */\ntype Read<T> = { readonly kind: \"found\"; readonly value: T } | { readonly kind: \"refused\"; readonly message: string };\n\n/** The id condition of a table scan from `start`. */\nfunction scanFrom(start: ScanStart): Condition {\n\treturn start.order === \"ascending\"\n\t\t? [\"id\", \"gt\", start.after ?? -1]\n\t\t: [\"id\", \"lt\", start.after ?? Number.MAX_SAFE_INTEGER];\n}\n\nfunction page<T extends { readonly id: Id<string> }>(\n\tvalues: readonly T[],\n\tlimit: number,\n\torder: ScanOrder,\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\nfunction cursorId(cursor: Cursor | undefined): number | undefined {\n\tconst after = cursor?.after;\n\tif (after === undefined) return undefined;\n\tif (typeof after !== \"number\" || !Number.isSafeInteger(after))\n\t\tthrow new StorageRequestError(\"Invalid storage cursor\");\n\treturn after;\n}\n\n/**\n * Durable's `Storage` on Chord's store (slice 6b D1, D2, §2): its records as declared tables under an owner name, its\n * documents in the store's documents engine, its ids from the store's one allocator, each commit call as one series\n * of the store's commit queue (one backend transaction, one seq per batch), published in the host's batch. Several may share a store under distinct owner names\n * (claims); the app owns the store, and `close` leaves it open.\n */\nexport class StoreStorage implements Storage {\n\treadonly #store: ChordStore;\n\treadonly #owner: string;\n\treadonly #claimant: Claimant;\n\treadonly #tables: CommitTables;\n\treadonly #queries: StorageQueries;\n\t#closed = false;\n\t#closing: Promise<void> | undefined;\n\t/** Calls underway, which `close` waits for before it releases the claims (`#drained` once they reach 0). */\n\t#underway = 0;\n\t#drained: (() => void) | undefined;\n\n\tprivate constructor(store: ChordStore, owner: string, claimant: Claimant, tables: CommitTables) {\n\t\tthis.#store = store;\n\t\tthis.#owner = owner;\n\t\tthis.#claimant = claimant;\n\t\tthis.#tables = tables;\n\t\tthis.#queries = storageQueries(tables);\n\t}\n\n\t/**\n\t * Opens Durable's storage in `store` under `owner` (a lowercase `[a-z0-9@/._~-]` name): claims its tables and its\n\t * document namespaces (a second claim is refused `invalid/args`), creates or migrates its tables, and raises the\n\t * store's allocator above every id it holds (one index read). A failure releases what it claimed.\n\t */\n\tstatic async open(store: Store, owner: string, context: Context): Promise<StoreStorage> {\n\t\t// Chord's own: `openStore` or `importStore` made it.\n\t\tconst chord = store as ChordStore;\n\t\tconst claimant: Claimant = { label: `StoreStorage(${owner})` };\n\t\ttry {\n\t\t\tconst declared = new StoreOwnerTables(chord, owner, claimant);\n\t\t\tconst tables: CommitTables = {\n\t\t\t\trecordIds: declared.declare(RecordIds),\n\t\t\t\tconversations: declared.declare(Conversations),\n\t\t\t\tentries: declared.declare(Entries),\n\t\t\t\tentryHeads: declared.declare(EntryHeads),\n\t\t\t\ttasks: declared.declare(Tasks),\n\t\t\t\tsubmissions: declared.declare(Submissions),\n\t\t\t};\n\t\t\tfor (const namespace of SCOPE_NAMESPACES) chord.claims.documents(owner, namespace, claimant);\n\t\t\tawait declared.prepare(context);\n\t\t\tconst highest = await chord.read(\n\t\t\t\t(executor) =>\n\t\t\t\t\texecutor.get<{ readonly id: number | null }>(\n\t\t\t\t\t\t`SELECT max(\"id\") AS id FROM \"${tables.recordIds.sql.table}\"`,\n\t\t\t\t\t),\n\t\t\t\tcontext,\n\t\t\t);\n\t\t\tif (highest?.id != null) chord.ids.raise(highest.id);\n\t\t\treturn new StoreStorage(chord, owner, claimant, tables);\n\t\t} catch (error) {\n\t\t\tchord.claims.release(claimant);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Commit `batches` as one series of the store (`ChordStore.commitSeries`): one backend transaction, one seq per\n\t * batch, each batch's checks (at staging, then against the state the earlier ones left) before its writes.\n\t */\n\tcommit(\n\t\tbatches: readonly (readonly StorageWrite[])[],\n\t\treceive: (index: number, seq: Seq) => void,\n\t\tcontext: Context,\n\t): Promise<CommitResult> {\n\t\treturn this.#call(() => {\n\t\t\tconst store = this.#store;\n\t\t\tconst raise = (id: number): void => store.ids.raise(id);\n\t\t\tconst commits: SeriesCommit[] = [];\n\t\t\tfor (const writes of batches) {\n\t\t\t\ttry {\n\t\t\t\t\tcommits.push(new DurableCommit(writes, this.#owner, this.#tables, raise, context));\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// Staging runs Durable's checks of the batch itself: a refusal in its turn, the batches before it stored.\n\t\t\t\t\tcommits.push({ check: () => Promise.reject(error), writes: [] });\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn store.commitSeries(commits, (index, seq) => receive(index, seqFromNumber(seq)), context);\n\t\t});\n\t}\n\n\t/**\n\t * Run a commit's publication in the attached host's batch (`batch.within`: it joins a running batch, opens one, or\n\t * runs next while one sends): Chord sources over Durable's views are marked in one batch per commit. Plainly without\n\t * a host.\n\t */\n\tpublishing(publish: () => void, context: Context): void {\n\t\tconst batch = this.#store.batch;\n\t\tif (batch === undefined) publish();\n\t\telse batch.within(publish, context);\n\t}\n\n\tmintId<I extends Id<string>>(): Promise<I> {\n\t\treturn this.#call(async () => idFromNumber<I>(this.#store.mintId()));\n\t}\n\n\tconversation(id: ConversationId, context: Context): Promise<ConversationRecord | undefined> {\n\t\treturn this.#read((executor) => this.#conversation(executor, id, context), context);\n\t}\n\n\tscanConversations(\n\t\tquery: ConversationQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\tcontext: Context,\n\t): Promise<Page<ConversationRecord, Cursor>> {\n\t\treturn this.#reading(() => {\n\t\t\tconst start = scanStart(query.order, cursor, \"ascending\");\n\t\t\tconst conditions: Condition[] = [scanFrom(start)];\n\t\t\tif (query.ownerConversationId !== undefined) {\n\t\t\t\tconditions.push([\"owner_conversation_id\", \"eq\", query.ownerConversationId]);\n\t\t\t}\n\t\t\tif (query.ownerTaskId !== undefined) conditions.push([\"owner_task_id\", \"eq\", query.ownerTaskId]);\n\t\t\treturn this.#scan<ConversationRecord>(this.#queries.conversations, conditions, start, limit, context);\n\t\t});\n\t}\n\n\tentry(id: EntryId, context: Context): Promise<StoredEntry | undefined>;\n\tentry(conversationId: ConversationId, id: EntryId, context: Context): Promise<StoredEntry | undefined>;\n\tentry(\n\t\tidOrConversationId: EntryId | ConversationId,\n\t\tidOrContext: EntryId | Context,\n\t\tmaybeContext?: Context,\n\t): Promise<StoredEntry | undefined> {\n\t\tif (maybeContext === undefined) {\n\t\t\tconst context = idOrContext as Context;\n\t\t\treturn this.#read((executor) => this.#entry(executor, idOrConversationId as EntryId, context), context);\n\t\t}\n\t\tconst context = maybeContext;\n\t\tconst id = typeof idOrContext === \"number\" ? idFromNumber<EntryId>(idOrContext) : undefined;\n\t\treturn this.#reading(() => {\n\t\t\tif (id === undefined) throw new StorageRequestError(\"Storage.entry() requires an entry ID\");\n\t\t\tconst conversationId = idOrConversationId as ConversationId;\n\t\t\treturn this.#store\n\t\t\t\t.read((executor) => this.#visibleEntry(executor, conversationId, id, context), context)\n\t\t\t\t.then(told);\n\t\t});\n\t}\n\n\tfindLatestHeadMarker(\n\t\tconversationId: ConversationId,\n\t\tatOrBeforeEntryId: EntryId | undefined,\n\t\tcontext: Context,\n\t): Promise<(EntryRecord & { readonly head: EntryId }) | undefined> {\n\t\treturn this.#reading(() =>\n\t\t\tthis.#store\n\t\t\t\t.read((executor) => this.#latestHeadMarker(executor, conversationId, atOrBeforeEntryId, context), context)\n\t\t\t\t.then(told),\n\t\t);\n\t}\n\n\tscanEntries(\n\t\tquery: EntryQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\tcontext: Context,\n\t): Promise<Page<EntryRecord, Cursor>> {\n\t\treturn this.#reading(() => {\n\t\t\tconst { order, after } = scanStart(query.order, cursor, \"descending\");\n\t\t\tconst read =\n\t\t\t\torder === \"ascending\"\n\t\t\t\t\t? (executor: SqliteExecutor) => this.#entriesAscending(executor, query, limit, after, context)\n\t\t\t\t\t: (executor: SqliteExecutor) => this.#entriesDescending(executor, query, limit, after, context);\n\t\t\treturn this.#store.read(read, context).then(told);\n\t\t});\n\t}\n\n\ttask(id: TaskId, context: Context): Promise<StoredTask | undefined> {\n\t\tconst tasks = this.#queries.tasks;\n\t\treturn this.#read(async (executor) => {\n\t\t\tconst row = await tasks.byId(executor, id);\n\t\t\treturn row === undefined ? undefined : tasks.record<StoredTask>(row, context);\n\t\t}, context);\n\t}\n\n\tscanTasks(\n\t\tquery: TaskQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\tcontext: Context,\n\t): Promise<Page<StoredTask, Cursor>> {\n\t\treturn this.#reading(() => {\n\t\t\tconst start = scanStart(query.order, cursor, \"ascending\");\n\t\t\tconst conditions: Condition[] = [scanFrom(start)];\n\t\t\tif (query.conversationId !== undefined) conditions.push([\"conversation_id\", \"eq\", query.conversationId]);\n\t\t\tif (query.kind !== undefined) conditions.push([\"kind\", \"eq\", encodeIndexed(query.kind)]);\n\t\t\tif (query.status !== undefined) conditions.push([\"status\", \"eq\", query.status]);\n\t\t\tif (query.abortRequested !== undefined)\n\t\t\t\tconditions.push([\"abort_requested\", \"eq\", query.abortRequested ? 1 : 0]);\n\t\t\tif (query.background !== undefined) conditions.push([\"background\", \"eq\", query.background ? 1 : 0]);\n\t\t\treturn this.#scan<StoredTask>(this.#queries.tasks, conditions, start, limit, context);\n\t\t});\n\t}\n\n\tsubmission(id: SubmissionId, context: Context): Promise<SubmissionRecord | undefined> {\n\t\tconst submissions = this.#queries.submissions;\n\t\treturn this.#read(async (executor) => {\n\t\t\tconst row = await submissions.byId(executor, id);\n\t\t\treturn row === undefined ? undefined : submissions.record<SubmissionRecord>(row, context);\n\t\t}, context);\n\t}\n\n\tscanSubmissions(\n\t\tquery: SubmissionQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\tcontext: Context,\n\t): Promise<Page<SubmissionRecord, Cursor>> {\n\t\treturn this.#reading(() => {\n\t\t\tconst start = scanStart(query.order, cursor, \"ascending\");\n\t\t\tconst conditions: Condition[] = [scanFrom(start)];\n\t\t\tif (query.conversationId !== undefined) conditions.push([\"conversation_id\", \"eq\", query.conversationId]);\n\t\t\tif (query.status !== undefined) conditions.push([\"status\", \"eq\", query.status]);\n\t\t\treturn this.#scan<SubmissionRecord>(this.#queries.submissions, conditions, start, limit, context);\n\t\t});\n\t}\n\n\tsubmissionByRequest(\n\t\tconversationId: ConversationId,\n\t\trequestId: string,\n\t\tcontext: Context,\n\t): Promise<SubmissionRecord | undefined> {\n\t\tconst submissions = this.#queries.submissions;\n\t\tconst conditions: Condition[] = [\n\t\t\t[\"conversation_id\", \"eq\", conversationId],\n\t\t\t[\"request_id\", \"eq\", encodeIndexed(requestId)],\n\t\t];\n\t\treturn this.#read(async (executor) => {\n\t\t\tconst row = await submissions.first(executor, conditions, \"ascending\");\n\t\t\treturn row === undefined ? undefined : submissions.record<SubmissionRecord>(row, context);\n\t\t}, context);\n\t}\n\n\tfindDocument(address: DocumentAddress, at: DocumentPoint, context: Context): Promise<DocumentRecord | undefined> {\n\t\treturn this.#read(async (executor) => {\n\t\t\tconst entry = await findDocumentEntry(executor, addressOf(address, this.#owner), at);\n\t\t\treturn entry === undefined ? undefined : recordOfEntry(entry);\n\t\t}, context);\n\t}\n\n\tdocument(id: DocumentId, at: DocumentPoint, context: Context): Promise<StoredDocument | undefined> {\n\t\t// The record and its revisions must come from one committed state (S4).\n\t\treturn this.#reading(() =>\n\t\t\tthis.#store.readTransaction((executor) => readAt(executor, id, at, this.#owner), context).then(documentOf),\n\t\t);\n\t}\n\n\tscanDocuments(\n\t\tquery: DocumentQuery,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\tcontext: Context,\n\t): Promise<Page<DocumentRecord, Cursor>> {\n\t\treturn this.#reading(() => {\n\t\t\tconst after = cursorId(cursor) ?? -1;\n\t\t\tconst scope = {\n\t\t\t\towner: this.#owner,\n\t\t\t\tnamespace: namespaceOf(query.scope),\n\t\t\t\t...(query.kind === undefined ? {} : { kind: encodeIndexed(query.kind) }),\n\t\t\t};\n\t\t\treturn this.#store\n\t\t\t\t.read((executor) => listDocumentEntries(executor, scope, query.at, after, limit + 1), context)\n\t\t\t\t.then((found) => page(found.map(recordOfEntry), limit, \"ascending\"));\n\t\t});\n\t}\n\n\t/**\n\t * Refuses new calls, waits for its commits underway, then releases its claims; the store stays open (the app's),\n\t * and finishes the reads underway, which change nothing.\n\t */\n\tclose(_context: Context): Promise<void> {\n\t\tif (this.#closing === undefined) {\n\t\t\tthis.#closed = true;\n\t\t\tthis.#closing = (async () => {\n\t\t\t\tif (this.#underway > 0) {\n\t\t\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\t\t\tthis.#drained = resolve;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tthis.#store.claims.release(this.#claimant);\n\t\t\t})();\n\t\t}\n\t\treturn this.#closing;\n\t}\n\n\t/** Runs one commit or mint of this storage: refused once it closed, counted until it settles (`close` waits). */\n\tasync #call<T>(run: () => Promise<T>): Promise<T> {\n\t\tif (this.#closed) throw new Error(\"StoreStorage is closed\");\n\t\tthis.#underway++;\n\t\ttry {\n\t\t\treturn await run();\n\t\t} finally {\n\t\t\tif (--this.#underway === 0) this.#drained?.();\n\t\t}\n\t}\n\n\t/**\n\t * A call that is one guarded read of the store: refused once closed; not waited for by `close` (a read changes\n\t * nothing, and the store, which stays open, finishes it).\n\t */\n\t#read<T>(read: (executor: SqliteExecutor) => Promise<T>, context: Context): Promise<T> {\n\t\treturn this.#reading(() => this.#store.read(read, context));\n\t}\n\n\t/**\n\t * A read call: `read` prepares its guarded read (a request error thrown then, before it) and returns it. Refused\n\t * once closed; one promise per call besides the guard's (no async wrapper).\n\t */\n\t#reading<T>(read: () => Promise<T>): Promise<T> {\n\t\ttry {\n\t\t\tif (this.#closed) throw new Error(\"StoreStorage is closed\");\n\t\t\treturn read();\n\t\t} catch (error) {\n\t\t\treturn Promise.reject(error);\n\t\t}\n\t}\n\n\tasync #conversation(\n\t\texecutor: SqliteExecutor,\n\t\tid: ConversationId,\n\t\tcontext: Context,\n\t): Promise<ConversationRecord | undefined> {\n\t\tconst conversations = this.#queries.conversations;\n\t\tconst row = await conversations.byId(executor, id);\n\t\treturn row === undefined ? undefined : conversations.record<ConversationRecord>(row, context);\n\t}\n\n\t#entry(executor: SqliteExecutor, id: EntryId, context: Context): Promise<StoredEntry | undefined> {\n\t\tconst entries = this.#queries.entries;\n\t\treturn entries.byId(executor, id).then((row) => {\n\t\t\tif (row === undefined) return undefined;\n\t\t\treturn { entry: entries.record<EntryRecord>(row, context), commitSeq: seqFromNumber(row.commit_seq!) };\n\t\t});\n\t}\n\n\t/** Entry `id` when visible through `conversationId`'s fork chain (`SqliteStorage.readEntry`). */\n\tasync #visibleEntry(\n\t\texecutor: SqliteExecutor,\n\t\tconversationId: ConversationId,\n\t\tid: EntryId,\n\t\tcontext: Context,\n\t): Promise<Read<StoredEntry | undefined>> {\n\t\tlet conversation = await this.#conversation(executor, conversationId, context);\n\t\tif (conversation === undefined) return unknownConversation(conversationId);\n\t\tconst stored = await this.#entry(executor, id, context);\n\t\tif (stored === undefined) return NOTHING_FOUND;\n\t\tlet upper = Number.POSITIVE_INFINITY;\n\t\twhile (conversation.id !== stored.entry.conversationId) {\n\t\t\tif (conversation.parent === undefined) return NOTHING_FOUND;\n\t\t\tupper = Math.min(upper, conversation.parent.at);\n\t\t\tconversation = (await this.#conversation(executor, conversation.parent.conversationId, context))!;\n\t\t}\n\t\treturn stored.entry.id > upper ? NOTHING_FOUND : { kind: \"found\", value: stored };\n\t}\n\n\tasync #latestHeadMarker(\n\t\texecutor: SqliteExecutor,\n\t\tconversationId: ConversationId,\n\t\tatOrBeforeEntryId: EntryId | undefined,\n\t\tcontext: Context,\n\t): Promise<Read<(EntryRecord & { readonly head: EntryId }) | undefined>> {\n\t\tlet conversation = await this.#conversation(executor, conversationId, context);\n\t\tif (conversation === undefined) return unknownConversation(conversationId);\n\t\tlet upper: number | undefined = atOrBeforeEntryId;\n\t\twhile (true) {\n\t\t\tconst { latestHead } = this.#queries;\n\t\t\tconst head =\n\t\t\t\tupper === undefined\n\t\t\t\t\t? await executor.get<{ readonly id: number }>(latestHead.any, conversation.id)\n\t\t\t\t\t: await executor.get<{ readonly id: number }>(latestHead.atOrBefore, conversation.id, upper);\n\t\t\tif (head !== undefined) {\n\t\t\t\t// Written with its entry, in the same commit.\n\t\t\t\tconst row = (await this.#queries.entries.byId(executor, head.id))!;\n\t\t\t\tconst value = this.#queries.entries.record<EntryRecord & { readonly head: EntryId }>(row, context);\n\t\t\t\treturn { kind: \"found\", value };\n\t\t\t}\n\t\t\tif (conversation.parent === undefined) return NOTHING_FOUND;\n\t\t\tupper = upper === undefined ? conversation.parent.at : Math.min(upper, conversation.parent.at);\n\t\t\tconversation = (await this.#conversation(executor, conversation.parent.conversationId, context))!;\n\t\t}\n\t}\n\n\t/** Newest first: each conversation of the fork chain up to its fork point (`SqliteStorage.readEntries`). */\n\tasync #entriesDescending(\n\t\texecutor: SqliteExecutor,\n\t\tquery: EntryQuery,\n\t\tlimit: number,\n\t\tafter: number | undefined,\n\t\tcontext: Context,\n\t): Promise<Read<Page<EntryRecord, Cursor>>> {\n\t\tlet conversation = await this.#conversation(executor, query.conversationId, context);\n\t\tif (conversation === undefined) return unknownConversation(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 range = this.#range(conversation.id, query.minEntryId, upper);\n\t\t\tconst rows = await this.#queries.entries.select(executor, range, \"descending\", limit + 1 - values.length);\n\t\t\tthis.#queries.entries.records(rows, values, context);\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.#conversation(executor, conversation.parent.conversationId, context))!;\n\t\t}\n\t\treturn { kind: \"found\", value: page(values, limit, \"descending\") };\n\t}\n\n\t/** Oldest first: the fork chain's segments from the root forward, each up to its fork point. */\n\tasync #entriesAscending(\n\t\texecutor: SqliteExecutor,\n\t\tquery: EntryQuery,\n\t\tlimit: number,\n\t\tafter: number | undefined,\n\t\tcontext: Context,\n\t): Promise<Read<Page<EntryRecord, Cursor>>> {\n\t\tconst segments: { readonly conversationId: ConversationId; readonly upper: number | undefined }[] = [];\n\t\tlet conversation = await this.#conversation(executor, query.conversationId, context);\n\t\tif (conversation === undefined) return unknownConversation(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.#conversation(executor, conversation.parent.conversationId, context))!;\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 range = this.#range(segment.conversationId, lower, segment.upper);\n\t\t\tconst rows = await this.#queries.entries.select(executor, range, \"ascending\", limit + 1 - values.length);\n\t\t\tthis.#queries.entries.records(rows, values, context);\n\t\t\tif (values.length > limit) break;\n\t\t}\n\t\treturn { kind: \"found\", value: page(values, limit, \"ascending\") };\n\t}\n\n\t/** One conversation's entries with ids from `lower` to `upper` (inclusive, each optional). */\n\t#range(conversationId: ConversationId, lower: number | undefined, upper: number | undefined): Condition[] {\n\t\tconst conditions: Condition[] = [[\"conversation_id\", \"eq\", conversationId]];\n\t\tif (lower !== undefined) conditions.push([\"id\", \"gte\", lower]);\n\t\tif (upper !== undefined) conditions.push([\"id\", \"lte\", upper]);\n\t\treturn conditions;\n\t}\n\n\t/** A page of a table scan: up to `limit` records of `queries`' table whose `conditions` hold, from `start`. */\n\t#scan<T extends { readonly id: Id<string> }>(\n\t\tqueries: TableQueries,\n\t\tconditions: readonly Condition[],\n\t\tstart: ScanStart,\n\t\tlimit: number,\n\t\tcontext: Context,\n\t): Promise<Page<T, Cursor>> {\n\t\treturn this.#store\n\t\t\t.read((executor) => queries.select(executor, conditions, start.order, limit + 1), context)\n\t\t\t.then((rows) => {\n\t\t\t\tconst values: T[] = [];\n\t\t\t\tqueries.records(rows, values, context);\n\t\t\t\treturn page(values, limit, start.order);\n\t\t\t});\n\t}\n}\n\n/** A read that found nothing. */\nconst NOTHING_FOUND: Read<undefined> = { kind: \"found\", value: undefined };\n\nfunction unknownConversation(id: ConversationId): Read<never> {\n\treturn { kind: \"refused\", message: `Unknown conversation: ${id}` };\n}\n\n/** A read's data, its request error thrown now that the guarded read returned (slice 6b §1.4). */\nfunction told<T>(read: Read<T>): T {\n\tif (read.kind === \"refused\") throw new StorageRequestError(read.message);\n\treturn read.value;\n}\n\n/** A document read's result, a record that keeps no history at the point thrown as Durable's request error. */\nfunction documentOf(read: DocumentRead): StoredDocument | undefined {\n\tif (read.kind === \"current_only\")\n\t\tthrow new StorageRequestError(`Document ${read.id} does not retain historical content`);\n\treturn read.document;\n}\n"]}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { JsonValue } from "@earendil-works/chord";
|
|
2
|
+
import type { ConversationRecord, EntryRecord, SubmissionRecord, TaskRecord } from "../../types.ts";
|
|
3
|
+
/** Which record type owns an id: Durable's one namespace across its five record types. */
|
|
4
|
+
export declare const RecordIds: import("@earendil-works/chord/next").TableDefinition<{
|
|
5
|
+
id: import("@earendil-works/chord/next").IntegerSchema;
|
|
6
|
+
record_type: import("@earendil-works/chord/next").StringSchema;
|
|
7
|
+
}, readonly ["id"], 1>;
|
|
8
|
+
export declare const Conversations: import("@earendil-works/chord/next").TableDefinition<{
|
|
9
|
+
id: import("@earendil-works/chord/next").IntegerSchema;
|
|
10
|
+
owner_conversation_id: import("@earendil-works/chord/next").IntegerSchema;
|
|
11
|
+
owner_task_id: import("@earendil-works/chord/next").IntegerSchema;
|
|
12
|
+
record: import("@earendil-works/chord/next").JsonColumnSchema<unknown>;
|
|
13
|
+
}, readonly ["id"], 1>;
|
|
14
|
+
export declare const Entries: import("@earendil-works/chord/next").TableDefinition<{
|
|
15
|
+
id: import("@earendil-works/chord/next").IntegerSchema;
|
|
16
|
+
conversation_id: import("@earendil-works/chord/next").IntegerSchema;
|
|
17
|
+
commit_seq: import("@earendil-works/chord/next").IntegerSchema;
|
|
18
|
+
record: import("@earendil-works/chord/next").JsonColumnSchema<unknown>;
|
|
19
|
+
}, readonly ["id"], 1>;
|
|
20
|
+
/**
|
|
21
|
+
* The entries with a head marker, by conversation: what `SqliteStorage`'s partial index on `head IS NOT NULL` is,
|
|
22
|
+
* as rows written only with such an entry, so a commit of an entry without one updates no second index.
|
|
23
|
+
*/
|
|
24
|
+
export declare const EntryHeads: import("@earendil-works/chord/next").TableDefinition<{
|
|
25
|
+
id: import("@earendil-works/chord/next").IntegerSchema;
|
|
26
|
+
conversation_id: import("@earendil-works/chord/next").IntegerSchema;
|
|
27
|
+
}, readonly ["id"], 1>;
|
|
28
|
+
export declare const Tasks: import("@earendil-works/chord/next").TableDefinition<{
|
|
29
|
+
id: import("@earendil-works/chord/next").IntegerSchema;
|
|
30
|
+
conversation_id: import("@earendil-works/chord/next").IntegerSchema;
|
|
31
|
+
kind: import("@earendil-works/chord/next").StringSchema;
|
|
32
|
+
status: import("@earendil-works/chord/next").StringSchema;
|
|
33
|
+
abort_requested: import("@earendil-works/chord/next").IntegerSchema;
|
|
34
|
+
background: import("@earendil-works/chord/next").IntegerSchema;
|
|
35
|
+
record: import("@earendil-works/chord/next").JsonColumnSchema<unknown>;
|
|
36
|
+
}, readonly ["id"], 1>;
|
|
37
|
+
export declare const Submissions: import("@earendil-works/chord/next").TableDefinition<{
|
|
38
|
+
id: import("@earendil-works/chord/next").IntegerSchema;
|
|
39
|
+
conversation_id: import("@earendil-works/chord/next").IntegerSchema;
|
|
40
|
+
request_id: import("@earendil-works/chord/next").StringSchema;
|
|
41
|
+
status: import("@earendil-works/chord/next").StringSchema;
|
|
42
|
+
record: import("@earendil-works/chord/next").JsonColumnSchema<unknown>;
|
|
43
|
+
}, readonly ["id"], 1>;
|
|
44
|
+
/** Durable's JSON encoding of an indexed string: lossless whatever the string (lone surrogates, NUL). */
|
|
45
|
+
export declare const encodeIndexed: (value: string) => string;
|
|
46
|
+
/** The row of a conversation record. */
|
|
47
|
+
export declare function conversationRow(value: ConversationRecord): object;
|
|
48
|
+
/** The row of an entry record; `commit_seq` is stamped by the step. */
|
|
49
|
+
export declare function entryRow(value: EntryRecord): object;
|
|
50
|
+
/** The row of a task record. */
|
|
51
|
+
export declare function taskRow(value: TaskRecord<JsonValue, JsonValue, JsonValue>): object;
|
|
52
|
+
/** The row of a submission record. */
|
|
53
|
+
export declare function submissionRow(value: SubmissionRecord): object;
|
|
54
|
+
//# sourceMappingURL=tables.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tables.d.ts","sourceRoot":"","sources":["../../../src/storage/store/tables.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEvD,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAKpG,0FAA0F;AAC1F,eAAO,MAAM,SAAS;;;sBAIpB,CAAC;AAEH,eAAO,MAAM,aAAa;;;;;sBAKxB,CAAC;AAEH,eAAO,MAAM,OAAO;;;;;sBAKlB,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,UAAU;;;sBAKrB,CAAC;AAEH,eAAO,MAAM,KAAK;;;;;;;;sBAmBhB,CAAC;AAEH,eAAO,MAAM,WAAW;;;;;;sBAStB,CAAC;AAEH,yGAAyG;AACzG,eAAO,MAAM,aAAa,UAAW,MAAM,KAAG,MAA+B,CAAC;AAE9E,wCAAwC;AACxC,wBAAgB,eAAe,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM,CAOjE;AAED,uEAAuE;AACvE,wBAAgB,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAOnD;AAED,gCAAgC;AAChC,wBAAgB,OAAO,CAAC,KAAK,EAAE,UAAU,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,GAAG,MAAM,CAUlF;AAED,sCAAsC;AACtC,wBAAgB,aAAa,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAQ7D"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// Durable's records as declared tables of the store (slice 6b D2, §2.2): every row carries its record's indexed columns
|
|
2
|
+
// and the whole record as one `json(...)` cell. Indexed strings that must stay lossless (`kind`, `request_id`) hold
|
|
3
|
+
// Durable's JSON encoding; index columns are never `opt`, so absent values take sentinels no encoded value can be
|
|
4
|
+
// (`0` for an absent owner, which is never an id; `""` for an absent request id: an encoded string starts with `"`).
|
|
5
|
+
import { defineTable, int, json, str, unknown } from "@earendil-works/chord/next";
|
|
6
|
+
/** A record as one `json(...)` cell. */
|
|
7
|
+
const record = () => json(unknown(), { version: 1 });
|
|
8
|
+
/** Which record type owns an id: Durable's one namespace across its five record types. */
|
|
9
|
+
export const RecordIds = defineTable("record_ids", {
|
|
10
|
+
version: 1,
|
|
11
|
+
columns: { id: int(), record_type: str() },
|
|
12
|
+
key: ["id"],
|
|
13
|
+
});
|
|
14
|
+
export const Conversations = defineTable("conversations", {
|
|
15
|
+
version: 1,
|
|
16
|
+
columns: { id: int(), owner_conversation_id: int(), owner_task_id: int(), record: record() },
|
|
17
|
+
key: ["id"],
|
|
18
|
+
indexes: { by_owner_conversation: ["owner_conversation_id"], by_owner_task: ["owner_task_id"] },
|
|
19
|
+
});
|
|
20
|
+
export const Entries = defineTable("entries", {
|
|
21
|
+
version: 1,
|
|
22
|
+
columns: { id: int(), conversation_id: int(), commit_seq: int(), record: record() },
|
|
23
|
+
key: ["id"],
|
|
24
|
+
indexes: { by_conversation: ["conversation_id"] },
|
|
25
|
+
});
|
|
26
|
+
/**
|
|
27
|
+
* The entries with a head marker, by conversation: what `SqliteStorage`'s partial index on `head IS NOT NULL` is,
|
|
28
|
+
* as rows written only with such an entry, so a commit of an entry without one updates no second index.
|
|
29
|
+
*/
|
|
30
|
+
export const EntryHeads = defineTable("entry_heads", {
|
|
31
|
+
version: 1,
|
|
32
|
+
columns: { id: int(), conversation_id: int() },
|
|
33
|
+
key: ["id"],
|
|
34
|
+
indexes: { by_conversation: ["conversation_id"] },
|
|
35
|
+
});
|
|
36
|
+
export const Tasks = defineTable("tasks", {
|
|
37
|
+
version: 1,
|
|
38
|
+
columns: {
|
|
39
|
+
id: int(),
|
|
40
|
+
conversation_id: int(),
|
|
41
|
+
kind: str(),
|
|
42
|
+
status: str(),
|
|
43
|
+
abort_requested: int(),
|
|
44
|
+
background: int(),
|
|
45
|
+
record: record(),
|
|
46
|
+
},
|
|
47
|
+
key: ["id"],
|
|
48
|
+
indexes: {
|
|
49
|
+
by_status: ["status"],
|
|
50
|
+
by_conversation: ["conversation_id"],
|
|
51
|
+
by_kind: ["kind"],
|
|
52
|
+
by_abort_requested: ["abort_requested"],
|
|
53
|
+
by_background: ["background"],
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
export const Submissions = defineTable("submissions", {
|
|
57
|
+
version: 1,
|
|
58
|
+
columns: { id: int(), conversation_id: int(), request_id: str(), status: str(), record: record() },
|
|
59
|
+
key: ["id"],
|
|
60
|
+
indexes: {
|
|
61
|
+
by_request: ["conversation_id", "request_id"],
|
|
62
|
+
by_conversation: ["conversation_id"],
|
|
63
|
+
by_status: ["status"],
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
/** Durable's JSON encoding of an indexed string: lossless whatever the string (lone surrogates, NUL). */
|
|
67
|
+
export const encodeIndexed = (value) => JSON.stringify(value);
|
|
68
|
+
/** The row of a conversation record. */
|
|
69
|
+
export function conversationRow(value) {
|
|
70
|
+
return {
|
|
71
|
+
id: value.id,
|
|
72
|
+
owner_conversation_id: value.owner?.conversationId ?? 0,
|
|
73
|
+
owner_task_id: value.owner?.taskId ?? 0,
|
|
74
|
+
record: value,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/** The row of an entry record; `commit_seq` is stamped by the step. */
|
|
78
|
+
export function entryRow(value) {
|
|
79
|
+
return {
|
|
80
|
+
id: value.id,
|
|
81
|
+
conversation_id: value.conversationId,
|
|
82
|
+
commit_seq: 0,
|
|
83
|
+
record: value,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/** The row of a task record. */
|
|
87
|
+
export function taskRow(value) {
|
|
88
|
+
return {
|
|
89
|
+
id: value.id,
|
|
90
|
+
conversation_id: value.conversationId,
|
|
91
|
+
kind: encodeIndexed(value.kind),
|
|
92
|
+
status: value.state.status,
|
|
93
|
+
abort_requested: value.abortRequested ? 1 : 0,
|
|
94
|
+
background: value.background ? 1 : 0,
|
|
95
|
+
record: value,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/** The row of a submission record. */
|
|
99
|
+
export function submissionRow(value) {
|
|
100
|
+
return {
|
|
101
|
+
id: value.id,
|
|
102
|
+
conversation_id: value.conversationId,
|
|
103
|
+
request_id: value.requestId === undefined ? "" : encodeIndexed(value.requestId),
|
|
104
|
+
status: value.status,
|
|
105
|
+
record: value,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=tables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tables.js","sourceRoot":"","sources":["../../../src/storage/store/tables.ts"],"names":[],"mappings":"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","sourcesContent":["// Durable's records as declared tables of the store (slice 6b D2, §2.2): every row carries its record's indexed columns\n// and the whole record as one `json(...)` cell. Indexed strings that must stay lossless (`kind`, `request_id`) hold\n// Durable's JSON encoding; index columns are never `opt`, so absent values take sentinels no encoded value can be\n// (`0` for an absent owner, which is never an id; `\"\"` for an absent request id: an encoded string starts with `\"`).\n\nimport type { JsonValue } from \"@earendil-works/chord\";\nimport { defineTable, int, json, str, unknown } from \"@earendil-works/chord/next\";\nimport type { ConversationRecord, EntryRecord, SubmissionRecord, TaskRecord } from \"../../types.ts\";\n\n/** A record as one `json(...)` cell. */\nconst record = () => json(unknown(), { version: 1 });\n\n/** Which record type owns an id: Durable's one namespace across its five record types. */\nexport const RecordIds = defineTable(\"record_ids\", {\n\tversion: 1,\n\tcolumns: { id: int(), record_type: str() },\n\tkey: [\"id\"],\n});\n\nexport const Conversations = defineTable(\"conversations\", {\n\tversion: 1,\n\tcolumns: { id: int(), owner_conversation_id: int(), owner_task_id: int(), record: record() },\n\tkey: [\"id\"],\n\tindexes: { by_owner_conversation: [\"owner_conversation_id\"], by_owner_task: [\"owner_task_id\"] },\n});\n\nexport const Entries = defineTable(\"entries\", {\n\tversion: 1,\n\tcolumns: { id: int(), conversation_id: int(), commit_seq: int(), record: record() },\n\tkey: [\"id\"],\n\tindexes: { by_conversation: [\"conversation_id\"] },\n});\n\n/**\n * The entries with a head marker, by conversation: what `SqliteStorage`'s partial index on `head IS NOT NULL` is,\n * as rows written only with such an entry, so a commit of an entry without one updates no second index.\n */\nexport const EntryHeads = defineTable(\"entry_heads\", {\n\tversion: 1,\n\tcolumns: { id: int(), conversation_id: int() },\n\tkey: [\"id\"],\n\tindexes: { by_conversation: [\"conversation_id\"] },\n});\n\nexport const Tasks = defineTable(\"tasks\", {\n\tversion: 1,\n\tcolumns: {\n\t\tid: int(),\n\t\tconversation_id: int(),\n\t\tkind: str(),\n\t\tstatus: str(),\n\t\tabort_requested: int(),\n\t\tbackground: int(),\n\t\trecord: record(),\n\t},\n\tkey: [\"id\"],\n\tindexes: {\n\t\tby_status: [\"status\"],\n\t\tby_conversation: [\"conversation_id\"],\n\t\tby_kind: [\"kind\"],\n\t\tby_abort_requested: [\"abort_requested\"],\n\t\tby_background: [\"background\"],\n\t},\n});\n\nexport const Submissions = defineTable(\"submissions\", {\n\tversion: 1,\n\tcolumns: { id: int(), conversation_id: int(), request_id: str(), status: str(), record: record() },\n\tkey: [\"id\"],\n\tindexes: {\n\t\tby_request: [\"conversation_id\", \"request_id\"],\n\t\tby_conversation: [\"conversation_id\"],\n\t\tby_status: [\"status\"],\n\t},\n});\n\n/** Durable's JSON encoding of an indexed string: lossless whatever the string (lone surrogates, NUL). */\nexport const encodeIndexed = (value: string): string => JSON.stringify(value);\n\n/** The row of a conversation record. */\nexport function conversationRow(value: ConversationRecord): object {\n\treturn {\n\t\tid: value.id,\n\t\towner_conversation_id: value.owner?.conversationId ?? 0,\n\t\towner_task_id: value.owner?.taskId ?? 0,\n\t\trecord: value,\n\t};\n}\n\n/** The row of an entry record; `commit_seq` is stamped by the step. */\nexport function entryRow(value: EntryRecord): object {\n\treturn {\n\t\tid: value.id,\n\t\tconversation_id: value.conversationId,\n\t\tcommit_seq: 0,\n\t\trecord: value,\n\t};\n}\n\n/** The row of a task record. */\nexport function taskRow(value: TaskRecord<JsonValue, JsonValue, JsonValue>): object {\n\treturn {\n\t\tid: value.id,\n\t\tconversation_id: value.conversationId,\n\t\tkind: encodeIndexed(value.kind),\n\t\tstatus: value.state.status,\n\t\tabort_requested: value.abortRequested ? 1 : 0,\n\t\tbackground: value.background ? 1 : 0,\n\t\trecord: value,\n\t};\n}\n\n/** The row of a submission record. */\nexport function submissionRow(value: SubmissionRecord): object {\n\treturn {\n\t\tid: value.id,\n\t\tconversation_id: value.conversationId,\n\t\trequest_id: value.requestId === undefined ? \"\" : encodeIndexed(value.requestId),\n\t\tstatus: value.status,\n\t\trecord: value,\n\t};\n}\n"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Context } from "@earendil-works/chord";
|
|
2
|
+
import type { Seq, Storage, StorageWrite } from "../types.ts";
|
|
3
|
+
/** Commits `writes` as one batch and resolves with its seq; rejects with the refusal if the storage refused it. */
|
|
4
|
+
export declare function commitWrites(storage: Storage, writes: readonly StorageWrite[], context: Context): Promise<Seq>;
|
|
5
|
+
//# sourceMappingURL=commit-writes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commit-writes.d.ts","sourceRoot":"","sources":["../../src/testing/commit-writes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE9D,mHAAmH;AACnH,wBAAsB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,YAAY,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAWpH"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// One batch through `Storage.commit()`, for tests and suites that seed or write a storage directly.
|
|
2
|
+
/** Commits `writes` as one batch and resolves with its seq; rejects with the refusal if the storage refused it. */
|
|
3
|
+
export async function commitWrites(storage, writes, context) {
|
|
4
|
+
let stored;
|
|
5
|
+
const result = await storage.commit([writes], (_index, seq) => {
|
|
6
|
+
stored = seq;
|
|
7
|
+
}, context);
|
|
8
|
+
if (result.stored === 0)
|
|
9
|
+
throw result.refused;
|
|
10
|
+
return stored;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=commit-writes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commit-writes.js","sourceRoot":"","sources":["../../src/testing/commit-writes.ts"],"names":[],"mappings":"AAAA,oGAAoG;AAKpG,mHAAmH;AACnH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAgB,EAAE,MAA+B,EAAE,OAAgB;IACrG,IAAI,MAAuB,CAAC;IAC5B,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,MAAM,CAClC,CAAC,MAAM,CAAC,EACR,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;QACf,MAAM,GAAG,GAAG,CAAC;IACd,CAAC,EACD,OAAO,CACP,CAAC;IACF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,MAAM,CAAC,OAAO,CAAC;IAC9C,OAAO,MAAO,CAAC;AAChB,CAAC","sourcesContent":["// One batch through `Storage.commit()`, for tests and suites that seed or write a storage directly.\n\nimport type { Context } from \"@earendil-works/chord\";\nimport type { Seq, Storage, StorageWrite } from \"../types.ts\";\n\n/** Commits `writes` as one batch and resolves with its seq; rejects with the refusal if the storage refused it. */\nexport async function commitWrites(storage: Storage, writes: readonly StorageWrite[], context: Context): Promise<Seq> {\n\tlet stored: Seq | undefined;\n\tconst result = await storage.commit(\n\t\t[writes],\n\t\t(_index, seq) => {\n\t\t\tstored = seq;\n\t\t},\n\t\tcontext,\n\t);\n\tif (result.stored === 0) throw result.refused;\n\treturn stored!;\n}\n"]}
|
|
@@ -40,9 +40,9 @@ async function listed(env, path, options) {
|
|
|
40
40
|
}
|
|
41
41
|
/** Whether a change reports `path`: an overflow, or a reported path at or above it. */
|
|
42
42
|
function covers(change, path) {
|
|
43
|
-
if ("overflow"
|
|
43
|
+
if (change.kind === "overflow")
|
|
44
44
|
return true;
|
|
45
|
-
if (
|
|
45
|
+
if (change.kind !== "paths")
|
|
46
46
|
return false;
|
|
47
47
|
return change.paths.some((reported) => path === reported || path.startsWith(`${reported}/`) || path.startsWith(`${reported}\\`));
|
|
48
48
|
}
|
|
@@ -70,7 +70,7 @@ async function watching(env, targets, run) {
|
|
|
70
70
|
});
|
|
71
71
|
}
|
|
72
72
|
finally {
|
|
73
|
-
await watcher.
|
|
73
|
+
await watcher.stop(context);
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
/**
|
|
@@ -297,7 +297,7 @@ export function createEnvConformance(options) {
|
|
|
297
297
|
});
|
|
298
298
|
const hidden = [await absolute("skills/node_modules"), await absolute("skills/.SKILL.md.tmp")];
|
|
299
299
|
for (const change of changes) {
|
|
300
|
-
if (
|
|
300
|
+
if (change.kind !== "paths")
|
|
301
301
|
continue;
|
|
302
302
|
for (const path of change.paths) {
|
|
303
303
|
assert.ok(!hidden.some((excluded) => path === excluded || path.startsWith(excluded)), `excluded ${path}`);
|
|
@@ -329,12 +329,12 @@ export function createEnvConformance(options) {
|
|
|
329
329
|
});
|
|
330
330
|
});
|
|
331
331
|
}),
|
|
332
|
-
watchCase("watch stops reporting once
|
|
332
|
+
watchCase("watch stops reporting once stopped", async (env) => {
|
|
333
333
|
const changes = [];
|
|
334
334
|
const watcher = getOrThrow(await env.watch([{ path: "file.txt" }], (change) => changes.push(change), context));
|
|
335
335
|
assert.ok(watcher.mode === "native" || watcher.mode === "polling", "watcher reports its mode");
|
|
336
|
-
await watcher.
|
|
337
|
-
await watcher.
|
|
336
|
+
await watcher.stop(context);
|
|
337
|
+
await watcher.stop(context);
|
|
338
338
|
getOrThrow(await env.writeFile("file.txt", "x", context));
|
|
339
339
|
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
340
340
|
assert.deepEqual(changes, []);
|