fix(core): the preview's scene window settles when a scene can't unmount instead of hanging the page (#6740)

* fix(core): the preview's scene window settles when a scene can't unmount instead of hanging the page

* refactor(core): name the scene window's stuck step instead of commenting it
This commit is contained in:
Miguel Ángel
2026-10-29 12:04:12 +00:00
committed by GitHub
parent 943849025a
commit 93f3d3dcbb
2 changed files with 25 additions and 1 deletions
@@ -1924,6 +1924,28 @@ describe("the preview's scene window", () => {
}
});
it("settles when a scene it would retire cannot be retired, instead of planning it again forever", async () => {
bootWindowed([S0, S1, S2], trackingRoot().root);
await tick();
window.__hfSceneAnimations = { s0: [made.a1] };
window.__timelines.elsewhere = made.a1;
try {
await seekAndSettle(5);
const host = sceneHost("s0");
const has = host.hasAttribute.bind(host);
let asks = 0;
host.hasAttribute = (name: string) => {
// A runaway plan starves every timer; seeking back to s0 is what ends it, so a failure fails, not hangs.
if (name === "data-hf-scene-no-swap" && ++asks === 1000) window.__player?.seek(0.5);
return has(name);
};
await new Promise((resolve) => setTimeout(resolve, 0));
expect(asks).toBeLessThan(100);
} finally {
delete window.__hfSceneAnimations;
}
});
it("shows a scene mounted again after the visibility pass hid it by display and it unmounted", async () => {
const leaf: Scene = { ...S2, body: "<p>two</p>", extraAttrs: ' style="position: static"' };
bootWindowed([S0, S1, leaf], trackingRoot().root);
+3 -1
View File
@@ -4580,6 +4580,7 @@ export function initSandboxRuntimeModular(): void {
const wantedNow = (name: string) =>
heldScenes.has(name) ||
scenesWanted(windowScenes, state.currentTime, clock.isPlaying()).has(name);
const parkedBeforeStep = parkedNames.size;
windowWork = (async () => {
if (landed) await mountScene(landed.name);
else if (toMount) {
@@ -4589,7 +4590,8 @@ export function initSandboxRuntimeModular(): void {
} else for (const { name } of toRetire) retireScene(name);
})().finally(() => {
windowWork = null;
windowNear = "";
const stuckStepKeepsItsPlan = parkedNames.size === parkedBeforeStep;
windowNear = stuckStepKeepsItsPlan ? key : "";
moveSceneWindow(state.currentTime);
});
// A seek is not done until the scene it lands in is mounted.