feat(runtime): swallow() helper replaces empty catches in inlined runtime

After hf#641 inlined the runtime IIFE into every bundle, lint tools
inspecting bundled output (including Abhay's c2v eval) started flagging
empty `catch {}` blocks across the runtime. The source had explanatory
comments inside, but esbuild's minifier strips them — the IIFE ships
~10 visible patterns of `}catch{}` and consumers' linters fire on each.

Each empty catch is intentional best-effort error swallowing —
postMessage to a parent frame that may not exist, `media.play()` /
`pause()` that throw under autoplay restrictions, timeline `seek()` on
a disposed timeline, anime.js / lottie feature detection on hosts that
don't load those libraries, etc. The right behaviour stays "tried,
didn't work, move on", but doing it visibly improves three things:

  - lint clean: helper call is a real statement; no `no-empty` warnings
    survive minification
  - debuggable: flip `window.__hfDebug = true` in DevTools to see every
    swallow site with `console.debug` (silent in prod by default)
  - observable: studio / embeddings can install
    `window.__hf.onSwallowed = handler` to collect runtime swallow
    events without polluting the page console

Implementation: `packages/core/src/runtime/diagnostics.ts` exports
`swallow(label, err?)`. 41 catch sites across 12 runtime files
converted via mechanical pass (auto-generated `runtime.<module>.siteN`
labels — labels can be tightened site-by-site as a follow-up; the
shape of the change is what matters here).

Verification:
- core 674/674 (incl. 6 new diagnostics tests covering silent default,
  __hfDebug logging, legacy __HYPERFRAMES_DEBUG flag, handler hook,
  handler-throws-doesn't-recurse, both-active)
- typecheck clean
- format / lint clean
- runtime IIFE rebuilds successfully (`bun run build:hyperframes-runtime`)

Refs Abhay's c2v eval — bundler artefacts now lint-clean with the
runtime body inlined.
This commit is contained in:
James
2026-05-06 23:53:21 +00:00
parent 0e7e33cf7d
commit e87196456b
15 changed files with 243 additions and 44 deletions
+5 -2
View File
@@ -1,5 +1,6 @@
import type { RuntimePlayer, RuntimeTimelineLike } from "./types";
import { quantizeTimeToFrame } from "../inline-scripts/parityContract";
import { swallow } from "./diagnostics";
type PlayerDeps = {
getTimeline: () => RuntimeTimelineLike | null;
@@ -38,8 +39,9 @@ function forEachSiblingTimeline(
if (!tl || tl === master) continue;
try {
fn(tl);
} catch {
} catch (err) {
// ignore sibling failures — one broken timeline shouldn't poison play/pause
swallow("runtime.player.site1", err);
}
}
}
@@ -76,8 +78,9 @@ function seekMasterAndSiblingTimelinesDeterministically(
for (const tl of rearmedSiblings) {
try {
tl.pause();
} catch {
} catch (err) {
// ignore sibling failures — one broken timeline shouldn't poison seek
swallow("runtime.player.site2", err);
}
}
}