@earendil-works/pi-durable 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/README.md +111 -3
  3. package/dist/codemode/codemode.d.ts.map +1 -1
  4. package/dist/codemode/codemode.js +12 -4
  5. package/dist/codemode/codemode.js.map +1 -1
  6. package/dist/codemode/models.d.ts.map +1 -1
  7. package/dist/codemode/models.js +2 -0
  8. package/dist/codemode/models.js.map +1 -1
  9. package/dist/documents.d.ts +1 -1
  10. package/dist/documents.d.ts.map +1 -1
  11. package/dist/documents.js.map +1 -1
  12. package/dist/env/node.d.ts.map +1 -1
  13. package/dist/env/node.js +11 -3
  14. package/dist/env/node.js.map +1 -1
  15. package/dist/harness/agent.d.ts +13 -2
  16. package/dist/harness/agent.d.ts.map +1 -1
  17. package/dist/harness/agent.js +39 -5
  18. package/dist/harness/agent.js.map +1 -1
  19. package/dist/harness/compaction.d.ts +3 -1
  20. package/dist/harness/compaction.d.ts.map +1 -1
  21. package/dist/harness/compaction.js +19 -4
  22. package/dist/harness/compaction.js.map +1 -1
  23. package/dist/harness/generation.d.ts.map +1 -1
  24. package/dist/harness/generation.js +67 -27
  25. package/dist/harness/generation.js.map +1 -1
  26. package/dist/harness/harness.d.ts +5 -2
  27. package/dist/harness/harness.d.ts.map +1 -1
  28. package/dist/harness/harness.js +78 -13
  29. package/dist/harness/harness.js.map +1 -1
  30. package/dist/harness/inbox.d.ts +2 -2
  31. package/dist/harness/inbox.d.ts.map +1 -1
  32. package/dist/harness/inbox.js +3 -3
  33. package/dist/harness/inbox.js.map +1 -1
  34. package/dist/harness/prompt.d.ts +1 -1
  35. package/dist/harness/prompt.d.ts.map +1 -1
  36. package/dist/harness/prompt.js +1 -1
  37. package/dist/harness/prompt.js.map +1 -1
  38. package/dist/harness/scheduler.d.ts +55 -10
  39. package/dist/harness/scheduler.d.ts.map +1 -1
  40. package/dist/harness/scheduler.js +617 -124
  41. package/dist/harness/scheduler.js.map +1 -1
  42. package/dist/harness/submissions.d.ts +7 -2
  43. package/dist/harness/submissions.d.ts.map +1 -1
  44. package/dist/harness/submissions.js +48 -17
  45. package/dist/harness/submissions.js.map +1 -1
  46. package/dist/harness/task-graph.d.ts +18 -1
  47. package/dist/harness/task-graph.d.ts.map +1 -1
  48. package/dist/harness/task-graph.js +50 -11
  49. package/dist/harness/task-graph.js.map +1 -1
  50. package/dist/harness/telemetry.d.ts +307 -0
  51. package/dist/harness/telemetry.d.ts.map +1 -0
  52. package/dist/harness/telemetry.js +136 -0
  53. package/dist/harness/telemetry.js.map +1 -0
  54. package/dist/harness/tool.d.ts.map +1 -1
  55. package/dist/harness/tool.js +53 -7
  56. package/dist/harness/tool.js.map +1 -1
  57. package/dist/harness/types.d.ts +110 -15
  58. package/dist/harness/types.d.ts.map +1 -1
  59. package/dist/harness/types.js.map +1 -1
  60. package/dist/harness/util.d.ts +4 -0
  61. package/dist/harness/util.d.ts.map +1 -1
  62. package/dist/harness/util.js +4 -0
  63. package/dist/harness/util.js.map +1 -1
  64. package/dist/index.d.ts +6 -4
  65. package/dist/index.d.ts.map +1 -1
  66. package/dist/index.js +3 -2
  67. package/dist/index.js.map +1 -1
  68. package/dist/session/session.d.ts +17 -6
  69. package/dist/session/session.d.ts.map +1 -1
  70. package/dist/session/session.js +64 -32
  71. package/dist/session/session.js.map +1 -1
  72. package/dist/session/transaction.d.ts +5 -1
  73. package/dist/session/transaction.d.ts.map +1 -1
  74. package/dist/session/transaction.js +26 -1
  75. package/dist/session/transaction.js.map +1 -1
  76. package/dist/storage/indexeddb.d.ts +60 -0
  77. package/dist/storage/indexeddb.d.ts.map +1 -0
  78. package/dist/storage/indexeddb.js +831 -0
  79. package/dist/storage/indexeddb.js.map +1 -0
  80. package/dist/storage/jsonl/storage.d.ts +16 -0
  81. package/dist/storage/jsonl/storage.d.ts.map +1 -1
  82. package/dist/storage/memory.js +1 -1
  83. package/dist/storage/memory.js.map +1 -1
  84. package/dist/storage/sqlite/cloudflare.d.ts +2 -51
  85. package/dist/storage/sqlite/cloudflare.d.ts.map +1 -1
  86. package/dist/storage/sqlite/cloudflare.js +2 -133
  87. package/dist/storage/sqlite/cloudflare.js.map +1 -1
  88. package/dist/storage/sqlite/database.d.ts +1 -36
  89. package/dist/storage/sqlite/database.d.ts.map +1 -1
  90. package/dist/storage/sqlite/database.js.map +1 -1
  91. package/dist/storage/sqlite/index.d.ts +1 -1
  92. package/dist/storage/sqlite/index.d.ts.map +1 -1
  93. package/dist/storage/sqlite/index.js.map +1 -1
  94. package/dist/storage/sqlite/migrations.d.ts +2 -5
  95. package/dist/storage/sqlite/migrations.d.ts.map +1 -1
  96. package/dist/storage/sqlite/migrations.js +28 -28
  97. package/dist/storage/sqlite/migrations.js.map +1 -1
  98. package/dist/storage/sqlite/node.d.ts +2 -37
  99. package/dist/storage/sqlite/node.d.ts.map +1 -1
  100. package/dist/storage/sqlite/node.js +3 -174
  101. package/dist/storage/sqlite/node.js.map +1 -1
  102. package/dist/storage/sqlite/schema.d.ts +1 -3
  103. package/dist/storage/sqlite/schema.d.ts.map +1 -1
  104. package/dist/storage/sqlite/schema.js +2 -9
  105. package/dist/storage/sqlite/schema.js.map +1 -1
  106. package/dist/storage/sqlite/storage.d.ts +1 -1
  107. package/dist/storage/sqlite/storage.d.ts.map +1 -1
  108. package/dist/storage/sqlite/storage.js.map +1 -1
  109. package/dist/testing/storage-conformance.d.ts.map +1 -1
  110. package/dist/testing/storage-conformance.js +17 -0
  111. package/dist/testing/storage-conformance.js.map +1 -1
  112. package/dist/timers.d.ts +21 -0
  113. package/dist/timers.d.ts.map +1 -0
  114. package/dist/timers.js +72 -0
  115. package/dist/timers.js.map +1 -0
  116. package/dist/types.d.ts +130 -9
  117. package/dist/types.d.ts.map +1 -1
  118. package/dist/types.js.map +1 -1
  119. package/package.json +15 -5
