From b6ff3ab74556b844dd87b067cf850badc000bba7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miguel=20=C3=81ngel?=
, so it landed after any inline script the composition carried. At the moment a composition's own script ran, window.__hyperframes was undefined and getVariables() was unreachable: our documented API did not exist at the point authors are told to call it. Served order was gsap at line 6, the composition's init script at 20, the runtime at 37. A probe inside the composition's IIFE recorded hfTypeAtInit undefined with no variable keys, and the element rendered its hardcoded fallback rather than the declared value. The runtime is designed to load early. Its entry assigns __timelines, installs the authored-opacity capture (whose own comment says it must run while the document is still parsing), and exposes __hyperframes synchronously, deferring real work to DOMContentLoaded. End-of-body injection defeated all three, and nothing in it needs a parsed DOM, so no defer is wanted. Injects at head start instead, reusing the placement cascade injectScriptsAtHeadStart already implemented rather than adding a fourth copy of it. Head start rather than the closing tag so the runtime also precedes author scripts inside head. injectRuntime has exactly one consumer, the play server's composition route. Every other surface reaches the runtime through the bundler, which already injects into head, or deliberately serves raw. Two registry blocks had independently worked around this by parsing the authored attribute themselves. Those stay, but the workaround is no longer the only way to read a variable at init. --- packages/cli/src/commands/play.test.ts | 25 +++++++++++++++++ packages/cli/src/utils/compositionServer.ts | 16 +++++++---- packages/core/src/compiler/htmlDocument.ts | 20 +++++++++---- packages/core/src/compiler/index.ts | 1 + packages/player/src/shader-options.ts | 31 ++++++++++++++++----- 5 files changed, 75 insertions(+), 18 deletions(-) diff --git a/packages/cli/src/commands/play.test.ts b/packages/cli/src/commands/play.test.ts index fda0351e6..f4fec2413 100644 --- a/packages/cli/src/commands/play.test.ts +++ b/packages/cli/src/commands/play.test.ts @@ -251,6 +251,31 @@ describe("registerCompositionRoute", () => { expect(mocks.resolveProxy).not.toHaveBeenCalled(); }); + it("serves the runtime script ahead of every author script", async () => { + // Compositions read `window.__hyperframes.getVariables()` from an inline + // script at init. A runtime injected before loads after that script, + // so the documented API is undefined exactly where authors are told to call + // it. Pin the ordering at the served-document boundary. + const project = tmpProject(); + writeFileSync( + join(project.dir, "index.html"), + [ + '
', + '