fix!: joindre un document n-est pas en avoir des nouvelles, et une reinit invalide ce qu-elle abandonne
Deux defauts, aucun des deux sur la reprise - elle a passe cette revue intacte et n'a pas ete rouverte. 1. La barriere verifiait qu'un document nomme peut etre JOINT, jamais qu'il a REPONDU. Elle attendait `ensureRepoOpen` puis demandait `assertMayReach`, qui est la question de la capacite, et ne consultait pas l'etat de synchro que l'ouverture venait de produire. Un document dont l'abonnement a reussi mais dont le premier `State` n'est jamais venu publiait donc `isSuccess` avec `data: []` : le defaut d'origine, dans le cas precis pour lequel la barriere a ete ajoutee. La verification rejoint le reste de la decision, dans `publish`, donc rejouee a chaque publication au lieu d'etre memorisee. Les trois valeurs, enumerees avant d'ecrire la condition : `"synced"` fait autorite - zero ligne VEUT DIRE zero objet, la ligne tenue depuis cinq revues -, `"timed-out"` et `"syncing"` non, et `"unknown"` PASSE deliberement, parce qu'il veut dire « pas de semantique de `State` sur ce `ng` » et que le traiter autrement est exactement la regression du cas inerte livree aux tours 1 et 3. `isPending` plutot que `isError`, des deux que le contrat autorise : rien n'a echoue, il manque l'autorite de dire que le document est vide. Le test (t) EPINGLAIT le defaut - il attendait `isSuccess` apres trois barrieres expirees. Corrige. Ce n'est pas un test affaibli : l'ancienne assertion etait fausse. Et un trou dans ma propre suite, trouve par mutation : inverser la condition pour refuser `"unknown"` passait tous les tests, faute d'un `ng` SANS `doc_subscribe` nulle part. (cc) le couvre. 2. Regression de mon correctif du tour 4. Terminer une ouverture abandonnee faisait tourner sa continuation juste apres que la reinit avait vide les tables, donc elle ecrivait une entree `opened` perimee dans le registre neuf - et toute ouverture ulterieure de ce nuri court-circuitait dessus. Le depot n'etait jamais abonne dans la nouvelle session. Une epoque de registre corrige cela : une reinit l'incremente, une continuation dont l'epoque ne correspond plus n'ecrit rien. Une reinit INVALIDE ce qu'elle abandonne, en plus de le terminer. `getSyncState` reste interne, et la doctrine cesse de l'offrir : elle pointait sur un symbole qu'aucun appelant ne peut importer.
This commit is contained in:
@@ -176,7 +176,7 @@
|
||||
|
||||
import { getCaps, getConfig } from "../shared-wallet/bootstrap";
|
||||
import { filterReadable } from "../emulated-verifier/read-filter";
|
||||
import { ensureRepoOpen } from "../emulated-verifier/open-repo";
|
||||
import { ensureRepoOpen, getSyncState } from "../emulated-verifier/open-repo";
|
||||
import { assertMayReach } from "../emulated-verifier/reach";
|
||||
import { isNuri } from "../model/nuri";
|
||||
import type { Nuri, OrmSubscriptionHandle, OrmSubscriptionLike } from "../model/types";
|
||||
@@ -417,6 +417,35 @@ export function useShapeQuery<T extends BaseType = BaseType>(
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has every document the scope NAMES actually ARRIVED - not merely "may this holder
|
||||
* reach it", which is a different question and the only one this module used to ask?
|
||||
*
|
||||
* `emulated-verifier/open-repo.ts` keeps three values apart for exactly this reader, and
|
||||
* which of them counts as an answer is the whole of the decision:
|
||||
*
|
||||
* - `"synced"` - the first `State` came. THE truth signal: zero rows means zero
|
||||
* objects, and that is the success this surface exists to publish.
|
||||
* - `"timed-out"` - the bounded fallback fired with no `State`. Opened best-effort,
|
||||
* sync unconfirmed. The document may hold anything and this read has no standing to
|
||||
* call it empty. This is the case the barrier was added for and did not close.
|
||||
* - `"syncing"` - unreachable once the open has resolved (it resolves on the `State`
|
||||
* or on the fallback, and each sets its own value); refused anyway, because if it
|
||||
* ever IS reached then the barrier demonstrably was not.
|
||||
* - `"unknown"` - "never requested, or the fake-ng no-op path: no `State` semantics".
|
||||
* **Passes, deliberately.** There is no barrier to have missed where there are no
|
||||
* barrier semantics, and an `ng` without `doc_subscribe` is the whole unit suite and
|
||||
* every early path. Treating it as not-synced is the inert regression this line of
|
||||
* work has already shipped twice.
|
||||
*/
|
||||
function namedDocumentsArrived(): boolean {
|
||||
for (const doc of namedDocuments(scope)) {
|
||||
const state = getSyncState(doc);
|
||||
if (state === "timed-out" || state === "syncing") return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish what the subscription holds right now. Only ever called on a READY
|
||||
* generation, so this snapshot is always an answer.
|
||||
@@ -441,6 +470,14 @@ export function useShapeQuery<T extends BaseType = BaseType>(
|
||||
setUnknown(refusal);
|
||||
return;
|
||||
}
|
||||
// NOT AUTHORITATIVE YET, so say nothing rather than say "empty". A named document
|
||||
// whose sync barrier was never crossed may hold anything, and publishing the ORM's
|
||||
// view of it as `isSuccess` is the original defect in the one case the barrier was
|
||||
// added to close. Returning here leaves the snapshot where it was - the initial
|
||||
// pending one on a first publication - which is the contract's "a longer `isPending`",
|
||||
// and never a successful empty. Re-read on every publication, so a `State` that lands
|
||||
// later and brings data republishes through the ORM's own change signal and answers.
|
||||
if (!namedDocumentsArrived()) return;
|
||||
setSnapshot({
|
||||
data: readable(handle),
|
||||
isPending: false,
|
||||
|
||||
Reference in New Issue
Block a user