@@ -1 +1 @@
1
- {"version":3,"file":"database.js","sourceRoot":"","sources":["../../../src/storage/sqlite/database.ts"],"names":[],"mappings":"","sourcesContent":["/** Values supported by the portable SQLite storage core. */\nexport type SqliteValue = null | number | bigint | string | Uint8Array;\n\n/**\n * Asynchronous SQL operations shared by a database and its transaction handles.\n *\n * `exec` runs SQL text without bindings and may contain several statements. `run`, `get`, and `all`\n * execute one statement with positional bindings. Adapters may cache prepared statements by SQL text,\n * so callers pass values as bindings instead of interpolating them.\n */\nexport interface SqliteExecutor {\n\texec(sql: string): Promise<void>;\n\trun(sql: string, ...params: SqliteValue[]): Promise<void>;\n\tget<T extends object>(sql: string, ...params: SqliteValue[]): Promise<T | undefined>;\n\tall<T extends object>(sql: string, ...params: SqliteValue[]): Promise<T[]>;\n}\n\n/**\n * Minimal database facade required by `SqliteStorage`.\n *\n * All operations are asynchronous so adapters may execute outside the harness runtime.\n *\n * `transaction` passes the callback a transaction handle. All work in the transaction\n * must use that handle; the handle is invalid after the callback settles. Adapters must\n * queue unrelated operations and other transactions until the transaction finishes. The\n * returned promise settles after commit or rollback. Calling the database itself (including\n * `transaction` or `close`) from inside a callback therefore waits for that transaction and\n * never settles.\n *\n * When the callback rejects, the adapter must roll the transaction back before rejecting\n * with that same error. If rollback fails, it must reject with a different error (for\n * example an `AggregateError`) so callers cannot mistake the callback error for a\n * guaranteed rollback.\n */\nexport interface SqliteDatabase extends SqliteExecutor {\n\ttransaction<T>(callback: (transaction: SqliteExecutor) => Promise<T>): Promise<T>;\n\tclose(): Promise<void>;\n}\n"]}
1
+ {"version":3,"file":"database.js","sourceRoot":"","sources":["../../../src/storage/sqlite/database.ts"],"names":[],"mappings":"","sourcesContent":["export type { SqliteDatabase, SqliteExecutor, SqliteValue } from \"@earendil-works/chord/sqlite\";\n"]}
@@ -1,4 +1,4 @@
1
- export type { SqliteDatabase, SqliteExecutor, SqliteValue } from "./database.ts";
1
+ export type { SqliteDatabase, SqliteExecutor, SqliteValue } from "@earendil-works/chord/sqlite";
2
2
  export { applySqliteMigrations, CURRENT_SQLITE_SCHEMA_VERSION, SQLITE_MIGRATIONS, type SqliteMigration, } from "./migrations.ts";
