@editframe/elements 0.16.8-beta.0 → 0.18.3-beta.0

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 (267) hide show
  1. package/README.md +30 -0
  2. package/dist/DecoderResetFrequency.test.d.ts +1 -0
  3. package/dist/DecoderResetRecovery.test.d.ts +1 -0
  4. package/dist/DelayedLoadingState.d.ts +48 -0
  5. package/dist/DelayedLoadingState.integration.test.d.ts +1 -0
  6. package/dist/DelayedLoadingState.js +113 -0
  7. package/dist/DelayedLoadingState.test.d.ts +1 -0
  8. package/dist/EF_FRAMEGEN.d.ts +10 -1
  9. package/dist/EF_FRAMEGEN.js +199 -179
  10. package/dist/EF_INTERACTIVE.js +2 -6
  11. package/dist/EF_RENDERING.js +1 -3
  12. package/dist/LoadingDebounce.test.d.ts +1 -0
  13. package/dist/LoadingIndicator.browsertest.d.ts +0 -0
  14. package/dist/ManualScrubTest.test.d.ts +1 -0
  15. package/dist/ScrubResolvedFlashing.test.d.ts +1 -0
  16. package/dist/ScrubTrackManager.d.ts +96 -0
  17. package/dist/ScrubTrackManager.test.d.ts +1 -0
  18. package/dist/VideoSeekFlashing.browsertest.d.ts +0 -0
  19. package/dist/VideoStuckDiagnostic.test.d.ts +1 -0
  20. package/dist/elements/CrossUpdateController.js +13 -15
  21. package/dist/elements/EFAudio.browsertest.d.ts +0 -0
  22. package/dist/elements/EFAudio.d.ts +22 -3
  23. package/dist/elements/EFAudio.js +60 -43
  24. package/dist/elements/EFCaptions.js +337 -373
  25. package/dist/elements/EFImage.d.ts +1 -0
  26. package/dist/elements/EFImage.js +73 -91
  27. package/dist/elements/EFMedia/AssetIdMediaEngine.d.ts +18 -0
  28. package/dist/elements/EFMedia/AssetIdMediaEngine.js +41 -0
  29. package/dist/elements/EFMedia/AssetIdMediaEngine.test.d.ts +1 -0
  30. package/dist/elements/EFMedia/AssetMediaEngine.d.ts +47 -0
  31. package/dist/elements/EFMedia/AssetMediaEngine.js +116 -0
  32. package/dist/elements/EFMedia/BaseMediaEngine.d.ts +55 -0
  33. package/dist/elements/EFMedia/BaseMediaEngine.js +96 -0
  34. package/dist/elements/EFMedia/BaseMediaEngine.test.d.ts +1 -0
  35. package/dist/elements/EFMedia/BufferedSeekingInput.browsertest.d.ts +1 -0
  36. package/dist/elements/EFMedia/BufferedSeekingInput.d.ts +43 -0
  37. package/dist/elements/EFMedia/BufferedSeekingInput.js +159 -0
  38. package/dist/elements/EFMedia/JitMediaEngine.browsertest.d.ts +0 -0
  39. package/dist/elements/EFMedia/JitMediaEngine.d.ts +31 -0
  40. package/dist/elements/EFMedia/JitMediaEngine.js +62 -0
  41. package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.browsertest.d.ts +9 -0
  42. package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.d.ts +16 -0
  43. package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.js +48 -0
  44. package/dist/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.d.ts +3 -0
  45. package/dist/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.js +138 -0
  46. package/dist/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.browsertest.d.ts +9 -0
  47. package/dist/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.d.ts +4 -0
  48. package/dist/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.js +16 -0
  49. package/dist/elements/EFMedia/audioTasks/makeAudioInputTask.browsertest.d.ts +9 -0
  50. package/dist/elements/EFMedia/audioTasks/makeAudioInputTask.d.ts +3 -0
  51. package/dist/elements/EFMedia/audioTasks/makeAudioInputTask.js +22 -0
  52. package/dist/elements/EFMedia/audioTasks/makeAudioSeekTask.d.ts +7 -0
  53. package/dist/elements/EFMedia/audioTasks/makeAudioSeekTask.js +24 -0
  54. package/dist/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.d.ts +4 -0
  55. package/dist/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.js +18 -0
  56. package/dist/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.d.ts +4 -0
  57. package/dist/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.js +16 -0
  58. package/dist/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.d.ts +3 -0
  59. package/dist/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.js +104 -0
  60. package/dist/elements/EFMedia/services/AudioElementFactory.browsertest.d.ts +1 -0
  61. package/dist/elements/EFMedia/services/AudioElementFactory.d.ts +22 -0
  62. package/dist/elements/EFMedia/services/AudioElementFactory.js +72 -0
  63. package/dist/elements/EFMedia/services/MediaSourceService.browsertest.d.ts +1 -0
  64. package/dist/elements/EFMedia/services/MediaSourceService.d.ts +47 -0
  65. package/dist/elements/EFMedia/services/MediaSourceService.js +73 -0
  66. package/dist/elements/EFMedia/shared/AudioSpanUtils.d.ts +7 -0
  67. package/dist/elements/EFMedia/shared/AudioSpanUtils.js +54 -0
  68. package/dist/elements/EFMedia/shared/BufferUtils.d.ts +70 -0
  69. package/dist/elements/EFMedia/shared/BufferUtils.js +89 -0
  70. package/dist/elements/EFMedia/shared/MediaTaskUtils.d.ts +23 -0
  71. package/dist/elements/EFMedia/shared/RenditionHelpers.browsertest.d.ts +1 -0
  72. package/dist/elements/EFMedia/shared/RenditionHelpers.d.ts +19 -0
  73. package/dist/elements/EFMedia/tasks/makeMediaEngineTask.browsertest.d.ts +1 -0
  74. package/dist/elements/EFMedia/tasks/makeMediaEngineTask.d.ts +18 -0
  75. package/dist/elements/EFMedia/tasks/makeMediaEngineTask.js +60 -0
  76. package/dist/elements/EFMedia/tasks/makeMediaEngineTask.test.d.ts +1 -0
  77. package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.browsertest.d.ts +9 -0
  78. package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.d.ts +16 -0
  79. package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.js +46 -0
  80. package/dist/elements/EFMedia/videoTasks/makeVideoInitSegmentFetchTask.browsertest.d.ts +9 -0
  81. package/dist/elements/EFMedia/videoTasks/makeVideoInitSegmentFetchTask.d.ts +4 -0
  82. package/dist/elements/EFMedia/videoTasks/makeVideoInitSegmentFetchTask.js +16 -0
  83. package/dist/elements/EFMedia/videoTasks/makeVideoInputTask.browsertest.d.ts +9 -0
  84. package/dist/elements/EFMedia/videoTasks/makeVideoInputTask.d.ts +3 -0
  85. package/dist/elements/EFMedia/videoTasks/makeVideoInputTask.js +27 -0
  86. package/dist/elements/EFMedia/videoTasks/makeVideoSeekTask.d.ts +7 -0
  87. package/dist/elements/EFMedia/videoTasks/makeVideoSeekTask.js +25 -0
  88. package/dist/elements/EFMedia/videoTasks/makeVideoSegmentFetchTask.browsertest.d.ts +9 -0
  89. package/dist/elements/EFMedia/videoTasks/makeVideoSegmentFetchTask.d.ts +4 -0
  90. package/dist/elements/EFMedia/videoTasks/makeVideoSegmentFetchTask.js +18 -0
  91. package/dist/elements/EFMedia/videoTasks/makeVideoSegmentIdTask.browsertest.d.ts +9 -0
  92. package/dist/elements/EFMedia/videoTasks/makeVideoSegmentIdTask.d.ts +4 -0
  93. package/dist/elements/EFMedia/videoTasks/makeVideoSegmentIdTask.js +16 -0
  94. package/dist/elements/EFMedia.browsertest.d.ts +1 -0
  95. package/dist/elements/EFMedia.d.ts +95 -66
  96. package/dist/elements/EFMedia.js +204 -683
  97. package/dist/elements/EFSourceMixin.js +31 -48
  98. package/dist/elements/EFTemporal.d.ts +2 -1
  99. package/dist/elements/EFTemporal.js +266 -360
  100. package/dist/elements/EFTimegroup.d.ts +14 -1
  101. package/dist/elements/EFTimegroup.js +337 -323
  102. package/dist/elements/EFVideo.browsertest.d.ts +0 -0
  103. package/dist/elements/EFVideo.d.ts +123 -4
  104. package/dist/elements/EFVideo.js +308 -111
  105. package/dist/elements/EFWaveform.js +375 -411
  106. package/dist/elements/FetchMixin.js +14 -24
  107. package/dist/elements/MediaController.d.ts +30 -0
  108. package/dist/elements/SampleBuffer.d.ts +14 -0
  109. package/dist/elements/SampleBuffer.js +52 -0
  110. package/dist/elements/TargetController.js +130 -156
  111. package/dist/elements/TimegroupController.js +17 -19
  112. package/dist/elements/durationConverter.js +15 -4
  113. package/dist/elements/parseTimeToMs.js +4 -10
  114. package/dist/elements/printTaskStatus.d.ts +2 -0
  115. package/dist/elements/updateAnimations.js +39 -59
  116. package/dist/getRenderInfo.d.ts +2 -2
  117. package/dist/getRenderInfo.js +59 -67
  118. package/dist/gui/ContextMixin.js +150 -288
  119. package/dist/gui/EFConfiguration.js +27 -43
  120. package/dist/gui/EFFilmstrip.d.ts +3 -3
  121. package/dist/gui/EFFilmstrip.js +440 -620
  122. package/dist/gui/EFFitScale.d.ts +2 -2
  123. package/dist/gui/EFFitScale.js +112 -135
  124. package/dist/gui/EFFocusOverlay.js +45 -61
  125. package/dist/gui/EFPreview.js +30 -49
  126. package/dist/gui/EFScrubber.js +78 -99
  127. package/dist/gui/EFTimeDisplay.js +49 -70
  128. package/dist/gui/EFToggleLoop.js +17 -34
  129. package/dist/gui/EFTogglePlay.js +37 -58
  130. package/dist/gui/EFWorkbench.js +66 -88
  131. package/dist/gui/TWMixin.js +2 -48
  132. package/dist/gui/TWMixin2.js +31 -0
  133. package/dist/gui/efContext.js +2 -6
  134. package/dist/gui/fetchContext.js +1 -3
  135. package/dist/gui/focusContext.js +1 -3
  136. package/dist/gui/focusedElementContext.js +2 -6
  137. package/dist/gui/playingContext.js +1 -4
  138. package/dist/gui/services/ElementConnectionManager.browsertest.d.ts +1 -0
  139. package/dist/gui/services/ElementConnectionManager.d.ts +59 -0
  140. package/dist/gui/services/ElementConnectionManager.js +128 -0
  141. package/dist/gui/services/PlaybackController.browsertest.d.ts +1 -0
  142. package/dist/gui/services/PlaybackController.d.ts +103 -0
  143. package/dist/gui/services/PlaybackController.js +290 -0
  144. package/dist/index.js +5 -30
  145. package/dist/msToTimeCode.js +11 -13
  146. package/dist/services/MediaSourceManager.d.ts +62 -0
  147. package/dist/services/MediaSourceManager.js +211 -0
  148. package/dist/style.css +2 -1
  149. package/dist/transcoding/cache/CacheManager.d.ts +73 -0
  150. package/dist/transcoding/cache/RequestDeduplicator.d.ts +29 -0
  151. package/dist/transcoding/cache/RequestDeduplicator.js +53 -0
  152. package/dist/transcoding/cache/RequestDeduplicator.test.d.ts +1 -0
  153. package/dist/transcoding/types/index.d.ts +242 -0
  154. package/dist/transcoding/utils/MediaUtils.d.ts +9 -0
  155. package/dist/transcoding/utils/UrlGenerator.d.ts +26 -0
  156. package/dist/transcoding/utils/UrlGenerator.js +45 -0
  157. package/dist/transcoding/utils/constants.d.ts +27 -0
  158. package/dist/utils/LRUCache.d.ts +34 -0
  159. package/dist/utils/LRUCache.js +115 -0
  160. package/package.json +4 -3
  161. package/src/elements/EFAudio.browsertest.ts +709 -0
  162. package/src/elements/EFAudio.ts +59 -15
  163. package/src/elements/EFCaptions.browsertest.ts +0 -1
  164. package/src/elements/EFImage.browsertest.ts +42 -1
  165. package/src/elements/EFImage.ts +23 -3
  166. package/src/elements/EFMedia/AssetIdMediaEngine.test.ts +222 -0
  167. package/src/elements/EFMedia/AssetIdMediaEngine.ts +70 -0
  168. package/src/elements/EFMedia/AssetMediaEngine.ts +210 -0
  169. package/src/elements/EFMedia/BaseMediaEngine.test.ts +164 -0
  170. package/src/elements/EFMedia/BaseMediaEngine.ts +170 -0
  171. package/src/elements/EFMedia/BufferedSeekingInput.browsertest.ts +400 -0
  172. package/src/elements/EFMedia/BufferedSeekingInput.ts +267 -0
  173. package/src/elements/EFMedia/JitMediaEngine.browsertest.ts +165 -0
  174. package/src/elements/EFMedia/JitMediaEngine.ts +110 -0
  175. package/src/elements/EFMedia/audioTasks/makeAudioBufferTask.browsertest.ts +554 -0
  176. package/src/elements/EFMedia/audioTasks/makeAudioBufferTask.ts +81 -0
  177. package/src/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.ts +241 -0
  178. package/src/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.browsertest.ts +59 -0
  179. package/src/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.ts +23 -0
  180. package/src/elements/EFMedia/audioTasks/makeAudioInputTask.browsertest.ts +55 -0
  181. package/src/elements/EFMedia/audioTasks/makeAudioInputTask.ts +35 -0
  182. package/src/elements/EFMedia/audioTasks/makeAudioSeekTask.ts +42 -0
  183. package/src/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.ts +34 -0
  184. package/src/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.ts +23 -0
  185. package/src/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.ts +174 -0
  186. package/src/elements/EFMedia/services/AudioElementFactory.browsertest.ts +325 -0
  187. package/src/elements/EFMedia/services/AudioElementFactory.ts +119 -0
  188. package/src/elements/EFMedia/services/MediaSourceService.browsertest.ts +257 -0
  189. package/src/elements/EFMedia/services/MediaSourceService.ts +102 -0
  190. package/src/elements/EFMedia/shared/AudioSpanUtils.ts +128 -0
  191. package/src/elements/EFMedia/shared/BufferUtils.ts +310 -0
  192. package/src/elements/EFMedia/shared/MediaTaskUtils.ts +44 -0
  193. package/src/elements/EFMedia/shared/RenditionHelpers.browsertest.ts +247 -0
  194. package/src/elements/EFMedia/shared/RenditionHelpers.ts +79 -0
  195. package/src/elements/EFMedia/tasks/makeMediaEngineTask.browsertest.ts +128 -0
  196. package/src/elements/EFMedia/tasks/makeMediaEngineTask.test.ts +233 -0
  197. package/src/elements/EFMedia/tasks/makeMediaEngineTask.ts +89 -0
  198. package/src/elements/EFMedia/videoTasks/makeVideoBufferTask.browsertest.ts +555 -0
  199. package/src/elements/EFMedia/videoTasks/makeVideoBufferTask.ts +79 -0
  200. package/src/elements/EFMedia/videoTasks/makeVideoInitSegmentFetchTask.browsertest.ts +59 -0
  201. package/src/elements/EFMedia/videoTasks/makeVideoInitSegmentFetchTask.ts +23 -0
  202. package/src/elements/EFMedia/videoTasks/makeVideoInputTask.browsertest.ts +55 -0
  203. package/src/elements/EFMedia/videoTasks/makeVideoInputTask.ts +45 -0
  204. package/src/elements/EFMedia/videoTasks/makeVideoSeekTask.ts +44 -0
  205. package/src/elements/EFMedia/videoTasks/makeVideoSegmentFetchTask.browsertest.ts +57 -0
  206. package/src/elements/EFMedia/videoTasks/makeVideoSegmentFetchTask.ts +32 -0
  207. package/src/elements/EFMedia/videoTasks/makeVideoSegmentIdTask.browsertest.ts +56 -0
  208. package/src/elements/EFMedia/videoTasks/makeVideoSegmentIdTask.ts +23 -0
  209. package/src/elements/EFMedia.browsertest.ts +696 -271
  210. package/src/elements/EFMedia.ts +218 -776
  211. package/src/elements/EFTemporal.browsertest.ts +0 -1
  212. package/src/elements/EFTemporal.ts +13 -3
  213. package/src/elements/EFTimegroup.browsertest.ts +6 -3
  214. package/src/elements/EFTimegroup.ts +221 -27
  215. package/src/elements/EFVideo.browsertest.ts +758 -0
  216. package/src/elements/EFVideo.ts +418 -68
  217. package/src/elements/EFWaveform.ts +5 -5
  218. package/src/elements/MediaController.ts +98 -0
  219. package/src/elements/SampleBuffer.ts +97 -0
  220. package/src/elements/printTaskStatus.ts +16 -0
  221. package/src/elements/updateAnimations.ts +6 -0
  222. package/src/gui/ContextMixin.ts +23 -104
  223. package/src/gui/TWMixin.ts +10 -3
  224. package/src/gui/services/ElementConnectionManager.browsertest.ts +263 -0
  225. package/src/gui/services/ElementConnectionManager.ts +224 -0
  226. package/src/gui/services/PlaybackController.browsertest.ts +437 -0
  227. package/src/gui/services/PlaybackController.ts +521 -0
  228. package/src/services/MediaSourceManager.ts +333 -0
  229. package/src/transcoding/cache/CacheManager.ts +208 -0
  230. package/src/transcoding/cache/RequestDeduplicator.test.ts +170 -0
  231. package/src/transcoding/cache/RequestDeduplicator.ts +65 -0
  232. package/src/transcoding/types/index.ts +265 -0
  233. package/src/transcoding/utils/MediaUtils.ts +63 -0
  234. package/src/transcoding/utils/UrlGenerator.ts +68 -0
  235. package/src/transcoding/utils/constants.ts +36 -0
  236. package/src/utils/LRUCache.ts +153 -0
  237. package/test/EFVideo.framegen.browsertest.ts +127 -0
  238. package/test/__cache__/GET__api_v1_transcode_audio_1_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__32da3954ba60c96ad732020c65a08ebc/data.bin +0 -0
  239. package/test/__cache__/GET__api_v1_transcode_audio_1_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__32da3954ba60c96ad732020c65a08ebc/metadata.json +21 -0
  240. package/test/__cache__/GET__api_v1_transcode_audio_2_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__b0b2b07efcf607de8ee0f650328c32f7/data.bin +0 -0
  241. package/test/__cache__/GET__api_v1_transcode_audio_2_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__b0b2b07efcf607de8ee0f650328c32f7/metadata.json +21 -0
  242. package/test/__cache__/GET__api_v1_transcode_audio_3_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__a75c2252b542e0c152c780e9a8d7b154/data.bin +0 -0
  243. package/test/__cache__/GET__api_v1_transcode_audio_3_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__a75c2252b542e0c152c780e9a8d7b154/metadata.json +21 -0
  244. package/test/__cache__/GET__api_v1_transcode_audio_4_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__a64ff1cfb1b52cae14df4b5dfa1e222b/data.bin +0 -0
  245. package/test/__cache__/GET__api_v1_transcode_audio_4_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__a64ff1cfb1b52cae14df4b5dfa1e222b/metadata.json +21 -0
  246. package/test/__cache__/GET__api_v1_transcode_audio_5_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__91e8a522f950809b9f09f4173113b4b0/data.bin +0 -0
  247. package/test/__cache__/GET__api_v1_transcode_audio_5_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__91e8a522f950809b9f09f4173113b4b0/metadata.json +21 -0
  248. package/test/__cache__/GET__api_v1_transcode_audio_init_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__e66d2c831d951e74ad0aeaa6489795d0/data.bin +0 -0
  249. package/test/__cache__/GET__api_v1_transcode_audio_init_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__e66d2c831d951e74ad0aeaa6489795d0/metadata.json +21 -0
  250. package/test/__cache__/GET__api_v1_transcode_high_1_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__26197f6f7c46cacb0a71134131c3f775/data.bin +0 -0
  251. package/test/__cache__/GET__api_v1_transcode_high_1_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__26197f6f7c46cacb0a71134131c3f775/metadata.json +21 -0
  252. package/test/__cache__/GET__api_v1_transcode_high_2_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__4cb6774cd3650ccf59c8f8dc6678c0b9/data.bin +0 -0
  253. package/test/__cache__/GET__api_v1_transcode_high_2_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__4cb6774cd3650ccf59c8f8dc6678c0b9/metadata.json +21 -0
  254. package/test/__cache__/GET__api_v1_transcode_high_3_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__0b3b2b1c8933f7fcf8a9ecaa88d58b41/data.bin +0 -0
  255. package/test/__cache__/GET__api_v1_transcode_high_3_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__0b3b2b1c8933f7fcf8a9ecaa88d58b41/metadata.json +21 -0
  256. package/test/__cache__/GET__api_v1_transcode_high_init_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__0798c479b44aaeef850609a430f6e613/data.bin +0 -0
  257. package/test/__cache__/GET__api_v1_transcode_high_init_m4s_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__0798c479b44aaeef850609a430f6e613/metadata.json +21 -0
  258. package/test/__cache__/GET__api_v1_transcode_manifest_json_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__3be92a0437de726b431ed5af2369158a/data.bin +1 -0
  259. package/test/__cache__/GET__api_v1_transcode_manifest_json_url_http_3A_2F_2Fweb_3A3000_2Fhead_moov_480p_mp4__3be92a0437de726b431ed5af2369158a/metadata.json +19 -0
  260. package/test/createJitTestClips.ts +425 -0
  261. package/test/recordReplayProxyPlugin.js +302 -0
  262. package/test/useAssetMSW.ts +49 -0
  263. package/test/useMSW.ts +44 -0
  264. package/types.json +1 -1
  265. package/dist/gui/TWMixin.css.js +0 -4
  266. /package/dist/elements/{TargetController.test.d.ts → TargetController.browsertest.d.ts} +0 -0
  267. /package/src/elements/{TargetController.test.ts → TargetController.browsertest.ts} +0 -0
