@godspeedai/cognate-store-sqlite 0.1.1 → 0.1.2

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 (2) hide show
  1. package/README.md +75 -38
  2. package/package.json +2 -2
package/README.md CHANGED
@@ -1,40 +1,77 @@
1
1
  # @godspeedai/cognate-store-sqlite
2
2
 
3
- Authoritative `DurableStore` on `bun:sqlite` (spec §13).
4
-
5
- ## Tables (spec §13.2)
6
-
7
- `schema_versions` (migrations), `event_streams` (per-stream version), `events` (envelope only —
8
- position, event_id, stream_id/sequence, type, timing, causality, semantic ref, metadata),
9
- `payloads` (event_id → JSON payload, separate from the envelope so `erasePayload` can delete
10
- content without touching causality), `idempotency` (scope+key → fingerprint/result/event_ids),
11
- `records` (collection+id → version/JSON value, CAS), `outbox` (id, topic, payload, status,
12
- attempts, `claimed_until` lease), `projection_checkpoints`, `projection_state`, `blobs`
13
- (sha256-addressed bytes).
14
-
15
- ## Transaction boundary
16
-
17
- `commit()` runs the entire decision — envelope validation, idempotency lookup, stream/record CAS,
18
- event/record/outbox writes, idempotency recording — inside one `BEGIN IMMEDIATE` transaction.
19
- Any failure throws and rolls back everything; `onCommitted` listeners fire only after `COMMIT`
20
- returns. `commitProjection` and `erasePayload` are each their own single transaction. bun:sqlite
21
- is synchronous and the store performs no `await` before entering a transaction, so concurrent
22
- `commit()` calls in one process serialize naturally through the JS event loop — exactly one wins
23
- a stream-version race, the rest see `ConcurrencyError`.
24
-
25
- ## Durability settings
26
-
27
- `journal_mode=WAL`, `synchronous=FULL` (fsync on every commit — durability over speed, per spec
28
- §31.2 "fail closed": a decision must never be reported committed before SQLite confirms it),
29
- `foreign_keys=ON`, `busy_timeout=5000`. `secure_delete=ON` so `erasePayload` overwrites freed
30
- pages instead of merely unlinking them; it also runs `PRAGMA wal_checkpoint(TRUNCATE)` so no
31
- plaintext lingers in the WAL either.
32
-
33
- ## Limits
34
-
35
- Single-process writer: correctness relies on one Node/Bun process holding the connection and on
36
- bun:sqlite's synchronous API for in-process serialization, not on SQLite's file locking for
37
- cross-process write concurrency. Multiple processes writing the same file concurrently will hit
38
- `SQLITE_BUSY` after `busy_timeout` rather than being serialized by this store. Back up by copying
39
- the `.sqlite` file plus its `-wal`/`-shm` siblings only after a checkpoint (or use the SQLite
40
- backup API); a bare copy of the main file while WAL is active can miss committed data.
3
+ Durable, transactional event storage for Cognate applications, built on `bun:sqlite`. One SQLite
4
+ file holds an application's entire authoritative history: events, records, idempotency results,
5
+ outbox intents, and blobs — committed atomically per decision.
6
+
7
+ **When to use this package:** any Cognate app that must survive restarts. Use
8
+ [`@godspeedai/cognate-store-memory`](https://www.npmjs.com/package/@godspeedai/cognate-store-memory)
9
+ for tests and throwaway prototypes instead. Both implement the same
10
+ `@godspeedai/cognate-events` store contract, so an app can switch stores with one line.
11
+
12
+ ## Installation
13
+
14
+ ```sh
15
+ bun add @godspeedai/cognate-store-sqlite
16
+ ```
17
+
18
+ Requires [Bun](https://bun.sh) >= 1.4.0 (the store uses Bun's built-in `bun:sqlite`).
19
+
20
+ ## Quick start
21
+
22
+ ```ts
23
+ import { openSqliteStore } from "@godspeedai/cognate-store-sqlite";
24
+
25
+ const store = openSqliteStore({ path: "./app.sqlite" });
26
+ ```
27
+
28
+ Pass the store to `createRuntime` from
29
+ [`@godspeedai/cognate-runtime-bun`](https://www.npmjs.com/package/@godspeedai/cognate-runtime-bun)
30
+ to make an entire agent runtime durable — `createRuntime` also accepts a file path directly
31
+ (`store: "./app.sqlite"`), which selects this store:
32
+
33
+ ```ts
34
+ import { createRuntime } from "@godspeedai/cognate-runtime-bun";
35
+
36
+ const runtime = await createRuntime({ store: "./app.sqlite" /* agents, policy, ... */ });
37
+ ```
38
+
39
+ The store implements the `DurableStore` contract from
40
+ [`@godspeedai/cognate-events`](https://www.npmjs.com/package/@godspeedai/cognate-events):
41
+ `commit` applies an atomic batch per decision (stream appends with expected versions, record
42
+ compare-and-swap writes, outbox intents, idempotency results), and `ConcurrencyError` is thrown
43
+ when a concurrent writer loses a stream-version race.
44
+
45
+ ## What the schema guarantees
46
+
47
+ Every committed decision is one SQLite transaction (`BEGIN IMMEDIATE`): envelope validation,
48
+ per-stream version checks, record compare-and-swap writes, outbox intents, and idempotency
49
+ recording succeed or roll back together. A duplicate idempotency key returns the originally
50
+ recorded result instead of re-applying the decision.
51
+
52
+ Durability is configured for correctness over speed: `journal_mode=WAL` with
53
+ `synchronous=FULL` (fsync on every commit), so a decision is never reported committed before
54
+ SQLite has confirmed it. Payload erasure overwrites freed pages (`secure_delete`) and
55
+ checkpoints the WAL, so erased content does not linger in sidecar files.
56
+
57
+ ## Limitations
58
+
59
+ - **One writer process.** Concurrent `commit` calls in one process serialize naturally, but
60
+ multiple processes writing the same file will hit `SQLITE_BUSY` after the 5-second busy
61
+ timeout rather than being serialized by this store.
62
+ - **Back up carefully.** Copy the `.sqlite` file plus its `-wal`/`-shm` siblings only after a
63
+ WAL checkpoint (or use SQLite's backup API) — a bare copy while WAL is active can miss
64
+ committed data.
65
+
66
+ ## Related packages
67
+
68
+ - [`@godspeedai/cognate-events`](https://www.npmjs.com/package/@godspeedai/cognate-events) — the
69
+ store contract and conformance kit this package implements.
70
+ - [`@godspeedai/cognate-store-memory`](https://www.npmjs.com/package/@godspeedai/cognate-store-memory) —
71
+ the in-memory implementation of the same contract.
72
+ - [`@godspeedai/cognate`](https://www.npmjs.com/package/@godspeedai/cognate) — the SDK umbrella;
73
+ the easiest way to get a runtime backed by this store.
74
+
75
+ ## License
76
+
77
+ Apache-2.0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@godspeedai/cognate-store-sqlite",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Authoritative DurableStore on bun:sqlite (spec §13).",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -22,6 +22,6 @@
22
22
  ".": "./src/index.ts"
23
23
  },
24
24
  "dependencies": {
25
- "@godspeedai/cognate-events": "^0.1.1"
25
+ "@godspeedai/cognate-events": "^0.1.2"
26
26
  }
27
27
  }