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>
2.5 KiB
ADR — Use SPARQL DELETE (not ORM ngSet.delete()) to remove objects
Date: 2026-03-17 · Status: Accepted → Superseded (2026-06-15). Historical decision, ported for the current-SDK behaviour it records. Original context: the consuming app.
Superseded (2026-06-15). The
ngSet.delete()non-persistence bug that motivated this decision was largely fixed upstream in@ng-org/orm; deletion code went back tongSet.delete(). Kept as arbitration memory — the CRDT conflict rule ("don't combine the two") still holds.
Context
Removing an object from the NextGraph store: DeepSignalSet.delete() updates the
local reactive state (immediate UI) but does not persist to the broker — after
refresh the object reappears.
Options considered
A — ORM ngSet.delete(item)
Official API, instant local reactive update. Against: did not persist in
practice (delete() returned true, local set updated, object back after
refresh); graph_orm_update seemed to mishandle "remove" patches for top-level
set objects (likely engine bug); failed silently.
B — ng.sparql_update() with SPARQL DELETE
DELETE WHERE { GRAPH <graph> { <subject> ?p ?o } } removes all the RDF triples.
For: persists (survives refresh); the broker confirms via a GraphOrmUpdate
op: "remove" that reactively removes the item from the ORM set; direct control.
Against: not instant (~50ms SPARQL round-trip + broker callback); must NOT be
combined with ngSet.delete().
C — both together
Does not work: the ORM .delete() patch and the SPARQL DELETE conflict at the
CRDT level → neither UI nor persistence.
Decision
Option B — SPARQL DELETE alone. The broker returns a GraphOrmUpdate
op: "remove" that reactively removes the item from the ORM set (UI updates, just
not synchronously). Do NOT call ngSet.delete() alongside.
await ng.sparql_update(
session_id,
`DELETE WHERE { GRAPH <${partGraph}> { <${partId}> ?p ?o } }`,
partGraph,
);
This is the authoritative-delete pattern this lib's emulation relies on for inbox
deposits and shim graphs (an interpolated NURI/subject must pass through
assertNuri/escapeLiteral first — see SPARQL hardening in
../simulation.md).
Consequences
- Positive: deletion persists; single source of truth (broker → ORM → UI).
- Negative: slight UI delay (~50ms); diverges from the ORM README examples.
- Risk: if
ng.sparql_updatechanges, this breaks; revisit asngSet.delete()matures upstream.