fix(core,cli): address review — guard __renderReady, drop pre-quantization, add tests

- Guard __renderReady with `if (state.capturedTimeline)` in all three
  paths (setTimeout(0) and .finally() were setting it unconditionally
  even when bindRootTimelineIfAvailable returned false)
- Remove redundant fps=30 pre-quantization in snapshot — renderSeek
  already calls quantizeTimeToFrame internally with the runtime's
  canonicalFps, so pre-quantizing was double-quantizing at a
  potentially wrong grid
- Add regression tests: __renderReady is set when timeline exists,
  stays undefined when no timeline is available
This commit is contained in:
Miguel Ángel
2026-05-24 13:31:36 -04:00
parent 16e049b320
commit e7d0b392c7
3 changed files with 56 additions and 8 deletions
+48
View File
@@ -576,4 +576,52 @@ describe("initSandboxRuntimeModular", () => {
expect(player?.getTime()).toBeCloseTo(1, 1);
expect(childTimeline.time()).toBeCloseTo(1, 1);
});
it("sets __renderReady only after timeline is bound, not at __playerReady time", async () => {
const root = document.createElement("div");
root.setAttribute("data-composition-id", "main");
root.setAttribute("data-root", "true");
root.setAttribute("data-start", "0");
root.setAttribute("data-width", "1920");
root.setAttribute("data-height", "1080");
document.body.appendChild(root);
(window as Window & { __timelines?: Record<string, RuntimeTimelineLike> }).__timelines = {
main: createMockTimeline(10),
};
initSandboxRuntimeModular();
const win = window as Window & {
__playerReady?: boolean;
__renderReady?: boolean;
__player?: { _timeline: RuntimeTimelineLike | null };
};
expect(win.__playerReady).toBe(true);
expect(win.__renderReady).toBe(true);
expect(win.__player?._timeline).not.toBeNull();
});
it("does not set __renderReady when no timeline is available", () => {
const root = document.createElement("div");
root.setAttribute("data-composition-id", "main");
root.setAttribute("data-root", "true");
root.setAttribute("data-start", "0");
root.setAttribute("data-width", "1920");
root.setAttribute("data-height", "1080");
document.body.appendChild(root);
(window as Window & { __timelines?: Record<string, RuntimeTimelineLike> }).__timelines = {};
initSandboxRuntimeModular();
const win = window as Window & {
__playerReady?: boolean;
__renderReady?: boolean;
};
expect(win.__playerReady).toBe(true);
expect(win.__renderReady).toBeUndefined();
});
});
+6 -3
View File
@@ -1463,7 +1463,9 @@ export function initSandboxRuntimeModular(): void {
.finally(() => {
externalCompositionsReady = true;
bindRootTimelineIfAvailable();
(window as Window & { __renderReady?: boolean }).__renderReady = true;
if (state.capturedTimeline) {
(window as Window & { __renderReady?: boolean }).__renderReady = true;
}
runAdapters("discover", state.currentTime);
bindMediaMetadataListeners();
installAssetFailureDiagnostics();
@@ -1650,9 +1652,10 @@ export function initSandboxRuntimeModular(): void {
if (bindRootTimelineIfAvailable() && state.capturedTimeline !== prevTimeline) {
player._timeline = state.capturedTimeline;
}
// Re-run adapters to discover new elements
runAdapters("discover", state.currentTime);
(window as Window & { __renderReady?: boolean }).__renderReady = true;
if (state.capturedTimeline) {
(window as Window & { __renderReady?: boolean }).__renderReady = true;
}
postTimeline();
postState(true);
}, 0);