This library presents a mature-NextGraph SDK face to consumers while compensating for the current SDK's gaps via a shared-wallet simulation. It therefore OWNS all current-state + simulation knowledge — moved here out of the Festipod app repo, which must treat this library as a finished SDK. New docs/: - nextgraph-current-state.md — what the current SDK/broker do and don't expose (5 store types, document=repo, per-document ReadCap, inbox not exposed, iframe RPC proxy, mono-user/no-global-data, wallet import constraint). Keeps the nextgraph-rs source pointers. - simulation.md — how the lib emulates the mature behaviour on one shared wallet (shim, store!=document two axes, docCreate→private store, RepoNotFound scope rule, @ng-org double-proxy DataCloneError, emulated ReadCap/inbox/curator). - decisions/ — the current-SDK ADRs (private-store-nuri-scope, sparql-delete, shared-wallet-login, discovery mechanism). - fork-inbox-fallback.md — the Rust-patch/self-host route not taken. - migration-guide.md — the checklist for when real NextGraph matures. README: boundary framing from the lib's side + docs/ index; replaced the stale "scaffold/stubbed" status with the actually-implemented mechanisms per source. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4.6 KiB
Migration guide — when real NextGraph matures
The whole point of this library: the consumer already writes SDK-shaped code, so when NextGraph ships cross-wallet reads, capabilities and inboxes, only this lib changes. The consumer's application code does not change. This is the checklist.
Guiding invariant
Every emulated piece has a 1:1 image in the real infra. Migration = swap the
emulation for the real primitive, remove the scaffold. If a piece of the emulation
has no clear target image, that is a drift signal (see
simulation.md).
Checklist
1. Emulated ReadCaps → real capabilities
Translate the per-document CapRegistry (caps.ts) into real NextGraph caps: the
broker/verifier enforces them, and useShape already returns only authorized
documents. The read filter (read-filter.ts) and the write guard (ng-proxy.ts
sparql_update override) are then dead code — remove them. The access unit is
already the document (@graph), matching the native per-repo cap model, so this is
a data step, not a reshape.
2. Place documents in real native stores
Today docCreate(..., undefined) writes every document into the shared wallet's
private store, and the public|protected|private scope is a logical label
in the shim (see the two-axes section in simulation.md).
doc_createcannot target a non-private native store today — verified:StoreRepois not JS-constructible from the SDK, so there is no way to pass a public/protected store as the create destination (docCreate's trailingstorearg is leftundefined→ private store). The private store works only because it opens withoutRepoNotFound.- When the SDK lets you construct/target a native store, the migration adds a
getNativeStore(scope)-style resolver returning the real store to pass as thedocCreatedestination, so the logical scope label becomes a real store placement. (No such helper exists yet — it is blocked on the SDK gap above.) - At that point
store-registry.tsmaps(account, scope)to the user's real store NURI instead of a document in the shared wallet; the per-scope index document (the store-container emulation) is replaced by the store itself. The consumer-facing surface (createEntityDoc,listEntityDocs, resolvers) is designed to survive that swap unchanged.
3. Drop the resolver / shim
The sharedWalletShim (account → 3 scope-document NURIs, RDF in the private store)
has no target equivalent — the target has no central directory. Remove it:
store-registry.ts, configureStoreRegistry, the shim SPARQL. Cross-wallet reads
replace the fan-out; per-user wallets replace the shared one.
4. Real inbox → drop the emulated curator
Replace the emulated inbox.ts deposit (docs.sparqlUpdate into a shared-wallet
document) with the native inbox_post_link, and move read/materialize/watch
to a separate curator package (the deferred global-index curator — see the
top-level README and decisions/discovery-model.md).
The in-client read side goes away. The single global index replaces the
cross-account fan-out.
5. Faux login → real per-user login
Remove accounts.ts (the username localStorage faux login) and the app-level
"Connexion" screen. The technical broker gate becomes the real per-user login
(see decisions/shared-wallet-login-flow.md).
The flow shape ("broker redirect → app") does not change.
6. Drop the isolation scaffold
isolation.ts (application social-visibility filter) disappears against a
different piece of infra than the caps: real per-account wallets + a real
per-account social graph. Distinct axis from ReadCaps — remove independently.
7. Remove the build alias — the client becomes the real SDK
The consumer imports @ng-org/web / @ng-org/orm resolved to this lib via a
build alias during the polyfill period. Removing the alias makes those imports
resolve to the real SDK — the ng/useShape/inbox surface is SDK-identical, so
no consumer code changes. The one non-SDK call — configure(...) /
@ng-eventually/client/polyfill — is deleted. The lib itself disappears.
What does NOT change
The consumer's application code. Shapes, screens, the acts of granting access, entity→scope mapping, the connection graph — all injected, all untouched. Migration is entirely inside this library plus removing the alias + the bootstrap call. That asymmetry — a mature SDK face outward, all compensation inward — is the library's reason to exist.