@editframe/elements 0.20.4-beta.0 → 0.21.0-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 (92) hide show
  1. package/dist/DelayedLoadingState.js +0 -27
  2. package/dist/EF_FRAMEGEN.d.ts +5 -3
  3. package/dist/EF_FRAMEGEN.js +50 -11
  4. package/dist/_virtual/_@oxc-project_runtime@0.93.0/helpers/decorate.js +7 -0
  5. package/dist/elements/ContextProxiesController.js +2 -22
  6. package/dist/elements/EFAudio.js +4 -8
  7. package/dist/elements/EFCaptions.js +59 -84
  8. package/dist/elements/EFImage.js +5 -6
  9. package/dist/elements/EFMedia/AssetIdMediaEngine.js +2 -4
  10. package/dist/elements/EFMedia/AssetMediaEngine.js +35 -30
  11. package/dist/elements/EFMedia/BaseMediaEngine.js +57 -73
  12. package/dist/elements/EFMedia/BufferedSeekingInput.js +134 -76
  13. package/dist/elements/EFMedia/JitMediaEngine.js +9 -19
  14. package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.js +3 -6
  15. package/dist/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.js +1 -1
  16. package/dist/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.js +1 -1
  17. package/dist/elements/EFMedia/audioTasks/makeAudioInputTask.js +6 -5
  18. package/dist/elements/EFMedia/audioTasks/makeAudioSeekTask.js +1 -3
  19. package/dist/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.js +1 -1
  20. package/dist/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.js +1 -1
  21. package/dist/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.js +1 -1
  22. package/dist/elements/EFMedia/shared/AudioSpanUtils.js +4 -16
  23. package/dist/elements/EFMedia/shared/BufferUtils.js +2 -15
  24. package/dist/elements/EFMedia/shared/GlobalInputCache.js +0 -24
  25. package/dist/elements/EFMedia/shared/PrecisionUtils.js +0 -21
  26. package/dist/elements/EFMedia/shared/ThumbnailExtractor.js +0 -17
  27. package/dist/elements/EFMedia/tasks/makeMediaEngineTask.js +1 -10
  28. package/dist/elements/EFMedia/videoTasks/MainVideoInputCache.d.ts +29 -0
  29. package/dist/elements/EFMedia/videoTasks/MainVideoInputCache.js +32 -0
  30. package/dist/elements/EFMedia/videoTasks/ScrubInputCache.js +1 -15
  31. package/dist/elements/EFMedia/videoTasks/makeScrubVideoBufferTask.js +1 -7
  32. package/dist/elements/EFMedia/videoTasks/makeScrubVideoInputTask.js +8 -5
  33. package/dist/elements/EFMedia/videoTasks/makeScrubVideoSeekTask.js +12 -13
  34. package/dist/elements/EFMedia/videoTasks/makeScrubVideoSegmentIdTask.js +1 -1
  35. package/dist/elements/EFMedia/videoTasks/makeUnifiedVideoSeekTask.js +134 -70
  36. package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.js +7 -11
  37. package/dist/elements/EFMedia.js +26 -24
  38. package/dist/elements/EFSourceMixin.js +5 -7
  39. package/dist/elements/EFSurface.js +6 -9
  40. package/dist/elements/EFTemporal.js +19 -37
  41. package/dist/elements/EFThumbnailStrip.js +16 -59
  42. package/dist/elements/EFTimegroup.js +95 -90
  43. package/dist/elements/EFVideo.d.ts +6 -2
  44. package/dist/elements/EFVideo.js +142 -107
  45. package/dist/elements/EFWaveform.js +18 -27
  46. package/dist/elements/SampleBuffer.js +2 -5
  47. package/dist/elements/TargetController.js +3 -3
  48. package/dist/elements/durationConverter.js +4 -4
  49. package/dist/elements/updateAnimations.js +14 -35
  50. package/dist/gui/ContextMixin.js +23 -52
  51. package/dist/gui/EFConfiguration.js +7 -7
  52. package/dist/gui/EFControls.js +5 -5
  53. package/dist/gui/EFFilmstrip.js +77 -98
  54. package/dist/gui/EFFitScale.js +5 -6
  55. package/dist/gui/EFFocusOverlay.js +4 -4
  56. package/dist/gui/EFPreview.js +4 -4
  57. package/dist/gui/EFScrubber.js +9 -9
  58. package/dist/gui/EFTimeDisplay.js +5 -5
  59. package/dist/gui/EFToggleLoop.js +4 -4
  60. package/dist/gui/EFTogglePlay.js +5 -5
  61. package/dist/gui/EFWorkbench.js +5 -5
  62. package/dist/gui/TWMixin2.js +1 -1
  63. package/dist/index.d.ts +1 -0
  64. package/dist/otel/BridgeSpanExporter.d.ts +13 -0
  65. package/dist/otel/BridgeSpanExporter.js +87 -0
  66. package/dist/otel/setupBrowserTracing.d.ts +12 -0
  67. package/dist/otel/setupBrowserTracing.js +30 -0
  68. package/dist/otel/tracingHelpers.d.ts +34 -0
  69. package/dist/otel/tracingHelpers.js +113 -0
  70. package/dist/transcoding/cache/RequestDeduplicator.js +0 -21
  71. package/dist/transcoding/cache/URLTokenDeduplicator.js +1 -21
  72. package/dist/transcoding/utils/UrlGenerator.js +2 -19
  73. package/dist/utils/LRUCache.js +6 -53
  74. package/package.json +10 -2
  75. package/src/elements/EFCaptions.browsertest.ts +2 -0
  76. package/src/elements/EFMedia/AssetMediaEngine.ts +65 -37
  77. package/src/elements/EFMedia/BaseMediaEngine.ts +110 -52
  78. package/src/elements/EFMedia/BufferedSeekingInput.ts +218 -101
  79. package/src/elements/EFMedia/audioTasks/makeAudioInputTask.ts +7 -3
  80. package/src/elements/EFMedia/videoTasks/MainVideoInputCache.ts +76 -0
  81. package/src/elements/EFMedia/videoTasks/makeScrubVideoInputTask.ts +16 -10
  82. package/src/elements/EFMedia/videoTasks/makeScrubVideoSeekTask.ts +7 -1
  83. package/src/elements/EFMedia/videoTasks/makeUnifiedVideoSeekTask.ts +222 -116
  84. package/src/elements/EFMedia.ts +16 -1
  85. package/src/elements/EFTimegroup.browsertest.ts +10 -8
  86. package/src/elements/EFTimegroup.ts +164 -76
  87. package/src/elements/EFVideo.browsertest.ts +19 -27
  88. package/src/elements/EFVideo.ts +203 -101
  89. package/src/otel/BridgeSpanExporter.ts +150 -0
  90. package/src/otel/setupBrowserTracing.ts +68 -0
  91. package/src/otel/tracingHelpers.ts +251 -0
  92. package/types.json +1 -1