3
3
  export { SqliteStorage, type SqliteStorageOptions } from "./storage.ts";
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -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,KAAK,oBAAoB,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,8BAA8B,CAAC;AAChG,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,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
+ {"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 \"@earendil-works/chord/sqlite\";\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,9 +1,6 @@
1
- import type { SqliteDatabase } from "./database.ts";
1
+ import { type SqliteDatabase, type SqliteMigration } from "@earendil-works/chord/sqlite";
2
2
  import { type SqliteSchema } from "./schema.ts";
3
- export type SqliteMigration = {
4
- readonly version: number;
5
- readonly statements: readonly string[];
6
- };
3
+ export type { SqliteMigration } from "@earendil-works/chord/sqlite";
7
4
  /** Build immutable, ordered schema history for a set of SQLite identifiers. */
8
5
  export declare function createSqliteMigrations(schema: SqliteSchema): readonly SqliteMigration[];
9
6
  export declare const SQLITE_MIGRATIONS: readonly SqliteMigration[];
@@ -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;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
+ {"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../../src/storage/sqlite/migrations.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAyB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAEvE,YAAY,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE,+EAA+E;AAC/E,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,eAAe,EAAE,CA0GvF;AAED,eAAO,MAAM,iBAAiB,EAAE,SAAS,eAAe,EAAkD,CAAC;AAE3G,eAAO,MAAM,6BAA6B,QAAyC,CAAC;AAEpF,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,CAEf"}
@@ -1,3 +1,4 @@
1
+ import { applySqliteMigrations as applyMigrations, } from "@earendil-works/chord/sqlite";
1
2
  import { DEFAULT_SQLITE_SCHEMA } from "./schema.js";
2
3
  /** Build immutable, ordered schema history for a set of SQLite identifiers. */
3
4
  export function createSqliteMigrations(schema) {
@@ -80,7 +81,32 @@ export function createSqliteMigrations(schema) {
80
81
  ) STRICT`,
81
82
  `CREATE INDEX ${indexes.documentRevisionsByKind} ON ${tables.documentRevisions} (document_id, kind, seq DESC)`,
82
83
  ];
83
- return [{ version: 1, statements: initialSchema }];
84
+ // Version 2 adds the `sleeping` task status. SQLite cannot change a CHECK constraint in place, so the table is rebuilt.
85
+ const rebuiltTasks = `${tables.tasks}_v2`;
86
+ const sleepingStatus = [
87
+ `CREATE TABLE ${rebuiltTasks} (
88
+ id INTEGER PRIMARY KEY,
89
+ conversation_id INTEGER NOT NULL,
90
+ kind TEXT NOT NULL,
91
+ status TEXT NOT NULL CHECK (status IN ('pending', 'running', 'waiting', 'sleeping', 'completing', 'terminal')),
92
+ abort_requested INTEGER NOT NULL CHECK (abort_requested IN (0, 1)),
93
+ background INTEGER NOT NULL CHECK (background IN (0, 1)),
94
+ record TEXT NOT NULL CHECK (json_valid(record))
95
+ ) STRICT`,
96
+ `INSERT INTO ${rebuiltTasks} (id, conversation_id, kind, status, abort_requested, background, record)
97
+ SELECT id, conversation_id, kind, status, abort_requested, background, record FROM ${tables.tasks}`,
98
+ `DROP TABLE ${tables.tasks}`,
99
+ `ALTER TABLE ${rebuiltTasks} RENAME TO ${tables.tasks}`,
100
+ `CREATE INDEX ${indexes.tasksByStatus} ON ${tables.tasks} (status, id)`,
101
+ `CREATE INDEX ${indexes.tasksByConversation} ON ${tables.tasks} (conversation_id, id)`,
102
+ `CREATE INDEX ${indexes.tasksByKind} ON ${tables.tasks} (kind, id)`,
103
+ `CREATE INDEX ${indexes.tasksByAbortRequested} ON ${tables.tasks} (abort_requested, id)`,
104
+ `CREATE INDEX ${indexes.tasksByBackground} ON ${tables.tasks} (background, id)`,
105
+ ];
106
+ return [
107
+ { version: 1, statements: initialSchema },
108
+ { version: 2, statements: sleepingStatus },
109
+ ];
84
110
  }
85
111
  export const SQLITE_MIGRATIONS = createSqliteMigrations(DEFAULT_SQLITE_SCHEMA);
86
112
  export const CURRENT_SQLITE_SCHEMA_VERSION = SQLITE_MIGRATIONS.at(-1)?.version ?? 0;
@@ -90,32 +116,6 @@ export async function applySqliteMigrations(database, migrations = SQLITE_MIGRAT
90
116
  }
91
117
  /** Apply migrations rendered for a particular schema. */
92
118
  export async function applySqliteMigrationsForSchema(database, schema, migrations = createSqliteMigrations(schema)) {
93
- for (let index = 0; index < migrations.length; index++) {
94
- if (migrations[index]?.version !== index + 1) {
95
- throw new Error("Durable SQLite migrations must have contiguous versions starting at 1");
96
- }
97
- }
98
- const { durableSchema } = schema.tables;
99
- await database.transaction(async (transaction) => {
100
- await transaction.exec(`CREATE TABLE IF NOT EXISTS ${durableSchema} (
101
- singleton INTEGER PRIMARY KEY CHECK (singleton = 1),
102
- version INTEGER NOT NULL CHECK (version >= 0)
103
- ) STRICT`);
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`);
106
- if (row === undefined)
107
- throw new Error("Durable SQLite schema metadata is missing");
108
- const currentVersion = migrations.at(-1)?.version ?? 0;
109
- if (row.version > currentVersion) {
110
- throw new Error(`Durable SQLite schema version ${row.version} is newer than supported version ${currentVersion}`);
111
- }
112
- for (const migration of migrations) {
113
- if (migration.version <= row.version)
114
- continue;
115
- for (const statement of migration.statements)
116
- await transaction.exec(statement);
117
- await transaction.run(`UPDATE ${durableSchema} SET version = ? WHERE singleton = 1`, migration.version);
118
- }
119
- });
119
+ await applyMigrations(database, migrations, { table: schema.tables.durableSchema });
120
120
  }
