@lucaismyname/ginger 0.0.32 → 0.0.35

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 (43) hide show
  1. package/README.md +105 -5
  2. package/dist/client.cjs +1 -1
  3. package/dist/client.js +2 -2
  4. package/dist/{ginger-L2ZFgzH4.js → ginger-DlCkxDXs.js} +38 -38
  5. package/dist/ginger-DlCkxDXs.js.map +1 -0
  6. package/dist/{ginger-NEcOSSJD.cjs → ginger-jToP7EpI.cjs} +2 -2
  7. package/dist/ginger-jToP7EpI.cjs.map +1 -0
  8. package/dist/hooks/useNextTrackPrefetch.d.ts +3 -0
  9. package/dist/hooks/useNextTrackPrefetch.d.ts.map +1 -1
  10. package/dist/index.cjs +1 -1
  11. package/dist/index.js +2 -2
  12. package/dist/remote/index.cjs +1 -1
  13. package/dist/remote/index.cjs.map +1 -1
  14. package/dist/remote/index.js +122 -103
  15. package/dist/remote/index.js.map +1 -1
  16. package/dist/remote/useGingerRemote.d.ts.map +1 -1
  17. package/dist/remote/useGingerRemote.test.d.ts +2 -0
  18. package/dist/remote/useGingerRemote.test.d.ts.map +1 -0
  19. package/dist/remote/validateGingerInitPayloadDev.d.ts +7 -0
  20. package/dist/remote/validateGingerInitPayloadDev.d.ts.map +1 -0
  21. package/dist/remote/validateGingerInitPayloadDev.test.d.ts +2 -0
  22. package/dist/remote/validateGingerInitPayloadDev.test.d.ts.map +1 -0
  23. package/dist/testing/index.cjs +1 -1
  24. package/dist/testing/index.js +1 -1
  25. package/dist/{useGingerChapterProgress-BdaalJvX.cjs → useGingerChapterProgress-B2-J3dSP.cjs} +2 -2
  26. package/dist/useGingerChapterProgress-B2-J3dSP.cjs.map +1 -0
  27. package/dist/{useGingerChapterProgress-CZdv-HiI.js → useGingerChapterProgress-BW6v65wN.js} +2 -2
  28. package/dist/useGingerChapterProgress-BW6v65wN.js.map +1 -0
  29. package/dist/waveform/analyzeAudioFile.d.ts.map +1 -1
  30. package/dist/waveform/getAudioContextConstructor.d.ts +6 -0
  31. package/dist/waveform/getAudioContextConstructor.d.ts.map +1 -0
  32. package/dist/waveform/index.cjs +1 -1
  33. package/dist/waveform/index.cjs.map +1 -1
  34. package/dist/waveform/index.js +162 -153
  35. package/dist/waveform/index.js.map +1 -1
  36. package/dist/waveform/useAudioFileAnalysis.d.ts +1 -0
  37. package/dist/waveform/useAudioFileAnalysis.d.ts.map +1 -1
  38. package/dist/waveform/useAudioPeaks.d.ts.map +1 -1
  39. package/package.json +1 -1
  40. package/dist/ginger-L2ZFgzH4.js.map +0 -1
  41. package/dist/ginger-NEcOSSJD.cjs.map +0 -1
  42. package/dist/useGingerChapterProgress-BdaalJvX.cjs.map +0 -1
  43. package/dist/useGingerChapterProgress-CZdv-HiI.js.map +0 -1
package/README.md CHANGED
@@ -56,7 +56,7 @@ Mount **`<Ginger.Player />`** once inside the same provider tree so the hidden a
56
56
  - Streaming adapters: [`docs/guides/streaming-adapters.md`](./docs/guides/streaming-adapters.md)
57
57
  - Components reference: [`docs/reference/components.md`](./docs/reference/components.md)
58
58
  - Hooks reference: [`docs/reference/hooks.md`](./docs/reference/hooks.md)
59
- - Subpath exports: [`docs/reference/subpaths.md`](./docs/reference/subpaths.md)
59
+ - Subpath exports (waveform, EQ, spatial, transcript, remote, …): [`docs/reference/subpaths.md`](./docs/reference/subpaths.md)
60
60
  - Generated API docs: [`docs/api/index.html`](./docs/api/index.html)
