From 4a4e6af3371817cd61f48a4b9a06de026cedfc32 Mon Sep 17 00:00:00 2001 From: Sylvain Duchesne Date: Mon, 21 Sep 2026 10:52:07 +0200 Subject: [PATCH] chore: ng-e2e-helpers suit alpha.14, et la mise a jour des paquets devient une tache --- ...rsarial-review-of-the-published-surface.md | 2 +- .../T01.h-refresh-the-nextgraph-packages.md | 26 ++++++ packages/ng-e2e-helpers/package.json | 2 +- packages/polyfill/e2e/orm-live-entry.ts | 19 ++++- packages/polyfill/e2e/tsconfig.json | 5 +- packages/polyfill/package.json | 8 +- .../polyfill/src/surface/use-shape-query.ts | 8 +- .../polyfill/test/use-shape-query.test.ts | 6 +- pnpm-lock.yaml | 84 +++++++++---------- 9 files changed, 107 insertions(+), 53 deletions(-) create mode 100644 .tasks/todo/T01.h-refresh-the-nextgraph-packages.md diff --git a/.tasks/todo/T01.g-adversarial-review-of-the-published-surface.md b/.tasks/todo/T01.g-adversarial-review-of-the-published-surface.md index f46f4b4..b0c3b40 100644 --- a/.tasks/todo/T01.g-adversarial-review-of-the-published-surface.md +++ b/.tasks/todo/T01.g-adversarial-review-of-the-published-surface.md @@ -2,7 +2,7 @@ id: T01.g title: Adversarial review of the whole published surface parent: T01 -depends_on: [T01.a, T01.b, T01.c, T01.d, T01.e, T01.f] +depends_on: [T01.a, T01.b, T01.c, T01.d, T01.e, T01.f, T01.h] created: 2026-09-16 claimed_by: null claimed_at: null diff --git a/.tasks/todo/T01.h-refresh-the-nextgraph-packages.md b/.tasks/todo/T01.h-refresh-the-nextgraph-packages.md new file mode 100644 index 0000000..46eab8f --- /dev/null +++ b/.tasks/todo/T01.h-refresh-the-nextgraph-packages.md @@ -0,0 +1,26 @@ +--- +id: T01.h +title: Refresh the NextGraph packages to their latest published versions +parent: T01 +depends_on: [T01.f] +created: 2026-09-21 +claimed_by: null +claimed_at: null +blocked: false +--- + +## Description + +Once the surface work is done, bring `@ng-org/web`, `@ng-org/orm`, `@ng-org/shex-orm` and `@ng-org/alien-deepsignals` to their latest published versions, in BOTH workspace packages, and reconcile whatever the update surfaces. + +**Why this is its own task and not a chore.** The 2026-09-21 update from `alpha.13/19/8/11` to `alpha.14/21/9/13` was expected to be routine and was not: it revealed that `orm_start_graph` had gained a sixth parameter (`config`, before the callback), which is exactly what a live measurement had observed against the deployed broker and attributed to the deployment being ahead. It also renamed `OrmSubscription` to `RdfOrmSubscription`, made `Scope.graphs` required, and — through a clean reinstall — exposed that six e2e files imported `ng-e2e-helpers` without the polyfill declaring it. An update against this SDK is a source of findings, so it gets a task and a gate. + +**What to do.** Check the published version of each of the four packages. Bump them in `packages/polyfill/package.json` and `packages/ng-e2e-helpers/package.json` together, so no two versions of a package with module-level state coexist in the tree — that duplication is the single-instance hazard the polyfill's own contract names. Reinstall with pnpm (`CI=true pnpm install --no-frozen-lockfile` when the lockfile has drifted), then read what the typechecks and the suites say rather than assuming the update was invisible. + +**Then verify against the real broker**, not only by typecheck: run `packages/polyfill/e2e/orm-live-read.ts` and the polyfill e2e suite. A signature that matches at compile time can still disagree with the deployment. + +**Record what the update revealed.** If it changes a fact already written in a doctrine leaf — an arity, a symbol name, a type's optionality — fix the leaf in the same pass. A stale fact in doctrine is worse than an absent one. + +## Progress + +## Result diff --git a/packages/ng-e2e-helpers/package.json b/packages/ng-e2e-helpers/package.json index c2949f4..31034b5 100644 --- a/packages/ng-e2e-helpers/package.json +++ b/packages/ng-e2e-helpers/package.json @@ -16,7 +16,7 @@ "@ng-org/web": ">=0.1.2-alpha.13" }, "devDependencies": { - "@ng-org/web": "0.1.2-alpha.13", + "@ng-org/web": "0.1.2-alpha.14", "playwright": "^1.61.1" }, "scripts": { diff --git a/packages/polyfill/e2e/orm-live-entry.ts b/packages/polyfill/e2e/orm-live-entry.ts index b645741..ed7b4cc 100644 --- a/packages/polyfill/e2e/orm-live-entry.ts +++ b/packages/polyfill/e2e/orm-live-entry.ts @@ -26,7 +26,7 @@ */ import { ng as realNg, init as realInit } from "@ng-org/web"; -import { initNg as ormInitNg, OrmSubscription, type Scope as OrmScope } from "@ng-org/orm"; +import { initNg as ormInitNg, RdfOrmSubscription, type Scope as OrmScope } from "@ng-org/orm"; import { configure, docs, init, useShape as libUseShape } from "@ng-eventually/polyfill"; import type { BaseType, Nuri, ShapeType } from "@ng-eventually/polyfill"; import { adoptCurrentUser, configureStoreRegistry } from "../src/shared-wallet/bootstrap"; @@ -92,9 +92,22 @@ const sessionReady = new Promise((r) => (sessionResolve = r)); * the broker refused leaves it pending for ever — the silence this measurement is here to * break. */ -let liveSubscription: OrmSubscription | null = null; +/** + * The handle this page keeps, DERIVED from `getOrCreate` rather than written by hand. + * + * `RdfOrmSubscription` (renamed from `OrmSubscription` in `@ng-org/orm@0.1.2-alpha.21`) + * now takes its config as a type parameter and `getOrCreate` returns a narrowed + * `RdfOrmSubscriptionFor<...>` - the paging methods are `Omit`ted when no `pageSize` is + * asked for. Naming the class directly would restate that narrowing and get it wrong the + * next time it moves; `ReturnType` asks the package what it actually hands back. + */ +type LiveSubscription = ReturnType< + typeof RdfOrmSubscription.getOrCreate, BaseType, OrmScope> +>; + +let liveSubscription: LiveSubscription | null = null; function realOrmUseShape(shapeType: unknown, scope: unknown): unknown { - const sub = OrmSubscription.getOrCreate(shapeType as ShapeType, scope as OrmScope); + const sub = RdfOrmSubscription.getOrCreate(shapeType as ShapeType, scope as OrmScope); liveSubscription = sub; return sub.signalObject; } diff --git a/packages/polyfill/e2e/tsconfig.json b/packages/polyfill/e2e/tsconfig.json index a940899..b70c899 100644 --- a/packages/polyfill/e2e/tsconfig.json +++ b/packages/polyfill/e2e/tsconfig.json @@ -2,7 +2,10 @@ "extends": "../../../tsconfig.base.json", "compilerOptions": { "types": ["bun"], - "noEmit": true + "noEmit": true, + "paths": { + "@ng-org/web": ["../node_modules/@ng-org/web"] + } }, "include": ["."] } diff --git a/packages/polyfill/package.json b/packages/polyfill/package.json index f3f6395..6377680 100644 --- a/packages/polyfill/package.json +++ b/packages/polyfill/package.json @@ -29,9 +29,11 @@ } }, "devDependencies": { - "@ng-org/web": "0.1.2-alpha.13", - "@ng-org/shex-orm": "0.1.2-alpha.8", - "@ng-org/alien-deepsignals": "0.1.2-alpha.11" + "@ng-org/alien-deepsignals": "0.1.2-alpha.13", + "@ng-org/orm": "0.1.2-alpha.21", + "@ng-org/shex-orm": "0.1.2-alpha.9", + "@ng-org/web": "0.1.2-alpha.14", + "ng-e2e-helpers": "workspace:*" }, "scripts": { "test": "bun test", diff --git a/packages/polyfill/src/surface/use-shape-query.ts b/packages/polyfill/src/surface/use-shape-query.ts index 99168aa..654626e 100644 --- a/packages/polyfill/src/surface/use-shape-query.ts +++ b/packages/polyfill/src/surface/use-shape-query.ts @@ -19,12 +19,18 @@ * scope still syncing reads `{ data: [], isPending: true, isSuccess: false }`. * * ── The scope is the SDK's, and translating it is EXPLICITLY TEMPORARY ───── - * `scope` is `@ng-org/orm`'s own `Scope` — `{ graphs?: string[] | string; subjects?: + * `scope` is `@ng-org/orm`'s own `Scope` — `{ graphs: string[] | string; subjects?: * string[] }` — not the three strings this module took before. A `graphs` entry names * ONE document's graph, `did:ng:i` (or `""`) discards the rest and means the whole local * dataset, and `[]` or `undefined` returns no objects at all: all three are upstream's * rules, reproduced by `normalizeScope` below. * + * `graphs` is REQUIRED as of `@ng-org/orm@0.1.2-alpha.21`; it used to be optional. Only + * the spelling changed, never the meaning: a caller who wants "everything" still has to + * say `did:ng:i`, because on this axis an empty list is the EMPTY set and not the absent + * filter. `subjects` keeps the opposite convention - there `[]` means no filtering - so + * the two axes read `[]` in opposite directions and `normalizeScope` keeps them apart. + * * Only the whole-dataset reading still has to be TRANSLATED, and the translation is the * tell that the mechanism under it is about to stop being ours: it is served by * enumerating this identity's own documents across its three stores diff --git a/packages/polyfill/test/use-shape-query.test.ts b/packages/polyfill/test/use-shape-query.test.ts index 9cd2a3f..f53d2ce 100644 --- a/packages/polyfill/test/use-shape-query.test.ts +++ b/packages/polyfill/test/use-shape-query.test.ts @@ -453,7 +453,11 @@ describe("useShapeQuery", () => { // Upstream: "Setting value to `[]` or leaving it `undefined`, no objects are returned." // It is an ANSWER, not a failure - and not the pending state either, which is what an // application would otherwise be left staring at. - const obs = useShapeQuery(EventShape, {}); + // `graphs` became REQUIRED in `@ng-org/orm@0.1.2-alpha.21`, so the "leaving it + // `undefined`" half of that sentence is no longer reachable by omitting the key. `[]` + // is the other half, and it is the one that still spells "empty" - `normalizeScope` + // maps both onto the same empty list, so this asks the same question it always did. + const obs = useShapeQuery(EventShape, { graphs: [] }); const unsub = obs.subscribe(() => {}); await tick(); await tick(); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f8bf31c..a8d913c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,21 +18,32 @@ importers: specifier: ^5.6.0 version: 5.9.3 - packages/client: - dependencies: - '@ng-org/orm': - specifier: '*' - version: 0.1.2-alpha.19 + packages/ng-e2e-helpers: devDependencies: - '@ng-org/alien-deepsignals': - specifier: 0.1.2-alpha.11 - version: 0.1.2-alpha.11 - '@ng-org/shex-orm': - specifier: 0.1.2-alpha.8 - version: 0.1.2-alpha.8(typescript@5.9.3) '@ng-org/web': specifier: 0.1.2-alpha.13 version: 0.1.2-alpha.13 + playwright: + specifier: ^1.61.1 + version: 1.61.1 + + packages/polyfill: + devDependencies: + '@ng-org/alien-deepsignals': + specifier: 0.1.2-alpha.13 + version: 0.1.2-alpha.13 + '@ng-org/orm': + specifier: 0.1.2-alpha.21 + version: 0.1.2-alpha.21 + '@ng-org/shex-orm': + specifier: 0.1.2-alpha.9 + version: 0.1.2-alpha.9(typescript@5.9.3) + '@ng-org/web': + specifier: 0.1.2-alpha.14 + version: 0.1.2-alpha.14 + ng-e2e-helpers: + specifier: workspace:* + version: link:../ng-e2e-helpers packages: @@ -42,8 +53,8 @@ packages: '@ldo/type-traverser@1.0.0-alpha.28': resolution: {integrity: sha512-pGMIVxLzoLjYVhADuVhg6r5ZDNleXZ9DcyIvLXo1/ADEocLnysg/Xjk9D/7l/Rw3WtDJrTFOOtBv8OnH+VPgKA==} - '@ng-org/alien-deepsignals@0.1.2-alpha.11': - resolution: {integrity: sha512-nPgqOrheAda/pW5FHgSb45SrSZWuyMyEVqO683ijEsVPpD105bngfh92PPfcRoRnFzGSoKXa3CfuqUHi2+qVIQ==} + '@ng-org/alien-deepsignals@0.1.2-alpha.13': + resolution: {integrity: sha512-yOEh/J+9IrCo8WDXTdZLxRcO9IHAczrUA4pjSD4BaZzmWhnCFE/amy/0PsAdh/yePurBrtQj3tG/y+hReM15Ew==} peerDependencies: react: ^19.0.0 || ^18.0.0 svelte: ^5.0.0 || ^4.0.0 @@ -56,8 +67,8 @@ packages: vue: optional: true - '@ng-org/alien-deepsignals@0.1.2-alpha.12': - resolution: {integrity: sha512-STIfMLJvwNDnAIdi/wFToLtnZDjbf0PaeYfshfMal2HbYirSPFEBue393nlYKv9rLlCrqjYOBNeSBK9FO7/Qng==} + '@ng-org/orm@0.1.2-alpha.21': + resolution: {integrity: sha512-+Dtt9jEa+277wonExxqC1BHqVwvWhXeXM51zcGg2w+Mc6C1F74qaXMGYZT3CcWCQISGEMOWV3n2movP3yQ8xJA==} peerDependencies: react: ^19.0.0 || ^18.0.0 svelte: ^5.0.0 || ^4.0.0 @@ -70,22 +81,8 @@ packages: vue: optional: true - '@ng-org/orm@0.1.2-alpha.19': - resolution: {integrity: sha512-wPDQ0OEitpoEKrvj4IJKIRxeTHr3X5+rApvZJOh54CNV1Q1b5MaT2XvyJ9YDvlgyUX2CxNkcmumV4k4ASmBXNA==} - peerDependencies: - react: ^19.0.0 || ^18.0.0 - svelte: ^5.0.0 || ^4.0.0 - vue: ^3.0.0 - peerDependenciesMeta: - react: - optional: true - svelte: - optional: true - vue: - optional: true - - '@ng-org/shex-orm@0.1.2-alpha.8': - resolution: {integrity: sha512-jogxiLfUtI3WkuF5O3PPwRBRWylpapk/JlvElGUqZnEavXXlEMmEGbK3VwqMUsbp1pweNA0sEKIFLIk3Lzt2Gg==} + '@ng-org/shex-orm@0.1.2-alpha.9': + resolution: {integrity: sha512-M69oIHrcjl24xKXIaiZjZ64rJvispAPIqn73asLPR73GWpEMvbiot/EN0vDkcfrbRy3cMEql36A9e1Nwv2csOA==} hasBin: true peerDependencies: typescript: ^4.9.0 || ^5.0.0 || ^6.0.0 @@ -93,6 +90,9 @@ packages: '@ng-org/web@0.1.2-alpha.13': resolution: {integrity: sha512-/xO0c+3NTphnws5Do2LDqgZWmAf+aNnYdChJKdU0dnp1U1iVSgi/y3yb8AYryf0v9sooj0aYJxt08B6DpirFMQ==} + '@ng-org/web@0.1.2-alpha.14': + resolution: {integrity: sha512-FPQ7kyngMhAXK/WJtZ6pkoEJwGcau6GaBH2nhjjYorMq7OG//I+zwghat90FsIeMrfYsps0+5Y0UrRqfxNdUXA==} + '@rdfjs/types@1.1.2': resolution: {integrity: sha512-wqpOJK1QCbmsGNtyzYnojPU8gRDPid2JO0Q0kMtb4j65xhCK880cnKAfEOwC+dX85VJcCByQx5zOwyyfCjDJsg==} @@ -490,19 +490,15 @@ snapshots: dependencies: uuid: 8.3.2 - '@ng-org/alien-deepsignals@0.1.2-alpha.11': + '@ng-org/alien-deepsignals@0.1.2-alpha.13': dependencies: alien-signals: 2.0.8 - '@ng-org/alien-deepsignals@0.1.2-alpha.12': + '@ng-org/orm@0.1.2-alpha.21': dependencies: - alien-signals: 2.0.8 + '@ng-org/alien-deepsignals': 0.1.2-alpha.13 - '@ng-org/orm@0.1.2-alpha.19': - dependencies: - '@ng-org/alien-deepsignals': 0.1.2-alpha.12 - - '@ng-org/shex-orm@0.1.2-alpha.8(typescript@5.9.3)': + '@ng-org/shex-orm@0.1.2-alpha.9(typescript@5.9.3)': dependencies: '@ldo/traverser-shexj': 1.0.0-alpha.28 '@ldo/type-traverser': 1.0.0-alpha.28 @@ -522,6 +518,10 @@ snapshots: dependencies: async-proxy: 0.4.1 + '@ng-org/web@0.1.2-alpha.14': + dependencies: + async-proxy: 0.4.1 + '@rdfjs/types@1.1.2': dependencies: '@types/node': 26.1.1 @@ -564,15 +564,15 @@ snapshots: '@types/concat-stream@1.6.1': dependencies: - '@types/node': 8.10.66 + '@types/node': 26.1.1 '@types/form-data@0.0.33': dependencies: - '@types/node': 8.10.66 + '@types/node': 26.1.1 '@types/http-link-header@1.0.7': dependencies: - '@types/node': 18.19.130 + '@types/node': 26.1.1 '@types/jsonld@1.5.15': {}