@@ -2,6 +2,7 @@ import { EF_RENDERING } from "../EF_RENDERING.js";
2
2
  import { globalURLTokenDeduplicator } from "../transcoding/cache/URLTokenDeduplicator.js";
3
3
  import { currentTimeContext } from "./currentTimeContext.js";
4
4
  import { durationContext } from "./durationContext.js";
5
+ import { __decorate } from "../_virtual/_@oxc-project_runtime@0.93.0/helpers/decorate.js";
5
6
  import { efConfigurationContext } from "./EFConfiguration.js";
6
7
  import { efContext } from "./efContext.js";
7
8
  import { fetchContext } from "./fetchContext.js";
@@ -10,9 +11,8 @@ import { focusedElementContext } from "./focusedElementContext.js";
10
11
  import { loopContext, playingContext } from "./playingContext.js";
11
12
  import { consume, createContext, provide } from "@lit/context";
12
13
  import { property, state } from "lit/decorators.js";
13
- import _decorate from "@oxc-project/runtime/helpers/decorate";
14
14
  const targetTimegroupContext = createContext("target-timegroup");
15
- const contextMixinSymbol = Symbol("contextMixin");
15
+ var contextMixinSymbol = Symbol("contextMixin");
16
16
  function isContextMixin(value) {
17
17
  return typeof value === "object" && value !== null && contextMixinSymbol in value.constructor;
18
18
  }
@@ -37,10 +37,7 @@ function ContextMixin(superClass) {
37
37
  method: "POST",
38
38
  body: JSON.stringify(signingPayload)
39
39
  });
