Skip to content

feat(store)!: extract nexus-wake + nexus-inmemory — tokio out of nexus-store (#300)#306

Merged
joeldsouzax merged 2 commits into
mainfrom
feat/300-nexus-wake
Jul 9, 2026
Merged

feat(store)!: extract nexus-wake + nexus-inmemory — tokio out of nexus-store (#300)#306
joeldsouzax merged 2 commits into
mainfrom
feat/300-nexus-wake

Conversation

@joeldsouzax

Copy link
Copy Markdown
Contributor

Why

nexus-store's production code is no_std+alloc-clean except tokio, confined to notify.rs behind the subscription feature — a packaging choice, not a design dependency (#224 already cut the WakeSource seam). This is the prerequisite for the store no_std port (#301) and moves the public path nexus_store::notify::* before the 1.0 freeze makes it permanent.

What

  • nexus-wakeStreamNotifiers/WakeReg/NotifyError moved verbatim (git mv); owns tokio/foldhash/parking_lot. The StreamNotifiers white-box tests from wake.rs moved along.
  • nexus-inmemoryInMemoryStore + InMemorySnapshotStore as a first-class adapter crate (RawEventStore + WakeSource + SnapshotStore + StreamLister/AtomicAppend behind export/import). StoredFrame now carries its SchemaVersion typed (captured at append like offsets), so the read path never re-parses header bytes — wire::SCHEMA_VERSION_OFFSET stays pub(crate) and the unreachable CorruptSchemaVersion variant is gone.
  • nexus-store — zero tokio/foldhash/parking_lot; subscription is a dep-free gate; the testing feature is deleted.
  • fjall/postgres repoint nexus_store::notifynexus_wake; examples repoint nexus_store::testingnexus_inmemory.

Deviation from the issue text

#300 kept InMemoryStore in nexus-store with a dev-dep on nexus-wake — but InMemoryStore embeds StreamNotifiers structurally behind a feature, and features cannot enable dev-dependencies, so that design is a normal-dep cycle cargo rejects. Extracting the adapter crate (as discussed) resolves it.

Test relocation

A dev-dep cycle unifies types only for integration tests; the lib-test target recompiles the crate under cfg(test) as a distinct crate, so nexus-inmemory's impls satisfy none of its bounds. Hence:

  • The InMemoryStore-fixture mods of export/import/cbor/decoded/projection moved to tests/ (import's private plan_section tests stayed inline; cbor's white-box mod stayed, only the store-using pipeline test moved).
  • inmemory_store_tests + inmemory_conformance moved into nexus-inmemory.
  • The catchup/subscription_cursor white-box mods (pub(crate) seams: CATCHUP_CHUNK, live_stepped) drive an in-crate TestStore double (src/test_support.rs, cfg(test)-only, ~200 lines); the public subscribe surface stays proven against the real adapter + real nexus-wake in tests/subscription_tests.rs.

Acceptance (from #300)

  • nexus-store has no tokio/foldhash/parking_lot dependency
  • nexus-fjall + nexus-postgres build against nexus-wake
  • nix flake check green (pre-commit); 1051/1051 workspace tests pass; clippy clean under --all-features --all-targets

Closes #300

🤖 Generated with Claude Code

joeldsouzax and others added 2 commits July 9, 2026 22:48
…s-store (#300)

nexus-store's production code was no_std+alloc-clean except tokio, confined
to notify.rs behind the subscription feature — a packaging choice, not a
design dependency (#224 already cut the WakeSource seam). Two new crates:

- nexus-wake: StreamNotifiers/WakeReg/NotifyError moved verbatim from
  nexus_store::notify (public path now nexus_wake::*), owning tokio,
  foldhash, parking_lot. The StreamNotifiers white-box tests moved along
  from wake.rs.
- nexus-inmemory: InMemoryStore/InMemoryStream/InMemoryAllPos (from
  nexus_store::testing) + InMemorySnapshotStore (from state.rs) as a
  first-class adapter crate; export/import features forward to
  nexus-store's. StoredFrame now carries its SchemaVersion typed (captured
  at append like offsets), so the read path never re-parses header bytes
  and wire's SCHEMA_VERSION_OFFSET stays pub(crate); the unreachable
  CorruptSchemaVersion variant is gone.

nexus-store drops tokio/foldhash/parking_lot entirely; the subscription
feature is a dep-free gate; the testing feature is deleted. Deviation from
the issue text: the issue kept InMemoryStore in nexus-store with a dev-dep
on nexus-wake, but InMemoryStore embeds StreamNotifiers structurally behind
a *feature*, and features cannot enable dev-deps — that design is a normal-
dep cycle cargo rejects. Adapter-crate extraction resolves it.

Test relocation (cargo constraint: a dev-dep cycle unifies types only for
integration tests; the lib-test build recompiles the crate under cfg(test),
so nexus-inmemory's impls satisfy none of its bounds):
- InMemoryStore-fixture test mods of export/import/cbor/decoded/projection
  moved to tests/ (import's private plan_section tests stayed inline as
  plan_tests; cbor's white-box mod stayed, only the store-using pipeline
  test moved).
- inmemory_store_tests + inmemory_conformance moved to nexus-inmemory.
- catchup/subscription_cursor white-box mods (pub(crate) seams) now drive
  an in-crate TestStore double (src/test_support.rs, cfg(test)-only); the
  public subscribe surface stays proven against the real adapter + real
  nexus-wake in tests/subscription_tests.rs.

fjall/postgres repoint nexus_store::notify -> nexus_wake; examples repoint
nexus_store::testing -> nexus_inmemory. CLAUDE.md architecture docs updated
(also folds in the shared-rules dedup to the global ~/.claude/CLAUDE.md).

Closes #300

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…d tests (#300)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@joeldsouzax joeldsouzax enabled auto-merge (squash) July 9, 2026 21:17
@joeldsouzax joeldsouzax merged commit 934e4c2 into main Jul 9, 2026
4 checks passed
@joeldsouzax joeldsouzax deleted the feat/300-nexus-wake branch July 9, 2026 21:26
@github-actions github-actions Bot mentioned this pull request Jul 8, 2026
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.

[freeze] Extract StreamNotifiers → nexus-wake crate (remove tokio from nexus-store)

1 participant