()
| 71 | } |
| 72 | |
| 73 | export function initSandboxRuntimeModular(): void { |
| 74 | const state = createRuntimeState(); |
| 75 | const exportRenderFps = resolveExportRenderFps(); |
| 76 | state.canonicalFps = exportRenderFps.fps ?? state.canonicalFps; |
| 77 | if (window.__HF_EXPORT_RENDER_SEEK_CONFIG) { |
| 78 | console.info("[hyperframes] render runtime fps", { |
| 79 | canonicalFps: state.canonicalFps, |
| 80 | source: exportRenderFps.source, |
| 81 | rawFpsSource: exportRenderFps.rawFpsSource, |
| 82 | rawFps: exportRenderFps.rawFps, |
| 83 | fallbackReason: exportRenderFps.fallbackReason, |
| 84 | }); |
| 85 | } |
| 86 | let colorGradingRuntime: RuntimeColorGradingApi | null = null; |
| 87 | let runtimeErrorListener: ((event: ErrorEvent) => void) | null = null; |
| 88 | let runtimeUnhandledRejectionListener: ((event: PromiseRejectionEvent) => void) | null = null; |
| 89 | const runtimeCleanupCallbacks: Array<() => void> = []; |
| 90 | const postedDiagnosticKeys = new Set<string>(); |
| 91 | let rootStageDiagnosticRafId: number | null = null; |
| 92 | if (typeof window.__hfRuntimeTeardown === "function") { |
| 93 | try { |
| 94 | window.__hfRuntimeTeardown(); |
| 95 | } catch (err) { |
| 96 | // keep runtime resilient across reinits |
| 97 | swallow("runtime.init.site1", err); |
| 98 | } |
| 99 | } |
| 100 | // `_auto` is a Studio-internal keyframe marker (an auto-tracked endpoint the |
| 101 | // parser reads back), NOT an animatable property. Register it as a no-op GSAP |
| 102 | // plugin so GSAP doesn't log "Invalid property _auto" on every tween build — |
| 103 | // that per-frame warning destabilizes the preview and makes the selection |
| 104 | // overlay stop tracking the pointer. Idempotent + best-effort. |
| 105 | const ensureAutoMarkerNoop = (): void => { |
| 106 | const g = window.gsap as { registerPlugin?: (plugin: unknown) => void } | undefined; |
| 107 | const w = window as Window & { __hfAutoNoopRegistered?: boolean }; |
| 108 | if (!g?.registerPlugin || w.__hfAutoNoopRegistered) return; |
| 109 | try { |
| 110 | g.registerPlugin({ name: "_auto", init: () => false }); |
| 111 | w.__hfAutoNoopRegistered = true; |
| 112 | } catch { |
| 113 | // a stray warning is preferable to a broken runtime |
| 114 | } |
| 115 | }; |
| 116 | ensureAutoMarkerNoop(); |
| 117 | // Normalize html/body so browser defaults (8px margin, white background) never |
| 118 | // bleed into renders as white bars. Runs in both preview and render contexts, |
| 119 | // eliminating the preview/render parity gap that existed when only the React |
| 120 | // component's normalizePreviewViewport call applied this normalization. |
| 121 | if (document.documentElement) { |
| 122 | document.documentElement.style.margin = "0"; |
| 123 | document.documentElement.style.padding = "0"; |
| 124 | document.documentElement.style.overflow = "hidden"; |
| 125 | } |
| 126 | if (document.body) { |
| 127 | document.body.style.margin = "0"; |
| 128 | document.body.style.padding = "0"; |
| 129 | document.body.style.overflow = "hidden"; |
| 130 | } |
no test coverage detected