docs: "what is emulated (and how it goes away)" recap table + read-path reconcile

README: new section with a recap table (11 rows) — for each emulated behavior:
what the consumer sees (SDK-shaped API), how it's emulated on one shared wallet,
the real NextGraph target, and the lib-only migration. Makes "emulated ≠ real,
migration is a lib-only swap" explicit.
simulation.md: opening banner that EVERYTHING in the file is emulation pending
real NextGraph; corrected the stale read-path paragraph (per-doc anchored, never
an anchorless union-scan). read-model.md: reactivity bullet aligned to per-doc.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sylvain Duchesne
2026-07-06 11:18:10 +02:00
parent b15229fbd5
commit 5717e08f6d
3 changed files with 45 additions and 7 deletions
+2 -1
View File
@@ -95,7 +95,8 @@ There is **no reactive union query**. So reactivity is assembled:
- keep a lightweight reactive subscription — `doc_subscribe`, or the ORM on an
**already-opened single store** (never a per-entity fan-out) — on the synced docs;
- on its change signal, **re-run** the one-shot union `sparql_query`.
- on its change signal, **re-run** the bounded set of per-doc anchored
`sparql_query`s (`readModel.readUnion`) — never an anchorless union-scan.
Keep the reactive ORM strictly to already-opened single stores; it is a change
*signal* source here, not the list source.
+17 -4
View File
@@ -1,5 +1,16 @@
# How this library emulates mature NextGraph on ONE shared wallet
> **EVERYTHING in this file is EMULATION.** Not one behaviour described here is a
> real NextGraph feature: each is a **stopgap** the lib fabricates on top of the
> *current, immature* NextGraph (the exact gaps it compensates for are in
> [`nextgraph-current-state.md`](./nextgraph-current-state.md)). Every piece has a
> **real target** and goes away when NextGraph matures — the swap is **lib-only**,
> the consumer's code is unchanged. The per-behaviour recap table lives in the
> top-level [`README.md`](../README.md) (*What is emulated (and how it goes away)*);
> the removal checklist is [`migration-guide.md`](./migration-guide.md). Read this
> file for *how* each emulation works; read those two for *what is fake* and *what
> replaces it*.
The consumer writes against `@ng-eventually/client` **as if** NextGraph already
shipped per-entity documents in public/protected/private stores, capabilities and
inboxes. It hasn't (see [`nextgraph-current-state.md`](./nextgraph-current-state.md)).
@@ -103,10 +114,12 @@ public/protected/private stores — on top of one shared wallet.
handing the NURIs to `useShape({ graphs })` opens/syncs other accounts' possibly-
unsynced docs and HANGS (the ORM fan-out, ~75s — see
[`read-model.md`](./read-model.md)). The real READ path is
`readModel.readUnion(docs)` (open/sync by-need + ONE anchorless union
`sparql_query`); the app resolves the by-need doc set from the discovery index
(public events) and `listMyEntityDocs(username, scope)` (my own account, bounded —
no cross-account fan-out).
`readModel.readUnion(docs)`, which reads the by-need doc set with **one PER-DOC
ANCHORED `sparql_query`** — **never an anchorless union-scan** of the physical
wallet (that is O(wallet size) and timed out ~90s; see
[`read-model.md`](./read-model.md)). The app resolves the by-need doc set from the
discovery index (public events) and `listMyEntityDocs(username, scope)` (my own
account, bounded — no cross-account fan-out).
- **GENERIC by construction.** The registry knows only the three native scopes,
**zero** application entity kind. The consumer maps its entities to a scope and
injects the session + username normalization via `configureStoreRegistry({