@crvouga/mockingbird-service-sqlite 1.2.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,30 @@
1
1
  # Changelog — @crvouga/mockingbird-service-sqlite
2
2
 
3
- ## 1.2.1 (2026-09-30)
3
+ ## 2.0.0 (2026-10-04)
4
+
5
+ ### ⚠️ Breaking changes
6
+
7
+ - isolate internal routes ([5e19b21](https://github.com/crvouga/mockingbird/commit/5e19b21d403acc74b04778a8b545e80bcbdf8d51))
8
+
9
+ ### Features
10
+
11
+ - publish agent package indexes ([eca61d3](https://github.com/crvouga/mockingbird/commit/eca61d358b86982cf0b777ae8bd7feaa3663aaa6))
12
+
13
+ ### Fixes and improvements
14
+
15
+ - honor configured prefixes ([4f569d7](https://github.com/crvouga/mockingbird/commit/4f569d74ca8089f2ed5e33a1abf32b90973f41dd))
16
+
17
+ ## 1.3.0 (2026-09-30)
18
+
19
+ ### Features
20
+
21
+ - record SQL timelines and serve the admin explorer ([8ced17a](https://github.com/crvouga/mockingbird/commit/8ced17ac398e386ef4e9d7e01fc7744c34b95d07))
22
+
23
+ ### Fixes and improvements
24
+
25
+ - typecheck SQL admin timelines without a built sqlite port ([072daf4](https://github.com/crvouga/mockingbird/commit/072daf439f3967823149d7b0a8a9ce664d25097c))
26
+
27
+ ## 1.2.1 (2026-09-29)
4
28
 
5
29
  ### Fixes and improvements
6
30
 
package/DISCOVERY.md ADDED
@@ -0,0 +1,48 @@
1
+ # @crvouga/mockingbird-service-sqlite discovery
2
+
3
+ This is the installed-package index for coding agents and tooling. All relative links resolve
4
+ inside `node_modules/@crvouga/mockingbird-service-sqlite/`; no repository checkout is needed to discover the mock's
5
+ supported surface or documented behavior.
6
+
7
+ ## Capability and behavior sources
8
+
9
+ | Question | Authoritative file | What it contains |
10
+ | --- | --- | --- |
11
+ | Behaviour and integration | [`README.md`](README.md) | Routes, state transitions, auth, webhooks, controls, presets and deliberate omissions. |
12
+ | Exact capabilities | [`COMPATIBILITY.md`](COMPATIBILITY.md) | Supported, unsupported and parity-covered operations or commands, including reasons for gaps. |
13
+ | Public API | [`dist/index.d.ts`](dist/index.d.ts) | The installed package's exact TypeScript exports and signatures. |
14
+ | Package metadata | [`package.json`](package.json) | Runtime/entry-point claims, vendor links, parity scope/tier and `mockingbird.discovery`. |
15
+
16
+ Read these together: the contract/capability matrix says *what* is available, while the README
17
+ defines stateful behavior, lifecycle rules, test controls, and intentional oracle differences.
18
+ If prose and an executable surface disagree, report a parity mismatch instead of adding a
19
+ consumer-side workaround.
20
+
21
+ ## Parity and oracle
22
+
23
+ - Declared parity surface: **In-memory SQL engine**.
24
+ - Oracle: **SQLite via bun:sqlite (version pinned in COMPATIBILITY.md)**.
25
+ - Repository command: `bun run --cwd packages/service/sqlite test:sqlite-compat`.
26
+ - Evidence model: Fail-closed differential contracts compare results, errors, counters and logical state.
27
+
28
+ The npm package contains evidence summaries and the exact contract, not credentials or the
29
+ repository-only parity harness. Self-parity/property and acceptance tests run in the Mockingbird
30
+ repository; live parity is an additional oracle check, not a substitute for the packaged matrix.
31
+
32
+ ## Runtime introspection
33
+
34
+ - `README.md public test controls`
35
+ - `COMPATIBILITY.md compatibility and divergence evidence`
36
+
37
+ For HTTP services, use `x-mockingbird-namespace` (or the documented credential/path carrier) so
38
+ parallel tests do not share state. Admin state, journal, metrics and fault-preset endpoints are
39
+ designed for assertions and diagnosis by consuming test suites.
40
+
41
+ ## Report a mismatch or missing capability
42
+
43
+ Follow the [agent reporting contract](https://github.com/crvouga/mockingbird/blob/main/docs/REPORTING_ISSUES.md). Include package version,
44
+ operation/command, a minimal redacted request, actual mock result, expected oracle result or vendor
45
+ documentation, and whether the mismatch appears in the matrix. Never include keys, tokens,
46
+ customer data, prompts, PHI, card data, or unredacted recordings.
47
+
48
+ Service key: `sqlite`.
package/README.md CHANGED
@@ -145,16 +145,39 @@ The mocks create their own tables (`mockingbird_records`, `mockingbird_sequences
145
145
  resetting one mock leaves the others' data in a shared database intact. Any other client with the same sync surface (better-sqlite3, a
146
146
  wrapped `bun:sqlite`) also satisfies the port.
147
147
 
148
+ ### Socket
149
+
150
+ SQLite has no client/server protocol, so the stock `sqlite3` CLI cannot attach to this
151
+ engine. `@crvouga/mockingbird-service-sqlite/socket` is a Node entry (it needs `node:net`)
152
+ that listens on `sqlite://host:port/name` and speaks a length-prefixed JSON frame. The
153
+ in-package `connect(uri)` client runs statements against it. Portable queries, including
154
+ from a browser, go through the admin API (`POST /__admin/sql/query`) instead.
155
+
156
+ ```ts
157
+ import { connect, serve } from "@crvouga/mockingbird-service-sqlite/socket"
158
+
159
+ const server = await serve("sqlite://127.0.0.1:0/app")
160
+ const db = await connect(server.url)
161
+ await db.exec("CREATE TABLE notes (body TEXT)")
162
+ await db.close()
163
+ await server.close()
164
+ ```
165
+
166
+ `mockingbird-sqlite serve` prints that URI. `createAdmin` from
167
+ `@crvouga/mockingbird-service-sqlite/admin` serves the same `/__admin` surface as every
168
+ other mock, including the table explorer.
169
+
148
170
  ### Method semantics
149
171
 
150
172
  | Method | Behaviour |
151
173
  | --- | --- |
152
174
  | `exec(sql)` | Runs all semicolon-separated statements; **discards** row results (`void`). Does **not** accept bind parameters. Read `db.changes` / `db.lastInsertRowid` afterwards if needed (counters reflect the **most recent** completed statement, matching SQLite). |
153
- | `query(sql, params?, { at? }?)` | **Single statement only** (trailing `;` is fine). Returns all rows. `at` queries an immutable checkpoint without changing live state. Multi-statement scripts throw `misuse`. |
175
+ | `query(sql, params?, { at? }?)` | **Single statement only** (trailing `;` is fine). Returns all rows. `at` is a `Snapshot` or a timeline checkpoint id and queries that checkpoint without changing live state. Multi-statement scripts throw `misuse`. |
154
176
  | `prepare(sql)` | **Single statement only**. Parses immediately; the AST is reused. Pass binds as rest args to `run` / `all` / `get` / `result` on each call. |
155
177
  | `transaction(fn)` | If idle: `BEGIN`, `fn()`, `COMMIT`, or `ROLLBACK` + rethrow. If already in a transaction: nested savepoint. A nested SQL `BEGIN` still errors. `close()` inside `fn` throws `misuse`. |
156
- | `snapshot()` | Freeze a reusable `Snapshot` template (no encode). Illegal inside a transaction. |
157
- | `checkpoint()` / `branch(at?)` | Name a COW snapshot as a checkpoint; open an isolated branch from it (or current state). |
178
+ | `snapshot()` | Freeze a reusable `Snapshot` template (no encode) and commit it on the followed timeline branch. Illegal inside a transaction. |
179
+ | `checkpoint()` / `branch(at?)` | `checkpoint` records the same timeline point as `snapshot`. `branch` opens an isolated database from a snapshot (or the current state). |
180
+ | `record(branch?)` / `fork(name, at?)` / `checkout(id, branch?)` / `reset()` | Timeline history on this database. `record` commits the live state. `fork` adds a branch pointer and does not switch live state. `checkout` installs a checkpoint. `reset` returns to the origin checkpoint on `main`. `history` lists heads and checkpoints. |
158
181
  | `Snapshot.open()` | Copy-on-write fork from a template. The parent stays open. |
159
182
  | `Snapshot.encode()` | Lazy SQLM blob for persistence / worker boot (computed once, cached). |
160
183
  | `Snapshot.decode(bytes)` | Decode a blob once per `Uint8Array` (WeakMap); later `open()` calls are copy-on-write. |
@@ -295,24 +318,44 @@ Stable runtime exports of the main entry:
295
318
  | `Statement` | Class returned by `db.prepare(sql)` (not constructed directly): `run`, `all`, `get`, `result`. |
296
319
  | `SqliteError` | Error class thrown for SQL and API errors: `category` (`ErrorCategory`), `sqliteCode` / `code` (SQLite result-code name, e.g. `"SQLITE_CONSTRAINT_UNIQUE"`; default `"SQLITE_ERROR"`). |
297
320
 
298
- Signatures (types are exported too: `DatabaseOptions`, `RunResult`, `ResultSet`, `ErrorCategory`,
299
- `BindValue`, `QueryRow`, `QueryValue`):
321
+ Signatures (types are exported too: `DatabaseOptions`, `HistoryCheckpoint`, `DatabaseHistory`,
322
+ `RunResult`, `ResultSet`, `ErrorCategory`, `BindValue`, `QueryRow`, `QueryValue`):
300
323
 
301
324
  ```ts
302
325
  interface DatabaseOptions {
303
326
  seed?: number | bigint // default 1; ignored when random is "os"
304
327
  random?: "deterministic" | "os" // default "deterministic"; "os" is CSPRNG like SQLite
305
328
  now?: Date | (() => Date) | "system" // default 2000-01-01T00:00:00.000Z; "system" is wall clock
329
+ maxCheckpoints?: number // timeline checkpoints to retain; default 1000
330
+ }
331
+
332
+ interface HistoryCheckpoint {
333
+ id: string
334
+ branch: string
335
+ parent: string | null
336
+ at: number
337
+ }
338
+
339
+ interface DatabaseHistory {
340
+ readonly size: number
341
+ head(branch?: string): HistoryCheckpoint | undefined
342
+ branches(): Readonly<Record<string, string>>
343
+ checkpoints(): readonly HistoryCheckpoint[]
306
344
  }
307
345
 
308
346
  declare class Database {
309
347
  constructor(options?: DatabaseOptions)
310
348
  exec(sql: string): void
311
- query<T = QueryRow>(sql: string, params?: readonly BindValue[], options?: { at?: Snapshot }): T[]
349
+ query<T = QueryRow>(sql: string, params?: readonly BindValue[], options?: { at?: Snapshot | string }): T[]
312
350
  prepare(sql: string): Statement
313
351
  transaction<T>(fn: () => T): T
314
352
  snapshot(): Snapshot
315
353
  checkpoint(): Snapshot
354
+ record(branch?: string): HistoryCheckpoint
355
+ fork(name: string, at?: string): HistoryCheckpoint
356
+ checkout(id: string, branch?: string): HistoryCheckpoint
357
+ reset(): HistoryCheckpoint
358
+ readonly history: DatabaseHistory
316
359
  branch(at?: Snapshot): Database
317
360
  close(): void // also [Symbol.dispose] when available
318
361
  readonly changes: number
@@ -0,0 +1,13 @@
1
+ import type { Database, DatabaseOptions } from "./api/database.js";
2
+
3
+ export interface AdminOptions {
4
+ database?: Database;
5
+ adminKey?: string;
6
+ databaseOptions?: DatabaseOptions;
7
+ }
8
+
9
+ export interface AdminServer {
10
+ fetch(request: Request): Promise<Response>;
11
+ }
12
+
13
+ export declare function createAdmin(options?: AdminOptions): AdminServer;