@editframe/elements 0.33.0-beta → 0.34.5-beta

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.
Files changed (251) hide show
  1. package/dist/EF_FRAMEGEN.js +5 -3
  2. package/dist/EF_FRAMEGEN.js.map +1 -1
  3. package/dist/_virtual/{_@oxc-project_runtime@0.94.0 → _@oxc-project_runtime@0.95.0}/helpers/decorate.js +1 -1
  4. package/dist/canvas/EFCanvas.d.ts +7 -4
  5. package/dist/canvas/EFCanvas.js +1 -1
  6. package/dist/canvas/EFCanvasItem.d.ts +4 -4
  7. package/dist/canvas/EFCanvasItem.js +1 -1
  8. package/dist/canvas/overlays/SelectionOverlay.d.ts +95 -0
  9. package/dist/canvas/overlays/SelectionOverlay.js +1 -1
  10. package/dist/canvas/selection/SelectionController.js +7 -11
  11. package/dist/canvas/selection/SelectionController.js.map +1 -1
  12. package/dist/elements/EFAudio.d.ts +25 -7
  13. package/dist/elements/EFAudio.js +31 -61
  14. package/dist/elements/EFAudio.js.map +1 -1
  15. package/dist/elements/EFCaptions.d.ts +65 -52
  16. package/dist/elements/EFCaptions.js +186 -400
  17. package/dist/elements/EFCaptions.js.map +1 -1
  18. package/dist/elements/EFImage.d.ts +34 -6
  19. package/dist/elements/EFImage.js +114 -79
  20. package/dist/elements/EFImage.js.map +1 -1
  21. package/dist/elements/EFMedia/AssetIdMediaEngine.js +17 -17
  22. package/dist/elements/EFMedia/AssetIdMediaEngine.js.map +1 -1
  23. package/dist/elements/EFMedia/AssetMediaEngine.js +41 -25
  24. package/dist/elements/EFMedia/AssetMediaEngine.js.map +1 -1
  25. package/dist/elements/EFMedia/BaseMediaEngine.js +4 -4
  26. package/dist/elements/EFMedia/BaseMediaEngine.js.map +1 -1
  27. package/dist/elements/EFMedia/BufferedSeekingInput.js +1 -1
  28. package/dist/elements/EFMedia/BufferedSeekingInput.js.map +1 -1
  29. package/dist/elements/EFMedia/JitMediaEngine.js +31 -17
  30. package/dist/elements/EFMedia/JitMediaEngine.js.map +1 -1
  31. package/dist/elements/EFMedia/shared/AudioSpanUtils.js +3 -3
  32. package/dist/elements/EFMedia/shared/AudioSpanUtils.js.map +1 -1
  33. package/dist/elements/EFMedia/videoTasks/ScrubInputCache.js +17 -9
  34. package/dist/elements/EFMedia/videoTasks/ScrubInputCache.js.map +1 -1
  35. package/dist/elements/EFMedia.d.ts +66 -20
  36. package/dist/elements/EFMedia.js +412 -30
  37. package/dist/elements/EFMedia.js.map +1 -1
  38. package/dist/elements/EFPanZoom.d.ts +4 -4
  39. package/dist/elements/EFPanZoom.js +1 -1
  40. package/dist/elements/EFSourceMixin.js +43 -15
  41. package/dist/elements/EFSourceMixin.js.map +1 -1
  42. package/dist/elements/EFSurface.d.ts +23 -10
  43. package/dist/elements/EFSurface.js +64 -22
  44. package/dist/elements/EFSurface.js.map +1 -1
  45. package/dist/elements/EFTemporal.d.ts +8 -2
  46. package/dist/elements/EFTemporal.js +42 -31
  47. package/dist/elements/EFTemporal.js.map +1 -1
  48. package/dist/elements/EFText.d.ts +5 -4
  49. package/dist/elements/EFText.js +11 -2
  50. package/dist/elements/EFText.js.map +1 -1
  51. package/dist/elements/EFTextSegment.d.ts +4 -4
  52. package/dist/elements/EFTextSegment.js +1 -1
  53. package/dist/elements/EFThumbnailStrip.d.ts +4 -4
  54. package/dist/elements/EFThumbnailStrip.js +1 -1
  55. package/dist/elements/EFTimegroup.d.ts +22 -8
  56. package/dist/elements/EFTimegroup.js +203 -115
  57. package/dist/elements/EFTimegroup.js.map +1 -1
  58. package/dist/elements/EFVideo.d.ts +57 -20
  59. package/dist/elements/EFVideo.js +324 -72
  60. package/dist/elements/EFVideo.js.map +1 -1
  61. package/dist/elements/EFWaveform.d.ts +33 -7
  62. package/dist/elements/EFWaveform.js +103 -59
  63. package/dist/elements/EFWaveform.js.map +1 -1
  64. package/dist/elements/renderTemporalAudio.js +14 -3
  65. package/dist/elements/renderTemporalAudio.js.map +1 -1
  66. package/dist/getRenderInfo.d.ts +2 -2
  67. package/dist/gui/ContextMixin.js +1 -1
  68. package/dist/gui/Controllable.d.ts +2 -0
  69. package/dist/gui/EFActiveRootTemporal.d.ts +4 -4
  70. package/dist/gui/EFActiveRootTemporal.js +1 -1
  71. package/dist/gui/EFConfiguration.d.ts +4 -4
  72. package/dist/gui/EFConfiguration.js +1 -1
  73. package/dist/gui/EFControls.d.ts +2 -2
  74. package/dist/gui/EFControls.js +1 -1
  75. package/dist/gui/EFDial.d.ts +4 -4
  76. package/dist/gui/EFDial.js +1 -1
  77. package/dist/gui/EFFilmstrip.d.ts +3 -2
  78. package/dist/gui/EFFilmstrip.js +1 -1
  79. package/dist/gui/EFFitScale.js +1 -1
  80. package/dist/gui/EFFocusOverlay.d.ts +4 -4
  81. package/dist/gui/EFFocusOverlay.js +1 -1
  82. package/dist/gui/EFOverlayItem.d.ts +4 -4
  83. package/dist/gui/EFOverlayItem.js +1 -1
  84. package/dist/gui/EFOverlayLayer.d.ts +4 -4
  85. package/dist/gui/EFOverlayLayer.js +1 -1
  86. package/dist/gui/EFPause.d.ts +4 -4
  87. package/dist/gui/EFPause.js +1 -1
  88. package/dist/gui/EFPlay.d.ts +4 -4
  89. package/dist/gui/EFPlay.js +1 -1
  90. package/dist/gui/EFPreview.d.ts +4 -4
  91. package/dist/gui/EFPreview.js +1 -1
  92. package/dist/gui/EFResizableBox.d.ts +4 -4
  93. package/dist/gui/EFResizableBox.js +1 -1
  94. package/dist/gui/EFScrubber.d.ts +4 -4
  95. package/dist/gui/EFScrubber.js +1 -1
  96. package/dist/gui/EFTimeDisplay.d.ts +4 -4
  97. package/dist/gui/EFTimeDisplay.js +1 -1
  98. package/dist/gui/EFTimelineRuler.d.ts +4 -4
  99. package/dist/gui/EFTimelineRuler.js +1 -1
  100. package/dist/gui/EFToggleLoop.d.ts +4 -4
  101. package/dist/gui/EFToggleLoop.js +1 -1
  102. package/dist/gui/EFTogglePlay.d.ts +4 -4
  103. package/dist/gui/EFTogglePlay.js +1 -1
  104. package/dist/gui/EFTransformHandles.d.ts +4 -4
  105. package/dist/gui/EFTransformHandles.js +1 -1
  106. package/dist/gui/EFWorkbench.d.ts +5 -4
  107. package/dist/gui/EFWorkbench.js +1 -1
  108. package/dist/gui/PlaybackController.d.ts +10 -2
  109. package/dist/gui/PlaybackController.js +52 -30
  110. package/dist/gui/PlaybackController.js.map +1 -1
  111. package/dist/gui/TWMixin.js +1 -1
  112. package/dist/gui/TWMixin.js.map +1 -1
  113. package/dist/gui/TargetOrContextMixin.js +1 -1
  114. package/dist/gui/hierarchy/EFHierarchy.d.ts +4 -4
  115. package/dist/gui/hierarchy/EFHierarchy.js +1 -1
  116. package/dist/gui/hierarchy/EFHierarchyItem.d.ts +3 -3
  117. package/dist/gui/hierarchy/EFHierarchyItem.js +1 -1
  118. package/dist/gui/timeline/EFTimeline.d.ts +6 -2
  119. package/dist/gui/timeline/EFTimeline.js +1 -1
  120. package/dist/gui/timeline/EFTimelineRow.d.ts +57 -0
  121. package/dist/gui/timeline/EFTimelineRow.js +1 -1
  122. package/dist/gui/timeline/TrimHandles.d.ts +4 -4
  123. package/dist/gui/timeline/TrimHandles.js +1 -1
  124. package/dist/gui/timeline/tracks/AudioTrack.d.ts +2 -0
  125. package/dist/gui/timeline/tracks/AudioTrack.js +1 -1
  126. package/dist/gui/timeline/tracks/CaptionsTrack.d.ts +58 -0
  127. package/dist/gui/timeline/tracks/CaptionsTrack.js +1 -1
  128. package/dist/gui/timeline/tracks/HTMLTrack.d.ts +13 -0
  129. package/dist/gui/timeline/tracks/HTMLTrack.js +1 -1
  130. package/dist/gui/timeline/tracks/ImageTrack.d.ts +14 -0
  131. package/dist/gui/timeline/tracks/ImageTrack.js +1 -1
  132. package/dist/gui/timeline/tracks/TextTrack.d.ts +26 -0
  133. package/dist/gui/timeline/tracks/TextTrack.js +1 -1
  134. package/dist/gui/timeline/tracks/TimegroupTrack.d.ts +47 -0
  135. package/dist/gui/timeline/tracks/TimegroupTrack.js +4 -12
  136. package/dist/gui/timeline/tracks/TimegroupTrack.js.map +1 -1
  137. package/dist/gui/timeline/tracks/TrackItem.d.ts +81 -0
  138. package/dist/gui/timeline/tracks/TrackItem.js +1 -1
  139. package/dist/gui/timeline/tracks/VideoTrack.d.ts +25 -0
  140. package/dist/gui/timeline/tracks/VideoTrack.js +1 -1
  141. package/dist/gui/timeline/tracks/WaveformTrack.d.ts +14 -0
  142. package/dist/gui/timeline/tracks/WaveformTrack.js +1 -1
  143. package/dist/gui/timeline/tracks/ensureTrackItemInit.d.ts +1 -0
  144. package/dist/gui/timeline/tracks/preloadTracks.d.ts +9 -0
  145. package/dist/gui/tree/EFTree.d.ts +5 -4
  146. package/dist/gui/tree/EFTree.js +1 -1
  147. package/dist/gui/tree/EFTreeItem.d.ts +4 -4
  148. package/dist/gui/tree/EFTreeItem.js +1 -1
  149. package/dist/index.d.ts +4 -1
  150. package/dist/preview/AdaptiveResolutionTracker.js +6 -14
  151. package/dist/preview/AdaptiveResolutionTracker.js.map +1 -1
  152. package/dist/preview/FrameController.d.ts +123 -0
  153. package/dist/preview/FrameController.js +216 -0
  154. package/dist/preview/FrameController.js.map +1 -0
  155. package/dist/preview/RenderContext.d.ts +1 -0
  156. package/dist/preview/RenderContext.js +193 -0
  157. package/dist/preview/RenderContext.js.map +1 -0
  158. package/dist/preview/encoding/canvasEncoder.js +166 -0
  159. package/dist/preview/encoding/canvasEncoder.js.map +1 -0
  160. package/dist/preview/encoding/mainThreadEncoder.js +39 -0
  161. package/dist/preview/encoding/mainThreadEncoder.js.map +1 -0
  162. package/dist/preview/encoding/types.d.ts +1 -0
  163. package/dist/preview/encoding/workerEncoder.js +58 -0
  164. package/dist/preview/encoding/workerEncoder.js.map +1 -0
  165. package/dist/preview/logger.js +41 -0
  166. package/dist/preview/logger.js.map +1 -0
  167. package/dist/preview/previewTypes.js +11 -10
  168. package/dist/preview/previewTypes.js.map +1 -1
  169. package/dist/preview/renderTimegroupPreview.js +259 -236
  170. package/dist/preview/renderTimegroupPreview.js.map +1 -1
  171. package/dist/preview/renderTimegroupToCanvas.d.ts +5 -0
  172. package/dist/preview/renderTimegroupToCanvas.js +99 -489
  173. package/dist/preview/renderTimegroupToCanvas.js.map +1 -1
  174. package/dist/preview/renderTimegroupToVideo.d.ts +1 -0
  175. package/dist/preview/renderTimegroupToVideo.js +80 -22
  176. package/dist/preview/renderTimegroupToVideo.js.map +1 -1
  177. package/dist/preview/renderers.js.map +1 -1
  178. package/dist/preview/rendering/inlineImages.js +56 -0
  179. package/dist/preview/rendering/inlineImages.js.map +1 -0
  180. package/dist/preview/rendering/renderToImage.d.ts +1 -0
  181. package/dist/preview/rendering/renderToImage.js +120 -0
  182. package/dist/preview/rendering/renderToImage.js.map +1 -0
  183. package/dist/preview/rendering/renderToImageForeignObject.js +135 -0
  184. package/dist/preview/rendering/renderToImageForeignObject.js.map +1 -0
  185. package/dist/preview/rendering/renderToImageNative.d.ts +1 -0
  186. package/dist/preview/rendering/renderToImageNative.js +129 -0
  187. package/dist/preview/rendering/renderToImageNative.js.map +1 -0
  188. package/dist/preview/rendering/svgSerializer.js +43 -0
  189. package/dist/preview/rendering/svgSerializer.js.map +1 -0
  190. package/dist/preview/rendering/types.d.ts +2 -0
  191. package/dist/preview/statsTrackingStrategy.js +3 -1
  192. package/dist/preview/statsTrackingStrategy.js.map +1 -1
  193. package/dist/preview/workers/WorkerPool.js +8 -57
  194. package/dist/preview/workers/WorkerPool.js.map +1 -1
  195. package/dist/render/EFRenderAPI.d.ts +35 -0
  196. package/dist/render/EFRenderAPI.js +1 -0
  197. package/dist/render/EFRenderAPI.js.map +1 -1
  198. package/dist/sandbox/PlaybackControls.d.ts +1 -0
  199. package/dist/sandbox/ScenarioRunner.d.ts +1 -0
  200. package/dist/sandbox/defineSandbox.d.ts +1 -0
  201. package/dist/sandbox/index.d.ts +3 -0
  202. package/dist/style.css +3 -0
  203. package/dist/transcoding/types/index.d.ts +6 -3
  204. package/package.json +2 -3
  205. package/test/EFVideo.framegen.browsertest.ts +8 -1
  206. package/test/profilingPlugin.ts +1 -3
  207. package/test/setup.ts +23 -1
  208. package/dist/EF_INTERACTIVE.js +0 -7
  209. package/dist/EF_INTERACTIVE.js.map +0 -1
  210. package/dist/elements/EFMedia/BufferedSeekingInput.d.ts +0 -50
  211. package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.d.ts +0 -12
  212. package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.js +0 -104
  213. package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.js.map +0 -1
  214. package/dist/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.js +0 -168
  215. package/dist/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.js.map +0 -1
  216. package/dist/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.js +0 -46
  217. package/dist/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.js.map +0 -1
  218. package/dist/elements/EFMedia/audioTasks/makeAudioInputTask.js +0 -49
  219. package/dist/elements/EFMedia/audioTasks/makeAudioInputTask.js.map +0 -1
  220. package/dist/elements/EFMedia/audioTasks/makeAudioSeekTask.js +0 -30
  221. package/dist/elements/EFMedia/audioTasks/makeAudioSeekTask.js.map +0 -1
  222. package/dist/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.js +0 -49
  223. package/dist/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.js.map +0 -1
  224. package/dist/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.js +0 -47
  225. package/dist/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.js.map +0 -1
  226. package/dist/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.js +0 -140
  227. package/dist/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.js.map +0 -1
  228. package/dist/elements/EFMedia/shared/BufferUtils.d.ts +0 -13
  229. package/dist/elements/EFMedia/shared/BufferUtils.js +0 -86
  230. package/dist/elements/EFMedia/shared/BufferUtils.js.map +0 -1
  231. package/dist/elements/EFMedia/shared/MediaTaskUtils.d.ts +0 -17
  232. package/dist/elements/EFMedia/tasks/makeMediaEngineTask.js +0 -90
  233. package/dist/elements/EFMedia/tasks/makeMediaEngineTask.js.map +0 -1
  234. package/dist/elements/EFMedia/videoTasks/makeScrubVideoBufferTask.js +0 -80
  235. package/dist/elements/EFMedia/videoTasks/makeScrubVideoBufferTask.js.map +0 -1
  236. package/dist/elements/EFMedia/videoTasks/makeScrubVideoInitSegmentFetchTask.js +0 -49
  237. package/dist/elements/EFMedia/videoTasks/makeScrubVideoInitSegmentFetchTask.js.map +0 -1
  238. package/dist/elements/EFMedia/videoTasks/makeScrubVideoInputTask.js +0 -58
  239. package/dist/elements/EFMedia/videoTasks/makeScrubVideoInputTask.js.map +0 -1
  240. package/dist/elements/EFMedia/videoTasks/makeScrubVideoSeekTask.js +0 -71
  241. package/dist/elements/EFMedia/videoTasks/makeScrubVideoSeekTask.js.map +0 -1
  242. package/dist/elements/EFMedia/videoTasks/makeScrubVideoSegmentFetchTask.js +0 -52
  243. package/dist/elements/EFMedia/videoTasks/makeScrubVideoSegmentFetchTask.js.map +0 -1
  244. package/dist/elements/EFMedia/videoTasks/makeScrubVideoSegmentIdTask.js +0 -50
  245. package/dist/elements/EFMedia/videoTasks/makeScrubVideoSegmentIdTask.js.map +0 -1
  246. package/dist/elements/EFMedia/videoTasks/makeUnifiedVideoSeekTask.js +0 -109
  247. package/dist/elements/EFMedia/videoTasks/makeUnifiedVideoSeekTask.js.map +0 -1
  248. package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.d.ts +0 -12
  249. package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.js +0 -97
  250. package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.js.map +0 -1
  251. package/dist/elements/SampleBuffer.d.ts +0 -19
