Skip to content

fix(core): harden runtime resolution, inline constant, CI smoke test#458

Merged
miguel-heygen merged 1 commit intomainfrom
fix/runtime-fallback-resolution
Apr 23, 2026
Merged

fix(core): harden runtime resolution, inline constant, CI smoke test#458
miguel-heygen merged 1 commit intomainfrom
fix/runtime-fallback-resolution

Conversation

@miguel-heygen
Copy link
Copy Markdown
Collaborator

@miguel-heygen miguel-heygen commented Apr 23, 2026

Summary

Hardens the runtime resolution pipeline end-to-end so the #452 bug class can't recur, and adds a CI smoke test to catch it if it does.

Core hardening

buildHyperframesRuntimeScript() in @hyperframes/core used to call esbuild.buildSync() unconditionally on src/runtime/entry.ts. When any consumer bundles core (tsup, webpack, etc.), import.meta.url resolves to the bundle — not the source tree — and esbuild crashes with ✘ [ERROR] on stderr before throwing. The JS-level catch can't suppress that.

Fix: existsSync(entryPath) guard before calling esbuild. Returns null when entry.ts is missing. No stderr, no crash, no consumer-side workaround needed.

Inlined runtime constant

New export getHyperframeRuntimeScript() — the build script bakes the IIFE into src/generated/runtime-inline.ts as a string constant. No esbuild, no file I/O, no import.meta.url path arithmetic. This is the production-safe default.

The split follows the design from the review: loadHyperframeRuntimeSource() stays as the dev-only helper (esbuild from entry.ts), getHyperframeRuntimeScript() is the production path (baked-in constant).

CLI resolution chain

loadRuntimeSource() in the CLI now has a clear priority chain:

  1. esbuild from source — dev only, gated on entry.ts existence
  2. inlined constantgetHyperframeRuntimeScript(), production default
  3. pre-built artifact — reads IIFE file from dist/, fallback for edge cases

CI smoke test

New smoke-global-install job that reproduces the exact user flow:

  1. npm pack → install globally with --prefix
  2. hyperframes init --example blank
  3. hyperframes preview --port 3099
  4. Assert GET /api/runtime.js returns non-empty JS
  5. Assert stderr has no ✘ [ERROR] or Failed to load runtime

Validated: grep pattern catches the pre-#452 broken state (verified against 0.4.15-alpha.1) and passes on fixed code. CI green.

Other

  • Version bump to 0.4.16
  • .github/workflows/** added to change detection filter
  • oxfmt trailing blank line fix in chunkEncoder.test.ts

Test plan

  • bun run build passes
  • bun run --cwd packages/core test — 514 tests pass
  • bun run --cwd packages/cli test — 161 tests pass
  • Smoke test catches broken state, passes on fixed code
  • Smoke test CI job green
  • npm pack --dry-run confirms dist/generated/runtime-inline.js ships

@miguel-heygen miguel-heygen force-pushed the fix/runtime-fallback-resolution branch from 340ce52 to 6947d6f Compare April 23, 2026 19:31
Copy link
Copy Markdown
Collaborator

@jrusso1020 jrusso1020 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: approve

Squash is faithful to the two reviews I already went through — #455 (CI smoke) + #457 (core hardening + inline constant). I diffed the composite hunks against the originals:

  • ci.yml smoke-global-install + .github/workflows/** filter — same as #455.
  • loadRuntimeSource three-strategy chain with getInlinedRuntime between buildFromSource and readPrebuiltArtifact — same as #457.
  • buildHyperframesRuntimeScript(): string | null with existsSync(entryPath) guard — same.
  • Generated src/generated/runtime-inline.ts via the JSON-escaped IIFE constant, gitignored, wired into packages/core/src/index.ts — same.
  • Build order flip build:hyperframes-runtime && tsc — same.
  • All caller-side null-handling (loadHyperframeRuntimeSource, core dev scripts, engine test-fitTextFontSize-browser.ts, build-hyperframes-runtime-artifact.ts) — same.

New in the squash: uniform 0.4.15 → 0.4.16 bump across cli, core, engine, player, producer, shader-transitions, studio. Correct for a release cut that carries both #452's shipping fix and this hardening — the inlined-constant export is a new public API on @hyperframes/core, so a minor-revision bump (rather than patch) would also be defensible, but 0.4.16 is fine given the pre-1.0 posture.

Prior non-blockers still apply (see <https://github.com/heygen-com/hyperframes/pull/455#pullrequestreview-4165273519|#455 review> and <https://github.com/heygen-com/hyperframes/pull/457#pullrequestreview-4165276834|#457 review>): npx variant follow-up, fresh-clone typecheck footgun for src/generated/ (postinstall fix), trivial tarball bloat, and the housekeeping ask to promote Smoke: global install to a required check in branch protection once this lands.

Minor observation: the PR body mentions "oxfmt trailing blank line fix in chunkEncoder.test.ts" but that hunk isn't in the #458 diff — it was part of #452, already on main. Body line is stale; not a review concern.

CI at review time: the initial run was cancelled on all core jobs (Build/Typecheck/Test/Lint/Windows) — probably a force-push retrigger. A second run is in flight (regression shards, perf, Windows render in_progress, Smoke: global install cancelled-and-presumably-queued). My approval is on code merit; gate the merge on green CI as usual, with particular attention to Typecheck given the generated-file arithmetic.

Ship it once CI settles green.


Review by hyperframes

… test

Guard buildHyperframesRuntimeScript() against missing entry.ts so it
returns null instead of crashing with esbuild stderr output. Add
getHyperframeRuntimeScript() that returns the pre-built IIFE as a
baked-in string constant — no esbuild, no file I/O, no import.meta.url.

Consolidate CLI runtime source resolution into a single module with
a clear priority chain: esbuild from source (dev) → inlined constant
(production) → pre-built artifact file (fallback).

Add CI smoke test that npm-packs the CLI, installs globally, runs
hyperframes preview, and asserts no stderr errors + runtime endpoint
returns JS.

Bump version to 0.4.16.
@miguel-heygen miguel-heygen force-pushed the fix/runtime-fallback-resolution branch from 6947d6f to e51a682 Compare April 23, 2026 19:35
@miguel-heygen miguel-heygen merged commit 072814e into main Apr 23, 2026
36 checks passed
@miguel-heygen miguel-heygen deleted the fix/runtime-fallback-resolution branch April 23, 2026 19:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants