fix!: le registre d-ouverture n-a plus qu-un seul sens, et il cesse de mentir
Trois constats, un seul defaut sous trois visages : un etat enregistre comme vrai qui ne l'est pas, sans moyen de se corriger. Deux des trois vivaient dans `open-repo.ts`. Cinq tours sont alles dans l'appelant ; c'est le teneur de registre qui mentait. CE QUE LE REGISTRE VEUT DIRE, ecrit dans l'en-tete. `held` est le SEUL registre d'ouverture : cette session detient un abonnement vivant a ce document. Il y avait a cote un `opened` voulant dire « on a appele `doc_subscribe` une fois et on a cesse d'attendre », et ce sens plus lache mentait de trois facons : il survivait a un abonnement REFUSE par le courtier (donc la reprise que `subscribe.ts` offre etait bloquee a jamais), il survivait a une reinitialisation (donc une nouvelle session court-circuitait sur l'enregistrement de la precedente), et il laissait un document annoncer une barriere jamais franchie. `opened` est supprime. Les trois consequences, desormais vraies par construction : - un abonnement qui a ECHOUE n'enregistre rien - `onSetupFailed`, le canal que `subscribe.ts` offre exactement pour cela, est enfin branche - donc l'appelant suivant s'abonne a nouveau ; - une reinitialisation efface l'enregistrement ET DECLASSE l'etat de synchro : une barriere franchie dans la session qui vient de disparaitre n'en est pas une que celle-ci a franchie ; - `"unknown"` ne veut plus dire qu'une chose : aucune barriere n'etait attendue ici (jamais demande, ou un `ng` sans `doc_subscribe`). Jamais « on a oublie ». Cote appelant, un seul changement, et c'est le troisieme constat : quand un document nomme n'a pas repondu, `publish` PUBLIE « la question reste ouverte » au lieu de sortir en laissant en place l'instantane precedent. Sortir laissait un refus DEJA LEVE a l'affichage : l'application lisait « vous ne detenez pas la capacite de ce document » a propos d'un document qu'elle detient desormais. Deux tests portaient l'ancien sens et sont corriges avec leur raison : celui du `ng` sans `doc_subscribe` (le compteur d'ids du faux courtier redemarrait a chaque test, donc deux tests aliasaient leurs depots - la lecon de `wallet-fake` a l'echelle du fichier), et celui de la lecture froide, ou « timed-out » est desormais ce que dit « cette page ne l'a pas confirme ».
This commit is contained in:
@@ -380,6 +380,26 @@ export function useShapeQuery<T extends BaseType = BaseType>(
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish "the question is still open" - no authority yet, and nothing to say about the
|
||||
* data either way.
|
||||
*
|
||||
* `data` is carried over for the same reason {@link setUnknown} carries it: an observable
|
||||
* cannot un-emit a list a subscriber has already rendered. Before the first answer there
|
||||
* is nothing to carry and it stays `[]`. Idempotent, so a document that keeps failing to
|
||||
* sync does not wake every bound view on each attempt.
|
||||
*/
|
||||
function setNotYetAnswered(): void {
|
||||
if (snapshot.isPending && !snapshot.isSuccess && !snapshot.isError) return;
|
||||
setSnapshot({
|
||||
data: snapshot.data,
|
||||
isPending: true,
|
||||
isSuccess: false,
|
||||
isError: false,
|
||||
error: undefined,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The readable items of the live subscription, as a plain array.
|
||||
*
|
||||
@@ -470,14 +490,20 @@ 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;
|
||||
// NOT AUTHORITATIVE YET, so say the question is still open 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.
|
||||
//
|
||||
// It PUBLISHES pending rather than returning. Returning left whatever snapshot was
|
||||
// standing, and that was wrong in the case that matters: a refusal that has since been
|
||||
// LIFTED stayed on display, so an application was handed `isError` reading "you do not
|
||||
// hold this document's cap" about a document it now holds. Whatever the state was, it
|
||||
// is not the answer to the question just asked.
|
||||
if (!namedDocumentsArrived()) {
|
||||
setNotYetAnswered();
|
||||
return;
|
||||
}
|
||||
setSnapshot({
|
||||
data: readable(handle),
|
||||
isPending: false,
|
||||
|
||||
Reference in New Issue
Block a user