fix: le filtre de lecture couvre l-enveloppe que le SDK renvoie vraiment
Le `useShape` publie enveloppait le resultat du hook dans le filtre ecrit pour une COLLECTION. Depuis que `@ng-org/orm` renvoie un `UseShapeResult` autour du set, `[...resultat]` et `.size` levaient, et `data`, `promise` et `subscription` revenaient BRUTS - chacun tous les objets de toutes les identites, sans que rien ne casse. Aucun faux de ce depot ne renvoyait la forme livree, donc aucune garde ne pouvait le voir. Deux vues au lieu d-une : celle de la collection, et celle de l-enveloppe que `surface/use-shape.ts` applique. `data` et `promise` sont filtres, `subscription` est refuse (c-est le handle de l-ORM, que cette surface ne publie pas), les deux commandes de page passent. Le defaut par TYPE et non par une liste de noms : un primitif ne peut atteindre aucun objet et passe, un objet ou une fonction refuse tant qu-il n-existe pas de forme filtree ici. C-est pourquoi `isLoading` n-est nomme nulle part, et pourquoi un membre qu-une version suivante ajoutera est deja tranche. `size` et `length` comptent ce que le porteur peut lire. `UseShapeLike` etait `(...args: any[]) => any`, ce qui est la raison pour laquelle les deux typechecks restaient a 0 pendant que la fuite etait ouverte : aucune declaration ne disait ce que le hook rend. Il rend `ShapeResult`, releve sur le `.d.ts` installe, et le vrai `reactUseShape` y est assignable sans cast. Le faux partage `test/use-shape-fake.ts` renvoie la forme livree et c-est celui que les deux gardes injectent - unitaire et e2e. La garantie du contrat et le test qui l-epingle arrivent ensemble ; `1.0.0-dev.11`, majeur.
This commit is contained in:
@@ -78,9 +78,61 @@ export type PrincipalId = string;
|
||||
// @provenance NgLike kind=invention level=none ref=none — nothing upstream is injected; the type exists only to describe what `configure` receives
|
||||
export type NgLike = Record<string, any>;
|
||||
|
||||
/** Loose shape of `@ng-org/orm`'s `useShape` (a generic hook). */
|
||||
// @provenance UseShapeLike kind=invention level=none ref=none — same, for the injected `useShape`
|
||||
export type UseShapeLike = (...args: any[]) => any;
|
||||
/**
|
||||
* What the SDK's `useShape` hands back - the members this package reads off the result
|
||||
* envelope, and not one more. Same discipline as {@link OrmSubscriptionHandle}.
|
||||
*
|
||||
* NOT published: an application never writes this type down, it reads the value. What is
|
||||
* published is the call that returns one.
|
||||
*
|
||||
* `@ng-org/orm@0.1.2-alpha.21` calls it `UseShapeResult` and declares it in
|
||||
* `dist/frontendAdapters/react/useShape.d.ts` - which no subpath of the package EXPORTS
|
||||
* (`.` is `core.d.ts`, `/react` re-exports the hook alone, `/all` re-exports the config
|
||||
* types alone), so it cannot be imported and is restated here. The three item-carrying
|
||||
* members are `unknown` on purpose: each is read through the capability filter, never off
|
||||
* this type, and narrowing them here would make the real hook unassignable to
|
||||
* {@link UseShapeLike} for a difference no reader of this package can act on.
|
||||
*
|
||||
* The two page commands are OPTIONAL because upstream `WithMaybePagination` `Omit`s them
|
||||
* unless the config asks for a `pageSize`, and the shipped hook sets them to `undefined`
|
||||
* outside a paginated mode.
|
||||
*/
|
||||
// @provenance ShapeResult kind=aligned level=3 ref=sdk/js/orm/src/frontendAdapters/react/useShape.ts:useShape - the result type of the cited hook, restated because the package exports it from no subpath; the cited revision returns a bare `DeepSignalSet` and the build returns this envelope around one, which is the gap the anchor records
|
||||
export interface ShapeResult {
|
||||
/** The requested objects once loaded, `undefined` while they are not. A `DeepSignalSet`
|
||||
* for an unordered read, an array-like `DeepSignal<ReadOnlyArray>` once the config asks
|
||||
* for an `orderBy`. Upstream: "the value returned by `RdfOrmSubscription.signalObject`". */
|
||||
readonly data: unknown;
|
||||
/** Resolves to the same data once it has arrived; `undefined` when the config was. */
|
||||
readonly promise: unknown;
|
||||
/** The `RdfOrmSubscription` underneath. This package refuses to hand it on - see
|
||||
* `emulated-verifier/read-filter.ts` - and declares it here because refusing a member
|
||||
* requires knowing it is there. */
|
||||
readonly subscription: unknown;
|
||||
/** Whether the initial payload is still outstanding. */
|
||||
readonly isLoading: boolean;
|
||||
/** Load the next page. Present only under a paginated config. */
|
||||
readonly nextPage?: (() => void) | undefined;
|
||||
/** Load the previous page. Present only under `maxActivePages`. */
|
||||
readonly previousPage?: (() => void) | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shape of `@ng-org/orm`'s React `useShape`, the hook an application injects at
|
||||
* {@link configure}.
|
||||
*
|
||||
* It was `(...args: any[]) => any` until 2026-09-24, and that is not a detail: an `any`
|
||||
* return means no declaration anywhere in this package said what the injected hook hands
|
||||
* back, so the prose said "a bare `DeepSignalSet`" - true of `alpha.18`, false of the
|
||||
* `alpha.21` this package builds against - and nothing could contradict it. The type now
|
||||
* says it, and the real `reactUseShape` is assignable to it with no wrapper and no cast
|
||||
* (pinned by `test/use-shape.test.ts`).
|
||||
*/
|
||||
// @provenance UseShapeLike kind=invention level=none ref=none — nothing upstream is injected; the type exists only to describe what `configure` receives, here for the ORM's React hook
|
||||
export type UseShapeLike = <T extends BaseType>(
|
||||
shapeType: ShapeType<T>,
|
||||
conf: RdfOrmConfig<T> | string | undefined,
|
||||
) => ShapeResult;
|
||||
|
||||
/**
|
||||
* The shape query in force, as `surface/use-shape-query.ts` reads it - the four members
|
||||
@@ -121,8 +173,10 @@ export interface OrmSubscriptionHandle {
|
||||
*
|
||||
* An application injects the real one (`ormSubscription: RdfOrmSubscription.getOrCreate`);
|
||||
* it is assignable to this as it stands, with no wrapper and no cast. `useShape` is not a
|
||||
* substitute: it is React's hook, it returns a bare `DeepSignalSet`, and a set cannot
|
||||
* carry the request state `ShapeQuery` publishes.
|
||||
* substitute: it is React's hook, so it can only be called from a render, and what it
|
||||
* returns carries the ORM's own two states and not the three `ShapeQuery` publishes - an
|
||||
* `isLoading` that does not tell a refused read from a pending one, and no error state at
|
||||
* all.
|
||||
*/
|
||||
// @provenance OrmSubscriptionLike kind=invention level=none ref=none - nothing upstream is injected; the type exists only to describe what `configure` receives, here for the ORM's own `getOrCreate`
|
||||
export type OrmSubscriptionLike = <T extends BaseType>(
|
||||
|
||||
Reference in New Issue
Block a user