mirror of
https://github.com/backnotprop/plannotator.git
synced 2026-09-14 14:17:26 +08:00
c2950e709f
Fixes from the 0.27.9 pre-release review. Servers: an unreadable rendered-HTML root falls back to the startup snapshot on both runtimes with a once-per-process warning instead of hanging (Pi) or answering 500 (Bun); the version diff is recomputed against current bytes on reload and carried through the in-app Refresh instead of being dropped, with no history write on a GET. Client: a Refresh action on the compact touch shell; HtmlSurfaceControls renders Refresh independently of the eye; the dead HtmlSurfaceActions removed. Threading: one linear, cycle-safe reply resolution shared by the annotations panel, its sort, and the export (5,000-chain tests), PATCH ingest on both runtimes rejects self-references and cycles, nothing is ever dropped from feedback. WebMCP and viewer hygiene: bounded tombstone and request memories, per-instance minted ids, nudge id caps, waiter cleanup on unmount, a shared retry epoch for diagram blocks. Docs: HTML Refresh documented, the WebMCP design pointer fixed, marketing pages updated. AI-assisted (Claude) under maintainer direction.
32 lines
1.0 KiB
TypeScript
32 lines
1.0 KiB
TypeScript
/**
|
|
* A shared retry epoch for lazily loaded diagram runtimes.
|
|
*
|
|
* Mermaid and Graphviz memoize one runtime per module, so when a chunk
|
|
* import fails every block on the page fails together. Each block's Retry
|
|
* button used to bump only that block's own token, leaving its siblings on
|
|
* their error panels after the shared runtime had recovered. Bumping the
|
|
* epoch notifies every subscribed block, so one Retry re-attempts all of
|
|
* them (the memoized loader still issues a single import for the batch).
|
|
*/
|
|
export interface RuntimeRetryEpoch {
|
|
/** Ask every subscriber to re-attempt. */
|
|
bump(): void;
|
|
/** Subscribe; returns the unsubscribe. */
|
|
subscribe(listener: () => void): () => void;
|
|
}
|
|
|
|
export function createRuntimeRetryEpoch(): RuntimeRetryEpoch {
|
|
const listeners = new Set<() => void>();
|
|
return {
|
|
bump() {
|
|
for (const listener of [...listeners]) listener();
|
|
},
|
|
subscribe(listener) {
|
|
listeners.add(listener);
|
|
return () => {
|
|
listeners.delete(listener);
|
|
};
|
|
},
|
|
};
|
|
}
|