@videojs/spf 10.0.0-beta.21 → 10.0.0-beta.23

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.
@@ -1,6 +1,10 @@
1
1
  import { update } from "../../core/signals/primitives.js";
2
2
  import { createPlaybackEngine } from "./engine.js";
3
3
  //#region src/dom/playback-engine/adapter.ts
4
+ const spfMediaDefaultProps = {
5
+ src: "",
6
+ preload: ""
7
+ };
4
8
  /**
5
9
  * Mixin that adds SPF playback engine behavior to any base class.
6
10
  *
@@ -23,7 +27,7 @@ function SpfMediaMixin(BaseClass) {
23
27
  class SpfMediaImpl extends BaseClass {
24
28
  #engine;
25
29
  #config;
26
- #preload = "";
30
+ #preload = spfMediaDefaultProps.preload;
27
31
  /** Pending loadstart listener from a deferred play() retry, if any. */
28
32
  #loadstartListener = null;
29
33
  constructor(...args) {
@@ -95,6 +99,6 @@ function SpfMediaMixin(BaseClass) {
95
99
  /** Standalone SPF media adapter with no base class. */
96
100
  var SpfMedia = class extends SpfMediaMixin(class {}) {};
97
101
  //#endregion
98
- export { SpfMedia, SpfMediaMixin };
102
+ export { SpfMedia, SpfMediaMixin, spfMediaDefaultProps };
99
103
 
100
104
  //# sourceMappingURL=adapter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.js","names":["#config","#engine","#cancelPendingPlay","#preload","#loadstartListener"],"sources":["../../../../src/dom/playback-engine/adapter.ts"],"sourcesContent":["import type { Constructor, MixinReturn } from '@videojs/utils/types';\nimport { update } from '../../core/signals/primitives';\nimport type { PlaybackEngineConfig } from './engine';\nimport { createPlaybackEngine, type PlaybackEngine } from './engine';\n\nexport interface SpfMediaAPI {\n readonly engine: PlaybackEngine;\n src: string;\n preload: '' | 'none' | 'metadata' | 'auto';\n attach(mediaElement: HTMLMediaElement): void;\n detach(): void;\n destroy(): void;\n play(): Promise<void>;\n}\n\n/**\n * Mixin that adds SPF playback engine behavior to any base class.\n *\n * Implements the src/play() contract per the WHATWG HTML spec so that SPF can\n * be used anywhere a media element API is expected.\n *\n * A new engine is created on every src assignment — this fully tears down all\n * state, SourceBuffers, and in-flight requests from the previous source before\n * the next one begins. The media element reference is preserved across src\n * changes and re-applied to the new engine automatically.\n *\n * @example\n * class SimpleHlsMedia extends SpfMediaMixin(HTMLVideoElementHost) {}\n *\n * const media = new SimpleHlsMedia();\n * media.attach(document.querySelector('video'));\n * media.src = 'https://stream.mux.com/abc123.m3u8';\n */\nexport function SpfMediaMixin<Base extends Constructor<any>>(BaseClass: Base) {\n class SpfMediaImpl extends BaseClass {\n #engine: PlaybackEngine;\n #config: PlaybackEngineConfig;\n #preload: '' | 'none' | 'metadata' | 'auto' = '';\n\n /** Pending loadstart listener from a deferred play() retry, if any. */\n #loadstartListener: (() => void) | null = null;\n\n constructor(...args: any[]) {\n super(...args);\n\n const { config } = args?.[0] ?? {};\n this.#config = config;\n this.#engine = createPlaybackEngine(config);\n }\n\n get engine(): PlaybackEngine {\n return this.#engine;\n }\n\n // -------------------------------------------------------------------------\n // Media element lifecycle\n // -------------------------------------------------------------------------\n\n attach(mediaElement: HTMLMediaElement): void {\n super.attach?.(mediaElement);\n update(this.#engine.owners, { mediaElement });\n }\n\n detach(): void {\n this.#cancelPendingPlay();\n update(this.#engine.owners, { mediaElement: undefined });\n super.detach?.();\n }\n\n destroy(): void {\n this.#cancelPendingPlay();\n this.#engine.destroy();\n }\n\n // -------------------------------------------------------------------------\n // preload — synchronous IDL attribute (WHATWG §4.8.11.2)\n // -------------------------------------------------------------------------\n\n get preload(): '' | 'none' | 'metadata' | 'auto' {\n return this.#preload;\n }\n\n set preload(value: '' | 'none' | 'metadata' | 'auto') {\n this.#preload = value;\n if (value) {\n update(this.#engine.state, { preload: value });\n }\n // value = '' clears #preload (so the next engine recreation won't re-apply\n // an explicit value) but does not patch current state — the existing preload\n // stays in effect until the next src change creates a fresh engine.\n }\n\n // -------------------------------------------------------------------------\n // src — synchronous IDL attribute (WHATWG §4.8.11.2)\n // Each assignment destroys the current engine and starts a fresh one, exactly\n // as the browser's load algorithm resets all media element state on src change.\n // -------------------------------------------------------------------------\n\n get src(): string {\n return this.#engine.state.get().presentation?.url ?? '';\n }\n\n set src(value: string) {\n const prevMediaElement = this.#engine.owners.get().mediaElement;\n\n this.#cancelPendingPlay();\n this.#engine.destroy();\n this.#engine = createPlaybackEngine(this.#config);\n\n // Apply explicit preload before setting owners so syncPreloadAttribute skips\n // element inference and the explicit value is preserved across src changes.\n if (this.#preload) {\n update(this.#engine.state, { preload: this.#preload });\n }\n\n if (prevMediaElement) {\n update(this.#engine.owners, { mediaElement: prevMediaElement });\n }\n\n if (value) {\n update(this.#engine.state, { presentation: { url: value } });\n }\n }\n\n // -------------------------------------------------------------------------\n // play() — WHATWG §4.8.11.8\n // Delegates to the attached media element's native play().\n // -------------------------------------------------------------------------\n\n play(): Promise<void> {\n const { mediaElement } = this.#engine.owners.get();\n if (!mediaElement) {\n return Promise.reject(new Error('SpfMedia: no media element attached'));\n }\n\n // Signal play intent — enables loading even with preload=\"none\"\n update(this.#engine.state, { playbackInitiated: true });\n\n return mediaElement.play().catch((err: unknown) => {\n // If we have a pending HLS source, the rejection may be because MSE\n // hasn't attached a blob URL yet. Wait for loadstart (src assigned\n // by MSE setup) and retry once.\n if (this.src) {\n return new Promise<void>((resolve, reject) => {\n const listener = () => {\n this.#loadstartListener = null;\n mediaElement.play().then(resolve, reject);\n };\n this.#loadstartListener = listener;\n mediaElement.addEventListener('loadstart', listener, { once: true });\n });\n }\n throw err;\n });\n }\n\n // -------------------------------------------------------------------------\n // Private\n // -------------------------------------------------------------------------\n\n #cancelPendingPlay(): void {\n if (!this.#loadstartListener) return;\n const { mediaElement } = this.#engine.owners.get();\n mediaElement?.removeEventListener('loadstart', this.#loadstartListener);\n this.#loadstartListener = null;\n }\n }\n\n return SpfMediaImpl as unknown as MixinReturn<Base, SpfMediaAPI>;\n}\n\n/** Standalone SPF media adapter with no base class. */\nexport class SpfMedia extends SpfMediaMixin(class {}) {}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAiCA,SAAgB,cAA6C,WAAiB;CAC5E,MAAM,qBAAqB,UAAU;EACnC;EACA;EACA,WAA8C;;EAG9C,qBAA0C;EAE1C,YAAY,GAAG,MAAa;AAC1B,SAAM,GAAG,KAAK;GAEd,MAAM,EAAE,WAAW,OAAO,MAAM,EAAE;AAClC,SAAA,SAAe;AACf,SAAA,SAAe,qBAAqB,OAAO;;EAG7C,IAAI,SAAyB;AAC3B,UAAO,MAAA;;EAOT,OAAO,cAAsC;AAC3C,SAAM,SAAS,aAAa;AAC5B,UAAO,MAAA,OAAa,QAAQ,EAAE,cAAc,CAAC;;EAG/C,SAAe;AACb,SAAA,mBAAyB;AACzB,UAAO,MAAA,OAAa,QAAQ,EAAE,cAAc,KAAA,GAAW,CAAC;AACxD,SAAM,UAAU;;EAGlB,UAAgB;AACd,SAAA,mBAAyB;AACzB,SAAA,OAAa,SAAS;;EAOxB,IAAI,UAA6C;AAC/C,UAAO,MAAA;;EAGT,IAAI,QAAQ,OAA0C;AACpD,SAAA,UAAgB;AAChB,OAAI,MACF,QAAO,MAAA,OAAa,OAAO,EAAE,SAAS,OAAO,CAAC;;EAalD,IAAI,MAAc;AAChB,UAAO,MAAA,OAAa,MAAM,KAAK,CAAC,cAAc,OAAO;;EAGvD,IAAI,IAAI,OAAe;GACrB,MAAM,mBAAmB,MAAA,OAAa,OAAO,KAAK,CAAC;AAEnD,SAAA,mBAAyB;AACzB,SAAA,OAAa,SAAS;AACtB,SAAA,SAAe,qBAAqB,MAAA,OAAa;AAIjD,OAAI,MAAA,QACF,QAAO,MAAA,OAAa,OAAO,EAAE,SAAS,MAAA,SAAe,CAAC;AAGxD,OAAI,iBACF,QAAO,MAAA,OAAa,QAAQ,EAAE,cAAc,kBAAkB,CAAC;AAGjE,OAAI,MACF,QAAO,MAAA,OAAa,OAAO,EAAE,cAAc,EAAE,KAAK,OAAO,EAAE,CAAC;;EAShE,OAAsB;GACpB,MAAM,EAAE,iBAAiB,MAAA,OAAa,OAAO,KAAK;AAClD,OAAI,CAAC,aACH,QAAO,QAAQ,uBAAO,IAAI,MAAM,sCAAsC,CAAC;AAIzE,UAAO,MAAA,OAAa,OAAO,EAAE,mBAAmB,MAAM,CAAC;AAEvD,UAAO,aAAa,MAAM,CAAC,OAAO,QAAiB;AAIjD,QAAI,KAAK,IACP,QAAO,IAAI,SAAe,SAAS,WAAW;KAC5C,MAAM,iBAAiB;AACrB,YAAA,oBAA0B;AAC1B,mBAAa,MAAM,CAAC,KAAK,SAAS,OAAO;;AAE3C,WAAA,oBAA0B;AAC1B,kBAAa,iBAAiB,aAAa,UAAU,EAAE,MAAM,MAAM,CAAC;MACpE;AAEJ,UAAM;KACN;;EAOJ,qBAA2B;AACzB,OAAI,CAAC,MAAA,kBAAyB;GAC9B,MAAM,EAAE,iBAAiB,MAAA,OAAa,OAAO,KAAK;AAClD,iBAAc,oBAAoB,aAAa,MAAA,kBAAwB;AACvE,SAAA,oBAA0B;;;AAI9B,QAAO;;;AAIT,IAAa,WAAb,cAA8B,cAAc,MAAM,GAAG,CAAC"}
1
+ {"version":3,"file":"adapter.js","names":["#config","#engine","#cancelPendingPlay","#preload","#loadstartListener"],"sources":["../../../../src/dom/playback-engine/adapter.ts"],"sourcesContent":["import type { Constructor, MixinReturn } from '@videojs/utils/types';\nimport { update } from '../../core/signals/primitives';\nimport type { PlaybackEngineConfig } from './engine';\nimport { createPlaybackEngine, type PlaybackEngine } from './engine';\n\nexport interface SpfMediaProps {\n src: string;\n preload: '' | 'none' | 'metadata' | 'auto';\n}\n\nexport const spfMediaDefaultProps: SpfMediaProps = {\n src: '',\n preload: '',\n};\n\nexport interface SpfMediaAPI extends SpfMediaProps {\n readonly engine: PlaybackEngine;\n attach(mediaElement: HTMLMediaElement): void;\n detach(): void;\n destroy(): void;\n play(): Promise<void>;\n}\n\n/**\n * Mixin that adds SPF playback engine behavior to any base class.\n *\n * Implements the src/play() contract per the WHATWG HTML spec so that SPF can\n * be used anywhere a media element API is expected.\n *\n * A new engine is created on every src assignment — this fully tears down all\n * state, SourceBuffers, and in-flight requests from the previous source before\n * the next one begins. The media element reference is preserved across src\n * changes and re-applied to the new engine automatically.\n *\n * @example\n * class SimpleHlsMedia extends SpfMediaMixin(HTMLVideoElementHost) {}\n *\n * const media = new SimpleHlsMedia();\n * media.attach(document.querySelector('video'));\n * media.src = 'https://stream.mux.com/abc123.m3u8';\n */\nexport function SpfMediaMixin<Base extends Constructor<any>>(BaseClass: Base) {\n class SpfMediaImpl extends BaseClass {\n #engine: PlaybackEngine;\n #config: PlaybackEngineConfig;\n #preload: '' | 'none' | 'metadata' | 'auto' = spfMediaDefaultProps.preload;\n\n /** Pending loadstart listener from a deferred play() retry, if any. */\n #loadstartListener: (() => void) | null = null;\n\n constructor(...args: any[]) {\n super(...args);\n\n const { config } = args?.[0] ?? {};\n this.#config = config;\n this.#engine = createPlaybackEngine(config);\n }\n\n get engine(): PlaybackEngine {\n return this.#engine;\n }\n\n // -------------------------------------------------------------------------\n // Media element lifecycle\n // -------------------------------------------------------------------------\n\n attach(mediaElement: HTMLMediaElement): void {\n super.attach?.(mediaElement);\n update(this.#engine.owners, { mediaElement });\n }\n\n detach(): void {\n this.#cancelPendingPlay();\n update(this.#engine.owners, { mediaElement: undefined });\n super.detach?.();\n }\n\n destroy(): void {\n this.#cancelPendingPlay();\n this.#engine.destroy();\n }\n\n // -------------------------------------------------------------------------\n // preload — synchronous IDL attribute (WHATWG §4.8.11.2)\n // -------------------------------------------------------------------------\n\n get preload(): '' | 'none' | 'metadata' | 'auto' {\n return this.#preload;\n }\n\n set preload(value: '' | 'none' | 'metadata' | 'auto') {\n this.#preload = value;\n if (value) {\n update(this.#engine.state, { preload: value });\n }\n // value = '' clears #preload (so the next engine recreation won't re-apply\n // an explicit value) but does not patch current state — the existing preload\n // stays in effect until the next src change creates a fresh engine.\n }\n\n // -------------------------------------------------------------------------\n // src — synchronous IDL attribute (WHATWG §4.8.11.2)\n // Each assignment destroys the current engine and starts a fresh one, exactly\n // as the browser's load algorithm resets all media element state on src change.\n // -------------------------------------------------------------------------\n\n get src(): string {\n return this.#engine.state.get().presentation?.url ?? '';\n }\n\n set src(value: string) {\n const prevMediaElement = this.#engine.owners.get().mediaElement;\n\n this.#cancelPendingPlay();\n this.#engine.destroy();\n this.#engine = createPlaybackEngine(this.#config);\n\n // Apply explicit preload before setting owners so syncPreloadAttribute skips\n // element inference and the explicit value is preserved across src changes.\n if (this.#preload) {\n update(this.#engine.state, { preload: this.#preload });\n }\n\n if (prevMediaElement) {\n update(this.#engine.owners, { mediaElement: prevMediaElement });\n }\n\n if (value) {\n update(this.#engine.state, { presentation: { url: value } });\n }\n }\n\n // -------------------------------------------------------------------------\n // play() — WHATWG §4.8.11.8\n // Delegates to the attached media element's native play().\n // -------------------------------------------------------------------------\n\n play(): Promise<void> {\n const { mediaElement } = this.#engine.owners.get();\n if (!mediaElement) {\n return Promise.reject(new Error('SpfMedia: no media element attached'));\n }\n\n // Signal play intent — enables loading even with preload=\"none\"\n update(this.#engine.state, { playbackInitiated: true });\n\n return mediaElement.play().catch((err: unknown) => {\n // If we have a pending HLS source, the rejection may be because MSE\n // hasn't attached a blob URL yet. Wait for loadstart (src assigned\n // by MSE setup) and retry once.\n if (this.src) {\n return new Promise<void>((resolve, reject) => {\n const listener = () => {\n this.#loadstartListener = null;\n mediaElement.play().then(resolve, reject);\n };\n this.#loadstartListener = listener;\n mediaElement.addEventListener('loadstart', listener, { once: true });\n });\n }\n throw err;\n });\n }\n\n // -------------------------------------------------------------------------\n // Private\n // -------------------------------------------------------------------------\n\n #cancelPendingPlay(): void {\n if (!this.#loadstartListener) return;\n const { mediaElement } = this.#engine.owners.get();\n mediaElement?.removeEventListener('loadstart', this.#loadstartListener);\n this.#loadstartListener = null;\n }\n }\n\n return SpfMediaImpl as unknown as MixinReturn<Base, SpfMediaAPI>;\n}\n\n/** Standalone SPF media adapter with no base class. */\nexport class SpfMedia extends SpfMediaMixin(class {}) {}\n"],"mappings":";;;AAUA,MAAa,uBAAsC;CACjD,KAAK;CACL,SAAS;CACV;;;;;;;;;;;;;;;;;;;AA4BD,SAAgB,cAA6C,WAAiB;CAC5E,MAAM,qBAAqB,UAAU;EACnC;EACA;EACA,WAA8C,qBAAqB;;EAGnE,qBAA0C;EAE1C,YAAY,GAAG,MAAa;AAC1B,SAAM,GAAG,KAAK;GAEd,MAAM,EAAE,WAAW,OAAO,MAAM,EAAE;AAClC,SAAA,SAAe;AACf,SAAA,SAAe,qBAAqB,OAAO;;EAG7C,IAAI,SAAyB;AAC3B,UAAO,MAAA;;EAOT,OAAO,cAAsC;AAC3C,SAAM,SAAS,aAAa;AAC5B,UAAO,MAAA,OAAa,QAAQ,EAAE,cAAc,CAAC;;EAG/C,SAAe;AACb,SAAA,mBAAyB;AACzB,UAAO,MAAA,OAAa,QAAQ,EAAE,cAAc,KAAA,GAAW,CAAC;AACxD,SAAM,UAAU;;EAGlB,UAAgB;AACd,SAAA,mBAAyB;AACzB,SAAA,OAAa,SAAS;;EAOxB,IAAI,UAA6C;AAC/C,UAAO,MAAA;;EAGT,IAAI,QAAQ,OAA0C;AACpD,SAAA,UAAgB;AAChB,OAAI,MACF,QAAO,MAAA,OAAa,OAAO,EAAE,SAAS,OAAO,CAAC;;EAalD,IAAI,MAAc;AAChB,UAAO,MAAA,OAAa,MAAM,KAAK,CAAC,cAAc,OAAO;;EAGvD,IAAI,IAAI,OAAe;GACrB,MAAM,mBAAmB,MAAA,OAAa,OAAO,KAAK,CAAC;AAEnD,SAAA,mBAAyB;AACzB,SAAA,OAAa,SAAS;AACtB,SAAA,SAAe,qBAAqB,MAAA,OAAa;AAIjD,OAAI,MAAA,QACF,QAAO,MAAA,OAAa,OAAO,EAAE,SAAS,MAAA,SAAe,CAAC;AAGxD,OAAI,iBACF,QAAO,MAAA,OAAa,QAAQ,EAAE,cAAc,kBAAkB,CAAC;AAGjE,OAAI,MACF,QAAO,MAAA,OAAa,OAAO,EAAE,cAAc,EAAE,KAAK,OAAO,EAAE,CAAC;;EAShE,OAAsB;GACpB,MAAM,EAAE,iBAAiB,MAAA,OAAa,OAAO,KAAK;AAClD,OAAI,CAAC,aACH,QAAO,QAAQ,uBAAO,IAAI,MAAM,sCAAsC,CAAC;AAIzE,UAAO,MAAA,OAAa,OAAO,EAAE,mBAAmB,MAAM,CAAC;AAEvD,UAAO,aAAa,MAAM,CAAC,OAAO,QAAiB;AAIjD,QAAI,KAAK,IACP,QAAO,IAAI,SAAe,SAAS,WAAW;KAC5C,MAAM,iBAAiB;AACrB,YAAA,oBAA0B;AAC1B,mBAAa,MAAM,CAAC,KAAK,SAAS,OAAO;;AAE3C,WAAA,oBAA0B;AAC1B,kBAAa,iBAAiB,aAAa,UAAU,EAAE,MAAM,MAAM,CAAC;MACpE;AAEJ,UAAM;KACN;;EAOJ,qBAA2B;AACzB,OAAI,CAAC,MAAA,kBAAyB;GAC9B,MAAM,EAAE,iBAAiB,MAAA,OAAa,OAAO,KAAK;AAClD,iBAAc,oBAAoB,aAAa,MAAA,kBAAwB;AACvE,SAAA,oBAA0B;;;AAI9B,QAAO;;;AAIT,IAAa,WAAb,cAA8B,cAAc,MAAM,GAAG,CAAC"}
@@ -6,5 +6,5 @@ import { trackPlaybackInitiated } from "./dom/features/track-playback-initiated.
6
6
  import { trackPlaybackRate } from "./dom/features/track-playback-rate.js";
7
7
  import { appendSegment } from "./dom/media/append-segment.js";
8
8
  import { flushBuffer } from "./dom/media/buffer-flusher.js";
9
- import { SpfMedia, SpfMediaMixin } from "./dom/playback-engine/adapter.js";
10
- export { SpfMedia, SpfMediaMixin, appendSegment, destroyVttParser, flushBuffer, loadSegments, loadTextTrackCues, parseVttSegment, trackCurrentTime, trackPlaybackInitiated, trackPlaybackRate };
9
+ import { SpfMedia, SpfMediaMixin, spfMediaDefaultProps } from "./dom/playback-engine/adapter.js";
10
+ export { SpfMedia, SpfMediaMixin, appendSegment, destroyVttParser, flushBuffer, loadSegments, loadTextTrackCues, parseVttSegment, spfMediaDefaultProps, trackCurrentTime, trackPlaybackInitiated, trackPlaybackRate };
@@ -2,10 +2,13 @@ import { PlaybackEngine } from "./engine.js";
2
2
  import { Constructor, MixinReturn } from "@videojs/utils/types";
3
3
 
4
4
  //#region src/dom/playback-engine/adapter.d.ts
5
- interface SpfMediaAPI {
6
- readonly engine: PlaybackEngine;
5
+ interface SpfMediaProps {
7
6
  src: string;
8
7
  preload: '' | 'none' | 'metadata' | 'auto';
8
+ }
9
+ declare const spfMediaDefaultProps: SpfMediaProps;
10
+ interface SpfMediaAPI extends SpfMediaProps {
11
+ readonly engine: PlaybackEngine;
9
12
  attach(mediaElement: HTMLMediaElement): void;
10
13
  detach(): void;
11
14
  destroy(): void;
@@ -36,5 +39,5 @@ declare const SpfMedia_base: MixinReturn<{
36
39
  /** Standalone SPF media adapter with no base class. */
37
40
  declare class SpfMedia extends SpfMedia_base {}
38
41
  //#endregion
39
- export { SpfMedia, SpfMediaAPI, SpfMediaMixin };
42
+ export { SpfMedia, SpfMediaAPI, SpfMediaMixin, SpfMediaProps, spfMediaDefaultProps };
40
43
  //# sourceMappingURL=adapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","names":[],"sources":["../../../../src/dom/playback-engine/adapter.ts"],"mappings":";;;;UAKiB,WAAA;EAAA,SACN,MAAA,EAAQ,cAAA;EACjB,GAAA;EACA,OAAA;EACA,MAAA,CAAO,YAAA,EAAc,gBAAA;EACrB,MAAA;EACA,OAAA;EACA,IAAA,IAAQ,OAAA;AAAA;;;;;;;;;;;;;;;AAqBV;;;;iBAAgB,aAAA,cAA2B,WAAA,MAAA,CAAkB,SAAA,EAAW,IAAA,GAuIpC,WAAA,CAAY,IAAA,EAAM,WAAA;AAAA,cACrD,aAAA;;;;cAGY,QAAA,SAAiB,aAAA"}
1
+ {"version":3,"file":"adapter.d.ts","names":[],"sources":["../../../../src/dom/playback-engine/adapter.ts"],"mappings":";;;;UAKiB,aAAA;EACf,GAAA;EACA,OAAA;AAAA;AAAA,cAGW,oBAAA,EAAsB,aAAA;AAAA,UAKlB,WAAA,SAAoB,aAAA;EAAA,SAC1B,MAAA,EAAQ,cAAA;EACjB,MAAA,CAAO,YAAA,EAAc,gBAAA;EACrB,MAAA;EACA,OAAA;EACA,IAAA,IAAQ,OAAA;AAAA;AALV;;;;;;;;;;;;;;;;;;AAAA,iBA0BgB,aAAA,cAA2B,WAAA,MAAA,CAAkB,SAAA,EAAW,IAAA,GAuIpC,WAAA,CAAY,IAAA,EAAM,WAAA;AAAA,cACrD,aAAA;;;;cAGY,QAAA,SAAiB,aAAA"}
@@ -1,6 +1,10 @@
1
1
  import { update } from "../../core/signals/primitives.js";
2
2
  import { createPlaybackEngine } from "./engine.js";
3
3
  //#region src/dom/playback-engine/adapter.ts
4
+ const spfMediaDefaultProps = {
5
+ src: "",
6
+ preload: ""
7
+ };
4
8
  /**
5
9
  * Mixin that adds SPF playback engine behavior to any base class.
6
10
  *
@@ -23,7 +27,7 @@ function SpfMediaMixin(BaseClass) {
23
27
  class SpfMediaImpl extends BaseClass {
24
28
  #engine;
25
29
  #config;
26
- #preload = "";
30
+ #preload = spfMediaDefaultProps.preload;
27
31
  /** Pending loadstart listener from a deferred play() retry, if any. */
28
32
  #loadstartListener = null;
29
33
  constructor(...args) {
@@ -95,6 +99,6 @@ function SpfMediaMixin(BaseClass) {
95
99
  /** Standalone SPF media adapter with no base class. */
96
100
  var SpfMedia = class extends SpfMediaMixin(class {}) {};
97
101
  //#endregion
98
- export { SpfMedia, SpfMediaMixin };
102
+ export { SpfMedia, SpfMediaMixin, spfMediaDefaultProps };
99
103
 
100
104
  //# sourceMappingURL=adapter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.js","names":["#config","#engine","#cancelPendingPlay","#preload","#loadstartListener"],"sources":["../../../../src/dom/playback-engine/adapter.ts"],"sourcesContent":["import type { Constructor, MixinReturn } from '@videojs/utils/types';\nimport { update } from '../../core/signals/primitives';\nimport type { PlaybackEngineConfig } from './engine';\nimport { createPlaybackEngine, type PlaybackEngine } from './engine';\n\nexport interface SpfMediaAPI {\n readonly engine: PlaybackEngine;\n src: string;\n preload: '' | 'none' | 'metadata' | 'auto';\n attach(mediaElement: HTMLMediaElement): void;\n detach(): void;\n destroy(): void;\n play(): Promise<void>;\n}\n\n/**\n * Mixin that adds SPF playback engine behavior to any base class.\n *\n * Implements the src/play() contract per the WHATWG HTML spec so that SPF can\n * be used anywhere a media element API is expected.\n *\n * A new engine is created on every src assignment — this fully tears down all\n * state, SourceBuffers, and in-flight requests from the previous source before\n * the next one begins. The media element reference is preserved across src\n * changes and re-applied to the new engine automatically.\n *\n * @example\n * class SimpleHlsMedia extends SpfMediaMixin(HTMLVideoElementHost) {}\n *\n * const media = new SimpleHlsMedia();\n * media.attach(document.querySelector('video'));\n * media.src = 'https://stream.mux.com/abc123.m3u8';\n */\nexport function SpfMediaMixin<Base extends Constructor<any>>(BaseClass: Base) {\n class SpfMediaImpl extends BaseClass {\n #engine: PlaybackEngine;\n #config: PlaybackEngineConfig;\n #preload: '' | 'none' | 'metadata' | 'auto' = '';\n\n /** Pending loadstart listener from a deferred play() retry, if any. */\n #loadstartListener: (() => void) | null = null;\n\n constructor(...args: any[]) {\n super(...args);\n\n const { config } = args?.[0] ?? {};\n this.#config = config;\n this.#engine = createPlaybackEngine(config);\n }\n\n get engine(): PlaybackEngine {\n return this.#engine;\n }\n\n // -------------------------------------------------------------------------\n // Media element lifecycle\n // -------------------------------------------------------------------------\n\n attach(mediaElement: HTMLMediaElement): void {\n super.attach?.(mediaElement);\n update(this.#engine.owners, { mediaElement });\n }\n\n detach(): void {\n this.#cancelPendingPlay();\n update(this.#engine.owners, { mediaElement: undefined });\n super.detach?.();\n }\n\n destroy(): void {\n this.#cancelPendingPlay();\n this.#engine.destroy();\n }\n\n // -------------------------------------------------------------------------\n // preload — synchronous IDL attribute (WHATWG §4.8.11.2)\n // -------------------------------------------------------------------------\n\n get preload(): '' | 'none' | 'metadata' | 'auto' {\n return this.#preload;\n }\n\n set preload(value: '' | 'none' | 'metadata' | 'auto') {\n this.#preload = value;\n if (value) {\n update(this.#engine.state, { preload: value });\n }\n // value = '' clears #preload (so the next engine recreation won't re-apply\n // an explicit value) but does not patch current state — the existing preload\n // stays in effect until the next src change creates a fresh engine.\n }\n\n // -------------------------------------------------------------------------\n // src — synchronous IDL attribute (WHATWG §4.8.11.2)\n // Each assignment destroys the current engine and starts a fresh one, exactly\n // as the browser's load algorithm resets all media element state on src change.\n // -------------------------------------------------------------------------\n\n get src(): string {\n return this.#engine.state.get().presentation?.url ?? '';\n }\n\n set src(value: string) {\n const prevMediaElement = this.#engine.owners.get().mediaElement;\n\n this.#cancelPendingPlay();\n this.#engine.destroy();\n this.#engine = createPlaybackEngine(this.#config);\n\n // Apply explicit preload before setting owners so syncPreloadAttribute skips\n // element inference and the explicit value is preserved across src changes.\n if (this.#preload) {\n update(this.#engine.state, { preload: this.#preload });\n }\n\n if (prevMediaElement) {\n update(this.#engine.owners, { mediaElement: prevMediaElement });\n }\n\n if (value) {\n update(this.#engine.state, { presentation: { url: value } });\n }\n }\n\n // -------------------------------------------------------------------------\n // play() — WHATWG §4.8.11.8\n // Delegates to the attached media element's native play().\n // -------------------------------------------------------------------------\n\n play(): Promise<void> {\n const { mediaElement } = this.#engine.owners.get();\n if (!mediaElement) {\n return Promise.reject(new Error('SpfMedia: no media element attached'));\n }\n\n // Signal play intent — enables loading even with preload=\"none\"\n update(this.#engine.state, { playbackInitiated: true });\n\n return mediaElement.play().catch((err: unknown) => {\n // If we have a pending HLS source, the rejection may be because MSE\n // hasn't attached a blob URL yet. Wait for loadstart (src assigned\n // by MSE setup) and retry once.\n if (this.src) {\n return new Promise<void>((resolve, reject) => {\n const listener = () => {\n this.#loadstartListener = null;\n mediaElement.play().then(resolve, reject);\n };\n this.#loadstartListener = listener;\n mediaElement.addEventListener('loadstart', listener, { once: true });\n });\n }\n throw err;\n });\n }\n\n // -------------------------------------------------------------------------\n // Private\n // -------------------------------------------------------------------------\n\n #cancelPendingPlay(): void {\n if (!this.#loadstartListener) return;\n const { mediaElement } = this.#engine.owners.get();\n mediaElement?.removeEventListener('loadstart', this.#loadstartListener);\n this.#loadstartListener = null;\n }\n }\n\n return SpfMediaImpl as unknown as MixinReturn<Base, SpfMediaAPI>;\n}\n\n/** Standalone SPF media adapter with no base class. */\nexport class SpfMedia extends SpfMediaMixin(class {}) {}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAiCA,SAAgB,cAA6C,WAAiB;CAC5E,MAAM,qBAAqB,UAAU;EACnC;EACA;EACA,WAA8C;;EAG9C,qBAA0C;EAE1C,YAAY,GAAG,MAAa;AAC1B,SAAM,GAAG,KAAK;GAEd,MAAM,EAAE,WAAW,OAAO,MAAM,EAAE;AAClC,SAAA,SAAe;AACf,SAAA,SAAe,qBAAqB,OAAO;;EAG7C,IAAI,SAAyB;AAC3B,UAAO,MAAA;;EAOT,OAAO,cAAsC;AAC3C,SAAM,SAAS,aAAa;AAC5B,UAAO,MAAA,OAAa,QAAQ,EAAE,cAAc,CAAC;;EAG/C,SAAe;AACb,SAAA,mBAAyB;AACzB,UAAO,MAAA,OAAa,QAAQ,EAAE,cAAc,KAAA,GAAW,CAAC;AACxD,SAAM,UAAU;;EAGlB,UAAgB;AACd,SAAA,mBAAyB;AACzB,SAAA,OAAa,SAAS;;EAOxB,IAAI,UAA6C;AAC/C,UAAO,MAAA;;EAGT,IAAI,QAAQ,OAA0C;AACpD,SAAA,UAAgB;AAChB,OAAI,MACF,QAAO,MAAA,OAAa,OAAO,EAAE,SAAS,OAAO,CAAC;;EAalD,IAAI,MAAc;AAChB,UAAO,MAAA,OAAa,MAAM,KAAK,CAAC,cAAc,OAAO;;EAGvD,IAAI,IAAI,OAAe;GACrB,MAAM,mBAAmB,MAAA,OAAa,OAAO,KAAK,CAAC;AAEnD,SAAA,mBAAyB;AACzB,SAAA,OAAa,SAAS;AACtB,SAAA,SAAe,qBAAqB,MAAA,OAAa;AAIjD,OAAI,MAAA,QACF,QAAO,MAAA,OAAa,OAAO,EAAE,SAAS,MAAA,SAAe,CAAC;AAGxD,OAAI,iBACF,QAAO,MAAA,OAAa,QAAQ,EAAE,cAAc,kBAAkB,CAAC;AAGjE,OAAI,MACF,QAAO,MAAA,OAAa,OAAO,EAAE,cAAc,EAAE,KAAK,OAAO,EAAE,CAAC;;EAShE,OAAsB;GACpB,MAAM,EAAE,iBAAiB,MAAA,OAAa,OAAO,KAAK;AAClD,OAAI,CAAC,aACH,QAAO,QAAQ,uBAAO,IAAI,MAAM,sCAAsC,CAAC;AAIzE,UAAO,MAAA,OAAa,OAAO,EAAE,mBAAmB,MAAM,CAAC;AAEvD,UAAO,aAAa,MAAM,CAAC,OAAO,QAAiB;AAIjD,QAAI,KAAK,IACP,QAAO,IAAI,SAAe,SAAS,WAAW;KAC5C,MAAM,iBAAiB;AACrB,YAAA,oBAA0B;AAC1B,mBAAa,MAAM,CAAC,KAAK,SAAS,OAAO;;AAE3C,WAAA,oBAA0B;AAC1B,kBAAa,iBAAiB,aAAa,UAAU,EAAE,MAAM,MAAM,CAAC;MACpE;AAEJ,UAAM;KACN;;EAOJ,qBAA2B;AACzB,OAAI,CAAC,MAAA,kBAAyB;GAC9B,MAAM,EAAE,iBAAiB,MAAA,OAAa,OAAO,KAAK;AAClD,iBAAc,oBAAoB,aAAa,MAAA,kBAAwB;AACvE,SAAA,oBAA0B;;;AAI9B,QAAO;;;AAIT,IAAa,WAAb,cAA8B,cAAc,MAAM,GAAG,CAAC"}
1
+ {"version":3,"file":"adapter.js","names":["#config","#engine","#cancelPendingPlay","#preload","#loadstartListener"],"sources":["../../../../src/dom/playback-engine/adapter.ts"],"sourcesContent":["import type { Constructor, MixinReturn } from '@videojs/utils/types';\nimport { update } from '../../core/signals/primitives';\nimport type { PlaybackEngineConfig } from './engine';\nimport { createPlaybackEngine, type PlaybackEngine } from './engine';\n\nexport interface SpfMediaProps {\n src: string;\n preload: '' | 'none' | 'metadata' | 'auto';\n}\n\nexport const spfMediaDefaultProps: SpfMediaProps = {\n src: '',\n preload: '',\n};\n\nexport interface SpfMediaAPI extends SpfMediaProps {\n readonly engine: PlaybackEngine;\n attach(mediaElement: HTMLMediaElement): void;\n detach(): void;\n destroy(): void;\n play(): Promise<void>;\n}\n\n/**\n * Mixin that adds SPF playback engine behavior to any base class.\n *\n * Implements the src/play() contract per the WHATWG HTML spec so that SPF can\n * be used anywhere a media element API is expected.\n *\n * A new engine is created on every src assignment — this fully tears down all\n * state, SourceBuffers, and in-flight requests from the previous source before\n * the next one begins. The media element reference is preserved across src\n * changes and re-applied to the new engine automatically.\n *\n * @example\n * class SimpleHlsMedia extends SpfMediaMixin(HTMLVideoElementHost) {}\n *\n * const media = new SimpleHlsMedia();\n * media.attach(document.querySelector('video'));\n * media.src = 'https://stream.mux.com/abc123.m3u8';\n */\nexport function SpfMediaMixin<Base extends Constructor<any>>(BaseClass: Base) {\n class SpfMediaImpl extends BaseClass {\n #engine: PlaybackEngine;\n #config: PlaybackEngineConfig;\n #preload: '' | 'none' | 'metadata' | 'auto' = spfMediaDefaultProps.preload;\n\n /** Pending loadstart listener from a deferred play() retry, if any. */\n #loadstartListener: (() => void) | null = null;\n\n constructor(...args: any[]) {\n super(...args);\n\n const { config } = args?.[0] ?? {};\n this.#config = config;\n this.#engine = createPlaybackEngine(config);\n }\n\n get engine(): PlaybackEngine {\n return this.#engine;\n }\n\n // -------------------------------------------------------------------------\n // Media element lifecycle\n // -------------------------------------------------------------------------\n\n attach(mediaElement: HTMLMediaElement): void {\n super.attach?.(mediaElement);\n update(this.#engine.owners, { mediaElement });\n }\n\n detach(): void {\n this.#cancelPendingPlay();\n update(this.#engine.owners, { mediaElement: undefined });\n super.detach?.();\n }\n\n destroy(): void {\n this.#cancelPendingPlay();\n this.#engine.destroy();\n }\n\n // -------------------------------------------------------------------------\n // preload — synchronous IDL attribute (WHATWG §4.8.11.2)\n // -------------------------------------------------------------------------\n\n get preload(): '' | 'none' | 'metadata' | 'auto' {\n return this.#preload;\n }\n\n set preload(value: '' | 'none' | 'metadata' | 'auto') {\n this.#preload = value;\n if (value) {\n update(this.#engine.state, { preload: value });\n }\n // value = '' clears #preload (so the next engine recreation won't re-apply\n // an explicit value) but does not patch current state — the existing preload\n // stays in effect until the next src change creates a fresh engine.\n }\n\n // -------------------------------------------------------------------------\n // src — synchronous IDL attribute (WHATWG §4.8.11.2)\n // Each assignment destroys the current engine and starts a fresh one, exactly\n // as the browser's load algorithm resets all media element state on src change.\n // -------------------------------------------------------------------------\n\n get src(): string {\n return this.#engine.state.get().presentation?.url ?? '';\n }\n\n set src(value: string) {\n const prevMediaElement = this.#engine.owners.get().mediaElement;\n\n this.#cancelPendingPlay();\n this.#engine.destroy();\n this.#engine = createPlaybackEngine(this.#config);\n\n // Apply explicit preload before setting owners so syncPreloadAttribute skips\n // element inference and the explicit value is preserved across src changes.\n if (this.#preload) {\n update(this.#engine.state, { preload: this.#preload });\n }\n\n if (prevMediaElement) {\n update(this.#engine.owners, { mediaElement: prevMediaElement });\n }\n\n if (value) {\n update(this.#engine.state, { presentation: { url: value } });\n }\n }\n\n // -------------------------------------------------------------------------\n // play() — WHATWG §4.8.11.8\n // Delegates to the attached media element's native play().\n // -------------------------------------------------------------------------\n\n play(): Promise<void> {\n const { mediaElement } = this.#engine.owners.get();\n if (!mediaElement) {\n return Promise.reject(new Error('SpfMedia: no media element attached'));\n }\n\n // Signal play intent — enables loading even with preload=\"none\"\n update(this.#engine.state, { playbackInitiated: true });\n\n return mediaElement.play().catch((err: unknown) => {\n // If we have a pending HLS source, the rejection may be because MSE\n // hasn't attached a blob URL yet. Wait for loadstart (src assigned\n // by MSE setup) and retry once.\n if (this.src) {\n return new Promise<void>((resolve, reject) => {\n const listener = () => {\n this.#loadstartListener = null;\n mediaElement.play().then(resolve, reject);\n };\n this.#loadstartListener = listener;\n mediaElement.addEventListener('loadstart', listener, { once: true });\n });\n }\n throw err;\n });\n }\n\n // -------------------------------------------------------------------------\n // Private\n // -------------------------------------------------------------------------\n\n #cancelPendingPlay(): void {\n if (!this.#loadstartListener) return;\n const { mediaElement } = this.#engine.owners.get();\n mediaElement?.removeEventListener('loadstart', this.#loadstartListener);\n this.#loadstartListener = null;\n }\n }\n\n return SpfMediaImpl as unknown as MixinReturn<Base, SpfMediaAPI>;\n}\n\n/** Standalone SPF media adapter with no base class. */\nexport class SpfMedia extends SpfMediaMixin(class {}) {}\n"],"mappings":";;;AAUA,MAAa,uBAAsC;CACjD,KAAK;CACL,SAAS;CACV;;;;;;;;;;;;;;;;;;;AA4BD,SAAgB,cAA6C,WAAiB;CAC5E,MAAM,qBAAqB,UAAU;EACnC;EACA;EACA,WAA8C,qBAAqB;;EAGnE,qBAA0C;EAE1C,YAAY,GAAG,MAAa;AAC1B,SAAM,GAAG,KAAK;GAEd,MAAM,EAAE,WAAW,OAAO,MAAM,EAAE;AAClC,SAAA,SAAe;AACf,SAAA,SAAe,qBAAqB,OAAO;;EAG7C,IAAI,SAAyB;AAC3B,UAAO,MAAA;;EAOT,OAAO,cAAsC;AAC3C,SAAM,SAAS,aAAa;AAC5B,UAAO,MAAA,OAAa,QAAQ,EAAE,cAAc,CAAC;;EAG/C,SAAe;AACb,SAAA,mBAAyB;AACzB,UAAO,MAAA,OAAa,QAAQ,EAAE,cAAc,KAAA,GAAW,CAAC;AACxD,SAAM,UAAU;;EAGlB,UAAgB;AACd,SAAA,mBAAyB;AACzB,SAAA,OAAa,SAAS;;EAOxB,IAAI,UAA6C;AAC/C,UAAO,MAAA;;EAGT,IAAI,QAAQ,OAA0C;AACpD,SAAA,UAAgB;AAChB,OAAI,MACF,QAAO,MAAA,OAAa,OAAO,EAAE,SAAS,OAAO,CAAC;;EAalD,IAAI,MAAc;AAChB,UAAO,MAAA,OAAa,MAAM,KAAK,CAAC,cAAc,OAAO;;EAGvD,IAAI,IAAI,OAAe;GACrB,MAAM,mBAAmB,MAAA,OAAa,OAAO,KAAK,CAAC;AAEnD,SAAA,mBAAyB;AACzB,SAAA,OAAa,SAAS;AACtB,SAAA,SAAe,qBAAqB,MAAA,OAAa;AAIjD,OAAI,MAAA,QACF,QAAO,MAAA,OAAa,OAAO,EAAE,SAAS,MAAA,SAAe,CAAC;AAGxD,OAAI,iBACF,QAAO,MAAA,OAAa,QAAQ,EAAE,cAAc,kBAAkB,CAAC;AAGjE,OAAI,MACF,QAAO,MAAA,OAAa,OAAO,EAAE,cAAc,EAAE,KAAK,OAAO,EAAE,CAAC;;EAShE,OAAsB;GACpB,MAAM,EAAE,iBAAiB,MAAA,OAAa,OAAO,KAAK;AAClD,OAAI,CAAC,aACH,QAAO,QAAQ,uBAAO,IAAI,MAAM,sCAAsC,CAAC;AAIzE,UAAO,MAAA,OAAa,OAAO,EAAE,mBAAmB,MAAM,CAAC;AAEvD,UAAO,aAAa,MAAM,CAAC,OAAO,QAAiB;AAIjD,QAAI,KAAK,IACP,QAAO,IAAI,SAAe,SAAS,WAAW;KAC5C,MAAM,iBAAiB;AACrB,YAAA,oBAA0B;AAC1B,mBAAa,MAAM,CAAC,KAAK,SAAS,OAAO;;AAE3C,WAAA,oBAA0B;AAC1B,kBAAa,iBAAiB,aAAa,UAAU,EAAE,MAAM,MAAM,CAAC;MACpE;AAEJ,UAAM;KACN;;EAOJ,qBAA2B;AACzB,OAAI,CAAC,MAAA,kBAAyB;GAC9B,MAAM,EAAE,iBAAiB,MAAA,OAAa,OAAO,KAAK;AAClD,iBAAc,oBAAoB,aAAa,MAAA,kBAAwB;AACvE,SAAA,oBAA0B;;;AAI9B,QAAO;;;AAIT,IAAa,WAAb,cAA8B,cAAc,MAAM,GAAG,CAAC"}
package/dist/dev/dom.d.ts CHANGED
@@ -5,6 +5,6 @@ import { CurrentTimeOwners, CurrentTimeState, trackCurrentTime } from "./dom/fea
5
5
  import { PlaybackInitiatedOwners, PlaybackInitiatedState, trackPlaybackInitiated } from "./dom/features/track-playback-initiated.js";
6
6
  import { PlaybackRateOwners, PlaybackRateState, trackPlaybackRate } from "./dom/features/track-playback-rate.js";
7
7
  import { flushBuffer } from "./dom/media/buffer-flusher.js";
8
- import { SpfMedia, SpfMediaAPI, SpfMediaMixin } from "./dom/playback-engine/adapter.js";
8
+ import { SpfMedia, SpfMediaAPI, SpfMediaMixin, SpfMediaProps, spfMediaDefaultProps } from "./dom/playback-engine/adapter.js";
9
9
  import { destroyVttParser, parseVttSegment } from "./dom/text/parse-vtt-segment.js";
10
- export { type CurrentTimeOwners, type CurrentTimeState, type PlaybackInitiatedOwners, type PlaybackInitiatedState, type PlaybackRateOwners, type PlaybackRateState, SpfMedia, type SpfMediaAPI, SpfMediaMixin, appendSegment, destroyVttParser, flushBuffer, loadSegments, loadTextTrackCues, parseVttSegment, trackCurrentTime, trackPlaybackInitiated, trackPlaybackRate };
10
+ export { type CurrentTimeOwners, type CurrentTimeState, type PlaybackInitiatedOwners, type PlaybackInitiatedState, type PlaybackRateOwners, type PlaybackRateState, SpfMedia, type SpfMediaAPI, SpfMediaMixin, type SpfMediaProps, appendSegment, destroyVttParser, flushBuffer, loadSegments, loadTextTrackCues, parseVttSegment, spfMediaDefaultProps, trackCurrentTime, trackPlaybackInitiated, trackPlaybackRate };
package/dist/dev/dom.js CHANGED
@@ -6,5 +6,5 @@ import { trackPlaybackInitiated } from "./dom/features/track-playback-initiated.
6
6
  import { trackPlaybackRate } from "./dom/features/track-playback-rate.js";
7
7
  import { appendSegment } from "./dom/media/append-segment.js";
8
8
  import { flushBuffer } from "./dom/media/buffer-flusher.js";
9
- import { SpfMedia, SpfMediaMixin } from "./dom/playback-engine/adapter.js";
10
- export { SpfMedia, SpfMediaMixin, appendSegment, destroyVttParser, flushBuffer, loadSegments, loadTextTrackCues, parseVttSegment, trackCurrentTime, trackPlaybackInitiated, trackPlaybackRate };
9
+ import { SpfMedia, SpfMediaMixin, spfMediaDefaultProps } from "./dom/playback-engine/adapter.js";
10
+ export { SpfMedia, SpfMediaMixin, appendSegment, destroyVttParser, flushBuffer, loadSegments, loadTextTrackCues, parseVttSegment, spfMediaDefaultProps, trackCurrentTime, trackPlaybackInitiated, trackPlaybackRate };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@videojs/spf",
3
3
  "type": "module",
4
- "version": "10.0.0-beta.21",
4
+ "version": "10.0.0-beta.23",
5
5
  "description": "Stream Processing Framework for Video.js 10",
6
6
  "license": "Apache-2.0",
7
7
  "repository": {
@@ -42,7 +42,7 @@
42
42
  ],
43
43
  "dependencies": {
44
44
  "signal-polyfill": "^0.2.2",
45
- "@videojs/utils": "10.0.0-beta.21"
45
+ "@videojs/utils": "10.0.0-beta.23"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@vitest/browser": "^4.1.0",
@@ -50,8 +50,7 @@
50
50
  "@vitest/coverage-v8": "^4.1.0",
51
51
  "jsdom": "^26.1.0",
52
52
  "playwright": "^1.59.1",
53
- "tsdown": "^0.21.4",
54
- "typescript": "^6.0.2",
53
+ "tsdown": "^0.21.9",
55
54
  "vitest": "^4.1.0"
56
55
  },
57
56
  "publishConfig": {