@lucaismyname/ginger 0.0.26 → 0.0.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +40 -68
  2. package/dist/analyzer/liveAudioGraph.test.d.ts +2 -0
  3. package/dist/analyzer/liveAudioGraph.test.d.ts.map +1 -0
  4. package/dist/analyzer/useGingerLiveAnalyzer.test.d.ts +2 -0
  5. package/dist/analyzer/useGingerLiveAnalyzer.test.d.ts.map +1 -0
  6. package/dist/audio/GingerPlayer.d.ts.map +1 -1
  7. package/dist/client.cjs +1 -1
  8. package/dist/client.js +37 -28
  9. package/dist/components/controls/Controls.d.ts +1 -1
  10. package/dist/components/controls/Controls.d.ts.map +1 -1
  11. package/dist/components/current/Artwork.d.ts.map +1 -1
  12. package/dist/components/current/Chapters.d.ts.map +1 -1
  13. package/dist/components/current/Lyrics.d.ts +3 -1
  14. package/dist/components/current/Lyrics.d.ts.map +1 -1
  15. package/dist/components/current/LyricsSynced.d.ts.map +1 -1
  16. package/dist/components/current/Playback.d.ts +1 -1
  17. package/dist/components/current/Playback.d.ts.map +1 -1
  18. package/dist/components/current/QueueMeta.d.ts +1 -1
  19. package/dist/components/current/QueueMeta.d.ts.map +1 -1
  20. package/dist/components/current/Time.d.ts +2 -2
  21. package/dist/components/current/Time.d.ts.map +1 -1
  22. package/dist/components/current/Year.d.ts +1 -1
  23. package/dist/components/current/Year.d.ts.map +1 -1
  24. package/dist/components/icons/Pause.d.ts +2 -0
  25. package/dist/components/icons/Pause.d.ts.map +1 -0
  26. package/dist/components/icons/Play.d.ts +2 -0
  27. package/dist/components/icons/Play.d.ts.map +1 -0
  28. package/dist/components/icons/RepeatGlyph.d.ts +5 -0
  29. package/dist/components/icons/RepeatGlyph.d.ts.map +1 -0
  30. package/dist/components/icons/ShuffleIcon.d.ts +2 -0
  31. package/dist/components/icons/ShuffleIcon.d.ts.map +1 -0
  32. package/dist/components/icons/SkipBack.d.ts +2 -0
  33. package/dist/components/icons/SkipBack.d.ts.map +1 -0
  34. package/dist/components/icons/SkipForward.d.ts +2 -0
  35. package/dist/components/icons/SkipForward.d.ts.map +1 -0
  36. package/dist/components/icons/Volume2.d.ts +2 -0
  37. package/dist/components/icons/Volume2.d.ts.map +1 -0
  38. package/dist/components/icons/VolumeX.d.ts +2 -0
  39. package/dist/components/icons/VolumeX.d.ts.map +1 -0
  40. package/dist/components/icons/Wrapper.d.ts +14 -0
  41. package/dist/components/icons/Wrapper.d.ts.map +1 -0
  42. package/dist/components/icons/index.d.ts +11 -0
  43. package/dist/components/icons/index.d.ts.map +1 -0
  44. package/dist/components/queue/QueueDisplay.d.ts.map +1 -1
  45. package/dist/context/GingerLocaleContext.d.ts.map +1 -1
  46. package/dist/context/GingerProvider.d.ts +1 -1
  47. package/dist/context/GingerProvider.d.ts.map +1 -1
  48. package/dist/ginger-B26HM2Ja.cjs +2 -0
  49. package/dist/ginger-B26HM2Ja.cjs.map +1 -0
  50. package/dist/ginger-DlNYfHbV.js +2278 -0
  51. package/dist/ginger-DlNYfHbV.js.map +1 -0
  52. package/dist/ginger.d.ts +12 -0
  53. package/dist/ginger.d.ts.map +1 -1
  54. package/dist/index.cjs +1 -1
  55. package/dist/index.d.ts +2 -0
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +37 -28
  58. package/dist/testing/helpers.d.ts +1 -1
  59. package/dist/testing/helpers.d.ts.map +1 -1
  60. package/dist/testing/index.cjs +1 -1
  61. package/dist/testing/index.cjs.map +1 -1
  62. package/dist/testing/index.js +1 -1
  63. package/dist/testing/index.js.map +1 -1
  64. package/dist/testing/mockWebAudio.d.ts +47 -0
  65. package/dist/testing/mockWebAudio.d.ts.map +1 -0
  66. package/dist/types.d.ts +9 -0
  67. package/dist/types.d.ts.map +1 -1
  68. package/dist/{useNextTrackPrefetch-eR_p__O2.js → useNextTrackPrefetch-Y_fs2JEx.js} +51 -51
  69. package/dist/{useNextTrackPrefetch-eR_p__O2.js.map → useNextTrackPrefetch-Y_fs2JEx.js.map} +1 -1
  70. package/dist/{useNextTrackPrefetch-Cs4A1oFv.cjs → useNextTrackPrefetch-wSILz6TL.cjs} +2 -2
  71. package/dist/{useNextTrackPrefetch-Cs4A1oFv.cjs.map → useNextTrackPrefetch-wSILz6TL.cjs.map} +1 -1
  72. package/package.json +2 -2
  73. package/dist/ginger-DE4TKdCR.js +0 -1877
  74. package/dist/ginger-DE4TKdCR.js.map +0 -1
  75. package/dist/ginger-yY4Y5liv.cjs +0 -2
  76. package/dist/ginger-yY4Y5liv.cjs.map +0 -1