@@ -1,18 +1,18 @@
1
- import { EF_INTERACTIVE } from "../EF_INTERACTIVE.js";
2
1
  import { quantizeToFrameTimeS } from "../utils/frameTime.js";
3
2
  import { EF_RENDERING } from "../EF_RENDERING.js";
3
+ import { evaluateAnimationVisibilityState, updateAnimations } from "./updateAnimations.js";
4
4
  import { parseTimeToMs } from "./parseTimeToMs.js";
5
- import { __decorate } from "../_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.js";
5
+ import { __decorate } from "../_virtual/_@oxc-project_runtime@0.95.0/helpers/decorate.js";
6
6
  import { EFTemporal, deepGetElementsWithFrameTasks, flushStartTimeMsCache, registerIsTimegroupCalculatingDuration, resetTemporalCache, shallowGetTemporalElements, timegroupContext } from "./EFTemporal.js";
7
7
  import { efContext } from "../gui/efContext.js";
8
8
  import { isContextMixin } from "../gui/ContextMixin.js";
9
9
  import { TWMixin } from "../gui/TWMixin2.js";
10
10
  import { isTracingEnabled, withSpan } from "../otel/tracingHelpers.js";
11
+ import { FrameController } from "../preview/FrameController.js";
11
12
  import { renderTemporalAudio } from "./renderTemporalAudio.js";
