@videojs/spf 10.0.0-beta.11 → 10.0.0-beta.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/default/core/abr/bandwidth-estimator.js +2 -3
- package/dist/default/core/abr/bandwidth-estimator.js.map +1 -1
- package/dist/default/core/abr/ewma.js +1 -1
- package/dist/default/core/abr/quality-selection.js +2 -2
- package/dist/default/core/abr/quality-selection.js.map +1 -1
- package/dist/default/core/buffer/back-buffer.js +2 -2
- package/dist/default/core/buffer/forward-buffer.js +1 -1
- package/dist/default/core/features/calculate-presentation-duration.js +11 -9
- package/dist/default/core/features/calculate-presentation-duration.js.map +1 -1
- package/dist/default/core/features/quality-switching.js +7 -6
- package/dist/default/core/features/quality-switching.js.map +1 -1
- package/dist/default/core/features/resolve-presentation.js +30 -52
- package/dist/default/core/features/resolve-presentation.js.map +1 -1
- package/dist/default/core/features/resolve-track.js +17 -28
- package/dist/default/core/features/resolve-track.js.map +1 -1
- package/dist/default/core/features/select-tracks.js +18 -35
- package/dist/default/core/features/select-tracks.js.map +1 -1
- package/dist/default/core/features/sync-preload-attribute.js +26 -0
- package/dist/default/core/features/sync-preload-attribute.js.map +1 -0
- package/dist/default/core/hls/parse-attributes.js +1 -1
- package/dist/default/core/hls/parse-attributes.js.map +1 -1
- package/dist/default/core/hls/parse-media-playlist.js +1 -2
- package/dist/default/core/hls/parse-media-playlist.js.map +1 -1
- package/dist/default/core/hls/parse-multivariant.js +2 -3
- package/dist/default/core/hls/parse-multivariant.js.map +1 -1
- package/dist/default/core/hls/resolve-url.js +1 -1
- package/dist/default/core/signals/effect.js +41 -0
- package/dist/default/core/signals/effect.js.map +1 -0
- package/dist/default/core/signals/primitives.js +32 -0
- package/dist/default/core/signals/primitives.js.map +1 -0
- package/dist/default/core/task.js +3 -3
- package/dist/default/core/task.js.map +1 -1
- package/dist/default/core/types/index.js +1 -1
- package/dist/default/core/types/index.js.map +1 -1
- package/dist/default/core/utils/generate-id.js +1 -1
- package/dist/default/core/utils/track-selection.js +10 -2
- package/dist/default/core/utils/track-selection.js.map +1 -1
- package/dist/default/dom/features/end-of-stream.js +24 -48
- package/dist/default/dom/features/end-of-stream.js.map +1 -1
- package/dist/default/dom/features/load-segments.js +40 -36
- package/dist/default/dom/features/load-segments.js.map +1 -1
- package/dist/default/dom/features/load-text-track-cues.js +36 -26
- package/dist/default/dom/features/load-text-track-cues.js.map +1 -1
- package/dist/default/dom/features/segment-loader-actor.js +4 -5
- package/dist/default/dom/features/segment-loader-actor.js.map +1 -1
- package/dist/default/dom/features/setup-mediasource.js +29 -36
- package/dist/default/dom/features/setup-mediasource.js.map +1 -1
- package/dist/default/dom/features/setup-sourcebuffer.js +43 -35
- package/dist/default/dom/features/setup-sourcebuffer.js.map +1 -1
- package/dist/default/dom/features/setup-text-tracks.js +25 -46
- package/dist/default/dom/features/setup-text-tracks.js.map +1 -1
- package/dist/default/dom/features/sync-selected-text-track-from-dom.js +14 -23
- package/dist/default/dom/features/sync-selected-text-track-from-dom.js.map +1 -1
- package/dist/default/dom/features/sync-text-track-modes.js +12 -17
- package/dist/default/dom/features/sync-text-track-modes.js.map +1 -1
- package/dist/default/dom/features/track-current-time.js +10 -7
- package/dist/default/dom/features/track-current-time.js.map +1 -1
- package/dist/default/dom/features/track-playback-initiated.js +34 -36
- package/dist/default/dom/features/track-playback-initiated.js.map +1 -1
- package/dist/default/dom/features/track-playback-rate.js +12 -16
- package/dist/default/dom/features/track-playback-rate.js.map +1 -1
- package/dist/default/dom/features/update-duration.js +19 -13
- package/dist/default/dom/features/update-duration.js.map +1 -1
- package/dist/default/dom/media/append-segment.js +1 -1
- package/dist/default/dom/media/buffer-flusher.js +1 -1
- package/dist/default/dom/media/mediasource-setup.js +32 -40
- package/dist/default/dom/media/mediasource-setup.js.map +1 -1
- package/dist/default/dom/media/source-buffer-actor.js +16 -26
- package/dist/default/dom/media/source-buffer-actor.js.map +1 -1
- package/dist/default/dom/network/chunked-stream-iterable.js +1 -1
- package/dist/default/dom/network/chunked-stream-iterable.js.map +1 -1
- package/dist/default/dom/network/fetch.js +1 -2
- package/dist/default/dom/network/fetch.js.map +1 -1
- package/dist/default/dom/playback-engine/adapter.js +13 -13
- package/dist/default/dom/playback-engine/adapter.js.map +1 -1
- package/dist/default/dom/playback-engine/engine.js +24 -49
- package/dist/default/dom/playback-engine/engine.js.map +1 -1
- package/dist/default/dom/playback-engine.js +2 -2
- package/dist/default/dom/text/parse-vtt-segment.js +1 -1
- package/dist/default/dom.js +1 -2
- package/dist/default/index.js +1 -1
- package/dist/dev/core/abr/bandwidth-estimator.js +2 -3
- package/dist/dev/core/abr/bandwidth-estimator.js.map +1 -1
- package/dist/dev/core/abr/ewma.js +1 -1
- package/dist/dev/core/abr/quality-selection.js +2 -2
- package/dist/dev/core/abr/quality-selection.js.map +1 -1
- package/dist/dev/core/actor.d.ts +6 -19
- package/dist/dev/core/actor.d.ts.map +1 -1
- package/dist/dev/core/buffer/back-buffer.js +2 -2
- package/dist/dev/core/buffer/forward-buffer.js +1 -1
- package/dist/dev/core/features/calculate-presentation-duration.js +11 -9
- package/dist/dev/core/features/calculate-presentation-duration.js.map +1 -1
- package/dist/dev/core/features/quality-switching.js +7 -6
- package/dist/dev/core/features/quality-switching.js.map +1 -1
- package/dist/dev/core/features/resolve-presentation.js +30 -52
- package/dist/dev/core/features/resolve-presentation.js.map +1 -1
- package/dist/dev/core/features/resolve-track.js +17 -28
- package/dist/dev/core/features/resolve-track.js.map +1 -1
- package/dist/dev/core/features/select-tracks.js +18 -35
- package/dist/dev/core/features/select-tracks.js.map +1 -1
- package/dist/dev/core/features/sync-preload-attribute.js +26 -0
- package/dist/dev/core/features/sync-preload-attribute.js.map +1 -0
- package/dist/dev/core/hls/parse-attributes.js +1 -1
- package/dist/dev/core/hls/parse-attributes.js.map +1 -1
- package/dist/dev/core/hls/parse-media-playlist.js +1 -2
- package/dist/dev/core/hls/parse-media-playlist.js.map +1 -1
- package/dist/dev/core/hls/parse-multivariant.js +2 -3
- package/dist/dev/core/hls/parse-multivariant.js.map +1 -1
- package/dist/dev/core/hls/resolve-url.js +1 -1
- package/dist/dev/core/signals/effect.d.ts +15 -0
- package/dist/dev/core/signals/effect.d.ts.map +1 -0
- package/dist/dev/core/signals/effect.js +41 -0
- package/dist/dev/core/signals/effect.js.map +1 -0
- package/dist/dev/core/signals/primitives.d.ts +10 -0
- package/dist/dev/core/signals/primitives.d.ts.map +1 -0
- package/dist/dev/core/signals/primitives.js +32 -0
- package/dist/dev/core/signals/primitives.js.map +1 -0
- package/dist/dev/core/task.js +3 -3
- package/dist/dev/core/task.js.map +1 -1
- package/dist/dev/core/types/index.js +1 -1
- package/dist/dev/core/types/index.js.map +1 -1
- package/dist/dev/core/utils/generate-id.js +1 -1
- package/dist/dev/core/utils/track-selection.js +10 -2
- package/dist/dev/core/utils/track-selection.js.map +1 -1
- package/dist/dev/dom/features/end-of-stream.js +24 -48
- package/dist/dev/dom/features/end-of-stream.js.map +1 -1
- package/dist/dev/dom/features/load-segments.d.ts +4 -4
- package/dist/dev/dom/features/load-segments.d.ts.map +1 -1
- package/dist/dev/dom/features/load-segments.js +40 -36
- package/dist/dev/dom/features/load-segments.js.map +1 -1
- package/dist/dev/dom/features/load-text-track-cues.d.ts +4 -4
- package/dist/dev/dom/features/load-text-track-cues.d.ts.map +1 -1
- package/dist/dev/dom/features/load-text-track-cues.js +36 -26
- package/dist/dev/dom/features/load-text-track-cues.js.map +1 -1
- package/dist/dev/dom/features/segment-loader-actor.d.ts +1 -0
- package/dist/dev/dom/features/segment-loader-actor.js +4 -5
- package/dist/dev/dom/features/segment-loader-actor.js.map +1 -1
- package/dist/dev/dom/features/setup-mediasource.js +29 -36
- package/dist/dev/dom/features/setup-mediasource.js.map +1 -1
- package/dist/dev/dom/features/setup-sourcebuffer.d.ts.map +1 -1
- package/dist/dev/dom/features/setup-sourcebuffer.js +43 -35
- package/dist/dev/dom/features/setup-sourcebuffer.js.map +1 -1
- package/dist/dev/dom/features/setup-text-tracks.js +25 -46
- package/dist/dev/dom/features/setup-text-tracks.js.map +1 -1
- package/dist/dev/dom/features/sync-selected-text-track-from-dom.js +14 -23
- package/dist/dev/dom/features/sync-selected-text-track-from-dom.js.map +1 -1
- package/dist/dev/dom/features/sync-text-track-modes.js +12 -17
- package/dist/dev/dom/features/sync-text-track-modes.js.map +1 -1
- package/dist/dev/dom/features/track-current-time.d.ts +4 -4
- package/dist/dev/dom/features/track-current-time.d.ts.map +1 -1
- package/dist/dev/dom/features/track-current-time.js +10 -7
- package/dist/dev/dom/features/track-current-time.js.map +1 -1
- package/dist/dev/dom/features/track-playback-initiated.d.ts +14 -23
- package/dist/dev/dom/features/track-playback-initiated.d.ts.map +1 -1
- package/dist/dev/dom/features/track-playback-initiated.js +34 -36
- package/dist/dev/dom/features/track-playback-initiated.js.map +1 -1
- package/dist/dev/dom/features/track-playback-rate.d.ts +4 -4
- package/dist/dev/dom/features/track-playback-rate.d.ts.map +1 -1
- package/dist/dev/dom/features/track-playback-rate.js +12 -16
- package/dist/dev/dom/features/track-playback-rate.js.map +1 -1
- package/dist/dev/dom/features/update-duration.js +19 -13
- package/dist/dev/dom/features/update-duration.js.map +1 -1
- package/dist/dev/dom/media/append-segment.js +1 -1
- package/dist/dev/dom/media/buffer-flusher.js +1 -1
- package/dist/dev/dom/media/mediasource-setup.js +32 -40
- package/dist/dev/dom/media/mediasource-setup.js.map +1 -1
- package/dist/dev/dom/media/source-buffer-actor.d.ts +2 -2
- package/dist/dev/dom/media/source-buffer-actor.d.ts.map +1 -1
- package/dist/dev/dom/media/source-buffer-actor.js +16 -26
- package/dist/dev/dom/media/source-buffer-actor.js.map +1 -1
- package/dist/dev/dom/network/chunked-stream-iterable.js +1 -1
- package/dist/dev/dom/network/chunked-stream-iterable.js.map +1 -1
- package/dist/dev/dom/network/fetch.js +1 -2
- package/dist/dev/dom/network/fetch.js.map +1 -1
- package/dist/dev/dom/playback-engine/adapter.d.ts.map +1 -1
- package/dist/dev/dom/playback-engine/adapter.js +13 -13
- package/dist/dev/dom/playback-engine/adapter.js.map +1 -1
- package/dist/dev/dom/playback-engine/engine.d.ts +14 -26
- package/dist/dev/dom/playback-engine/engine.d.ts.map +1 -1
- package/dist/dev/dom/playback-engine/engine.js +24 -49
- package/dist/dev/dom/playback-engine/engine.js.map +1 -1
- package/dist/dev/dom/playback-engine.d.ts +3 -2
- package/dist/dev/dom/playback-engine.js +2 -2
- package/dist/dev/dom/text/parse-vtt-segment.js +1 -1
- package/dist/dev/dom.js +1 -2
- package/dist/dev/index.js +1 -1
- package/package.json +5 -4
- package/dist/default/all.js +0 -16
- package/dist/default/core/events/create-event-stream.js +0 -48
- package/dist/default/core/events/create-event-stream.js.map +0 -1
- package/dist/default/core/reactive/combine-latest.js +0 -72
- package/dist/default/core/reactive/combine-latest.js.map +0 -1
- package/dist/default/core/state/create-state.js +0 -143
- package/dist/default/core/state/create-state.js.map +0 -1
- package/dist/dev/all.js +0 -16
- package/dist/dev/core/events/create-event-stream.d.ts +0 -48
- package/dist/dev/core/events/create-event-stream.d.ts.map +0 -1
- package/dist/dev/core/events/create-event-stream.js +0 -48
- package/dist/dev/core/events/create-event-stream.js.map +0 -1
- package/dist/dev/core/features/resolve-presentation.d.ts +0 -16
- package/dist/dev/core/features/resolve-presentation.d.ts.map +0 -1
- package/dist/dev/core/features/resolve-track.d.ts +0 -13
- package/dist/dev/core/features/resolve-track.d.ts.map +0 -1
- package/dist/dev/core/features/select-tracks.d.ts +0 -11
- package/dist/dev/core/features/select-tracks.d.ts.map +0 -1
- package/dist/dev/core/reactive/combine-latest.js +0 -72
- package/dist/dev/core/reactive/combine-latest.js.map +0 -1
- package/dist/dev/core/state/create-state.d.ts +0 -104
- package/dist/dev/core/state/create-state.d.ts.map +0 -1
- package/dist/dev/core/state/create-state.js +0 -143
- package/dist/dev/core/state/create-state.js.map +0 -1
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
//#region src/core/state/create-state.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* Reactive state container with selectors, custom equality, and batched updates.
|
|
4
|
-
*
|
|
5
|
-
* Manages both immutable state values and mutable object references (e.g., HTMLMediaElement).
|
|
6
|
-
*/
|
|
7
|
-
declare const STATE_SYMBOL: unique symbol;
|
|
8
|
-
/**
|
|
9
|
-
* State change listener for full-state subscriptions.
|
|
10
|
-
*/
|
|
11
|
-
type StateListener<T> = (current: T) => void;
|
|
12
|
-
/**
|
|
13
|
-
* Selector function to derive a value from state.
|
|
14
|
-
*/
|
|
15
|
-
type StateSelector<T, R> = (state: T) => R;
|
|
16
|
-
/**
|
|
17
|
-
* Listener for selector-based subscriptions.
|
|
18
|
-
*/
|
|
19
|
-
type SelectorListener<R> = (current: R) => void;
|
|
20
|
-
/**
|
|
21
|
-
* Options for selector subscriptions.
|
|
22
|
-
*/
|
|
23
|
-
interface SelectorOptions<R> {
|
|
24
|
-
/**
|
|
25
|
-
* Custom equality function for selected value.
|
|
26
|
-
* Defaults to Object.is
|
|
27
|
-
*/
|
|
28
|
-
equalityFn?: (a: R, b: R) => boolean;
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Configuration for creating a state container.
|
|
32
|
-
*/
|
|
33
|
-
interface StateConfig<T> {
|
|
34
|
-
/**
|
|
35
|
-
* Custom equality function for change detection.
|
|
36
|
-
* Defaults to Object.is for top-level comparison.
|
|
37
|
-
*/
|
|
38
|
-
equalityFn?: (a: T, b: T) => boolean;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Read-only state interface.
|
|
42
|
-
*/
|
|
43
|
-
interface State<T> {
|
|
44
|
-
/** Symbol for type identification */
|
|
45
|
-
readonly [STATE_SYMBOL]: true;
|
|
46
|
-
/** Current state snapshot */
|
|
47
|
-
readonly current: T;
|
|
48
|
-
/** Subscribe to state changes */
|
|
49
|
-
subscribe(listener: StateListener<T>): () => void;
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Writable state interface with patch capability.
|
|
53
|
-
*/
|
|
54
|
-
interface WritableState<T> extends State<T> {
|
|
55
|
-
/** Update state with partial object (for object state) or full value (for primitive state) */
|
|
56
|
-
patch(partial: T extends object ? Partial<T> : T): void;
|
|
57
|
-
/** Subscribe to full-state changes */
|
|
58
|
-
subscribe(listener: StateListener<T>): () => void;
|
|
59
|
-
/** Subscribe to selected value changes */
|
|
60
|
-
subscribe<R>(selector: StateSelector<T, R>, listener: SelectorListener<R>, options?: SelectorOptions<R>): () => void;
|
|
61
|
-
/** Manually flush pending updates */
|
|
62
|
-
flush(): void;
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Create a reactive state container.
|
|
66
|
-
*
|
|
67
|
-
* @example
|
|
68
|
-
* ```typescript
|
|
69
|
-
* const state = createState({ count: 0 });
|
|
70
|
-
*
|
|
71
|
-
* // Subscribe to changes
|
|
72
|
-
* state.subscribe((current, prev) => {
|
|
73
|
-
* console.log('Changed:', prev, '->', current);
|
|
74
|
-
* });
|
|
75
|
-
*
|
|
76
|
-
* // Updates are batched
|
|
77
|
-
* state.patch({ count: 1 });
|
|
78
|
-
* state.patch({ count: 2 });
|
|
79
|
-
* // Only one notification fires (with count: 2)
|
|
80
|
-
* ```
|
|
81
|
-
*
|
|
82
|
-
* @example Selector subscriptions
|
|
83
|
-
* ```typescript
|
|
84
|
-
* const state = createState({ count: 0, name: 'test' });
|
|
85
|
-
*
|
|
86
|
-
* // Only notified when count changes
|
|
87
|
-
* state.subscribe(
|
|
88
|
-
* s => s.count,
|
|
89
|
-
* (current, prev) => console.log(current, prev)
|
|
90
|
-
* );
|
|
91
|
-
* ```
|
|
92
|
-
*
|
|
93
|
-
* @example Custom equality
|
|
94
|
-
* ```typescript
|
|
95
|
-
* const state = createState(
|
|
96
|
-
* { count: 0, name: 'test' },
|
|
97
|
-
* { equalityFn: (a, b) => a.count === b.count }
|
|
98
|
-
* );
|
|
99
|
-
* ```
|
|
100
|
-
*/
|
|
101
|
-
declare function createState<T>(initial: T, config?: StateConfig<T>): WritableState<T>;
|
|
102
|
-
//#endregion
|
|
103
|
-
export { WritableState, createState };
|
|
104
|
-
//# sourceMappingURL=create-state.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"create-state.d.ts","names":[],"sources":["../../../../src/core/state/create-state.ts"],"mappings":";;;;;;cAUM,YAAA;AASN;;;AAAA,KAAY,aAAA,OAAoB,OAAA,EAAS,CAAA;;;;KAK7B,aAAA,UAAuB,KAAA,EAAO,CAAA,KAAM,CAAA;;AAAhD;;KAKY,gBAAA,OAAuB,OAAA,EAAS,CAAA;;;;UAK3B,eAAA;EAVkB;;;;EAejC,UAAA,IAAc,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA;AAAA;;;;UAMR,WAAA;EAhBkB;;;AAKnC;EAgBE,UAAA,IAAc,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA;AAAA;;;;UAMR,KAAA;EAjBD;EAAA,UAmBJ,YAAA;EAnBU;EAAA,SAsBX,OAAA,EAAS,CAAA;EAtBM;EAyBxB,SAAA,CAAU,QAAA,EAAU,aAAA,CAAc,CAAA;AAAA;;;;UAMnB,aAAA,YAAyB,KAAA,CAAM,CAAA;EApB7B;EAsBjB,KAAA,CAAM,OAAA,EAAS,CAAA,kBAAmB,OAAA,CAAQ,CAAA,IAAK,CAAA;EAtBxB;EAyBvB,SAAA,CAAU,QAAA,EAAU,aAAA,CAAc,CAAA;EAzBV;EA4BxB,SAAA,IAAa,QAAA,EAAU,aAAA,CAAc,CAAA,EAAG,CAAA,GAAI,QAAA,EAAU,gBAAA,CAAiB,CAAA,GAAI,OAAA,GAAU,eAAA,CAAgB,CAAA;EAtBtF;EAyBf,KAAA;AAAA;;;;;;;;;;;;;;;;;AAXF;;;;;;;;;;;;;;;;;;;;;iBA4NgB,WAAA,GAAA,CAAe,OAAA,EAAS,CAAA,EAAG,MAAA,GAAS,WAAA,CAAY,CAAA,IAAK,aAAA,CAAc,CAAA"}
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
//#region src/core/state/create-state.ts
|
|
2
|
-
/**
|
|
3
|
-
* Reactive state container with selectors, custom equality, and batched updates.
|
|
4
|
-
*
|
|
5
|
-
* Manages both immutable state values and mutable object references (e.g., HTMLMediaElement).
|
|
6
|
-
*/
|
|
7
|
-
const STATE_SYMBOL = Symbol("@videojs/spf/state");
|
|
8
|
-
/**
|
|
9
|
-
* Default equality function using Object.is.
|
|
10
|
-
*/
|
|
11
|
-
function defaultEquality(a, b) {
|
|
12
|
-
return Object.is(a, b);
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* State container implementation.
|
|
16
|
-
*/
|
|
17
|
-
var StateContainer = class {
|
|
18
|
-
[STATE_SYMBOL] = true;
|
|
19
|
-
#current;
|
|
20
|
-
#pending = null;
|
|
21
|
-
#pendingFlush = false;
|
|
22
|
-
#equalityFn;
|
|
23
|
-
#listeners = /* @__PURE__ */ new Set();
|
|
24
|
-
#selectorListeners = /* @__PURE__ */ new Set();
|
|
25
|
-
constructor(initial, config) {
|
|
26
|
-
this.#current = typeof initial === "object" && initial !== null ? { ...initial } : initial;
|
|
27
|
-
this.#equalityFn = config?.equalityFn ?? defaultEquality;
|
|
28
|
-
}
|
|
29
|
-
get current() {
|
|
30
|
-
return this.#pending ?? this.#current;
|
|
31
|
-
}
|
|
32
|
-
patch(partial) {
|
|
33
|
-
const base = this.#pending ?? this.#current;
|
|
34
|
-
if (typeof base !== "object" || base === null) {
|
|
35
|
-
const value = partial;
|
|
36
|
-
if (!Object.is(base, value)) {
|
|
37
|
-
this.#pending = value;
|
|
38
|
-
this.#scheduleFlush();
|
|
39
|
-
}
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
const next = { ...base };
|
|
43
|
-
let changed = false;
|
|
44
|
-
for (const key in partial) {
|
|
45
|
-
if (!Object.hasOwn(partial, key)) continue;
|
|
46
|
-
const value = partial[key];
|
|
47
|
-
if (!Object.is(base[key], value)) {
|
|
48
|
-
next[key] = value;
|
|
49
|
-
changed = true;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
if (changed) {
|
|
53
|
-
this.#pending = next;
|
|
54
|
-
this.#scheduleFlush();
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
subscribe(selectorOrListener, maybeListener, options) {
|
|
58
|
-
if (maybeListener === void 0) {
|
|
59
|
-
const listener = selectorOrListener;
|
|
60
|
-
this.#listeners.add(listener);
|
|
61
|
-
listener(this.current);
|
|
62
|
-
return () => {
|
|
63
|
-
this.#listeners.delete(listener);
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
const selector = selectorOrListener;
|
|
67
|
-
const listener = maybeListener;
|
|
68
|
-
const entry = {
|
|
69
|
-
selector,
|
|
70
|
-
listener,
|
|
71
|
-
options: options ?? {}
|
|
72
|
-
};
|
|
73
|
-
this.#selectorListeners.add(entry);
|
|
74
|
-
listener(selector(this.current));
|
|
75
|
-
return () => {
|
|
76
|
-
this.#selectorListeners.delete(entry);
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
flush() {
|
|
80
|
-
if (this.#pending === null) return;
|
|
81
|
-
const prev = this.#current;
|
|
82
|
-
const next = this.#pending;
|
|
83
|
-
this.#pending = null;
|
|
84
|
-
this.#pendingFlush = false;
|
|
85
|
-
if (this.#equalityFn(prev, next)) return;
|
|
86
|
-
this.#current = next;
|
|
87
|
-
for (const listener of this.#listeners) listener(this.#current);
|
|
88
|
-
for (const entry of this.#selectorListeners) {
|
|
89
|
-
const prevSelected = entry.selector(prev);
|
|
90
|
-
const nextSelected = entry.selector(this.#current);
|
|
91
|
-
if (!(entry.options.equalityFn ?? Object.is)(prevSelected, nextSelected)) entry.listener(nextSelected);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
#scheduleFlush() {
|
|
95
|
-
if (this.#pendingFlush) return;
|
|
96
|
-
this.#pendingFlush = true;
|
|
97
|
-
queueMicrotask(() => this.flush());
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
/**
|
|
101
|
-
* Create a reactive state container.
|
|
102
|
-
*
|
|
103
|
-
* @example
|
|
104
|
-
* ```typescript
|
|
105
|
-
* const state = createState({ count: 0 });
|
|
106
|
-
*
|
|
107
|
-
* // Subscribe to changes
|
|
108
|
-
* state.subscribe((current, prev) => {
|
|
109
|
-
* console.log('Changed:', prev, '->', current);
|
|
110
|
-
* });
|
|
111
|
-
*
|
|
112
|
-
* // Updates are batched
|
|
113
|
-
* state.patch({ count: 1 });
|
|
114
|
-
* state.patch({ count: 2 });
|
|
115
|
-
* // Only one notification fires (with count: 2)
|
|
116
|
-
* ```
|
|
117
|
-
*
|
|
118
|
-
* @example Selector subscriptions
|
|
119
|
-
* ```typescript
|
|
120
|
-
* const state = createState({ count: 0, name: 'test' });
|
|
121
|
-
*
|
|
122
|
-
* // Only notified when count changes
|
|
123
|
-
* state.subscribe(
|
|
124
|
-
* s => s.count,
|
|
125
|
-
* (current, prev) => console.log(current, prev)
|
|
126
|
-
* );
|
|
127
|
-
* ```
|
|
128
|
-
*
|
|
129
|
-
* @example Custom equality
|
|
130
|
-
* ```typescript
|
|
131
|
-
* const state = createState(
|
|
132
|
-
* { count: 0, name: 'test' },
|
|
133
|
-
* { equalityFn: (a, b) => a.count === b.count }
|
|
134
|
-
* );
|
|
135
|
-
* ```
|
|
136
|
-
*/
|
|
137
|
-
function createState(initial, config) {
|
|
138
|
-
return new StateContainer(initial, config);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
//#endregion
|
|
142
|
-
export { createState };
|
|
143
|
-
//# sourceMappingURL=create-state.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"create-state.js","names":["#current","#equalityFn","#pending","#scheduleFlush","#listeners","#selectorListeners","#pendingFlush"],"sources":["../../../../src/core/state/create-state.ts"],"sourcesContent":["/**\n * Reactive state container with selectors, custom equality, and batched updates.\n *\n * Manages both immutable state values and mutable object references (e.g., HTMLMediaElement).\n */\n\n// =============================================================================\n// Symbol for type identification\n// =============================================================================\n\nconst STATE_SYMBOL = Symbol('@videojs/spf/state');\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * State change listener for full-state subscriptions.\n */\nexport type StateListener<T> = (current: T) => void;\n\n/**\n * Selector function to derive a value from state.\n */\nexport type StateSelector<T, R> = (state: T) => R;\n\n/**\n * Listener for selector-based subscriptions.\n */\nexport type SelectorListener<R> = (current: R) => void;\n\n/**\n * Options for selector subscriptions.\n */\nexport interface SelectorOptions<R> {\n /**\n * Custom equality function for selected value.\n * Defaults to Object.is\n */\n equalityFn?: (a: R, b: R) => boolean;\n}\n\n/**\n * Configuration for creating a state container.\n */\nexport interface StateConfig<T> {\n /**\n * Custom equality function for change detection.\n * Defaults to Object.is for top-level comparison.\n */\n equalityFn?: (a: T, b: T) => boolean;\n}\n\n/**\n * Read-only state interface.\n */\nexport interface State<T> {\n /** Symbol for type identification */\n readonly [STATE_SYMBOL]: true;\n\n /** Current state snapshot */\n readonly current: T;\n\n /** Subscribe to state changes */\n subscribe(listener: StateListener<T>): () => void;\n}\n\n/**\n * Writable state interface with patch capability.\n */\nexport interface WritableState<T> extends State<T> {\n /** Update state with partial object (for object state) or full value (for primitive state) */\n patch(partial: T extends object ? Partial<T> : T): void;\n\n /** Subscribe to full-state changes */\n subscribe(listener: StateListener<T>): () => void;\n\n /** Subscribe to selected value changes */\n subscribe<R>(selector: StateSelector<T, R>, listener: SelectorListener<R>, options?: SelectorOptions<R>): () => void;\n\n /** Manually flush pending updates */\n flush(): void;\n}\n\n/**\n * Entry for selector subscriptions.\n */\ninterface SelectorEntry<T, R> {\n selector: StateSelector<T, R>;\n listener: SelectorListener<R>;\n options: SelectorOptions<R>;\n}\n\n// =============================================================================\n// Default equality function\n// =============================================================================\n\n/**\n * Default equality function using Object.is.\n */\nfunction defaultEquality<T>(a: T, b: T): boolean {\n return Object.is(a, b);\n}\n\n// =============================================================================\n// Implementation\n// =============================================================================\n\n/**\n * State container implementation.\n */\nclass StateContainer<T> implements WritableState<T> {\n [STATE_SYMBOL] = true as const;\n\n #current: T;\n #pending: T | null = null;\n #pendingFlush = false;\n #equalityFn: (a: T, b: T) => boolean;\n\n // Full-state listeners\n #listeners = new Set<StateListener<T>>();\n\n // Selector-based listeners\n #selectorListeners = new Set<SelectorEntry<T, unknown>>();\n\n constructor(initial: T, config?: StateConfig<T>) {\n this.#current = typeof initial === 'object' && initial !== null ? ({ ...initial } as T) : initial;\n this.#equalityFn = config?.equalityFn ?? defaultEquality;\n }\n\n get current(): T {\n // Return pending state if available (for chained patches)\n return this.#pending ?? this.#current;\n }\n\n patch(partial: T extends object ? Partial<T> : T): void {\n const base = this.#pending ?? this.#current;\n\n if (typeof base !== 'object' || base === null) {\n // Primitive state: replace the whole value\n const value = partial as T;\n if (!Object.is(base, value)) {\n this.#pending = value;\n this.#scheduleFlush();\n }\n return;\n }\n\n const next = { ...base } as T;\n let changed = false;\n\n // Apply partial updates with change detection\n for (const key in partial) {\n if (!Object.hasOwn(partial as any, key)) continue;\n\n const value = (partial as Partial<T>)[key as keyof T];\n\n if (!Object.is((base as Partial<T>)[key as keyof T], value)) {\n (next as Partial<T>)[key as keyof T] = value;\n changed = true;\n }\n }\n\n if (changed) {\n this.#pending = next;\n this.#scheduleFlush();\n }\n }\n\n subscribe(listener: StateListener<T>): () => void;\n subscribe<R>(selector: StateSelector<T, R>, listener: SelectorListener<R>, options?: SelectorOptions<R>): () => void;\n subscribe<R>(\n selectorOrListener: StateListener<T> | StateSelector<T, R>,\n maybeListener?: SelectorListener<R>,\n options?: SelectorOptions<R>\n ): () => void {\n // Overload 1: Full-state subscription\n if (maybeListener === undefined) {\n const listener = selectorOrListener as StateListener<T>;\n this.#listeners.add(listener);\n\n // Fire immediately with current state\n listener(this.current);\n\n return () => {\n this.#listeners.delete(listener);\n };\n }\n\n // Overload 2: Selector subscription\n const selector = selectorOrListener as StateSelector<T, R>;\n const listener = maybeListener;\n const opts = options ?? {};\n\n const entry: SelectorEntry<T, unknown> = {\n selector: selector as StateSelector<T, unknown>,\n listener: listener as SelectorListener<unknown>,\n options: opts as SelectorOptions<unknown>,\n };\n\n this.#selectorListeners.add(entry);\n\n // Fire immediately with current selected value\n const selected = selector(this.current);\n listener(selected);\n\n return () => {\n this.#selectorListeners.delete(entry);\n };\n }\n\n flush(): void {\n if (this.#pending === null) return;\n\n const prev = this.#current;\n const next = this.#pending;\n this.#pending = null;\n this.#pendingFlush = false;\n\n // Check if state actually changed using custom equality\n if (this.#equalityFn(prev, next)) return;\n\n this.#current = next;\n\n // Notify full-state listeners\n for (const listener of this.#listeners) {\n listener(this.#current);\n }\n\n // Notify selector listeners\n for (const entry of this.#selectorListeners) {\n const prevSelected = entry.selector(prev);\n const nextSelected = entry.selector(this.#current);\n\n const equalityFn = entry.options.equalityFn ?? Object.is;\n\n if (!equalityFn(prevSelected, nextSelected)) {\n entry.listener(nextSelected);\n }\n }\n }\n\n #scheduleFlush(): void {\n if (this.#pendingFlush) return;\n this.#pendingFlush = true;\n queueMicrotask(() => this.flush());\n }\n}\n\n// =============================================================================\n// Factory function\n// =============================================================================\n\n/**\n * Create a reactive state container.\n *\n * @example\n * ```typescript\n * const state = createState({ count: 0 });\n *\n * // Subscribe to changes\n * state.subscribe((current, prev) => {\n * console.log('Changed:', prev, '->', current);\n * });\n *\n * // Updates are batched\n * state.patch({ count: 1 });\n * state.patch({ count: 2 });\n * // Only one notification fires (with count: 2)\n * ```\n *\n * @example Selector subscriptions\n * ```typescript\n * const state = createState({ count: 0, name: 'test' });\n *\n * // Only notified when count changes\n * state.subscribe(\n * s => s.count,\n * (current, prev) => console.log(current, prev)\n * );\n * ```\n *\n * @example Custom equality\n * ```typescript\n * const state = createState(\n * { count: 0, name: 'test' },\n * { equalityFn: (a, b) => a.count === b.count }\n * );\n * ```\n */\nexport function createState<T>(initial: T, config?: StateConfig<T>): WritableState<T> {\n return new StateContainer(initial, config);\n}\n\n// =============================================================================\n// Type guard\n// =============================================================================\n\n/**\n * Check if a value is a State container.\n */\nexport function isState(value: unknown): value is State<object> {\n return typeof value === 'object' && value !== null && STATE_SYMBOL in value;\n}\n"],"mappings":";;;;;;AAUA,MAAM,eAAe,OAAO,qBAAqB;;;;AA0FjD,SAAS,gBAAmB,GAAM,GAAe;AAC/C,QAAO,OAAO,GAAG,GAAG,EAAE;;;;;AAUxB,IAAM,iBAAN,MAAoD;CAClD,CAAC,gBAAgB;CAEjB;CACA,WAAqB;CACrB,gBAAgB;CAChB;CAGA,6BAAa,IAAI,KAAuB;CAGxC,qCAAqB,IAAI,KAAgC;CAEzD,YAAY,SAAY,QAAyB;AAC/C,QAAKA,UAAW,OAAO,YAAY,YAAY,YAAY,OAAQ,EAAE,GAAG,SAAS,GAAS;AAC1F,QAAKC,aAAc,QAAQ,cAAc;;CAG3C,IAAI,UAAa;AAEf,SAAO,MAAKC,WAAY,MAAKF;;CAG/B,MAAM,SAAkD;EACtD,MAAM,OAAO,MAAKE,WAAY,MAAKF;AAEnC,MAAI,OAAO,SAAS,YAAY,SAAS,MAAM;GAE7C,MAAM,QAAQ;AACd,OAAI,CAAC,OAAO,GAAG,MAAM,MAAM,EAAE;AAC3B,UAAKE,UAAW;AAChB,UAAKC,eAAgB;;AAEvB;;EAGF,MAAM,OAAO,EAAE,GAAG,MAAM;EACxB,IAAI,UAAU;AAGd,OAAK,MAAM,OAAO,SAAS;AACzB,OAAI,CAAC,OAAO,OAAO,SAAgB,IAAI,CAAE;GAEzC,MAAM,QAAS,QAAuB;AAEtC,OAAI,CAAC,OAAO,GAAI,KAAoB,MAAiB,MAAM,EAAE;AAC3D,IAAC,KAAoB,OAAkB;AACvC,cAAU;;;AAId,MAAI,SAAS;AACX,SAAKD,UAAW;AAChB,SAAKC,eAAgB;;;CAMzB,UACE,oBACA,eACA,SACY;AAEZ,MAAI,kBAAkB,QAAW;GAC/B,MAAM,WAAW;AACjB,SAAKC,UAAW,IAAI,SAAS;AAG7B,YAAS,KAAK,QAAQ;AAEtB,gBAAa;AACX,UAAKA,UAAW,OAAO,SAAS;;;EAKpC,MAAM,WAAW;EACjB,MAAM,WAAW;EAGjB,MAAM,QAAmC;GAC7B;GACA;GACV,SALW,WAAW,EAAE;GAMzB;AAED,QAAKC,kBAAmB,IAAI,MAAM;AAIlC,WADiB,SAAS,KAAK,QAAQ,CACrB;AAElB,eAAa;AACX,SAAKA,kBAAmB,OAAO,MAAM;;;CAIzC,QAAc;AACZ,MAAI,MAAKH,YAAa,KAAM;EAE5B,MAAM,OAAO,MAAKF;EAClB,MAAM,OAAO,MAAKE;AAClB,QAAKA,UAAW;AAChB,QAAKI,eAAgB;AAGrB,MAAI,MAAKL,WAAY,MAAM,KAAK,CAAE;AAElC,QAAKD,UAAW;AAGhB,OAAK,MAAM,YAAY,MAAKI,UAC1B,UAAS,MAAKJ,QAAS;AAIzB,OAAK,MAAM,SAAS,MAAKK,mBAAoB;GAC3C,MAAM,eAAe,MAAM,SAAS,KAAK;GACzC,MAAM,eAAe,MAAM,SAAS,MAAKL,QAAS;AAIlD,OAAI,EAFe,MAAM,QAAQ,cAAc,OAAO,IAEtC,cAAc,aAAa,CACzC,OAAM,SAAS,aAAa;;;CAKlC,iBAAuB;AACrB,MAAI,MAAKM,aAAe;AACxB,QAAKA,eAAgB;AACrB,uBAAqB,KAAK,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CtC,SAAgB,YAAe,SAAY,QAA2C;AACpF,QAAO,IAAI,eAAe,SAAS,OAAO"}
|