@loomwork/plugin-sqlite 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +8 -0
  3. package/README.md +62 -2
  4. package/dist/SqliteArchiveStore.d.ts +22 -0
  5. package/dist/SqliteArchiveStore.d.ts.map +1 -0
  6. package/dist/SqliteArchiveStore.js +129 -0
  7. package/dist/SqliteArchiveStore.js.map +1 -0
  8. package/dist/SqliteBranchRegistry.d.ts +26 -0
  9. package/dist/SqliteBranchRegistry.d.ts.map +1 -0
  10. package/dist/SqliteBranchRegistry.js +154 -0
  11. package/dist/SqliteBranchRegistry.js.map +1 -0
  12. package/dist/SqliteContentStore.d.ts +55 -0
  13. package/dist/SqliteContentStore.d.ts.map +1 -0
  14. package/dist/SqliteContentStore.js +150 -0
  15. package/dist/SqliteContentStore.js.map +1 -0
  16. package/dist/SqliteDurableStateStore.d.ts +26 -0
  17. package/dist/SqliteDurableStateStore.d.ts.map +1 -0
  18. package/dist/SqliteDurableStateStore.js +81 -0
  19. package/dist/SqliteDurableStateStore.js.map +1 -0
  20. package/dist/SqliteEventStore.d.ts +55 -0
  21. package/dist/SqliteEventStore.d.ts.map +1 -0
  22. package/dist/SqliteEventStore.js +297 -0
  23. package/dist/SqliteEventStore.js.map +1 -0
  24. package/dist/SqliteLeaseStore.d.ts +25 -0
  25. package/dist/SqliteLeaseStore.d.ts.map +1 -0
  26. package/dist/SqliteLeaseStore.js +107 -0
  27. package/dist/SqliteLeaseStore.js.map +1 -0
  28. package/dist/SqliteMemoryStore.d.ts +52 -0
  29. package/dist/SqliteMemoryStore.d.ts.map +1 -0
  30. package/dist/SqliteMemoryStore.js +149 -0
  31. package/dist/SqliteMemoryStore.js.map +1 -0
  32. package/dist/SqliteReadModelStore.d.ts +38 -0
  33. package/dist/SqliteReadModelStore.d.ts.map +1 -0
  34. package/dist/SqliteReadModelStore.js +292 -0
  35. package/dist/SqliteReadModelStore.js.map +1 -0
  36. package/dist/SqliteSnapshotStore.d.ts +31 -0
  37. package/dist/SqliteSnapshotStore.d.ts.map +1 -0
  38. package/dist/SqliteSnapshotStore.js +101 -0
  39. package/dist/SqliteSnapshotStore.js.map +1 -0
  40. package/dist/SqliteTimerStore.d.ts +19 -0
  41. package/dist/SqliteTimerStore.d.ts.map +1 -0
  42. package/dist/SqliteTimerStore.js +106 -0
  43. package/dist/SqliteTimerStore.js.map +1 -0
  44. package/dist/index.d.ts +13 -0
  45. package/dist/index.d.ts.map +1 -0
  46. package/dist/index.js +26 -0
  47. package/dist/index.js.map +1 -0
  48. package/dist/preset.d.ts +31 -0
  49. package/dist/preset.d.ts.map +1 -0
  50. package/dist/preset.js +51 -0
  51. package/dist/preset.js.map +1 -0
  52. package/dist/schema.d.ts +3 -0
  53. package/dist/schema.d.ts.map +1 -0
  54. package/dist/schema.js +103 -0
  55. package/dist/schema.js.map +1 -0
  56. package/dist/snapshotSchema.d.ts +3 -0
  57. package/dist/snapshotSchema.d.ts.map +1 -0
  58. package/dist/snapshotSchema.js +19 -0
  59. package/dist/snapshotSchema.js.map +1 -0
  60. package/package.json +62 -3
  61. package/src/SqliteArchiveStore.ts +189 -0
  62. package/src/SqliteBranchRegistry.ts +199 -0
  63. package/src/SqliteContentStore.ts +195 -0
  64. package/src/SqliteDurableStateStore.ts +101 -0
  65. package/src/SqliteEventStore.ts +414 -0
  66. package/src/SqliteLeaseStore.ts +165 -0
  67. package/src/SqliteMemoryStore.ts +160 -0
  68. package/src/SqliteReadModelStore.ts +378 -0
  69. package/src/SqliteSnapshotStore.ts +157 -0
  70. package/src/SqliteTimerStore.ts +124 -0
  71. package/src/index.ts +13 -0
  72. package/src/preset.ts +66 -0
  73. package/src/schema.ts +100 -0
  74. package/src/snapshotSchema.ts +17 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SqliteSnapshotStore.js","sourceRoot":"","sources":["../src/SqliteSnapshotStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { TimerRecord, TimerStore } from "@loomwork/event-runtime";