121
121
  //# sourceMappingURL=migrations.js.map
@@ -1 +1 @@
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
+ {"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../../src/storage/sqlite/migrations.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tapplySqliteMigrations as applyMigrations,\n\ttype SqliteDatabase,\n\ttype SqliteMigration,\n} from \"@earendil-works/chord/sqlite\";\nimport { DEFAULT_SQLITE_SCHEMA, type SqliteSchema } from \"./schema.ts\";\n\nexport type { SqliteMigration } from \"@earendil-works/chord/sqlite\";\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\t// Version 2 adds the `sleeping` task status. SQLite cannot change a CHECK constraint in place, so the table is rebuilt.\n\tconst rebuiltTasks = `${tables.tasks}_v2`;\n\tconst sleepingStatus: readonly string[] = [\n\t\t`CREATE TABLE ${rebuiltTasks} (\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', 'sleeping', '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`INSERT INTO ${rebuiltTasks} (id, conversation_id, kind, status, abort_requested, background, record)\n\t\t\tSELECT id, conversation_id, kind, status, abort_requested, background, record FROM ${tables.tasks}`,\n\t\t`DROP TABLE ${tables.tasks}`,\n\t\t`ALTER TABLE ${rebuiltTasks} RENAME TO ${tables.tasks}`,\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];\n\treturn [\n\t\t{ version: 1, statements: initialSchema },\n\t\t{ version: 2, statements: sleepingStatus },\n\t];\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\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\tawait applyMigrations(database, migrations, { table: schema.tables.durableSchema });\n}\n"]}
@@ -1,43 +1,8 @@
1
- import type { StatementSync } from "node:sqlite";
2
- import { DatabaseSync } from "node:sqlite";
3
- import type { SqliteDatabase, SqliteExecutor, SqliteValue } from "./database.ts";
1
+ import { type NodeSqliteDatabaseOptions } from "@earendil-works/chord/sqlite/node";
4
2
  import { SqliteStorage, type SqliteStorageOptions } from "./storage.ts";
