Skip to content

fix(player): honor runtime discovery and source in embeds - #5244

Merged
jrusso1020 merged 1 commit into
heygen-com:mainfrom
user-github-me:fix/player-src-runtime-discovery
Oct 8, 2026
Merged

jrusso1020 merged 1 commit into
heygen-com:mainfrom
user-github-me:fix/player-src-runtime-discovery

Conversation

@user-github-me

@user-github-me user-github-me commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #4002
Fixes #4003

A src embed can mistake the shared window.__hf shader namespace for the runtime bridge. On current main it can report ready from document metadata while seeking leaves the authored timeline at zero; nested scenes can remain unmounted. Check the actual __player bridge so standalone timelines remain driveable and nested scenes receive the runtime.

Use the existing validated runtime-src resolver for probe injection as well as srcdoc. A blocked or missing runtime now emits a load error with its URL, stops probing, and marks that document failed. Detach the error handler when stopping or restarting so an old script cannot fail the next document. Same-origin/loopback validation and pinned-CDN fallback stay intact.

Follows the scope described in unmerged #4246, with before/after captures and additional failure/recovery coverage.

Before

Main at 188475aaf: CDN access blocked; every embed has runtime-src="/local-runtime.js" and receives seek(1). The shader namespace leaves its marker at x=40 instead of x=200. Nested scenes stay empty, and the plain nested embed fetches jsDelivr and times out.

Before: main leaves shader timelines undriven and nested scenes empty

After

Identical fixture HTML, same blocked-CDN policy. All four embeds load and seek to x=200; nested scenes use /local-runtime.js, expose __player, and register their child timelines. No CDN requests or browser runtime errors.

After: all four embeds seek correctly and nested scenes use the local bridge

Validation

  • Seven new probe cases fail on main; all 552 player tests pass after the fix (16 new cases including bridge priority, URL policy, late errors, failure latching, and recovery). Disabled script loading in Happy DOM is configured as successful; explicit error events test failures.
  • Real Chrome 152 with built player, local GSAP, and local core runtime: four before/after embeds above; separate real 404 runtime emits its URL error in 230 ms, then changing runtime-src recovers and seeks correctly.
  • All four fixture projects pass composition lint and strict browser checks.
  • Player build/runtime-version pin, both player typechecks, repository lint, and changed-file formatting pass.
  • Sandbox origin browser check passes. One-run load/scrub smoke check passes its thresholds (cold 604 ms; warm 84 ms; inline/isolated scrub p95 16.3/17.8 ms).

@jrusso1020 jrusso1020 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks, this fixes #4002 and #4003.

  • Runtime detection (#4002). shader-transitions also creates window.__hf, so __hf was never a reliable sign that the runtime had loaded. Keying on __player, which the runtime sets in the same synchronous init, fixes the src embeds that reported ready but wouldn't seek.
  • runtime-src (#4003). Reusing runtimeSrcFromElement keeps the existing http/https, same-origin or loopback rule and the pinned-CDN fallback.
  • Fail-fast. Replacing a timeout that could only ever fail removes no success path. Detaching onerror on stop/restart, plus the script and document identity checks, keeps a stale error from failing a new document.

On the vitest setting, I checked happy-dom 20.9.0. handleDisabledFileLoadingAsSuccess only changes the synthetic event for a <script src> that loading-disabled happy-dom would otherwise fail synchronously. It's documented and not deprecated, and it can't hide a real failure: every load-failure test dispatches error by hand, and nothing in the player listens for script load. Without it, 5/552 player tests fail; with it, 552/552 pass.

Non-blocking suggestion: only compositionProbeReadiness.test.ts and composition-probe.test.ts need it. A per-file // @vitest-environment-options {"settings":{"handleDisabledFileLoadingAsSuccess":true}} docblock in those two files, with the config line removed, also passes 552/552 and keeps the rest of the suite on happy-dom's defaults.

— Rames

@jrusso1020
jrusso1020 enabled auto-merge October 8, 2026 21:14
@jrusso1020
jrusso1020 added this pull request to the merge queue Oct 8, 2026
Merged via the queue into heygen-com:main with commit 2dd708e Oct 8, 2026
145 of 187 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants