@earendil-works/pi-durable 1.2.0 → 1.3.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 +15 -0
- package/README.md +17 -0
- package/dist/env/index.d.ts +1 -0
- package/dist/env/index.d.ts.map +1 -1
- package/dist/env/index.js.map +1 -1
- package/dist/harness/context.d.ts +5 -0
- package/dist/harness/context.d.ts.map +1 -1
- package/dist/harness/context.js +46 -12
- package/dist/harness/context.js.map +1 -1
- package/dist/harness/tool.d.ts.map +1 -1
- package/dist/harness/tool.js +1 -1
- package/dist/harness/tool.js.map +1 -1
- package/dist/storage/sqlite/cloudflare.d.ts +17 -5
- package/dist/storage/sqlite/cloudflare.d.ts.map +1 -1
- package/dist/storage/sqlite/cloudflare.js +57 -21
- package/dist/storage/sqlite/cloudflare.js.map +1 -1
- package/dist/storage/sqlite/index.d.ts +1 -1
- package/dist/storage/sqlite/index.d.ts.map +1 -1
- package/dist/storage/sqlite/index.js.map +1 -1
- package/dist/storage/sqlite/migrations.d.ts +5 -1
- package/dist/storage/sqlite/migrations.d.ts.map +1 -1
- package/dist/storage/sqlite/migrations.js +94 -84
- package/dist/storage/sqlite/migrations.js.map +1 -1
- package/dist/storage/sqlite/node.d.ts +6 -4
- package/dist/storage/sqlite/node.d.ts.map +1 -1
- package/dist/storage/sqlite/node.js +6 -2
- package/dist/storage/sqlite/node.js.map +1 -1
- package/dist/storage/sqlite/schema.d.ts +47 -0
- package/dist/storage/sqlite/schema.d.ts.map +1 -0
- package/dist/storage/sqlite/schema.js +57 -0
- package/dist/storage/sqlite/schema.js.map +1 -0
- package/dist/storage/sqlite/storage.d.ts +9 -1
- package/dist/storage/sqlite/storage.d.ts.map +1 -1
- package/dist/storage/sqlite/storage.js +46 -43
- package/dist/storage/sqlite/storage.js.map +1 -1
- package/dist/tools/image-processor.d.ts +4 -1
- package/dist/tools/image-processor.d.ts.map +1 -1
- package/dist/tools/image-processor.js +8 -18
- package/dist/tools/image-processor.js.map +1 -1
- package/dist/tools/read.d.ts.map +1 -1
- package/dist/tools/read.js +1 -1
- package/dist/tools/read.js.map +1 -1
- package/dist/truncate.d.ts +3 -2
- package/dist/truncate.d.ts.map +1 -1
- package/dist/truncate.js +4 -34
- package/dist/truncate.js.map +1 -1
- package/package.json +4 -4
- package/dist/harness/output.d.ts +0 -69
- package/dist/harness/output.d.ts.map +0 -1
- package/dist/harness/output.js +0 -318
- package/dist/harness/output.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/storage/sqlite/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjF,OAAO,EACN,qBAAqB,EACrB,6BAA6B,EAC7B,iBAAiB,EACjB,KAAK,eAAe,GACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/storage/sqlite/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjF,OAAO,EACN,qBAAqB,EACrB,6BAA6B,EAC7B,iBAAiB,EACjB,KAAK,eAAe,GACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/sqlite/index.ts"],"names":[],"mappings":"AACA,OAAO,EACN,qBAAqB,EACrB,6BAA6B,EAC7B,iBAAiB,GAEjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/storage/sqlite/index.ts"],"names":[],"mappings":"AACA,OAAO,EACN,qBAAqB,EACrB,6BAA6B,EAC7B,iBAAiB,GAEjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,aAAa,EAA6B,MAAM,cAAc,CAAC","sourcesContent":["export type { SqliteDatabase, SqliteExecutor, SqliteValue } from \"./database.ts\";\nexport {\n\tapplySqliteMigrations,\n\tCURRENT_SQLITE_SCHEMA_VERSION,\n\tSQLITE_MIGRATIONS,\n\ttype SqliteMigration,\n} from \"./migrations.ts\";\nexport { SqliteStorage, type SqliteStorageOptions } from \"./storage.ts\";\n"]}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import type { SqliteDatabase } from "./database.ts";
|
|
2
|
+
import { type SqliteSchema } from "./schema.ts";
|
|
2
3
|
export type SqliteMigration = {
|
|
3
4
|
readonly version: number;
|
|
4
5
|
readonly statements: readonly string[];
|
|
5
6
|
};
|
|
6
|
-
/**
|
|
7
|
+
/** Build immutable, ordered schema history for a set of SQLite identifiers. */
|
|
8
|
+
export declare function createSqliteMigrations(schema: SqliteSchema): readonly SqliteMigration[];
|
|
7
9
|
export declare const SQLITE_MIGRATIONS: readonly SqliteMigration[];
|
|
8
10
|
export declare const CURRENT_SQLITE_SCHEMA_VERSION: number;
|
|
9
11
|
/** Apply all pending schema migrations atomically. */
|
|
10
12
|
export declare function applySqliteMigrations(database: SqliteDatabase, migrations?: readonly SqliteMigration[]): Promise<void>;
|
|
13
|
+
/** Apply migrations rendered for a particular schema. */
|
|
14
|
+
export declare function applySqliteMigrationsForSchema(database: SqliteDatabase, schema: SqliteSchema, migrations?: readonly SqliteMigration[]): Promise<void>;
|
|
11
15
|
//# sourceMappingURL=migrations.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../../src/storage/sqlite/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../../src/storage/sqlite/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAyB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAEvE,MAAM,MAAM,eAAe,GAAG;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC,CAAC;AAEF,+EAA+E;AAC/E,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,eAAe,EAAE,CAiFvF;AAED,eAAO,MAAM,iBAAiB,EAAE,SAAS,eAAe,EAAkD,CAAC;AAE3G,eAAO,MAAM,6BAA6B,QAAyC,CAAC;AAIpF,sDAAsD;AACtD,wBAAsB,qBAAqB,CAC1C,QAAQ,EAAE,cAAc,EACxB,UAAU,GAAE,SAAS,eAAe,EAAsB,GACxD,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,yDAAyD;AACzD,wBAAsB,8BAA8B,CACnD,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,YAAY,EACpB,UAAU,GAAE,SAAS,eAAe,EAAmC,GACrE,OAAO,CAAC,IAAI,CAAC,CA4Bf"}
|
|
@@ -1,98 +1,108 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
1
|
+
import { DEFAULT_SQLITE_SCHEMA } from "./schema.js";
|
|
2
|
+
/** Build immutable, ordered schema history for a set of SQLite identifiers. */
|
|
3
|
+
export function createSqliteMigrations(schema) {
|
|
4
|
+
const { tables, indexes } = schema;
|
|
5
|
+
// next_id is TEXT because node:sqlite rejects INTEGER results outside JavaScript's safe integer range.
|
|
6
|
+
const initialSchema = [
|
|
7
|
+
`CREATE TABLE ${tables.durableMetadata} (
|
|
8
|
+
singleton INTEGER PRIMARY KEY CHECK (singleton = 1),
|
|
9
|
+
next_id TEXT NOT NULL,
|
|
10
|
+
next_seq INTEGER NOT NULL
|
|
11
|
+
) STRICT`,
|
|
12
|
+
`INSERT INTO ${tables.durableMetadata} (singleton, next_id, next_seq) VALUES (1, '2', 1)`,
|
|
13
|
+
`CREATE TABLE ${tables.recordIds} (
|
|
14
|
+
id INTEGER PRIMARY KEY,
|
|
15
|
+
record_type TEXT NOT NULL CHECK (record_type IN ('conversation', 'entry', 'task', 'submission', 'document'))
|
|
16
|
+
) STRICT`,
|
|
17
|
+
`CREATE TABLE ${tables.conversations} (
|
|
18
|
+
id INTEGER PRIMARY KEY,
|
|
19
|
+
owner_conversation_id INTEGER,
|
|
20
|
+
owner_task_id INTEGER,
|
|
21
|
+
record TEXT NOT NULL CHECK (json_valid(record))
|
|
22
|
+
) STRICT`,
|
|
23
|
+
`CREATE INDEX ${indexes.conversationsByOwnerConversation} ON ${tables.conversations} (owner_conversation_id, id)`,
|
|
24
|
+
`CREATE INDEX ${indexes.conversationsByOwnerTask} ON ${tables.conversations} (owner_task_id, id)`,
|
|
25
|
+
`CREATE TABLE ${tables.entries} (
|
|
26
|
+
id INTEGER PRIMARY KEY,
|
|
27
|
+
conversation_id INTEGER NOT NULL,
|
|
28
|
+
head INTEGER,
|
|
29
|
+
commit_seq INTEGER NOT NULL,
|
|
30
|
+
record TEXT NOT NULL CHECK (json_valid(record))
|
|
31
|
+
) STRICT`,
|
|
32
|
+
`CREATE INDEX ${indexes.entriesByConversation} ON ${tables.entries} (conversation_id, id DESC)`,
|
|
33
|
+
`CREATE INDEX ${indexes.entryHeadsByConversation} ON ${tables.entries} (conversation_id, id DESC) WHERE head IS NOT NULL`,
|
|
34
|
+
`CREATE TABLE ${tables.tasks} (
|
|
35
|
+
id INTEGER PRIMARY KEY,
|
|
36
|
+
conversation_id INTEGER NOT NULL,
|
|
37
|
+
kind TEXT NOT NULL,
|
|
38
|
+
status TEXT NOT NULL CHECK (status IN ('pending', 'running', 'waiting', 'completing', 'terminal')),
|
|
39
|
+
abort_requested INTEGER NOT NULL CHECK (abort_requested IN (0, 1)),
|
|
40
|
+
background INTEGER NOT NULL CHECK (background IN (0, 1)),
|
|
41
|
+
record TEXT NOT NULL CHECK (json_valid(record))
|
|
42
|
+
) STRICT`,
|
|
43
|
+
`CREATE INDEX ${indexes.tasksByStatus} ON ${tables.tasks} (status, id)`,
|
|
44
|
+
`CREATE INDEX ${indexes.tasksByConversation} ON ${tables.tasks} (conversation_id, id)`,
|
|
45
|
+
`CREATE INDEX ${indexes.tasksByKind} ON ${tables.tasks} (kind, id)`,
|
|
46
|
+
`CREATE INDEX ${indexes.tasksByAbortRequested} ON ${tables.tasks} (abort_requested, id)`,
|
|
47
|
+
`CREATE INDEX ${indexes.tasksByBackground} ON ${tables.tasks} (background, id)`,
|
|
48
|
+
`CREATE TABLE ${tables.submissions} (
|
|
49
|
+
id INTEGER PRIMARY KEY,
|
|
50
|
+
conversation_id INTEGER NOT NULL,
|
|
51
|
+
request_id TEXT,
|
|
52
|
+
status TEXT NOT NULL CHECK (status IN ('queued', 'placed', 'done', 'unanswered')),
|
|
53
|
+
record TEXT NOT NULL CHECK (json_valid(record))
|
|
54
|
+
) STRICT`,
|
|
55
|
+
`CREATE INDEX ${indexes.submissionsByRequest} ON ${tables.submissions} (conversation_id, request_id)`,
|
|
56
|
+
`CREATE INDEX ${indexes.submissionsByConversation} ON ${tables.submissions} (conversation_id, id)`,
|
|
57
|
+
`CREATE INDEX ${indexes.submissionsByStatus} ON ${tables.submissions} (status, id)`,
|
|
58
|
+
`CREATE TABLE ${tables.documents} (
|
|
59
|
+
id INTEGER PRIMARY KEY,
|
|
60
|
+
kind TEXT NOT NULL,
|
|
61
|
+
family INTEGER NOT NULL CHECK (family IN (0, 1)),
|
|
62
|
+
key_value TEXT NOT NULL,
|
|
63
|
+
scope_kind TEXT NOT NULL CHECK (scope_kind IN ('session', 'conversation', 'task')),
|
|
64
|
+
owner_id INTEGER NOT NULL,
|
|
65
|
+
created_at INTEGER NOT NULL,
|
|
66
|
+
retired_at INTEGER,
|
|
67
|
+
record TEXT NOT NULL CHECK (json_valid(record))
|
|
68
|
+
) STRICT`,
|
|
69
|
+
`CREATE INDEX ${indexes.documentsByAddress}
|
|
70
|
+
ON ${tables.documents} (kind, scope_kind, owner_id, family, key_value, created_at DESC, retired_at)`,
|
|
71
|
+
`CREATE INDEX ${indexes.documentsByScope} ON ${tables.documents} (scope_kind, owner_id, id)`,
|
|
72
|
+
`CREATE INDEX ${indexes.documentsByScopeKind} ON ${tables.documents} (scope_kind, owner_id, kind, id)`,
|
|
73
|
+
`CREATE TABLE ${tables.documentRevisions} (
|
|
74
|
+
document_id INTEGER NOT NULL,
|
|
75
|
+
seq INTEGER NOT NULL,
|
|
76
|
+
kind TEXT NOT NULL CHECK (kind IN ('base', 'delta')),
|
|
77
|
+
version INTEGER NOT NULL,
|
|
78
|
+
content TEXT NOT NULL CHECK (json_valid(content)),
|
|
79
|
+
PRIMARY KEY (document_id, seq)
|
|
80
|
+
) STRICT`,
|
|
81
|
+
`CREATE INDEX ${indexes.documentRevisionsByKind} ON ${tables.documentRevisions} (document_id, kind, seq DESC)`,
|
|
82
|
+
];
|
|
83
|
+
return [{ version: 1, statements: initialSchema }];
|
|
84
|
+
}
|
|
85
|
+
export const SQLITE_MIGRATIONS = createSqliteMigrations(DEFAULT_SQLITE_SCHEMA);
|
|
81
86
|
export const CURRENT_SQLITE_SCHEMA_VERSION = SQLITE_MIGRATIONS.at(-1)?.version ?? 0;
|
|
82
87
|
/** Apply all pending schema migrations atomically. */
|
|
83
88
|
export async function applySqliteMigrations(database, migrations = SQLITE_MIGRATIONS) {
|
|
89
|
+
await applySqliteMigrationsForSchema(database, DEFAULT_SQLITE_SCHEMA, migrations);
|
|
90
|
+
}
|
|
91
|
+
/** Apply migrations rendered for a particular schema. */
|
|
92
|
+
export async function applySqliteMigrationsForSchema(database, schema, migrations = createSqliteMigrations(schema)) {
|
|
84
93
|
for (let index = 0; index < migrations.length; index++) {
|
|
85
94
|
if (migrations[index]?.version !== index + 1) {
|
|
86
95
|
throw new Error("Durable SQLite migrations must have contiguous versions starting at 1");
|
|
87
96
|
}
|
|
88
97
|
}
|
|
98
|
+
const { durableSchema } = schema.tables;
|
|
89
99
|
await database.transaction(async (transaction) => {
|
|
90
|
-
await transaction.exec(`CREATE TABLE IF NOT EXISTS
|
|
100
|
+
await transaction.exec(`CREATE TABLE IF NOT EXISTS ${durableSchema} (
|
|
91
101
|
singleton INTEGER PRIMARY KEY CHECK (singleton = 1),
|
|
92
102
|
version INTEGER NOT NULL CHECK (version >= 0)
|
|
93
103
|
) STRICT`);
|
|
94
|
-
await transaction.run(
|
|
95
|
-
const row = await transaction.get(
|
|
104
|
+
await transaction.run(`INSERT OR IGNORE INTO ${durableSchema} (singleton, version) VALUES (1, 0)`);
|
|
105
|
+
const row = await transaction.get(`SELECT version FROM ${durableSchema} WHERE singleton = 1`);
|
|
96
106
|
if (row === undefined)
|
|
97
107
|
throw new Error("Durable SQLite schema metadata is missing");
|
|
98
108
|
const currentVersion = migrations.at(-1)?.version ?? 0;
|
|
@@ -104,7 +114,7 @@ export async function applySqliteMigrations(database, migrations = SQLITE_MIGRAT
|
|
|
104
114
|
continue;
|
|
105
115
|
for (const statement of migration.statements)
|
|
106
116
|
await transaction.exec(statement);
|
|
107
|
-
await transaction.run(
|
|
117
|
+
await transaction.run(`UPDATE ${durableSchema} SET version = ? WHERE singleton = 1`, migration.version);
|
|
108
118
|
}
|
|
109
119
|
});
|
|
110
120
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../../src/storage/sqlite/migrations.ts"],"names":[],"mappings":"AAOA,uGAAuG;AACvG,MAAM,cAAc,GAAsB;IACzC;;;;UAIS;IACT,gFAAgF;IAChF;;;UAGS;IACT;;;;;UAKS;IACT,+FAA+F;IAC/F,+EAA+E;IAC/E;;;;;;UAMS;IACT,4EAA4E;IAC5E,uGAAuG;IACvG;;;;;;;;UAQS;IACT,oDAAoD;IACpD,mEAAmE;IACnE,gDAAgD;IAChD,sEAAsE;IACtE,4DAA4D;IAC5D;;;;;;UAMS;IACT,kFAAkF;IAClF,+EAA+E;IAC/E,gEAAgE;IAChE;;;;;;;;;;UAUS;IACT;4FAC2F;IAC3F,yEAAyE;IACzE,oFAAoF;IACpF;;;;;;;UAOS;IACT,6FAA6F;CAC7F,CAAC;AAEF,+FAA+F;AAC/F,MAAM,CAAC,MAAM,iBAAiB,GAA+B,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,cAAc,EAAE,CAAC,CAAC;AAE1G,MAAM,CAAC,MAAM,6BAA6B,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,CAAC,CAAC;AAIpF,sDAAsD;AACtD,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAC1C,QAAwB,EACxB,UAAU,GAA+B,iBAAiB;IAE1D,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QACxD,IAAI,UAAU,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,KAAK,GAAG,CAAC,EAAE,CAAC;YAC9C,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAC;QAC1F,CAAC;IACF,CAAC;IAED,MAAM,QAAQ,CAAC,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE;QAChD,MAAM,WAAW,CAAC,IAAI,CAAC;;;WAGd,CAAC,CAAC;QACX,MAAM,WAAW,CAAC,GAAG,CAAC,yEAAyE,CAAC,CAAC;QACjG,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,GAAG,CAAY,wDAAwD,CAAC,CAAC;QACvG,IAAI,GAAG,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;QACpF,MAAM,cAAc,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,CAAC,CAAC;QACvD,IAAI,GAAG,CAAC,OAAO,GAAG,cAAc,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CACd,iCAAiC,GAAG,CAAC,OAAO,oCAAoC,cAAc,EAAE,CAChG,CAAC;QACH,CAAC;QACD,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACpC,IAAI,SAAS,CAAC,OAAO,IAAI,GAAG,CAAC,OAAO;gBAAE,SAAS;YAC/C,KAAK,MAAM,SAAS,IAAI,SAAS,CAAC,UAAU;gBAAE,MAAM,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAChF,MAAM,WAAW,CAAC,GAAG,CAAC,2DAA2D,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;QACvG,CAAC;IACF,CAAC,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import type { SqliteDatabase } from \"./database.ts\";\n\nexport type SqliteMigration = {\n\treadonly version: number;\n\treadonly statements: readonly string[];\n};\n\n// next_id is TEXT because node:sqlite rejects INTEGER results outside JavaScript's safe integer range.\nconst INITIAL_SCHEMA: readonly string[] = [\n\t`CREATE TABLE durable_metadata (\n\t\tsingleton INTEGER PRIMARY KEY CHECK (singleton = 1),\n\t\tnext_id TEXT NOT NULL,\n\t\tnext_seq INTEGER NOT NULL\n\t) STRICT`,\n\t`INSERT INTO durable_metadata (singleton, next_id, next_seq) VALUES (1, '2', 1)`,\n\t`CREATE TABLE record_ids (\n\t\tid INTEGER PRIMARY KEY,\n\t\trecord_type TEXT NOT NULL CHECK (record_type IN ('conversation', 'entry', 'task', 'submission', 'document'))\n\t) STRICT`,\n\t`CREATE TABLE conversations (\n\t\tid INTEGER PRIMARY KEY,\n\t\towner_conversation_id INTEGER,\n\t\towner_task_id INTEGER,\n\t\trecord TEXT NOT NULL CHECK (json_valid(record))\n\t) STRICT`,\n\t\"CREATE INDEX conversations_by_owner_conversation ON conversations (owner_conversation_id, id)\",\n\t\"CREATE INDEX conversations_by_owner_task ON conversations (owner_task_id, id)\",\n\t`CREATE TABLE entries (\n\t\tid INTEGER PRIMARY KEY,\n\t\tconversation_id INTEGER NOT NULL,\n\t\thead INTEGER,\n\t\tcommit_seq INTEGER NOT NULL,\n\t\trecord TEXT NOT NULL CHECK (json_valid(record))\n\t) STRICT`,\n\t\"CREATE INDEX entries_by_conversation ON entries (conversation_id, id DESC)\",\n\t\"CREATE INDEX entry_heads_by_conversation ON entries (conversation_id, id DESC) WHERE head IS NOT NULL\",\n\t`CREATE TABLE tasks (\n\t\tid INTEGER PRIMARY KEY,\n\t\tconversation_id INTEGER NOT NULL,\n\t\tkind TEXT NOT NULL,\n\t\tstatus TEXT NOT NULL CHECK (status IN ('pending', 'running', 'waiting', 'completing', 'terminal')),\n\t\tabort_requested INTEGER NOT NULL CHECK (abort_requested IN (0, 1)),\n\t\tbackground INTEGER NOT NULL CHECK (background IN (0, 1)),\n\t\trecord TEXT NOT NULL CHECK (json_valid(record))\n\t) STRICT`,\n\t\"CREATE INDEX tasks_by_status ON tasks (status, id)\",\n\t\"CREATE INDEX tasks_by_conversation ON tasks (conversation_id, id)\",\n\t\"CREATE INDEX tasks_by_kind ON tasks (kind, id)\",\n\t\"CREATE INDEX tasks_by_abort_requested ON tasks (abort_requested, id)\",\n\t\"CREATE INDEX tasks_by_background ON tasks (background, id)\",\n\t`CREATE TABLE submissions (\n\t\tid INTEGER PRIMARY KEY,\n\t\tconversation_id INTEGER NOT NULL,\n\t\trequest_id TEXT,\n\t\tstatus TEXT NOT NULL CHECK (status IN ('queued', 'placed', 'done', 'unanswered')),\n\t\trecord TEXT NOT NULL CHECK (json_valid(record))\n\t) STRICT`,\n\t\"CREATE INDEX submissions_by_request ON submissions (conversation_id, request_id)\",\n\t\"CREATE INDEX submissions_by_conversation ON submissions (conversation_id, id)\",\n\t\"CREATE INDEX submissions_by_status ON submissions (status, id)\",\n\t`CREATE TABLE documents (\n\t\tid INTEGER PRIMARY KEY,\n\t\tkind TEXT NOT NULL,\n\t\tfamily INTEGER NOT NULL CHECK (family IN (0, 1)),\n\t\tkey_value TEXT NOT NULL,\n\t\tscope_kind TEXT NOT NULL CHECK (scope_kind IN ('session', 'conversation', 'task')),\n\t\towner_id INTEGER NOT NULL,\n\t\tcreated_at INTEGER NOT NULL,\n\t\tretired_at INTEGER,\n\t\trecord TEXT NOT NULL CHECK (json_valid(record))\n\t) STRICT`,\n\t`CREATE INDEX documents_by_address\n\t\tON documents (kind, scope_kind, owner_id, family, key_value, created_at DESC, retired_at)`,\n\t\"CREATE INDEX documents_by_scope ON documents (scope_kind, owner_id, id)\",\n\t\"CREATE INDEX documents_by_scope_kind ON documents (scope_kind, owner_id, kind, id)\",\n\t`CREATE TABLE document_revisions (\n\t\tdocument_id INTEGER NOT NULL,\n\t\tseq INTEGER NOT NULL,\n\t\tkind TEXT NOT NULL CHECK (kind IN ('base', 'delta')),\n\t\tversion INTEGER NOT NULL,\n\t\tcontent TEXT NOT NULL CHECK (json_valid(content)),\n\t\tPRIMARY KEY (document_id, seq)\n\t) STRICT`,\n\t\"CREATE INDEX document_revisions_by_kind ON document_revisions (document_id, kind, seq DESC)\",\n];\n\n/** Immutable, ordered schema history. Append new migrations after the initial schema ships. */\nexport const SQLITE_MIGRATIONS: readonly SqliteMigration[] = [{ version: 1, statements: INITIAL_SCHEMA }];\n\nexport const CURRENT_SQLITE_SCHEMA_VERSION = SQLITE_MIGRATIONS.at(-1)?.version ?? 0;\n\ntype SchemaRow = { readonly version: number };\n\n/** Apply all pending schema migrations atomically. */\nexport async function applySqliteMigrations(\n\tdatabase: SqliteDatabase,\n\tmigrations: readonly SqliteMigration[] = SQLITE_MIGRATIONS,\n): Promise<void> {\n\tfor (let index = 0; index < migrations.length; index++) {\n\t\tif (migrations[index]?.version !== index + 1) {\n\t\t\tthrow new Error(\"Durable SQLite migrations must have contiguous versions starting at 1\");\n\t\t}\n\t}\n\n\tawait database.transaction(async (transaction) => {\n\t\tawait transaction.exec(`CREATE TABLE IF NOT EXISTS durable_schema (\n\t\t\tsingleton INTEGER PRIMARY KEY CHECK (singleton = 1),\n\t\t\tversion INTEGER NOT NULL CHECK (version >= 0)\n\t\t) STRICT`);\n\t\tawait transaction.run(\"INSERT OR IGNORE INTO durable_schema (singleton, version) VALUES (1, 0)\");\n\t\tconst row = await transaction.get<SchemaRow>(\"SELECT version FROM durable_schema WHERE singleton = 1\");\n\t\tif (row === undefined) throw new Error(\"Durable SQLite schema metadata is missing\");\n\t\tconst currentVersion = migrations.at(-1)?.version ?? 0;\n\t\tif (row.version > currentVersion) {\n\t\t\tthrow new Error(\n\t\t\t\t`Durable SQLite schema version ${row.version} is newer than supported version ${currentVersion}`,\n\t\t\t);\n\t\t}\n\t\tfor (const migration of migrations) {\n\t\t\tif (migration.version <= row.version) continue;\n\t\t\tfor (const statement of migration.statements) await transaction.exec(statement);\n\t\t\tawait transaction.run(\"UPDATE durable_schema SET version = ? WHERE singleton = 1\", migration.version);\n\t\t}\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../../src/storage/sqlite/migrations.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SqliteDatabase } from \"./database.ts\";\nimport { DEFAULT_SQLITE_SCHEMA, type SqliteSchema } from \"./schema.ts\";\n\nexport type SqliteMigration = {\n\treadonly version: number;\n\treadonly statements: readonly string[];\n};\n\n/** Build immutable, ordered schema history for a set of SQLite identifiers. */\nexport function createSqliteMigrations(schema: SqliteSchema): readonly SqliteMigration[] {\n\tconst { tables, indexes } = schema;\n\t// next_id is TEXT because node:sqlite rejects INTEGER results outside JavaScript's safe integer range.\n\tconst initialSchema: readonly string[] = [\n\t\t`CREATE TABLE ${tables.durableMetadata} (\n\t\t\tsingleton INTEGER PRIMARY KEY CHECK (singleton = 1),\n\t\t\tnext_id TEXT NOT NULL,\n\t\t\tnext_seq INTEGER NOT NULL\n\t\t) STRICT`,\n\t\t`INSERT INTO ${tables.durableMetadata} (singleton, next_id, next_seq) VALUES (1, '2', 1)`,\n\t\t`CREATE TABLE ${tables.recordIds} (\n\t\t\tid INTEGER PRIMARY KEY,\n\t\t\trecord_type TEXT NOT NULL CHECK (record_type IN ('conversation', 'entry', 'task', 'submission', 'document'))\n\t\t) STRICT`,\n\t\t`CREATE TABLE ${tables.conversations} (\n\t\t\tid INTEGER PRIMARY KEY,\n\t\t\towner_conversation_id INTEGER,\n\t\t\towner_task_id INTEGER,\n\t\t\trecord TEXT NOT NULL CHECK (json_valid(record))\n\t\t) STRICT`,\n\t\t`CREATE INDEX ${indexes.conversationsByOwnerConversation} ON ${tables.conversations} (owner_conversation_id, id)`,\n\t\t`CREATE INDEX ${indexes.conversationsByOwnerTask} ON ${tables.conversations} (owner_task_id, id)`,\n\t\t`CREATE TABLE ${tables.entries} (\n\t\t\tid INTEGER PRIMARY KEY,\n\t\t\tconversation_id INTEGER NOT NULL,\n\t\t\thead INTEGER,\n\t\t\tcommit_seq INTEGER NOT NULL,\n\t\t\trecord TEXT NOT NULL CHECK (json_valid(record))\n\t\t) STRICT`,\n\t\t`CREATE INDEX ${indexes.entriesByConversation} ON ${tables.entries} (conversation_id, id DESC)`,\n\t\t`CREATE INDEX ${indexes.entryHeadsByConversation} ON ${tables.entries} (conversation_id, id DESC) WHERE head IS NOT NULL`,\n\t\t`CREATE TABLE ${tables.tasks} (\n\t\t\tid INTEGER PRIMARY KEY,\n\t\t\tconversation_id INTEGER NOT NULL,\n\t\t\tkind TEXT NOT NULL,\n\t\t\tstatus TEXT NOT NULL CHECK (status IN ('pending', 'running', 'waiting', 'completing', 'terminal')),\n\t\t\tabort_requested INTEGER NOT NULL CHECK (abort_requested IN (0, 1)),\n\t\t\tbackground INTEGER NOT NULL CHECK (background IN (0, 1)),\n\t\t\trecord TEXT NOT NULL CHECK (json_valid(record))\n\t\t) STRICT`,\n\t\t`CREATE INDEX ${indexes.tasksByStatus} ON ${tables.tasks} (status, id)`,\n\t\t`CREATE INDEX ${indexes.tasksByConversation} ON ${tables.tasks} (conversation_id, id)`,\n\t\t`CREATE INDEX ${indexes.tasksByKind} ON ${tables.tasks} (kind, id)`,\n\t\t`CREATE INDEX ${indexes.tasksByAbortRequested} ON ${tables.tasks} (abort_requested, id)`,\n\t\t`CREATE INDEX ${indexes.tasksByBackground} ON ${tables.tasks} (background, id)`,\n\t\t`CREATE TABLE ${tables.submissions} (\n\t\t\tid INTEGER PRIMARY KEY,\n\t\t\tconversation_id INTEGER NOT NULL,\n\t\t\trequest_id TEXT,\n\t\t\tstatus TEXT NOT NULL CHECK (status IN ('queued', 'placed', 'done', 'unanswered')),\n\t\t\trecord TEXT NOT NULL CHECK (json_valid(record))\n\t\t) STRICT`,\n\t\t`CREATE INDEX ${indexes.submissionsByRequest} ON ${tables.submissions} (conversation_id, request_id)`,\n\t\t`CREATE INDEX ${indexes.submissionsByConversation} ON ${tables.submissions} (conversation_id, id)`,\n\t\t`CREATE INDEX ${indexes.submissionsByStatus} ON ${tables.submissions} (status, id)`,\n\t\t`CREATE TABLE ${tables.documents} (\n\t\t\tid INTEGER PRIMARY KEY,\n\t\t\tkind TEXT NOT NULL,\n\t\t\tfamily INTEGER NOT NULL CHECK (family IN (0, 1)),\n\t\t\tkey_value TEXT NOT NULL,\n\t\t\tscope_kind TEXT NOT NULL CHECK (scope_kind IN ('session', 'conversation', 'task')),\n\t\t\towner_id INTEGER NOT NULL,\n\t\t\tcreated_at INTEGER NOT NULL,\n\t\t\tretired_at INTEGER,\n\t\t\trecord TEXT NOT NULL CHECK (json_valid(record))\n\t\t) STRICT`,\n\t\t`CREATE INDEX ${indexes.documentsByAddress}\n\t\t\tON ${tables.documents} (kind, scope_kind, owner_id, family, key_value, created_at DESC, retired_at)`,\n\t\t`CREATE INDEX ${indexes.documentsByScope} ON ${tables.documents} (scope_kind, owner_id, id)`,\n\t\t`CREATE INDEX ${indexes.documentsByScopeKind} ON ${tables.documents} (scope_kind, owner_id, kind, id)`,\n\t\t`CREATE TABLE ${tables.documentRevisions} (\n\t\t\tdocument_id INTEGER NOT NULL,\n\t\t\tseq INTEGER NOT NULL,\n\t\t\tkind TEXT NOT NULL CHECK (kind IN ('base', 'delta')),\n\t\t\tversion INTEGER NOT NULL,\n\t\t\tcontent TEXT NOT NULL CHECK (json_valid(content)),\n\t\t\tPRIMARY KEY (document_id, seq)\n\t\t) STRICT`,\n\t\t`CREATE INDEX ${indexes.documentRevisionsByKind} ON ${tables.documentRevisions} (document_id, kind, seq DESC)`,\n\t];\n\treturn [{ version: 1, statements: initialSchema }];\n}\n\nexport const SQLITE_MIGRATIONS: readonly SqliteMigration[] = createSqliteMigrations(DEFAULT_SQLITE_SCHEMA);\n\nexport const CURRENT_SQLITE_SCHEMA_VERSION = SQLITE_MIGRATIONS.at(-1)?.version ?? 0;\n\ntype SchemaRow = { readonly version: number };\n\n/** Apply all pending schema migrations atomically. */\nexport async function applySqliteMigrations(\n\tdatabase: SqliteDatabase,\n\tmigrations: readonly SqliteMigration[] = SQLITE_MIGRATIONS,\n): Promise<void> {\n\tawait applySqliteMigrationsForSchema(database, DEFAULT_SQLITE_SCHEMA, migrations);\n}\n\n/** Apply migrations rendered for a particular schema. */\nexport async function applySqliteMigrationsForSchema(\n\tdatabase: SqliteDatabase,\n\tschema: SqliteSchema,\n\tmigrations: readonly SqliteMigration[] = createSqliteMigrations(schema),\n): Promise<void> {\n\tfor (let index = 0; index < migrations.length; index++) {\n\t\tif (migrations[index]?.version !== index + 1) {\n\t\t\tthrow new Error(\"Durable SQLite migrations must have contiguous versions starting at 1\");\n\t\t}\n\t}\n\n\tconst { durableSchema } = schema.tables;\n\tawait database.transaction(async (transaction) => {\n\t\tawait transaction.exec(`CREATE TABLE IF NOT EXISTS ${durableSchema} (\n\t\t\tsingleton INTEGER PRIMARY KEY CHECK (singleton = 1),\n\t\t\tversion INTEGER NOT NULL CHECK (version >= 0)\n\t\t) STRICT`);\n\t\tawait transaction.run(`INSERT OR IGNORE INTO ${durableSchema} (singleton, version) VALUES (1, 0)`);\n\t\tconst row = await transaction.get<SchemaRow>(`SELECT version FROM ${durableSchema} WHERE singleton = 1`);\n\t\tif (row === undefined) throw new Error(\"Durable SQLite schema metadata is missing\");\n\t\tconst currentVersion = migrations.at(-1)?.version ?? 0;\n\t\tif (row.version > currentVersion) {\n\t\t\tthrow new Error(\n\t\t\t\t`Durable SQLite schema version ${row.version} is newer than supported version ${currentVersion}`,\n\t\t\t);\n\t\t}\n\t\tfor (const migration of migrations) {\n\t\t\tif (migration.version <= row.version) continue;\n\t\t\tfor (const statement of migration.statements) await transaction.exec(statement);\n\t\t\tawait transaction.run(`UPDATE ${durableSchema} SET version = ? WHERE singleton = 1`, migration.version);\n\t\t}\n\t});\n}\n"]}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import type { StatementSync } from "node:sqlite";
|
|
2
2
|
import { DatabaseSync } from "node:sqlite";
|
|
3
3
|
import type { SqliteDatabase, SqliteExecutor, SqliteValue } from "./database.ts";
|
|
4
|
-
import { SqliteStorage } from "./storage.ts";
|
|
4
|
+
import { SqliteStorage, type SqliteStorageOptions } from "./storage.ts";
|
|
5
5
|
/** Node SQLite connection settings for a durable storage file. */
|
|
6
|
-
export type
|
|
6
|
+
export type NodeSqliteDatabaseOptions = {
|
|
7
7
|
/** SQLite WAL auto-checkpoint threshold. SQLite and this adapter default to 1,000 pages; 0 disables it. */
|
|
8
8
|
readonly walAutoCheckpointPages?: number;
|
|
9
9
|
/** Time SQLite waits for a competing file lock. SQLite defaults to 0; this adapter defaults to 5,000 ms. */
|
|
10
10
|
readonly busyTimeoutMs?: number;
|
|
11
11
|
};
|
|
12
|
+
/** Node SQLite connection settings plus durable storage options. */
|
|
13
|
+
export type NodeSqliteStorageOptions = NodeSqliteDatabaseOptions & SqliteStorageOptions;
|
|
12
14
|
/**
|
|
13
15
|
* Executes SQL on one connection. Prepared statements are cached per connection by SQL text, so the
|
|
14
16
|
* database and its transaction handles share them across transactions.
|
|
@@ -34,8 +36,8 @@ export declare class NodeSqliteDatabase extends NodeSqliteExecutor implements Sq
|
|
|
34
36
|
protected runOperation<T>(operation: () => T): Promise<T>;
|
|
35
37
|
}
|
|
36
38
|
/** Open and configure a Node-backed SQLite database facade. */
|
|
37
|
-
export declare function openNodeSqliteDatabase(path: string, options?:
|
|
38
|
-
/** Open or create file-backed durable storage using Node's built-in SQLite. */
|
|
39
|
+
export declare function openNodeSqliteDatabase(path: string, options?: NodeSqliteDatabaseOptions): Promise<NodeSqliteDatabase>;
|
|
40
|
+
/** Open or create file-backed durable storage using Node's built-in SQLite, optionally under a table prefix. */
|
|
39
41
|
export declare function openNodeSqliteStorage(path: string, options?: NodeSqliteStorageOptions): Promise<SqliteStorage>;
|
|
40
42
|
export {};
|
|
41
43
|
//# sourceMappingURL=node.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../src/storage/sqlite/node.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../src/storage/sqlite/node.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjF,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAExE,kEAAkE;AAClE,MAAM,MAAM,yBAAyB,GAAG;IACvC,2GAA2G;IAC3G,QAAQ,CAAC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IACzC,4GAA4G;IAC5G,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CAChC,CAAC;AAEF,oEAAoE;AACpE,MAAM,MAAM,wBAAwB,GAAG,yBAAyB,GAAG,oBAAoB,CAAC;AA0DxF;;;GAGG;AACH,uBAAe,kBAAmB,YAAW,cAAc;IAC1D,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAC1C,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAE1D,YAAY,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,EAGzE;IAED,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI/B;IAED,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAIxD;IAED,GAAG,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAEnF;IAED,GAAG,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAEzE;IAED,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAEnE,OAAO,CAAC,SAAS;CAQjB;AAgBD,wEAAwE;AACxE,qBAAa,kBAAmB,SAAQ,kBAAmB,YAAW,cAAc;IACnF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA8B;IACrD,OAAO,CAAC,MAAM,CAAS;IAEvB,YAAY,QAAQ,EAAE,YAAY,EAEjC;IAED,WAAW,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,WAAW,EAAE,cAAc,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAmBhF;IAED,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAWrB;IAED,SAAS,CAAC,YAAY,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAExD;CACD;AAED,+DAA+D;AAC/D,wBAAsB,sBAAsB,CAC3C,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,yBAA8B,GACrC,OAAO,CAAC,kBAAkB,CAAC,CAmB7B;AAED,gHAAgH;AAChH,wBAAsB,qBAAqB,CAC1C,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,wBAA6B,GACpC,OAAO,CAAC,aAAa,CAAC,CAIxB"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { mkdir } from "node:fs/promises";
|
|
2
2
|
import { dirname } from "node:path";
|
|
3
3
|
import { DatabaseSync } from "node:sqlite";
|
|
4
|
+
import { validateSqliteSchemaPrefix } from "./schema.js";
|
|
4
5
|
import { SqliteStorage } from "./storage.js";
|
|
5
6
|
const DEFAULT_WAL_AUTO_CHECKPOINT_PAGES = 1_000;
|
|
6
7
|
const DEFAULT_BUSY_TIMEOUT_MS = 5_000;
|
|
@@ -172,8 +173,11 @@ export async function openNodeSqliteDatabase(path, options = {}) {
|
|
|
172
173
|
throw error;
|
|
173
174
|
}
|
|
174
175
|
}
|
|
175
|
-
/** Open or create file-backed durable storage using Node's built-in SQLite. */
|
|
176
|
+
/** Open or create file-backed durable storage using Node's built-in SQLite, optionally under a table prefix. */
|
|
176
177
|
export async function openNodeSqliteStorage(path, options = {}) {
|
|
177
|
-
|
|
178
|
+
const { prefix, ...databaseOptions } = options;
|
|
179
|
+
if (prefix !== undefined)
|
|
180
|
+
validateSqliteSchemaPrefix(prefix);
|
|
181
|
+
return SqliteStorage.open(await openNodeSqliteDatabase(path, databaseOptions), { prefix });
|
|
178
182
|
}
|
|
179
183
|
//# sourceMappingURL=node.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.js","sourceRoot":"","sources":["../../../src/storage/sqlite/node.ts"],"names":[],"mappings":"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","sourcesContent":["import { mkdir } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport type { StatementSync } from \"node:sqlite\";\nimport { DatabaseSync } from \"node:sqlite\";\nimport type { SqliteDatabase, SqliteExecutor, SqliteValue } from \"./database.ts\";\nimport { SqliteStorage } from \"./storage.ts\";\n\n/** Node SQLite connection settings for a durable storage file. */\nexport type NodeSqliteStorageOptions = {\n\t/** SQLite WAL auto-checkpoint threshold. SQLite and this adapter default to 1,000 pages; 0 disables it. */\n\treadonly walAutoCheckpointPages?: number;\n\t/** Time SQLite waits for a competing file lock. SQLite defaults to 0; this adapter defaults to 5,000 ms. */\n\treadonly busyTimeoutMs?: number;\n};\n\nconst DEFAULT_WAL_AUTO_CHECKPOINT_PAGES = 1_000;\nconst DEFAULT_BUSY_TIMEOUT_MS = 5_000;\n\ntype TransactionScope = { active: boolean };\n\nconst ignore = (): void => {};\n\n/**\n * Runs operations in call order. An operation starts immediately when nothing is running or waiting;\n * otherwise it waits for everything before it. An asynchronous operation holds the queue until it settles.\n */\nclass SerialOperationQueue {\n\tprivate tail: Promise<void> = Promise.resolve();\n\tprivate pending = 0;\n\n\trun<T>(operation: () => T): Promise<T> {\n\t\tif (this.pending > 0) return this.enqueue(operation);\n\t\ttry {\n\t\t\treturn Promise.resolve(operation());\n\t\t} catch (error) {\n\t\t\treturn Promise.reject(error);\n\t\t}\n\t}\n\n\trunAsync<T>(operation: () => Promise<T>): Promise<T> {\n\t\tif (this.pending > 0) return this.enqueue(operation);\n\t\tthis.pending++;\n\t\t// Publish the barrier before the operation starts, so calls it makes synchronously wait behind it.\n\t\tconst { promise: barrier, resolve: releaseBarrier } = Promise.withResolvers<void>();\n\t\tthis.tail = barrier;\n\t\tlet started: Promise<T>;\n\t\ttry {\n\t\t\tstarted = operation();\n\t\t} catch (error) {\n\t\t\tstarted = Promise.reject(error);\n\t\t}\n\t\treturn started.finally(() => {\n\t\t\tthis.pending--;\n\t\t\treleaseBarrier();\n\t\t});\n\t}\n\n\tprivate enqueue<T>(operation: () => T | Promise<T>): Promise<T> {\n\t\tthis.pending++;\n\t\treturn this.release(this.tail.then(operation));\n\t}\n\n\tprivate release<T>(operation: Promise<T>): Promise<T> {\n\t\tconst settled = operation.finally(() => {\n\t\t\tthis.pending--;\n\t\t});\n\t\tthis.tail = settled.then(ignore, ignore);\n\t\treturn settled;\n\t}\n}\n\n/**\n * Executes SQL on one connection. Prepared statements are cached per connection by SQL text, so the\n * database and its transaction handles share them across transactions.\n */\nabstract class NodeSqliteExecutor implements SqliteExecutor {\n\tprotected readonly database: DatabaseSync;\n\tprotected readonly statements: Map<string, StatementSync>;\n\n\tconstructor(database: DatabaseSync, statements: Map<string, StatementSync>) {\n\t\tthis.database = database;\n\t\tthis.statements = statements;\n\t}\n\n\texec(sql: string): Promise<void> {\n\t\treturn this.runOperation(() => {\n\t\t\tthis.database.exec(sql);\n\t\t});\n\t}\n\n\trun(sql: string, ...params: SqliteValue[]): Promise<void> {\n\t\treturn this.runOperation(() => {\n\t\t\tthis.statement(sql).run(...params);\n\t\t});\n\t}\n\n\tget<T extends object>(sql: string, ...params: SqliteValue[]): Promise<T | undefined> {\n\t\treturn this.runOperation(() => this.statement(sql).get(...params) as T | undefined);\n\t}\n\n\tall<T extends object>(sql: string, ...params: SqliteValue[]): Promise<T[]> {\n\t\treturn this.runOperation(() => this.statement(sql).all(...params) as T[]);\n\t}\n\n\tprotected abstract runOperation<T>(operation: () => T): Promise<T>;\n\n\tprivate statement(sql: string): StatementSync {\n\t\tlet statement = this.statements.get(sql);\n\t\tif (statement === undefined) {\n\t\t\tstatement = this.database.prepare(sql);\n\t\t\tthis.statements.set(sql, statement);\n\t\t}\n\t\treturn statement;\n\t}\n}\n\nclass NodeSqliteTransaction extends NodeSqliteExecutor {\n\tprivate readonly scope: TransactionScope;\n\n\tconstructor(database: DatabaseSync, statements: Map<string, StatementSync>, scope: TransactionScope) {\n\t\tsuper(database, statements);\n\t\tthis.scope = scope;\n\t}\n\n\tprotected async runOperation<T>(operation: () => T): Promise<T> {\n\t\tif (!this.scope.active) throw new Error(\"SQLite transaction handle is no longer active\");\n\t\treturn operation();\n\t}\n}\n\n/** `SqliteDatabase` adapter backed by Node's built-in `node:sqlite`. */\nexport class NodeSqliteDatabase extends NodeSqliteExecutor implements SqliteDatabase {\n\tprivate readonly access = new SerialOperationQueue();\n\tprivate closed = false;\n\n\tconstructor(database: DatabaseSync) {\n\t\tsuper(database, new Map());\n\t}\n\n\ttransaction<T>(callback: (transaction: SqliteExecutor) => Promise<T>): Promise<T> {\n\t\treturn this.access.runAsync(async () => {\n\t\t\tthis.database.exec(\"BEGIN IMMEDIATE\");\n\t\t\tconst scope = { active: true };\n\t\t\ttry {\n\t\t\t\tconst result = await callback(new NodeSqliteTransaction(this.database, this.statements, scope));\n\t\t\t\tscope.active = false;\n\t\t\t\tthis.database.exec(\"COMMIT\");\n\t\t\t\treturn result;\n\t\t\t} catch (error) {\n\t\t\t\tscope.active = false;\n\t\t\t\ttry {\n\t\t\t\t\tthis.database.exec(\"ROLLBACK\");\n\t\t\t\t} catch (rollbackError) {\n\t\t\t\t\tthrow new AggregateError([error, rollbackError], \"SQLite transaction failed and rollback failed\");\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t});\n\t}\n\n\tclose(): Promise<void> {\n\t\treturn this.access.run(() => {\n\t\t\tif (this.closed) return;\n\t\t\tthis.closed = true;\n\t\t\tthis.statements.clear();\n\t\t\ttry {\n\t\t\t\tthis.database.exec(\"PRAGMA wal_checkpoint(TRUNCATE)\");\n\t\t\t} finally {\n\t\t\t\tthis.database.close();\n\t\t\t}\n\t\t});\n\t}\n\n\tprotected runOperation<T>(operation: () => T): Promise<T> {\n\t\treturn this.access.run(operation);\n\t}\n}\n\n/** Open and configure a Node-backed SQLite database facade. */\nexport async function openNodeSqliteDatabase(\n\tpath: string,\n\toptions: NodeSqliteStorageOptions = {},\n): Promise<NodeSqliteDatabase> {\n\tconst checkpointPages = options.walAutoCheckpointPages ?? DEFAULT_WAL_AUTO_CHECKPOINT_PAGES;\n\tconst timeout = options.busyTimeoutMs ?? DEFAULT_BUSY_TIMEOUT_MS;\n\tif (path !== \":memory:\") await mkdir(dirname(path), { recursive: true });\n\tconst database = new DatabaseSync(path, { timeout });\n\tconst adapter = new NodeSqliteDatabase(database);\n\ttry {\n\t\tawait adapter.exec(\"PRAGMA journal_mode = WAL\");\n\t\tawait adapter.exec(\"PRAGMA synchronous = NORMAL\");\n\t\tawait adapter.exec(`PRAGMA wal_autocheckpoint = ${checkpointPages}`);\n\t\treturn adapter;\n\t} catch (error) {\n\t\ttry {\n\t\t\tawait adapter.close();\n\t\t} catch {\n\t\t\t// Preserve the configuration failure.\n\t\t}\n\t\tthrow error;\n\t}\n}\n\n/** Open or create file-backed durable storage using Node's built-in SQLite. */\nexport async function openNodeSqliteStorage(\n\tpath: string,\n\toptions: NodeSqliteStorageOptions = {},\n): Promise<SqliteStorage> {\n\treturn SqliteStorage.open(await openNodeSqliteDatabase(path, options));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"node.js","sourceRoot":"","sources":["../../../src/storage/sqlite/node.ts"],"names":[],"mappings":"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","sourcesContent":["import { mkdir } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport type { StatementSync } from \"node:sqlite\";\nimport { DatabaseSync } from \"node:sqlite\";\nimport type { SqliteDatabase, SqliteExecutor, SqliteValue } from \"./database.ts\";\nimport { validateSqliteSchemaPrefix } from \"./schema.ts\";\nimport { SqliteStorage, type SqliteStorageOptions } from \"./storage.ts\";\n\n/** Node SQLite connection settings for a durable storage file. */\nexport type NodeSqliteDatabaseOptions = {\n\t/** SQLite WAL auto-checkpoint threshold. SQLite and this adapter default to 1,000 pages; 0 disables it. */\n\treadonly walAutoCheckpointPages?: number;\n\t/** Time SQLite waits for a competing file lock. SQLite defaults to 0; this adapter defaults to 5,000 ms. */\n\treadonly busyTimeoutMs?: number;\n};\n\n/** Node SQLite connection settings plus durable storage options. */\nexport type NodeSqliteStorageOptions = NodeSqliteDatabaseOptions & SqliteStorageOptions;\n\nconst DEFAULT_WAL_AUTO_CHECKPOINT_PAGES = 1_000;\nconst DEFAULT_BUSY_TIMEOUT_MS = 5_000;\n\ntype TransactionScope = { active: boolean };\n\nconst ignore = (): void => {};\n\n/**\n * Runs operations in call order. An operation starts immediately when nothing is running or waiting;\n * otherwise it waits for everything before it. An asynchronous operation holds the queue until it settles.\n */\nclass SerialOperationQueue {\n\tprivate tail: Promise<void> = Promise.resolve();\n\tprivate pending = 0;\n\n\trun<T>(operation: () => T): Promise<T> {\n\t\tif (this.pending > 0) return this.enqueue(operation);\n\t\ttry {\n\t\t\treturn Promise.resolve(operation());\n\t\t} catch (error) {\n\t\t\treturn Promise.reject(error);\n\t\t}\n\t}\n\n\trunAsync<T>(operation: () => Promise<T>): Promise<T> {\n\t\tif (this.pending > 0) return this.enqueue(operation);\n\t\tthis.pending++;\n\t\t// Publish the barrier before the operation starts, so calls it makes synchronously wait behind it.\n\t\tconst { promise: barrier, resolve: releaseBarrier } = Promise.withResolvers<void>();\n\t\tthis.tail = barrier;\n\t\tlet started: Promise<T>;\n\t\ttry {\n\t\t\tstarted = operation();\n\t\t} catch (error) {\n\t\t\tstarted = Promise.reject(error);\n\t\t}\n\t\treturn started.finally(() => {\n\t\t\tthis.pending--;\n\t\t\treleaseBarrier();\n\t\t});\n\t}\n\n\tprivate enqueue<T>(operation: () => T | Promise<T>): Promise<T> {\n\t\tthis.pending++;\n\t\treturn this.release(this.tail.then(operation));\n\t}\n\n\tprivate release<T>(operation: Promise<T>): Promise<T> {\n\t\tconst settled = operation.finally(() => {\n\t\t\tthis.pending--;\n\t\t});\n\t\tthis.tail = settled.then(ignore, ignore);\n\t\treturn settled;\n\t}\n}\n\n/**\n * Executes SQL on one connection. Prepared statements are cached per connection by SQL text, so the\n * database and its transaction handles share them across transactions.\n */\nabstract class NodeSqliteExecutor implements SqliteExecutor {\n\tprotected readonly database: DatabaseSync;\n\tprotected readonly statements: Map<string, StatementSync>;\n\n\tconstructor(database: DatabaseSync, statements: Map<string, StatementSync>) {\n\t\tthis.database = database;\n\t\tthis.statements = statements;\n\t}\n\n\texec(sql: string): Promise<void> {\n\t\treturn this.runOperation(() => {\n\t\t\tthis.database.exec(sql);\n\t\t});\n\t}\n\n\trun(sql: string, ...params: SqliteValue[]): Promise<void> {\n\t\treturn this.runOperation(() => {\n\t\t\tthis.statement(sql).run(...params);\n\t\t});\n\t}\n\n\tget<T extends object>(sql: string, ...params: SqliteValue[]): Promise<T | undefined> {\n\t\treturn this.runOperation(() => this.statement(sql).get(...params) as T | undefined);\n\t}\n\n\tall<T extends object>(sql: string, ...params: SqliteValue[]): Promise<T[]> {\n\t\treturn this.runOperation(() => this.statement(sql).all(...params) as T[]);\n\t}\n\n\tprotected abstract runOperation<T>(operation: () => T): Promise<T>;\n\n\tprivate statement(sql: string): StatementSync {\n\t\tlet statement = this.statements.get(sql);\n\t\tif (statement === undefined) {\n\t\t\tstatement = this.database.prepare(sql);\n\t\t\tthis.statements.set(sql, statement);\n\t\t}\n\t\treturn statement;\n\t}\n}\n\nclass NodeSqliteTransaction extends NodeSqliteExecutor {\n\tprivate readonly scope: TransactionScope;\n\n\tconstructor(database: DatabaseSync, statements: Map<string, StatementSync>, scope: TransactionScope) {\n\t\tsuper(database, statements);\n\t\tthis.scope = scope;\n\t}\n\n\tprotected async runOperation<T>(operation: () => T): Promise<T> {\n\t\tif (!this.scope.active) throw new Error(\"SQLite transaction handle is no longer active\");\n\t\treturn operation();\n\t}\n}\n\n/** `SqliteDatabase` adapter backed by Node's built-in `node:sqlite`. */\nexport class NodeSqliteDatabase extends NodeSqliteExecutor implements SqliteDatabase {\n\tprivate readonly access = new SerialOperationQueue();\n\tprivate closed = false;\n\n\tconstructor(database: DatabaseSync) {\n\t\tsuper(database, new Map());\n\t}\n\n\ttransaction<T>(callback: (transaction: SqliteExecutor) => Promise<T>): Promise<T> {\n\t\treturn this.access.runAsync(async () => {\n\t\t\tthis.database.exec(\"BEGIN IMMEDIATE\");\n\t\t\tconst scope = { active: true };\n\t\t\ttry {\n\t\t\t\tconst result = await callback(new NodeSqliteTransaction(this.database, this.statements, scope));\n\t\t\t\tscope.active = false;\n\t\t\t\tthis.database.exec(\"COMMIT\");\n\t\t\t\treturn result;\n\t\t\t} catch (error) {\n\t\t\t\tscope.active = false;\n\t\t\t\ttry {\n\t\t\t\t\tthis.database.exec(\"ROLLBACK\");\n\t\t\t\t} catch (rollbackError) {\n\t\t\t\t\tthrow new AggregateError([error, rollbackError], \"SQLite transaction failed and rollback failed\");\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t});\n\t}\n\n\tclose(): Promise<void> {\n\t\treturn this.access.run(() => {\n\t\t\tif (this.closed) return;\n\t\t\tthis.closed = true;\n\t\t\tthis.statements.clear();\n\t\t\ttry {\n\t\t\t\tthis.database.exec(\"PRAGMA wal_checkpoint(TRUNCATE)\");\n\t\t\t} finally {\n\t\t\t\tthis.database.close();\n\t\t\t}\n\t\t});\n\t}\n\n\tprotected runOperation<T>(operation: () => T): Promise<T> {\n\t\treturn this.access.run(operation);\n\t}\n}\n\n/** Open and configure a Node-backed SQLite database facade. */\nexport async function openNodeSqliteDatabase(\n\tpath: string,\n\toptions: NodeSqliteDatabaseOptions = {},\n): Promise<NodeSqliteDatabase> {\n\tconst checkpointPages = options.walAutoCheckpointPages ?? DEFAULT_WAL_AUTO_CHECKPOINT_PAGES;\n\tconst timeout = options.busyTimeoutMs ?? DEFAULT_BUSY_TIMEOUT_MS;\n\tif (path !== \":memory:\") await mkdir(dirname(path), { recursive: true });\n\tconst database = new DatabaseSync(path, { timeout });\n\tconst adapter = new NodeSqliteDatabase(database);\n\ttry {\n\t\tawait adapter.exec(\"PRAGMA journal_mode = WAL\");\n\t\tawait adapter.exec(\"PRAGMA synchronous = NORMAL\");\n\t\tawait adapter.exec(`PRAGMA wal_autocheckpoint = ${checkpointPages}`);\n\t\treturn adapter;\n\t} catch (error) {\n\t\ttry {\n\t\t\tawait adapter.close();\n\t\t} catch {\n\t\t\t// Preserve the configuration failure.\n\t\t}\n\t\tthrow error;\n\t}\n}\n\n/** Open or create file-backed durable storage using Node's built-in SQLite, optionally under a table prefix. */\nexport async function openNodeSqliteStorage(\n\tpath: string,\n\toptions: NodeSqliteStorageOptions = {},\n): Promise<SqliteStorage> {\n\tconst { prefix, ...databaseOptions } = options;\n\tif (prefix !== undefined) validateSqliteSchemaPrefix(prefix);\n\treturn SqliteStorage.open(await openNodeSqliteDatabase(path, databaseOptions), { prefix });\n}\n"]}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Immutable identifier history for migrations and runtime queries. Never change or remove an existing value; a
|
|
3
|
+
* rename adds a new entry so historical migrations keep rendering their original object names.
|
|
4
|
+
*/
|
|
5
|
+
declare const TABLE_NAMES: {
|
|
6
|
+
readonly durableSchema: "durable_schema";
|
|
7
|
+
readonly durableMetadata: "durable_metadata";
|
|
8
|
+
readonly recordIds: "record_ids";
|
|
9
|
+
readonly conversations: "conversations";
|
|
10
|
+
readonly entries: "entries";
|
|
11
|
+
readonly tasks: "tasks";
|
|
12
|
+
readonly submissions: "submissions";
|
|
13
|
+
readonly documents: "documents";
|
|
14
|
+
readonly documentRevisions: "document_revisions";
|
|
15
|
+
};
|
|
16
|
+
declare const INDEX_NAMES: {
|
|
17
|
+
readonly conversationsByOwnerConversation: "conversations_by_owner_conversation";
|
|
18
|
+
readonly conversationsByOwnerTask: "conversations_by_owner_task";
|
|
19
|
+
readonly entriesByConversation: "entries_by_conversation";
|
|
20
|
+
readonly entryHeadsByConversation: "entry_heads_by_conversation";
|
|
21
|
+
readonly tasksByStatus: "tasks_by_status";
|
|
22
|
+
readonly tasksByConversation: "tasks_by_conversation";
|
|
23
|
+
readonly tasksByKind: "tasks_by_kind";
|
|
24
|
+
readonly tasksByAbortRequested: "tasks_by_abort_requested";
|
|
25
|
+
readonly tasksByBackground: "tasks_by_background";
|
|
26
|
+
readonly submissionsByRequest: "submissions_by_request";
|
|
27
|
+
readonly submissionsByConversation: "submissions_by_conversation";
|
|
28
|
+
readonly submissionsByStatus: "submissions_by_status";
|
|
29
|
+
readonly documentsByAddress: "documents_by_address";
|
|
30
|
+
readonly documentsByScope: "documents_by_scope";
|
|
31
|
+
readonly documentsByScopeKind: "documents_by_scope_kind";
|
|
32
|
+
readonly documentRevisionsByKind: "document_revisions_by_kind";
|
|
33
|
+
};
|
|
34
|
+
type SqliteIdentifiers<T extends Record<string, string>> = {
|
|
35
|
+
readonly [K in keyof T]: string;
|
|
36
|
+
};
|
|
37
|
+
export type SqliteSchema = {
|
|
38
|
+
readonly tables: SqliteIdentifiers<typeof TABLE_NAMES>;
|
|
39
|
+
readonly indexes: SqliteIdentifiers<typeof INDEX_NAMES>;
|
|
40
|
+
};
|
|
41
|
+
/** Validate a prefix before using it as part of a SQLite identifier. */
|
|
42
|
+
export declare function validateSqliteSchemaPrefix(prefix: string): void;
|
|
43
|
+
/** Build the identifiers used by every migration and storage query. */
|
|
44
|
+
export declare function createSqliteSchema(prefix?: string): SqliteSchema;
|
|
45
|
+
export declare const DEFAULT_SQLITE_SCHEMA: SqliteSchema;
|
|
46
|
+
export {};
|
|
47
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/storage/sqlite/schema.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,QAAA,MAAM,WAAW;aAChB,aAAa,EAAE,gBAAgB;aAC/B,eAAe,EAAE,kBAAkB;aACnC,SAAS,EAAE,YAAY;aACvB,aAAa,EAAE,eAAe;aAC9B,OAAO,EAAE,SAAS;aAClB,KAAK,EAAE,OAAO;aACd,WAAW,EAAE,aAAa;aAC1B,SAAS,EAAE,WAAW;aACtB,iBAAiB,EAAE,oBAAoB;CAC9B,CAAC;AAEX,QAAA,MAAM,WAAW;aAChB,gCAAgC,EAAE,qCAAqC;aACvE,wBAAwB,EAAE,6BAA6B;aACvD,qBAAqB,EAAE,yBAAyB;aAChD,wBAAwB,EAAE,6BAA6B;aACvD,aAAa,EAAE,iBAAiB;aAChC,mBAAmB,EAAE,uBAAuB;aAC5C,WAAW,EAAE,eAAe;aAC5B,qBAAqB,EAAE,0BAA0B;aACjD,iBAAiB,EAAE,qBAAqB;aACxC,oBAAoB,EAAE,wBAAwB;aAC9C,yBAAyB,EAAE,6BAA6B;aACxD,mBAAmB,EAAE,uBAAuB;aAC5C,kBAAkB,EAAE,sBAAsB;aAC1C,gBAAgB,EAAE,oBAAoB;aACtC,oBAAoB,EAAE,yBAAyB;aAC/C,uBAAuB,EAAE,4BAA4B;CAC5C,CAAC;AAEX,KAAK,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI;IAAE,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM;CAAE,CAAC;AAE/F,MAAM,MAAM,YAAY,GAAG;IAC1B,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC,OAAO,WAAW,CAAC,CAAC;IACvD,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC,OAAO,WAAW,CAAC,CAAC;CACxD,CAAC;AAEF,wEAAwE;AACxE,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAO/D;AAQD,uEAAuE;AACvE,wBAAgB,kBAAkB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,YAAY,CAOhE;AAED,eAAO,MAAM,qBAAqB,cAAuB,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Immutable identifier history for migrations and runtime queries. Never change or remove an existing value; a
|
|
3
|
+
* rename adds a new entry so historical migrations keep rendering their original object names.
|
|
4
|
+
*/
|
|
5
|
+
const TABLE_NAMES = {
|
|
6
|
+
durableSchema: "durable_schema",
|
|
7
|
+
durableMetadata: "durable_metadata",
|
|
8
|
+
recordIds: "record_ids",
|
|
9
|
+
conversations: "conversations",
|
|
10
|
+
entries: "entries",
|
|
11
|
+
tasks: "tasks",
|
|
12
|
+
submissions: "submissions",
|
|
13
|
+
documents: "documents",
|
|
14
|
+
documentRevisions: "document_revisions",
|
|
15
|
+
};
|
|
16
|
+
const INDEX_NAMES = {
|
|
17
|
+
conversationsByOwnerConversation: "conversations_by_owner_conversation",
|
|
18
|
+
conversationsByOwnerTask: "conversations_by_owner_task",
|
|
19
|
+
entriesByConversation: "entries_by_conversation",
|
|
20
|
+
entryHeadsByConversation: "entry_heads_by_conversation",
|
|
21
|
+
tasksByStatus: "tasks_by_status",
|
|
22
|
+
tasksByConversation: "tasks_by_conversation",
|
|
23
|
+
tasksByKind: "tasks_by_kind",
|
|
24
|
+
tasksByAbortRequested: "tasks_by_abort_requested",
|
|
25
|
+
tasksByBackground: "tasks_by_background",
|
|
26
|
+
submissionsByRequest: "submissions_by_request",
|
|
27
|
+
submissionsByConversation: "submissions_by_conversation",
|
|
28
|
+
submissionsByStatus: "submissions_by_status",
|
|
29
|
+
documentsByAddress: "documents_by_address",
|
|
30
|
+
documentsByScope: "documents_by_scope",
|
|
31
|
+
documentsByScopeKind: "documents_by_scope_kind",
|
|
32
|
+
documentRevisionsByKind: "document_revisions_by_kind",
|
|
33
|
+
};
|
|
34
|
+
/** Validate a prefix before using it as part of a SQLite identifier. */
|
|
35
|
+
export function validateSqliteSchemaPrefix(prefix) {
|
|
36
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(prefix)) {
|
|
37
|
+
throw new Error(`Invalid SQLite schema prefix ${JSON.stringify(prefix)}`);
|
|
38
|
+
}
|
|
39
|
+
if (prefix.toLowerCase().startsWith("sqlite_")) {
|
|
40
|
+
throw new Error(`SQLite schema prefix ${JSON.stringify(prefix)} is reserved`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function prefixIdentifiers(names, prefix) {
|
|
44
|
+
return Object.fromEntries(Object.entries(names).map(([key, name]) => [key, `${prefix}${name}`]));
|
|
45
|
+
}
|
|
46
|
+
/** Build the identifiers used by every migration and storage query. */
|
|
47
|
+
export function createSqliteSchema(prefix) {
|
|
48
|
+
if (prefix !== undefined)
|
|
49
|
+
validateSqliteSchemaPrefix(prefix);
|
|
50
|
+
const actualPrefix = prefix ?? "";
|
|
51
|
+
return {
|
|
52
|
+
tables: prefixIdentifiers(TABLE_NAMES, actualPrefix),
|
|
53
|
+
indexes: prefixIdentifiers(INDEX_NAMES, actualPrefix),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export const DEFAULT_SQLITE_SCHEMA = createSqliteSchema();
|
|
57
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/storage/sqlite/schema.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,GAAG;IACnB,aAAa,EAAE,gBAAgB;IAC/B,eAAe,EAAE,kBAAkB;IACnC,SAAS,EAAE,YAAY;IACvB,aAAa,EAAE,eAAe;IAC9B,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,OAAO;IACd,WAAW,EAAE,aAAa;IAC1B,SAAS,EAAE,WAAW;IACtB,iBAAiB,EAAE,oBAAoB;CAC9B,CAAC;AAEX,MAAM,WAAW,GAAG;IACnB,gCAAgC,EAAE,qCAAqC;IACvE,wBAAwB,EAAE,6BAA6B;IACvD,qBAAqB,EAAE,yBAAyB;IAChD,wBAAwB,EAAE,6BAA6B;IACvD,aAAa,EAAE,iBAAiB;IAChC,mBAAmB,EAAE,uBAAuB;IAC5C,WAAW,EAAE,eAAe;IAC5B,qBAAqB,EAAE,0BAA0B;IACjD,iBAAiB,EAAE,qBAAqB;IACxC,oBAAoB,EAAE,wBAAwB;IAC9C,yBAAyB,EAAE,6BAA6B;IACxD,mBAAmB,EAAE,uBAAuB;IAC5C,kBAAkB,EAAE,sBAAsB;IAC1C,gBAAgB,EAAE,oBAAoB;IACtC,oBAAoB,EAAE,yBAAyB;IAC/C,uBAAuB,EAAE,4BAA4B;CAC5C,CAAC;AASX,wEAAwE;AACxE,MAAM,UAAU,0BAA0B,CAAC,MAAc;IACxD,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,gCAAgC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC;IACD,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC,wBAAwB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IAC/E,CAAC;AACF,CAAC;AAED,SAAS,iBAAiB,CAAmC,KAAQ,EAAE,MAAc;IACpF,OAAO,MAAM,CAAC,WAAW,CACxB,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,MAAM,GAAG,IAAI,EAAE,CAAC,CAAC,CAC7C,CAAC;AAC3B,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,kBAAkB,CAAC,MAAe;IACjD,IAAI,MAAM,KAAK,SAAS;QAAE,0BAA0B,CAAC,MAAM,CAAC,CAAC;IAC7D,MAAM,YAAY,GAAG,MAAM,IAAI,EAAE,CAAC;IAClC,OAAO;QACN,MAAM,EAAE,iBAAiB,CAAC,WAAW,EAAE,YAAY,CAAC;QACpD,OAAO,EAAE,iBAAiB,CAAC,WAAW,EAAE,YAAY,CAAC;KACrD,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAG,kBAAkB,EAAE,CAAC","sourcesContent":["/**\n * Immutable identifier history for migrations and runtime queries. Never change or remove an existing value; a\n * rename adds a new entry so historical migrations keep rendering their original object names.\n */\nconst TABLE_NAMES = {\n\tdurableSchema: \"durable_schema\",\n\tdurableMetadata: \"durable_metadata\",\n\trecordIds: \"record_ids\",\n\tconversations: \"conversations\",\n\tentries: \"entries\",\n\ttasks: \"tasks\",\n\tsubmissions: \"submissions\",\n\tdocuments: \"documents\",\n\tdocumentRevisions: \"document_revisions\",\n} as const;\n\nconst INDEX_NAMES = {\n\tconversationsByOwnerConversation: \"conversations_by_owner_conversation\",\n\tconversationsByOwnerTask: \"conversations_by_owner_task\",\n\tentriesByConversation: \"entries_by_conversation\",\n\tentryHeadsByConversation: \"entry_heads_by_conversation\",\n\ttasksByStatus: \"tasks_by_status\",\n\ttasksByConversation: \"tasks_by_conversation\",\n\ttasksByKind: \"tasks_by_kind\",\n\ttasksByAbortRequested: \"tasks_by_abort_requested\",\n\ttasksByBackground: \"tasks_by_background\",\n\tsubmissionsByRequest: \"submissions_by_request\",\n\tsubmissionsByConversation: \"submissions_by_conversation\",\n\tsubmissionsByStatus: \"submissions_by_status\",\n\tdocumentsByAddress: \"documents_by_address\",\n\tdocumentsByScope: \"documents_by_scope\",\n\tdocumentsByScopeKind: \"documents_by_scope_kind\",\n\tdocumentRevisionsByKind: \"document_revisions_by_kind\",\n} as const;\n\ntype SqliteIdentifiers<T extends Record<string, string>> = { readonly [K in keyof T]: string };\n\nexport type SqliteSchema = {\n\treadonly tables: SqliteIdentifiers<typeof TABLE_NAMES>;\n\treadonly indexes: SqliteIdentifiers<typeof INDEX_NAMES>;\n};\n\n/** Validate a prefix before using it as part of a SQLite identifier. */\nexport function validateSqliteSchemaPrefix(prefix: string): void {\n\tif (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(prefix)) {\n\t\tthrow new Error(`Invalid SQLite schema prefix ${JSON.stringify(prefix)}`);\n\t}\n\tif (prefix.toLowerCase().startsWith(\"sqlite_\")) {\n\t\tthrow new Error(`SQLite schema prefix ${JSON.stringify(prefix)} is reserved`);\n\t}\n}\n\nfunction prefixIdentifiers<T extends Record<string, string>>(names: T, prefix: string): SqliteIdentifiers<T> {\n\treturn Object.fromEntries(\n\t\tObject.entries(names).map(([key, name]) => [key, `${prefix}${name}`]),\n\t) as SqliteIdentifiers<T>;\n}\n\n/** Build the identifiers used by every migration and storage query. */\nexport function createSqliteSchema(prefix?: string): SqliteSchema {\n\tif (prefix !== undefined) validateSqliteSchemaPrefix(prefix);\n\tconst actualPrefix = prefix ?? \"\";\n\treturn {\n\t\ttables: prefixIdentifiers(TABLE_NAMES, actualPrefix),\n\t\tindexes: prefixIdentifiers(INDEX_NAMES, actualPrefix),\n\t};\n}\n\nexport const DEFAULT_SQLITE_SCHEMA = createSqliteSchema();\n"]}
|
|
@@ -2,9 +2,17 @@ import type { Context, JsonValue } from "@earendil-works/chord";
|
|
|
2
2
|
import type { ConversationId, ConversationQuery, ConversationRecord, Cursor, DocumentAddress, DocumentId, DocumentPoint, DocumentQuery, DocumentRecord, EntryId, EntryQuery, EntryRecord, Id, Page, Seq, Storage, StorageWrite, StoredDocument, SubmissionId, SubmissionQuery, SubmissionRecord, TaskId, TaskQuery, TaskRecord } from "../../types.ts";
|
|
3
3
|
import type { SqliteDatabase } from "./database.ts";
|
|
4
4
|
type StoredTask = TaskRecord<JsonValue, JsonValue, JsonValue>;
|
|
5
|
+
export type SqliteStorageOptions = {
|
|
6
|
+
/**
|
|
7
|
+
* Prefix for every table and index in the durable schema. It must be a SQLite identifier and must not use
|
|
8
|
+
* SQLite's reserved `sqlite_` prefix. Existing data is not migrated when this changes.
|
|
9
|
+
*/
|
|
10
|
+
readonly prefix?: string;
|
|
11
|
+
};
|
|
5
12
|
/** Portable SQLite implementation of the Pico storage contract. */
|
|
6
13
|
export declare class SqliteStorage implements Storage {
|
|
7
14
|
private readonly db;
|
|
15
|
+
private readonly schema;
|
|
8
16
|
private nextId;
|
|
9
17
|
private closed;
|
|
10
18
|
private closing;
|
|
@@ -12,7 +20,7 @@ export declare class SqliteStorage implements Storage {
|
|
|
12
20
|
private readsDrained;
|
|
13
21
|
private constructor();
|
|
14
22
|
/** Initialize storage over an owned SQLite database facade. */
|
|
15
|
-
static open(db: SqliteDatabase): Promise<SqliteStorage>;
|
|
23
|
+
static open(db: SqliteDatabase, options?: SqliteStorageOptions): Promise<SqliteStorage>;
|
|
16
24
|
commit(writes: readonly StorageWrite[], _context: Context): Promise<Seq>;
|
|
17
25
|
mintId<I extends Id<string>>(): Promise<I>;
|
|
18
26
|
conversation(id: ConversationId, _context: Context): Promise<ConversationRecord | undefined>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/storage/sqlite/storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAIhE,OAAO,KAAK,EACX,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,MAAM,EACN,eAAe,EAGf,UAAU,EACV,aAAa,EACb,aAAa,EACb,cAAc,EACd,OAAO,EACP,UAAU,EACV,WAAW,EACX,EAAE,EAEF,IAAI,EAEJ,GAAG,EACH,OAAO,EACP,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,MAAM,EACN,SAAS,EACT,UAAU,EACV,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,cAAc,EAA+B,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/storage/sqlite/storage.ts"],"names":[],"mappings":"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"}
|