@@ -0,0 +1,47 @@
1
+ type MockAudioContextState = AudioContextState;
2
+ declare class MockAudioNode {
3
+ readonly connections: MockAudioNode[];
4
+ readonly connectCalls: MockAudioNode[];
5
+ disconnectCalls: number;
6
+ connect(node: MockAudioNode): MockAudioNode;
7
+ disconnect(): void;
8
+ }
9
+ export declare class MockAudioDestinationNode extends MockAudioNode {
10
+ }
11
+ export declare class MockMediaElementAudioSourceNode extends MockAudioNode {
12
+ readonly mediaElement: HTMLAudioElement;
13
+ constructor(mediaElement: HTMLAudioElement);
14
+ }
15
+ export declare class MockAnalyserNode extends MockAudioNode {
16
+ fftSize: number;
17
+ smoothingTimeConstant: number;
18
+ minDecibels: number;
19
+ maxDecibels: number;
20
+ get frequencyBinCount(): number;
21
+ getByteFrequencyData(array: Uint8Array): void;
22
+ getByteTimeDomainData(array: Uint8Array): void;
23
+ }
24
+ export declare class MockAudioContext extends EventTarget {
25
+ readonly destination: MockAudioDestinationNode;
26
+ readonly sources: MockMediaElementAudioSourceNode[];
27
+ readonly analysers: MockAnalyserNode[];
28
+ sampleRate: number;
29
+ state: MockAudioContextState;
30
+ closeCalls: number;
31
+ resumeCalls: number;
32
+ createMediaElementSource(element: HTMLAudioElement): MediaElementAudioSourceNode;
33
+ createAnalyser(): AnalyserNode;
34
+ resume(): Promise<void>;
35
+ close(): Promise<void>;
36
+ setStateForTest(nextState: MockAudioContextState): void;
37
+ }
38
+ export type MockWebAudioInstall = {
39
+ contexts: MockAudioContext[];
40
+ flushAnimationFrame: (time?: number) => void;
41
+ flushAnimationFrames: (count: number) => void;
42
+ pendingAnimationFrameCount: () => number;
43
+ restore: () => void;
44
+ };
45
+ export declare function installMockWebAudio(): MockWebAudioInstall;
46
+ export {};
47
+ //# sourceMappingURL=mockWebAudio.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mockWebAudio.d.ts","sourceRoot":"","sources":["../../src/testing/mockWebAudio.ts"],"names":[],"mappings":"AAAA,KAAK,qBAAqB,GAAG,iBAAiB,CAAC;AAE/C,cAAM,aAAa;IACjB,QAAQ,CAAC,WAAW,EAAE,aAAa,EAAE,CAAM;IAC3C,QAAQ,CAAC,YAAY,EAAE,aAAa,EAAE,CAAM;IAC5C,eAAe,SAAK;IAEpB,OAAO,CAAC,IAAI,EAAE,aAAa;IAM3B,UAAU;CAIX;AAED,qBAAa,wBAAyB,SAAQ,aAAa;CAAG;AAE9D,qBAAa,+BAAgC,SAAQ,aAAa;IACpD,QAAQ,CAAC,YAAY,EAAE,gBAAgB;gBAA9B,YAAY,EAAE,gBAAgB;CAGpD;AAED,qBAAa,gBAAiB,SAAQ,aAAa;IACjD,OAAO,SAAQ;IACf,qBAAqB,SAAO;IAC5B,WAAW,SAAQ;IACnB,WAAW,SAAO;IAElB,IAAI,iBAAiB,WAEpB;IAED,oBAAoB,CAAC,KAAK,EAAE,UAAU;IAMtC,qBAAqB,CAAC,KAAK,EAAE,UAAU;CAKxC;AAED,qBAAa,gBAAiB,SAAQ,WAAW;IAC/C,QAAQ,CAAC,WAAW,2BAAkC;IACtD,QAAQ,CAAC,OAAO,EAAE,+BAA+B,EAAE,CAAM;IACzD,QAAQ,CAAC,SAAS,EAAE,gBAAgB,EAAE,CAAM;IAE5C,UAAU,SAAU;IACpB,KAAK,EAAE,qBAAqB,CAAa;IACzC,UAAU,SAAK;IACf,WAAW,SAAK;IAEhB,wBAAwB,CAAC,OAAO,EAAE,gBAAgB,GAGpB,2BAA2B;IAGzD,cAAc,IAGkB,YAAY;IAGtC,MAAM;IAON,KAAK;IAKX,eAAe,CAAC,SAAS,EAAE,qBAAqB;CAKjD;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,mBAAmB,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,oBAAoB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,0BAA0B,EAAE,MAAM,MAAM,CAAC;IACzC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,wBAAgB,mBAAmB,IAAI,mBAAmB,CAgFzD"}
package/dist/types.d.ts CHANGED
@@ -6,6 +6,10 @@ export type GingerLocaleMessages = {
6
6
  seek: string;
7
7
  volume: string;
8
8
  playbackSpeed: string;
9
+ /** Accessible name for the chapter list (`Ginger.Current.Chapters`). */
10
+ chaptersList: string;
11
+ /** Accessible name for the synced lyrics list (`Ginger.Current.LyricsSynced`). */
12
+ syncedLyricsList: string;
9
13
  nextTrack: string;
10
14
  previousTrack: string;
11
15
  shuffle: string;
@@ -236,6 +240,11 @@ export type GingerProviderProps = {
236
240
  resumeOnTrackChange?: boolean;
237
241
  /** Disable default CSS variable/theme styles on provider root. */
238
242
  unstyled?: boolean;
243
+ /**
244
+ * Merge provider props (`className`, `style`, `data-ginger-playback`, `dir`) onto the single child
245
+ * element instead of wrapping in an extra `div`. Use for layout systems that forbid wrapper nodes.
246
+ */
247
+ asChild?: boolean;
239
248
  className?: string;
240
249
  style?: CSSProperties;
241
250
  onTrackChange?: (track: Track | null, index: number) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { useMemo as V, useState as R, useRef as M, useCallback as H, useLayoutEffect as J, useEffect as b } from "react";
2
2
  import { b as S, u as z, g as O, c as Y } from "./GingerSplitContexts-BzBExb95.js";
3
- import { r as Z, j as _, k as Q, l as $, m as ee, b as te, n as ne, o as re } from "./ginger-DE4TKdCR.js";
3
+ import { r as Z, n as _, o as Q, q as $, s as ee, h as te, t as ne, v as re } from "./ginger-DlNYfHbV.js";
4
4
  function se() {
5
5
  const t = S(), e = z();
6
6
  return V(() => {
@@ -53,8 +53,8 @@ function oe(t, e) {
53
53
  const f = window.AudioContext ?? window.webkitAudioContext;
54
54
  if (!f)
55
55
  throw new Error("Web Audio API is not available");
56
- const u = new f(), m = u.createMediaElementSource(t);
57
- n = { context: u, source: m, consumers: /* @__PURE__ */ new Map(), nextId: 0 }, U.set(t, n);
56
+ const u = new f(), d = u.createMediaElementSource(t);
57
+ n = { context: u, source: d, consumers: /* @__PURE__ */ new Map(), nextId: 0 }, U.set(t, n);
58
58
  }
59
59
  const { context: s, source: o } = n, r = s.createAnalyser();
60
60
  r.fftSize = ae(e.fftSize), r.smoothingTimeConstant = e.smoothingTimeConstant, r.minDecibels = e.minDecibels, r.maxDecibels = e.maxDecibels, o.connect(r);
@@ -98,51 +98,51 @@ function fe(t = {}) {
98
98
  maxDecibels: r
99
99
  }),
100
100
  [n, s, o, r]
101
- ), [u, m] = R(0), [d, c] = R(null), [w, g] = R(!1), [C, A] = R({ frequencyBinCount: 0, sampleRate: 0 }), p = M(q), k = M(F), W = H(async () => {
102
- const x = P.current;
103
- x && x.state === "suspended" && await x.resume();
104
- }, []), P = M(null), L = M(null);
101
+ ), [u, d] = R(0), [m, c] = R(null), [w, g] = R(!1), [C, A] = R({ frequencyBinCount: 0, sampleRate: 0 }), p = M(q), k = M(F), W = H(async () => {
102
+ const v = h.current;
103
+ v && v.state === "suspended" && await v.resume();
104
+ }, []), h = M(null), L = M(null);
105
105
  return J(() => {
106
106
  if (!e || typeof window > "u")
107
107
  return;
108
- let x = !1, D = null, E = null, I = 0;
108
+ let v = !1, D = null, E = null, I = 0;
109
109
  const B = () => {
110
- const l = P.current;
110
+ const l = h.current;
111
111
  l && g(l.state === "suspended");
112
112
  }, G = () => {
113
- if (x) return;
114
- const l = L.current, v = p.current, y = k.current;
115
- l && v.length > 0 && y.length > 0 && (l.getByteFrequencyData(v), l.getByteTimeDomainData(y), m((T) => T + 1)), I = requestAnimationFrame(G);
113
+ if (v) return;
114
+ const l = L.current, x = p.current, y = k.current;
115
+ l && x.length > 0 && y.length > 0 && (l.getByteFrequencyData(x), l.getByteTimeDomainData(y), d((P) => P + 1)), I = requestAnimationFrame(G);
116
116
  }, N = () => {
117
117
  const l = a.current;
118
- if (!l || x) return "no-element";
118
+ if (!l || v) return "no-element";
119
119
  try {
120
- const { id: v, context: y, analyser: T } = oe(l, f);
121
- D = v, E = l, P.current = y, L.current = T, g(y.state === "suspended"), c(null), y.addEventListener("statechange", B);
122
- const h = T.frequencyBinCount, j = T.fftSize;
123
- return p.current = new Uint8Array(h), k.current = new Uint8Array(j), A({ frequencyBinCount: h, sampleRate: y.sampleRate }), I = requestAnimationFrame(G), "ok";
124
- } catch (v) {
125
- const y = v instanceof Error ? v.message : "Failed to attach live analyser";
126
- return c(y), P.current = null, L.current = null, p.current = q, k.current = F, A({ frequencyBinCount: 0, sampleRate: 0 }), "error";
120
+ const { id: x, context: y, analyser: P } = oe(l, f);
121
+ D = x, E = l, h.current = y, L.current = P, g(y.state === "suspended"), c(null), y.addEventListener("statechange", B);
122
+ const T = P.frequencyBinCount, j = P.fftSize;
123
+ return p.current = new Uint8Array(T), k.current = new Uint8Array(j), A({ frequencyBinCount: T, sampleRate: y.sampleRate }), I = requestAnimationFrame(G), "ok";
124
+ } catch (x) {
125
+ const y = x instanceof Error ? x.message : "Failed to attach live analyser";
126
+ return c(y), h.current = null, L.current = null, p.current = q, k.current = F, A({ frequencyBinCount: 0, sampleRate: 0 }), "error";
127
127
  }
128
128
  }, K = N();
129
129
  if (K !== "ok") {
130
130
  let l = 0;
131
- const v = 120;
131
+ const x = 120;
132
132
  let y = 0;
133
- const T = () => {
134
- if (x) return;
135
- const h = N();
136
- h === "ok" || h === "error" || (y += 1, !(y >= v) && (l = requestAnimationFrame(T)));
133
+ const P = () => {
134
+ if (v) return;
135
+ const T = N();
136
+ T === "ok" || T === "error" || (y += 1, !(y >= x) && (l = requestAnimationFrame(P)));
137
137
  };
138
- return K === "no-element" && (l = requestAnimationFrame(T)), () => {
139
- var h;
140
- x = !0, cancelAnimationFrame(l), cancelAnimationFrame(I), D != null && E && X(E, D), (h = P.current) == null || h.removeEventListener("statechange", B), P.current = null, L.current = null, p.current = q, k.current = F;
138
+ return K === "no-element" && (l = requestAnimationFrame(P)), () => {
139
+ var T;
140
+ v = !0, cancelAnimationFrame(l), cancelAnimationFrame(I), D != null && E && X(E, D), (T = h.current) == null || T.removeEventListener("statechange", B), h.current = null, L.current = null, p.current = q, k.current = F;
141
141
  };
142
142
  }
143
143
  return () => {
144
144
  var l;
145
- x = !0, cancelAnimationFrame(I), D != null && E && X(E, D), (l = P.current) == null || l.removeEventListener("statechange", B), P.current = null, L.current = null, p.current = q, k.current = F, A({ frequencyBinCount: 0, sampleRate: 0 });
145
+ v = !0, cancelAnimationFrame(I), D != null && E && X(E, D), (l = h.current) == null || l.removeEventListener("statechange", B), h.current = null, L.current = null, p.current = q, k.current = F, A({ frequencyBinCount: 0, sampleRate: 0 });
146
146
  };
147
147
  }, [e, a, f, i.currentIndex]), {
148
148
  frequencyData: p.current,
@@ -150,22 +150,22 @@ function fe(t = {}) {
150
150
  frequencyBinCount: C.frequencyBinCount,
151
151
  sampleRate: C.sampleRate,
152
152
  isSuspended: w,
153
- error: d,
153
+ error: m,
154
154
  resume: W
155
155
  };
156
156
  }
157
- function me(t = !0, e = {}) {
157
+ function de(t = !0, e = {}) {
158
158
  const { togglePlayPause: n, next: s, prev: o } = S(), { toggleMute: r } = z(), a = e.mute;
159
159
  b(() => {
160
160
  if (!t || typeof window > "u") return;
161
- const i = (e.playPause ?? " ").toLowerCase(), f = (e.next ?? "ArrowRight").toLowerCase(), u = (e.previous ?? "ArrowLeft").toLowerCase(), m = a == null ? void 0 : a.toLowerCase(), d = (c) => {
161
+ const i = (e.playPause ?? " ").toLowerCase(), f = (e.next ?? "ArrowRight").toLowerCase(), u = (e.previous ?? "ArrowLeft").toLowerCase(), d = a == null ? void 0 : a.toLowerCase(), m = (c) => {
162
162
  const w = c.target;
163
163
  if (w && (["INPUT", "TEXTAREA", "SELECT"].includes(w.tagName) || w.isContentEditable))
164
164
  return;
165
165
  const g = c.key.toLowerCase();
166
- g === i ? (c.preventDefault(), n()) : g === f ? (c.preventDefault(), s()) : g === u ? (c.preventDefault(), o()) : m && g === m && (c.preventDefault(), r());
166
+ g === i ? (c.preventDefault(), n()) : g === f ? (c.preventDefault(), s()) : g === u ? (c.preventDefault(), o()) : d && g === d && (c.preventDefault(), r());
167
167
  };
168
- return window.addEventListener("keydown", d), () => window.removeEventListener("keydown", d);
168
+ return window.addEventListener("keydown", m), () => window.removeEventListener("keydown", m);
169
169
  }, [
170
170
  e.next,
171
171
  e.playPause,
@@ -178,20 +178,20 @@ function me(t = !0, e = {}) {
178
178
  n
179
179
  ]);
180
180
  }
181
- function de(t) {
182
- const { durationMs: e, stopAfterTracks: n, respectPause: s = !0, enabled: o = !0, onFire: r } = t, { currentIndex: a, pause: i, isPaused: f } = S(), u = M(n ?? 0), m = M(a);
181
+ function me(t) {
182
+ const { durationMs: e, stopAfterTracks: n, respectPause: s = !0, enabled: o = !0, onFire: r } = t, { currentIndex: a, pause: i, isPaused: f } = S(), u = M(n ?? 0), d = M(a);
183
183
  b(() => {
184
184
  u.current = n ?? 0;
185
185
  }, [n]), b(() => {
186
186
  if (!o || !e || e <= 0 || s && f) return;
187
- const d = setTimeout(() => {
187
+ const m = setTimeout(() => {
188
188
  i(), r == null || r();
189
189
  }, e);
190
- return () => clearTimeout(d);
190
+ return () => clearTimeout(m);
191
191
  }, [e, o, f, r, i, s]), b(() => {
192
192
  if (!o || !n || n <= 0) return;
193
- const d = m.current;
194
- m.current = a, a !== d && (u.current -= 1, u.current <= 0 && (i(), r == null || r()));
193
+ const m = d.current;
194
+ d.current = a, a !== m && (u.current -= 1, u.current <= 0 && (i(), r == null || r()));
195
195
  }, [a, o, r, i, n]);
196
196
  }
197
197
  function pe(t = !1) {
@@ -219,31 +219,31 @@ function ce(t) {
219
219
  return Math.max(0, Math.min(1, t));
220
220
  }
221
221
  function ye(t) {
222
- const e = z(), n = S(), { seek: s } = e, [o, r] = R(0), [a, i] = R(!1), f = Q(O(n, e)), u = a ? o : f, m = H(
223
- (d) => {
222
+ const e = z(), n = S(), { seek: s } = e, [o, r] = R(0), [a, i] = R(!1), f = Q(O(n, e)), u = a ? o : f, d = H(
223
+ (m) => {
224
224
  if (!(t > 0)) return;
225
- const c = d.currentTarget, w = c.getBoundingClientRect(), g = (p) => {
225
+ const c = m.currentTarget, w = c.getBoundingClientRect(), g = (p) => {
226
226
  const k = ce((p - w.left) / w.width);
227
227
  r(k), s(k * t);
228
228
  };
229
- i(!0), c.setPointerCapture(d.pointerId), g(d.clientX);
229
+ i(!0), c.setPointerCapture(m.pointerId), g(m.clientX);
230
230
  const C = (p) => g(p.clientX), A = (p) => {
231
- g(p.clientX), i(!1), c.releasePointerCapture(d.pointerId), c.removeEventListener("pointermove", C), c.removeEventListener("pointerup", A), c.removeEventListener("pointercancel", A);
231
+ g(p.clientX), i(!1), c.releasePointerCapture(m.pointerId), c.removeEventListener("pointermove", C), c.removeEventListener("pointerup", A), c.removeEventListener("pointercancel", A);
232
232
  };
233
233
  c.addEventListener("pointermove", C), c.addEventListener("pointerup", A), c.addEventListener("pointercancel", A);
234
234
  },
235
235
  [t, s]
236
236
  );
237
- return { fraction: o, displayFraction: u, isDragging: a, onPointerDown: m };
237
+ return { fraction: o, displayFraction: u, isDragging: a, onPointerDown: d };
238
238
  }
239
239
  function ge(t = {}) {
240
240
  const { enabled: e = !0, crossOrigin: n } = t, { tracks: s, currentIndex: o, repeatMode: r, playbackMode: a } = S();
241
241
  b(() => {
242
- var m;
242
+ var d;
243
243
  if (!e || typeof document > "u") return;
244
244
  const i = re({ tracks: s, currentIndex: o, repeatMode: r, playbackMode: a });
245
245
  if (i === o) return;
246
- const f = ((m = s[i]) == null ? void 0 : m.fileUrl) ?? "";
246
+ const f = ((d = s[i]) == null ? void 0 : d.fileUrl) ?? "";
247
247
  if (!f) return;
248
248
  const u = document.createElement("audio");
249
249
  return u.preload = "auto", n && (u.crossOrigin = n), u.src = f, u.load(), () => {
@@ -254,12 +254,12 @@ function ge(t = {}) {
254
254
  export {
255
255
  oe as a,
256
256
  pe as b,
257
- me as c,
257
+ de as c,
258
258
  X as d,
259
259
  fe as e,
260
- de as f,
260
+ me as f,
261
261
  ge as g,
262
262
  ye as h,
263
263
  se as u
264
264
  };
265
- //# sourceMappingURL=useNextTrackPrefetch-eR_p__O2.js.map
265
+ //# sourceMappingURL=useNextTrackPrefetch-Y_fs2JEx.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useNextTrackPrefetch-eR_p__O2.js","sources":["../src/hooks/useGinger.ts","../src/analyzer/liveAudioGraph.ts","../src/analyzer/useGingerLiveAnalyzer.ts","../src/hooks/useGingerKeyboardShortcuts.ts","../src/hooks/useGingerSleepTimer.ts","../src/hooks/useGingerDebugLog.ts","../src/hooks/useSeekDrag.ts","../src/hooks/useNextTrackPrefetch.ts"],"sourcesContent":["import { useMemo } from \"react\";\nimport {\n gingerStateFromContextValues,\n useGingerMedia,\n useGingerPlayback,\n} from \"../context/GingerSplitContexts\";\nimport {\n derivePlaybackUiState,\n effectiveDuration,\n effectiveRemaining,\n getCurrentTrack,\n progressFraction,\n resolvedAlbumLine,\n resolvedArtwork,\n} from \"../internal/selectors\";\n\nexport function useGinger() {\n const pb = useGingerPlayback();\n const md = useGingerMedia();\n\n return useMemo(() => {\n const state = gingerStateFromContextValues(pb, md);\n return {\n state,\n currentTrack: getCurrentTrack(state),\n playbackUi: derivePlaybackUiState(state),\n duration: effectiveDuration(state),\n remaining: effectiveRemaining(state),\n progress: progressFraction(state),\n artworkUrl: resolvedArtwork(state),\n albumLine: resolvedAlbumLine(state),\n play: pb.play,\n pause: pb.pause,\n togglePlayPause: pb.togglePlayPause,\n seek: md.seek,\n setVolume: md.setVolume,\n setMuted: md.setMuted,\n toggleMute: md.toggleMute,\n setPlaybackRate: md.setPlaybackRate,\n next: pb.next,\n prev: pb.prev,\n setRepeatMode: pb.setRepeatMode,\n cycleRepeat: pb.cycleRepeat,\n toggleShuffle: pb.toggleShuffle,\n setQueue: pb.setQueue,\n insertTrackAt: pb.insertTrackAt,\n removeTrackAt: pb.removeTrackAt,\n moveTrack: pb.moveTrack,\n enqueueNext: pb.enqueueNext,\n playTrackAt: pb.playTrackAt,\n selectTrackAt: pb.selectTrackAt,\n setPlaylistMeta: pb.setPlaylistMeta,\n setPlaybackMode: pb.setPlaybackMode,\n init: pb.init,\n audioRef: md.audioRef,\n dispatch: pb.dispatch,\n };\n }, [pb, md]);\n}\n","/** One MediaElementAudioSourceNode per HTMLAudioElement; multiple AnalyserNodes may tap the source. */\n\nexport type LiveAnalyserOptions = {\n fftSize: number;\n smoothingTimeConstant: number;\n minDecibels: number;\n maxDecibels: number;\n};\n\ntype Consumer = {\n analyser: AnalyserNode;\n /** This analyser is wired to `audioContext.destination` so the graph is audible. */\n isPlaybackSink: boolean;\n};\n\ntype ElementEntry = {\n context: AudioContext;\n source: MediaElementAudioSourceNode;\n consumers: Map<number, Consumer>;\n nextId: number;\n};\n\nconst entries = new WeakMap<HTMLAudioElement, ElementEntry>();\n\nfunction clampFftSize(n: number): number {\n const p = 2 ** Math.round(Math.log2(n));\n return Math.min(32768, Math.max(32, p));\n}\n\nexport function attachLiveAnalyser(\n element: HTMLAudioElement,\n options: LiveAnalyserOptions,\n): { id: number; context: AudioContext; analyser: AnalyserNode } {\n let entry = entries.get(element);\n if (!entry) {\n const Context =\n window.AudioContext ??\n (window as unknown as { webkitAudioContext?: typeof AudioContext }).webkitAudioContext;\n if (!Context) {\n throw new Error(\"Web Audio API is not available\");\n }\n const context = new Context();\n const source = context.createMediaElementSource(element);\n entry = { context, source, consumers: new Map(), nextId: 0 };\n entries.set(element, entry);\n }\n\n const { context, source } = entry;\n const analyser = context.createAnalyser();\n analyser.fftSize = clampFftSize(options.fftSize);\n analyser.smoothingTimeConstant = options.smoothingTimeConstant;\n analyser.minDecibels = options.minDecibels;\n analyser.maxDecibels = options.maxDecibels;\n\n source.connect(analyser);\n\n const isFirst = entry.consumers.size === 0;\n if (isFirst) {\n analyser.connect(context.destination);\n }\n\n const id = entry.nextId;\n entry.nextId += 1;\n entry.consumers.set(id, { analyser, isPlaybackSink: isFirst });\n\n return { id, context, analyser };\n}\n\nexport function detachLiveAnalyser(element: HTMLAudioElement, id: number): void {\n const entry = entries.get(element);\n if (!entry) return;\n\n const consumer = entry.consumers.get(id);\n if (!consumer) return;\n\n const { analyser, isPlaybackSink } = consumer;\n analyser.disconnect();\n entry.consumers.delete(id);\n\n if (entry.consumers.size === 0) {\n try {\n entry.source.disconnect();\n } catch {\n // ignore\n }\n void entry.context.close();\n entries.delete(element);\n return;\n }\n\n if (isPlaybackSink) {\n const first = entry.consumers.values().next().value as Consumer | undefined;\n if (first) {\n first.analyser.connect(entry.context.destination);\n first.isPlaybackSink = true;\n }\n }\n}\n","import { useCallback, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { useGinger } from \"../hooks/useGinger\";\nimport { type LiveAnalyserOptions, attachLiveAnalyser, detachLiveAnalyser } from \"./liveAudioGraph\";\n\nexport type UseGingerLiveAnalyzerOptions = {\n /** When false, the analyser is detached and no frames are read. Default true. */\n enabled?: boolean;\n fftSize?: number;\n smoothingTimeConstant?: number;\n minDecibels?: number;\n maxDecibels?: number;\n};\n\nexport type UseGingerLiveAnalyzerResult = {\n /** Byte frequency data (0–255); length equals `frequencyBinCount`. Updated each animation frame while enabled. */\n frequencyData: Uint8Array;\n /** Byte time-domain data (0–255); length equals `fftSize`. */\n timeDomainData: Uint8Array;\n frequencyBinCount: number;\n sampleRate: number;\n isSuspended: boolean;\n error: string | null;\n resume: () => Promise<void>;\n};\n\nconst emptyFreq = new Uint8Array(0);\nconst emptyTime = new Uint8Array(0);\n\nexport function useGingerLiveAnalyzer(\n options: UseGingerLiveAnalyzerOptions = {},\n): UseGingerLiveAnalyzerResult {\n const {\n enabled = true,\n fftSize = 2048,\n smoothingTimeConstant = 0.8,\n minDecibels = -100,\n maxDecibels = -30,\n } = options;\n\n const { audioRef, state } = useGinger();\n const opts = useMemo<LiveAnalyserOptions>(\n () => ({\n fftSize,\n smoothingTimeConstant,\n minDecibels,\n maxDecibels,\n }),\n [fftSize, smoothingTimeConstant, minDecibels, maxDecibels],\n );\n\n const [frame, setFrame] = useState(0);\n const [error, setError] = useState<string | null>(null);\n const [isSuspended, setIsSuspended] = useState(false);\n const [meta, setMeta] = useState({ frequencyBinCount: 0, sampleRate: 0 });\n\n const freqRef = useRef<Uint8Array>(emptyFreq);\n const timeRef = useRef<Uint8Array>(emptyTime);\n\n const resume = useCallback(async () => {\n const ctx = contextHolderRef.current;\n if (ctx && ctx.state === \"suspended\") {\n await ctx.resume();\n }\n }, []);\n\n const contextHolderRef = useRef<AudioContext | null>(null);\n const analyserHolderRef = useRef<AnalyserNode | null>(null);\n\n useLayoutEffect(() => {\n if (!enabled || typeof window === \"undefined\") {\n return;\n }\n\n let cancelled = false;\n let consumerId: number | null = null;\n let element: HTMLAudioElement | null = null;\n let rafId = 0;\n\n const onStateChange = () => {\n const ctx = contextHolderRef.current;\n if (ctx) setIsSuspended(ctx.state === \"suspended\");\n };\n\n const runLoop = () => {\n if (cancelled) return;\n const a = analyserHolderRef.current;\n const fq = freqRef.current;\n const td = timeRef.current;\n if (a && fq.length > 0 && td.length > 0) {\n a.getByteFrequencyData(fq as Uint8Array<ArrayBuffer>);\n a.getByteTimeDomainData(td as Uint8Array<ArrayBuffer>);\n setFrame((n) => n + 1);\n }\n rafId = requestAnimationFrame(runLoop);\n };\n\n type AttachOutcome = \"ok\" | \"no-element\" | \"error\";\n\n const attach = (): AttachOutcome => {\n const el = audioRef.current;\n if (!el || cancelled) return \"no-element\";\n try {\n const { id, context, analyser } = attachLiveAnalyser(el, opts);\n consumerId = id;\n element = el;\n contextHolderRef.current = context;\n analyserHolderRef.current = analyser;\n setIsSuspended(context.state === \"suspended\");\n setError(null);\n\n context.addEventListener(\"statechange\", onStateChange);\n\n const n = analyser.frequencyBinCount;\n const fft = analyser.fftSize;\n freqRef.current = new Uint8Array(n);\n timeRef.current = new Uint8Array(fft);\n setMeta({ frequencyBinCount: n, sampleRate: context.sampleRate });\n\n rafId = requestAnimationFrame(runLoop);\n return \"ok\";\n } catch (e) {\n const msg = e instanceof Error ? e.message : \"Failed to attach live analyser\";\n setError(msg);\n contextHolderRef.current = null;\n analyserHolderRef.current = null;\n freqRef.current = emptyFreq;\n timeRef.current = emptyTime;\n setMeta({ frequencyBinCount: 0, sampleRate: 0 });\n return \"error\";\n }\n };\n\n const first = attach();\n if (first !== \"ok\") {\n let retryRaf = 0;\n const maxAttempts = 120;\n let attempts = 0;\n\n const retryLoop = () => {\n if (cancelled) return;\n const out = attach();\n if (out === \"ok\" || out === \"error\") return;\n attempts += 1;\n if (attempts >= maxAttempts) return;\n retryRaf = requestAnimationFrame(retryLoop);\n };\n\n if (first === \"no-element\") {\n retryRaf = requestAnimationFrame(retryLoop);\n }\n\n return () => {\n cancelled = true;\n cancelAnimationFrame(retryRaf);\n cancelAnimationFrame(rafId);\n if (consumerId != null && element) {\n detachLiveAnalyser(element, consumerId);\n }\n contextHolderRef.current?.removeEventListener(\"statechange\", onStateChange);\n contextHolderRef.current = null;\n analyserHolderRef.current = null;\n freqRef.current = emptyFreq;\n timeRef.current = emptyTime;\n };\n }\n\n return () => {\n cancelled = true;\n cancelAnimationFrame(rafId);\n if (consumerId != null && element) {\n detachLiveAnalyser(element, consumerId);\n }\n contextHolderRef.current?.removeEventListener(\"statechange\", onStateChange);\n contextHolderRef.current = null;\n analyserHolderRef.current = null;\n freqRef.current = emptyFreq;\n timeRef.current = emptyTime;\n setMeta({ frequencyBinCount: 0, sampleRate: 0 });\n };\n }, [enabled, audioRef, opts, state.currentIndex]);\n\n void frame;\n\n return {\n frequencyData: freqRef.current,\n timeDomainData: timeRef.current,\n frequencyBinCount: meta.frequencyBinCount,\n sampleRate: meta.sampleRate,\n isSuspended,\n error,\n resume,\n };\n}\n","import { useEffect } from \"react\";\nimport { useGingerMedia, useGingerPlayback } from \"../context/GingerSplitContexts\";\n\nexport type GingerKeyboardShortcutBindings = {\n playPause?: string;\n next?: string;\n previous?: string;\n mute?: string;\n};\n\nexport function useGingerKeyboardShortcuts(\n enabled = true,\n bindings: GingerKeyboardShortcutBindings = {},\n): void {\n const { togglePlayPause, next, prev } = useGingerPlayback();\n const { toggleMute } = useGingerMedia();\n\n const muteBinding = bindings.mute;\n\n useEffect(() => {\n if (!enabled || typeof window === \"undefined\") return;\n const playPause = (bindings.playPause ?? \" \").toLowerCase();\n const nextKey = (bindings.next ?? \"ArrowRight\").toLowerCase();\n const prevKey = (bindings.previous ?? \"ArrowLeft\").toLowerCase();\n const muteKey = muteBinding?.toLowerCase();\n\n const onKeyDown = (event: KeyboardEvent) => {\n const target = event.target as HTMLElement | null;\n if (\n target &&\n ([\"INPUT\", \"TEXTAREA\", \"SELECT\"].includes(target.tagName) || target.isContentEditable)\n )\n return;\n const key = event.key.toLowerCase();\n if (key === playPause) {\n event.preventDefault();\n togglePlayPause();\n } else if (key === nextKey) {\n event.preventDefault();\n next();\n } else if (key === prevKey) {\n event.preventDefault();\n prev();\n } else if (muteKey && key === muteKey) {\n event.preventDefault();\n toggleMute();\n }\n };\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [\n bindings.next,\n bindings.playPause,\n bindings.previous,\n enabled,\n muteBinding,\n next,\n prev,\n toggleMute,\n togglePlayPause,\n ]);\n}\n","import { useEffect, useRef } from \"react\";\nimport { useGingerPlayback } from \"../context/GingerSplitContexts\";\n\nexport type GingerSleepTimerOptions = {\n durationMs?: number;\n stopAfterTracks?: number;\n respectPause?: boolean;\n enabled?: boolean;\n onFire?: () => void;\n};\n\nexport function useGingerSleepTimer(options: GingerSleepTimerOptions): void {\n const { durationMs, stopAfterTracks, respectPause = true, enabled = true, onFire } = options;\n const { currentIndex, pause, isPaused } = useGingerPlayback();\n const remainingTracksRef = useRef(stopAfterTracks ?? 0);\n const prevIndexRef = useRef(currentIndex);\n\n useEffect(() => {\n remainingTracksRef.current = stopAfterTracks ?? 0;\n }, [stopAfterTracks]);\n\n useEffect(() => {\n if (!enabled || !durationMs || durationMs <= 0) return;\n if (respectPause && isPaused) return;\n const id = setTimeout(() => {\n pause();\n onFire?.();\n }, durationMs);\n return () => clearTimeout(id);\n }, [durationMs, enabled, isPaused, onFire, pause, respectPause]);\n\n useEffect(() => {\n if (!enabled || !stopAfterTracks || stopAfterTracks <= 0) return;\n const prev = prevIndexRef.current;\n prevIndexRef.current = currentIndex;\n if (currentIndex === prev) return;\n remainingTracksRef.current -= 1;\n if (remainingTracksRef.current <= 0) {\n pause();\n onFire?.();\n }\n }, [currentIndex, enabled, onFire, pause, stopAfterTracks]);\n}\n","import { useEffect, useRef } from \"react\";\nimport { useGingerState } from \"../context/GingerSplitContexts\";\n\nexport function useGingerDebugLog(enabled = false): void {\n const state = useGingerState();\n const prevRef = useRef(state);\n\n useEffect(() => {\n if (!enabled || typeof console === \"undefined\") return;\n const prev = prevRef.current;\n if (prev !== state) {\n console.debug(\"[ginger]\", {\n from: {\n currentIndex: prev.currentIndex,\n isPaused: prev.isPaused,\n currentTime: prev.currentTime,\n repeatMode: prev.repeatMode,\n },\n to: {\n currentIndex: state.currentIndex,\n isPaused: state.isPaused,\n currentTime: state.currentTime,\n repeatMode: state.repeatMode,\n },\n });\n }\n prevRef.current = state;\n }, [enabled, state]);\n}\n","import { useCallback, useState } from \"react\";\nimport type { PointerEvent as ReactPointerEvent } from \"react\";\nimport {\n gingerStateFromContextValues,\n useGingerMedia,\n useGingerPlayback,\n} from \"../context/GingerSplitContexts\";\nimport { progressFraction } from \"../internal/selectors\";\n\nexport type SeekDragState = {\n /** Raw drag fraction — only updated during an active drag gesture. */\n fraction: number;\n /** Blended fraction: follows live playback when idle, drag position when dragging. */\n displayFraction: number;\n isDragging: boolean;\n onPointerDown: (event: ReactPointerEvent<HTMLElement>) => void;\n};\n\nfunction clamp01(value: number): number {\n return Math.max(0, Math.min(1, value));\n}\n\nexport function useSeekDrag(duration: number): SeekDragState {\n const media = useGingerMedia();\n const playback = useGingerPlayback();\n const { seek } = media;\n const [fraction, setFraction] = useState(0);\n const [isDragging, setIsDragging] = useState(false);\n\n const liveFraction = progressFraction(gingerStateFromContextValues(playback, media));\n const displayFraction = isDragging ? fraction : liveFraction;\n\n const onPointerDown = useCallback(\n (event: ReactPointerEvent<HTMLElement>) => {\n if (!(duration > 0)) return;\n const target = event.currentTarget;\n const rect = target.getBoundingClientRect();\n const update = (clientX: number) => {\n const ratio = clamp01((clientX - rect.left) / rect.width);\n setFraction(ratio);\n seek(ratio * duration);\n };\n setIsDragging(true);\n target.setPointerCapture(event.pointerId);\n update(event.clientX);\n const onMove = (moveEvent: PointerEvent) => update(moveEvent.clientX);\n const onUp = (upEvent: PointerEvent) => {\n update(upEvent.clientX);\n setIsDragging(false);\n target.releasePointerCapture(event.pointerId);\n target.removeEventListener(\"pointermove\", onMove);\n target.removeEventListener(\"pointerup\", onUp);\n target.removeEventListener(\"pointercancel\", onUp);\n };\n target.addEventListener(\"pointermove\", onMove);\n target.addEventListener(\"pointerup\", onUp);\n target.addEventListener(\"pointercancel\", onUp);\n },\n [duration, seek],\n );\n\n return { fraction, displayFraction, isDragging, onPointerDown };\n}\n","import { useEffect } from \"react\";\nimport { useGingerPlayback } from \"../context/GingerSplitContexts\";\nimport { computeNextIndex } from \"../core/transitions\";\n\nexport type UseNextTrackPrefetchOptions = {\n /** When false, no prefetch runs. Default true. */\n enabled?: boolean;\n /**\n * Match `crossOrigin` on `Ginger.Player` when `fileUrl` is cross-origin so the browser\n * can reuse cached media consistently.\n */\n crossOrigin?: \"\" | \"anonymous\" | \"use-credentials\" | undefined;\n};\n\n/**\n * Warms the browser cache for the **logical** next track (same rules as the Next control:\n * `computeNextIndex` from queue, repeat, and playback mode) using a detached `HTMLAudioElement`\n * with `preload=\"auto\"`. Safe to call alongside `Ginger.Player`; it does not replace main playback.\n */\nexport function useNextTrackPrefetch(options: UseNextTrackPrefetchOptions = {}): void {\n const { enabled = true, crossOrigin } = options;\n const { tracks, currentIndex, repeatMode, playbackMode } = useGingerPlayback();\n\n useEffect(() => {\n if (!enabled || typeof document === \"undefined\") return;\n const nextIndex = computeNextIndex({ tracks, currentIndex, repeatMode, playbackMode });\n if (nextIndex === currentIndex) return;\n const nextUrl = tracks[nextIndex]?.fileUrl ?? \"\";\n if (!nextUrl) return;\n\n const audio = document.createElement(\"audio\");\n audio.preload = \"auto\";\n if (crossOrigin) audio.crossOrigin = crossOrigin;\n audio.src = nextUrl;\n audio.load();\n\n return () => {\n audio.removeAttribute(\"src\");\n audio.load();\n };\n }, [enabled, crossOrigin, tracks, currentIndex, repeatMode, playbackMode]);\n}\n"],"names":["useGinger","pb","useGingerPlayback","md","useGingerMedia","useMemo","state","gingerStateFromContextValues","getCurrentTrack","derivePlaybackUiState","effectiveDuration","effectiveRemaining","progressFraction","resolvedArtwork","resolvedAlbumLine","entries","clampFftSize","n","p","attachLiveAnalyser","element","options","entry","Context","context","source","analyser","isFirst","id","detachLiveAnalyser","consumer","isPlaybackSink","first","emptyFreq","emptyTime","useGingerLiveAnalyzer","enabled","fftSize","smoothingTimeConstant","minDecibels","maxDecibels","audioRef","opts","frame","setFrame","useState","error","setError","isSuspended","setIsSuspended","meta","setMeta","freqRef","useRef","timeRef","resume","useCallback","ctx","contextHolderRef","analyserHolderRef","useLayoutEffect","cancelled","consumerId","rafId","onStateChange","runLoop","a","fq","td","attach","el","fft","e","msg","retryRaf","maxAttempts","attempts","retryLoop","out","_a","useGingerKeyboardShortcuts","bindings","togglePlayPause","next","prev","toggleMute","muteBinding","useEffect","playPause","nextKey","prevKey","muteKey","onKeyDown","event","target","key","useGingerSleepTimer","durationMs","stopAfterTracks","respectPause","onFire","currentIndex","pause","isPaused","remainingTracksRef","prevIndexRef","useGingerDebugLog","useGingerState","prevRef","clamp01","value","useSeekDrag","duration","media","playback","seek","fraction","setFraction","isDragging","setIsDragging","liveFraction","displayFraction","onPointerDown","rect","update","clientX","ratio","onMove","moveEvent","onUp","upEvent","useNextTrackPrefetch","crossOrigin","tracks","repeatMode","playbackMode","nextIndex","computeNextIndex","nextUrl","audio"],"mappings":"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"}
1
+ {"version":3,"file":"useNextTrackPrefetch-Y_fs2JEx.js","sources":["../src/hooks/useGinger.ts","../src/analyzer/liveAudioGraph.ts","../src/analyzer/useGingerLiveAnalyzer.ts","../src/hooks/useGingerKeyboardShortcuts.ts","../src/hooks/useGingerSleepTimer.ts","../src/hooks/useGingerDebugLog.ts","../src/hooks/useSeekDrag.ts","../src/hooks/useNextTrackPrefetch.ts"],"sourcesContent":["import { useMemo } from \"react\";\nimport {\n gingerStateFromContextValues,\n useGingerMedia,\n useGingerPlayback,\n} from \"../context/GingerSplitContexts\";\nimport {\n derivePlaybackUiState,\n effectiveDuration,\n effectiveRemaining,\n getCurrentTrack,\n progressFraction,\n resolvedAlbumLine,\n resolvedArtwork,\n} from \"../internal/selectors\";\n\nexport function useGinger() {\n const pb = useGingerPlayback();\n const md = useGingerMedia();\n\n return useMemo(() => {\n const state = gingerStateFromContextValues(pb, md);\n return {\n state,\n currentTrack: getCurrentTrack(state),\n playbackUi: derivePlaybackUiState(state),\n duration: effectiveDuration(state),\n remaining: effectiveRemaining(state),\n progress: progressFraction(state),\n artworkUrl: resolvedArtwork(state),\n albumLine: resolvedAlbumLine(state),\n play: pb.play,\n pause: pb.pause,\n togglePlayPause: pb.togglePlayPause,\n seek: md.seek,\n setVolume: md.setVolume,\n setMuted: md.setMuted,\n toggleMute: md.toggleMute,\n setPlaybackRate: md.setPlaybackRate,\n next: pb.next,\n prev: pb.prev,\n setRepeatMode: pb.setRepeatMode,\n cycleRepeat: pb.cycleRepeat,\n toggleShuffle: pb.toggleShuffle,\n setQueue: pb.setQueue,\n insertTrackAt: pb.insertTrackAt,\n removeTrackAt: pb.removeTrackAt,\n moveTrack: pb.moveTrack,\n enqueueNext: pb.enqueueNext,\n playTrackAt: pb.playTrackAt,\n selectTrackAt: pb.selectTrackAt,\n setPlaylistMeta: pb.setPlaylistMeta,\n setPlaybackMode: pb.setPlaybackMode,\n init: pb.init,\n audioRef: md.audioRef,\n dispatch: pb.dispatch,\n };\n }, [pb, md]);\n}\n","/** One MediaElementAudioSourceNode per HTMLAudioElement; multiple AnalyserNodes may tap the source. */\n\nexport type LiveAnalyserOptions = {\n fftSize: number;\n smoothingTimeConstant: number;\n minDecibels: number;\n maxDecibels: number;\n};\n\ntype Consumer = {\n analyser: AnalyserNode;\n /** This analyser is wired to `audioContext.destination` so the graph is audible. */\n isPlaybackSink: boolean;\n};\n\ntype ElementEntry = {\n context: AudioContext;\n source: MediaElementAudioSourceNode;\n consumers: Map<number, Consumer>;\n nextId: number;\n};\n\nconst entries = new WeakMap<HTMLAudioElement, ElementEntry>();\n\nfunction clampFftSize(n: number): number {\n const p = 2 ** Math.round(Math.log2(n));\n return Math.min(32768, Math.max(32, p));\n}\n\nexport function attachLiveAnalyser(\n element: HTMLAudioElement,\n options: LiveAnalyserOptions,\n): { id: number; context: AudioContext; analyser: AnalyserNode } {\n let entry = entries.get(element);\n if (!entry) {\n const Context =\n window.AudioContext ??\n (window as unknown as { webkitAudioContext?: typeof AudioContext }).webkitAudioContext;\n if (!Context) {\n throw new Error(\"Web Audio API is not available\");\n }\n const context = new Context();\n const source = context.createMediaElementSource(element);\n entry = { context, source, consumers: new Map(), nextId: 0 };\n entries.set(element, entry);\n }\n\n const { context, source } = entry;\n const analyser = context.createAnalyser();\n analyser.fftSize = clampFftSize(options.fftSize);\n analyser.smoothingTimeConstant = options.smoothingTimeConstant;\n analyser.minDecibels = options.minDecibels;\n analyser.maxDecibels = options.maxDecibels;\n\n source.connect(analyser);\n\n const isFirst = entry.consumers.size === 0;\n if (isFirst) {\n analyser.connect(context.destination);\n }\n\n const id = entry.nextId;\n entry.nextId += 1;\n entry.consumers.set(id, { analyser, isPlaybackSink: isFirst });\n\n return { id, context, analyser };\n}\n\nexport function detachLiveAnalyser(element: HTMLAudioElement, id: number): void {\n const entry = entries.get(element);\n if (!entry) return;\n\n const consumer = entry.consumers.get(id);\n if (!consumer) return;\n\n const { analyser, isPlaybackSink } = consumer;\n analyser.disconnect();\n entry.consumers.delete(id);\n\n if (entry.consumers.size === 0) {\n try {\n entry.source.disconnect();\n } catch {\n // ignore\n }\n void entry.context.close();\n entries.delete(element);\n return;\n }\n\n if (isPlaybackSink) {\n const first = entry.consumers.values().next().value as Consumer | undefined;\n if (first) {\n first.analyser.connect(entry.context.destination);\n first.isPlaybackSink = true;\n }\n }\n}\n","import { useCallback, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport { useGinger } from \"../hooks/useGinger\";\nimport { type LiveAnalyserOptions, attachLiveAnalyser, detachLiveAnalyser } from \"./liveAudioGraph\";\n\nexport type UseGingerLiveAnalyzerOptions = {\n /** When false, the analyser is detached and no frames are read. Default true. */\n enabled?: boolean;\n fftSize?: number;\n smoothingTimeConstant?: number;\n minDecibels?: number;\n maxDecibels?: number;\n};\n\nexport type UseGingerLiveAnalyzerResult = {\n /** Byte frequency data (0–255); length equals `frequencyBinCount`. Updated each animation frame while enabled. */\n frequencyData: Uint8Array;\n /** Byte time-domain data (0–255); length equals `fftSize`. */\n timeDomainData: Uint8Array;\n frequencyBinCount: number;\n sampleRate: number;\n isSuspended: boolean;\n error: string | null;\n resume: () => Promise<void>;\n};\n\nconst emptyFreq = new Uint8Array(0);\nconst emptyTime = new Uint8Array(0);\n\nexport function useGingerLiveAnalyzer(\n options: UseGingerLiveAnalyzerOptions = {},\n): UseGingerLiveAnalyzerResult {\n const {\n enabled = true,\n fftSize = 2048,\n smoothingTimeConstant = 0.8,\n minDecibels = -100,\n maxDecibels = -30,\n } = options;\n\n const { audioRef, state } = useGinger();\n const opts = useMemo<LiveAnalyserOptions>(\n () => ({\n fftSize,\n smoothingTimeConstant,\n minDecibels,\n maxDecibels,\n }),\n [fftSize, smoothingTimeConstant, minDecibels, maxDecibels],\n );\n\n const [frame, setFrame] = useState(0);\n const [error, setError] = useState<string | null>(null);\n const [isSuspended, setIsSuspended] = useState(false);\n const [meta, setMeta] = useState({ frequencyBinCount: 0, sampleRate: 0 });\n\n const freqRef = useRef<Uint8Array>(emptyFreq);\n const timeRef = useRef<Uint8Array>(emptyTime);\n\n const resume = useCallback(async () => {\n const ctx = contextHolderRef.current;\n if (ctx && ctx.state === \"suspended\") {\n await ctx.resume();\n }\n }, []);\n\n const contextHolderRef = useRef<AudioContext | null>(null);\n const analyserHolderRef = useRef<AnalyserNode | null>(null);\n\n useLayoutEffect(() => {\n if (!enabled || typeof window === \"undefined\") {\n return;\n }\n\n let cancelled = false;\n let consumerId: number | null = null;\n let element: HTMLAudioElement | null = null;\n let rafId = 0;\n\n const onStateChange = () => {\n const ctx = contextHolderRef.current;\n if (ctx) setIsSuspended(ctx.state === \"suspended\");\n };\n\n const runLoop = () => {\n if (cancelled) return;\n const a = analyserHolderRef.current;\n const fq = freqRef.current;\n const td = timeRef.current;\n if (a && fq.length > 0 && td.length > 0) {\n a.getByteFrequencyData(fq as Uint8Array<ArrayBuffer>);\n a.getByteTimeDomainData(td as Uint8Array<ArrayBuffer>);\n setFrame((n) => n + 1);\n }\n rafId = requestAnimationFrame(runLoop);\n };\n\n type AttachOutcome = \"ok\" | \"no-element\" | \"error\";\n\n const attach = (): AttachOutcome => {\n const el = audioRef.current;\n if (!el || cancelled) return \"no-element\";\n try {\n const { id, context, analyser } = attachLiveAnalyser(el, opts);\n consumerId = id;\n element = el;\n contextHolderRef.current = context;\n analyserHolderRef.current = analyser;\n setIsSuspended(context.state === \"suspended\");\n setError(null);\n\n context.addEventListener(\"statechange\", onStateChange);\n\n const n = analyser.frequencyBinCount;\n const fft = analyser.fftSize;\n freqRef.current = new Uint8Array(n);\n timeRef.current = new Uint8Array(fft);\n setMeta({ frequencyBinCount: n, sampleRate: context.sampleRate });\n\n rafId = requestAnimationFrame(runLoop);\n return \"ok\";\n } catch (e) {\n const msg = e instanceof Error ? e.message : \"Failed to attach live analyser\";\n setError(msg);\n contextHolderRef.current = null;\n analyserHolderRef.current = null;\n freqRef.current = emptyFreq;\n timeRef.current = emptyTime;\n setMeta({ frequencyBinCount: 0, sampleRate: 0 });\n return \"error\";\n }\n };\n\n const first = attach();\n if (first !== \"ok\") {\n let retryRaf = 0;\n const maxAttempts = 120;\n let attempts = 0;\n\n const retryLoop = () => {\n if (cancelled) return;\n const out = attach();\n if (out === \"ok\" || out === \"error\") return;\n attempts += 1;\n if (attempts >= maxAttempts) return;\n retryRaf = requestAnimationFrame(retryLoop);\n };\n\n if (first === \"no-element\") {\n retryRaf = requestAnimationFrame(retryLoop);\n }\n\n return () => {\n cancelled = true;\n cancelAnimationFrame(retryRaf);\n cancelAnimationFrame(rafId);\n if (consumerId != null && element) {\n detachLiveAnalyser(element, consumerId);\n }\n contextHolderRef.current?.removeEventListener(\"statechange\", onStateChange);\n contextHolderRef.current = null;\n analyserHolderRef.current = null;\n freqRef.current = emptyFreq;\n timeRef.current = emptyTime;\n };\n }\n\n return () => {\n cancelled = true;\n cancelAnimationFrame(rafId);\n if (consumerId != null && element) {\n detachLiveAnalyser(element, consumerId);\n }\n contextHolderRef.current?.removeEventListener(\"statechange\", onStateChange);\n contextHolderRef.current = null;\n analyserHolderRef.current = null;\n freqRef.current = emptyFreq;\n timeRef.current = emptyTime;\n setMeta({ frequencyBinCount: 0, sampleRate: 0 });\n };\n }, [enabled, audioRef, opts, state.currentIndex]);\n\n void frame;\n\n return {\n frequencyData: freqRef.current,\n timeDomainData: timeRef.current,\n frequencyBinCount: meta.frequencyBinCount,\n sampleRate: meta.sampleRate,\n isSuspended,\n error,\n resume,\n };\n}\n","import { useEffect } from \"react\";\nimport { useGingerMedia, useGingerPlayback } from \"../context/GingerSplitContexts\";\n\nexport type GingerKeyboardShortcutBindings = {\n playPause?: string;\n next?: string;\n previous?: string;\n mute?: string;\n};\n\nexport function useGingerKeyboardShortcuts(\n enabled = true,\n bindings: GingerKeyboardShortcutBindings = {},\n): void {\n const { togglePlayPause, next, prev } = useGingerPlayback();\n const { toggleMute } = useGingerMedia();\n\n const muteBinding = bindings.mute;\n\n useEffect(() => {\n if (!enabled || typeof window === \"undefined\") return;\n const playPause = (bindings.playPause ?? \" \").toLowerCase();\n const nextKey = (bindings.next ?? \"ArrowRight\").toLowerCase();\n const prevKey = (bindings.previous ?? \"ArrowLeft\").toLowerCase();\n const muteKey = muteBinding?.toLowerCase();\n\n const onKeyDown = (event: KeyboardEvent) => {\n const target = event.target as HTMLElement | null;\n if (\n target &&\n ([\"INPUT\", \"TEXTAREA\", \"SELECT\"].includes(target.tagName) || target.isContentEditable)\n )\n return;\n const key = event.key.toLowerCase();\n if (key === playPause) {\n event.preventDefault();\n togglePlayPause();\n } else if (key === nextKey) {\n event.preventDefault();\n next();\n } else if (key === prevKey) {\n event.preventDefault();\n prev();\n } else if (muteKey && key === muteKey) {\n event.preventDefault();\n toggleMute();\n }\n };\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [\n bindings.next,\n bindings.playPause,\n bindings.previous,\n enabled,\n muteBinding,\n next,\n prev,\n toggleMute,\n togglePlayPause,\n ]);\n}\n","import { useEffect, useRef } from \"react\";\nimport { useGingerPlayback } from \"../context/GingerSplitContexts\";\n\nexport type GingerSleepTimerOptions = {\n durationMs?: number;\n stopAfterTracks?: number;\n respectPause?: boolean;\n enabled?: boolean;\n onFire?: () => void;\n};\n\nexport function useGingerSleepTimer(options: GingerSleepTimerOptions): void {\n const { durationMs, stopAfterTracks, respectPause = true, enabled = true, onFire } = options;\n const { currentIndex, pause, isPaused } = useGingerPlayback();\n const remainingTracksRef = useRef(stopAfterTracks ?? 0);\n const prevIndexRef = useRef(currentIndex);\n\n useEffect(() => {\n remainingTracksRef.current = stopAfterTracks ?? 0;\n }, [stopAfterTracks]);\n\n useEffect(() => {\n if (!enabled || !durationMs || durationMs <= 0) return;\n if (respectPause && isPaused) return;\n const id = setTimeout(() => {\n pause();\n onFire?.();\n }, durationMs);\n return () => clearTimeout(id);\n }, [durationMs, enabled, isPaused, onFire, pause, respectPause]);\n\n useEffect(() => {\n if (!enabled || !stopAfterTracks || stopAfterTracks <= 0) return;\n const prev = prevIndexRef.current;\n prevIndexRef.current = currentIndex;\n if (currentIndex === prev) return;\n remainingTracksRef.current -= 1;\n if (remainingTracksRef.current <= 0) {\n pause();\n onFire?.();\n }\n }, [currentIndex, enabled, onFire, pause, stopAfterTracks]);\n}\n","import { useEffect, useRef } from \"react\";\nimport { useGingerState } from \"../context/GingerSplitContexts\";\n\nexport function useGingerDebugLog(enabled = false): void {\n const state = useGingerState();\n const prevRef = useRef(state);\n\n useEffect(() => {\n if (!enabled || typeof console === \"undefined\") return;\n const prev = prevRef.current;\n if (prev !== state) {\n console.debug(\"[ginger]\", {\n from: {\n currentIndex: prev.currentIndex,\n isPaused: prev.isPaused,\n currentTime: prev.currentTime,\n repeatMode: prev.repeatMode,\n },\n to: {\n currentIndex: state.currentIndex,\n isPaused: state.isPaused,\n currentTime: state.currentTime,\n repeatMode: state.repeatMode,\n },\n });\n }\n prevRef.current = state;\n }, [enabled, state]);\n}\n","import { useCallback, useState } from \"react\";\nimport type { PointerEvent as ReactPointerEvent } from \"react\";\nimport {\n gingerStateFromContextValues,\n useGingerMedia,\n useGingerPlayback,\n} from \"../context/GingerSplitContexts\";\nimport { progressFraction } from \"../internal/selectors\";\n\nexport type SeekDragState = {\n /** Raw drag fraction — only updated during an active drag gesture. */\n fraction: number;\n /** Blended fraction: follows live playback when idle, drag position when dragging. */\n displayFraction: number;\n isDragging: boolean;\n onPointerDown: (event: ReactPointerEvent<HTMLElement>) => void;\n};\n\nfunction clamp01(value: number): number {\n return Math.max(0, Math.min(1, value));\n}\n\nexport function useSeekDrag(duration: number): SeekDragState {\n const media = useGingerMedia();\n const playback = useGingerPlayback();\n const { seek } = media;\n const [fraction, setFraction] = useState(0);\n const [isDragging, setIsDragging] = useState(false);\n\n const liveFraction = progressFraction(gingerStateFromContextValues(playback, media));\n const displayFraction = isDragging ? fraction : liveFraction;\n\n const onPointerDown = useCallback(\n (event: ReactPointerEvent<HTMLElement>) => {\n if (!(duration > 0)) return;\n const target = event.currentTarget;\n const rect = target.getBoundingClientRect();\n const update = (clientX: number) => {\n const ratio = clamp01((clientX - rect.left) / rect.width);\n setFraction(ratio);\n seek(ratio * duration);\n };\n setIsDragging(true);\n target.setPointerCapture(event.pointerId);\n update(event.clientX);\n const onMove = (moveEvent: PointerEvent) => update(moveEvent.clientX);\n const onUp = (upEvent: PointerEvent) => {\n update(upEvent.clientX);\n setIsDragging(false);\n target.releasePointerCapture(event.pointerId);\n target.removeEventListener(\"pointermove\", onMove);\n target.removeEventListener(\"pointerup\", onUp);\n target.removeEventListener(\"pointercancel\", onUp);\n };\n target.addEventListener(\"pointermove\", onMove);\n target.addEventListener(\"pointerup\", onUp);\n target.addEventListener(\"pointercancel\", onUp);\n },\n [duration, seek],\n );\n\n return { fraction, displayFraction, isDragging, onPointerDown };\n}\n","import { useEffect } from \"react\";\nimport { useGingerPlayback } from \"../context/GingerSplitContexts\";\nimport { computeNextIndex } from \"../core/transitions\";\n\nexport type UseNextTrackPrefetchOptions = {\n /** When false, no prefetch runs. Default true. */\n enabled?: boolean;\n /**\n * Match `crossOrigin` on `Ginger.Player` when `fileUrl` is cross-origin so the browser\n * can reuse cached media consistently.\n */\n crossOrigin?: \"\" | \"anonymous\" | \"use-credentials\" | undefined;\n};\n\n/**\n * Warms the browser cache for the **logical** next track (same rules as the Next control:\n * `computeNextIndex` from queue, repeat, and playback mode) using a detached `HTMLAudioElement`\n * with `preload=\"auto\"`. Safe to call alongside `Ginger.Player`; it does not replace main playback.\n */\nexport function useNextTrackPrefetch(options: UseNextTrackPrefetchOptions = {}): void {\n const { enabled = true, crossOrigin } = options;\n const { tracks, currentIndex, repeatMode, playbackMode } = useGingerPlayback();\n\n useEffect(() => {\n if (!enabled || typeof document === \"undefined\") return;\n const nextIndex = computeNextIndex({ tracks, currentIndex, repeatMode, playbackMode });\n if (nextIndex === currentIndex) return;\n const nextUrl = tracks[nextIndex]?.fileUrl ?? \"\";\n if (!nextUrl) return;\n\n const audio = document.createElement(\"audio\");\n audio.preload = \"auto\";\n if (crossOrigin) audio.crossOrigin = crossOrigin;\n audio.src = nextUrl;\n audio.load();\n\n return () => {\n audio.removeAttribute(\"src\");\n audio.load();\n };\n }, [enabled, crossOrigin, tracks, currentIndex, repeatMode, playbackMode]);\n}\n"],"names":["useGinger","pb","useGingerPlayback","md","useGingerMedia","useMemo","state","gingerStateFromContextValues","getCurrentTrack","derivePlaybackUiState","effectiveDuration","effectiveRemaining","progressFraction","resolvedArtwork","resolvedAlbumLine","entries","clampFftSize","n","p","attachLiveAnalyser","element","options","entry","Context","context","source","analyser","isFirst","id","detachLiveAnalyser","consumer","isPlaybackSink","first","emptyFreq","emptyTime","useGingerLiveAnalyzer","enabled","fftSize","smoothingTimeConstant","minDecibels","maxDecibels","audioRef","opts","frame","setFrame","useState","error","setError","isSuspended","setIsSuspended","meta","setMeta","freqRef","useRef","timeRef","resume","useCallback","ctx","contextHolderRef","analyserHolderRef","useLayoutEffect","cancelled","consumerId","rafId","onStateChange","runLoop","a","fq","td","attach","el","fft","e","msg","retryRaf","maxAttempts","attempts","retryLoop","out","_a","useGingerKeyboardShortcuts","bindings","togglePlayPause","next","prev","toggleMute","muteBinding","useEffect","playPause","nextKey","prevKey","muteKey","onKeyDown","event","target","key","useGingerSleepTimer","durationMs","stopAfterTracks","respectPause","onFire","currentIndex","pause","isPaused","remainingTracksRef","prevIndexRef","useGingerDebugLog","useGingerState","prevRef","clamp01","value","useSeekDrag","duration","media","playback","seek","fraction","setFraction","isDragging","setIsDragging","liveFraction","displayFraction","onPointerDown","rect","update","clientX","ratio","onMove","moveEvent","onUp","upEvent","useNextTrackPrefetch","crossOrigin","tracks","repeatMode","playbackMode","nextIndex","computeNextIndex","nextUrl","audio"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";const o=require("react"),v=require("./GingerSplitContexts-C7puo0M7.cjs"),P=require("./ginger-yY4Y5liv.cjs");function K(){const t=v.useGingerPlayback(),e=v.useGingerMedia();return o.useMemo(()=>{const n=v.gingerStateFromContextValues(t,e);return{state:n,currentTrack:P.getCurrentTrack(n),playbackUi:P.derivePlaybackUiState(n),duration:P.effectiveDuration(n),remaining:P.effectiveRemaining(n),progress:P.progressFraction(n),artworkUrl:P.resolvedArtwork(n),albumLine:P.resolvedAlbumLine(n),play:t.play,pause:t.pause,togglePlayPause:t.togglePlayPause,seek:e.seek,setVolume:e.setVolume,setMuted:e.setMuted,toggleMute:e.toggleMute,setPlaybackRate:e.setPlaybackRate,next:t.next,prev:t.prev,setRepeatMode:t.setRepeatMode,cycleRepeat:t.cycleRepeat,toggleShuffle:t.toggleShuffle,setQueue:t.setQueue,insertTrackAt:t.insertTrackAt,removeTrackAt:t.removeTrackAt,moveTrack:t.moveTrack,enqueueNext:t.enqueueNext,playTrackAt:t.playTrackAt,selectTrackAt:t.selectTrackAt,setPlaylistMeta:t.setPlaylistMeta,setPlaybackMode:t.setPlaybackMode,init:t.init,audioRef:e.audioRef,dispatch:t.dispatch}},[t,e])}const G=new WeakMap;function O(t){const e=2**Math.round(Math.log2(t));return Math.min(32768,Math.max(32,e))}function V(t,e){let n=G.get(t);if(!n){const d=window.AudioContext??window.webkitAudioContext;if(!d)throw new Error("Web Audio API is not available");const i=new d,m=i.createMediaElementSource(t);n={context:i,source:m,consumers:new Map,nextId:0},G.set(t,n)}const{context:s,source:c}=n,r=s.createAnalyser();r.fftSize=O(e.fftSize),r.smoothingTimeConstant=e.smoothingTimeConstant,r.minDecibels=e.minDecibels,r.maxDecibels=e.maxDecibels,c.connect(r);const a=n.consumers.size===0;a&&r.connect(s.destination);const l=n.nextId;return n.nextId+=1,n.consumers.set(l,{analyser:r,isPlaybackSink:a}),{id:l,context:s,analyser:r}}function U(t,e){const n=G.get(t);if(!n)return;const s=n.consumers.get(e);if(!s)return;const{analyser:c,isPlaybackSink:r}=s;if(c.disconnect(),n.consumers.delete(e),n.consumers.size===0){try{n.source.disconnect()}catch{}n.context.close(),G.delete(t);return}if(r){const a=n.consumers.values().next().value;a&&(a.analyser.connect(n.context.destination),a.isPlaybackSink=!0)}}const q=new Uint8Array(0),I=new Uint8Array(0);function Q(t={}){const{enabled:e=!0,fftSize:n=2048,smoothingTimeConstant:s=.8,minDecibels:c=-100,maxDecibels:r=-30}=t,{audioRef:a,state:l}=K(),d=o.useMemo(()=>({fftSize:n,smoothingTimeConstant:s,minDecibels:c,maxDecibels:r}),[n,s,c,r]),[i,m]=o.useState(0),[p,u]=o.useState(null),[R,k]=o.useState(!1),[S,h]=o.useState({frequencyBinCount:0,sampleRate:0}),g=o.useRef(q),x=o.useRef(I),X=o.useCallback(async()=>{const A=M.current;A&&A.state==="suspended"&&await A.resume()},[]),M=o.useRef(null),L=o.useRef(null);return o.useLayoutEffect(()=>{if(!e||typeof window>"u")return;let A=!1,C=null,E=null,D=0;const F=()=>{const f=M.current;f&&k(f.state==="suspended")},z=()=>{if(A)return;const f=L.current,w=g.current,y=x.current;f&&w.length>0&&y.length>0&&(f.getByteFrequencyData(w),f.getByteTimeDomainData(y),m(T=>T+1)),D=requestAnimationFrame(z)},B=()=>{const f=a.current;if(!f||A)return"no-element";try{const{id:w,context:y,analyser:T}=V(f,d);C=w,E=f,M.current=y,L.current=T,k(y.state==="suspended"),u(null),y.addEventListener("statechange",F);const b=T.frequencyBinCount,H=T.fftSize;return g.current=new Uint8Array(b),x.current=new Uint8Array(H),h({frequencyBinCount:b,sampleRate:y.sampleRate}),D=requestAnimationFrame(z),"ok"}catch(w){const y=w instanceof Error?w.message:"Failed to attach live analyser";return u(y),M.current=null,L.current=null,g.current=q,x.current=I,h({frequencyBinCount:0,sampleRate:0}),"error"}},N=B();if(N!=="ok"){let f=0;const w=120;let y=0;const T=()=>{if(A)return;const b=B();b==="ok"||b==="error"||(y+=1,!(y>=w)&&(f=requestAnimationFrame(T)))};return N==="no-element"&&(f=requestAnimationFrame(T)),()=>{var b;A=!0,cancelAnimationFrame(f),cancelAnimationFrame(D),C!=null&&E&&U(E,C),(b=M.current)==null||b.removeEventListener("statechange",F),M.current=null,L.current=null,g.current=q,x.current=I}}return()=>{var f;A=!0,cancelAnimationFrame(D),C!=null&&E&&U(E,C),(f=M.current)==null||f.removeEventListener("statechange",F),M.current=null,L.current=null,g.current=q,x.current=I,h({frequencyBinCount:0,sampleRate:0})}},[e,a,d,l.currentIndex]),{frequencyData:g.current,timeDomainData:x.current,frequencyBinCount:S.frequencyBinCount,sampleRate:S.sampleRate,isSuspended:R,error:p,resume:X}}function W(t=!0,e={}){const{togglePlayPause:n,next:s,prev:c}=v.useGingerPlayback(),{toggleMute:r}=v.useGingerMedia(),a=e.mute;o.useEffect(()=>{if(!t||typeof window>"u")return;const l=(e.playPause??" ").toLowerCase(),d=(e.next??"ArrowRight").toLowerCase(),i=(e.previous??"ArrowLeft").toLowerCase(),m=a==null?void 0:a.toLowerCase(),p=u=>{const R=u.target;if(R&&(["INPUT","TEXTAREA","SELECT"].includes(R.tagName)||R.isContentEditable))return;const k=u.key.toLowerCase();k===l?(u.preventDefault(),n()):k===d?(u.preventDefault(),s()):k===i?(u.preventDefault(),c()):m&&k===m&&(u.preventDefault(),r())};return window.addEventListener("keydown",p),()=>window.removeEventListener("keydown",p)},[e.next,e.playPause,e.previous,t,a,s,c,r,n])}function j(t){const{durationMs:e,stopAfterTracks:n,respectPause:s=!0,enabled:c=!0,onFire:r}=t,{currentIndex:a,pause:l,isPaused:d}=v.useGingerPlayback(),i=o.useRef(n??0),m=o.useRef(a);o.useEffect(()=>{i.current=n??0},[n]),o.useEffect(()=>{if(!c||!e||e<=0||s&&d)return;const p=setTimeout(()=>{l(),r==null||r()},e);return()=>clearTimeout(p)},[e,c,d,r,l,s]),o.useEffect(()=>{if(!c||!n||n<=0)return;const p=m.current;m.current=a,a!==p&&(i.current-=1,i.current<=0&&(l(),r==null||r()))},[a,c,r,l,n])}function J(t=!1){const e=v.useGingerState(),n=o.useRef(e);o.useEffect(()=>{if(!t||typeof console>"u")return;const s=n.current;s!==e&&console.debug("[ginger]",{from:{currentIndex:s.currentIndex,isPaused:s.isPaused,currentTime:s.currentTime,repeatMode:s.repeatMode},to:{currentIndex:e.currentIndex,isPaused:e.isPaused,currentTime:e.currentTime,repeatMode:e.repeatMode}}),n.current=e},[t,e])}function Y(t){return Math.max(0,Math.min(1,t))}function Z(t){const e=v.useGingerMedia(),n=v.useGingerPlayback(),{seek:s}=e,[c,r]=o.useState(0),[a,l]=o.useState(!1),d=P.progressFraction(v.gingerStateFromContextValues(n,e)),i=a?c:d,m=o.useCallback(p=>{if(!(t>0))return;const u=p.currentTarget,R=u.getBoundingClientRect(),k=g=>{const x=Y((g-R.left)/R.width);r(x),s(x*t)};l(!0),u.setPointerCapture(p.pointerId),k(p.clientX);const S=g=>k(g.clientX),h=g=>{k(g.clientX),l(!1),u.releasePointerCapture(p.pointerId),u.removeEventListener("pointermove",S),u.removeEventListener("pointerup",h),u.removeEventListener("pointercancel",h)};u.addEventListener("pointermove",S),u.addEventListener("pointerup",h),u.addEventListener("pointercancel",h)},[t,s]);return{fraction:c,displayFraction:i,isDragging:a,onPointerDown:m}}function _(t={}){const{enabled:e=!0,crossOrigin:n}=t,{tracks:s,currentIndex:c,repeatMode:r,playbackMode:a}=v.useGingerPlayback();o.useEffect(()=>{var m;if(!e||typeof document>"u")return;const l=P.computeNextIndex({tracks:s,currentIndex:c,repeatMode:r,playbackMode:a});if(l===c)return;const d=((m=s[l])==null?void 0:m.fileUrl)??"";if(!d)return;const i=document.createElement("audio");return i.preload="auto",n&&(i.crossOrigin=n),i.src=d,i.load(),()=>{i.removeAttribute("src"),i.load()}},[e,n,s,c,r,a])}exports.attachLiveAnalyser=V;exports.detachLiveAnalyser=U;exports.useGinger=K;exports.useGingerDebugLog=J;exports.useGingerKeyboardShortcuts=W;exports.useGingerLiveAnalyzer=Q;exports.useGingerSleepTimer=j;exports.useNextTrackPrefetch=_;exports.useSeekDrag=Z;
2
- //# sourceMappingURL=useNextTrackPrefetch-Cs4A1oFv.cjs.map
1
+ "use strict";const o=require("react"),v=require("./GingerSplitContexts-C7puo0M7.cjs"),P=require("./ginger-B26HM2Ja.cjs");function K(){const t=v.useGingerPlayback(),e=v.useGingerMedia();return o.useMemo(()=>{const n=v.gingerStateFromContextValues(t,e);return{state:n,currentTrack:P.getCurrentTrack(n),playbackUi:P.derivePlaybackUiState(n),duration:P.effectiveDuration(n),remaining:P.effectiveRemaining(n),progress:P.progressFraction(n),artworkUrl:P.resolvedArtwork(n),albumLine:P.resolvedAlbumLine(n),play:t.play,pause:t.pause,togglePlayPause:t.togglePlayPause,seek:e.seek,setVolume:e.setVolume,setMuted:e.setMuted,toggleMute:e.toggleMute,setPlaybackRate:e.setPlaybackRate,next:t.next,prev:t.prev,setRepeatMode:t.setRepeatMode,cycleRepeat:t.cycleRepeat,toggleShuffle:t.toggleShuffle,setQueue:t.setQueue,insertTrackAt:t.insertTrackAt,removeTrackAt:t.removeTrackAt,moveTrack:t.moveTrack,enqueueNext:t.enqueueNext,playTrackAt:t.playTrackAt,selectTrackAt:t.selectTrackAt,setPlaylistMeta:t.setPlaylistMeta,setPlaybackMode:t.setPlaybackMode,init:t.init,audioRef:e.audioRef,dispatch:t.dispatch}},[t,e])}const G=new WeakMap;function O(t){const e=2**Math.round(Math.log2(t));return Math.min(32768,Math.max(32,e))}function V(t,e){let n=G.get(t);if(!n){const d=window.AudioContext??window.webkitAudioContext;if(!d)throw new Error("Web Audio API is not available");const i=new d,m=i.createMediaElementSource(t);n={context:i,source:m,consumers:new Map,nextId:0},G.set(t,n)}const{context:s,source:c}=n,r=s.createAnalyser();r.fftSize=O(e.fftSize),r.smoothingTimeConstant=e.smoothingTimeConstant,r.minDecibels=e.minDecibels,r.maxDecibels=e.maxDecibels,c.connect(r);const a=n.consumers.size===0;a&&r.connect(s.destination);const l=n.nextId;return n.nextId+=1,n.consumers.set(l,{analyser:r,isPlaybackSink:a}),{id:l,context:s,analyser:r}}function U(t,e){const n=G.get(t);if(!n)return;const s=n.consumers.get(e);if(!s)return;const{analyser:c,isPlaybackSink:r}=s;if(c.disconnect(),n.consumers.delete(e),n.consumers.size===0){try{n.source.disconnect()}catch{}n.context.close(),G.delete(t);return}if(r){const a=n.consumers.values().next().value;a&&(a.analyser.connect(n.context.destination),a.isPlaybackSink=!0)}}const q=new Uint8Array(0),I=new Uint8Array(0);function Q(t={}){const{enabled:e=!0,fftSize:n=2048,smoothingTimeConstant:s=.8,minDecibels:c=-100,maxDecibels:r=-30}=t,{audioRef:a,state:l}=K(),d=o.useMemo(()=>({fftSize:n,smoothingTimeConstant:s,minDecibels:c,maxDecibels:r}),[n,s,c,r]),[i,m]=o.useState(0),[p,u]=o.useState(null),[R,k]=o.useState(!1),[S,h]=o.useState({frequencyBinCount:0,sampleRate:0}),g=o.useRef(q),x=o.useRef(I),X=o.useCallback(async()=>{const A=M.current;A&&A.state==="suspended"&&await A.resume()},[]),M=o.useRef(null),L=o.useRef(null);return o.useLayoutEffect(()=>{if(!e||typeof window>"u")return;let A=!1,C=null,E=null,D=0;const F=()=>{const f=M.current;f&&k(f.state==="suspended")},z=()=>{if(A)return;const f=L.current,w=g.current,y=x.current;f&&w.length>0&&y.length>0&&(f.getByteFrequencyData(w),f.getByteTimeDomainData(y),m(T=>T+1)),D=requestAnimationFrame(z)},B=()=>{const f=a.current;if(!f||A)return"no-element";try{const{id:w,context:y,analyser:T}=V(f,d);C=w,E=f,M.current=y,L.current=T,k(y.state==="suspended"),u(null),y.addEventListener("statechange",F);const b=T.frequencyBinCount,H=T.fftSize;return g.current=new Uint8Array(b),x.current=new Uint8Array(H),h({frequencyBinCount:b,sampleRate:y.sampleRate}),D=requestAnimationFrame(z),"ok"}catch(w){const y=w instanceof Error?w.message:"Failed to attach live analyser";return u(y),M.current=null,L.current=null,g.current=q,x.current=I,h({frequencyBinCount:0,sampleRate:0}),"error"}},N=B();if(N!=="ok"){let f=0;const w=120;let y=0;const T=()=>{if(A)return;const b=B();b==="ok"||b==="error"||(y+=1,!(y>=w)&&(f=requestAnimationFrame(T)))};return N==="no-element"&&(f=requestAnimationFrame(T)),()=>{var b;A=!0,cancelAnimationFrame(f),cancelAnimationFrame(D),C!=null&&E&&U(E,C),(b=M.current)==null||b.removeEventListener("statechange",F),M.current=null,L.current=null,g.current=q,x.current=I}}return()=>{var f;A=!0,cancelAnimationFrame(D),C!=null&&E&&U(E,C),(f=M.current)==null||f.removeEventListener("statechange",F),M.current=null,L.current=null,g.current=q,x.current=I,h({frequencyBinCount:0,sampleRate:0})}},[e,a,d,l.currentIndex]),{frequencyData:g.current,timeDomainData:x.current,frequencyBinCount:S.frequencyBinCount,sampleRate:S.sampleRate,isSuspended:R,error:p,resume:X}}function W(t=!0,e={}){const{togglePlayPause:n,next:s,prev:c}=v.useGingerPlayback(),{toggleMute:r}=v.useGingerMedia(),a=e.mute;o.useEffect(()=>{if(!t||typeof window>"u")return;const l=(e.playPause??" ").toLowerCase(),d=(e.next??"ArrowRight").toLowerCase(),i=(e.previous??"ArrowLeft").toLowerCase(),m=a==null?void 0:a.toLowerCase(),p=u=>{const R=u.target;if(R&&(["INPUT","TEXTAREA","SELECT"].includes(R.tagName)||R.isContentEditable))return;const k=u.key.toLowerCase();k===l?(u.preventDefault(),n()):k===d?(u.preventDefault(),s()):k===i?(u.preventDefault(),c()):m&&k===m&&(u.preventDefault(),r())};return window.addEventListener("keydown",p),()=>window.removeEventListener("keydown",p)},[e.next,e.playPause,e.previous,t,a,s,c,r,n])}function j(t){const{durationMs:e,stopAfterTracks:n,respectPause:s=!0,enabled:c=!0,onFire:r}=t,{currentIndex:a,pause:l,isPaused:d}=v.useGingerPlayback(),i=o.useRef(n??0),m=o.useRef(a);o.useEffect(()=>{i.current=n??0},[n]),o.useEffect(()=>{if(!c||!e||e<=0||s&&d)return;const p=setTimeout(()=>{l(),r==null||r()},e);return()=>clearTimeout(p)},[e,c,d,r,l,s]),o.useEffect(()=>{if(!c||!n||n<=0)return;const p=m.current;m.current=a,a!==p&&(i.current-=1,i.current<=0&&(l(),r==null||r()))},[a,c,r,l,n])}function J(t=!1){const e=v.useGingerState(),n=o.useRef(e);o.useEffect(()=>{if(!t||typeof console>"u")return;const s=n.current;s!==e&&console.debug("[ginger]",{from:{currentIndex:s.currentIndex,isPaused:s.isPaused,currentTime:s.currentTime,repeatMode:s.repeatMode},to:{currentIndex:e.currentIndex,isPaused:e.isPaused,currentTime:e.currentTime,repeatMode:e.repeatMode}}),n.current=e},[t,e])}function Y(t){return Math.max(0,Math.min(1,t))}function Z(t){const e=v.useGingerMedia(),n=v.useGingerPlayback(),{seek:s}=e,[c,r]=o.useState(0),[a,l]=o.useState(!1),d=P.progressFraction(v.gingerStateFromContextValues(n,e)),i=a?c:d,m=o.useCallback(p=>{if(!(t>0))return;const u=p.currentTarget,R=u.getBoundingClientRect(),k=g=>{const x=Y((g-R.left)/R.width);r(x),s(x*t)};l(!0),u.setPointerCapture(p.pointerId),k(p.clientX);const S=g=>k(g.clientX),h=g=>{k(g.clientX),l(!1),u.releasePointerCapture(p.pointerId),u.removeEventListener("pointermove",S),u.removeEventListener("pointerup",h),u.removeEventListener("pointercancel",h)};u.addEventListener("pointermove",S),u.addEventListener("pointerup",h),u.addEventListener("pointercancel",h)},[t,s]);return{fraction:c,displayFraction:i,isDragging:a,onPointerDown:m}}function _(t={}){const{enabled:e=!0,crossOrigin:n}=t,{tracks:s,currentIndex:c,repeatMode:r,playbackMode:a}=v.useGingerPlayback();o.useEffect(()=>{var m;if(!e||typeof document>"u")return;const l=P.computeNextIndex({tracks:s,currentIndex:c,repeatMode:r,playbackMode:a});if(l===c)return;const d=((m=s[l])==null?void 0:m.fileUrl)??"";if(!d)return;const i=document.createElement("audio");return i.preload="auto",n&&(i.crossOrigin=n),i.src=d,i.load(),()=>{i.removeAttribute("src"),i.load()}},[e,n,s,c,r,a])}exports.attachLiveAnalyser=V;exports.detachLiveAnalyser=U;exports.useGinger=K;exports.useGingerDebugLog=J;exports.useGingerKeyboardShortcuts=W;exports.useGingerLiveAnalyzer=Q;exports.useGingerSleepTimer=j;exports.useNextTrackPrefetch=_;exports.useSeekDrag=Z;
2
+ //# sourceMappingURL=useNextTrackPrefetch-wSILz6TL.cjs.map