fix: les trois citations que les paquets installes invalidaient

Recherche menee sur les 94 citations vers engine/ et sdk/, en comparant
l'arbre cite aux artefacts publies. Onze citations de niveau 2
(doc_subscribe, sparql_update, sparql_query, doc_create) sont
identiques de part et d'autre, ainsi que ShapeType, Schema et
DeepSignalSet. Trois ne l'etaient pas.

- Scope : la revision citee declare `graphs?` OPTIONNEL,
  @ng-org/orm@0.1.2-alpha.21 le rend requis - et c'est le paquet
  installe qui est reexporte ici.
- BaseType : la revision citee garde "@graph" en commentaire derriere un
  TODO, @ng-org/shex-orm@0.1.2-alpha.9 le declare.
- NG : le compte de membres disait 88 en neuf endroits, dont un marque
  VERIFIED et un autre annoncant une mesure contre alpha.14. Le paquet
  installe en declare 90 - 84 fonctions et 6 classes RDF - et deux des
  quatre-vingt-dix, graph_orm_next_page et graph_orm_previous_page, sont
  absents de l'arbre cite. Le compte vit desormais a un seul endroit,
  avec la version a laquelle il appartient ; ailleurs il disparait, parce
  que la phrase disait "tous les membres" et que le chiffre n'y ajoutait
  qu'une occasion de perimer.