@@ -1,13 +1,45 @@
1
1
  import { Task } from "@lit/task";
2
- import { css, html } from "lit";
3
- import { customElement } from "lit/decorators.js";
2
+ import debug from "debug";
3
+ import { css, html, type PropertyValueMap } from "lit";
4
+ import { customElement, property, state } from "lit/decorators.js";
4
5
  import { createRef, ref } from "lit/directives/ref.js";
5
6
 
7
+ import { DelayedLoadingState } from "../DelayedLoadingState.js";
6
8
  import { TWMixin } from "../gui/TWMixin.js";
9
+ import type { CacheStats, ScrubTrackManager } from "../ScrubTrackManager.js";
10
+ import { makeVideoBufferTask } from "./EFMedia/videoTasks/makeVideoBufferTask.ts";
11
+ import { makeVideoInitSegmentFetchTask } from "./EFMedia/videoTasks/makeVideoInitSegmentFetchTask.ts";
12
+ import { makeVideoInputTask } from "./EFMedia/videoTasks/makeVideoInputTask.ts";
13
+ import { makeVideoSeekTask } from "./EFMedia/videoTasks/makeVideoSeekTask.ts";
14
+ import { makeVideoSegmentFetchTask } from "./EFMedia/videoTasks/makeVideoSegmentFetchTask.ts";
15
+ import { makeVideoSegmentIdTask } from "./EFMedia/videoTasks/makeVideoSegmentIdTask.ts";
7
16
  import { EFMedia } from "./EFMedia.js";
