fix: un dépôt est délivré une fois et retiré, comme en amont

This commit is contained in:
Sylvain Duchesne
2026-08-26 14:11:56 +02:00
parent abfb619c76
commit f6a48a4507
24 changed files with 1486 additions and 176 deletions
@@ -151,12 +151,21 @@ function makeWallet(quads: Quad[] = []) {
const anchor = a[2] as string | undefined;
const del = query.match(/DELETE\s+WHERE\s*\{([\s\S]*)\}/i);
if (del) {
const pattern = del[1]!.match(/<([^>]+)>\s+<([^>]+)>\s+\?/);
if (pattern && anchor !== undefined) {
if (del && anchor !== undefined) {
// `<s> <p> ?o` clears one register slot; `<s> ?p ?o` retires a whole DEPOSIT
// (`emulated-verifier/inbox-consume.removeDeposit`) — a deposit carries
// `a`/`payload`/`ts` and optionally `from`, so naming predicates would leave some.
const boundPredicate = del[1]!.match(/<([^>]+)>\s+<([^>]+)>\s+\?/);
const wholeSubject = del[1]!.match(/<([^>]+)>\s+\?\w+\s+\?\w+/);
const matches = boundPredicate
? (q: Quad) => q.s === boundPredicate[1] && q.p === boundPredicate[2]
: wholeSubject
? (q: Quad) => q.s === wholeSubject[1]
: null;
if (matches) {
for (let i = quads.length - 1; i >= 0; i--) {
const q = quads[i]!;
if (q.g === anchor && q.s === pattern[1] && q.p === pattern[2]) quads.splice(i, 1);
if (q.g === anchor && matches(q)) quads.splice(i, 1);
}
}
return undefined;
@@ -222,6 +231,8 @@ function makeWallet(quads: Quad[] = []) {
const bySubject = new Map<string, Record<string, string>>();
for (const q of inGraph) {
const rec = bySubject.get(q.s) ?? {};
// The deposit's own subject — the key a drain names to retire it.
rec.d = q.s;
if (q.p === `${INBOX}:payload`) rec.payload = q.o;
if (q.p === `${INBOX}:ts`) rec.ts = q.o;
if (q.p === `${INBOX}:from`) rec.from = q.o;
@@ -231,6 +242,7 @@ function makeWallet(quads: Quad[] = []) {
.filter((r) => r.payload !== undefined && r.ts !== undefined)
.map((r) => {
const row: Record<string, { value: string }> = {
d: { value: r.d! },
payload: { value: r.payload! },
ts: { value: r.ts! },
};