5
- /** Node SQLite connection settings for a durable storage file. */
6
- export type NodeSqliteDatabaseOptions = {
7
- /** SQLite WAL auto-checkpoint threshold. SQLite and this adapter default to 1,000 pages; 0 disables it. */
8
- readonly walAutoCheckpointPages?: number;
9
- /** Time SQLite waits for a competing file lock. SQLite defaults to 0; this adapter defaults to 5,000 ms. */
10
- readonly busyTimeoutMs?: number;
11
- };
3
+ export { NodeSqliteDatabase, type NodeSqliteDatabaseOptions, openNodeSqliteDatabase, } from "@earendil-works/chord/sqlite/node";
12
4
  /** Node SQLite connection settings plus durable storage options. */
13
5
  export type NodeSqliteStorageOptions = NodeSqliteDatabaseOptions & SqliteStorageOptions;
14
- /**
15
- * Executes SQL on one connection. Prepared statements are cached per connection by SQL text, so the
16
- * database and its transaction handles share them across transactions.
17
- */
18
- declare abstract class NodeSqliteExecutor implements SqliteExecutor {
19
- protected readonly database: DatabaseSync;
20
- protected readonly statements: Map<string, StatementSync>;
21
- constructor(database: DatabaseSync, statements: Map<string, StatementSync>);
22
- exec(sql: string): Promise<void>;
23
- run(sql: string, ...params: SqliteValue[]): Promise<void>;
24
- get<T extends object>(sql: string, ...params: SqliteValue[]): Promise<T | undefined>;
25
- all<T extends object>(sql: string, ...params: SqliteValue[]): Promise<T[]>;
26
- protected abstract runOperation<T>(operation: () => T): Promise<T>;
27
- private statement;
28
- }
29
- /** `SqliteDatabase` adapter backed by Node's built-in `node:sqlite`. */
30
- export declare class NodeSqliteDatabase extends NodeSqliteExecutor implements SqliteDatabase {
31
- private readonly access;
32
- private closed;
33
- constructor(database: DatabaseSync);
34
- transaction<T>(callback: (transaction: SqliteExecutor) => Promise<T>): Promise<T>;
35
- close(): Promise<void>;
36
- protected runOperation<T>(operation: () => T): Promise<T>;
37
- }
38
- /** Open and configure a Node-backed SQLite database facade. */
39
- export declare function openNodeSqliteDatabase(path: string, options?: NodeSqliteDatabaseOptions): Promise<NodeSqliteDatabase>;
40
6
  /** Open or create file-backed durable storage using Node's built-in SQLite, optionally under a table prefix. */
41
7
  export declare function openNodeSqliteStorage(path: string, options?: NodeSqliteStorageOptions): Promise<SqliteStorage>;
42
- export {};
43
8
  //# 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;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
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../src/storage/sqlite/node.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,yBAAyB,EAA0B,MAAM,mCAAmC,CAAC;AAC3G,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAExE,OAAO,EACN,kBAAkB,EAClB,KAAK,yBAAyB,EAC9B,sBAAsB,GACtB,MAAM,mCAAmC,CAAC;AAE3C,oEAAoE;AACpE,MAAM,MAAM,wBAAwB,GAAG,yBAAyB,GAAG,oBAAoB,CAAC;AAExF,gHAAgH;AAChH,wBAAsB,qBAAqB,CAC1C,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,wBAA6B,GACpC,OAAO,CAAC,aAAa,CAAC,CAIxB"}
@@ -1,178 +1,7 @@
1
- import { mkdir } from "node:fs/promises";
2
- import { dirname } from "node:path";
3
- import { DatabaseSync } from "node:sqlite";
4
- import { validateSqliteSchemaPrefix } from "./schema.js";
1
+ import { validateSqliteSchemaPrefix } from "@earendil-works/chord/sqlite";
2
+ import { openNodeSqliteDatabase } from "@earendil-works/chord/sqlite/node";
5
3
  import { SqliteStorage } from "./storage.js";
