Ng eventually #1

Open
Sylvain wants to merge 110 commits from ng-eventually into main
2 changed files with 26 additions and 31 deletions
Showing only changes of commit 22487ed575 - Show all commits
+11 -14
View File
@@ -94,13 +94,12 @@ export async function updateEntityField(
const s = assertNuri(subject);
const pred = `${FP}${field}`;
const obj = renderTerm(term);
// NO explicit `GRAPH <${graphNuri}>` wrapper: anchored to `graphNuri`, both the
// DELETE and the INSERT target that repo's DEFAULT graph — the exact graph the
// anchored default-graph READ queries (read-model.ts readDoc). An explicit
// `GRAPH <plainNuri>` body writes into a NAMED graph the anchored read never
// sees, so the mutation would not round-trip (same fix as writeEntity / the
// lib's inbox.post). `assertNuri(graphNuri)` is still done implicitly by
// `docs.sparqlUpdate`'s anchor handling — validate `subject` here as it lands
// NO explicit `GRAPH <>` wrapper: anchored to `graphNuri`, both the DELETE and
// the INSERT target that doc's anchored DEFAULT graph — the exact graph the
// anchored read queries. This no-GRAPH default-graph form is the CANONICAL SDK
// write shape (same as writeEntity / registration.ts); SDK graph details live in
// `@ng-eventually/client`, not here. `assertNuri(graphNuri)` is done implicitly
// by `docs.sparqlUpdate`'s anchor handling — validate `subject` here as it lands
// in an IRI position.
const del = `DELETE WHERE { <${s}> <${pred}> ?o }`;
await docs.sparqlUpdate(sid, del, graphNuri);
@@ -134,13 +133,11 @@ export async function writeEntity(
if (obj === null) continue;
triples.push(`<${FP}${field}> ${obj}`);
}
// NO explicit `GRAPH <${g}>` wrapper: anchored to `graphNuri`, the write lands in
// that repo's DEFAULT graph — the exact graph the anchored default-graph READ
// queries (read-model.ts readDoc). An explicit `GRAPH <plainNuri>` body instead
// writes into a NAMED graph distinct from the repo's default graph, which the
// anchored default-graph read never sees (the old anchorless `GRAPH ?g` scan did,
// which is why it worked before the read switched to per-doc anchored). Same shape
// as the lib's inbox.post / entity writes: anchor scopes the write, no GRAPH clause.
// NO explicit `GRAPH <>` wrapper: anchored to `graphNuri`, the write lands in
// that doc's anchored DEFAULT graph — the exact graph the anchored read queries.
// This is the CANONICAL SDK write shape (anchor scopes the write, no GRAPH clause;
// same as updateEntityField / registration.ts); SDK graph details live in
// `@ng-eventually/client`, not here.
const update = `
INSERT DATA {
<${assertNuri(subject)}> ${triples.join(' ;\n ')} .
+15 -17
View File
@@ -331,12 +331,11 @@ async function countParticipations(
): Promise<number> {
const evL = escapeLiteral(eventId);
const usL = escapeLiteral(userId);
// NO explicit `GRAPH <${graphNuri}>` wrapper: participations are written by
// `writeEntity` into the anchored DEFAULT graph (one doc per entity), so this
// count MUST read that same default graph — anchored to `graphNuri`, with no
// `GRAPH` clause. An explicit `GRAPH <plainNuri>` body reads a NAMED graph the
// writes never land in → always 0 (the graph-mismatch bug — same fix as
// writeEntity/updateEntityField and the lib's read-model/inbox).
// NO explicit `GRAPH <>` wrapper: participations are written by `writeEntity`
// into the anchored DEFAULT graph (one doc per entity), so this count reads that
// same anchored default graph — anchored to `graphNuri`, no `GRAPH` clause. This
// is the CANONICAL SDK read/write shape (write and read the same anchored default
// graph); SDK graph details live in `@ng-eventually/client`, not here.
const query = `
SELECT (COUNT(DISTINCT ?s) AS ?n) WHERE {
?s a <${P.partType}> ;
@@ -420,12 +419,12 @@ export async function deleteParticipation(
const usIri = escapeIri(userId);
const evL = escapeLiteral(eventId);
const usL = escapeLiteral(userId);
// NO explicit `GRAPH <${graphNuri}>` wrapper: participations live in the
// anchored DEFAULT graph (writeEntity), so the sweep must DELETE from that same
// default graph — anchored to `graphNuri`, no `GRAPH` clause. Deleting from an
// explicit `GRAPH <plainNuri>` named graph would no-op (the triples aren't
// there), silently leaving the participation → the F2 resurrection. Same fix as
// countParticipations / writeEntity.
// NO explicit `GRAPH <>` wrapper: participations live in the anchored DEFAULT
// graph (writeEntity), so the sweep DELETEs from that same anchored default
// graph — anchored to `graphNuri`, no `GRAPH` clause. Write, read and delete all
// use the one CANONICAL anchored-default-graph shape so they stay consistent (a
// mismatched target here would no-op the delete → the F2 resurrection). SDK graph
// details live in `@ng-eventually/client`, not here.
const sweep = `
DELETE { ?s ?p ?o }
WHERE {
@@ -478,11 +477,10 @@ export async function insertNotification(
const payloadTriple = notif.payload
? `\n <${P.payload}> "${escapeLiteral(notif.payload)}" ;`
: '';
// NO explicit `GRAPH <${graphNuri}>` wrapper: anchored to `graphNuri`, the
// INSERT lands in that repo's DEFAULT graph — consistent with every other
// per-entity write (writeEntity / updateEntity / the lib's inbox.post). An
// explicit `GRAPH <plainNuri>` body targets a phantom named graph that no
// anchored default-graph read ever sees (graph-mismatch bug).
// NO explicit `GRAPH <>` wrapper: anchored to `graphNuri`, the INSERT lands in
// that doc's anchored DEFAULT graph — the CANONICAL SDK write shape, consistent
// with every other per-entity write (writeEntity / updateEntityField). SDK graph
// details live in `@ng-eventually/client`, not here.
const update = `
INSERT DATA {
<${assertNuri(subject)}> a <${NOTIF_TYPE_IRI}> ;