61
61
 
62
62
  ## Subpath Exports
@@ -65,6 +65,9 @@ Mount **`<Ginger.Player />`** once inside the same provider tree so the hidden a
65
65
  - `@lucaismyname/ginger/testing`
66
66
  - `@lucaismyname/ginger/waveform`
67
67
  - `@lucaismyname/ginger/equalizer`
68
+ - `@lucaismyname/ginger/spatial`
69
+ - `@lucaismyname/ginger/transcript`
70
+ - `@lucaismyname/ginger/remote`
68
71
  - `@lucaismyname/ginger/experimental-gapless`
69
72
 
70
73
  ### Equalizer
@@ -105,6 +108,96 @@ function MyPlayer() {
105
108
 
106
109
  The EQ and `useGingerLiveAnalyzer` share the same `AudioContext` and can be used together. EQ filters are inserted before the analyser in the Web Audio graph.
107
110
 
111
+ ### Spatial audio (`@lucaismyname/ginger/spatial`)
112
+
113
+ Inserts an HRTF **`PannerNode`** into the same Web Audio graph as the EQ and live analyser (one `MediaElementAudioSourceNode` per `<audio>`).
114
+
115
+ ```tsx
116
+ import { useGingerSpatialAudio } from "@lucaismyname/ginger/spatial";
117
+
118
+ function Spatialized() {
119
+ const { setSourcePosition, error } = useGingerSpatialAudio({
120
+ panningModel: "HRTF",
121
+ position: [2, 0, 0],
122
+ listenerPosition: [0, 0, 0],
123
+ });
124
+
125
+ return (
126
+ <div>
127
+ <button type="button" onClick={() => setSourcePosition(0, 0, -2)}>
128
+ Move source
129
+ </button>
130
+ {error && <p>{error}</p>}
131
+ </div>
132
+ );
133
+ }
134
+ ```
135
+
136
+ Use **`setListenerPosition`** and **`setPanningModel`** for runtime updates without rebuilding the graph.
137
+
138
+ ### Transcript (`@lucaismyname/ginger/transcript`)
139
+
140
+ Parse **SRT** and **WebVTT** captions and sync cues to playback time (podcasts, video-style transcripts). HTML tags in cue text are stripped.
141
+
142
+ ```tsx
143
+ import {
144
+ parseSrt,
145
+ parseVtt,
146
+ useGingerTranscriptSync,
147
+ } from "@lucaismyname/ginger/transcript";
148
+
149
+ const vtt = `WEBVTT
150
+
151
+ 00:00:01.000 --> 00:00:04.000
152
+ Hello from VTT
153
+ `;
154
+
155
+ function TranscriptPanel() {
156
+ const { cues, activeCue, activeCues } = useGingerTranscriptSync({
157
+ transcript: vtt,
158
+ format: "auto",
159
+ });
160
+
161
+ return (
162
+ <div>
163
+ <p>Now: {activeCue?.text ?? "—"}</p>
164
+ <p>Overlapping: {activeCues.map((c) => c.text).join(" · ")}</p>
165
+ </div>
166
+ );
167
+ }
168
+
169
+ // Or parse ahead of time:
170
+ const cuesFromSrt = parseSrt(srtString);
171
+ const cuesFromVtt = parseVtt(vttString);
172
+ ```
173
+
174
+ **`useGingerTranscriptSync`** mirrors **`useGingerLyricsSync`** but uses cue **start/end** ranges and exposes **`activeCues`** for overlapping captions. **`parseTranscriptAuto`** chooses VTT when the string starts with `WEBVTT`, otherwise SRT.
175
+
176
+ ### Multi-tab sync (`@lucaismyname/ginger/remote`)
177
+
178
+ Elects a **leader** tab via **`BroadcastChannel`** and pushes **`INIT`** snapshots to followers so queue and transport settings stay aligned. Mount **`Ginger.Player`** only on the leader so a single `<audio>` element plays.
179
+
180
+ ```tsx
181
+ import { Ginger } from "@lucaismyname/ginger";
182
+ import { useGingerRemote } from "@lucaismyname/ginger/remote";
183
+
184
+ function RemoteAwarePlayer() {
185
+ const { isLeader, isPending, error } = useGingerRemote({
186
+ channelName: "my-app-ginger",
187
+ });
188
+
189
+ return (
190
+ <>
191
+ {error && <p role="alert">{error}</p>}
192
+ {isLeader && <Ginger.Player />}
193
+ {isPending && <p>Connecting to other tabs…</p>}
194
+ </>
195
+ );
196
+ }
197
+ ```
198
+
199
+ Snapshots send the current queue order with **`isShuffled: false`** so followers do not re-randomize; the visible order matches the leader. **`claimLeadership()`** requests leadership (lexicographically smaller tab IDs win conflicts).
200
+
108
201
  ### Experimental Notice
109
202
 
110
203
  `@lucaismyname/ginger/experimental-gapless` is intentionally non-production.
@@ -781,7 +874,11 @@ Example:
781
874
 
782
875
  - **Buffered UI** — **`Ginger.Current.BufferRail`** shows load progress; **`Ginger.Current.TimeRail`** supports **`showBuffered`** to stack a buffered layer behind the played segment.
783
876
 
784
- - **Audio analyzers** — Live Web Audio data for real-time visuals (**`useGingerLiveAnalyzer`**, main package), parametric EQ (**`useGingerEqualizer`**, `@lucaismyname/ginger/equalizer`), and whole-file grids for waveforms or spectrograms (**`useAudioFileAnalysis`** / **`analyzeAudioFile`**, `@lucaismyname/ginger/waveform`). See [Audio analyzers (visualizations)](#audio-analyzers-visualizations).
877
+ - **Audio analyzers** — Live Web Audio data for real-time visuals (**`useGingerLiveAnalyzer`**, main package), parametric EQ (**`useGingerEqualizer`**, `@lucaismyname/ginger/equalizer`), **spatial / HRTF panning** (**`useGingerSpatialAudio`**, `@lucaismyname/ginger/spatial`), and whole-file grids for waveforms or spectrograms (**`useAudioFileAnalysis`** / **`analyzeAudioFile`**, `@lucaismyname/ginger/waveform`). See [Audio analyzers (visualizations)](#audio-analyzers-visualizations).
878
+
879
+ - **Transcripts** — **SRT / WebVTT** parsing and sync (**`parseSrt`**, **`parseVtt`**, **`useGingerTranscriptSync`**, `@lucaismyname/ginger/transcript`); LRC / in-track lyrics remain **`useGingerLyricsSync`** and **`parseLrc()`** on the main package.
880
+
881
+ - **Multi-tab** — **`useGingerRemote`** (`@lucaismyname/ginger/remote`) coordinates playback state across browser tabs; see [Subpath exports](#subpath-exports).
785
882
 
786
883
  Recipes below cover queue lifecycle and media edge cases.
787
884
 
@@ -1114,9 +1211,12 @@ Additional entrypoints:
1114
1211
  - `@lucaismyname/ginger/client`
1115
1212
  - `@lucaismyname/ginger/testing`
1116
1213
  - `@lucaismyname/ginger/waveform`
1214
+ - `@lucaismyname/ginger/spatial`
1215
+ - `@lucaismyname/ginger/transcript`
1216
+ - `@lucaismyname/ginger/remote`
1117
1217
  - `@lucaismyname/ginger/experimental-gapless`
1118
1218
 
1119
- `experimental-gapless` is explicitly non-production and does not alter core playback.
1219
+ See [Subpath Exports](#subpath-exports) for **`spatial`**, **`transcript`**, and **`remote`** usage. `experimental-gapless` is explicitly non-production and does not alter core playback.
1120
1220
 
1121
1221
  ## Notes
1122
1222
 
@@ -1137,8 +1237,8 @@ See [Recipes — Updating the queue after mount](#updating-the-queue-after-mount
1137
1237
  These priorities guide new work in the library; they are not a guarantee of shipping order.
1138
1238
 
1139
1239
  1. **Music libraries and continuous listening** — Features that make track-to-track playback feel better come first: **next-track prefetch** (`useNextTrackPrefetch`), future gapless or crossfade (see `@lucaismyname/ginger/experimental-gapless`), and first-class **chapter** / **synced lyrics** UI (`Ginger.Current.Chapters`, `Ginger.Current.LyricsSynced`).
1140
- 2. **Podcasts and live-style streams** — **HLS / DASH** integration is emphasized when a concrete app needs it; the core package stays on native `<audio>` with optional adapters or documentation rather than hard dependencies.
1141
- 3. **Embedded or internal players** — **Accessibility**, persistence, and **testing** helpers are favored over heavier ecosystem integrations (Cast, remote playback modules) unless there is a dedicated use case.
1240
+ 2. **Podcasts and live-style streams** — **HLS / DASH** integration is emphasized when a concrete app needs it; the core package stays on native `<audio>` with optional adapters or documentation rather than hard dependencies. **SRT / WebVTT** transcripts are supported via `@lucaismyname/ginger/transcript`.
1241
+ 3. **Embedded or internal players** — **Accessibility**, persistence, and **testing** helpers are favored over heavier ecosystem integrations (Cast, proprietary cast SDKs) unless there is a dedicated use case. **Multi-tab** web apps can use `@lucaismyname/ginger/remote` (BroadcastChannel) before reaching for OS-level remote playback.
1142
1242
 
1143
1243
  ## Monorepo Development
1144
1244
 
package/dist/client.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./ginger-NEcOSSJD.cjs"),s=require("./useGinger-BXgia32v.cjs"),r=require("./useGingerChapterProgress-BdaalJvX.cjs"),i=require("./liveAudioGraph-0cpHD_Ic.cjs"),n=require("./selectors-YXnP8Y8g.cjs"),a=require("./GingerSplitContexts-C7puo0M7.cjs");exports.Chapters=e.Chapters;exports.Ginger=e.Ginger;exports.LyricsSynced=e.LyricsSynced;exports.Pause=e.Pause;exports.Play=e.Play;exports.RepeatGlyph=e.RepeatGlyph;exports.ShuffleIcon=e.ShuffleIcon;exports.SkipBack=e.SkipBack;exports.SkipForward=e.SkipForward;exports.Volume2=e.Volume2;exports.VolumeX=e.VolumeX;exports.Wrapper=e.Wrapper;exports.clampPlaybackRate=e.clampPlaybackRate;exports.clampVolume=e.clampVolume;exports.defaultGingerLocale=e.defaultGingerLocale;exports.parseLrc=e.parseLrc;exports.useGingerChapters=e.useGingerChapters;exports.useGingerLocale=e.useGingerLocale;exports.useGingerLyricsSync=e.useGingerLyricsSync;exports.usePlayPauseBinding=e.usePlayPauseBinding;exports.useSeekBarBinding=e.useSeekBarBinding;exports.useVolumeSlider=e.useVolumeSlider;exports.useGinger=s.useGinger;exports.createGingerStore=r.createGingerStore;exports.useGingerChapterProgress=r.useGingerChapterProgress;exports.useGingerDebugLog=r.useGingerDebugLog;exports.useGingerKeyboardShortcuts=r.useGingerKeyboardShortcuts;exports.useGingerLiveAnalyzer=r.useGingerLiveAnalyzer;exports.useGingerPlaybackHistory=r.useGingerPlaybackHistory;exports.useGingerSleepTimer=r.useGingerSleepTimer;exports.useGingerVolumeFade=r.useGingerVolumeFade;exports.useNextTrackPrefetch=r.useNextTrackPrefetch;exports.useSeekDrag=r.useSeekDrag;exports.attachLiveAnalyser=i.attachLiveAnalyser;exports.detachLiveAnalyser=i.detachLiveAnalyser;exports.setProcessingChain=i.setProcessingChain;exports.derivePlaybackUiState=n.derivePlaybackUiState;exports.gingerStateFromContextValues=a.gingerStateFromContextValues;exports.gingerStateFromContexts=a.gingerStateFromContexts;exports.useGingerMedia=a.useGingerMedia;exports.useGingerPlayback=a.useGingerPlayback;exports.useGingerState=a.useGingerState;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./ginger-jToP7EpI.cjs"),s=require("./useGinger-BXgia32v.cjs"),r=require("./useGingerChapterProgress-B2-J3dSP.cjs"),i=require("./liveAudioGraph-0cpHD_Ic.cjs"),n=require("./selectors-YXnP8Y8g.cjs"),a=require("./GingerSplitContexts-C7puo0M7.cjs");exports.Chapters=e.Chapters;exports.Ginger=e.Ginger;exports.LyricsSynced=e.LyricsSynced;exports.Pause=e.Pause;exports.Play=e.Play;exports.RepeatGlyph=e.RepeatGlyph;exports.ShuffleIcon=e.ShuffleIcon;exports.SkipBack=e.SkipBack;exports.SkipForward=e.SkipForward;exports.Volume2=e.Volume2;exports.VolumeX=e.VolumeX;exports.Wrapper=e.Wrapper;exports.clampPlaybackRate=e.clampPlaybackRate;exports.clampVolume=e.clampVolume;exports.defaultGingerLocale=e.defaultGingerLocale;exports.parseLrc=e.parseLrc;exports.useGingerChapters=e.useGingerChapters;exports.useGingerLocale=e.useGingerLocale;exports.useGingerLyricsSync=e.useGingerLyricsSync;exports.usePlayPauseBinding=e.usePlayPauseBinding;exports.useSeekBarBinding=e.useSeekBarBinding;exports.useVolumeSlider=e.useVolumeSlider;exports.useGinger=s.useGinger;exports.createGingerStore=r.createGingerStore;exports.useGingerChapterProgress=r.useGingerChapterProgress;exports.useGingerDebugLog=r.useGingerDebugLog;exports.useGingerKeyboardShortcuts=r.useGingerKeyboardShortcuts;exports.useGingerLiveAnalyzer=r.useGingerLiveAnalyzer;exports.useGingerPlaybackHistory=r.useGingerPlaybackHistory;exports.useGingerSleepTimer=r.useGingerSleepTimer;exports.useGingerVolumeFade=r.useGingerVolumeFade;exports.useNextTrackPrefetch=r.useNextTrackPrefetch;exports.useSeekDrag=r.useSeekDrag;exports.attachLiveAnalyser=i.attachLiveAnalyser;exports.detachLiveAnalyser=i.detachLiveAnalyser;exports.setProcessingChain=i.setProcessingChain;exports.derivePlaybackUiState=n.derivePlaybackUiState;exports.gingerStateFromContextValues=a.gingerStateFromContextValues;exports.gingerStateFromContexts=a.gingerStateFromContexts;exports.useGingerMedia=a.useGingerMedia;exports.useGingerPlayback=a.useGingerPlayback;exports.useGingerState=a.useGingerState;
2
2
  //# sourceMappingURL=client.cjs.map
package/dist/client.js CHANGED
@@ -1,6 +1,6 @@
1
- import { C as s, G as r, L as i, P as t, a as u, R as n, S as o, b as g, c, V as l, d as p, W as G, e as m, f as y, g as S, p as d, u as f, h, i as P, j as k, k as L, l as b } from "./ginger-L2ZFgzH4.js";
1
+ import { C as s, G as r, L as i, P as t, a as u, R as n, S as o, b as g, c, V as l, d as p, W as G, e as m, f as y, g as S, p as d, u as f, h, i as P, j as k, k as L, l as b } from "./ginger-DlCkxDXs.js";
2
2
  import { u as C } from "./useGinger-hpp2pAGY.js";
3
- import { c as v, u as B, a as F, b as A, d as R, e as D, f as T, g as W, h as j, i as w } from "./useGingerChapterProgress-CZdv-HiI.js";
3
+ import { c as v, u as B, a as F, b as A, d as R, e as D, f as T, g as W, h as j, i as w } from "./useGingerChapterProgress-BW6v65wN.js";
4
4
  import { a as H, d as I, s as K } from "./liveAudioGraph-DvPaxBCP.js";
5
5
  import { d as N } from "./selectors-BalBCc7X.js";
6
6
  import { g as X, a as q, u as E, b as J, c as O } from "./GingerSplitContexts-BzBExb95.js";
@@ -31,14 +31,14 @@ function kn({
31
31
  return I(), g.addEventListener("change", I), () => g.removeEventListener("change", I);
32
32
  }, [n]);
33
33
  const v = (g, I = !1) => {
34
- const G = {
34
+ const w = {
35
35
  currentTime: g.currentTime,
36
36
  duration: g.duration,
37
37
  bufferedFraction: nr(g)
38
- }, F = f.current, Z = T ? 0.5 : 0.25, ee = Math.abs(G.currentTime - F.currentTime) >= Z || Math.abs(G.duration - F.duration) >= 0.01 || Math.abs(G.bufferedFraction - F.bufferedFraction) >= 0.01;
39
- !I && !ee || (f.current = G, o({
38
+ }, F = f.current, Z = T ? 0.5 : 0.25, ee = Math.abs(w.currentTime - F.currentTime) >= Z || Math.abs(w.duration - F.duration) >= 0.01 || Math.abs(w.bufferedFraction - F.bufferedFraction) >= 0.01;
39
+ !I && !ee || (f.current = w, o({
40
40
  type: "MEDIA_TIME_UPDATE",
41
- payload: G
41
+ payload: w
42
42
  }));
43
43
  };
44
44
  return E(() => {
@@ -522,10 +522,10 @@ function H(e, r) {
522
522
  function j(e, r) {
523
523
  return H(e, (t) => r(K(t)));
524
524
  }
525
- const An = j("Ginger.Current.Title", (e) => e == null ? void 0 : e.title), Sn = j("Ginger.Current.Artist", (e) => e == null ? void 0 : e.artist), Rn = H("Ginger.Current.Album", (e) => ln(e)), Gn = j(
525
+ const An = j("Ginger.Current.Title", (e) => e == null ? void 0 : e.title), Sn = j("Ginger.Current.Artist", (e) => e == null ? void 0 : e.artist), Rn = H("Ginger.Current.Album", (e) => ln(e)), wn = j(
526
526
  "Ginger.Current.Description",
527
527
  (e) => e == null ? void 0 : e.description
528
- ), wn = H("Ginger.Current.Copyright", (e) => {
528
+ ), Gn = H("Ginger.Current.Copyright", (e) => {
529
529
  var t;
530
530
  const r = K(e);
531
531
  return (r == null ? void 0 : r.copyright) ?? ((t = e.playlistMeta) == null ? void 0 : t.copyright);
@@ -604,7 +604,7 @@ function Fn() {
604
604
  activeLine: i >= 0 ? n[i] ?? null : null
605
605
  };
606
606
  }
607
- function Gr({
607
+ function wr({
608
608
  className: e,
609
609
  style: r,
610
610
  fallback: t,
@@ -661,7 +661,7 @@ function Gr({
661
661
  }
662
662
  );
663
663
  }
664
- Gr.displayName = "Ginger.Current.LyricsSynced";
664
+ wr.displayName = "Ginger.Current.LyricsSynced";
665
665
  function Un() {
666
666
  const { tracks: e, currentIndex: r } = N(), { currentTime: t, seek: a } = X(), n = A(() => {
667
667
  var u;
@@ -682,7 +682,7 @@ function Un() {
682
682
  }
683
683
  };
684
684
  }
685
- function wr({
685
+ function Gr({
686
686
  className: e,
687
687
  style: r,
688
688
  fallback: t,
@@ -750,7 +750,7 @@ function wr({
750
750
  }
751
751
  );
752
752
  }
753
- wr.displayName = "Ginger.Current.Chapters";
753
+ Gr.displayName = "Ginger.Current.Chapters";
754
754
  function Lr({
755
755
  visible: e = !1,
756
756
  className: r,
@@ -1314,7 +1314,7 @@ function zr({
1314
1314
  const o = P(), u = (l = o.playlistMeta) == null ? void 0 : l.artworkUrl;
1315
1315
  if (!u) {
1316
1316
  const m = a ?? t ?? null;
1317
- return m ? /* @__PURE__ */ c("span", { className: e, style: r, children: m }) : null;
1317
+ return m ? /* @__PURE__ */ c("span", { "data-ginger-component": "Artwork", className: e, style: r, children: m }) : null;
1318
1318
  }
1319
1319
  const d = ((f = o.playlistMeta) == null ? void 0 : f.title) ?? "Playlist artwork";
1320
1320
  return /* @__PURE__ */ c(
@@ -1658,7 +1658,7 @@ function Xn({
1658
1658
  onPlayBlocked: x,
1659
1659
  persistence: g,
1660
1660
  hydrateOnMount: I = !1,
1661
- resumeOnTrackChange: G = !1,
1661
+ resumeOnTrackChange: w = !1,
1662
1662
  unstyled: F = !1,
1663
1663
  asChild: Z = !1,
1664
1664
  className: ee,
@@ -1831,7 +1831,7 @@ function Xn({
1831
1831
  E(() => {
1832
1832
  if (!(!g || !I))
1833
1833
  try {
1834
- const p = g.get("ginger:volume"), b = g.get("ginger:muted"), k = g.get("ginger:playbackRate"), w = g.get("ginger:repeatMode"), we = g.get("ginger:currentIndex"), D = De.current;
1834
+ const p = g.get("ginger:volume"), b = g.get("ginger:muted"), k = g.get("ginger:playbackRate"), G = g.get("ginger:repeatMode"), Ge = g.get("ginger:currentIndex"), D = De.current;
1835
1835
  y({
1836
1836
  type: "INIT",
1837
1837
  payload: {
@@ -1840,8 +1840,8 @@ function Xn({
1840
1840
  isPaused: D.isPaused,
1841
1841
  isShuffled: D.isShuffled,
1842
1842
  playbackMode: D.playbackMode,
1843
- currentIndex: typeof we == "number" ? we : D.currentIndex,
1844
- repeatMode: w === "off" || w === "all" || w === "one" ? w : D.repeatMode,
1843
+ currentIndex: typeof Ge == "number" ? Ge : D.currentIndex,
1844
+ repeatMode: G === "off" || G === "all" || G === "one" ? G : D.repeatMode,
1845
1845
  volume: typeof p == "number" ? p : D.volume,
1846
1846
  muted: typeof b == "boolean" ? b : D.muted,
1847
1847
  playbackRate: typeof k == "number" ? k : D.playbackRate
@@ -1865,7 +1865,7 @@ function Xn({
1865
1865
  s.repeatMode,
1866
1866
  s.currentIndex
1867
1867
  ]), E(() => {
1868
- if (!g || !G) return;
1868
+ if (!g || !w) return;
1869
1869
  const p = s.tracks[s.currentIndex];
1870
1870
  if (!p) return;
1871
1871
  const b = `ginger:resume:${Ve(p)}`;
@@ -1875,19 +1875,19 @@ function Xn({
1875
1875
  } catch (k) {
1876
1876
  process.env.NODE_ENV !== "production" && console.warn("[@lucaismyname/ginger] persistence.get() threw during resume:", k);
1877
1877
  }
1878
- }, [g, G, s.currentIndex, s.tracks, $]), E(() => {
1879
- if (!g || !G) return;
1878
+ }, [g, w, s.currentIndex, s.tracks, $]), E(() => {
1879
+ if (!g || !w) return;
1880
1880
  const p = s.tracks[s.currentIndex];
1881
1881
  if (!p || !(s.currentTime >= 0)) return;
1882
1882
  const b = `ginger:resume:${Ve(p)}`, k = setTimeout(() => {
1883
1883
  try {
1884
1884
  g.set(b, s.currentTime);
1885
- } catch (w) {
1886
- process.env.NODE_ENV !== "production" && console.warn("[@lucaismyname/ginger] persistence.set() threw during resume save:", w);
1885
+ } catch (G) {
1886
+ process.env.NODE_ENV !== "production" && console.warn("[@lucaismyname/ginger] persistence.set() threw during resume save:", G);
1887
1887
  }
1888
1888
  }, 250);
1889
1889
  return () => clearTimeout(k);
1890
- }, [g, G, s.currentIndex, s.tracks, s.currentTime]);
1890
+ }, [g, w, s.currentIndex, s.tracks, s.currentTime]);
1891
1891
  const Kr = (Je = s.tracks[s.currentIndex]) == null ? void 0 : Je.fileUrl;
1892
1892
  E(() => {
1893
1893
  const p = V.current;
@@ -1902,9 +1902,9 @@ function Xn({
1902
1902
  let k = !1;
1903
1903
  try {
1904
1904
  k = await v();
1905
- } catch (w) {
1906
- const we = w instanceof Error ? w.message : "beforePlay rejected";
1907
- y({ type: "MEDIA_ERROR", payload: { message: we } });
1905
+ } catch (G) {
1906
+ const Ge = G instanceof Error ? G.message : "beforePlay rejected";
1907
+ y({ type: "MEDIA_ERROR", payload: { message: Ge } });
1908
1908
  return;
1909
1909
  }
1910
1910
  if (!k) {
@@ -1913,14 +1913,14 @@ function Xn({
1913
1913
  }
1914
1914
  }
1915
1915
  b || p.play().catch((k) => {
1916
- const w = k instanceof Error ? k.message : typeof k == "string" ? k : "Playback failed (e.g. autoplay blocked or unavailable source)";
1917
- y({ type: "MEDIA_ERROR", payload: { message: w } });
1916
+ const G = k instanceof Error ? k.message : typeof k == "string" ? k : "Playback failed (e.g. autoplay blocked or unavailable source)";
1917
+ y({ type: "MEDIA_ERROR", payload: { message: G } });
1918
1918
  });
1919
1919
  })(), () => {
1920
1920
  b = !0;
1921
1921
  };
1922
1922
  }, [v, Kr, x, s.isPaused]);
1923
- const Ge = M(() => {
1923
+ const we = M(() => {
1924
1924
  const p = vn(ze.current);
1925
1925
  if (p.kind === "replay_same") {
1926
1926
  const k = V.current;
@@ -1943,7 +1943,7 @@ function Xn({
1943
1943
  state: s,
1944
1944
  dispatch: y,
1945
1945
  audioRef: V,
1946
- notifyEnded: Ge,
1946
+ notifyEnded: we,
1947
1947
  init: Re,
1948
1948
  play: B,
1949
1949
  pause: O,
@@ -1973,7 +1973,7 @@ function Xn({
1973
1973
  y,
1974
1974
  Re,
1975
1975
  z,
1976
- Ge,
1976
+ we,
1977
1977
  O,
1978
1978
  B,
1979
1979
  Ee,
@@ -2071,7 +2071,7 @@ function Xn({
2071
2071
  toggleMute: me,
2072
2072
  setPlaybackRate: ye,
2073
2073
  audioRef: V,
2074
- notifyEnded: Ge,
2074
+ notifyEnded: we,
2075
2075
  dispatch: y
2076
2076
  }),
2077
2077
  [
@@ -2089,7 +2089,7 @@ function Xn({
2089
2089
  me,
2090
2090
  ye,
2091
2091
  V,
2092
- Ge,
2092
+ we,
2093
2093
  y
2094
2094
  ]
2095
2095
  ), Ke = cr(s), qe = A(
@@ -2139,16 +2139,16 @@ const rt = {
2139
2139
  Title: An,
2140
2140
  Artist: Sn,
2141
2141
  Album: Rn,
2142
- Description: Gn,
2143
- Copyright: wn,
2142
+ Description: wn,
2143
+ Copyright: Gn,
2144
2144
  Genre: Ln,
2145
2145
  Label: Nn,
2146
2146
  Isrc: _n,
2147
2147
  TrackNumber: Dn,
2148
2148
  Year: Sr,
2149
2149
  Lyrics: Rr,
2150
- LyricsSynced: Gr,
2151
- Chapters: wr,
2150
+ LyricsSynced: wr,
2151
+ Chapters: Gr,
2152
2152
  FileUrl: Lr,
2153
2153
  Artwork: Nr,
2154
2154
  QueueIndex: _r,
@@ -2195,9 +2195,9 @@ const rt = {
2195
2195
  Playlist: Bn
2196
2196
  };
2197
2197
  export {
2198
- wr as C,
2198
+ Gr as C,
2199
2199
  rt as G,
2200
- Gr as L,
2200
+ wr as L,
2201
2201
  dr as P,
2202
2202
  gr as R,
2203
2203
  fr as S,
@@ -2220,4 +2220,4 @@ export {
2220
2220
  Cn as p,
2221
2221
  Un as u
2222
2222
  };
2223
- //# sourceMappingURL=ginger-L2ZFgzH4.js.map
2223
+ //# sourceMappingURL=ginger-DlCkxDXs.js.map