docs: ce que le hook du SDK rend vraiment, la ou le depot disait un set nu
Six endroits affirmaient au present que `useShape` rend un `DeepSignalSet` nu. C-est vrai de la revision citee, faux de celle contre laquelle ce paquet est construit - et deux de ces six PORTAIENT une decision de provenance : - `ShapeQuery kind=invention` etait justifie par "aucun type amont ne porte d-etat de chargement", alors que `isLoading` en porte un. Le kind tient, mais pour l-autre raison : ce qui n-a de contrepartie nulle part est le troisieme etat, la lecture ECHOUEE, parce qu-un `orm_start_graph` refuse n-est qu-un `console.error` et laisse une attente eternelle a tous les niveaux. - l-annotation `announced-not-written` de `useShapeQuery` posait la meme premisse fausse. La direction annoncee ne bouge pas ; sa premisse si. Ajoutee aussi l-instruction d-injection qui ne resolvait pas : l-export `.` de `@ng-org/orm` pointe sur `core`, qui n-exporte aucun `useShape`. Il est sur `/react` (export par defaut) ou `reactUseShape` sur `/all`.
This commit is contained in:
@@ -63,7 +63,7 @@ Reading the `json!({})` as *"level 1 discards the richness"* is inference from a
|
|||||||
|
|
||||||
## "Not ready" and "ready and empty" are distinguishable — one level down
|
## "Not ready" and "ready and empty" are distinguishable — one level down
|
||||||
|
|
||||||
`OrmSubscription` (`sdk/js/orm/src/connector/GraphOrmSubscription.ts`) is exported from the package entry — `core.ts`, which `@ng-org/orm` resolves `.` to — and carries a public `readyPromise` getter. In the installed alpha.21 both the symbol and its file are renamed, to `RdfOrmSubscription` and `connector/RdfOrmSubscription.ts`, and it gains an `isReady` getter that answers the same question without awaiting. So at that level the two states **are** distinguishable. The React `useShape` adapter drops the distinction: it returns a `DeepSignalSet` and documents it as *"the orm objects or an empty set, if still loading"*. The gap is between level 3's class and level 3's hook, not between us and the target.
|
`OrmSubscription` (`sdk/js/orm/src/connector/GraphOrmSubscription.ts`) is exported from the package entry — `core.ts`, which `@ng-org/orm` resolves `.` to — and carries a public `readyPromise` getter. In the installed alpha.21 both the symbol and its file are renamed, to `RdfOrmSubscription` and `connector/RdfOrmSubscription.ts`, and it gains an `isReady` getter that answers the same question without awaiting. So at that level the two states **are** distinguishable. The React `useShape` adapter drops the distinction: what it publishes beside the data is an `isLoading`, which says whether the initial payload has arrived and has no value for a read that will never answer - and its own doc still describes the data as *"the orm objects or an empty set, if still loading"*. The gap is between level 3's class and level 3's hook, not between us and the target.
|
||||||
|
|
||||||
## What this package does instead
|
## What this package does instead
|
||||||
|
|
||||||
|
|||||||
@@ -20,12 +20,12 @@ This is the surface-level sibling of [[no-divergence-from-nextgraph]], which ask
|
|||||||
|
|
||||||
**A true citation attached to the wrong claim.** `readUnion` has no counterpart upstream — it is N calls plus a batch policy — yet its head annotation reads `kind=aligned level=2 ref=sdk/js/lib-wasm/src/lib.rs:sparql_query`. That symbol exists and does what the annotation says it does. The citation is exact; the claim is false. A *composition* cannot be "aligned" on a single function. **This is the tell to watch for**, because it defeats the very thing annotations are for: a reader checks the citation, finds it correct, and moves on. The rest of the surface offers the honest form by contrast — `useShape` is annotated `kind=passthrough level=3` and the cited symbol *is* the function it forwards to. (The annotation has since been split so that the enumeration and the failure policy are marked `invention`; the head claim of alignment is still there.)
|
**A true citation attached to the wrong claim.** `readUnion` has no counterpart upstream — it is N calls plus a batch policy — yet its head annotation reads `kind=aligned level=2 ref=sdk/js/lib-wasm/src/lib.rs:sparql_query`. That symbol exists and does what the annotation says it does. The citation is exact; the claim is false. A *composition* cannot be "aligned" on a single function. **This is the tell to watch for**, because it defeats the very thing annotations are for: a reader checks the citation, finds it correct, and moves on. The rest of the surface offers the honest form by contrast — `useShape` is annotated `kind=passthrough level=3` and the cited symbol *is* the function it forwards to. (The annotation has since been split so that the enumeration and the failure policy are marked `invention`; the head claim of alignment is still there.)
|
||||||
|
|
||||||
**The legitimate deviation, so nobody concludes every difference is a fault.** `watchShape` returns a `ShapeQuery` shaped like TanStack Query's `useQuery` — `{ data, isPending, isSuccess, isError, error }` — where the SDK's `useShape` returns a bare `DeepSignalSet`. That is a real difference from what the SDK ships today, and it is **justified**: NextGraph's direction, as reported by its developers, is a `useShapeQuery` returning exactly that shape. Deviating *toward* the announced target is alignment, not divergence — it is the rest of the surface that will have to catch up.
|
**The legitimate deviation, so nobody concludes every difference is a fault.** `watchShape` returns a `ShapeQuery` shaped like TanStack Query's `useQuery` — `{ data, isPending, isSuccess, isError, error }` — where the SDK's `useShape` returns a result carrying the data and a load state and no failure at all (`{ data, promise, subscription, isLoading, nextPage, previousPage }`; the revision cited above returned the collection on its own, and that difference is the anchor's, not this rule's). That is a real difference from what the SDK ships today, and it is **justified**: NextGraph's direction, as reported by its developers, is a `useShapeQuery` returning exactly that shape. Deviating *toward* the announced target is alignment, not divergence — it is the rest of the surface that will have to catch up.
|
||||||
|
|
||||||
**The gap that same example exposed — closed by `announced-not-written`.** A target **stated by its developers but not yet written** has no `file:symbol` to cite: `useShapeQuery` has zero occurrences in the tree. The taxonomy in [[no-divergence-from-nextgraph]] had no kind for it either — `declared-not-wired` needs a declaration, `reserved-name` needs a name present in the tree — so an author holding the strongest possible justification had only two bad moves left: cite an approximate symbol, which is precisely the `readUnion` failure, or declare `invention`, which understates the alignment and tells a later reader the shape is ours to change. The kind `announced-not-written` is the third move: in place of a symbol upstream it cites the **record of the statement**, and it names who made it and when.
|
**The gap that same example exposed — closed by `announced-not-written`.** A target **stated by its developers but not yet written** has no `file:symbol` to cite: `useShapeQuery` has zero occurrences in the tree. The taxonomy in [[no-divergence-from-nextgraph]] had no kind for it either — `declared-not-wired` needs a declaration, `reserved-name` needs a name present in the tree — so an author holding the strongest possible justification had only two bad moves left: cite an approximate symbol, which is precisely the `readUnion` failure, or declare `invention`, which understates the alignment and tells a later reader the shape is ours to change. The kind `announced-not-written` is the third move: in place of a symbol upstream it cites the **record of the statement**, and it names who made it and when.
|
||||||
|
|
||||||
```
|
```
|
||||||
// @provenance useShapeQuery kind=announced-not-written level=3 ref=.project/rules/nextgraph/surface-mirrors-the-sdk.md:useShapeQuery announced-by=nextgraph-developers@2026-09-16 — the SDK ships `useShape` returning a bare `DeepSignalSet`; the announced direction is a `useShapeQuery` returning a TanStack-shaped snapshot
|
// @provenance useShapeQuery kind=announced-not-written level=3 ref=.project/rules/nextgraph/surface-mirrors-the-sdk.md:useShapeQuery announced-by=nextgraph-developers@2026-09-16 - the SDK ships `useShape`, whose result carries data and a load state and no failure; the announced direction is a `useShapeQuery` returning a TanStack-shaped snapshot
|
||||||
```
|
```
|
||||||
|
|
||||||
**This section is that record**, and the annotation above points back at it. The statement it holds: NextGraph's direction is a `useShapeQuery` returning `{ data, isPending, isSuccess, isError, error }`, reported from its developers and written down here on 2026-09-16 — the date the annotation carries, so a later reader can weigh how long the direction has been announced and still unwritten. An announcement nobody wrote down is hearsay: `packages/polyfill/test/provenance.test.ts` refuses an annotation of this kind whose record is missing, is a source file rather than prose, or no longer names the symbol.
|
**This section is that record**, and the annotation above points back at it. The statement it holds: NextGraph's direction is a `useShapeQuery` returning `{ data, isPending, isSuccess, isError, error }`, reported from its developers and written down here on 2026-09-16 — the date the annotation carries, so a later reader can weigh how long the direction has been announced and still unwritten. An announcement nobody wrote down is hearsay: `packages/polyfill/test/provenance.test.ts` refuses an annotation of this kind whose record is missing, is a source file rather than prose, or no longer names the symbol.
|
||||||
|
|||||||
+21
-6
@@ -47,7 +47,10 @@ The prose labels above map onto the annotation's closed `kind` set, and where th
|
|||||||
// shared-wallet/bootstrap.ts
|
// shared-wallet/bootstrap.ts
|
||||||
export interface EventuallyConfig {
|
export interface EventuallyConfig {
|
||||||
ng: NgLike; // the REAL @ng-org/web ng
|
ng: NgLike; // the REAL @ng-org/web ng
|
||||||
useShape: UseShapeLike; // the REAL @ng-org/orm useShape
|
useShape: UseShapeLike; // the REAL React hook: `@ng-org/orm/react`'s
|
||||||
|
// default export, or `reactUseShape` from
|
||||||
|
// `@ng-org/orm/all`. NOT on the main entry:
|
||||||
|
// `.` resolves to `core`, which has no `useShape`.
|
||||||
ormSubscription?: OrmSubscriptionLike; // the REAL @ng-org/orm RdfOrmSubscription.getOrCreate
|
ormSubscription?: OrmSubscriptionLike; // the REAL @ng-org/orm RdfOrmSubscription.getOrCreate
|
||||||
pointerGuard?: { attempts?: number; baseMs?: number; maxStepMs?: number };
|
pointerGuard?: { attempts?: number; baseMs?: number; maxStepMs?: number };
|
||||||
sharedWallet?: SharedWalletConfig; // the gate's, § 2bis
|
sharedWallet?: SharedWalletConfig; // the gate's, § 2bis
|
||||||
@@ -192,18 +195,21 @@ The overrides:
|
|||||||
### Today — `@ng-eventually/polyfill`
|
### Today — `@ng-eventually/polyfill`
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
// use-shape.ts:12
|
// use-shape.ts
|
||||||
export function useShape(shapeType: unknown, scope: unknown): unknown;
|
export function useShape<T extends BaseType>(
|
||||||
|
shapeType: ShapeType<T>,
|
||||||
|
conf: RdfOrmConfig<T> | string | undefined,
|
||||||
|
): ShapeResult; // { data, promise, subscription, isLoading, nextPage?, previousPage? }
|
||||||
// type re-exports, index.ts:48-49
|
// type re-exports, index.ts:48-49
|
||||||
export type { ShapeType, BaseType, Schema } from "@ng-org/shex-orm";
|
export type { ShapeType, BaseType, Schema } from "@ng-org/shex-orm";
|
||||||
export type { DeepSignalSet } from "@ng-org/alien-deepsignals";
|
export type { DeepSignalSet } from "@ng-org/alien-deepsignals";
|
||||||
```
|
```
|
||||||
|
|
||||||
Behaviour: forwards to the injected real `useShape`; once any emulated cap exists (`caps.isEnforcing()`), the returned set is wrapped in a read-filtered view keeping only items whose document cap the current holder has.
|
Behaviour: forwards to the injected real hook; once any emulated cap exists (`caps.isEnforcing()`), the RESULT OBJECT is wrapped in a read-filtered view. `data` and `promise` yield only items whose document cap the current holder has, `subscription` is refused (it is the ORM's own handle, which this surface does not publish), `isLoading` and the two page commands pass through, and any other member is refused unless what is behind it is a plain scalar - the rule is the value's type, so a member a later release adds is decided before anyone has seen it.
|
||||||
|
|
||||||
### Target
|
### Target
|
||||||
|
|
||||||
**PASSTHROUGH (level 3, VERIFIED), with a signature the wrapper widens.** The real hook:
|
**PASSTHROUGH (level 3, VERIFIED).** The real hook, as the CITED revision writes it:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
// level 3 — @ng-org/orm/react: sdk/js/orm/src/frontendAdapters/react/useShape.ts:86-124
|
// level 3 — @ng-org/orm/react: sdk/js/orm/src/frontendAdapters/react/useShape.ts:86-124
|
||||||
@@ -212,6 +218,15 @@ const useShape = <T extends BaseType>(
|
|||||||
scope: Scope | string | undefined
|
scope: Scope | string | undefined
|
||||||
) => DeepSignalSet<T>;
|
) => DeepSignalSet<T>;
|
||||||
|
|
||||||
|
// …and as the BUILD ships it (`dist/frontendAdapters/react/useShape.d.ts`), which is the
|
||||||
|
// shape the wrapper mirrors: the collection moved inside a result object, and the second
|
||||||
|
// parameter widened from a bare `Scope` to the config. The gap between the two columns is
|
||||||
|
// the one the provenance anchor records.
|
||||||
|
const useShape = <ST extends ShapeType<T>, const CONF extends RdfOrmConfig<T>, T extends BaseType>(
|
||||||
|
shape: ST,
|
||||||
|
conf: CONF | string | undefined
|
||||||
|
) => UseShapeResult<ST, CONF, T>; // { data, promise, subscription, isLoading, nextPage, previousPage }
|
||||||
|
|
||||||
// its Scope — sdk/js/orm/src/types.ts:25-38 (NOT this lib's Scope, see § 12)
|
// its Scope — sdk/js/orm/src/types.ts:25-38 (NOT this lib's Scope, see § 12)
|
||||||
// *(Corrected 2026-08-16: this said `sdk/js/orm/src/model/types.ts`, a path that does not
|
// *(Corrected 2026-08-16: this said `sdk/js/orm/src/model/types.ts`, a path that does not
|
||||||
// exist in the clone. The type is at `sdk/js/orm/src/types.ts:25`. A citation nobody can
|
// exist in the clone. The type is at `sdk/js/orm/src/types.ts:25`. A citation nobody can
|
||||||
@@ -257,7 +272,7 @@ export function useShapeQuery<T extends BaseType = BaseType>(
|
|||||||
): ShapeObservable<T>;
|
): ShapeObservable<T>;
|
||||||
```
|
```
|
||||||
|
|
||||||
**What it reads THROUGH, since `1.0.0-dev.6`: the SDK's own shape query.** `RdfOrmSubscription.getOrCreate(shapeType, scope)`, injected at `configure` as `ormSubscription` (§ 1). Four steps went with the change and they were one mechanism: resolving the logical scope to a document set (`listMyEntityDocs`), opening those documents through `ensureReposOpen` for a sync barrier, an anchored read over each, and filtering the result by the shape's `@type` IRI. All four existed because the parameter had to be TRANSLATED; once it is upstream's own `Scope`, the question goes to the thing that answers it, and `graphs` / `subjects` / `did:ng:i` are read by the engine literally. It does NOT delegate to the SDK's `useShape` — that is React's hook and its `DeepSignalSet` cannot carry the request state, which is the whole reason this symbol exists. What is taken from the SDK is the QUERY; the observable, the snapshot and the state tracking stay here, and so does the capability filter (`emulated-verifier/read-filter.ts`, applied per `@graph` on what comes back, exactly where § 4 applies it).
|
**What it reads THROUGH, since `1.0.0-dev.6`: the SDK's own shape query.** `RdfOrmSubscription.getOrCreate(shapeType, scope)`, injected at `configure` as `ormSubscription` (§ 1). Four steps went with the change and they were one mechanism: resolving the logical scope to a document set (`listMyEntityDocs`), opening those documents through `ensureReposOpen` for a sync barrier, an anchored read over each, and filtering the result by the shape's `@type` IRI. All four existed because the parameter had to be TRANSLATED; once it is upstream's own `Scope`, the question goes to the thing that answers it, and `graphs` / `subjects` / `did:ng:i` are read by the engine literally. It does NOT delegate to the SDK's `useShape` - that is React's hook, callable only from a render, and its result carries two states where this one publishes three: `isLoading` has no value for a read that will never answer, and there is no error state beside it. What is taken from the SDK is the QUERY; the observable, the snapshot and the state tracking stay here, and so does the capability filter (`emulated-verifier/read-filter.ts`, applied per `@graph` on what comes back, exactly where § 4 applies it).
|
||||||
|
|
||||||
**Consequences a caller sees.** `data` items are now the SHAPE's own objects — `@id`, `@graph` and the shape's readable predicates — where they were the property bags the then-published `readUnion` returned; `shapeType` is typed `ShapeType<T>` instead of `unknown`, so `T` follows the shape and the snapshot is typed without a cast; and the read no longer opens a document of its own, so a public-store document whose cap has not been fetched by some other read does not appear until it has been (the same limit § 4 carries, and the same `CapRegistry.onChange` recovery). *(Corrected 2026-09-21, `1.0.0-dev.9`: that last clause now holds only for `graphs: "did:ng:i"`. A document NAMED in `scope.graphs` is put through the same public-store fetch and sync barrier `docs.sparqlQuery` applies to its anchor, before the query opens - and is refused out loud rather than silently emptied when its cap cannot be obtained.)*
|
**Consequences a caller sees.** `data` items are now the SHAPE's own objects — `@id`, `@graph` and the shape's readable predicates — where they were the property bags the then-published `readUnion` returned; `shapeType` is typed `ShapeType<T>` instead of `unknown`, so `T` follows the shape and the snapshot is typed without a cast; and the read no longer opens a document of its own, so a public-store document whose cap has not been fetched by some other read does not appear until it has been (the same limit § 4 carries, and the same `CapRegistry.onChange` recovery). *(Corrected 2026-09-21, `1.0.0-dev.9`: that last clause now holds only for `graphs: "did:ng:i"`. A document NAMED in `scope.graphs` is put through the same public-store fetch and sync barrier `docs.sparqlQuery` applies to its anchor, before the query opens - and is refused out loud rather than silently emptied when its cap cannot be obtained.)*
|
||||||
|
|
||||||
|
|||||||
@@ -85,21 +85,29 @@ change** to any document in scope.
|
|||||||
```ts
|
```ts
|
||||||
useShape<T extends BaseType>(
|
useShape<T extends BaseType>(
|
||||||
shape: ShapeType<T>,
|
shape: ShapeType<T>,
|
||||||
scope: Scope | string | undefined,
|
conf: RdfOrmConfig<T> | string | undefined,
|
||||||
): DeepSignalSet<T>
|
): ShapeResult // { data, promise, subscription, isLoading, nextPage?, previousPage? }
|
||||||
```
|
```
|
||||||
|
|
||||||
- `shape` — the ORM shape type (generated from a SHEX shape). Names the entity type
|
- `shape` — the ORM shape type (generated from a SHEX shape). Names the entity type
|
||||||
and the properties to materialize.
|
and the properties to materialize.
|
||||||
- `scope` — where to read: a `{ graphs, subjects }` scope object or a NURI string.
|
- `conf` — where to read and how: the ORM's `RdfOrmConfig` (a `{ graphs, subjects }`
|
||||||
|
scope plus `where`, `orderBy`, `pageSize`, `maxActivePages`) or a NURI string.
|
||||||
**Not to be confused with this library's `Scope`** (`types.ts`), which is the
|
**Not to be confused with this library's `Scope`** (`types.ts`), which is the
|
||||||
literal union `public | protected | private` naming a store. Same word, two
|
literal union `public | protected | private` naming a store. Same word, two
|
||||||
meanings: the ORM's is a read target, ours is a placement.
|
meanings: the ORM's is a read target, ours is a placement.
|
||||||
`undefined` yields an empty read.
|
`undefined` yields an empty read, with `data`, `promise` and `subscription` all
|
||||||
- **Returns** a `DeepSignalSet<T>` — a **live reactive set**. Iterate it like a set;
|
`undefined` and `isLoading` false.
|
||||||
the component re-renders whenever the set changes.
|
- **Returns** the ORM's own result object, read-filtered. Read the objects off
|
||||||
|
**`data`** — a **live reactive set** (an ordered array once `orderBy` is asked for),
|
||||||
|
which the component re-renders on — or `await promise` for the same collection once
|
||||||
|
it has arrived. `isLoading` says whether the initial payload is still outstanding.
|
||||||
|
`subscription` is REFUSED here: it is the ORM's own handle, which reads and writes
|
||||||
|
with no capability filter at all, and this library does not hand it on.
|
||||||
|
|
||||||
Verified surface in `nextgraph-rs`:
|
Verified surface in `nextgraph-rs` — the CITED revision, which returns the collection
|
||||||
|
itself; the BUILD returns it inside a result object, which is the signature above and the
|
||||||
|
gap the provenance anchor records:
|
||||||
`sdk/js/orm/src/frontendAdapters/react/useShape.ts` (`useShape`, line 86) →
|
`sdk/js/orm/src/frontendAdapters/react/useShape.ts` (`useShape`, line 86) →
|
||||||
`OrmSubscription` (`sdk/js/orm/src/connector/GraphOrmSubscription.ts`), which calls
|
`OrmSubscription` (`sdk/js/orm/src/connector/GraphOrmSubscription.ts`), which calls
|
||||||
`ng.orm_start_graph(...)` with a callback, applies the initial materialized objects
|
`ng.orm_start_graph(...)` with a callback, applies the initial materialized objects
|
||||||
@@ -116,8 +124,8 @@ alongside the React one (`sdk/js/orm/src/frontendAdapters/{vue,svelte}/`).
|
|||||||
|
|
||||||
1. **An initial value.** On subscribe, the ORM materializes the current objects in
|
1. **An initial value.** On subscribe, the ORM materializes the current objects in
|
||||||
scope and delivers them first (`AppResponseV0::GraphOrmInitial`,
|
scope and delivers them first (`AppResponseV0::GraphOrmInitial`,
|
||||||
`engine/verifier/src/orm/graph/initialize.rs:113`). The hook returns them as the
|
`engine/verifier/src/orm/graph/initialize.rs:113`). The hook publishes them as
|
||||||
initial `DeepSignalSet`.
|
`data`, the initial `DeepSignalSet`.
|
||||||
2. **A stream of updates.** On every subsequent commit affecting the scope — local or
|
2. **A stream of updates.** On every subsequent commit affecting the scope — local or
|
||||||
remote — the ORM pushes a patch (`AppResponseV0::GraphOrmUpdate`), the connector
|
remote — the ORM pushes a patch (`AppResponseV0::GraphOrmUpdate`), the connector
|
||||||
applies it to the `DeepSignalSet`, and the component re-renders. No refetch, no
|
applies it to the `DeepSignalSet`, and the component re-renders. No refetch, no
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Does a live `useShape` read reach the DEPLOYED broker, and does deleting from the set it
|
* Does a live `useShape` read reach the DEPLOYED broker, and does deleting from the set it
|
||||||
* returns reach the document?
|
* publishes on `data` reach the document?
|
||||||
*
|
*
|
||||||
* Standalone, and deliberately outside `e2e/run.ts`: what it measures is the PUBLISHED
|
* Standalone, and deliberately outside `e2e/run.ts`: what it measures is the PUBLISHED
|
||||||
* `useShape` - the collection an application reads off the `data` member of what the ORM
|
* `useShape` - the collection an application reads off the `data` member of what the ORM
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
* It was `watchShape` until `1.0.0-dev.5`. That name has ZERO occurrences upstream, and
|
* It was `watchShape` until `1.0.0-dev.5`. That name has ZERO occurrences upstream, and
|
||||||
* it spent `watch`, a verb the ORM has already spent on signal observation
|
* it spent `watch`, a verb the ORM has already spent on signal observation
|
||||||
* (`watch as watchDeepSignal`). The target's own name is `useShapeQuery`, and what it
|
* (`watch as watchDeepSignal`). The target's own name is `useShapeQuery`, and what it
|
||||||
* returns is the snapshot below rather than the bare `DeepSignalSet` today's `useShape`
|
* returns is the snapshot below rather than the two states today's `useShape` hands back -
|
||||||
* hands back - announced by NextGraph's developers and on record in
|
* announced by NextGraph's developers and on record in
|
||||||
* `.project/rules/nextgraph/surface-mirrors-the-sdk.md`, which is what the annotation on
|
* `.project/rules/nextgraph/surface-mirrors-the-sdk.md`, which is what the annotation on
|
||||||
* the function cites. Deviating TOWARD an announced target is alignment; the rest of the
|
* the function cites. Deviating TOWARD an announced target is alignment; the rest of the
|
||||||
* surface is what will catch up:
|
* surface is what will catch up:
|
||||||
@@ -29,10 +29,12 @@
|
|||||||
* whole-dataset marker `did:ng:i` are now read by the engine, literally, and this module
|
* whole-dataset marker `did:ng:i` are now read by the engine, literally, and this module
|
||||||
* does not interpret them at all - so the three readings are upstream's, not ours.
|
* does not interpret them at all - so the three readings are upstream's, not ours.
|
||||||
*
|
*
|
||||||
* It does NOT delegate to the SDK's `useShape`: that is React's hook, it returns a bare
|
* It does NOT delegate to the SDK's `useShape`: that is React's hook, callable only from a
|
||||||
* `DeepSignalSet`, and a set cannot carry the request state this surface exists to
|
* render, and what it hands back carries two states where this surface publishes three. Its
|
||||||
* publish. What is taken from the SDK is the QUERY; the observable, the snapshot and the
|
* `isLoading` says whether the initial payload has arrived and has no value for "it never
|
||||||
* state tracking stay here.
|
* will" - a refused read and a slow one are the same answer there - and there is no error
|
||||||
|
* state to carry one. What is taken from the SDK is the QUERY; the observable, the snapshot
|
||||||
|
* and the state tracking stay here.
|
||||||
*
|
*
|
||||||
* -- What stays ours, and why ----------------------------------------------
|
* -- What stays ours, and why ----------------------------------------------
|
||||||
* 1. **The three states.** `readyPromise` is the ORM's own answer to "has the initial
|
* 1. **The three states.** `readyPromise` is the ORM's own answer to "has the initial
|
||||||
@@ -190,7 +192,7 @@ import type { BaseType, ShapeType } from "@ng-org/shex-orm";
|
|||||||
* (never `undefined`), and its items are the SHAPE's own objects - what the ORM
|
* (never `undefined`), and its items are the SHAPE's own objects - what the ORM
|
||||||
* returns, carrying `@id`, `@graph` and the shape's readable predicates.
|
* returns, carrying `@id`, `@graph` and the shape's readable predicates.
|
||||||
*/
|
*/
|
||||||
// @provenance ShapeQuery kind=invention level=none ref=none - no upstream type carries load state; `RdfOrmSubscription.readyPromise` expresses pending-vs-ready and nothing else (built with `resolve` alone, and a refused `orm_start_graph` is only `console.error`'d - a failed read is an eternal pending), so `isError` has no counterpart at any level
|
// @provenance ShapeQuery kind=invention level=none ref=none - no upstream type carries a FAILED read. The React hook's result carries a load state (`isLoading`) beside its data, so pending-vs-ready has a counterpart; what has none is the third state, because `readyPromise` is built with `resolve` alone and a refused `orm_start_graph` is only `console.error`'d - a failed read is an eternal pending at every level, so `isError` is answered nowhere
|
||||||
export interface ShapeQuery<T extends BaseType = BaseType> {
|
export interface ShapeQuery<T extends BaseType = BaseType> {
|
||||||
/** The objects of the requested shape/scope. Empty array when none (never undefined).
|
/** The objects of the requested shape/scope. Empty array when none (never undefined).
|
||||||
* When `isError`, this is the last read that ANSWERED - kept, not cleared, because an
|
* When `isError`, this is the last read that ANSWERED - kept, not cleared, because an
|
||||||
@@ -213,7 +215,7 @@ export interface ShapeQuery<T extends BaseType = BaseType> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** The observable a caller binds with `useSyncExternalStore` (phase B). */
|
/** The observable a caller binds with `useSyncExternalStore` (phase B). */
|
||||||
// @provenance ShapeObservable kind=invention level=none ref=none - no upstream observable exists; the ORM exposes a hook returning a DeepSignalSet and nothing else
|
// @provenance ShapeObservable kind=invention level=none ref=none - no upstream observable exists; the ORM exposes a React hook and a subscription class, neither of which a caller subscribes to with `getSnapshot`/`subscribe`
|
||||||
export interface ShapeObservable<T extends BaseType = BaseType> {
|
export interface ShapeObservable<T extends BaseType = BaseType> {
|
||||||
/** The current snapshot. STABLE across calls until it actually changes (so
|
/** The current snapshot. STABLE across calls until it actually changes (so
|
||||||
* `useSyncExternalStore` does not loop): the same reference is returned until a
|
* `useSyncExternalStore` does not loop): the same reference is returned until a
|
||||||
@@ -281,7 +283,7 @@ function sameFailure(a: unknown, b: unknown): boolean {
|
|||||||
* {@link ShapeObservable.refetch}) - that is what opens the shape query; before then
|
* {@link ShapeObservable.refetch}) - that is what opens the shape query; before then
|
||||||
* `getSnapshot` reports the initial pending snapshot.
|
* `getSnapshot` reports the initial pending snapshot.
|
||||||
*/
|
*/
|
||||||
// @provenance useShapeQuery kind=announced-not-written level=3 ref=.project/rules/nextgraph/surface-mirrors-the-sdk.md:useShapeQuery announced-by=nextgraph-developers@2026-09-16 - the SDK ships `useShape` returning a bare `DeepSignalSet`; the announced direction is a `useShapeQuery` returning a TanStack-shaped snapshot
|
// @provenance useShapeQuery kind=announced-not-written level=3 ref=.project/rules/nextgraph/surface-mirrors-the-sdk.md:useShapeQuery announced-by=nextgraph-developers@2026-09-16 - the SDK ships `useShape`, whose result carries data and a load state and no failure; the announced direction is a `useShapeQuery` returning a TanStack-shaped snapshot
|
||||||
export function useShapeQuery<T extends BaseType = BaseType>(
|
export function useShapeQuery<T extends BaseType = BaseType>(
|
||||||
shapeType: ShapeType<T>,
|
shapeType: ShapeType<T>,
|
||||||
scope: Scope,
|
scope: Scope,
|
||||||
|
|||||||
Reference in New Issue
Block a user