6
- const DEFAULT_WAL_AUTO_CHECKPOINT_PAGES = 1_000;
7
- const DEFAULT_BUSY_TIMEOUT_MS = 5_000;
8
- const ignore = () => { };
9
- /**
10
- * Runs operations in call order. An operation starts immediately when nothing is running or waiting;
11
- * otherwise it waits for everything before it. An asynchronous operation holds the queue until it settles.
12
- */
13
- class SerialOperationQueue {
14
- tail = Promise.resolve();
15
- pending = 0;
16
- run(operation) {
17
- if (this.pending > 0)
18
- return this.enqueue(operation);
19
- try {
20
- return Promise.resolve(operation());
21
- }
22
- catch (error) {
23
- return Promise.reject(error);
24
- }
25
- }
26
- runAsync(operation) {
27
- if (this.pending > 0)
28
- return this.enqueue(operation);
29
- this.pending++;
30
- // Publish the barrier before the operation starts, so calls it makes synchronously wait behind it.
31
- const { promise: barrier, resolve: releaseBarrier } = Promise.withResolvers();
32
- this.tail = barrier;
33
- let started;
34
- try {
35
- started = operation();
36
- }
37
- catch (error) {
38
- started = Promise.reject(error);
39
- }
40
- return started.finally(() => {
41
- this.pending--;
42
- releaseBarrier();
43
- });
44
- }
45
- enqueue(operation) {
46
- this.pending++;
47
- return this.release(this.tail.then(operation));
48
- }
49
- release(operation) {
50
- const settled = operation.finally(() => {
51
- this.pending--;
52
- });
53
- this.tail = settled.then(ignore, ignore);
54
- return settled;
55
- }
56
- }
57
- /**
58
- * Executes SQL on one connection. Prepared statements are cached per connection by SQL text, so the
59
- * database and its transaction handles share them across transactions.
60
- */
61
- class NodeSqliteExecutor {
62
- database;
63
- statements;
64
- constructor(database, statements) {
65
- this.database = database;
66
- this.statements = statements;
67
- }
68
- exec(sql) {
69
- return this.runOperation(() => {
70
- this.database.exec(sql);
71
- });
72
- }
73
- run(sql, ...params) {
74
- return this.runOperation(() => {
75
- this.statement(sql).run(...params);
76
- });
77
- }
78
- get(sql, ...params) {
79
- return this.runOperation(() => this.statement(sql).get(...params));
80
- }
81
- all(sql, ...params) {
82
- return this.runOperation(() => this.statement(sql).all(...params));
83
- }
84
- statement(sql) {
85
- let statement = this.statements.get(sql);
86
- if (statement === undefined) {
87
- statement = this.database.prepare(sql);
88
- this.statements.set(sql, statement);
89
- }
90
- return statement;
91
- }
92
- }
93
- class NodeSqliteTransaction extends NodeSqliteExecutor {
94
- scope;
95
- constructor(database, statements, scope) {
96
- super(database, statements);
97
- this.scope = scope;
98
- }
99
- async runOperation(operation) {
100
- if (!this.scope.active)
101
- throw new Error("SQLite transaction handle is no longer active");
102
- return operation();
103
- }
104
- }
105
- /** `SqliteDatabase` adapter backed by Node's built-in `node:sqlite`. */
106
- export class NodeSqliteDatabase extends NodeSqliteExecutor {
107
- access = new SerialOperationQueue();
108
- closed = false;
109
- constructor(database) {
110
- super(database, new Map());
111
- }
112
- transaction(callback) {
113
- return this.access.runAsync(async () => {
114
- this.database.exec("BEGIN IMMEDIATE");
115
- const scope = { active: true };
116
- try {
117
- const result = await callback(new NodeSqliteTransaction(this.database, this.statements, scope));
118
- scope.active = false;
119
- this.database.exec("COMMIT");
120
- return result;
121
- }
122
- catch (error) {
123
- scope.active = false;
124
- try {
125
- this.database.exec("ROLLBACK");
126
- }
127
- catch (rollbackError) {
128
- throw new AggregateError([error, rollbackError], "SQLite transaction failed and rollback failed");
129
- }
130
- throw error;
131
- }
132
- });
133
- }
134
- close() {
135
- return this.access.run(() => {
136
- if (this.closed)
137
- return;
138
- this.closed = true;
139
- this.statements.clear();
140
- try {
141
- this.database.exec("PRAGMA wal_checkpoint(TRUNCATE)");
142
- }
143
- finally {
144
- this.database.close();
145
- }
146
- });
147
- }
148
- runOperation(operation) {
149
- return this.access.run(operation);
150
- }
151
- }
152
- /** Open and configure a Node-backed SQLite database facade. */
153
- export async function openNodeSqliteDatabase(path, options = {}) {
154
- const checkpointPages = options.walAutoCheckpointPages ?? DEFAULT_WAL_AUTO_CHECKPOINT_PAGES;
155
- const timeout = options.busyTimeoutMs ?? DEFAULT_BUSY_TIMEOUT_MS;
156
- if (path !== ":memory:")
157
- await mkdir(dirname(path), { recursive: true });
158
- const database = new DatabaseSync(path, { timeout });
159
- const adapter = new NodeSqliteDatabase(database);
160
- try {
161
- await adapter.exec("PRAGMA journal_mode = WAL");
162
- await adapter.exec("PRAGMA synchronous = NORMAL");
163
- await adapter.exec(`PRAGMA wal_autocheckpoint = ${checkpointPages}`);
164
- return adapter;
165
- }
166
- catch (error) {
167
- try {
168
- await adapter.close();
169
- }
170
- catch {
171
- // Preserve the configuration failure.
172
- }
173
- throw error;
174
- }
175
- }
4
+ export { NodeSqliteDatabase, openNodeSqliteDatabase, } from "@earendil-works/chord/sqlite/node";
176
5
  /** Open or create file-backed durable storage using Node's built-in SQLite, optionally under a table prefix. */
