fix(page-templates): never strand a page-embed id in-flight (#35)

In the page-embed lookup flush(), the success branch cleared inFlightRef and
resolved waiters only for ids present in the response items. A short/partial
server response would leave a requested id stuck in inFlightRef forever (the
subscribe/refresh path is guarded by !inFlightRef.has(id)) and its refresh()
promise would never resolve. After processing returned items, also clear +
resolve any requested id that wasn't returned, mirroring the catch branch.
Cannot trigger under today's exact-mapping server contract; this is hardening.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
claude code agent 227
2026-06-20 21:42:30 +03:00
parent b8655ae52c
commit 4536d27ad2

View File

@@ -55,7 +55,9 @@ export function PageEmbedLookupProvider({
try {
const { items } = await lookupTemplate({ sourcePageIds: ids });
const returned = new Set<string>();
for (const r of items) {
returned.add(r.sourcePageId);
resultCacheRef.current.set(r.sourcePageId, r);
inFlightRef.current.delete(r.sourcePageId);
const subs = subscribersRef.current.get(r.sourcePageId);
@@ -64,6 +66,17 @@ export function PageEmbedLookupProvider({
}
resolveWaiters(r.sourcePageId);
}
// Harden against a partial/short server response: any requested id not
// present in `items` would otherwise stay in `inFlightRef` forever
// (subscribe/refresh are guarded by `!inFlightRef.has(id)`) and its
// refresh() promise would never resolve. Clear + resolve those ids,
// mirroring the catch branch, so no id can be stranded in-flight.
for (const id of ids) {
if (!returned.has(id)) {
inFlightRef.current.delete(id);
resolveWaiters(id);
}
}
} catch (err) {
// Surface the failure: errors must never be swallowed silently.
console.error("[pageEmbed] template lookup failed", err);