docs: reprendre les citations après le rangement, et retirer le membre login fabriqué

Les deux contrats et la doctrine portent des centaines de citations `file:line`
vers `src/`. Le rangement par destin les périmait en bloc — 208 reprises (45
chemins `src/x.ts`, 163 mentions nues). Sans ça la réorganisation pourrissait
l'instrument même qui tient la discipline qu'elle sert.

Et un défaut relevé par le contrat interne, vérifié : `ng-proxy` fabriquait un
membre `login`. `@ng-org/web` n'expose aucune méthode de ce nom — zéro
occurrence dans les déclarations installées comme dans `sdk/js/lib-wasm/src/lib.rs`
— mais le proxy répondait une fonction au lieu d'`undefined`, laquelle plantait
à l'appel. C'était le seul endroit où ce wrapper ajoutait à la surface du SDK,
contre son propre en-tête.

157 tests unitaires, typecheck src/test/e2e vert.
This commit is contained in:
Sylvain Duchesne
2026-08-04 12:56:02 +02:00
parent cd096de2b0
commit 0b37d17c2f
19 changed files with 151 additions and 145 deletions
+10 -10
View File
@@ -109,7 +109,7 @@ and every subsequent patch to a `DeepSignalSet`
alongside the React one (`sdk/js/orm/src/frontendAdapters/{vue,svelte}/`).
`@ng-eventually/client` re-exports `useShape` from
[`../src/use-shape.ts`](../src/use-shape.ts); import it from the SDK
[`../src/surface/use-shape.ts`](../src/surface/use-shape.ts); import it from the SDK
(`@ng-eventually/client`), never from `@ng-org/orm` directly.
### What you get, in order
@@ -164,11 +164,11 @@ computes a result and returns once (`sparql_query`,
In `@ng-eventually/client` the one-shot read is exposed as:
- **`docs.sparqlQuery(sid, query, base?, anchor?)`** — a raw anchored SPARQL query
([`../src/docs.ts`](../src/docs.ts)). `anchor` = the document NURI to read; the
([`../src/surface/docs.ts`](../src/surface/docs.ts)). `anchor` = the document NURI to read; the
anchor restricts the query to that one repo's graph.
- **`readModel.readUnion(docs)`** — read a **bounded, by-need set** of document NURIs,
each with its own anchored query, grouped per subject
([`../src/read-model.ts`](../src/read-model.ts)). This is the polyfill's listing
([`../src/surface/read-model.ts`](../src/surface/read-model.ts)). This is the polyfill's listing
primitive (see [§ Current emulation status](#current-emulation-status) and
[`read-model.md`](../../../docs/read-model.md)).
@@ -185,7 +185,7 @@ You do not need the write internals to read, but reads and writes share the same
document model, so briefly:
- **Create a document:** `docs.docCreate(sid, crdt, cls, dest, store?)`
([`../src/docs.ts`](../src/docs.ts)) — mirrors `ng.doc_create`. **One document = one
([`../src/surface/docs.ts`](../src/surface/docs.ts)) — mirrors `ng.doc_create`. **One document = one
repo** (`did:ng:o:<RepoID>`); there is no separate `Document` type.
- **Write into it:** `docs.sparqlUpdate(sid, query, anchor)` — a SPARQL
`INSERT/DELETE` scoped to the anchor document's graph. Or, at the ORM layer, the ORM
@@ -294,7 +294,7 @@ from the reactive contract:
2. **The inbox uses a polling watcher.** The inbox is emulated
(`AppRequestCommandV0::InboxPost` has no verifier arm today; no wasm helper seals a
deposit), so `inbox.watch` ([`../src/inbox.ts`](../src/inbox.ts)) **polls** via
deposit), so `inbox.watch` ([`../src/surface/inbox.ts`](../src/surface/inbox.ts)) **polls** via
`setInterval` (default 1s) instead of subscribing. The finished contract is push
(the broker already routes the inbox natively); these become subscriptions when the
sealed-inbox path is exposed to JS (no such method exists today).
@@ -314,15 +314,15 @@ from the reactive contract:
`sparqlUpdate` on a doc it is itself subscribed to (`subscribeDoc` /
`ng.doc_subscribe`), the subscription callback appears NOT to fire for its OWN
local commit in the same session — so the reactive re-read chain
([`../src/watch-shape.ts`](../src/watch-shape.ts) `watchShape` → `reread` →
[`../src/read-model.ts`](../src/read-model.ts) `readUnion`) never runs, and
([`../src/surface/watch-shape.ts`](../src/surface/watch-shape.ts) `watchShape` → `reread` →
[`../src/surface/read-model.ts`](../src/surface/read-model.ts) `readUnion`) never runs, and
consumers keep the STALE value until the next connection delivers a fresh
initial `State`. **Remote** commits DO push correctly (verified: cross-browser
reactive update works). A code review verified the consumer wiring is correct,
the doc IS in the subscribed set, and a triggered re-read WOULD return the new
value — leaving the self-commit echo as the only suspect link. That link is
**INFERRED**, not observed: the real `ng.doc_subscribe` runtime is not readable
from source, and [`../src/subscribe.ts`](../src/subscribe.ts)'s own doc-comment
from source, and [`../src/surface/subscribe.ts`](../src/surface/subscribe.ts)'s own doc-comment
CLAIMS local writes push a `Patch` — contradicted by the observation. (This
also sits in tension with § *The reactivity model* above, which documents the
target contract — one commit, every subscriber pushed, local or remote.) The
@@ -330,9 +330,9 @@ from the reactive contract:
must propagate reactively to ALL viewers — other viewers (remote push, which
works) AND the writer's own view (this suspect link). **Treatment (PLANNED,
not done):** confirm first via the temporary instrumentation just added
([`../src/subscribe.ts`](../src/subscribe.ts) ≈`:119` logs
([`../src/surface/subscribe.ts`](../src/surface/subscribe.ts) ≈`:119` logs
`doc_subscribe FIRE <nuri> (State|Patch)`;
[`../src/watch-shape.ts`](../src/watch-shape.ts) ≈`:341` logs
[`../src/surface/watch-shape.ts`](../src/surface/watch-shape.ts) ≈`:341` logs
`reread TRIGGER by <nuri>` — line numbers volatile, grep the log strings);
then, IF confirmed, fix **polyfill-side** — a
local commit should notify the doc's active `subscribeDoc` callbacks.
+8 -2
View File
@@ -12,8 +12,14 @@ export function makeNg(): Record<string, any> {
get(_target, prop: string) {
const { ng } = getConfig();
// login / session_start → open the SHARED wallet invisibly.
if (prop === "login" || prop === "session_start") {
// session_start → open the SHARED wallet invisibly.
//
// `login` used to be listed here too. `@ng-org/web` exposes no such method —
// zero occurrences in the installed declarations and in `sdk/js/lib-wasm/src/lib.rs`
// — so the proxy FABRICATED a member: `ng.login` answered a function instead of
// `undefined`, and calling it threw. The one place this wrapper added to the SDK
// surface, against its own header. Removed 2026-08-03.
if (prop === "session_start") {
return (...args: any[]) => {
// TODO(polyfill): supply shared-wallet credentials so no wallet UI
// is shown. For now, passthrough.