fix(client): ignore stale detail reads after refold (#106)
This commit is contained in:
1 parent
b65939e887
commit
06ec2af4ff
3 files changed
+109
-14
No files matched your search
@@ -66,6 +66,7 @@ The plugin lives off data it does not own: the durable session log (event shapes
|
||||
- **Host-side projection folds are TOTAL.** The harness projection registry drives `apply` straight off the session/event bus with no error boundary of its own: one throwing fold stalls that unit's cells and its `session/projection` push feed, and the browser waits on "loading" forever. Unknown event types return the state unchanged; per-event processing is isolated so a malformed event is dropped whole (all-or-nothing, no partial state); and no `undefined`-valued property is ever materialized into persisted state — the plain-JSON precondition makes one such property fail EVERY projection-cache write for the session, breaking sessions in unrelated, far-away places.
|
||||
- **Client-side parsing degrades visibly.** Delivered projection payloads are sanitized at the boundary (the `timelineOf` pattern: collections re-proved, scalars zeroed, whole-value absence stays `null` → loading screen); per-item work in any fold over join/log data is isolated (per-item guards, or a bounded catch where a hostile object may throw on property access); every async fetch resolves to data or a visible retryable state, never an unhandled rejection that leaves a spinner.
|
||||
- **A session with no pushed `contextTimeline` value never stalls the view.** The projection store's `seed()` clears a key its baseline omits, and a checkpoint row can be missing or version-stale on a cold-observed session — so the Context tab or `/context` modal can sit with no value at all and no push on the way. The source opens the detail channel itself in that case (rev 0): the plugin's own `/api/dsh-context/detail` route folds the durable log on demand and serves the slim head beside the collections, the next pushed head takes the channel back per its own revision, and a settled-without-data read surfaces the retryable failure note (the same `DetailNote` the detail cards use) instead of an eternal spinner.
|
||||
- **A refold invalidates earlier detail reads.** When the pushed revision decreases, the client resets its detail ledger and ignores any earlier read's data, absence, or failure. Once that read settles, the pending revision is fetched again; collections from the old fold never merge into the new head.
|
||||
- **Every field is re-proved at runtime.** Structural narrowing over blind casts; optional chaining over non-null assertions; elements that fail the shape are skipped instead of throwing.
|
||||
- **Every parser carries hostile fixtures next to its happy path**: wrong types, null/missing fields, null or primitive elements inside arrays, unpaired references, and objects that throw on property access. The repository's 100% per-file coverage bar applies to every guard branch — an untested guard is an unverified promise.
|
||||
|
||||
|
||||
Reference in new issue
Block a user