@hyperframes/studio 0.8.192 → 0.8.193

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import{n as Qi}from"./index-CHu83hHM.js";/*!
1
+ import{n as Qi}from"./index-Ca-mgTnS.js";/*!
2
2
  * Copyright (c) 2026-present, Vanilagy and contributors
3
3
  *
4
4
  * This Source Code Form is subject to the terms of the Mozilla Public
@@ -1028,7 +1028,8 @@ function sceneSwapFor(iframe) {
1028
1028
  () => deadline.abort(new Error("the preview took too long to swap")),
1029
1029
  SCENE_SWAP_MS
1030
1030
  );
1031
- cancel?.addEventListener("abort", () => deadline.abort(cancel.reason), { once: true });
1031
+ const onCancel = () => deadline.abort(cancel?.reason);
1032
+ cancel?.addEventListener("abort", onCancel, { once: true });
1032
1033
  const swapping = (async () => {
1033
1034
  const response = await studioApiFetch(url, { signal: deadline.signal });
1034
1035
  if (!response.ok) throw new Error(`preview request failed with ${response.status}`);
@@ -1043,6 +1044,7 @@ function sceneSwapFor(iframe) {
1043
1044
  await Promise.race([swapping, expired]);
1044
1045
  } finally {
1045
1046
  clearTimeout(timer);
1047
+ cancel?.removeEventListener("abort", onCancel);
1046
1048
  }
1047
1049
  iframe.dispatchEvent(new Event(SCENES_SWAPPED));
1048
1050
  };
package/dist/index.html CHANGED
@@ -14,7 +14,7 @@
14
14
  document.documentElement.dataset.theme = "paper";
15
15
  }
16
16
  </script>
17
- <script type="module" crossorigin src="/assets/index-CHu83hHM.js"></script>
17
+ <script type="module" crossorigin src="/assets/index-Ca-mgTnS.js"></script>
18
18
  <link rel="stylesheet" crossorigin href="/assets/index-CYbvOVp-.css">
19
19
  </head>
20
20
  <body>
package/dist/index.js CHANGED
@@ -48,7 +48,7 @@ import {
48
48
  usePreviewVariablesStore,
49
49
  whenPreviewBooted,
50
50
  writeStudioUiPreferences
51
- } from "./chunk-6SXUUBPD.js";
51
+ } from "./chunk-ORLUDHTU.js";
52
52
  import {
53
53
  Button,
54
54
  ContextMenu,
package/dist/player.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Player
3
- } from "./chunk-6SXUUBPD.js";
3
+ } from "./chunk-ORLUDHTU.js";
4
4
  import "./chunk-7HZGKFFU.js";
5
5
  import "./chunk-T43DM7Q6.js";
6
6
  import "./chunk-MLKGABMK.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperframes/studio",
3
- "version": "0.8.192",
3
+ "version": "0.8.193",
4
4
  "description": "",
5
5
  "repository": {
6
6
  "type": "git",
@@ -60,12 +60,12 @@
60
60
  "dockview-react": "8.3.1",
61
61
  "gsap": "^3.13.0",
62
62
  "mediabunny": "^1.45.3",
63
- "@hyperframes/core": "0.8.192",
64
- "@hyperframes/parsers": "0.8.192",
65
- "@hyperframes/player": "0.8.192",
66
- "@hyperframes/sdk": "0.8.192",
67
- "@hyperframes/shader-transitions": "0.8.192",
68
- "@hyperframes/studio-server": "0.8.192"
63
+ "@hyperframes/parsers": "0.8.193",
64
+ "@hyperframes/sdk": "0.8.193",
65
+ "@hyperframes/core": "0.8.193",
66
+ "@hyperframes/shader-transitions": "0.8.193",
67
+ "@hyperframes/studio-server": "0.8.193",
68
+ "@hyperframes/player": "0.8.193"
69
69
  },
70
70
  "devDependencies": {
71
71
  "@tailwindcss/vite": "^4.3.3",
@@ -82,7 +82,7 @@
82
82
  "vite": "^6.4.2",
83
83
  "vitest": "^4.1.11",
84
84
  "zustand": "^5.0.0",
85
- "@hyperframes/producer": "0.8.192"
85
+ "@hyperframes/producer": "0.8.193"
86
86
  },
87
87
  "peerDependencies": {
88
88
  "react": "19",
@@ -98,6 +98,28 @@ describe("sceneSwapFor", () => {
98
98
  expect(swap).not.toHaveBeenCalled();
99
99
  });
100
100
 
101
+ it("leaves no listener on the caller's cancel signal once swaps settle, so a swapped film can be freed", async () => {
102
+ vi.spyOn(globalThis, "fetch").mockImplementation(async () => new Response("<html></html>"));
103
+ const cancel = new AbortController();
104
+ const live = new Set<unknown>();
105
+ const { signal } = cancel;
106
+ const add = signal.addEventListener.bind(signal);
107
+ const remove = signal.removeEventListener.bind(signal);
108
+ signal.addEventListener = ((type: string, listener: EventListener, options?: unknown) => {
109
+ live.add(listener);
110
+ add(type, listener, options as AddEventListenerOptions);
111
+ }) as AbortSignal["addEventListener"];
112
+ signal.removeEventListener = ((type: string, listener: EventListener, options?: unknown) => {
113
+ live.delete(listener);
114
+ remove(type, listener, options as EventListenerOptions);
115
+ }) as AbortSignal["removeEventListener"];
116
+ const { iframe } = swappableIframe();
117
+ const refused = swappableIframe(vi.fn(async () => Promise.reject(new Error("refused")))).iframe;
118
+ for (let n = 0; n < 3; n++) await sceneSwapFor(iframe)!("/preview", () => true, signal);
119
+ await expect(sceneSwapFor(refused)!("/preview", () => true, signal)).rejects.toThrow("refused");
120
+ expect(live.size).toBe(0);
121
+ });
122
+
101
123
  it("swaps a document that arrives in time", async () => {
102
124
  vi.spyOn(globalThis, "fetch").mockImplementation(async () => new Response("<html></html>"));
103
125
  const { iframe, swap } = swappableIframe();
@@ -88,7 +88,8 @@ export function sceneSwapFor(
88
88
  () => deadline.abort(new Error("the preview took too long to swap")),
89
89
  SCENE_SWAP_MS,
90
90
  );
91
- cancel?.addEventListener("abort", () => deadline.abort(cancel.reason), { once: true });
91
+ const onCancel = () => deadline.abort(cancel?.reason);
92
+ cancel?.addEventListener("abort", onCancel, { once: true });
92
93
  const swapping = (async () => {
93
94
  const response = await studioApiFetch(url, { signal: deadline.signal });
94
95
  if (!response.ok) throw new Error(`preview request failed with ${response.status}`);
@@ -104,6 +105,7 @@ export function sceneSwapFor(
104
105
  await Promise.race([swapping, expired]);
105
106
  } finally {
106
107
  clearTimeout(timer);
108
+ cancel?.removeEventListener("abort", onCancel);
107
109
  }
108
110
  iframe.dispatchEvent(new Event(SCENES_SWAPPED));
109
111
  };