fix(client): dé-dupliquer les ensureAccount concurrents au cold-start (fork résolu)
Dernière couche du bug de reconnexion : au cold-start, `watchShape` public + protected + l'effet owned-events appellent `ensureAccount(A)` quasi-simultanément AVANT la sync du shim → chacun lit 0 → chacun provisionne un nouveau jeu de docs (fork par-appelant) → la résolution déterministe canonique fait alors diverger lecteur et écrivain sur le docProtected → `readScopeIndex` vide. Fix : `ensureInFlight` (map de promesses) dé-duplique les provisions concurrentes en UNE seule ; `discovery.readIndex` ouvre son repo au cold-start (`ensureRepoOpen`). Avec la résolution canonique déjà committée, écrivain et lecteur convergent. Mesuré (levier isSuccess) : la participation protected converge `isSuccess=true, data=1` sur la page fraîche (plus « vide à 30s »). gate : tsc 0 ; bun test 123 ; test:e2e 42/42. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -39,6 +39,7 @@
|
||||
|
||||
import * as inbox from "./inbox";
|
||||
import { subscribeDoc } from "./subscribe";
|
||||
import { ensureRepoOpen } from "./open-repo";
|
||||
import { ensureAccount, reservedAccount } from "./store-registry";
|
||||
import { getCaps } from "./polyfill";
|
||||
import type { Nuri, PrincipalId } from "./types";
|
||||
@@ -154,6 +155,19 @@ export async function submitToIndex(ref: unknown, opts?: SubmitOptions): Promise
|
||||
*/
|
||||
export async function readIndex(): Promise<IndexEntry[]> {
|
||||
const target = await indexInboxNuri();
|
||||
// COLD-START heal (polyfill-era): on a FRESH session over a persistent wallet the
|
||||
// discovery-index inbox repo is not yet in the verifier's `self.repos`, so the
|
||||
// anchored `inbox.read` below would resolve an unopened repo and silently return 0
|
||||
// deposits — the same self-inflicted cold-read gap `readScopeIndex`/`readUnion`
|
||||
// heal. This is what made the PUBLIC read's discovery fold come back empty on a
|
||||
// reconnect, so a fresh page's home stayed empty for tens of seconds while the doc
|
||||
// slowly synced by other means. Open/subscribe the index repo ONCE and await its
|
||||
// first `State` (the sync barrier) before the anchored read. Idempotent per session;
|
||||
// no-op with the unit fake ng (no `doc_subscribe`). This is done HERE (a cold direct
|
||||
// reader) rather than inside `inbox.read`, because `inbox.watch` already holds the
|
||||
// repo open via its own subscription and must not spawn a second bootstrap open. See
|
||||
// open-repo.ts.
|
||||
await ensureRepoOpen(target);
|
||||
const deposits = await inbox.read(target);
|
||||
const seen = new Set<string>();
|
||||
const entries: IndexEntry[] = [];
|
||||
|
||||
Reference in New Issue
Block a user