gapless 4.4.0 → 4.4.2

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.
@@ -0,0 +1,42 @@
1
+ export interface FetchDecodeContext {
2
+ trackUrl: string;
3
+ resolvedUrl: string;
4
+ skipHEAD: boolean;
5
+ }
6
+ export declare const fetchDecodeMachine: import("xstate").StateMachine<FetchDecodeContext, import("xstate").AnyEventObject, {
7
+ [x: string]: import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<void, void, import("xstate").EventObject> | import("xstate").PromiseActorLogic<void, {
8
+ resolvedUrl: string;
9
+ }, import("xstate").EventObject> | import("xstate").PromiseActorLogic<string | null, {
10
+ trackUrl: string;
11
+ }, import("xstate").EventObject>> | undefined;
12
+ }, {
13
+ src: "decodeAudio";
14
+ logic: import("xstate").PromiseActorLogic<void, void, import("xstate").EventObject>;
15
+ id: string | undefined;
16
+ } | {
17
+ src: "fetchAudio";
18
+ logic: import("xstate").PromiseActorLogic<void, {
19
+ resolvedUrl: string;
20
+ }, import("xstate").EventObject>;
21
+ id: string | undefined;
22
+ } | {
23
+ src: "resolveUrl";
24
+ logic: import("xstate").PromiseActorLogic<string | null, {
25
+ trackUrl: string;
26
+ }, import("xstate").EventObject>;
27
+ id: string | undefined;
28
+ }, never, {
29
+ type: "shouldSkipHEAD";
30
+ params: unknown;
31
+ }, never, "decoding" | "done" | "error" | "fetching" | "resolvingUrl", string, FetchDecodeContext, import("xstate").NonReducibleUnknown, import("xstate").EventObject, import("xstate").MetaObject, {
32
+ id: "fetchDecode";
33
+ states: {
34
+ readonly resolvingUrl: {};
35
+ readonly fetching: {};
36
+ readonly decoding: {};
37
+ readonly done: {};
38
+ readonly error: {};
39
+ };
40
+ }, import("xstate").MetaObject>;
41
+ export type FetchDecodeMachine = typeof fetchDecodeMachine;
42
+ //# sourceMappingURL=fetchDecode.machine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetchDecode.machine.d.ts","sourceRoot":"","sources":["../../src/machines/fetchDecode.machine.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAID,eAAO,MAAM,kBAAkB;;qBAOkB,MAAM;;kBADA,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+BAmG3D,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,OAAO,kBAAkB,CAAC"}
@@ -0,0 +1,165 @@
1
+ export interface QueueContext {
2
+ currentTrackIndex: number;
3
+ trackCount: number;
4
+ }
5
+ export type QueueEvent = {
6
+ type: 'PLAY';
7
+ } | {
8
+ type: 'PAUSE';
9
+ } | {
10
+ type: 'TOGGLE';
11
+ } | {
12
+ type: 'NEXT';
13
+ } | {
14
+ type: 'PREVIOUS';
15
+ } | {
16
+ type: 'GOTO';
17
+ index: number;
18
+ playImmediately?: boolean;
19
+ startTime?: number;
20
+ } | {
21
+ type: 'SEEK';
22
+ time: number;
23
+ } | {
24
+ type: 'SET_VOLUME';
25
+ volume: number;
26
+ } | {
27
+ type: 'ADD_TRACK';
28
+ } | {
29
+ type: 'REMOVE_TRACK';
30
+ index: number;
31
+ } | {
32
+ type: 'TRACK_ENDED';
33
+ } | {
34
+ type: 'TRACK_LOADED';
35
+ index: number;
36
+ };
37
+ export declare function createQueueMachine(initialContext: QueueContext): import("xstate").StateMachine<QueueContext, {
38
+ type: 'PLAY';
39
+ } | {
40
+ type: 'PAUSE';
41
+ } | {
42
+ type: 'TOGGLE';
43
+ } | {
44
+ type: 'NEXT';
45
+ } | {
46
+ type: 'PREVIOUS';
47
+ } | {
48
+ type: 'GOTO';
49
+ index: number;
50
+ playImmediately?: boolean;
51
+ startTime?: number;
52
+ } | {
53
+ type: 'SEEK';
54
+ time: number;
55
+ } | {
56
+ type: 'SET_VOLUME';
57
+ volume: number;
58
+ } | {
59
+ type: 'ADD_TRACK';
60
+ } | {
61
+ type: 'REMOVE_TRACK';
62
+ index: number;
63
+ } | {
64
+ type: 'TRACK_ENDED';
65
+ } | {
66
+ type: 'TRACK_LOADED';
67
+ index: number;
68
+ }, {}, never, {
69
+ type: "activateAndPlayCurrent";
70
+ params: unknown;
71
+ } | {
72
+ type: "advanceOnTrackEnd";
73
+ params: unknown;
74
+ } | {
75
+ type: "advanceToNextTrack";
76
+ params: unknown;
77
+ } | {
78
+ type: "cancelAllGapless";
79
+ params: unknown;
80
+ } | {
81
+ type: "cancelAndRescheduleGapless";
82
+ params: unknown;
83
+ } | {
84
+ type: "cancelScheduledGapless";
85
+ params: unknown;
86
+ } | {
87
+ type: "deactivateCurrent";
88
+ params: unknown;
89
+ } | {
90
+ type: "deactivateEndedTrack";
91
+ params: unknown;
92
+ } | {
93
+ type: "decrementTrackCount";
94
+ params: unknown;
95
+ } | {
96
+ type: "goToPreviousTrack";
97
+ params: unknown;
98
+ } | {
99
+ type: "gotoTrackIndex";
100
+ params: unknown;
101
+ } | {
102
+ type: "incrementTrackCount";
103
+ params: unknown;
104
+ } | {
105
+ type: "notifyEnded";
106
+ params: unknown;
107
+ } | {
108
+ type: "notifyPlayNextTrack";
109
+ params: unknown;
110
+ } | {
111
+ type: "notifyPlayPreviousTrack";
112
+ params: unknown;
113
+ } | {
114
+ type: "notifyStartNewTrack";
115
+ params: unknown;
116
+ } | {
117
+ type: "pauseCurrent";
118
+ params: unknown;
119
+ } | {
120
+ type: "playCurrent";
121
+ params: unknown;
122
+ } | {
123
+ type: "playOrContinueGapless";
124
+ params: unknown;
125
+ } | {
126
+ type: "preloadAhead";
127
+ params: unknown;
128
+ } | {
129
+ type: "resetToFirstTrack";
130
+ params: unknown;
131
+ } | {
132
+ type: "scheduleGapless";
133
+ params: unknown;
134
+ } | {
135
+ type: "seekCurrent";
136
+ params: unknown;
137
+ } | {
138
+ type: "seekCurrentToStartTime";
139
+ params: unknown;
140
+ } | {
141
+ type: "updateMediaSessionMetadata";
142
+ params: unknown;
143
+ }, {
144
+ type: "hasNextTrack";
145
+ params: unknown;
146
+ } | {
147
+ type: "isRemovingCurrent";
148
+ params: unknown;
149
+ } | {
150
+ type: "playImmediately";
151
+ params: unknown;
152
+ } | {
153
+ type: "willBeEmpty";
154
+ params: unknown;
155
+ }, never, "ended" | "idle" | "paused" | "playing", string, import("xstate").NonReducibleUnknown, import("xstate").NonReducibleUnknown, import("xstate").EventObject, import("xstate").MetaObject, {
156
+ id: "queue";
157
+ states: {
158
+ readonly idle: {};
159
+ readonly playing: {};
160
+ readonly paused: {};
161
+ readonly ended: {};
162
+ };
163
+ }, import("xstate").MetaObject>;
164
+ export type QueueMachine = ReturnType<typeof createQueueMachine>;
165
+ //# sourceMappingURL=queue.machine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.machine.d.ts","sourceRoot":"","sources":["../../src/machines/queue.machine.ts"],"names":[],"mappings":"AAsBA,MAAM,WAAW,YAAY;IAC3B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;CACpB;AAID,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9E;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAI5C,wBAAgB,kBAAkB,CAAC,cAAc,EAAE,YAAY;UAfnD,MAAM;;UACN,OAAO;;UACP,QAAQ;;UACR,MAAM;;UACN,UAAU;;UACV,MAAM;WAAS,MAAM;sBAAoB,OAAO;gBAAc,MAAM;;UACpE,MAAM;UAAQ,MAAM;;UACpB,YAAY;YAAU,MAAM;;UAC5B,WAAW;;UACX,cAAc;WAAS,MAAM;;UAC7B,aAAa;;UACb,cAAc;WAAS,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCAuZxC;AAED,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
@@ -0,0 +1,291 @@
1
+ import type { WebAudioLoadingState, PlaybackType } from '../types';
2
+ export interface TrackContext {
3
+ trackUrl: string;
4
+ resolvedUrl: string;
5
+ skipHEAD: boolean;
6
+ playbackType: PlaybackType;
7
+ webAudioLoadingState: WebAudioLoadingState;
8
+ isPlaying: boolean;
9
+ scheduledStartContextTime: number | null;
10
+ notifiedLookahead: boolean;
11
+ fetchStarted: boolean;
12
+ /** True when PLAY was received in webAudioOnly mode before buffer is ready. */
13
+ pendingPlay: boolean;
14
+ }
15
+ export type TrackEvent = {
16
+ type: 'ACTIVATE';
17
+ } | {
18
+ type: 'DEACTIVATE';
19
+ } | {
20
+ type: 'PRELOAD';
21
+ } | {
22
+ type: 'BUFFER_LOADING';
23
+ } | {
24
+ type: 'PLAY';
25
+ } | {
26
+ type: 'PLAY_WEBAUDIO';
27
+ } | {
28
+ type: 'PAUSE';
29
+ } | {
30
+ type: 'SEEK';
31
+ time: number;
32
+ } | {
33
+ type: 'SET_VOLUME';
34
+ volume: number;
35
+ } | {
36
+ type: 'BUFFER_READY';
37
+ } | {
38
+ type: 'BUFFER_ERROR';
39
+ } | {
40
+ type: 'HTML5_ENDED';
41
+ } | {
42
+ type: 'WEBAUDIO_ENDED';
43
+ } | {
44
+ type: 'URL_RESOLVED';
45
+ url: string;
46
+ } | {
47
+ type: 'START_FETCH';
48
+ } | {
49
+ type: 'SCHEDULE_GAPLESS';
50
+ when: number;
51
+ } | {
52
+ type: 'CANCEL_GAPLESS';
53
+ } | {
54
+ type: 'LOOKAHEAD_REACHED';
55
+ };
56
+ export declare function createTrackMachine(initialContext: TrackContext): import("xstate").StateMachine<TrackContext, {
57
+ type: 'ACTIVATE';
58
+ } | {
59
+ type: 'DEACTIVATE';
60
+ } | {
61
+ type: 'PRELOAD';
62
+ } | {
63
+ type: 'BUFFER_LOADING';
64
+ } | {
65
+ type: 'PLAY';
66
+ } | {
67
+ type: 'PLAY_WEBAUDIO';
68
+ } | {
69
+ type: 'PAUSE';
70
+ } | {
71
+ type: 'SEEK';
72
+ time: number;
73
+ } | {
74
+ type: 'SET_VOLUME';
75
+ volume: number;
76
+ } | {
77
+ type: 'BUFFER_READY';
78
+ } | {
79
+ type: 'BUFFER_ERROR';
80
+ } | {
81
+ type: 'HTML5_ENDED';
82
+ } | {
83
+ type: 'WEBAUDIO_ENDED';
84
+ } | {
85
+ type: 'URL_RESOLVED';
86
+ url: string;
87
+ } | {
88
+ type: 'START_FETCH';
89
+ } | {
90
+ type: 'SCHEDULE_GAPLESS';
91
+ when: number;
92
+ } | {
93
+ type: 'CANCEL_GAPLESS';
94
+ } | {
95
+ type: 'LOOKAHEAD_REACHED';
96
+ }, {
97
+ [x: string]: import("xstate").ActorRefFromLogic<import("xstate").StateMachine<import("./fetchDecode.machine").FetchDecodeContext, import("xstate").AnyEventObject, {
98
+ [x: string]: import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<void, void, import("xstate").EventObject> | import("xstate").PromiseActorLogic<void, {
99
+ resolvedUrl: string;
100
+ }, import("xstate").EventObject> | import("xstate").PromiseActorLogic<string | null, {
101
+ trackUrl: string;
102
+ }, import("xstate").EventObject>> | undefined;
103
+ }, {
104
+ src: "decodeAudio";
105
+ logic: import("xstate").PromiseActorLogic<void, void, import("xstate").EventObject>;
106
+ id: string | undefined;
107
+ } | {
108
+ src: "fetchAudio";
109
+ logic: import("xstate").PromiseActorLogic<void, {
110
+ resolvedUrl: string;
111
+ }, import("xstate").EventObject>;
112
+ id: string | undefined;
113
+ } | {
114
+ src: "resolveUrl";
115
+ logic: import("xstate").PromiseActorLogic<string | null, {
116
+ trackUrl: string;
117
+ }, import("xstate").EventObject>;
118
+ id: string | undefined;
119
+ }, never, {
120
+ type: "shouldSkipHEAD";
121
+ params: unknown;
122
+ }, never, "decoding" | "done" | "error" | "fetching" | "resolvingUrl", string, import("./fetchDecode.machine").FetchDecodeContext, import("xstate").NonReducibleUnknown, import("xstate").EventObject, import("xstate").MetaObject, {
123
+ id: "fetchDecode";
124
+ states: {
125
+ readonly resolvingUrl: {};
126
+ readonly fetching: {};
127
+ readonly decoding: {};
128
+ readonly done: {};
129
+ readonly error: {};
130
+ };
131
+ }, import("xstate").MetaObject>> | undefined;
132
+ }, {
133
+ src: "fetchDecode";
134
+ logic: import("xstate").StateMachine<import("./fetchDecode.machine").FetchDecodeContext, import("xstate").AnyEventObject, {
135
+ [x: string]: import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<void, void, import("xstate").EventObject> | import("xstate").PromiseActorLogic<void, {
136
+ resolvedUrl: string;
137
+ }, import("xstate").EventObject> | import("xstate").PromiseActorLogic<string | null, {
138
+ trackUrl: string;
139
+ }, import("xstate").EventObject>> | undefined;
140
+ }, {
141
+ src: "decodeAudio";
142
+ logic: import("xstate").PromiseActorLogic<void, void, import("xstate").EventObject>;
143
+ id: string | undefined;
144
+ } | {
145
+ src: "fetchAudio";
146
+ logic: import("xstate").PromiseActorLogic<void, {
147
+ resolvedUrl: string;
148
+ }, import("xstate").EventObject>;
149
+ id: string | undefined;
150
+ } | {
151
+ src: "resolveUrl";
152
+ logic: import("xstate").PromiseActorLogic<string | null, {
153
+ trackUrl: string;
154
+ }, import("xstate").EventObject>;
155
+ id: string | undefined;
156
+ }, never, {
157
+ type: "shouldSkipHEAD";
158
+ params: unknown;
159
+ }, never, "decoding" | "done" | "error" | "fetching" | "resolvingUrl", string, import("./fetchDecode.machine").FetchDecodeContext, import("xstate").NonReducibleUnknown, import("xstate").EventObject, import("xstate").MetaObject, {
160
+ id: "fetchDecode";
161
+ states: {
162
+ readonly resolvingUrl: {};
163
+ readonly fetching: {};
164
+ readonly decoding: {};
165
+ readonly done: {};
166
+ readonly error: {};
167
+ };
168
+ }, import("xstate").MetaObject>;
169
+ id: string | undefined;
170
+ }, {
171
+ type: "clearIsPlaying";
172
+ params: unknown;
173
+ } | {
174
+ type: "clearNotifiedLookahead";
175
+ params: unknown;
176
+ } | {
177
+ type: "clearPendingPlay";
178
+ params: unknown;
179
+ } | {
180
+ type: "clearPlayingAndSchedule";
181
+ params: unknown;
182
+ } | {
183
+ type: "clearScheduleAndLookahead";
184
+ params: unknown;
185
+ } | {
186
+ type: "clearScheduledStart";
187
+ params: unknown;
188
+ } | {
189
+ type: "crossoverHtml5ToWebAudio";
190
+ params: unknown;
191
+ } | {
192
+ type: "freezePausedTime";
193
+ params: unknown;
194
+ } | {
195
+ type: "notifyBufferReady";
196
+ params: unknown;
197
+ } | {
198
+ type: "notifyTrackEnded";
199
+ params: unknown;
200
+ } | {
201
+ type: "pauseHtml5";
202
+ params: unknown;
203
+ } | {
204
+ type: "playHtml5";
205
+ params: unknown;
206
+ } | {
207
+ type: "reportProgress";
208
+ params: unknown;
209
+ } | {
210
+ type: "resetHtml5Element";
211
+ params: unknown;
212
+ } | {
213
+ type: "resetTiming";
214
+ params: unknown;
215
+ } | {
216
+ type: "seekHtml5";
217
+ params: unknown;
218
+ } | {
219
+ type: "seekWebAudio";
220
+ params: unknown;
221
+ } | {
222
+ type: "setErrorState";
223
+ params: unknown;
224
+ } | {
225
+ type: "setIsPlaying";
226
+ params: unknown;
227
+ } | {
228
+ type: "setLoadedState";
229
+ params: unknown;
230
+ } | {
231
+ type: "setLoadingState";
232
+ params: unknown;
233
+ } | {
234
+ type: "setNotifiedLookahead";
235
+ params: unknown;
236
+ } | {
237
+ type: "setPendingPlay";
238
+ params: unknown;
239
+ } | {
240
+ type: "setPlaybackTypeWebAudio";
241
+ params: unknown;
242
+ } | {
243
+ type: "setPlayingWebAudio";
244
+ params: unknown;
245
+ } | {
246
+ type: "setPlayingWebAudioType";
247
+ params: unknown;
248
+ } | {
249
+ type: "setResolvedUrl";
250
+ params: unknown;
251
+ } | {
252
+ type: "setScheduledGapless";
253
+ params: unknown;
254
+ } | {
255
+ type: "startProgressLoop";
256
+ params: unknown;
257
+ } | {
258
+ type: "startScheduledSourceNode";
259
+ params: unknown;
260
+ } | {
261
+ type: "startSourceNode";
262
+ params: unknown;
263
+ } | {
264
+ type: "stopProgressLoop";
265
+ params: unknown;
266
+ } | {
267
+ type: "stopSourceNode";
268
+ params: unknown;
269
+ } | {
270
+ type: "triggerFetchForPendingPlay";
271
+ params: unknown;
272
+ }, {
273
+ type: "canPlayWebAudio";
274
+ params: unknown;
275
+ } | {
276
+ type: "canStartFetch";
277
+ params: unknown;
278
+ } | {
279
+ type: "isWebAudioOnly";
280
+ params: unknown;
281
+ }, never, "html5" | "idle" | "loading" | "webaudio", string, import("xstate").NonReducibleUnknown, import("xstate").NonReducibleUnknown, import("xstate").EventObject, import("xstate").MetaObject, {
282
+ id: "track";
283
+ states: {
284
+ readonly idle: {};
285
+ readonly html5: {};
286
+ readonly loading: {};
287
+ readonly webaudio: {};
288
+ };
289
+ }, import("xstate").MetaObject>;
290
+ export type TrackMachine = ReturnType<typeof createTrackMachine>;
291
+ //# sourceMappingURL=track.machine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"track.machine.d.ts","sourceRoot":"","sources":["../../src/machines/track.machine.ts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAInE,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,YAAY,CAAC;IAC3B,oBAAoB,EAAE,oBAAoB,CAAC;IAC3C,SAAS,EAAE,OAAO,CAAC;IACnB,yBAAyB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,+EAA+E;IAC/E,WAAW,EAAE,OAAO,CAAC;CACtB;AAID,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,GACtB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAC1B;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,eAAe,CAAA;CAAE,GACzB;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,GACxB;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,GACxB;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAC1B;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAC1B;IAAE,IAAI,EAAE,mBAAmB,CAAA;CAAE,CAAC;AAIlC,wBAAgB,kBAAkB,CAAC,cAAc,EAAE,YAAY;UArBnD,UAAU;;UACV,YAAY;;UACZ,SAAS;;UACT,gBAAgB;;UAChB,MAAM;;UACN,eAAe;;UACf,OAAO;;UACP,MAAM;UAAQ,MAAM;;UACpB,YAAY;YAAU,MAAM;;UAC5B,cAAc;;UACd,cAAc;;UACd,aAAa;;UACb,gBAAgB;;UAChB,cAAc;SAAO,MAAM;;UAC3B,aAAa;;UACb,kBAAkB;UAAQ,MAAM;;UAChC,gBAAgB;;UAChB,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gCA8a9B;AAED,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
@@ -0,0 +1,99 @@
1
+ export type PlaybackType = 'HTML5' | 'WEBAUDIO';
2
+ /**
3
+ * Controls how audio is rendered.
4
+ * - `'HYBRID'` (default): Starts with HTML5 audio, then switches to Web Audio after decode. Best for remote files.
5
+ * - `'HTML5_ONLY'`: Uses HTML5 audio exclusively. Gapless playback is not available.
6
+ * - `'WEBAUDIO_ONLY'`: Uses Web Audio API exclusively. Audio must fully buffer before playing — only use for very small or local files.
7
+ */
8
+ export type PlaybackMethod = 'HYBRID' | 'HTML5_ONLY' | 'WEBAUDIO_ONLY';
9
+ export type WebAudioLoadingState = 'NONE' | 'LOADING' | 'LOADED' | 'ERROR';
10
+ /** Metadata attached to a track (arbitrary user data). */
11
+ export interface TrackMetadata {
12
+ title?: string;
13
+ artist?: string;
14
+ album?: string;
15
+ artwork?: MediaImage[];
16
+ [key: string]: unknown;
17
+ }
18
+ /** Options accepted by the Queue constructor. */
19
+ export interface GaplessOptions {
20
+ /** Initial list of track URLs. */
21
+ tracks?: string[];
22
+ /** Called at ~60fps while playing. */
23
+ onProgress?: (info: TrackInfo) => void;
24
+ /** Called when the last track in the queue ends. */
25
+ onEnded?: () => void;
26
+ /** Called when the queue advances to the next track. */
27
+ onPlayNextTrack?: (info: TrackInfo) => void;
28
+ /** Called when the queue goes back to the previous track. */
29
+ onPlayPreviousTrack?: (info: TrackInfo) => void;
30
+ /** Called whenever a new track becomes the current track. */
31
+ onStartNewTrack?: (info: TrackInfo) => void;
32
+ /** Called on HTML5 audio errors. */
33
+ onError?: (error: Error) => void;
34
+ /** Called with internal debug messages. Only use for development. */
35
+ onDebug?: (msg: string) => void;
36
+ /** Called when autoplay is blocked by the browser. */
37
+ onPlayBlocked?: () => void;
38
+ /**
39
+ * Controls how audio is rendered.
40
+ * - `'HYBRID'` (default): Starts with HTML5 audio, switches to Web Audio after decode. Best for remote files.
41
+ * - `'HTML5_ONLY'`: HTML5 audio only. Gapless playback is not available.
42
+ * - `'WEBAUDIO_ONLY'`: Web Audio API only. Audio must fully buffer before playing.
43
+ */
44
+ playbackMethod?: PlaybackMethod;
45
+ /** Per-track metadata (aligned to the tracks array by index). */
46
+ trackMetadata?: TrackMetadata[];
47
+ /** Initial volume, 0.0–1.0. Defaults to 1. */
48
+ volume?: number;
49
+ /**
50
+ * Number of tracks to preload ahead of the current track.
51
+ * Defaults to 2. Set to 0 to disable preloading.
52
+ */
53
+ preloadNumTracks?: number;
54
+ /**
55
+ * Initial playback rate, 0.25–4.0. Defaults to 1.
56
+ */
57
+ playbackRate?: number;
58
+ }
59
+ /** Options for dynamically adding a track. */
60
+ export interface AddTrackOptions {
61
+ /**
62
+ * Skip the HEAD request used to resolve redirects.
63
+ * Set true when the URL is already a direct, final URL.
64
+ */
65
+ skipHEAD?: boolean;
66
+ metadata?: TrackMetadata;
67
+ }
68
+ /**
69
+ * A plain-data snapshot of a track's current state.
70
+ * Returned by Queue getters and passed to callbacks.
71
+ * No methods — pure data.
72
+ */
73
+ export interface TrackInfo {
74
+ /** Zero-based position of this track in the queue. */
75
+ index: number;
76
+ /** Current playback position in seconds. */
77
+ currentTime: number;
78
+ /** Total duration in seconds (NaN until loaded). */
79
+ duration: number;
80
+ /** True if currently playing. */
81
+ isPlaying: boolean;
82
+ /** True if explicitly paused. */
83
+ isPaused: boolean;
84
+ /** Current volume, 0.0–1.0. */
85
+ volume: number;
86
+ /** The resolved URL of the audio file. */
87
+ trackUrl: string;
88
+ /** Which backend is currently producing sound. */
89
+ playbackType: PlaybackType;
90
+ /** Whether the Web Audio buffer has been decoded. */
91
+ webAudioLoadingState: WebAudioLoadingState;
92
+ /** Arbitrary metadata supplied when the track was added. */
93
+ metadata?: TrackMetadata;
94
+ /** Current playback rate. */
95
+ playbackRate: number;
96
+ /** Current xstate machine state for this track (e.g. 'idle', 'html5', 'webaudio'). */
97
+ machineState: string;
98
+ }
99
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,UAAU,CAAC;AAEhD;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,YAAY,GAAG,eAAe,CAAC;AAEvE,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE3E,0DAA0D;AAC1D,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;IACvB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,iDAAiD;AACjD,MAAM,WAAW,cAAc;IAC7B,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,sCAAsC;IACtC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;IACvC,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,wDAAwD;IACxD,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;IAC5C,6DAA6D;IAC7D,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;IAChD,6DAA6D;IAC7D,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;IAC5C,oCAAoC;IACpC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,qEAAqE;IACrE,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,sDAAsD;IACtD,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B;;;;;OAKG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,iEAAiE;IACjE,aAAa,CAAC,EAAE,aAAa,EAAE,CAAC;IAChC,8CAA8C;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,8CAA8C;AAC9C,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAED;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,WAAW,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB,iCAAiC;IACjC,SAAS,EAAE,OAAO,CAAC;IACnB,iCAAiC;IACjC,QAAQ,EAAE,OAAO,CAAC;IAClB,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,kDAAkD;IAClD,YAAY,EAAE,YAAY,CAAC;IAC3B,qDAAqD;IACrD,oBAAoB,EAAE,oBAAoB,CAAC;IAC3C,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,6BAA6B;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,sFAAsF;IACtF,YAAY,EAAE,MAAM,CAAC;CACtB"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Return the shared AudioContext if it has already been created, otherwise null.
3
+ *
4
+ * Does NOT create the context — call resumeAudioContext() from a user-gesture
5
+ * handler to create and resume it. This prevents the browser warning:
6
+ * "An AudioContext was prevented from starting automatically."
7
+ */
8
+ export declare function getAudioContext(): AudioContext | null;
9
+ /**
10
+ * Create (if needed) and resume the AudioContext.
11
+ * Must be called from a user-gesture handler (click, keydown, etc.).
12
+ * Safe to call multiple times — subsequent calls are cheap no-ops.
13
+ */
14
+ export declare function resumeAudioContext(): Promise<void>;
15
+ /**
16
+ * Reset the cached AudioContext — used in tests so each test gets a fresh mock.
17
+ * @internal
18
+ */
19
+ export declare function _resetAudioContext(): void;
20
+ /**
21
+ * Directly set the cached AudioContext — used in tests to inject a mock instance.
22
+ * @internal
23
+ */
24
+ export declare function _setAudioContext(ctx: AudioContext | null): void;
25
+ //# sourceMappingURL=audioContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audioContext.d.ts","sourceRoot":"","sources":["../../src/utils/audioContext.ts"],"names":[],"mappings":"AAuBA;;;;;;GAMG;AACH,wBAAgB,eAAe,IAAI,YAAY,GAAG,IAAI,CAMrD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CASlD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,GAAG,IAAI,CAE/D"}
@@ -0,0 +1,17 @@
1
+ import type { TrackMetadata } from '../types';
2
+ export interface MediaSessionHandlers {
3
+ onPlay: () => void;
4
+ onPause: () => void;
5
+ onNext: () => void;
6
+ onPrevious: () => void;
7
+ onSeek: (time: number) => void;
8
+ }
9
+ /** Register Media Session action handlers. Call once after construction. */
10
+ export declare function setupMediaSession(handlers: MediaSessionHandlers): void;
11
+ /** Update the OS metadata display (title, artist, album, artwork). */
12
+ export declare function updateMediaSessionMetadata(metadata?: TrackMetadata): void;
13
+ /** Sync the OS playback state indicator (playing / paused). */
14
+ export declare function updateMediaSessionPlaybackState(isPlaying: boolean): void;
15
+ /** Update the OS position/duration display (lock screen scrubber). */
16
+ export declare function updateMediaSessionPositionState(duration: number, position: number, playbackRate?: number): void;
17
+ //# sourceMappingURL=mediaSession.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mediaSession.d.ts","sourceRoot":"","sources":["../../src/utils/mediaSession.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAK9C,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED,4EAA4E;AAC5E,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,oBAAoB,GAAG,IAAI,CAUtE;AAED,sEAAsE;AACtE,wBAAgB,0BAA0B,CAAC,QAAQ,CAAC,EAAE,aAAa,GAAG,IAAI,CAYzE;AAED,+DAA+D;AAC/D,wBAAgB,+BAA+B,CAC7C,SAAS,EAAE,OAAO,GACjB,IAAI,CAGN;AAED,sEAAsE;AACtE,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,YAAY,SAAI,GACf,IAAI,CAON"}
@@ -0,0 +1,3 @@
1
+ /** Returns a throttled version of `fn` that fires at most once per `ms`. */
2
+ export declare function throttle<T extends (...args: any[]) => void>(fn: T, ms: number): (...args: Parameters<T>) => void;
3
+ //# sourceMappingURL=throttle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"throttle.d.ts","sourceRoot":"","sources":["../../src/utils/throttle.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAE5E,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,EACzD,EAAE,EAAE,CAAC,EACL,EAAE,EAAE,MAAM,GACT,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,CAQlC"}