40
- if (response.ok) {
41
- const tokenData = await response.json();
42
- return tokenData.token;
43
- }
40
+ if (response.ok) return (await response.json()).token;
44
41
  throw new Error(`Failed to sign URL: ${url}. SigningURL: ${this.signingURL} ${response.status} ${response.statusText}`);
45
42
  } catch (error) {
46
43
  console.error("ContextMixin urlToken fetch error", url, error);
@@ -71,15 +68,6 @@ function ContextMixin(superClass) {
71
68
  set apiHost(value) {
72
69
  this.#apiHost = value;
73
70
  }
74
- /**
75
- * Generate a cache key for URL token based on signing strategy
76
- *
77
- * Uses unified prefix + parameter matching approach:
78
- * - For transcode URLs: signs base "/api/v1/transcode" + params like {url: "source.mp4"}
79
- * - For regular URLs: signs full URL with empty params {}
80
- * - All validation uses prefix matching + exhaustive parameter matching
81
- * - Multiple transcode segments with same source share one token (reduces round-trips)
82
- */
83
71
  #getTokenCacheKey(url) {
84
72
  try {
85
73
  const urlObj = new URL(url);
@@ -87,9 +75,8 @@ function ContextMixin(superClass) {
87
75
  const urlParam = urlObj.searchParams.get("url");
88
76
  if (urlParam) {
89
77
  const basePath = `${urlObj.origin}/api/v1/transcode`;
90
- const cacheKey = `${basePath}?url=${urlParam}`;
91
78
  return {
92
- cacheKey,
79
+ cacheKey: `${basePath}?url=${urlParam}`,
93
80
  signingPayload: {
94
81
  url: basePath,
95
82
  params: { url: urlParam }
@@ -108,11 +95,6 @@ function ContextMixin(superClass) {
108
95
  };
109
96
  }
110
97
  }
111
- /**
112
- * Parse JWT token to extract safe expiration time (with buffer)
113
- * @param token JWT token string
114
- * @returns Safe expiration timestamp in milliseconds (actual expiry minus buffer), or 0 if parsing fails
115
- */
116
98
  #parseTokenExpiration(token) {
117
99
  try {
118
100
  const parts = token.split(".");
@@ -124,20 +106,14 @@ function ContextMixin(superClass) {
124
106
  const exp = parsed.exp;
125
107
  const iat = parsed.iat;
126
108
  if (!exp) return 0;
127
- const lifetimeSeconds = iat ? exp - iat : 3600;
128
- const tenPercentBufferMs = lifetimeSeconds * .1 * 1e3;
129
- const fiveMinutesMs = 5 * 60 * 1e3;
130
- const bufferMs = Math.min(fiveMinutesMs, tenPercentBufferMs);
109
+ const tenPercentBufferMs = (iat ? exp - iat : 3600) * .1 * 1e3;
110
+ const bufferMs = Math.min(300 * 1e3, tenPercentBufferMs);
131
111
  return exp * 1e3 - bufferMs;
132
112
  } catch {
133
113
  return 0;
134
114
  }
135
115
  }
136
116
  #signingURL;
137
- /**
138
- * A URL that will be used to generated signed tokens for accessing media files from the
139
- * editframe API. This is used to authenticate media requests per-user.
140
- */
141
117
  get signingURL() {
142
118
  return this.#signingURL ?? this.efConfiguration?.signingURL ?? "";
143
119
  }
@@ -155,15 +131,14 @@ function ContextMixin(superClass) {
155
131
  shouldUpdate = true;
156
132
  } else if (mutation.target instanceof Element && (mutation.target.tagName === "EF-TIMEGROUP" || mutation.target.closest("ef-timegroup"))) shouldUpdate = true;
157
133
  } else if (mutation.type === "attributes") {
158
- const durationAffectingAttributes = [
134
+ if ([
159
135
  "duration",
160
136
  "mode",
161
137
  "trimstart",
162
138
  "trimend",
163
139
  "sourcein",
164
140
  "sourceout"
165
- ];
166
- if (durationAffectingAttributes.includes(mutation.attributeName || "") || mutation.target instanceof Element && (mutation.target.tagName === "EF-TIMEGROUP" || mutation.target.tagName === "EF-VIDEO" || mutation.target.tagName === "EF-AUDIO" || mutation.target.tagName === "EF-CAPTIONS" || mutation.target.closest("ef-timegroup"))) shouldUpdate = true;
141
+ ].includes(mutation.attributeName || "") || mutation.target instanceof Element && (mutation.target.tagName === "EF-TIMEGROUP" || mutation.target.tagName === "EF-VIDEO" || mutation.target.tagName === "EF-AUDIO" || mutation.target.tagName === "EF-CAPTIONS" || mutation.target.closest("ef-timegroup"))) shouldUpdate = true;
167
142
  }
168
143
  if (shouldUpdate) queueMicrotask(() => {
169
144
  this.updateDurationProperties();
@@ -171,9 +146,6 @@ function ContextMixin(superClass) {
171
146
  if (this.targetTimegroup) this.targetTimegroup.requestUpdate();
172
147
  });
173
148
  });
174
- /**
175
- * Update duration properties when timegroup changes
176
- */
177
149
  updateDurationProperties() {
178
150
  const newDuration = this.targetTimegroup?.durationMs ?? 0;
179
151
  const newEndTime = this.targetTimegroup?.endTimeMs ?? 0;
@@ -259,8 +231,7 @@ function ContextMixin(superClass) {
259
231
  await playbackContext.suspend();
260
232
  const fillBuffer = async () => {
261
233
  if (bufferCount > 2) return;
262
- const canFillBuffer = await queueBufferSource();
263
- if (canFillBuffer) fillBuffer();
234
+ if (await queueBufferSource()) fillBuffer();
264
235
  };
265
236
  const queueBufferSource = async () => {
266
237
  if (currentMs >= toMs) return false;
@@ -291,35 +262,35 @@ function ContextMixin(superClass) {
291
262
  await playbackContext.resume();
292
263
  }
293
264
  }
294
- _decorate([consume({
265
+ __decorate([consume({
295
266
  context: efConfigurationContext,
296
267
  subscribe: true
297
268
  })], ContextElement.prototype, "efConfiguration", void 0);
298
- _decorate([provide({ context: focusContext })], ContextElement.prototype, "focusContext", void 0);
299
- _decorate([provide({ context: focusedElementContext }), state()], ContextElement.prototype, "focusedElement", void 0);
300
- _decorate([property({
269
+ __decorate([provide({ context: focusContext })], ContextElement.prototype, "focusContext", void 0);
270
+ __decorate([provide({ context: focusedElementContext }), state()], ContextElement.prototype, "focusedElement", void 0);
271
+ __decorate([property({
301
272
  type: String,
302
273
  attribute: "api-host"
303
274
  })], ContextElement.prototype, "apiHost", null);
304
- _decorate([provide({ context: efContext })], ContextElement.prototype, "efContext", void 0);
305
- _decorate([provide({ context: targetTimegroupContext }), state()], ContextElement.prototype, "targetTimegroup", void 0);
306
- _decorate([provide({ context: durationContext }), property({ type: Number })], ContextElement.prototype, "durationMs", void 0);
307
- _decorate([property({ type: Number })], ContextElement.prototype, "endTimeMs", void 0);
308
- _decorate([provide({ context: fetchContext })], ContextElement.prototype, "fetch", void 0);
309
- _decorate([property({
275
+ __decorate([provide({ context: efContext })], ContextElement.prototype, "efContext", void 0);
276
+ __decorate([provide({ context: targetTimegroupContext }), state()], ContextElement.prototype, "targetTimegroup", void 0);
277
+ __decorate([provide({ context: durationContext }), property({ type: Number })], ContextElement.prototype, "durationMs", void 0);
278
+ __decorate([property({ type: Number })], ContextElement.prototype, "endTimeMs", void 0);
279
+ __decorate([provide({ context: fetchContext })], ContextElement.prototype, "fetch", void 0);
280
+ __decorate([property({
310
281
  type: String,
311
282
  attribute: "signing-url"
312
283
  })], ContextElement.prototype, "signingURL", null);
313
- _decorate([provide({ context: playingContext }), property({
284
+ __decorate([provide({ context: playingContext }), property({
314
285
  type: Boolean,
315
286
  reflect: true
316
287
  })], ContextElement.prototype, "playing", void 0);
317
- _decorate([provide({ context: loopContext }), property({
288
+ __decorate([provide({ context: loopContext }), property({
318
289
  type: Boolean,
319
290
  reflect: true
320
291
  })], ContextElement.prototype, "loop", void 0);
321
- _decorate([property({ type: Boolean })], ContextElement.prototype, "rendering", void 0);
322
- _decorate([provide({ context: currentTimeContext }), property({ type: Number })], ContextElement.prototype, "currentTimeMs", void 0);
292
+ __decorate([property({ type: Boolean })], ContextElement.prototype, "rendering", void 0);
293
+ __decorate([provide({ context: currentTimeContext }), property({ type: Number })], ContextElement.prototype, "currentTimeMs", void 0);
323
294
  return ContextElement;
324
295
  }
325
296
  export { ContextMixin, isContextMixin, targetTimegroupContext };
@@ -1,9 +1,9 @@
1
+ import { __decorate } from "../_virtual/_@oxc-project_runtime@0.93.0/helpers/decorate.js";
1
2
  import { createContext, provide } from "@lit/context";
2
3
  import { LitElement, css, html } from "lit";
3
4
  import { customElement, property } from "lit/decorators.js";
4
- import _decorate from "@oxc-project/runtime/helpers/decorate";
5
5
  const efConfigurationContext = createContext(Symbol("efConfigurationContext"));
6
- let EFConfiguration = class EFConfiguration$1 extends LitElement {
6
+ var EFConfiguration = class EFConfiguration$1 extends LitElement {
7
7
  constructor(..._args) {
8
8
  super(..._args);
9
9
  this.efConfiguration = this;
@@ -21,18 +21,18 @@ let EFConfiguration = class EFConfiguration$1 extends LitElement {
21
21
  return html`<slot></slot>`;
22
22
  }
23
23
  };
24
- _decorate([provide({ context: efConfigurationContext })], EFConfiguration.prototype, "efConfiguration", void 0);
25
- _decorate([property({
24
+ __decorate([provide({ context: efConfigurationContext })], EFConfiguration.prototype, "efConfiguration", void 0);
25
+ __decorate([property({
26
26
  type: String,
27
27
  attribute: "api-host"
28
28
  })], EFConfiguration.prototype, "apiHost", void 0);
29
- _decorate([property({
29
+ __decorate([property({
30
30
  type: String,
31
31
  attribute: "signing-url"
32
32
  })], EFConfiguration.prototype, "signingURL", void 0);
33
- _decorate([property({
33
+ __decorate([property({
34
34
  type: String,
35
35
  attribute: "media-engine"
36
36
  })], EFConfiguration.prototype, "mediaEngine", void 0);
37
- EFConfiguration = _decorate([customElement("ef-configuration")], EFConfiguration);
37
+ EFConfiguration = __decorate([customElement("ef-configuration")], EFConfiguration);
38
38
  export { EFConfiguration, efConfigurationContext };
@@ -1,5 +1,6 @@
1
1
  import { currentTimeContext } from "./currentTimeContext.js";
2
2
  import { durationContext } from "./durationContext.js";
3
+ import { __decorate } from "../_virtual/_@oxc-project_runtime@0.93.0/helpers/decorate.js";
3
4
  import { efConfigurationContext } from "./EFConfiguration.js";
4
5
  import { efContext } from "./efContext.js";
5
6
  import { fetchContext } from "./fetchContext.js";
@@ -11,8 +12,7 @@ import { TargetController } from "../elements/TargetController.js";
11
12
  import { ContextProxyController } from "../elements/ContextProxiesController.js";
12
13
  import { LitElement, css, html } from "lit";
13
14
  import { customElement, property, state } from "lit/decorators.js";
14
- import _decorate from "@oxc-project/runtime/helpers/decorate";
15
- let EFControls = class EFControls$1 extends LitElement {
15
+ var EFControls = class EFControls$1 extends LitElement {
16
16
  constructor(..._args) {
17
17
  super(..._args);
18
18
  this.target = "";
@@ -45,7 +45,7 @@ let EFControls = class EFControls$1 extends LitElement {
45
45
  return html`<slot></slot>`;
46
46
  }
47
47
  };
48
- _decorate([property({ type: String })], EFControls.prototype, "target", void 0);
49
- _decorate([state()], EFControls.prototype, "targetElement", void 0);
50
- EFControls = _decorate([customElement("ef-controls")], EFControls);
48
+ __decorate([property({ type: String })], EFControls.prototype, "target", void 0);
49
+ __decorate([state()], EFControls.prototype, "targetElement", void 0);
50
+ EFControls = __decorate([customElement("ef-controls")], EFControls);
51
51
  export { EFControls };