@editframe/elements 0.40.1-beta.0 → 0.40.3
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/EF_FRAMEGEN.d.ts +2 -2
- package/dist/EF_FRAMEGEN.js +10 -30
- package/dist/EF_FRAMEGEN.js.map +1 -1
- package/dist/canvas/EFCanvas.d.ts +4 -4
- package/dist/canvas/EFCanvasItem.d.ts +4 -4
- package/dist/elements/EFPanZoom.d.ts +4 -4
- package/dist/elements/EFSurface.d.ts +4 -4
- package/dist/elements/EFTimegroup.d.ts +12 -8
- package/dist/elements/EFTimegroup.js +24 -17
- package/dist/elements/EFTimegroup.js.map +1 -1
- package/dist/gui/EFFocusOverlay.d.ts +4 -4
- package/dist/gui/EFOverlayLayer.d.ts +4 -4
- package/dist/gui/EFResizableBox.d.ts +4 -4
- package/dist/gui/EFTransformHandles.d.ts +4 -4
- package/dist/preview/FrameController.d.ts +11 -7
- package/dist/preview/FrameController.js +12 -39
- package/dist/preview/FrameController.js.map +1 -1
- package/package.json +3 -3
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as lit25 from "lit";
|
|
2
2
|
import { LitElement } from "lit";
|
|
3
|
-
import * as
|
|
3
|
+
import * as lit_html23 from "lit-html";
|
|
4
4
|
import * as lit_html_directives_ref_js3 from "lit-html/directives/ref.js";
|
|
5
5
|
|
|
6
6
|
//#region src/gui/EFFocusOverlay.d.ts
|
|
7
7
|
declare class EFFocusOverlay extends LitElement {
|
|
8
|
-
static styles:
|
|
8
|
+
static styles: lit25.CSSResult;
|
|
9
9
|
focusedElement?: HTMLElement | null;
|
|
10
10
|
overlay: lit_html_directives_ref_js3.Ref<HTMLDivElement>;
|
|
11
11
|
private animationFrame?;
|
|
12
12
|
drawOverlay: () => void;
|
|
13
|
-
render():
|
|
13
|
+
render(): lit_html23.TemplateResult<1>;
|
|
14
14
|
connectedCallback(): void;
|
|
15
15
|
disconnectedCallback(): void;
|
|
16
16
|
protected updated(): void;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { PanZoomTransform } from "../elements/EFPanZoom.js";
|
|
2
2
|
import { EFOverlayItem } from "./EFOverlayItem.js";
|
|
3
|
-
import * as
|
|
3
|
+
import * as lit24 from "lit";
|
|
4
4
|
import { LitElement } from "lit";
|
|
5
|
-
import * as
|
|
5
|
+
import * as lit_html22 from "lit-html";
|
|
6
6
|
|
|
7
7
|
//#region src/gui/EFOverlayLayer.d.ts
|
|
8
8
|
|
|
@@ -26,7 +26,7 @@ import * as lit_html29 from "lit-html";
|
|
|
26
26
|
* 2. EFOverlayItem can use this rect for coordinate calculations
|
|
27
27
|
*/
|
|
28
28
|
declare class EFOverlayLayer extends LitElement {
|
|
29
|
-
static styles:
|
|
29
|
+
static styles: lit24.CSSResult[];
|
|
30
30
|
panZoomTransformFromContext?: PanZoomTransform;
|
|
31
31
|
/**
|
|
32
32
|
* Pan/zoom transform as fallback for when context or sibling PanZoom is not available.
|
|
@@ -58,7 +58,7 @@ declare class EFOverlayLayer extends LitElement {
|
|
|
58
58
|
connectedCallback(): void;
|
|
59
59
|
disconnectedCallback(): void;
|
|
60
60
|
updated(): void;
|
|
61
|
-
render():
|
|
61
|
+
render(): lit_html22.TemplateResult<1>;
|
|
62
62
|
}
|
|
63
63
|
declare global {
|
|
64
64
|
interface HTMLElementTagNameMap {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as lit27 from "lit";
|
|
2
2
|
import { LitElement } from "lit";
|
|
3
|
-
import * as
|
|
3
|
+
import * as lit_html25 from "lit-html";
|
|
4
4
|
|
|
5
5
|
//#region src/gui/EFResizableBox.d.ts
|
|
6
6
|
interface BoxBounds {
|
|
@@ -21,7 +21,7 @@ declare class EFResizableBox extends LitElement {
|
|
|
21
21
|
private resizeStartCorner;
|
|
22
22
|
private resizeStartSize;
|
|
23
23
|
private resizeStartPosition;
|
|
24
|
-
static styles:
|
|
24
|
+
static styles: lit27.CSSResult;
|
|
25
25
|
private resizeObserver?;
|
|
26
26
|
connectedCallback(): void;
|
|
27
27
|
disconnectedCallback(): void;
|
|
@@ -30,7 +30,7 @@ declare class EFResizableBox extends LitElement {
|
|
|
30
30
|
private handlePointerUp;
|
|
31
31
|
private cleanup;
|
|
32
32
|
private dispatchBoundsChange;
|
|
33
|
-
render():
|
|
33
|
+
render(): lit_html25.TemplateResult<1>;
|
|
34
34
|
}
|
|
35
35
|
//#endregion
|
|
36
36
|
export { BoxBounds, EFResizableBox };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PanZoomTransform } from "../elements/EFPanZoom.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as lit26 from "lit";
|
|
3
3
|
import { LitElement } from "lit";
|
|
4
|
-
import * as
|
|
4
|
+
import * as lit_html24 from "lit-html";
|
|
5
5
|
|
|
6
6
|
//#region src/gui/EFTransformHandles.d.ts
|
|
7
7
|
interface TransformBounds {
|
|
@@ -49,7 +49,7 @@ declare class EFTransformHandles extends LitElement {
|
|
|
49
49
|
* Note: Not a @state() property to avoid re-renders during interaction.
|
|
50
50
|
*/
|
|
51
51
|
private initialBounds;
|
|
52
|
-
static styles:
|
|
52
|
+
static styles: lit26.CSSResult;
|
|
53
53
|
private resizeObserver?;
|
|
54
54
|
/**
|
|
55
55
|
* Single source of truth for zoom scale.
|
|
@@ -79,7 +79,7 @@ declare class EFTransformHandles extends LitElement {
|
|
|
79
79
|
private handleMouseMove;
|
|
80
80
|
private handleMouseUp;
|
|
81
81
|
private cleanup;
|
|
82
|
-
render():
|
|
82
|
+
render(): lit_html24.TemplateResult<1>;
|
|
83
83
|
}
|
|
84
84
|
declare global {
|
|
85
85
|
interface HTMLElementTagNameMap {
|
|
@@ -56,6 +56,16 @@ interface FrameRenderable {
|
|
|
56
56
|
*/
|
|
57
57
|
renderFrame(timeMs: number): void;
|
|
58
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Per-phase timing data returned by FrameController.renderFrame().
|
|
61
|
+
* All values are in milliseconds.
|
|
62
|
+
*/
|
|
63
|
+
interface RenderFrameTiming {
|
|
64
|
+
queryMs: number;
|
|
65
|
+
prepareMs: number;
|
|
66
|
+
renderMs: number;
|
|
67
|
+
animsMs: number;
|
|
68
|
+
}
|
|
59
69
|
/**
|
|
60
70
|
* Options for FrameController.renderFrame()
|
|
61
71
|
*/
|
|
@@ -72,12 +82,6 @@ interface RenderFrameOptions {
|
|
|
72
82
|
*/
|
|
73
83
|
onAnimationsUpdate?: (rootElement: Element) => void;
|
|
74
84
|
}
|
|
75
|
-
interface RenderFrameTiming {
|
|
76
|
-
queryMs: number;
|
|
77
|
-
prepareMs: number;
|
|
78
|
-
renderMs: number;
|
|
79
|
-
animsMs: number;
|
|
80
|
-
}
|
|
81
85
|
/**
|
|
82
86
|
* Central controller for frame rendering.
|
|
83
87
|
* Lives at the root timegroup and orchestrates all element rendering.
|
|
@@ -103,7 +107,7 @@ declare class FrameController {
|
|
|
103
107
|
* @param timeMs - The time in milliseconds to render
|
|
104
108
|
* @param options - Optional configuration
|
|
105
109
|
*/
|
|
106
|
-
renderFrame(timeMs: number, options?: RenderFrameOptions): Promise<RenderFrameTiming>;
|
|
110
|
+
renderFrame(timeMs: number, options?: RenderFrameOptions): Promise<RenderFrameTiming | null>;
|
|
107
111
|
/**
|
|
108
112
|
* Check if a render is currently in progress.
|
|
109
113
|
*/
|
|
@@ -44,11 +44,6 @@ var FrameController = class {
|
|
|
44
44
|
#abortController = null;
|
|
45
45
|
#renderInProgress = false;
|
|
46
46
|
#pendingRenderTime = null;
|
|
47
|
-
#frameCount = 0;
|
|
48
|
-
#totalQueryMs = 0;
|
|
49
|
-
#totalPrepareMs = 0;
|
|
50
|
-
#totalRenderMs = 0;
|
|
51
|
-
#totalAnimsMs = 0;
|
|
52
47
|
/**
|
|
53
48
|
* Last successfully rendered time. Used for deduplication when multiple
|
|
54
49
|
* callers (e.g., PlaybackController RAF loop and canvas render loop)
|
|
@@ -80,25 +75,15 @@ var FrameController = class {
|
|
|
80
75
|
*/
|
|
81
76
|
async renderFrame(timeMs, options = {}) {
|
|
82
77
|
const { waitForLitUpdate = true, onAnimationsUpdate } = options;
|
|
83
|
-
|
|
84
|
-
queryMs: 0,
|
|
85
|
-
prepareMs: 0,
|
|
86
|
-
renderMs: 0,
|
|
87
|
-
animsMs: 0
|
|
88
|
-
};
|
|
89
|
-
if (timeMs === this.#lastRenderedTimeMs) return zero;
|
|
78
|
+
if (timeMs === this.#lastRenderedTimeMs) return null;
|
|
90
79
|
if (this.#renderInProgress) {
|
|
91
80
|
this.#pendingRenderTime = timeMs;
|
|
92
|
-
return
|
|
81
|
+
return null;
|
|
93
82
|
}
|
|
94
83
|
this.#abortController?.abort();
|
|
95
84
|
this.#abortController = new AbortController();
|
|
96
85
|
const signal = this.#abortController.signal;
|
|
97
86
|
this.#renderInProgress = true;
|
|
98
|
-
let queryMs = 0;
|
|
99
|
-
let prepareMs = 0;
|
|
100
|
-
let renderMs = 0;
|
|
101
|
-
let animsMs = 0;
|
|
102
87
|
try {
|
|
103
88
|
if (waitForLitUpdate) {
|
|
104
89
|
await this.#rootElement.updateComplete;
|
|
@@ -106,7 +91,7 @@ var FrameController = class {
|
|
|
106
91
|
}
|
|
107
92
|
const tQuery = performance.now();
|
|
108
93
|
const elements = this.#queryVisibleElements(timeMs);
|
|
109
|
-
queryMs = performance.now() - tQuery;
|
|
94
|
+
const queryMs = performance.now() - tQuery;
|
|
110
95
|
signal.throwIfAborted();
|
|
111
96
|
const tPrepare = performance.now();
|
|
112
97
|
const elementsNeedingPreparation = elements.filter((el) => el.getFrameState(timeMs).needsPreparation);
|
|
@@ -114,30 +99,24 @@ var FrameController = class {
|
|
|
114
99
|
await Promise.all(elementsNeedingPreparation.map((el) => el.prepareFrame(timeMs, signal)));
|
|
115
100
|
signal.throwIfAborted();
|
|
116
101
|
}
|
|
117
|
-
prepareMs = performance.now() - tPrepare;
|
|
102
|
+
const prepareMs = performance.now() - tPrepare;
|
|
118
103
|
const tRender = performance.now();
|
|
119
104
|
const sortedElements = [...elements].sort((a, b) => a.getFrameState(timeMs).priority - b.getFrameState(timeMs).priority);
|
|
120
105
|
for (const element of sortedElements) {
|
|
121
106
|
signal.throwIfAborted();
|
|
122
107
|
element.renderFrame(timeMs);
|
|
123
108
|
}
|
|
124
|
-
renderMs = performance.now() - tRender;
|
|
109
|
+
const renderMs = performance.now() - tRender;
|
|
125
110
|
const tAnims = performance.now();
|
|
126
111
|
if (onAnimationsUpdate) onAnimationsUpdate(this.#rootElement);
|
|
127
|
-
animsMs = performance.now() - tAnims;
|
|
128
|
-
this.#frameCount++;
|
|
129
|
-
this.#totalQueryMs += queryMs;
|
|
130
|
-
this.#totalPrepareMs += prepareMs;
|
|
131
|
-
this.#totalRenderMs += renderMs;
|
|
132
|
-
this.#totalAnimsMs += animsMs;
|
|
133
|
-
if (this.#frameCount % 60 === 0) {
|
|
134
|
-
this.#frameCount = 0;
|
|
135
|
-
this.#totalQueryMs = 0;
|
|
136
|
-
this.#totalPrepareMs = 0;
|
|
137
|
-
this.#totalRenderMs = 0;
|
|
138
|
-
this.#totalAnimsMs = 0;
|
|
139
|
-
}
|
|
112
|
+
const animsMs = performance.now() - tAnims;
|
|
140
113
|
this.#lastRenderedTimeMs = timeMs;
|
|
114
|
+
return {
|
|
115
|
+
queryMs,
|
|
116
|
+
prepareMs,
|
|
117
|
+
renderMs,
|
|
118
|
+
animsMs
|
|
119
|
+
};
|
|
141
120
|
} finally {
|
|
142
121
|
this.#renderInProgress = false;
|
|
143
122
|
if (this.#pendingRenderTime !== null) {
|
|
@@ -146,12 +125,6 @@ var FrameController = class {
|
|
|
146
125
|
this.renderFrame(pendingTime, options).catch(() => {});
|
|
147
126
|
}
|
|
148
127
|
}
|
|
149
|
-
return {
|
|
150
|
-
queryMs,
|
|
151
|
-
prepareMs,
|
|
152
|
-
renderMs,
|
|
153
|
-
animsMs
|
|
154
|
-
};
|
|
155
128
|
}
|
|
156
129
|
/**
|
|
157
130
|
* Query all visible FrameRenderable elements in the tree.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FrameController.js","names":["#rootElement","#abortController","#lastRenderedTimeMs","zero: RenderFrameTiming","#renderInProgress","#pendingRenderTime","#queryVisibleElements","#frameCount","#totalQueryMs","#totalPrepareMs","#totalRenderMs","#totalAnimsMs","result: FrameRenderable[]","#getChildrenIncludingSlotted","assignedElements: Element[]"],"sources":["../../src/preview/FrameController.ts"],"sourcesContent":["/**\n * FrameController: Centralized frame rendering control\n *\n * Replaces the distributed Lit Task hierarchy with a single control loop\n * that queries elements and coordinates rendering directly.\n *\n * Benefits over the previous Task-based system:\n * - Single abort controller instead of distributed abort handling\n * - Clear prepare → render phases\n * - All coordination visible in one place\n * - No Lit Task reactivity overhead\n */\n\nimport type { LitElement } from \"lit\";\n\n// ============================================================================\n// Priority Constants\n// ============================================================================\n// Lower numbers render first. Elements with dependencies should have higher\n// priority numbers than their dependencies.\n//\n// Example: Waveform depends on audio analysis data, so it renders after audio.\n// ============================================================================\n\n/**\n * Priority for video elements.\n * Video renders first as other elements may depend on video frames being ready.\n */\nexport const PRIORITY_VIDEO = 1;\n\n/**\n * Priority for captions elements.\n * Captions render after video so they can overlay correctly.\n */\nexport const PRIORITY_CAPTIONS = 2;\n\n/**\n * Priority for audio elements.\n * Audio renders after captions (no visual dependency, but keeps consistent ordering).\n */\nexport const PRIORITY_AUDIO = 3;\n\n/**\n * Priority for waveform elements.\n * Waveform renders after audio because it depends on audio analysis data.\n */\nexport const PRIORITY_WAVEFORM = 4;\n\n/**\n * Priority for image elements.\n * Images render with low priority as they're typically static.\n */\nexport const PRIORITY_IMAGE = 5;\n\n/**\n * Default priority for elements that don't specify one.\n * High number ensures custom elements render after standard elements.\n */\nexport const PRIORITY_DEFAULT = 100;\n\n/**\n * State returned by elements describing their readiness for a given time.\n */\nexport interface FrameState {\n /**\n * Whether async preparation is needed before rendering.\n * Examples: video needs to seek, captions need to load data.\n */\n needsPreparation: boolean;\n\n /**\n * Whether the element is ready to render synchronously.\n * True when all async work is complete and renderFrame() can be called.\n */\n isReady: boolean;\n\n /**\n * Rendering priority hint. Lower numbers render first.\n * Used to order render calls for elements with dependencies.\n *\n * Standard priorities:\n * - PRIORITY_VIDEO (1): Video elements\n * - PRIORITY_CAPTIONS (2): Caption overlays\n * - PRIORITY_AUDIO (3): Audio elements\n * - PRIORITY_WAVEFORM (4): Audio visualizers (depend on audio)\n * - PRIORITY_IMAGE (5): Static images\n * - PRIORITY_DEFAULT (100): Fallback for custom elements\n */\n priority: number;\n}\n\n/**\n * Interface that elements implement to participate in centralized frame rendering.\n * Elements keep their rendering logic local but expose a standardized interface.\n */\nexport interface FrameRenderable {\n /**\n * Query the element's readiness state for a given time.\n * Must be synchronous and cheap to call.\n */\n getFrameState(timeMs: number): FrameState;\n\n /**\n * Async preparation phase. Called when getFrameState().needsPreparation is true.\n * Performs any async work needed before rendering (seeking, loading, etc.).\n *\n * @param timeMs - The time to prepare for\n * @param signal - Abort signal for cancellation\n */\n prepareFrame(timeMs: number, signal: AbortSignal): Promise<void>;\n\n /**\n * Synchronous render phase. Called after all preparation is complete.\n * Performs the actual rendering (paint to canvas, update DOM, etc.).\n *\n * @param timeMs - The time to render\n */\n renderFrame(timeMs: number): void;\n}\n\n/**\n * Type guard to check if an element implements FrameRenderable.\n */\nexport function isFrameRenderable(\n element: unknown,\n): element is FrameRenderable {\n return (\n typeof element === \"object\" &&\n element !== null &&\n \"getFrameState\" in element &&\n \"prepareFrame\" in element &&\n \"renderFrame\" in element &&\n typeof (element as FrameRenderable).getFrameState === \"function\" &&\n typeof (element as FrameRenderable).prepareFrame === \"function\" &&\n typeof (element as FrameRenderable).renderFrame === \"function\"\n );\n}\n\n/**\n * Options for FrameController.renderFrame()\n */\nexport interface RenderFrameOptions {\n /**\n * Whether to wait for Lit updateComplete before querying elements.\n * Default: true\n */\n waitForLitUpdate?: boolean;\n\n /**\n * Callback to update CSS animations after frame rendering completes.\n * Called with the root element after all elements have rendered.\n * This centralizes animation synchronization in one place.\n */\n onAnimationsUpdate?: (rootElement: Element) => void;\n}\n\nexport interface RenderFrameTiming {\n queryMs: number;\n prepareMs: number;\n renderMs: number;\n animsMs: number;\n}\n\n/**\n * Central controller for frame rendering.\n * Lives at the root timegroup and orchestrates all element rendering.\n */\nexport class FrameController {\n #rootElement: LitElement & { currentTimeMs: number };\n #abortController: AbortController | null = null;\n #renderInProgress = false;\n #pendingRenderTime: number | null = null;\n #frameCount = 0;\n #totalQueryMs = 0;\n #totalPrepareMs = 0;\n #totalRenderMs = 0;\n #totalAnimsMs = 0;\n\n /**\n * Last successfully rendered time. Used for deduplication when multiple\n * callers (e.g., PlaybackController RAF loop and canvas render loop)\n * both try to render the same frame within one animation frame.\n */\n #lastRenderedTimeMs: number = -1;\n\n constructor(rootElement: LitElement & { currentTimeMs: number }) {\n this.#rootElement = rootElement;\n }\n\n /**\n * Cancel any in-progress render operation and reset deduplication state.\n */\n abort(): void {\n this.#abortController?.abort();\n this.#abortController = null;\n // Reset deduplication state so next render goes through even if same time\n this.#lastRenderedTimeMs = -1;\n }\n\n /**\n * Render a frame at the specified time.\n *\n * This is the main entry point for frame rendering. It:\n * 1. Cancels any previous in-progress render\n * 2. Queries all visible FrameRenderable elements\n * 3. Runs preparation in parallel for elements that need it\n * 4. Runs render in priority order\n *\n * @param timeMs - The time in milliseconds to render\n * @param options - Optional configuration\n */\n async renderFrame(\n timeMs: number,\n options: RenderFrameOptions = {},\n ): Promise<RenderFrameTiming> {\n const { waitForLitUpdate = true, onAnimationsUpdate } = options;\n const zero: RenderFrameTiming = { queryMs: 0, prepareMs: 0, renderMs: 0, animsMs: 0 };\n\n // Deduplicate: skip if we just rendered this exact time.\n // This prevents double-rendering when multiple RAF loops (e.g., PlaybackController\n // and canvas render loop) both call renderFrame() for the same frame.\n if (timeMs === this.#lastRenderedTimeMs) {\n return zero;\n }\n\n // If a render is in progress, queue this one\n if (this.#renderInProgress) {\n this.#pendingRenderTime = timeMs;\n return zero;\n }\n\n // Cancel any previous render operation\n this.#abortController?.abort();\n this.#abortController = new AbortController();\n const signal = this.#abortController.signal;\n\n this.#renderInProgress = true;\n\n let queryMs = 0;\n let prepareMs = 0;\n let renderMs = 0;\n let animsMs = 0;\n\n try {\n if (waitForLitUpdate) {\n await this.#rootElement.updateComplete;\n signal.throwIfAborted();\n }\n\n const tQuery = performance.now();\n const elements = this.#queryVisibleElements(timeMs);\n queryMs = performance.now() - tQuery;\n signal.throwIfAborted();\n\n const tPrepare = performance.now();\n const elementsNeedingPreparation = elements.filter(\n (el) => el.getFrameState(timeMs).needsPreparation,\n );\n\n if (elementsNeedingPreparation.length > 0) {\n await Promise.all(\n elementsNeedingPreparation.map((el) =>\n el.prepareFrame(timeMs, signal),\n ),\n );\n signal.throwIfAborted();\n }\n prepareMs = performance.now() - tPrepare;\n\n const tRender = performance.now();\n const sortedElements = [...elements].sort(\n (a, b) =>\n a.getFrameState(timeMs).priority - b.getFrameState(timeMs).priority,\n );\n\n for (const element of sortedElements) {\n signal.throwIfAborted();\n element.renderFrame(timeMs);\n }\n renderMs = performance.now() - tRender;\n\n const tAnims = performance.now();\n if (onAnimationsUpdate) {\n onAnimationsUpdate(this.#rootElement);\n }\n animsMs = performance.now() - tAnims;\n\n this.#frameCount++;\n this.#totalQueryMs += queryMs;\n this.#totalPrepareMs += prepareMs;\n this.#totalRenderMs += renderMs;\n this.#totalAnimsMs += animsMs;\n\n if (this.#frameCount % 60 === 0) {\n this.#frameCount = 0;\n this.#totalQueryMs = 0;\n this.#totalPrepareMs = 0;\n this.#totalRenderMs = 0;\n this.#totalAnimsMs = 0;\n }\n\n this.#lastRenderedTimeMs = timeMs;\n } finally {\n this.#renderInProgress = false;\n\n // Process any queued render\n if (this.#pendingRenderTime !== null) {\n const pendingTime = this.#pendingRenderTime;\n this.#pendingRenderTime = null;\n // Don't await - fire and forget to avoid recursive waiting\n this.renderFrame(pendingTime, options).catch(() => {\n // Silently ignore errors from queued renders (likely aborted)\n });\n }\n }\n\n return { queryMs, prepareMs, renderMs, animsMs };\n }\n\n /**\n * Query all visible FrameRenderable elements in the tree.\n * Uses temporal visibility to filter out elements not visible at current time.\n *\n * IMPORTANT: For temporal elements, we use temporal visibility (startTimeMs/endTimeMs)\n * instead of CSS visibility. This is because updateAnimations sets display:none on\n * elements outside their time range, but that CSS state is from the PREVIOUS frame.\n * When seeking, we need to evaluate visibility based on the NEW time, not stale CSS.\n *\n * @param timeMs - The time to use for visibility checks. This should be the target\n * render time, not read from root element (which may be stale).\n */\n #queryVisibleElements(timeMs: number): FrameRenderable[] {\n const result: FrameRenderable[] = [];\n const currentTimeMs = timeMs;\n\n const walk = (element: Element): void => {\n // For temporal elements (ef-timegroup, ef-video, etc.), use temporal visibility\n // instead of CSS visibility. CSS display:none may be stale from previous frame.\n const isTemporal = \"startTimeMs\" in element && \"endTimeMs\" in element;\n\n if (isTemporal) {\n // Temporal element: check time-based visibility\n // Use exclusive end (< not <=) to avoid overlap at boundaries\n const startMs =\n (element as { startTimeMs?: number }).startTimeMs ?? -Infinity;\n const endMs = (element as { endTimeMs?: number }).endTimeMs ?? Infinity;\n const isTemporallyVisible =\n currentTimeMs >= startMs && currentTimeMs < endMs;\n\n if (!isTemporallyVisible) {\n // Skip this element AND its children (children's times are relative to parent)\n return;\n }\n\n // Element is temporally visible - include if it implements FrameRenderable\n if (isFrameRenderable(element)) {\n result.push(element);\n }\n } else {\n // Non-temporal element: only check inline display style (fast path).\n // Skip getComputedStyle — it forces synchronous style recalc and is\n // unnecessary because FrameRenderable elements are always temporal.\n // We only walk non-temporal elements to reach temporal children.\n if (\n element instanceof HTMLElement &&\n element.style.display === \"none\"\n ) {\n return;\n }\n\n if (isFrameRenderable(element)) {\n result.push(element);\n }\n }\n\n // Walk children - handle both regular children and slotted content\n const children = this.#getChildrenIncludingSlotted(element);\n for (const child of children) {\n walk(child);\n }\n };\n\n walk(this.#rootElement);\n return result;\n }\n\n /**\n * Gets all child elements including slotted content for shadow DOM elements.\n * For elements with shadow DOM that contain slots, this returns the assigned\n * elements (slotted content) instead of just the shadow DOM children.\n */\n #getChildrenIncludingSlotted(element: Element): Iterable<Element> {\n // If element has shadowRoot with slots, get assigned elements\n if (element.shadowRoot) {\n const slots = element.shadowRoot.querySelectorAll(\"slot\");\n if (slots.length > 0) {\n const assignedElements: Element[] = [];\n for (const slot of slots) {\n assignedElements.push(...slot.assignedElements());\n }\n // Also include shadow DOM children that aren't slots (for mixed content)\n for (const child of element.shadowRoot.children) {\n if (child.tagName !== \"SLOT\") {\n assignedElements.push(child);\n }\n }\n return assignedElements;\n }\n }\n\n // Return HTMLCollection directly (iterable, no allocation)\n return element.children;\n }\n\n /**\n * Check if a render is currently in progress.\n */\n get isRendering(): boolean {\n return this.#renderInProgress;\n }\n}\n\n/**\n * Default frame state for elements that don't need special handling.\n * Use this for simple elements that are always ready.\n */\nexport const DEFAULT_FRAME_STATE: FrameState = {\n needsPreparation: false,\n isReady: true,\n priority: PRIORITY_DEFAULT,\n};\n\n/**\n * Helper to create a FrameRenderable mixin for elements.\n * Provides default implementations that can be overridden.\n */\nexport function createFrameRenderableMixin<\n T extends { new (...args: any[]): HTMLElement },\n>(Base: T) {\n return class FrameRenderableMixin extends Base implements FrameRenderable {\n getFrameState(_timeMs: number): FrameState {\n return DEFAULT_FRAME_STATE;\n }\n\n async prepareFrame(_timeMs: number, _signal: AbortSignal): Promise<void> {\n // Default: no preparation needed\n }\n\n renderFrame(_timeMs: number): void {\n // Default: no explicit render needed\n }\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FrameController.js","names":["#rootElement","#abortController","#lastRenderedTimeMs","#renderInProgress","#pendingRenderTime","#queryVisibleElements","result: FrameRenderable[]","#getChildrenIncludingSlotted","assignedElements: Element[]"],"sources":["../../src/preview/FrameController.ts"],"sourcesContent":["/**\n * FrameController: Centralized frame rendering control\n *\n * Replaces the distributed Lit Task hierarchy with a single control loop\n * that queries elements and coordinates rendering directly.\n *\n * Benefits over the previous Task-based system:\n * - Single abort controller instead of distributed abort handling\n * - Clear prepare → render phases\n * - All coordination visible in one place\n * - No Lit Task reactivity overhead\n */\n\nimport type { LitElement } from \"lit\";\n\n// ============================================================================\n// Priority Constants\n// ============================================================================\n// Lower numbers render first. Elements with dependencies should have higher\n// priority numbers than their dependencies.\n//\n// Example: Waveform depends on audio analysis data, so it renders after audio.\n// ============================================================================\n\n/**\n * Priority for video elements.\n * Video renders first as other elements may depend on video frames being ready.\n */\nexport const PRIORITY_VIDEO = 1;\n\n/**\n * Priority for captions elements.\n * Captions render after video so they can overlay correctly.\n */\nexport const PRIORITY_CAPTIONS = 2;\n\n/**\n * Priority for audio elements.\n * Audio renders after captions (no visual dependency, but keeps consistent ordering).\n */\nexport const PRIORITY_AUDIO = 3;\n\n/**\n * Priority for waveform elements.\n * Waveform renders after audio because it depends on audio analysis data.\n */\nexport const PRIORITY_WAVEFORM = 4;\n\n/**\n * Priority for image elements.\n * Images render with low priority as they're typically static.\n */\nexport const PRIORITY_IMAGE = 5;\n\n/**\n * Default priority for elements that don't specify one.\n * High number ensures custom elements render after standard elements.\n */\nexport const PRIORITY_DEFAULT = 100;\n\n/**\n * State returned by elements describing their readiness for a given time.\n */\nexport interface FrameState {\n /**\n * Whether async preparation is needed before rendering.\n * Examples: video needs to seek, captions need to load data.\n */\n needsPreparation: boolean;\n\n /**\n * Whether the element is ready to render synchronously.\n * True when all async work is complete and renderFrame() can be called.\n */\n isReady: boolean;\n\n /**\n * Rendering priority hint. Lower numbers render first.\n * Used to order render calls for elements with dependencies.\n *\n * Standard priorities:\n * - PRIORITY_VIDEO (1): Video elements\n * - PRIORITY_CAPTIONS (2): Caption overlays\n * - PRIORITY_AUDIO (3): Audio elements\n * - PRIORITY_WAVEFORM (4): Audio visualizers (depend on audio)\n * - PRIORITY_IMAGE (5): Static images\n * - PRIORITY_DEFAULT (100): Fallback for custom elements\n */\n priority: number;\n}\n\n/**\n * Interface that elements implement to participate in centralized frame rendering.\n * Elements keep their rendering logic local but expose a standardized interface.\n */\nexport interface FrameRenderable {\n /**\n * Query the element's readiness state for a given time.\n * Must be synchronous and cheap to call.\n */\n getFrameState(timeMs: number): FrameState;\n\n /**\n * Async preparation phase. Called when getFrameState().needsPreparation is true.\n * Performs any async work needed before rendering (seeking, loading, etc.).\n *\n * @param timeMs - The time to prepare for\n * @param signal - Abort signal for cancellation\n */\n prepareFrame(timeMs: number, signal: AbortSignal): Promise<void>;\n\n /**\n * Synchronous render phase. Called after all preparation is complete.\n * Performs the actual rendering (paint to canvas, update DOM, etc.).\n *\n * @param timeMs - The time to render\n */\n renderFrame(timeMs: number): void;\n}\n\n/**\n * Type guard to check if an element implements FrameRenderable.\n */\nexport function isFrameRenderable(\n element: unknown,\n): element is FrameRenderable {\n return (\n typeof element === \"object\" &&\n element !== null &&\n \"getFrameState\" in element &&\n \"prepareFrame\" in element &&\n \"renderFrame\" in element &&\n typeof (element as FrameRenderable).getFrameState === \"function\" &&\n typeof (element as FrameRenderable).prepareFrame === \"function\" &&\n typeof (element as FrameRenderable).renderFrame === \"function\"\n );\n}\n\n/**\n * Per-phase timing data returned by FrameController.renderFrame().\n * All values are in milliseconds.\n */\nexport interface RenderFrameTiming {\n queryMs: number;\n prepareMs: number;\n renderMs: number;\n animsMs: number;\n}\n\n/**\n * Options for FrameController.renderFrame()\n */\nexport interface RenderFrameOptions {\n /**\n * Whether to wait for Lit updateComplete before querying elements.\n * Default: true\n */\n waitForLitUpdate?: boolean;\n\n /**\n * Callback to update CSS animations after frame rendering completes.\n * Called with the root element after all elements have rendered.\n * This centralizes animation synchronization in one place.\n */\n onAnimationsUpdate?: (rootElement: Element) => void;\n}\n\n/**\n * Central controller for frame rendering.\n * Lives at the root timegroup and orchestrates all element rendering.\n */\nexport class FrameController {\n #rootElement: LitElement & { currentTimeMs: number };\n #abortController: AbortController | null = null;\n #renderInProgress = false;\n #pendingRenderTime: number | null = null;\n /**\n * Last successfully rendered time. Used for deduplication when multiple\n * callers (e.g., PlaybackController RAF loop and canvas render loop)\n * both try to render the same frame within one animation frame.\n */\n #lastRenderedTimeMs: number = -1;\n\n constructor(rootElement: LitElement & { currentTimeMs: number }) {\n this.#rootElement = rootElement;\n }\n\n /**\n * Cancel any in-progress render operation and reset deduplication state.\n */\n abort(): void {\n this.#abortController?.abort();\n this.#abortController = null;\n // Reset deduplication state so next render goes through even if same time\n this.#lastRenderedTimeMs = -1;\n }\n\n /**\n * Render a frame at the specified time.\n *\n * This is the main entry point for frame rendering. It:\n * 1. Cancels any previous in-progress render\n * 2. Queries all visible FrameRenderable elements\n * 3. Runs preparation in parallel for elements that need it\n * 4. Runs render in priority order\n *\n * @param timeMs - The time in milliseconds to render\n * @param options - Optional configuration\n */\n async renderFrame(\n timeMs: number,\n options: RenderFrameOptions = {},\n ): Promise<RenderFrameTiming | null> {\n const { waitForLitUpdate = true, onAnimationsUpdate } = options;\n\n // Deduplicate: skip if we just rendered this exact time.\n // This prevents double-rendering when multiple RAF loops (e.g., PlaybackController\n // and canvas render loop) both call renderFrame() for the same frame.\n if (timeMs === this.#lastRenderedTimeMs) {\n return null;\n }\n\n // If a render is in progress, queue this one\n if (this.#renderInProgress) {\n this.#pendingRenderTime = timeMs;\n return null;\n }\n\n // Cancel any previous render operation\n this.#abortController?.abort();\n this.#abortController = new AbortController();\n const signal = this.#abortController.signal;\n\n this.#renderInProgress = true;\n\n try {\n if (waitForLitUpdate) {\n await this.#rootElement.updateComplete;\n signal.throwIfAborted();\n }\n\n const tQuery = performance.now();\n const elements = this.#queryVisibleElements(timeMs);\n const queryMs = performance.now() - tQuery;\n signal.throwIfAborted();\n\n const tPrepare = performance.now();\n const elementsNeedingPreparation = elements.filter(\n (el) => el.getFrameState(timeMs).needsPreparation,\n );\n\n if (elementsNeedingPreparation.length > 0) {\n await Promise.all(\n elementsNeedingPreparation.map((el) =>\n el.prepareFrame(timeMs, signal),\n ),\n );\n signal.throwIfAborted();\n }\n const prepareMs = performance.now() - tPrepare;\n\n const tRender = performance.now();\n const sortedElements = [...elements].sort(\n (a, b) =>\n a.getFrameState(timeMs).priority - b.getFrameState(timeMs).priority,\n );\n\n for (const element of sortedElements) {\n signal.throwIfAborted();\n element.renderFrame(timeMs);\n }\n const renderMs = performance.now() - tRender;\n\n const tAnims = performance.now();\n if (onAnimationsUpdate) {\n onAnimationsUpdate(this.#rootElement);\n }\n const animsMs = performance.now() - tAnims;\n\n this.#lastRenderedTimeMs = timeMs;\n return { queryMs, prepareMs, renderMs, animsMs };\n } finally {\n this.#renderInProgress = false;\n\n // Process any queued render\n if (this.#pendingRenderTime !== null) {\n const pendingTime = this.#pendingRenderTime;\n this.#pendingRenderTime = null;\n // Don't await - fire and forget to avoid recursive waiting\n this.renderFrame(pendingTime, options).catch(() => {\n // Silently ignore errors from queued renders (likely aborted)\n });\n }\n }\n }\n\n /**\n * Query all visible FrameRenderable elements in the tree.\n * Uses temporal visibility to filter out elements not visible at current time.\n *\n * IMPORTANT: For temporal elements, we use temporal visibility (startTimeMs/endTimeMs)\n * instead of CSS visibility. This is because updateAnimations sets display:none on\n * elements outside their time range, but that CSS state is from the PREVIOUS frame.\n * When seeking, we need to evaluate visibility based on the NEW time, not stale CSS.\n *\n * @param timeMs - The time to use for visibility checks. This should be the target\n * render time, not read from root element (which may be stale).\n */\n #queryVisibleElements(timeMs: number): FrameRenderable[] {\n const result: FrameRenderable[] = [];\n const currentTimeMs = timeMs;\n\n const walk = (element: Element): void => {\n // For temporal elements (ef-timegroup, ef-video, etc.), use temporal visibility\n // instead of CSS visibility. CSS display:none may be stale from previous frame.\n const isTemporal = \"startTimeMs\" in element && \"endTimeMs\" in element;\n\n if (isTemporal) {\n // Temporal element: check time-based visibility\n // Use exclusive end (< not <=) to avoid overlap at boundaries\n const startMs =\n (element as { startTimeMs?: number }).startTimeMs ?? -Infinity;\n const endMs = (element as { endTimeMs?: number }).endTimeMs ?? Infinity;\n const isTemporallyVisible =\n currentTimeMs >= startMs && currentTimeMs < endMs;\n\n if (!isTemporallyVisible) {\n // Skip this element AND its children (children's times are relative to parent)\n return;\n }\n\n // Element is temporally visible - include if it implements FrameRenderable\n if (isFrameRenderable(element)) {\n result.push(element);\n }\n } else {\n // Non-temporal element: only check inline display style (fast path).\n // Skip getComputedStyle — it forces synchronous style recalc and is\n // unnecessary because FrameRenderable elements are always temporal.\n // We only walk non-temporal elements to reach temporal children.\n if (\n element instanceof HTMLElement &&\n element.style.display === \"none\"\n ) {\n return;\n }\n\n if (isFrameRenderable(element)) {\n result.push(element);\n }\n }\n\n // Walk children - handle both regular children and slotted content\n const children = this.#getChildrenIncludingSlotted(element);\n for (const child of children) {\n walk(child);\n }\n };\n\n walk(this.#rootElement);\n return result;\n }\n\n /**\n * Gets all child elements including slotted content for shadow DOM elements.\n * For elements with shadow DOM that contain slots, this returns the assigned\n * elements (slotted content) instead of just the shadow DOM children.\n */\n #getChildrenIncludingSlotted(element: Element): Iterable<Element> {\n // If element has shadowRoot with slots, get assigned elements\n if (element.shadowRoot) {\n const slots = element.shadowRoot.querySelectorAll(\"slot\");\n if (slots.length > 0) {\n const assignedElements: Element[] = [];\n for (const slot of slots) {\n assignedElements.push(...slot.assignedElements());\n }\n // Also include shadow DOM children that aren't slots (for mixed content)\n for (const child of element.shadowRoot.children) {\n if (child.tagName !== \"SLOT\") {\n assignedElements.push(child);\n }\n }\n return assignedElements;\n }\n }\n\n // Return HTMLCollection directly (iterable, no allocation)\n return element.children;\n }\n\n /**\n * Check if a render is currently in progress.\n */\n get isRendering(): boolean {\n return this.#renderInProgress;\n }\n}\n\n/**\n * Default frame state for elements that don't need special handling.\n * Use this for simple elements that are always ready.\n */\nexport const DEFAULT_FRAME_STATE: FrameState = {\n needsPreparation: false,\n isReady: true,\n priority: PRIORITY_DEFAULT,\n};\n\n/**\n * Helper to create a FrameRenderable mixin for elements.\n * Provides default implementations that can be overridden.\n */\nexport function createFrameRenderableMixin<\n T extends { new (...args: any[]): HTMLElement },\n>(Base: T) {\n return class FrameRenderableMixin extends Base implements FrameRenderable {\n getFrameState(_timeMs: number): FrameState {\n return DEFAULT_FRAME_STATE;\n }\n\n async prepareFrame(_timeMs: number, _signal: AbortSignal): Promise<void> {\n // Default: no preparation needed\n }\n\n renderFrame(_timeMs: number): void {\n // Default: no explicit render needed\n }\n };\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@editframe/elements",
|
|
3
|
-
"version": "0.40.
|
|
3
|
+
"version": "0.40.3",
|
|
4
4
|
"description": "",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"license": "UNLICENSED",
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@bramus/style-observer": "^1.3.0",
|
|
21
|
-
"@editframe/assets": "0.40.
|
|
21
|
+
"@editframe/assets": "0.40.3",
|
|
22
22
|
"@lit/context": "^1.1.6",
|
|
23
23
|
"@opentelemetry/api": "^1.9.0",
|
|
24
24
|
"@opentelemetry/context-zone": "^1.26.0",
|
|
@@ -111,4 +111,4 @@
|
|
|
111
111
|
},
|
|
112
112
|
"main": "./dist/index.js",
|
|
113
113
|
"module": "./dist/index.js"
|
|
114
|
-
}
|
|
114
|
+
}
|