8
17
 
18
+ // EF_FRAMEGEN is a global instance created in EF_FRAMEGEN.ts
19
+ declare global {
20
+ var EF_FRAMEGEN: import("../EF_FRAMEGEN.js").EFFramegen;
21
+ }
22
+
23
+ const log = debug("ef:elements:EFVideo");
24
+
25
+ interface LoadingState {
26
+ isLoading: boolean;
27
+ operation: "scrub-segment" | "video-segment" | "seeking" | "decoding" | null;
28
+ message: string;
29
+ }
30
+
9
31
  @customElement("ef-video")
10
32
  export class EFVideo extends TWMixin(EFMedia) {
33
+ static get observedAttributes() {
34
+ const parentAttributes = EFMedia.observedAttributes || [];
35
+ return [
36
+ ...parentAttributes,
37
+ "video-buffer-duration",
38
+ "max-video-buffer-fetches",
39
+ "enable-video-buffering",
40
+ ];
41
+ }
42
+
11
43
  static styles = [
12
44
  /**
13
45
  *
@@ -15,6 +47,7 @@ export class EFVideo extends TWMixin(EFMedia) {
15
47
  css`
16
48
  :host {
17
49
  display: block;
50
+ position: relative;
18
51
  }
19
52
  canvas {
20
53
  all: inherit;
@@ -29,12 +62,129 @@ export class EFVideo extends TWMixin(EFMedia) {
29
62
  outline: none;
30
63
  box-shadow: none;
31
64
  }
65
+ .loading-overlay {
66
+ position: absolute;
67
+ top: 0;
68
+ left: 0;
69
+ right: 0;
70
+ bottom: 0;
71
+ background: rgba(0, 0, 0, 0.6);
72
+ display: flex;
73
+ align-items: center;
74
+ justify-content: center;
75
+ z-index: 10;
76
+ backdrop-filter: blur(2px);
77
+ }
78
+ .loading-content {
79
+ background: rgba(0, 0, 0, 0.8);
80
+ border-radius: 8px;
81
+ padding: 16px 24px;
82
+ display: flex;
83
+ align-items: center;
84
+ gap: 12px;
85
+ color: white;
86
+ font-size: 14px;
87
+ font-weight: 500;
88
+ }
89
+ .loading-spinner {
90
+ width: 20px;
91
+ height: 20px;
92
+ border: 2px solid rgba(255, 255, 255, 0.2);
93
+ border-left: 2px solid #fff;
94
+ border-radius: 50%;
95
+ animation: spin 1s linear infinite;
96
+ }
97
+ @keyframes spin {
98
+ 0% { transform: rotate(0deg); }
99
+ 100% { transform: rotate(360deg); }
100
+ }
101
+ .loading-message {
102
+ font-size: 12px;
103
+ opacity: 0.8;
104
+ }
32
105
  `,
33
106
  ];
34
107
  canvasRef = createRef<HTMLCanvasElement>();
108
+
109
+ /**
110
+ * Duration in milliseconds for video buffering ahead of current time
111
+ * @domAttribute "video-buffer-duration"
112
+ */
113
+ @property({ type: Number, attribute: "video-buffer-duration" })
114
+ videoBufferDurationMs = 60000; // 60 seconds
115
+
116
+ /**
117
+ * Maximum number of concurrent video segment fetches for buffering
118
+ * @domAttribute "max-video-buffer-fetches"
119
+ */
120
+ @property({ type: Number, attribute: "max-video-buffer-fetches" })
121
+ maxVideoBufferFetches = 2;
122
+
123
+ /**
124
+ * Enable/disable video buffering system
125
+ * @domAttribute "enable-video-buffering"
126
+ */
127
+ @property({ type: Boolean, attribute: "enable-video-buffering" })
128
+ enableVideoBuffering = true;
129
+
130
+ // Video-specific tasks
131
+ videoSegmentIdTask = makeVideoSegmentIdTask(this);
132
+ videoInitSegmentFetchTask = makeVideoInitSegmentFetchTask(this);
133
+ videoSegmentFetchTask = makeVideoSegmentFetchTask(this);
134
+ videoInputTask = makeVideoInputTask(this);
135
+ videoSeekTask = makeVideoSeekTask(this);
136
+ videoBufferTask = makeVideoBufferTask(this);
137
+
138
+ /**
139
+ * Scrub track manager for fast timeline navigation
140
+ */
141
+ scrubTrackManager?: ScrubTrackManager;
142
+
143
+ /**
144
+ * Delayed loading state manager for user feedback
145
+ */
146
+ private delayedLoadingState: DelayedLoadingState;
147
+
148
+ /**
149
+ * Loading state for user feedback
150
+ */
151
+ @state()
152
+ loadingState = {
153
+ isLoading: false,
154
+ operation: null as LoadingState["operation"],
155
+ message: "",
156
+ };
157
+
158
+ constructor() {
159
+ super();
160
+
161
+ // Initialize delayed loading state with callback to update UI
162
+ this.delayedLoadingState = new DelayedLoadingState(
163
+ 250,
164
+ (isLoading, message) => {
165
+ this.setLoadingState(isLoading, null, message);
166
+ },
167
+ );
168
+ }
169
+
35
170
  render() {
36
171
  return html`
37
172
  <canvas ${ref(this.canvasRef)}></canvas>
173
+ ${
174
+ this.loadingState.isLoading
175
+ ? html`
176
+ <div class="loading-overlay">
177
+ <div class="loading-content">
178
+ <div class="loading-spinner"></div>
179
+ <div>
180
+ <div>Loading Video...</div>
181
+ <div class="loading-message">${this.loadingState.message}</div>
182
+ </div>
183
+ </div>
184
+ </div>
185
+ `
186
+ : ""
187
+ }
38
188
  `;
39
189
  }
40
190
 
@@ -42,89 +192,289 @@ export class EFVideo extends TWMixin(EFMedia) {
42
192
  return this.canvasRef.value;
43
193
  }
44
194
 
45
- // The underlying video decoder MUST NOT be used concurrently.
46
- // If frames are fed in out of order, the decoder may crash.
47
- #decoderLock = false;
48
-
49
195
  frameTask = new Task(this, {
50
- args: () =>
51
- [
52
- this.trackFragmentIndexLoader.status,
53
- this.initSegmentsLoader.status,
54
- this.seekTask.status,
55
- this.fetchSeekTask.status,
56
- this.videoAssetTask.status,
57
- this.paintTask.status,
58
- ] as const,
59
- task: async () => {
60
- await this.trackFragmentIndexLoader.taskComplete;
61
- await this.initSegmentsLoader.taskComplete;
62
- await this.seekTask.taskComplete;
63
- await this.fetchSeekTask.taskComplete;
64
- await this.videoAssetTask.taskComplete;
196
+ args: () => [this.desiredSeekTimeMs] as const,
197
+ onError: (error) => {
198
+ console.error("frameTask error", error);
199
+ },
200
+ onComplete: () => {},
201
+ task: async ([_desiredSeekTimeMs], { signal }) => {
202
+ await this.videoSeekTask.taskComplete;
65
203
  await this.paintTask.taskComplete;
204
+ if (signal.aborted) {
205
+ return;
206
+ }
66
207
  },
67
208
  });
68
209
 
210
+ protected updated(
211
+ changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>,
212
+ ): void {
213
+ super.updated(changedProperties);
214
+ }
215
+
216
+ /**
217
+ * Start a delayed loading operation for testing
218
+ */
219
+ startDelayedLoading(
220
+ operationId: string,
221
+ message: string,
222
+ options: { background?: boolean } = {},
223
+ ): void {
224
+ this.delayedLoadingState.startLoading(operationId, message, options);
225
+ }
226
+
227
+ /**
228
+ * Clear a delayed loading operation for testing
229
+ */
230
+ clearDelayedLoading(operationId: string): void {
231
+ this.delayedLoadingState.clearLoading(operationId);
232
+ }
233
+
234
+ /**
235
+ * Set loading state for user feedback
236
+ */
237
+ private setLoadingState(
238
+ isLoading: boolean,
239
+ operation: LoadingState["operation"] = null,
240
+ message = "",
241
+ ): void {
242
+ this.loadingState = {
243
+ isLoading,
244
+ operation,
245
+ message,
246
+ };
247
+ }
248
+
69
249
  paintTask = new Task(this, {
70
- args: () => [this.videoAssetTask.value, this.desiredSeekTimeMs] as const,
71
- task: async (
72
- [videoAsset, seekToMs],
73
- {
74
- signal:
75
- _signal /** Aborting seeks is counter-productive. It is better to drop seeks. */,
76
- },
77
- ) => {
78
- if (!videoAsset) {
79
- return;
80
- }
81
- if (this.#decoderLock) {
82
- return;
250
+ args: () => [this.desiredSeekTimeMs] as const,
251
+ onError: (error) => {
252
+ console.error("paintTask error", error);
253
+ },
254
+ onComplete: () => {},
255
+ task: async ([_seekToMs], { signal }) => {
256
+ await this.videoSeekTask.taskComplete;
257
+ // Check if we're in production rendering mode vs preview mode
258
+ const isProductionRendering = this.isInProductionRenderingMode();
259
+
260
+ const sample = this.videoSeekTask.value;
261
+ if (sample) {
262
+ const videoFrame = sample.toVideoFrame();
263
+ this.displayFrame(videoFrame, _seekToMs);
264
+ videoFrame.close();
83
265
  }
84
- try {
85
- this.#decoderLock = true;
86
- const frame = await videoAsset.seekToTime(seekToMs / 1000);
87
266
 
88
- if (!this.canvasElement) {
89
- return;
267
+ // EF_FRAMEGEN-aware rendering mode detection
268
+ if (!isProductionRendering) {
269
+ // Preview mode: skip rendering during initialization to prevent artifacts
270
+ if (
271
+ !this.rootTimegroup ||
272
+ (this.rootTimegroup.currentTimeMs === 0 &&
273
+ this.desiredSeekTimeMs === 0)
274
+ ) {
275
+ return; // Skip initialization frame in preview mode
90
276
  }
91
- const ctx = this.canvasElement.getContext("2d");
92
- if (!(frame && ctx)) {
277
+ // Preview mode: proceed with rendering
278
+ } else {
279
+ // Production rendering mode: only render when EF_FRAMEGEN has explicitly started frame rendering
280
+ // This prevents initialization frames before the actual render sequence begins
281
+ if (!this.rootTimegroup) {
93
282
  return;
94
283
  }
95
284
 
96
- if (frame?.codedWidth && frame?.codedHeight) {
97
- if (
98
- this.canvasElement.width !== frame.codedWidth ||
99
- this.canvasElement.height !== frame.codedHeight
100
- ) {
101
- this.canvasElement.width = frame.codedWidth;
102
- this.canvasElement.height = frame.codedHeight;
103
- }
285
+ if (!this.isFrameRenderingActive()) {
286
+ return; // Wait for EF_FRAMEGEN to start frame sequence
104
287
  }
105
288
 
106
- if (frame.format === null) {
107
- console.warn("Frame format is null", frame);
108
- return seekToMs;
109
- }
110
- ctx.drawImage(
111
- frame,
112
- 0,
113
- 0,
114
- this.canvasElement.width,
115
- this.canvasElement.height,
116
- );
117
-
118
- return seekToMs;
119
- } catch (error) {
120
- console.trace("Unexpected error while seeking video", error);
121
- // As a practical matter, we should probably just re-create the VideoAsset if decoding fails.
122
- // The decoder is probably in an invalid state anyway.
123
- } finally {
124
- this.#decoderLock = false;
289
+ // Production mode: EF_FRAMEGEN has started frame sequence, proceed with rendering
290
+ }
291
+
292
+ if (signal.aborted) {
293
+ return;
125
294
  }
126
295
  },
127
296
  });
297
+
298
+ /**
299
+ * Display a video frame on the canvas
300
+ */
301
+ private displayFrame(frame: VideoFrame, seekToMs: number): number {
302
+ log("trace: displayFrame start", { seekToMs, frameFormat: frame.format });
303
+ if (!this.canvasElement) {
304
+ log("trace: displayFrame aborted - no canvas element");
305
+ throw new Error(
306
+ `Frame display failed: Canvas element is not available at time ${seekToMs}ms. The video component may not be properly initialized.`,
307
+ );
308
+ }
309
+
310
+ const ctx = this.canvasElement.getContext("2d");
311
+ if (!ctx) {
312
+ log("trace: displayFrame aborted - no canvas context");
313
+ throw new Error(
314
+ `Frame display failed: Unable to get 2D canvas context at time ${seekToMs}ms. This may indicate a browser compatibility issue or canvas corruption.`,
315
+ );
316
+ }
317
+
318
+ if (frame?.codedWidth && frame?.codedHeight) {
319
+ if (
320
+ this.canvasElement.width !== frame.codedWidth ||
321
+ this.canvasElement.height !== frame.codedHeight
322
+ ) {
323
+ log("trace: updating canvas dimensions", {
324
+ width: frame.codedWidth,
325
+ height: frame.codedHeight,
326
+ });
327
+ this.canvasElement.width = frame.codedWidth;
328
+ this.canvasElement.height = frame.codedHeight;
329
+ }
330
+ }
331
+
332
+ if (frame.format === null) {
333
+ log("trace: displayFrame aborted - null frame format");
334
+ throw new Error(
335
+ `Frame display failed: Video frame has null format at time ${seekToMs}ms. This indicates corrupted or incompatible video data.`,
336
+ );
337
+ }
338
+
339
+ log("trace: drawing frame to canvas", frame.timestamp / 1000);
340
+ ctx.drawImage(
341
+ frame,
342
+ 0,
343
+ 0,
344
+ this.canvasElement.width,
345
+ this.canvasElement.height,
346
+ );
347
+ log("trace: frame drawn to canvas", { seekToMs });
348
+
349
+ return seekToMs;
350
+ }
351
+
352
+ /**
353
+ * Check if we're in production rendering mode (EF_FRAMEGEN active) vs preview mode
354
+ */
355
+ private isInProductionRenderingMode(): boolean {
356
+ // Check if EF_RENDERING function exists and returns true (production rendering)
357
+ if (typeof window.EF_RENDERING === "function") {
358
+ return window.EF_RENDERING();
359
+ }
360
+
361
+ // Check if workbench is in rendering mode
362
+ const workbench = document.querySelector("ef-workbench") as any;
363
+ if (workbench?.rendering) {
364
+ return true;
365
+ }
366
+
367
+ // Check if EF_FRAMEGEN exists and has render options (indicates active rendering)
368
+ if (window.EF_FRAMEGEN?.renderOptions) {
369
+ return true;
370
+ }
371
+
372
+ // Default to preview mode
373
+ return false;
374
+ }
375
+
376
+ /**
377
+ * Check if EF_FRAMEGEN has explicitly started frame rendering (not just initialization)
378
+ */
379
+ private isFrameRenderingActive(): boolean {
380
+ if (!window.EF_FRAMEGEN?.renderOptions) {
381
+ return false;
382
+ }
383
+
384
+ // In production mode, only render when EF_FRAMEGEN has actually begun frame sequence
385
+ // Check if we're past the initialization phase by looking for explicit frame control
386
+ const renderOptions = window.EF_FRAMEGEN.renderOptions;
387
+ const renderStartTime = renderOptions.encoderOptions.fromMs;
388
+ const currentTime = this.rootTimegroup?.currentTimeMs || 0;
389
+
390
+ // We're in active frame rendering if:
391
+ // 1. currentTime >= renderStartTime (includes the starting frame)
392
+ return currentTime >= renderStartTime;
393
+ }
394
+
395
+ /**
396
+ * Get scrub track performance statistics
397
+ */
398
+ getScrubTrackStats(): CacheStats | null {
399
+ return this.scrubTrackManager?.getCacheStats() || null;
400
+ }
401
+
402
+ // Getter properties for backward compatibility with tests
403
+ /**
404
+ * Effective mode - always returns "asset" for EFVideo
405
+ */
406
+ get effectiveMode(): string {
407
+ return "asset";
408
+ }
409
+
410
+ /**
411
+ * Legacy getter for asset index loader (maps to mediaEngine task)
412
+ */
413
+ get assetIndexLoader() {
414
+ return this.mediaEngineTask;
415
+ }
416
+
417
+ /**
418
+ * Legacy getter for fragment index task (maps to videoSegmentIdTask)
419
+ */
420
+ get fragmentIndexTask() {
421
+ return this.videoSegmentIdTask;
422
+ }
423
+
424
+ /**
425
+ * Legacy getter for seek task (maps to videoSeekTask)
426
+ */
427
+ get seekTask() {
428
+ return this.videoSeekTask;
429
+ }
430
+
431
+ /**
432
+ * Legacy getter for media segments task (maps to videoSegmentFetchTask)
433
+ */
434
+ get mediaSegmentsTask() {
435
+ return this.videoSegmentFetchTask;
436
+ }
437
+
438
+ /**
439
+ * Legacy getter for asset segment keys task (maps to videoSegmentIdTask)
440
+ */
441
+ get assetSegmentKeysTask() {
442
+ return this.videoSegmentIdTask;
443
+ }
444
+
445
+ /**
446
+ * Legacy getter for asset init segments task (maps to videoInitSegmentFetchTask)
447
+ */
448
+ get assetInitSegmentsTask() {
449
+ return this.videoInitSegmentFetchTask;
450
+ }
451
+
452
+ /**
453
+ * Legacy getter for asset segment loader (maps to videoSegmentFetchTask)
454
+ */
455
+ get assetSegmentLoader() {
456
+ return this.videoSegmentFetchTask;
457
+ }
458
+
459
+ /**
460
+ * Legacy getter for video asset task (maps to videoBufferTask)
461
+ */
462
+ get videoAssetTask() {
463
+ return this.videoBufferTask;
464
+ }
465
+
466
+ /**
467
+ * Clean up resources when component is disconnected
468
+ */
469
+ disconnectedCallback(): void {
470
+ super.disconnectedCallback();
471
+
472
+ // Clean up scrub track manager
473
+ this.scrubTrackManager?.cleanup();
474
+
475
+ // Clean up delayed loading state
476
+ this.delayedLoadingState.clearAllLoading();
477
+ }
128
478
  }
129
479
 
130
480
  declare global {
@@ -1,8 +1,8 @@
1
1
  import { CSSStyleObserver } from "@bramus/style-observer";
2
2
  import { Task } from "@lit/task";
3
- import { LitElement, type PropertyValueMap, css, html } from "lit";
3
+ import { css, html, LitElement, type PropertyValueMap } from "lit";
4
4
  import { customElement, property, state } from "lit/decorators.js";
5
- import { type Ref, createRef, ref } from "lit/directives/ref.js";
5
+ import { createRef, type Ref, ref } from "lit/directives/ref.js";
6
6
  import { EF_INTERACTIVE } from "../EF_INTERACTIVE.js";
7
7
  import { EF_RENDERING } from "../EF_RENDERING.js";
8
8
  import { TWMixin } from "../gui/TWMixin.js";
@@ -16,8 +16,8 @@ import { TargetController } from "./TargetController.ts";
16
16
  export class EFWaveform extends EFTemporal(TWMixin(LitElement)) {
17
17
  static styles = css`
18
18
  :host {
19
- display: block;
20
19
  all: inherit;
20
+ display: block;
21
21
  position: relative;
22
22
  }
23
23
 
@@ -38,7 +38,7 @@ export class EFWaveform extends EFTemporal(TWMixin(LitElement)) {
38
38
  private mutationObserver?: MutationObserver;
39
39
 
40
40
  render() {
41
- return html`<canvas ${ref(this.canvasRef)}></canvas>`;
41
+ return html`<canvas ${ref(this.canvasRef)}></canvas><div class="text-5xl inline-block bg-red-500">`;
42
42
  }
43
43
 
44
44
  @property({
@@ -78,7 +78,7 @@ export class EFWaveform extends EFTemporal(TWMixin(LitElement)) {
78
78
  if (this.targetElement) {
79
79
  new CrossUpdateController(this.targetElement, this);
80
80
  }
81
- } catch (e) {
81
+ } catch (_error) {
82
82
  // TODO: determine if this is a critical error, or if we should just ignore it
83
83
  // currenty evidence suggests everything still works
84
84
  // no target element, no cross update controller
@@ -0,0 +1,98 @@
1
+ import type { ReactiveController, ReactiveControllerHost } from "lit";
2
+
3
+ export class MediaController implements ReactiveController {
4
+ #src: string | null = null;
5
+ #assetId: string | null = null;
6
+
7
+ constructor(
8
+ private host: ReactiveControllerHost & {
9
+ src: string;
10
+ assetId: string | null;
11
+ mode: "asset" | "jit-transcode" | "auto";
12
+ },
13
+ ) {
14
+ this.host.addController(this);
15
+ }
16
+
17
+ get mode() {
18
+ const actualMode = this.host.mode;
19
+ if (actualMode === "asset" || actualMode === "jit-transcode") {
20
+ return actualMode;
21
+ }
22
+
23
+ if (this.host.assetId) {
24
+ return "asset";
25
+ }
26
+
27
+ if (!this.host.src) {
28
+ return "asset";
29
+ }
30
+
31
+ return "asset";
32
+ }
33
+
34
+ get src() {
35
+ return this.#src;
36
+ }
37
+
38
+ set src(value: string | null) {
39
+ if (this.#src !== value) {
40
+ this.trackUpdate("src", this.#src, value);
41
+ this.#src = value;
42
+ }
43
+ }
44
+
45
+ get assetId() {
46
+ return this.#assetId;
47
+ }
48
+ set assetId(value: string | null) {
49
+ if (this.#assetId !== value) {
50
+ this.trackUpdate("assetId", this.#assetId, value);
51
+ this.#assetId = value;
52
+ }
53
+ }
54
+
55
+ changes: Map<string, { oldValue: any; newValue: any }> | null = null;
56
+ updatePending = false;
57
+
58
+ trackUpdate(key: string, oldValue: any, newValue: any) {
59
+ this.changes ??= new Map<string, { oldValue: any; newValue: any }>();
60
+ this.changes.set(key, { oldValue, newValue });
61
+ if (!this.updatePending) {
62
+ this.updatePending = true;
63
+ queueMicrotask(() => {
64
+ this.endUpdate();
65
+ });
66
+ }
67
+ }
68
+
69
+ endUpdate() {
70
+ try {
71
+ if (this.changes) {
72
+ this.handleUpdate(this.changes);
73
+ }
74
+ } finally {
75
+ this.changes = null;
76
+ this.updatePending = false;
77
+ }
78
+ }
79
+
80
+ handleUpdate(changes: Map<string, { oldValue: any; newValue: any }>) {
81
+ if (changes.has("src") || changes.has("assetId") || changes.has("mode")) {
82
+ }
83
+ }
84
+
85
+ hostUpdated(): void {
86
+ this.src = this.host.src;
87
+ this.assetId = this.host.assetId;
88
+ }
89
+
90
+ hostConnected() {
91
+ this.src = this.host.src;
92
+ this.assetId = this.host.assetId;
93
+ }
94
+
95
+ hostDisconnected() {}
96
+
97
+ updated() {}
98
+ }