fix: les trois mutations posent la meme question, et la vue porte ses propres ecritures

L-ASYMETRIE, une fois de plus, et c-est elle le defaut. `delete` et `clear`
interrogeaient `keep`, `add` non - ce qui rendait la phrase publiee vraie par
coincidence : le `add` non garde FABRIQUAIT l-etat que les deux autres ne
traitaient qu-a moitie. Bob plante un objet dans le document d-ALICE, ne le
revoit jamais (la vue le refiltre), la liaison bidirectionnelle le commite
la-bas, puis `clear()` le laisse derriere. Les trois posent maintenant la meme
question ; ce qu-elles repondent differe parce que les membres different :
`delete` a `false`, qui est le mot du contrat Set pour "il n-y etait pas" et qui
est vrai de la vue ; `add` n-a aucune valeur de ce sens, donc il leve.

LA VUE PORTE SES PROPRES ECRITURES. Aucun piege `set`/`deleteProperty`/
`defineProperty` : contre un tableau ordonne, `view[0] = x`, `delete view[0]` et
`view.length = 0` passaient - le dernier defaisant `clear` entierement. Ce qui
est livre est un `readOnlyArray` qui les refuse, donc la production etait
protegee PAR LA CIBLE : la vue s-appuyait sur une garantie qu-elle ne donne pas,
sur une forme qu-elle ne controle pas. C-est l-hypothese empruntee qui est
derriere chaque defaut de cette famille.

LE PROPRIETAIRE EST SERVI. 18 membres declares d-un resultat ordonne levaient
pour celui dont ce sont les donnees, plus `includes` et les sept combinateurs
d-ensemble : une fuite echangee contre une panne. Tout ce que
`@ng-org/alien-deepsignals` declare non mutant est servi sur les objets
lisibles, et un test relit le fichier livre pour que la liste restee ici ne
derive pas.

Aussi : le descripteur d-un ACCESSEUR routait vers la cible ; le faux construit
maintenant les VRAIES collections (`deepSignal`, `readOnlyArray`) au lieu d-un
Set et d-un tableau nus, ce qui le rendait plus permissif que ce qui est livre
apres l-avoir rendu plus correct au round precedent.
This commit is contained in:
Sylvain Duchesne
2026-09-24 19:38:14 +02:00
parent b778fcff02
commit eb956c880d
5 changed files with 414 additions and 19 deletions
+14 -3
View File
@@ -18,8 +18,9 @@
* { data, promise, subscription, isLoading, nextPage, previousPage }
*
* Each of the six is reproduced with the cardinality the declaration gives it:
* - `data` is a `Set` for an unordered config and an ARRAY once `orderBy` is asked for
* (upstream `SubscriptionData<T, CONF>`), and `undefined` while nothing has arrived;
* - `data` is a `DeepSignalSet` for an unordered config and a `readOnlyArray` over a
* `DeepSignal` array once `orderBy` is asked for (upstream `SubscriptionData<T, CONF>`),
* built with upstream's OWN constructors, and `undefined` while nothing has arrived;
* - `promise` resolves to that same collection, and is `undefined` when `conf` is;
* - `subscription` is the handle, carrying the items three ways of its own -
* `signalObject`, `readyPromise` and the raw arrays a change listener is handed;
@@ -35,6 +36,14 @@
* the target proves things about a surface nobody ships.
*/
// The REAL collection kinds, not stand-ins for them. `data` is what `useDeepSignal` wraps
// - a `DeepSignalSet` unordered, a `readOnlyArray` over a `DeepSignal` array once an
// `orderBy` is asked for - and the two behave in ways a plain `Set` and a plain array do
// not: the set's `add` hands the proxy back, and the ordered one REFUSES a write to an
// index, to `length`, and even a `get` of `push`. A fake that used the plain kinds was
// MORE PERMISSIVE than what ships (it let a caller overwrite an item by index), having
// been more CORRECT than it one round earlier. Neither is a fake's business.
import { deepSignal, readOnlyArray } from "@ng-org/alien-deepsignals";
import type { BaseType } from "@ng-org/shex-orm";
import type { ShapeResult, UseShapeLike } from "../src/model/types";
@@ -94,7 +103,9 @@ export function makeUseShapeHook(
}
// `SubscriptionData<T, CONF>`: a set with no `orderBy`, an ordered array with one.
const ordered = typeof conf === "object" && conf.orderBy !== undefined;
const collection: unknown = ordered ? [...items] : new Set(items);
const collection: unknown = ordered
? readOnlyArray(deepSignal([...items]) as never)
: deepSignal(new Set(items));
lastRaw = collection;
const subscription: FakeSubscription = {
signalObject: collection,