@hyperframes/studio 0.7.85 → 0.7.86
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.
- package/dist/assets/{hyperframes-player-CXVkvR6C.js → hyperframes-player-BL3qfGEQ.js} +1 -1
- package/dist/assets/{index-CVcz5MoC.js → index-B5QGai9B.js} +1 -1
- package/dist/assets/{index-BZFIup06.js → index-C0Vr8jjc.js} +1 -1
- package/dist/assets/{index-DloBOPGY.js → index-CISVI7UC.js} +3 -3
- package/dist/index.html +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/src/player/components/useTimelinePerformanceTelemetry.test.ts +68 -2
- package/src/player/components/useTimelinePerformanceTelemetry.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyperframes/studio",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.86",
|
|
4
4
|
"description": "",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -46,11 +46,11 @@
|
|
|
46
46
|
"gsap": "^3.13.0",
|
|
47
47
|
"marked": "^14.1.4",
|
|
48
48
|
"mediabunny": "^1.45.3",
|
|
49
|
-
"@hyperframes/core": "0.7.
|
|
50
|
-
"@hyperframes/
|
|
51
|
-
"@hyperframes/player": "0.7.
|
|
52
|
-
"@hyperframes/
|
|
53
|
-
"@hyperframes/studio-server": "0.7.
|
|
49
|
+
"@hyperframes/core": "0.7.86",
|
|
50
|
+
"@hyperframes/parsers": "0.7.86",
|
|
51
|
+
"@hyperframes/player": "0.7.86",
|
|
52
|
+
"@hyperframes/sdk": "0.7.86",
|
|
53
|
+
"@hyperframes/studio-server": "0.7.86"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@types/react": "19",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"vite": "^6.4.2",
|
|
66
66
|
"vitest": "^3.2.4",
|
|
67
67
|
"zustand": "^5.0.0",
|
|
68
|
-
"@hyperframes/producer": "0.7.
|
|
68
|
+
"@hyperframes/producer": "0.7.86"
|
|
69
69
|
},
|
|
70
70
|
"peerDependencies": {
|
|
71
71
|
"react": "19",
|
|
@@ -1,7 +1,28 @@
|
|
|
1
1
|
// @vitest-environment happy-dom
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { act, createElement } from "react";
|
|
4
|
+
import { createRoot } from "react-dom/client";
|
|
5
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
6
|
+
|
|
7
|
+
const trackStudioTimelinePerformance = vi.hoisted(() => vi.fn());
|
|
8
|
+
|
|
9
|
+
vi.mock("../../telemetry/events", () => ({
|
|
10
|
+
trackStudioTimelinePerformance,
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
summarizeTimelinePerformance,
|
|
15
|
+
useTimelinePerformanceTelemetry,
|
|
16
|
+
} from "./useTimelinePerformanceTelemetry";
|
|
17
|
+
|
|
18
|
+
Reflect.set(globalThis, "IS_REACT_ACT_ENVIRONMENT", true);
|
|
19
|
+
|
|
20
|
+
afterEach(() => {
|
|
21
|
+
trackStudioTimelinePerformance.mockReset();
|
|
22
|
+
vi.useRealTimers();
|
|
23
|
+
vi.restoreAllMocks();
|
|
24
|
+
vi.unstubAllGlobals();
|
|
25
|
+
});
|
|
5
26
|
|
|
6
27
|
describe("summarizeTimelinePerformance", () => {
|
|
7
28
|
it("reports raw mounted work and p95 scroll timings", () => {
|
|
@@ -52,3 +73,48 @@ describe("summarizeTimelinePerformance", () => {
|
|
|
52
73
|
).toBeNull();
|
|
53
74
|
});
|
|
54
75
|
});
|
|
76
|
+
|
|
77
|
+
describe("useTimelinePerformanceTelemetry", () => {
|
|
78
|
+
it("measures callback delivery when the animation-frame timestamp predates the scroll", () => {
|
|
79
|
+
vi.useFakeTimers();
|
|
80
|
+
let frameCallback: FrameRequestCallback | undefined;
|
|
81
|
+
vi.stubGlobal("requestAnimationFrame", (callback: FrameRequestCallback) => {
|
|
82
|
+
frameCallback = callback;
|
|
83
|
+
return 1;
|
|
84
|
+
});
|
|
85
|
+
vi.stubGlobal("cancelAnimationFrame", vi.fn());
|
|
86
|
+
|
|
87
|
+
let recordTimelineScroll: ((scroll: HTMLDivElement) => void) | undefined;
|
|
88
|
+
function Probe() {
|
|
89
|
+
recordTimelineScroll = useTimelinePerformanceTelemetry({
|
|
90
|
+
totalClipCount: 1,
|
|
91
|
+
totalRowCount: 1,
|
|
92
|
+
zoomMode: "manual",
|
|
93
|
+
}).recordTimelineScroll;
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const root = createRoot(document.createElement("div"));
|
|
98
|
+
act(() => root.render(createElement(Probe)));
|
|
99
|
+
|
|
100
|
+
try {
|
|
101
|
+
vi.spyOn(performance, "now")
|
|
102
|
+
.mockReturnValueOnce(100)
|
|
103
|
+
.mockReturnValueOnce(108)
|
|
104
|
+
.mockReturnValueOnce(500);
|
|
105
|
+
|
|
106
|
+
recordTimelineScroll?.(document.createElement("div"));
|
|
107
|
+
frameCallback?.(99);
|
|
108
|
+
vi.advanceTimersByTime(400);
|
|
109
|
+
|
|
110
|
+
expect(trackStudioTimelinePerformance).toHaveBeenCalledWith(
|
|
111
|
+
expect.objectContaining({
|
|
112
|
+
scroll_frame_latency_p95_ms: 8,
|
|
113
|
+
scroll_frame_latency_max_ms: 8,
|
|
114
|
+
}),
|
|
115
|
+
);
|
|
116
|
+
} finally {
|
|
117
|
+
act(() => root.unmount());
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
});
|
|
@@ -87,7 +87,7 @@ export function useTimelinePerformanceTelemetry(context: TimelinePerformanceCont
|
|
|
87
87
|
state.pendingScrollStartedAt = now;
|
|
88
88
|
state.frameRequest = requestAnimationFrame((frameAt) => {
|
|
89
89
|
state.frameRequest = 0;
|
|
90
|
-
state.frameLatencies.push(
|
|
90
|
+
state.frameLatencies.push(performance.now() - state.pendingScrollStartedAt);
|
|
91
91
|
if (state.previousFrameAt !== null) {
|
|
92
92
|
state.frameIntervals.push(frameAt - state.previousFrameAt);
|
|
93
93
|
}
|