177
6
  export async function openNodeSqliteStorage(path, options = {}) {
178
7
  const { prefix, ...databaseOptions } = options;
@@ -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 { 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"]}
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../../../src/storage/sqlite/node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAC1E,OAAO,EAAkC,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAC3G,OAAO,EAAE,aAAa,EAA6B,MAAM,cAAc,CAAC;AAExE,OAAO,EACN,kBAAkB,EAElB,sBAAsB,GACtB,MAAM,mCAAmC,CAAC;AAK3C,gHAAgH;AAChH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAC1C,IAAY,EACZ,OAAO,GAA6B,EAAE;IAEtC,MAAM,EAAE,MAAM,EAAE,GAAG,eAAe,EAAE,GAAG,OAAO,CAAC;IAC/C,IAAI,MAAM,KAAK,SAAS;QAAE,0BAA0B,CAAC,MAAM,CAAC,CAAC;IAC7D,OAAO,aAAa,CAAC,IAAI,CAAC,MAAM,sBAAsB,CAAC,IAAI,EAAE,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;AAC5F,CAAC","sourcesContent":["import { validateSqliteSchemaPrefix } from \"@earendil-works/chord/sqlite\";\nimport { type NodeSqliteDatabaseOptions, openNodeSqliteDatabase } from \"@earendil-works/chord/sqlite/node\";\nimport { SqliteStorage, type SqliteStorageOptions } from \"./storage.ts\";\n\nexport {\n\tNodeSqliteDatabase,\n\ttype NodeSqliteDatabaseOptions,\n\topenNodeSqliteDatabase,\n} from \"@earendil-works/chord/sqlite/node\";\n\n/** Node SQLite connection settings plus durable storage options. */\nexport type NodeSqliteStorageOptions = NodeSqliteDatabaseOptions & SqliteStorageOptions;\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"]}
@@ -1,3 +1,4 @@
1
+ export { validateSqliteSchemaPrefix } from "@earendil-works/chord/sqlite";
1
2
  /**
2
3
  * Immutable identifier history for migrations and runtime queries. Never change or remove an existing value; a
3
4
  * rename adds a new entry so historical migrations keep rendering their original object names.
@@ -38,10 +39,7 @@ export type SqliteSchema = {
38
39
  readonly tables: SqliteIdentifiers<typeof TABLE_NAMES>;
39
40
  readonly indexes: SqliteIdentifiers<typeof INDEX_NAMES>;
40
41
  };
41
- /** Validate a prefix before using it as part of a SQLite identifier. */
42
- export declare function validateSqliteSchemaPrefix(prefix: string): void;
43
42
  /** Build the identifiers used by every migration and storage query. */
44
43
  export declare function createSqliteSchema(prefix?: string): SqliteSchema;
45
44
  export declare const DEFAULT_SQLITE_SCHEMA: SqliteSchema;
46
- export {};
47
45
  //# sourceMappingURL=schema.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/storage/sqlite/schema.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAE1E;;;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;AAQF,uEAAuE;AACvE,wBAAgB,kBAAkB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,YAAY,CAOhE;AAED,eAAO,MAAM,qBAAqB,cAAuB,CAAC"}