12
13
  import { EFTargetable } from "./TargetController.js";
13
14
  import { deepGetMediaElements } from "./EFMedia.js";
14
15
  import { TimegroupController } from "./TimegroupController.js";
15
- import { evaluateAnimationVisibilityState, updateAnimations } from "./updateAnimations.js";
16
16
  import { getContainerInfoFromElement } from "./ContainerInfo.js";
17
17
  import { getPositionInfoFromElement } from "./ElementPositionInfo.js";
18
18
  import { captureFromClone, captureTimegroupAtTime } from "../preview/renderTimegroupToCanvas.js";
@@ -24,7 +24,6 @@ import "../gui/EFFitScale.js";
24
24
  import "../gui/EFWorkbench.js";
25
25
  import "./EFPanZoom.js";
26
26
  import { provide } from "@lit/context";
27
- import { Task, TaskStatus } from "@lit/task";
28
27
  import debug from "debug";
29
28
  import { LitElement, css, html } from "lit";
30
29
  import { customElement, property } from "lit/decorators.js";
@@ -190,84 +189,37 @@ let EFTimegroup = class EFTimegroup$1 extends EFTargetable(EFTemporal(TWMixin(Li
190
189
  this.autoInit = false;
191
190
  this.workbench = false;
192
191
  this.fit = "none";
193
- this.frameTask = new Task(this, {
194
- autoRun: EF_INTERACTIVE,
195
- args: () => [this.ownCurrentTimeMs, this.currentTimeMs],
196
- onError: (error) => {
197
- this.frameTask.taskComplete.catch(() => {});
198
- if (error instanceof DOMException && error.name === "AbortError" || error instanceof Error && (error.name === "AbortError" || error.message?.includes("signal is aborted") || error.message?.includes("The user aborted a request"))) return;
199
- console.error("EFTimegroup frameTask error", error);
200
- },
201
- task: async ([ownCurrentTimeMs, currentTimeMs], { signal }) => {
202
- const now = Date.now();
203
- if (now - this.#timegroupFrameTaskLastReset > _EFTimegroup.TIMEGROUP_FRAME_TASK_RESET_MS) {
204
- this.#timegroupFrameTaskCount = 0;
205
- this.#timegroupFrameTaskLastReset = now;
206
- }
207
- this.#timegroupFrameTaskCount++;
208
- if (this.#timegroupFrameTaskCount > _EFTimegroup.TIMEGROUP_FRAME_TASK_THRESHOLD) return;
209
- signal?.throwIfAborted();
210
- if (this.isRootTimegroup) return withSpan("timegroup.frameTask", {
211
- timegroupId: this.id || "unknown",
212
- ownCurrentTimeMs,
213
- currentTimeMs
214
- }, void 0, async () => {
215
- await this.waitForFrameTasks(signal);
216
- signal?.throwIfAborted();
217
- await this.#executeCustomFrameTasks();
218
- signal?.throwIfAborted();
219
- updateAnimations(this);
220
- });
221
- else return this.#executeCustomFrameTasks();
222
- }
223
- });
224
- this.seekTask = new Task(this, {
225
- autoRun: false,
226
- args: () => [this.#pendingSeekTime ?? this.#currentTime],
227
- onComplete: () => {},
228
- task: async ([targetTime], { signal }) => {
229
- signal?.throwIfAborted();
230
- if (this.playbackController) return this.playbackController.seekTask.taskComplete.then(() => {
231
- signal?.throwIfAborted();
232
- return this.currentTime;
233
- });
234
- if (!this.isRootTimegroup) return;
235
- return withSpan("timegroup.seekTask", {
236
- timegroupId: this.id || "unknown",
237
- targetTime: targetTime ?? 0,
238
- durationMs: this.durationMs
239
- }, void 0, async (span) => {
240
- try {
241
- await Promise.race([this.waitForMediaDurations(signal), new Promise((_, reject) => {
242
- if (signal?.aborted) {
243
- reject(new DOMException("Aborted", "AbortError"));
244
- return;
245
- }
246
- const timeoutId = setTimeout(() => reject(/* @__PURE__ */ new Error("waitForMediaDurations timeout")), 1e4);
247
- signal?.addEventListener("abort", () => {
248
- clearTimeout(timeoutId);
249
- reject(new DOMException("Aborted", "AbortError"));
250
- });
251
- })]);
252
- } catch (error) {
253
- if (error instanceof DOMException && error.name === "AbortError") throw error;
254
- }
255
- signal?.throwIfAborted();
256
- const newTime = evaluateSeekTarget(targetTime ?? 0, this.durationMs, this.effectiveFps);
257
- if (isTracingEnabled()) span.setAttribute("newTime", newTime);
258
- this.#currentTime = newTime;
259
- this.requestUpdate("currentTime");
260
- await this.updateComplete;
261
- signal?.throwIfAborted();
262
- await this.#runThrottledFrameTask();
263
- signal?.throwIfAborted();
264
- if (!this.#restoringFromLocalStorage) this.saveTimeToLocalStorage(this.#currentTime);
265
- this.#seekInProgress = false;
266
- if (this.#restoringFromLocalStorage) this.#restoringFromLocalStorage = false;
267
- return newTime;
268
- });
269
- }
270
- });
192
+ this.frameTask = (() => {
193
+ const self = this;
194
+ const taskObj = {
195
+ run: () => {
196
+ self.#frameTaskAbortController?.abort();
197
+ self.#frameTaskAbortController = new AbortController();
198
+ const signal = self.#frameTaskAbortController.signal;
199
+ self.#frameTaskPromise = self.#runFrameTask(signal);
200
+ taskObj.taskComplete = self.#frameTaskPromise;
201
+ return self.#frameTaskPromise;
202
+ },
203
+ taskComplete: Promise.resolve()
204
+ };
205
+ return taskObj;
206
+ })();
207
+ this.seekTask = (() => {
208
+ const self = this;
209
+ const taskObj = {
210
+ run: () => {
211
+ self.#seekTaskAbortController?.abort();
212
+ self.#seekTaskAbortController = new AbortController();
213
+ const signal = self.#seekTaskAbortController.signal;
214
+ const targetTime = self.#pendingSeekTime ?? self.#currentTime;
215
+ self.#seekTaskPromise = self.#runSeekTask(targetTime, signal);
216
+ taskObj.taskComplete = self.#seekTaskPromise;
217
+ return self.#seekTaskPromise;
218
+ },
219
+ taskComplete: Promise.resolve(void 0)
220
+ };
221
+ return taskObj;
222
+ })();
271
223
  }
272
224
  static get observedAttributes() {
273
225
  return [
@@ -329,6 +281,18 @@ let EFTimegroup = class EFTimegroup$1 extends EFTargetable(EFTemporal(TWMixin(Li
329
281
  #onFrameCleanup = null;
330
282
  #playbackListener = null;
331
283
  /**
284
+ * Centralized frame controller for coordinating element rendering.
285
+ * Replaces the distributed Lit Task hierarchy with a single control point.
286
+ */
287
+ #frameController = new FrameController(this);
288
+ /**
289
+ * Get the frame controller for centralized rendering coordination.
290
+ * @public
291
+ */
292
+ get frameController() {
293
+ return this.#frameController;
294
+ }
295
+ /**
332
296
  * Get the effective FPS for this timegroup.
333
297
  * During rendering, uses the render options FPS if available.
334
298
  * Otherwise uses the configured fps property.
@@ -446,9 +410,9 @@ let EFTimegroup = class EFTimegroup$1 extends EFTargetable(EFTemporal(TWMixin(Li
446
410
  * Unlike `seek()`, this:
447
411
  * - Skips waitForMediaDurations (already loaded at render setup)
448
412
  * - Skips localStorage persistence
449
- * - Consolidates awaits to reduce event loop yields
413
+ * - Uses FrameController for centralized element coordination
450
414
  *
451
- * Still waits for all content to be ready (Lit updates, frame tasks, video frames).
415
+ * Still waits for all content to be ready (Lit updates, element preparation, rendering).
452
416
  *
453
417
  * @param timeMs - Time in milliseconds to seek to
454
418
  * @internal
@@ -466,23 +430,48 @@ let EFTimegroup = class EFTimegroup$1 extends EFTargetable(EFTemporal(TWMixin(Li
466
430
  if ("whenSegmentsReady" in el && typeof el.whenSegmentsReady === "function") return el.whenSegmentsReady();
467
431
  return Promise.resolve();
468
432
  }));
469
- await new Promise((resolve) => requestAnimationFrame(resolve));
470
- const visibleElements = this.#evaluateVisibleElementsForFrame();
471
- await Promise.all([this.frameTask.run(), ...visibleElements.map((element) => {
472
- if ("waitForFrameReady" in element && typeof element.waitForFrameReady === "function") return element.waitForFrameReady();
473
- else return element.updateComplete;
474
- })]);
475
- this.offsetWidth;
433
+ await this.#frameController.renderFrame(timeMs, {
434
+ waitForLitUpdate: false,
435
+ onAnimationsUpdate: (root) => {
436
+ updateAnimations(root);
437
+ root.offsetWidth;
438
+ }
439
+ });
440
+ await this.#executeCustomFrameTasks();
476
441
  }
477
442
  /**
478
443
  * Collects all LitElement descendants recursively.
479
444
  * Used by seekForRender to ensure all reactive elements have updated.
445
+ * Optimized to filter by temporal visibility and skip hidden subtrees.
480
446
  */
481
447
  #getAllLitElementDescendants() {
482
448
  const result = [];
449
+ const currentTimeMs = this.currentTimeMs;
450
+ let hiddenSubtreesSkipped = 0;
451
+ let temporallyFilteredOut = 0;
452
+ let totalLitElements = 0;
483
453
  const walk = (el) => {
454
+ if (el instanceof HTMLElement && el.style.display === "none") {
455
+ hiddenSubtreesSkipped++;
456
+ return;
457
+ }
458
+ if (el instanceof HTMLElement) {
459
+ const style = getComputedStyle(el);
460
+ if (style.display === "none" || style.visibility === "hidden") {
461
+ hiddenSubtreesSkipped++;
462
+ return;
463
+ }
464
+ }
484
465
  for (const child of el.children) {
485
- if (child instanceof LitElement) result.push(child);
466
+ if (child instanceof LitElement) {
467
+ totalLitElements++;
468
+ if ("startTimeMs" in child && "endTimeMs" in child) {
469
+ const startMs = child.startTimeMs ?? -Infinity;
470
+ const endMs = child.endTimeMs ?? Infinity;
471
+ if (currentTimeMs >= startMs && currentTimeMs <= endMs) result.push(child);
472
+ else temporallyFilteredOut++;
473
+ } else result.push(child);
474
+ }
486
475
  walk(child);
487
476
  }
488
477
  };
@@ -777,11 +766,9 @@ let EFTimegroup = class EFTimegroup$1 extends EFTargetable(EFTemporal(TWMixin(Li
777
766
  if (captionsElements.length === 0) return;
778
767
  const waitPromises = [];
779
768
  for (const el of captionsElements) {
780
- const task = el.unifiedCaptionsDataTask;
781
- if (!task) continue;
782
- if (task.status === TaskStatus.COMPLETE || task.status === TaskStatus.ERROR) continue;
783
- if (task.status === TaskStatus.INITIAL) task.run().catch(() => {});
784
- if (task.taskComplete) waitPromises.push(task.taskComplete);
769
+ const captions = el;
770
+ if (typeof captions.loadCaptionsData === "function") waitPromises.push(captions.loadCaptionsData().catch(() => {}));
771
+ else if (captions.unifiedCaptionsDataTask?.taskComplete) waitPromises.push(captions.unifiedCaptionsDataTask.taskComplete.catch(() => {}));
785
772
  }
786
773
  if (waitPromises.length > 0) await Promise.all(waitPromises);
787
774
  }
@@ -1032,23 +1019,39 @@ let EFTimegroup = class EFTimegroup$1 extends EFTargetable(EFTemporal(TWMixin(Li
1032
1019
  signal?.throwIfAborted();
1033
1020
  const elementStart = Date.now();
1034
1021
  try {
1035
- const status = m.mediaEngineTask.status;
1036
- if (status === TaskStatus.COMPLETE || status === TaskStatus.ERROR) return;
1037
- if (status === TaskStatus.INITIAL) m.mediaEngineTask.run().catch(() => {});
1038
- const timeoutPromise = new Promise((_, reject) => {
1039
- if (signal?.aborted) {
1040
- reject(new DOMException("Aborted", "AbortError"));
1041
- return;
1022
+ if (typeof m.getMediaEngine === "function") {
1023
+ const timeoutPromise = new Promise((_, reject) => {
1024
+ if (signal?.aborted) {
1025
+ reject(new DOMException("Aborted", "AbortError"));
1026
+ return;
1027
+ }
1028
+ const timeoutId = setTimeout(() => reject(/* @__PURE__ */ new Error(`Media element ${index} load timeout after ${MEDIA_LOAD_TIMEOUT_MS}ms`)), MEDIA_LOAD_TIMEOUT_MS);
1029
+ signal?.addEventListener("abort", () => {
1030
+ clearTimeout(timeoutId);
1031
+ reject(new DOMException("Aborted", "AbortError"));
1032
+ }, { once: true });
1033
+ });
1034
+ await Promise.race([m.getMediaEngine(signal), timeoutPromise]);
1035
+ } else if (m.mediaEngineTask) {
1036
+ const status = m.mediaEngineTask.status;
1037
+ if (status === 2 || status === 3) return;
1038
+ const taskPromise = m.mediaEngineTask.taskComplete;
1039
+ taskPromise?.catch(() => {});
1040
+ if (taskPromise) {
1041
+ const timeoutPromise = new Promise((_, reject) => {
1042
+ if (signal?.aborted) {
1043
+ reject(new DOMException("Aborted", "AbortError"));
1044
+ return;
1045
+ }
1046
+ const timeoutId = setTimeout(() => reject(/* @__PURE__ */ new Error(`Media element ${index} load timeout after ${MEDIA_LOAD_TIMEOUT_MS}ms`)), MEDIA_LOAD_TIMEOUT_MS);
1047
+ signal?.addEventListener("abort", () => {
1048
+ clearTimeout(timeoutId);
1049
+ reject(new DOMException("Aborted", "AbortError"));
1050
+ }, { once: true });
1051
+ });
1052
+ await Promise.race([taskPromise, timeoutPromise]);
1042
1053
  }
1043
- const timeoutId = setTimeout(() => reject(/* @__PURE__ */ new Error(`Media element ${index} load timeout after ${MEDIA_LOAD_TIMEOUT_MS}ms`)), MEDIA_LOAD_TIMEOUT_MS);
1044
- signal?.addEventListener("abort", () => {
1045
- clearTimeout(timeoutId);
1046
- reject(new DOMException("Aborted", "AbortError"));
1047
- }, { once: true });
1048
- });
1049
- const taskPromise = m.mediaEngineTask.taskComplete;
1050
- taskPromise.catch(() => {});
1051
- await Promise.race([taskPromise, timeoutPromise]);
1054
+ }
1052
1055
  } catch (error) {
1053
1056
  if (error instanceof DOMException && error.name === "AbortError") throw error;
1054
1057
  if (isTracingEnabled()) {
@@ -1184,9 +1187,9 @@ let EFTimegroup = class EFTimegroup$1 extends EFTargetable(EFTemporal(TWMixin(Li
1184
1187
  const loaderTasks = [];
1185
1188
  for (const el of efElements) {
1186
1189
  const md5SumLoader = el.md5SumLoader;
1187
- if (md5SumLoader instanceof Task) {
1190
+ if (md5SumLoader && typeof md5SumLoader.run === "function") {
1188
1191
  md5SumLoader.run().catch(() => {});
1189
- loaderTasks.push(md5SumLoader.taskComplete);
1192
+ if (md5SumLoader.taskComplete) loaderTasks.push(md5SumLoader.taskComplete);
1190
1193
  }
1191
1194
  }
1192
1195
  await Promise.all(loaderTasks);
@@ -1202,6 +1205,39 @@ let EFTimegroup = class EFTimegroup$1 extends EFTargetable(EFTemporal(TWMixin(Li
1202
1205
  static {
1203
1206
  this.TIMEGROUP_FRAME_TASK_RESET_MS = 1e3;
1204
1207
  }
1208
+ /** @internal */
1209
+ #frameTaskPromise = Promise.resolve();
1210
+ #frameTaskAbortController = null;
1211
+ async #runFrameTask(signal) {
1212
+ const now = Date.now();
1213
+ if (now - this.#timegroupFrameTaskLastReset > _EFTimegroup.TIMEGROUP_FRAME_TASK_RESET_MS) {
1214
+ this.#timegroupFrameTaskCount = 0;
1215
+ this.#timegroupFrameTaskLastReset = now;
1216
+ }
1217
+ this.#timegroupFrameTaskCount++;
1218
+ if (this.#timegroupFrameTaskCount > _EFTimegroup.TIMEGROUP_FRAME_TASK_THRESHOLD) return;
1219
+ try {
1220
+ signal.throwIfAborted();
1221
+ if (this.isRootTimegroup) await withSpan("timegroup.frameTask", {
1222
+ timegroupId: this.id || "unknown",
1223
+ ownCurrentTimeMs: this.ownCurrentTimeMs,
1224
+ currentTimeMs: this.currentTimeMs
1225
+ }, void 0, async () => {
1226
+ await this.#frameController.renderFrame(this.currentTimeMs, {
1227
+ waitForLitUpdate: false,
1228
+ onAnimationsUpdate: (root) => {
1229
+ updateAnimations(root);
1230
+ }
1231
+ });
1232
+ signal.throwIfAborted();
1233
+ await this.#executeCustomFrameTasks();
1234
+ });
1235
+ else await this.#executeCustomFrameTasks();
1236
+ } catch (error) {
1237
+ if (error instanceof DOMException && error.name === "AbortError") return;
1238
+ console.error("EFTimegroup frameTask error", error);
1239
+ }
1240
+ }
1205
1241
  async #executeCustomFrameTasks() {
1206
1242
  if (this.#customFrameTasks.size > 0) {
1207
1243
  const percentComplete = this.durationMs > 0 ? this.ownCurrentTimeMs / this.durationMs : 0;
@@ -1215,6 +1251,58 @@ let EFTimegroup = class EFTimegroup$1 extends EFTargetable(EFTemporal(TWMixin(Li
1215
1251
  await Promise.all(Array.from(this.#customFrameTasks).map((callback) => Promise.resolve(callback(frameInfo))));
1216
1252
  }
1217
1253
  }
1254
+ /** @internal */
1255
+ #seekTaskPromise = Promise.resolve(void 0);
1256
+ #seekTaskAbortController = null;
1257
+ async #runSeekTask(targetTime, signal) {
1258
+ try {
1259
+ signal.throwIfAborted();
1260
+ if (this.playbackController) {
1261
+ await this.playbackController.currentTime;
1262
+ signal.throwIfAborted();
1263
+ return this.currentTime;
1264
+ }
1265
+ if (!this.isRootTimegroup) return;
1266
+ return await withSpan("timegroup.seekTask", {
1267
+ timegroupId: this.id || "unknown",
1268
+ targetTime: targetTime ?? 0,
1269
+ durationMs: this.durationMs
1270
+ }, void 0, async (span) => {
1271
+ try {
1272
+ await Promise.race([this.waitForMediaDurations(signal), new Promise((_, reject) => {
1273
+ if (signal.aborted) {
1274
+ reject(new DOMException("Aborted", "AbortError"));
1275
+ return;
1276
+ }
1277
+ const timeoutId = setTimeout(() => reject(/* @__PURE__ */ new Error("waitForMediaDurations timeout")), 1e4);
1278
+ signal.addEventListener("abort", () => {
1279
+ clearTimeout(timeoutId);
1280
+ reject(new DOMException("Aborted", "AbortError"));
1281
+ }, { once: true });
1282
+ })]);
1283
+ } catch (error) {
1284
+ if (error instanceof DOMException && error.name === "AbortError") throw error;
1285
+ }
1286
+ signal.throwIfAborted();
1287
+ const newTime = evaluateSeekTarget(targetTime ?? 0, this.durationMs, this.effectiveFps);
1288
+ if (isTracingEnabled()) span.setAttribute("newTime", newTime);
1289
+ this.#currentTime = newTime;
1290
+ this.requestUpdate("currentTime");
1291
+ await this.updateComplete;
1292
+ signal.throwIfAborted();
1293
+ await this.#runThrottledFrameTask();
1294
+ signal.throwIfAborted();
1295
+ if (!this.#restoringFromLocalStorage) this.saveTimeToLocalStorage(this.#currentTime);
1296
+ this.#seekInProgress = false;
1297
+ if (this.#restoringFromLocalStorage) this.#restoringFromLocalStorage = false;
1298
+ return newTime;
1299
+ });
1300
+ } catch (error) {
1301
+ if (error instanceof DOMException && error.name === "AbortError") return;
1302
+ console.error("EFTimegroup seekTask error", error);
1303
+ return;
1304
+ }
1305
+ }
1218
1306
  /**
1219
1307
  * Get container information for this timegroup.
1220
1308
  * Timegroups are always containers and can contain children.