2
+ /**
3
+ * SQLite-backed {@link TimerStore} (T1.3). Point it at the same DB file as the
4
+ * SqliteEventStore so a single backup captures events + timers — the full
5
+ * kernel state. Own idempotent migration, same pattern as SqliteBranchRegistry.
6
+ */
7
+ export declare class SqliteTimerStore implements TimerStore {
8
+ private readonly db;
9
+ constructor(dbPath: string);
10
+ schedule(timer: TimerRecord): Promise<void>;
11
+ due(now: number, limit?: number, options?: {
12
+ redrive?: boolean;
13
+ inbox?: boolean;
14
+ refused?: boolean;
15
+ }): Promise<TimerRecord[]>;
16
+ complete(executionId: string, wakeAt: number): Promise<void>;
17
+ close(): Promise<void>;
18
+ }
19
+ //# sourceMappingURL=SqliteTimerStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SqliteTimerStore.d.ts","sourceRoot":"","sources":["../src/SqliteTimerStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAUvE;;;;GAIG;AACH,qBAAa,gBAAiB,YAAW,UAAU;IACjD,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAoB;gBAE3B,MAAM,EAAE,MAAM;IA6CpB,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IA6B3C,GAAG,CACP,GAAG,EAAE,MAAM,EACX,KAAK,SAAM,EACX,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAClE,OAAO,CAAC,WAAW,EAAE,CAAC;IAkBnB,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM5D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SqliteTimerStore = void 0;
7
+ const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
8
+ /**
9
+ * SQLite-backed {@link TimerStore} (T1.3). Point it at the same DB file as the
10
+ * SqliteEventStore so a single backup captures events + timers — the full
11
+ * kernel state. Own idempotent migration, same pattern as SqliteBranchRegistry.
12
+ */
13
+ class SqliteTimerStore {
14
+ db;
15
+ constructor(dbPath) {
16
+ this.db = new better_sqlite3_1.default(dbPath);
17
+ try {
18
+ this.db.pragma("journal_mode = WAL");
19
+ this.db.pragma("synchronous = NORMAL");
20
+ this.db.exec(`
21
+ CREATE TABLE IF NOT EXISTS timers (
22
+ execution_id TEXT NOT NULL,
23
+ wake_at INTEGER NOT NULL,
24
+ PRIMARY KEY (execution_id, wake_at)
25
+ );
26
+ CREATE INDEX IF NOT EXISTS idx_timers_wake ON timers (wake_at ASC);
27
+ `);
28
+ // ADR 0118 D4 — `CREATE TABLE IF NOT EXISTS` never adds a column to a table an older version
29
+ // created, so the re-drive column is added by a guarded ALTER: only when `table_info` lacks it
30
+ // (SQLite has no `ADD COLUMN IF NOT EXISTS`, and a second ALTER would throw). The check and
31
+ // the ALTER run under ONE write lock (`BEGIN IMMEDIATE`): two processes opening the same
32
+ // file at once would otherwise both see the column missing and the loser's ALTER would throw
33
+ // `duplicate column name`, failing its boot. The error is also tolerated (belt and braces: a
34
+ // peer on a SQLite build whose locking differs still ends with the column present).
35
+ this.db
36
+ .transaction(() => {
37
+ const columns = this.db.pragma("table_info(timers)");
38
+ // `redrive` (ADR 0118 D4) and `refused` (ADR 0130 D10), both nullable TEXT (JSON).
39
+ for (const column of ["redrive", "refused"]) {
40
+ if (columns.some((c) => c.name === column))
41
+ continue;
42
+ try {
43
+ this.db.exec(`ALTER TABLE timers ADD COLUMN ${column} TEXT`);
44
+ }
45
+ catch (err) {
46
+ if (!/duplicate column name/i.test(String(err.message)))
47
+ throw err;
48
+ }
49
+ }
50
+ })
51
+ .immediate();
52
+ // ADR 0130 D10 - a PARTIAL index over the (rare) refusal rows only: a scan for them
53
+ // (`due` with refusal rows wanted) never walks the plain timers, and a plain row pays nothing.
54
+ this.db.exec("CREATE INDEX IF NOT EXISTS idx_timers_refused ON timers (wake_at ASC) WHERE refused IS NOT NULL");
55
+ }
56
+ catch (err) {
57
+ this.db.close(); // don't leak the file handle if setup fails on a bad/locked file
58
+ throw err;
59
+ }
60
+ }
61
+ async schedule(timer) {
62
+ this.db
63
+ .prepare(
64
+ // Upsert (ADR 0118 D4, ADR 0130 D10): a flagged row is never downgraded, a plain one gains
65
+ // the flag, and a same-key `refused` upsert keeps the MAX head / MAX holds (never last-writer-wins).
66
+ `INSERT INTO timers (execution_id, wake_at, redrive, refused) VALUES (?, ?, ?, ?)
67
+ ON CONFLICT (execution_id, wake_at)
68
+ DO UPDATE SET redrive = COALESCE(excluded.redrive, timers.redrive),
69
+ refused = CASE
70
+ WHEN excluded.refused IS NULL THEN timers.refused
71
+ WHEN timers.refused IS NULL THEN excluded.refused
72
+ WHEN json_extract(excluded.refused, '$.holds') IS NULL
73
+ AND json_extract(timers.refused, '$.holds') IS NULL
74
+ THEN json_object('head', max(json_extract(excluded.refused, '$.head'),
75
+ json_extract(timers.refused, '$.head')))
76
+ ELSE json_object('head', max(json_extract(excluded.refused, '$.head'),
77
+ json_extract(timers.refused, '$.head')),
78
+ 'holds', max(COALESCE(json_extract(excluded.refused, '$.holds'), 0),
79
+ COALESCE(json_extract(timers.refused, '$.holds'), 0)))
80
+ END`)
81
+ .run(timer.executionId, timer.wakeAt, timer.redrive !== undefined ? JSON.stringify(timer.redrive) : null, timer.refused !== undefined ? JSON.stringify(timer.refused) : null);
82
+ }
83
+ async due(now, limit = 100, options) {
84
+ const rows = this.db
85
+ .prepare(`SELECT execution_id, wake_at, redrive, refused FROM timers WHERE wake_at <= ?${options?.redrive === false ? " AND redrive IS NULL" : ""}${options?.refused === false ? " AND refused IS NULL" : ""}${options?.inbox === false ? " AND (wake_at <> -1 OR redrive IS NOT NULL)" : ""} ORDER BY wake_at ASC LIMIT ?`)
86
+ .all(now, limit);
87
+ return rows.map((r) => ({
88
+ executionId: r.execution_id,
89
+ wakeAt: r.wake_at,
90
+ ...(r.redrive !== null && { redrive: JSON.parse(r.redrive) }),
91
+ ...(r.refused !== null && {
92
+ refused: JSON.parse(r.refused),
93
+ }),
94
+ }));
95
+ }
96
+ async complete(executionId, wakeAt) {
97
+ this.db
98
+ .prepare("DELETE FROM timers WHERE execution_id = ? AND wake_at = ?")
99
+ .run(executionId, wakeAt);
100
+ }
101
+ async close() {
102
+ this.db.close();
103
+ }
104
+ }
105
+ exports.SqliteTimerStore = SqliteTimerStore;
106
+ //# sourceMappingURL=SqliteTimerStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SqliteTimerStore.js","sourceRoot":"","sources":["../src/SqliteTimerStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export { SqliteEventStore } from "./SqliteEventStore";
2
+ export { SqliteBranchRegistry } from "./SqliteBranchRegistry";
3
+ export { SqliteLeaseStore } from "./SqliteLeaseStore";
4
+ export { SqliteTimerStore } from "./SqliteTimerStore";
5
+ export { SqliteSnapshotStore } from "./SqliteSnapshotStore";
6
+ export type { SqliteSnapshotStoreOptions } from "./SqliteSnapshotStore";
7
+ export { SqliteArchiveStore } from "./SqliteArchiveStore";
8
+ export { SqliteDurableStateStore } from "./SqliteDurableStateStore";
9
+ export { SqliteReadModelStore } from "./SqliteReadModelStore";
10
+ export { SqliteContentStore, type SqliteContentStoreOptions } from "./SqliteContentStore";
11
+ export { SqliteMemoryStore } from "./SqliteMemoryStore";
12
+ export { sqliteStorage, type SqliteStorageOptions } from "./preset";
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,KAAK,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAC1F,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,UAAU,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sqliteStorage = exports.SqliteMemoryStore = exports.SqliteContentStore = exports.SqliteReadModelStore = exports.SqliteDurableStateStore = exports.SqliteArchiveStore = exports.SqliteSnapshotStore = exports.SqliteTimerStore = exports.SqliteLeaseStore = exports.SqliteBranchRegistry = exports.SqliteEventStore = void 0;
4
+ var SqliteEventStore_1 = require("./SqliteEventStore");
5
+ Object.defineProperty(exports, "SqliteEventStore", { enumerable: true, get: function () { return SqliteEventStore_1.SqliteEventStore; } });
6
+ var SqliteBranchRegistry_1 = require("./SqliteBranchRegistry");
7
+ Object.defineProperty(exports, "SqliteBranchRegistry", { enumerable: true, get: function () { return SqliteBranchRegistry_1.SqliteBranchRegistry; } });
8
+ var SqliteLeaseStore_1 = require("./SqliteLeaseStore");
9
+ Object.defineProperty(exports, "SqliteLeaseStore", { enumerable: true, get: function () { return SqliteLeaseStore_1.SqliteLeaseStore; } });
10
+ var SqliteTimerStore_1 = require("./SqliteTimerStore");
11
+ Object.defineProperty(exports, "SqliteTimerStore", { enumerable: true, get: function () { return SqliteTimerStore_1.SqliteTimerStore; } });
12
+ var SqliteSnapshotStore_1 = require("./SqliteSnapshotStore");
13
+ Object.defineProperty(exports, "SqliteSnapshotStore", { enumerable: true, get: function () { return SqliteSnapshotStore_1.SqliteSnapshotStore; } });
14
+ var SqliteArchiveStore_1 = require("./SqliteArchiveStore");
15
+ Object.defineProperty(exports, "SqliteArchiveStore", { enumerable: true, get: function () { return SqliteArchiveStore_1.SqliteArchiveStore; } });
16
+ var SqliteDurableStateStore_1 = require("./SqliteDurableStateStore");
17
+ Object.defineProperty(exports, "SqliteDurableStateStore", { enumerable: true, get: function () { return SqliteDurableStateStore_1.SqliteDurableStateStore; } });
18
+ var SqliteReadModelStore_1 = require("./SqliteReadModelStore");
19
+ Object.defineProperty(exports, "SqliteReadModelStore", { enumerable: true, get: function () { return SqliteReadModelStore_1.SqliteReadModelStore; } });
20
+ var SqliteContentStore_1 = require("./SqliteContentStore");
21
+ Object.defineProperty(exports, "SqliteContentStore", { enumerable: true, get: function () { return SqliteContentStore_1.SqliteContentStore; } });
22
+ var SqliteMemoryStore_1 = require("./SqliteMemoryStore");
23
+ Object.defineProperty(exports, "SqliteMemoryStore", { enumerable: true, get: function () { return SqliteMemoryStore_1.SqliteMemoryStore; } });
24
+ var preset_1 = require("./preset");
25
+ Object.defineProperty(exports, "sqliteStorage", { enumerable: true, get: function () { return preset_1.sqliteStorage; } });
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,uDAAsD;AAA7C,oHAAA,gBAAgB,OAAA;AACzB,+DAA8D;AAArD,4HAAA,oBAAoB,OAAA;AAC7B,uDAAsD;AAA7C,oHAAA,gBAAgB,OAAA;AACzB,uDAAsD;AAA7C,oHAAA,gBAAgB,OAAA;AACzB,6DAA4D;AAAnD,0HAAA,mBAAmB,OAAA;AAE5B,2DAA0D;AAAjD,wHAAA,kBAAkB,OAAA;AAC3B,qEAAoE;AAA3D,kIAAA,uBAAuB,OAAA;AAChC,+DAA8D;AAArD,4HAAA,oBAAoB,OAAA;AAC7B,2DAA0F;AAAjF,wHAAA,kBAAkB,OAAA;AAC3B,yDAAwD;AAA/C,sHAAA,iBAAiB,OAAA;AAE1B,mCAAoE;AAA3D,uGAAA,aAAa,OAAA"}
@@ -0,0 +1,31 @@
1
+ import type { LeaseStore } from "@loomwork/event-runtime";
2
+ import type { CustomStorage } from "@loomwork/plugin-kit";
3
+ import type { SnapshotCodecName } from "@loomwork/snapshot-runtime";
4
+ export interface SqliteStorageOptions {
5
+ /** Directory holding the `.db` files. Defaults to `.loom`. */
6
+ dir?: string;
7
+ /** Also provision a branch registry (its own DB file to avoid write contention). */
8
+ branching?: boolean;
9
+ /**
10
+ * ADR 0141 - opt in to zstd-compressed snapshot states (default `"none"`: JSON text, as before).
11
+ * Needs Node >= 22.15 (throws at construction otherwise). Old snapshots stay readable; see
12
+ * `SqliteSnapshotStoreOptions.codec`.
13
+ */
14
+ snapshotCodec?: SnapshotCodecName;
15
+ }
16
+ /**
17
+ * A `defineConfig({ storage })` preset for embedded SQLite. Returns a `custom`
18
+ * storage descriptor with the SQLite stores constructed — so `@loomwork/app` never
19
+ * needs to know SQLite exists (ADR 0043: 1P/3P storage backends are symmetric,
20
+ * each supplied as a preset, none privileged with a `kind`).
21
+ *
22
+ * `leaseStore` (ADR 0130 D11) is the heartbeat-lease store CO-LOCATED with the event store: the
23
+ * same `events.db`, so the lease and the log share one failure domain. It is an accessor on
24
+ * the factory's result, not part of `CustomStorage`, so there is no `EventStore` SPI change;
25
+ * `defineConfig` does not read it yet. It is opened lazily on first access (its own connection) and
26
+ * closed by `eventStore.close()`.
27
+ */
28
+ export declare function sqliteStorage(options?: SqliteStorageOptions): CustomStorage & {
29
+ leaseStore: LeaseStore;
30
+ };
31
+ //# sourceMappingURL=preset.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preset.d.ts","sourceRoot":"","sources":["../src/preset.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAOpE,MAAM,WAAW,oBAAoB;IACnC,8DAA8D;IAC9D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oFAAoF;IACpF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;OAIG;IACH,aAAa,CAAC,EAAE,iBAAiB,CAAC;CACnC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAC3B,OAAO,GAAE,oBAAyB,GACjC,aAAa,GAAG;IAAE,UAAU,EAAE,UAAU,CAAA;CAAE,CA2B5C"}
package/dist/preset.js ADDED
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sqliteStorage = sqliteStorage;
4
+ const node_fs_1 = require("node:fs");
5
+ const node_path_1 = require("node:path");
6
+ const SqliteArchiveStore_1 = require("./SqliteArchiveStore");
7
+ const SqliteBranchRegistry_1 = require("./SqliteBranchRegistry");
8
+ const SqliteEventStore_1 = require("./SqliteEventStore");
9
+ const SqliteLeaseStore_1 = require("./SqliteLeaseStore");
10
+ const SqliteSnapshotStore_1 = require("./SqliteSnapshotStore");
11
+ /**
12
+ * A `defineConfig({ storage })` preset for embedded SQLite. Returns a `custom`
13
+ * storage descriptor with the SQLite stores constructed — so `@loomwork/app` never
14
+ * needs to know SQLite exists (ADR 0043: 1P/3P storage backends are symmetric,
15
+ * each supplied as a preset, none privileged with a `kind`).
16
+ *
17
+ * `leaseStore` (ADR 0130 D11) is the heartbeat-lease store CO-LOCATED with the event store: the
18
+ * same `events.db`, so the lease and the log share one failure domain. It is an accessor on
19
+ * the factory's result, not part of `CustomStorage`, so there is no `EventStore` SPI change;
20
+ * `defineConfig` does not read it yet. It is opened lazily on first access (its own connection) and
21
+ * closed by `eventStore.close()`.
22
+ */
23
+ function sqliteStorage(options = {}) {
24
+ const dir = options.dir ?? ".loom";
25
+ (0, node_fs_1.mkdirSync)(dir, { recursive: true });
26
+ const eventStore = new SqliteEventStore_1.SqliteEventStore((0, node_path_1.join)(dir, "events.db"));
27
+ // Lazy: a second events.db connection + migrate is opened only when something reads
28
+ // `leaseStore`, and it is closed together with the event store (as the Postgres preset does).
29
+ let lease;
30
+ const closeEvents = eventStore.close.bind(eventStore);
31
+ eventStore.close = async () => {
32
+ await closeEvents();
33
+ await lease?.close();
34
+ };
35
+ return {
36
+ kind: "custom",
37
+ eventStore,
38
+ snapshotStore: new SqliteSnapshotStore_1.SqliteSnapshotStore((0, node_path_1.join)(dir, "snapshots.db"), {
39
+ ...(options.snapshotCodec !== undefined && { codec: options.snapshotCodec }),
40
+ }),
41
+ archiveStore: new SqliteArchiveStore_1.SqliteArchiveStore((0, node_path_1.join)(dir, "archive.db")),
42
+ get leaseStore() {
43
+ lease ??= new SqliteLeaseStore_1.SqliteLeaseStore((0, node_path_1.join)(dir, "events.db"));
44
+ return lease;
45
+ },
46
+ ...(options.branching === true && {
47
+ branchRegistry: new SqliteBranchRegistry_1.SqliteBranchRegistry((0, node_path_1.join)(dir, "branches.db")),
48
+ }),
49
+ };
50
+ }
51
+ //# sourceMappingURL=preset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preset.js","sourceRoot":"","sources":["../src/preset.ts"],"names":[],"mappings":";;AAoCA,sCA6BC;AAjED,qCAAoC;AACpC,yCAAiC;AAIjC,6DAA0D;AAC1D,iEAA8D;AAC9D,yDAAsD;AACtD,yDAAsD;AACtD,+DAA4D;AAe5D;;;;;;;;;;;GAWG;AACH,SAAgB,aAAa,CAC3B,UAAgC,EAAE;IAElC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC;IACnC,IAAA,mBAAS,EAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpC,MAAM,UAAU,GAAG,IAAI,mCAAgB,CAAC,IAAA,gBAAI,EAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC;IAChE,oFAAoF;IACpF,8FAA8F;IAC9F,IAAI,KAAmC,CAAC;IACxC,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACtD,UAAU,CAAC,KAAK,GAAG,KAAK,IAAI,EAAE;QAC5B,MAAM,WAAW,EAAE,CAAC;QACpB,MAAM,KAAK,EAAE,KAAK,EAAE,CAAC;IACvB,CAAC,CAAC;IACF,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,UAAU;QACV,aAAa,EAAE,IAAI,yCAAmB,CAAC,IAAA,gBAAI,EAAC,GAAG,EAAE,cAAc,CAAC,EAAE;YAChE,GAAG,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC;SAC7E,CAAC;QACF,YAAY,EAAE,IAAI,uCAAkB,CAAC,IAAA,gBAAI,EAAC,GAAG,EAAE,YAAY,CAAC,CAAC;QAC7D,IAAI,UAAU;YACZ,KAAK,KAAK,IAAI,mCAAgB,CAAC,IAAA,gBAAI,EAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC;YACvD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,GAAG,CAAC,OAAO,CAAC,SAAS,KAAK,IAAI,IAAI;YAChC,cAAc,EAAE,IAAI,2CAAoB,CAAC,IAAA,gBAAI,EAAC,GAAG,EAAE,aAAa,CAAC,CAAC;SACnE,CAAC;KACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type Database from "better-sqlite3";
2
+ export declare function migrate(db: Database.Database): void;
3
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,wBAAgB,OAAO,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI,CA6DnD"}
package/dist/schema.js ADDED
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.migrate = migrate;
4
+ function migrate(db) {
5
+ db.exec(`
6
+ CREATE TABLE IF NOT EXISTS events (
7
+ id TEXT NOT NULL,
8
+ workflow_id TEXT NOT NULL,
9
+ execution_id TEXT NOT NULL,
10
+ event_type TEXT NOT NULL,
11
+ sequence INTEGER NOT NULL,
12
+ timestamp INTEGER NOT NULL,
13
+ payload TEXT NOT NULL,
14
+ metadata TEXT,
15
+ PRIMARY KEY (id),
16
+ UNIQUE (execution_id, sequence)
17
+ );
18
+
19
+ CREATE INDEX IF NOT EXISTS idx_events_exec
20
+ ON events (execution_id, sequence ASC);
21
+
22
+ CREATE TABLE IF NOT EXISTS executions (
23
+ id TEXT PRIMARY KEY,
24
+ workflow_id TEXT NOT NULL,
25
+ workflow_version TEXT NOT NULL,
26
+ status TEXT NOT NULL,
27
+ created_at INTEGER NOT NULL,
28
+ updated_at INTEGER NOT NULL
29
+ );
30
+
31
+ -- Branch registry: git-style movable pointers (refs) into the event-log
32
+ -- topology. A ref names an execution head; promote() repoints a ref onto a
33
+ -- winning execution ("pick-a-winner"). No merge — see BranchRegistry.
34
+ CREATE TABLE IF NOT EXISTS refs (
35
+ name TEXT PRIMARY KEY,
36
+ execution_id TEXT NOT NULL,
37
+ tip INTEGER NOT NULL,
38
+ parent_execution_id TEXT,
39
+ fork_sequence INTEGER,
40
+ created_at INTEGER NOT NULL,
41
+ updated_at INTEGER NOT NULL
42
+ );
43
+
44
+ -- Immutable fork DAG: each forked execution records its parent and the
45
+ -- sequence it forked at. One row per child execution.
46
+ -- #380 — durable ownership of a RUNNING execution; the primary key IS the exclusion.
47
+ CREATE TABLE IF NOT EXISTS leases (
48
+ execution_id TEXT NOT NULL PRIMARY KEY,
49
+ owner TEXT NOT NULL,
50
+ expires_at INTEGER NOT NULL
51
+ );
52
+ CREATE INDEX IF NOT EXISTS idx_leases_expiry ON leases (expires_at ASC);
53
+
54
+ CREATE TABLE IF NOT EXISTS lineage (
55
+ execution_id TEXT PRIMARY KEY,
56
+ parent_execution_id TEXT NOT NULL,
57
+ fork_sequence INTEGER NOT NULL,
58
+ created_at INTEGER NOT NULL
59
+ );
60
+
61
+ CREATE INDEX IF NOT EXISTS idx_lineage_parent
62
+ ON lineage (parent_execution_id);
63
+ `);
64
+ migrateIncarnation(db);
65
+ }
66
+ /**
67
+ * ADR 0129 — the store-assigned incarnation of an execution, kept in STORE METADATA only (never
68
+ * in an envelope, so replay stays byte-identical). It lives on the sequence-0 row and is filled
69
+ * by a trigger from a one-row counter, so EVERY way a sequence 0 can land (append, appendBatch,
70
+ * copyPrefix, appendIfUnchanged, another process) assigns one. The counter is never reset, so a
71
+ * deleted-and-recreated id always gets a larger value. Logs created before this column existed
72
+ * keep NULL (no backfill): their anchor stays the legacy `timestamp:id`. All steps are
73
+ * idempotent and tolerate two processes migrating at once.
74
+ */
75
+ function migrateIncarnation(db) {
76
+ const columns = db.prepare("PRAGMA table_info(events)").all();
77
+ if (!columns.some((c) => c.name === "incarnation")) {
78
+ try {
79
+ db.exec("ALTER TABLE events ADD COLUMN incarnation INTEGER");
80
+ }
81
+ catch (err) {
82
+ // A concurrent migrator added it between our check and our ALTER.
83
+ if (!/duplicate column name/i.test(String(err.message)))
84
+ throw err;
85
+ }
86
+ }
87
+ db.exec(`
88
+ CREATE TABLE IF NOT EXISTS incarnation_counter (
89
+ id INTEGER PRIMARY KEY CHECK (id = 1),
90
+ n INTEGER NOT NULL
91
+ );
92
+ INSERT OR IGNORE INTO incarnation_counter (id, n) VALUES (1, 0);
93
+ CREATE TRIGGER IF NOT EXISTS trg_events_incarnation
94
+ AFTER INSERT ON events
95
+ WHEN NEW.sequence = 0
96
+ BEGIN
97
+ UPDATE incarnation_counter SET n = n + 1 WHERE id = 1;
98
+ UPDATE events SET incarnation = (SELECT n FROM incarnation_counter WHERE id = 1)
99
+ WHERE id = NEW.id;
100
+ END;
101
+ `);
102
+ }
103
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":";;AAEA,0BA6DC;AA7DD,SAAgB,OAAO,CAAC,EAAqB;IAC3C,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DP,CAAC,CAAC;IACH,kBAAkB,CAAC,EAAE,CAAC,CAAC;AACzB,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,kBAAkB,CAAC,EAAqB;IAC/C,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,CAAuB,2BAA2B,CAAC,CAAC,GAAG,EAAE,CAAC;IACpF,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,CAAC,EAAE,CAAC;QACnD,IAAI,CAAC;YACH,EAAE,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;QAC/D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,kEAAkE;YAClE,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,MAAM,CAAE,GAAa,CAAC,OAAO,CAAC,CAAC;gBAAE,MAAM,GAAG,CAAC;QAChF,CAAC;IACH,CAAC;IACD,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;GAcP,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type Database from "better-sqlite3";
2
+ export declare function migrate(db: Database.Database): void;
3
+ //# sourceMappingURL=snapshotSchema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshotSchema.d.ts","sourceRoot":"","sources":["../src/snapshotSchema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,wBAAgB,OAAO,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAcnD"}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.migrate = migrate;
4
+ function migrate(db) {
5
+ db.exec(`
6
+ CREATE TABLE IF NOT EXISTS snapshots (
7
+ id TEXT PRIMARY KEY,
8
+ execution_id TEXT NOT NULL,
9
+ workflow_id TEXT NOT NULL,
10
+ sequence INTEGER NOT NULL,
11
+ state TEXT NOT NULL,
12
+ created_at INTEGER NOT NULL
13
+ );
14
+
15
+ CREATE INDEX IF NOT EXISTS idx_snapshots_exec
16
+ ON snapshots (execution_id, sequence DESC);
17
+ `);
18
+ }
19
+ //# sourceMappingURL=snapshotSchema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshotSchema.js","sourceRoot":"","sources":["../src/snapshotSchema.ts"],"names":[],"mappings":";;AAEA,0BAcC;AAdD,SAAgB,OAAO,CAAC,EAAqB;IAC3C,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;GAYP,CAAC,CAAC;AACL,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,65 @@
1
1
  {
2
2
  "name": "@loomwork/plugin-sqlite",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.1.0",
4
+ "description": "SQLite store plugin for Loom — embedded EventStore, SnapshotStore, BranchRegistry, TimerStore, DurableStateStore, ReadModelStore, ContentStore and MemoryStore over better-sqlite3, behind the same interfaces as the in-memory reference. The zero-server durable backend; keeps the native driver out of the kernel packages.",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "require": "./dist/index.js",
11
+ "default": "./dist/index.js"
12
+ }
13
+ },
14
+ "dependencies": {
15
+ "better-sqlite3": "^11.5.0",
16
+ "@loomwork/core": "^0.1.0",
17
+ "@loomwork/event-runtime": "^0.1.0",
18
+ "@loomwork/snapshot-runtime": "^0.1.0",
19
+ "@loomwork/plugin-read-model": "^0.1.0",
20
+ "@loomwork/plugin-content": "^0.1.0",
21
+ "@loomwork/memory": "^0.1.0",
22
+ "@loomwork/plugin-durable-state": "^0.1.0",
23
+ "@loomwork/plugin-kit": "^0.1.0"
24
+ },
25
+ "devDependencies": {
26
+ "@types/better-sqlite3": "^7.6.12",
27
+ "@types/node": "^22.0.0",
28
+ "typescript": "^5.6.3",
29
+ "vitest": "^2.1.8",
30
+ "@loomwork/conformance": "0.1.0"
31
+ },
32
+ "license": "Apache-2.0",
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "git+https://github.com/chhetrisushil/loom.git",
36
+ "directory": "plugins/sqlite"
37
+ },
38
+ "files": [
39
+ "dist",
40
+ "src",
41
+ "!src/**/*.test.ts",
42
+ "!src/**/*.test.tsx",
43
+ "!src/**/__tests__",
44
+ "!src/**/__fixtures__",
45
+ "!src/**/__snapshots__",
46
+ "!src/**/__golden__",
47
+ "LICENSE",
48
+ "NOTICE"
49
+ ],
50
+ "publishConfig": {
51
+ "access": "public",
52
+ "tag": "next"
53
+ },
54
+ "engines": {
55
+ "node": ">=20.0.0"
56
+ },
57
+ "scripts": {
58
+ "build": "tsc --build",
59
+ "dev": "tsc --build --watch",
60
+ "test": "vitest run",
61
+ "test:watch": "vitest",
62
+ "clean": "rm -rf dist tsconfig.tsbuildinfo",
63
+ "typecheck:tests": "tsc -p tsconfig.test.json"
64
+ }
6
65
  }