@@ -1,3 +1,5 @@
1
+ import { validateSqliteSchemaPrefix } from "@earendil-works/chord/sqlite";
2
+ export { validateSqliteSchemaPrefix } from "@earendil-works/chord/sqlite";
1
3
  /**
2
4
  * Immutable identifier history for migrations and runtime queries. Never change or remove an existing value; a
3
5
  * rename adds a new entry so historical migrations keep rendering their original object names.
@@ -31,15 +33,6 @@ const INDEX_NAMES = {
31
33
  documentsByScopeKind: "documents_by_scope_kind",
32
34
  documentRevisionsByKind: "document_revisions_by_kind",
33
35
  };
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
36
  function prefixIdentifiers(names, prefix) {
44
37
  return Object.fromEntries(Object.entries(names).map(([key, name]) => [key, `${prefix}${name}`]));
45
38
  }
@@ -1 +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"]}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/storage/sqlite/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAE1E,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAE1E;;;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,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":["import { validateSqliteSchemaPrefix } from \"@earendil-works/chord/sqlite\";\n\nexport { validateSqliteSchemaPrefix } from \"@earendil-works/chord/sqlite\";\n\n/**\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\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"]}
@@ -1,6 +1,6 @@
1
1
  import type { Context, JsonValue } from "@earendil-works/chord";
2
+ import type { SqliteDatabase } from "@earendil-works/chord/sqlite";
2
3
  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
- import type { SqliteDatabase } from "./database.ts";
4
4
  type StoredTask = TaskRecord<JsonValue, JsonValue, JsonValue>;
5
5
  export type SqliteStorageOptions = {
6
6
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/storage/sqlite/storage.ts"],"names":[],"mappings":"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"}
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;AAEhE,OAAO,KAAK,EAAE,cAAc,EAA+B,MAAM,8BAA8B,CAAC;AAGhG,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;AAKxB,KAAK,UAAU,GAAG,UAAU,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;AAwB9D,MAAM,MAAM,oBAAoB,GAAG;IAClC;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAiFF,mEAAmE;AACnE,qBAAa,aAAc,YAAW,OAAO;IAC5C,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAiB;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,YAAY,CAA2B;IAE/C,OAAO,eAIN;IAED,+DAA+D;IAC/D,OAAa,IAAI,CAAC,EAAE,EAAE,cAAc,EAAE,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAAC,aAAa,CAAC,CAiBhG;IAEK,MAAM,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAuB7E;IAEK,MAAM,CAAC,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAI/C;IAEK,YAAY,CAAC,EAAE,EAAE,cAAc,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAIjG;IAEK,iBAAiB,CACtB,KAAK,EAAE,iBAAiB,EACxB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,QAAQ,EAAE,OAAO,GACf,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,CAwB3C;IAED,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC;QAAE,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;QAAC,QAAQ,CAAC,SAAS,EAAE,GAAG,CAAA;KAAE,GAAG,SAAS,CAAC,CAAC;IACpH,KAAK,CACJ,cAAc,EAAE,cAAc,EAC9B,EAAE,EAAE,OAAO,EACX,OAAO,EAAE,OAAO,GACd,OAAO,CAAC;QAAE,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;QAAC,QAAQ,CAAC,SAAS,EAAE,GAAG,CAAA;KAAE,GAAG,SAAS,CAAC,CAAC;IASjF,oBAAoB,CACnB,cAAc,EAAE,cAAc,EAC9B,iBAAiB,EAAE,OAAO,GAAG,SAAS,EACtC,QAAQ,EAAE,OAAO,GACf,OAAO,CAAC,CAAC,WAAW,GAAG;QAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,GAAG,SAAS,CAAC,CAEjE;IAED,WAAW,CACV,KAAK,EAAE,UAAU,EACjB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,QAAQ,EAAE,OAAO,GACf,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAEpC;YAEa,SAAS;YAoCT,oBAAoB;YA0BpB,WAAW;IAqCzB,6GAA6G;YAC/F,oBAAoB;IAyC5B,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAIzE;IAEK,SAAS,CACd,KAAK,EAAE,SAAS,EAChB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,QAAQ,EAAE,OAAO,GACf,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAoCnC;IAEK,UAAU,CAAC,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAI3F;IAEK,eAAe,CACpB,KAAK,EAAE,eAAe,EACtB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,QAAQ,EAAE,OAAO,GACf,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC,CAwBzC;IAEK,mBAAmB,CACxB,cAAc,EAAE,cAAc,EAC9B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,OAAO,GACf,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAQvC;IAEK,YAAY,CACjB,OAAO,EAAE,eAAe,EACxB,EAAE,EAAE,aAAa,EACjB,QAAQ,EAAE,OAAO,GACf,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAgBrC;IAEK,QAAQ,CAAC,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,aAAa,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAIxG;IAEK,aAAa,CAClB,KAAK,EAAE,aAAa,EACpB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,QAAQ,EAAE,OAAO,GACf,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,CAwBvC;IAED,KAAK,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAMtC;YAEa,aAAa;IAS3B;;;OAGG;YACW,SAAS;YAUT,gBAAgB;YAKhB,mBAAmB;IAqCjC,OAAO,CAAC,eAAe;YAST,cAAc;IAuB5B,OAAO,CAAC,sBAAsB;YA+ChB,oBAAoB;YAqCpB,iBAAiB;YAoBjB,eAAe;YA6Df,OAAO;YAQP,oBAAoB;IA0FlC,OAAO,CAAC,UAAU;CAGlB"}