Les deux premieres reprennent la forme que RdfOrmConfig et
OrmSubscriptionHandle portaient deja : une clause finale nommant la
version publiee la ou elle diverge de la revision citee.
This commit is contained in:
Sylvain Duchesne
2026-09-24 15:05:36 +02:00
parent 7bcb52a5fd
commit 139d21843a
7 changed files with 25 additions and 17 deletions
+3 -3
View File
@@ -121,7 +121,7 @@ export declare type Session = {
};
```
`initNg`'s argument in position 0 is substituted since `1.0.0-dev.7`, and it is the same kind of move for the same reason. That argument is what the ORM reaches the engine through afterwards - every subscription, every `insertObject`, every batched patch awaits the promise this call resolves - and an ORM write leaves by `ng.graph_orm_update`, which is where the emulated write guard now sits (§ 3). Handing the caller's raw SDK object over leaves that guard on a door nothing knocks on, and "pass the package's `ng` here" would be an ordering rule in prose: unenforceable, silent when missed, and in fact missed by both consumers in this repository. What is substituted is the package's own `ng` - the same object the entry publishes, forwarding all 88 members to the very object `configure()` received - so the ORM now reaches the engine through exactly what the application does.
`initNg`'s argument in position 0 is substituted since `1.0.0-dev.7`, and it is the same kind of move for the same reason. That argument is what the ORM reaches the engine through afterwards - every subscription, every `insertObject`, every batched patch awaits the promise this call resolves - and an ORM write leaves by `ng.graph_orm_update`, which is where the emulated write guard now sits (§ 3). Handing the caller's raw SDK object over leaves that guard on a door nothing knocks on, and "pass the package's `ng` here" would be an ordering rule in prose: unenforceable, silent when missed, and in fact missed by both consumers in this repository. What is substituted is the package's own `ng` - the same object the entry publishes, forwarding every member to the very object `configure()` received - so the ORM now reaches the engine through exactly what the application does.
Divergence: none in behaviour (pure forwarding), but the wrappers erase the parameter types. A consumer typing calls against them learns nothing it must unlearn - it just gets no compile-time help the real SDK would give.
@@ -173,11 +173,11 @@ export type { NG } from "@ng-org/web";
There is exactly one instance of that proxy for the whole package (`wrappedNg()`), because two things now hold it: the entry publishes it, and `initNg` hands it to the ORM (§ 2).
**The passthrough itself was broken until `1.0.0-dev.7`, for every one of the 88 members, and nothing noticed.** It read `Reflect.get(ng, prop).bind(ng)`. `@ng-org/web`'s `ng` is ITSELF a Proxy - an "async proxy" whose `get` trap answers EVERY key with a fresh path-carrying callable and whose reflection traps throw (`dist/ngweb.js`, the `l(e = [])` factory) - so `.bind` never reached `Function.prototype.bind`: it was just another key, calling the result posted a remote request named after the MEMBER carrying the bind arguments, and what came back was a **Promise**. A caller therefore got the SDK's own `<member> is not a function`. Two things hid it: this library's internals never go through this proxy (they call the injected `ng` directly), and every fake in the suite is a plain object, on which `bind` behaves. It surfaced the moment `initNg` handed the ORM this object - `orm_start_graph` was not a function, the ORM catches that and only `console.error`s it, so a shape read stayed `isPending` for ever, which is the failure mode § 5 describes. MEASURED against `@ng-org/web@0.1.2-alpha.14`. The member is now FORWARDED (`Reflect.apply(real, ng, args)`), which gives a plain object the receiver it needs and lets the async proxy use the path it already carries; `test/ng-proxy.test.ts` pins it against a stand-in shaped like the real one.
**The passthrough itself was broken until `1.0.0-dev.7`, for every one of its members, and nothing noticed.** It read `Reflect.get(ng, prop).bind(ng)`. `@ng-org/web`'s `ng` is ITSELF a Proxy - an "async proxy" whose `get` trap answers EVERY key with a fresh path-carrying callable and whose reflection traps throw (`dist/ngweb.js`, the `l(e = [])` factory) - so `.bind` never reached `Function.prototype.bind`: it was just another key, calling the result posted a remote request named after the MEMBER carrying the bind arguments, and what came back was a **Promise**. A caller therefore got the SDK's own `<member> is not a function`. Two things hid it: this library's internals never go through this proxy (they call the injected `ng` directly), and every fake in the suite is a plain object, on which `bind` behaves. It surfaced the moment `initNg` handed the ORM this object - `orm_start_graph` was not a function, the ORM catches that and only `console.error`s it, so a shape read stayed `isPending` for ever, which is the failure mode § 5 describes. MEASURED against `@ng-org/web@0.1.2-alpha.14`. The member is now FORWARDED (`Reflect.apply(real, ng, args)`), which gives a plain object the receiver it needs and lets the async proxy use the path it already carries; `test/ng-proxy.test.ts` pins it against a stand-in shaped like the real one.
### Target
**PASSTHROUGH (level 2, VERIFIED).** `export declare const ng: NG` with `NG = typeof NGModule`, **88** exported members (`index.d.ts:136-231`; the namespace body is `:140-231`). The surface is identical by construction — the proxy adds no member and removes none — **and identical at the type level too since 2026-08-14**, when the published `ng` stopped being declared `Record<string, any>` and took `NG`, upstream's own type. That escape hatch silently dropped all 88 signatures: an application got no completion, and a misspelt member typechecked.
**PASSTHROUGH (level 2, VERIFIED).** `export declare const ng: NG` with `NG = typeof NGModule`, **90** exported members in `@ng-org/web@0.1.2-alpha.14` - 84 functions and 6 RDF classes, counted in the `NGModule` namespace of the installed `index.d.ts`. The count is named with its release because it MOVES with one: this document recorded **88**, two short, and two of the ninety - `graph_orm_next_page` and `graph_orm_previous_page` - appear nowhere in the cited checkout's `sdk/js/lib-wasm/src/lib.rs`, the tree declaring the previous release `@ng-org/web@0.1.2-alpha.13`. The figure was never re-measured after the build moved. The surface is identical by construction — the proxy adds no member and removes none — **and identical at the type level too since 2026-08-14**, when the published `ng` stopped being declared `Record<string, any>` and took `NG`, upstream's own type. That escape hatch silently dropped every signature: an application got no completion, and a misspelt member typechecked.
The overrides: