Commit Graph
13 Commits
Author SHA1 Message Date
Claude df7de27e20 Composite: don't undo writes made while a full sync is scanning
CI / Node 24 (pull_request) Successful in 11s
CI / Node 26 (pull_request) Successful in 12s
CI / Node 22 (pull_request) Successful in 13s
A write made during a full sync could be scanned in the replica but not in
the (read-ahead) source scan, so the diff removed it, and echo tracking then
consumed the server's echo. Keys written during a sync are now left out of
the diff. Deterministic regression test with a read-ahead source.

Also exclude -0 from the Extended JSON property test (JSON has no -0).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Qxbkp4tA7G5SCWjzWuxmE
2026-10-23 08:47:18 +00:00
Claude 4ffbc7e78d Add KVStorageComposite, IndexedDB storage and SSE change streams
CI / Node 24 (pull_request) Failing after 12s
CI / Node 22 (pull_request) Successful in 14s
CI / Node 26 (pull_request) Failing after 21s
- Every KV storage emits change events (base class owns writeMany/removeMany/
  writeIfAbsent; implementations provide protected apply* methods)
- KVStorageHttpServer streams changes over SSE (GET /events) with a resumable
  history; KVStorageHttp.watch() subscribes and resumes via Last-Event-ID
- KVStorageIndexedDB for local persistence
- KVStorageComposite keeps replicas of a source in sync: local reads, resume
  instead of full sync, offline outbox replayed in order, echo tracking
- Values may contain bigint/Uint8Array (Extended JSON over the network)
- Vendor sse-session, event-emitter and extended-json (no runtime deps)
- Freeze child nodes so shadowed state on children fails loudly
- CI on Node 22, 24 and 26

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Qxbkp4tA7G5SCWjzWuxmE
2026-10-23 08:41:42 +00:00
Claude 08fb78721f Simplify: one abstract base class per layer
CI / Node 20 (pull_request) Successful in 10s
CI / Node 22 (pull_request) Successful in 11s
- BaseKVStorage / BaseEventStorage / BaseDocumentStorage define the API once;
  implementations provide only raw primitives (client and server share an API)
- Drop KV indexes, query planner, unique indexes; document stores take index fields
- Escape every char <= '/' so child keys stay contiguous; skip-scan is now simple
- Event-sourced documents = event storage + any document store for projections
- New folder layout (kv-storage, event-storage, document-storage, utils); tests only in test/

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Qxbkp4tA7G5SCWjzWuxmE
2026-10-23 08:05:03 +00:00
Claude e27541c46a Add Prettier formatting and Gitea Actions CI (format, typecheck, test, build)
CI / Node 20 (push) Successful in 1m49s
CI / Node 22 (push) Successful in 1m52s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Qxbkp4tA7G5SCWjzWuxmE
2026-10-23 07:29:38 +00:00
Claude 5a370f8c78 M9: benchmarks, chunked sorted map and JSON clone for the in-memory driver
Profiling showed document updates dominated by O(n) sorted-array splices; the
chunked map makes inserts O(log n + chunk). Baselines recorded in DESIGN.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Qxbkp4tA7G5SCWjzWuxmE
2026-10-23 07:25:04 +00:00
Claude 76f791f54b M8: HTTP driver (framework-agnostic handler + HttpKVDriver client) passing conformance end-to-end
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Qxbkp4tA7G5SCWjzWuxmE
2026-10-23 07:21:09 +00:00
Claude f6541507ac M7: Spec typing across KV, events and documents with expectTypeOf tests
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Qxbkp4tA7G5SCWjzWuxmE
2026-10-23 07:19:11 +00:00
Claude 0c4e35b9b6 M6: EventSourcedDocumentStorage with projections, update operators, queries, planner, unique indexes, catch-up
Writes append resolved deltas with optimistic concurrency and self-heal lagging
projections. Reads hit projections only. Index-backed find is property-tested
against unindexed find.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Qxbkp4tA7G5SCWjzWuxmE
2026-10-23 07:18:03 +00:00
Claude 67f0ba11f7 M5: KVEventStorage with dense commit keys, setIfAbsent and mutex modes, head cache, probe-based read
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Qxbkp4tA7G5SCWjzWuxmE
2026-10-23 07:07:54 +00:00
Claude 8bc1c27c40 M4: KV indexes with pattern trie, atomic and non-atomic write paths, read-repair, range findBy
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Qxbkp4tA7G5SCWjzWuxmE
2026-10-23 07:04:19 +00:00
Claude 8f8c880efd M3: KVNode/KVStorage with arity dispatch, skip-scan keys, deleteTree, tree
Children are listed in subtree order (escaped segment + separator) so the
skip-scan stays O(children) even when sibling keys extend each other with
characters below the separator. Model-based property test vs a reference Map.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Qxbkp4tA7G5SCWjzWuxmE
2026-10-23 07:02:58 +00:00
Claude f1ef4a71e9 M2: KV driver interface, BaseKVDriver, InMemoryKVDriver, conformance suite
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Qxbkp4tA7G5SCWjzWuxmE
2026-10-23 06:53:54 +00:00
Claude 69108d1557 M1: core path escaping, order-preserving index value encoding, errors
Scaffold TypeScript/Vitest project, add DESIGN.md (brief) and CLAUDE.md.
Property tests cover escape round-trips, separator-freedom and order preservation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Qxbkp4tA7G5SCWjzWuxmE
2026-10-23 06:52:06 +00:00