Skip to content

Finish #46: swap adapter-local to native SQLite, make sqljs browser-only, update docs#86

Merged
cuibonobo merged 1 commit into
mainfrom
claude/issue-45-design-review-1jgkcj
Jul 11, 2026
Merged

Finish #46: swap adapter-local to native SQLite, make sqljs browser-only, update docs#86
cuibonobo merged 1 commit into
mainfrom
claude/issue-45-design-review-1jgkcj

Conversation

@cuibonobo

Copy link
Copy Markdown
Member

Summary

Closes out the remaining items of #46: §5 (adapter-local swap), §2 (sqljs browser cleanup), and §6 (docs).

adapter-local:

  • Swaps from record-adapter-sqljs to record-adapter-sqlite (NativeSQLiteRecordAdapter) — invisible at the API surface, per the issue's "none intended" breaking-changes note. Node engine floor rises to >=22.5.0 to match.
  • Bearer tokens now go through NativeTokenStore at a separate sibling file (<path>.tokens), opened lazily on first token method call — so plain single-app embedded use that never touches tokens never creates that file.
  • Adds deleteUnreferencedAttachmentRecords delegation, which turned out to be missing even before this swap — Stack.deleteAttachment()'s atomic path was silently never engaging through LocalAdapter without it.

record-adapter-sqljs (browser-only now, per the issue's breaking-changes section — no browser consumers exist yet to break):

  • initialize()/open() take { entityId, timezone, persist? } / { bytes, persist? } instead of a path. No more fs, node:crypto, or Buffer — durability is the embedder's job now (OPFS, IndexedDB, a download), wired through an optional persist(bytes) => Promise<void> callback called after every write.
  • No storage-ownership lock (no path, no PID concept in a browser) and no token methods (moved out entirely per Split SQLite support: native record-adapter-sqlite for Node, browser-only record-adapter-sqljs, and a StackTokenStore interface in core #46 §4 — a browser adapter has no business shipping bearer-token storage).
  • sqlite-shared's SharedSqlRecordLogic.onWrite is now awaited rather than fire-and-forget, since sqljs's persist callback is async; the native adapter's write path is unaffected (it has no onWrite at all).
  • Test suite rewritten for the new API (77 tests) — expected, since this is an intentionally breaking change unlike the earlier SqlExecutor consolidation where zero test changes was the whole point.

Docs (README, spec.md):

  • Package tables: add record-adapter-sqlite, reposition record-adapter-sqljs as browser-only.
  • Rewrote spec.md's "Concurrency & storage ownership" section — the PID-lock-file and atomic-persist guidance it described now applies to record-adapter-sqlite (whose WAL journaling actually makes most of it moot) and the still-planned adapter-json, not sqljs, which no longer touches a file at all.
  • Fixed the capabilities table's blanket "FTS5" claim to distinguish the native adapter (FTS5) from sqljs (FTS4), and the wire-format token-store aside to name StackTokenStore/NativeTokenStore instead of the old inline SQLiteAdapter token methods.

Test plan

  • pnpm build / pnpm typecheck / pnpm lint / pnpm format:check — full monorepo, clean
  • pnpm test — full monorepo, 567 tests passing, no regressions
  • adapter-local's existing 17 tests pass unmodified against the new native-backed implementation, confirming the "no API surface change" promise; added 3 new tests (lazy token-store file creation, and deleteUnreferencedAttachmentRecords delegation)
  • record-adapter-sqljs's test suite rewritten (77 tests) for the new bytes/persist-callback API: in-memory-only operation, persist-callback invocation on every write, open-from-previously-persisted-bytes roundtrip, re-persisting after reopening, plus all the existing CRUD/query/FTS/association/version/FK-enforcement coverage carried over unchanged in behavior

Closes #46.

https://claude.ai/code/session_01RRLiGUZC344E3pgNEGAe5W


Generated by Claude Code

Completes #46: the remaining §5 (adapter-local swap), §2 (sqljs
browser cleanup), and §6 (docs) items.

adapter-local:
- Swaps from record-adapter-sqljs to record-adapter-sqlite
  (NativeSQLiteRecordAdapter) — invisible at the API surface, per the
  issue's "none intended" breaking-changes note. Node engine floor
  rises to >=22.5.0 to match.
- Bearer tokens now go through NativeTokenStore at a separate sibling
  file (`<path>.tokens`), opened lazily on first token method call so
  plain single-app embedded use that never touches tokens never
  creates it.
- Adds deleteUnreferencedAttachmentRecords delegation, which was
  missing even before this swap — Stack.deleteAttachment()'s atomic
  path silently never engaged through LocalAdapter without it.

record-adapter-sqljs (browser-only, per the issue's breaking-changes
section — no browser consumers exist yet to break):
- initialize()/open() take `{ entityId, timezone, persist? }` /
  `{ bytes, persist? }` instead of a path. No more fs, node:crypto, or
  Buffer — durability is the embedder's job now (OPFS, IndexedDB, a
  download), wired through an optional `persist(bytes) =>
  Promise<void>` callback called after every write.
- No storage-ownership lock (no path, no PID concept in a browser) and
  no token methods (moved out entirely, per #46 §4 — a browser adapter
  has no business shipping bearer-token storage).
- sqlite-shared's SharedSqlRecordLogic.onWrite is now awaited rather
  than fire-and-forget, since sqljs's persist callback is async;
  native's write path is unaffected (it has no onWrite at all).
- Test suite rewritten for the new API (77 tests) — expected given
  this is an intentionally breaking change, unlike the earlier
  SqlExecutor consolidation where zero test changes was the point.

Docs (README, spec.md):
- Package tables: add record-adapter-sqlite, reposition
  record-adapter-sqljs as browser-only.
- Rewrote spec.md's "Concurrency & storage ownership" section — the
  PID lock file and atomic-persist guidance it described now applies
  to record-adapter-sqlite (whose WAL journaling actually makes most
  of it moot) and the still-planned adapter-json, not sqljs, which no
  longer touches a file at all.
- Fixed the capabilities table's blanket "FTS5" claim to distinguish
  the native adapter (FTS5) from sqljs (FTS4), and the wire-format
  token-store aside to name StackTokenStore/NativeTokenStore instead
  of the old inline SQLiteAdapter token methods.

Full monorepo: 567 tests passing, clean build/typecheck/lint/format.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RRLiGUZC344E3pgNEGAe5W
@cuibonobo cuibonobo merged commit 358601e into main Jul 11, 2026
5 checks passed
@cuibonobo cuibonobo deleted the claude/issue-45-design-review-1jgkcj branch July 11, 2026 23:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Split SQLite support: native record-adapter-sqlite for Node, browser-only record-adapter-sqljs, and a StackTokenStore interface in core

2 participants