@lucaismyname/ginger 0.0.55 → 0.0.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -1
- package/dist/client.cjs +1 -1
- package/dist/client.js +2 -2
- package/dist/context/GingerProvider.d.ts +1 -1
- package/dist/context/GingerProvider.d.ts.map +1 -1
- package/dist/devtools/GingerDevtools.d.ts +2 -0
- package/dist/devtools/GingerDevtools.d.ts.map +1 -0
- package/dist/devtools/index.cjs +2 -0
- package/dist/devtools/index.cjs.map +1 -0
- package/dist/devtools/index.d.ts +3 -0
- package/dist/devtools/index.d.ts.map +1 -0
- package/dist/devtools/index.js +465 -0
- package/dist/devtools/index.js.map +1 -0
- package/dist/devtools/registry.d.ts +49 -0
- package/dist/devtools/registry.d.ts.map +1 -0
- package/dist/formatTime-DUWvzW21.js +9 -0
- package/dist/formatTime-DUWvzW21.js.map +1 -0
- package/dist/formatTime-fm_QClmG.cjs +2 -0
- package/dist/formatTime-fm_QClmG.cjs.map +1 -0
- package/dist/ginger-B-W73LQC.cjs +2 -0
- package/dist/ginger-B-W73LQC.cjs.map +1 -0
- package/dist/ginger-BHu7Ofna.js +2177 -0
- package/dist/ginger-BHu7Ofna.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +2 -2
- package/dist/testing/index.cjs +1 -1
- package/dist/testing/index.js +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/{useGingerChapterProgress-DIk27KzH.js → useGingerChapterProgress-DAIWjAtG.js} +2 -2
- package/dist/{useGingerChapterProgress-DIk27KzH.js.map → useGingerChapterProgress-DAIWjAtG.js.map} +1 -1
- package/dist/{useGingerChapterProgress-BgLkDm2S.cjs → useGingerChapterProgress-DLx-LayX.cjs} +2 -2
- package/dist/{useGingerChapterProgress-BgLkDm2S.cjs.map → useGingerChapterProgress-DLx-LayX.cjs.map} +1 -1
- package/package.json +6 -1
- package/dist/ginger-Bzjmat52.cjs +0 -2
- package/dist/ginger-Bzjmat52.cjs.map +0 -1
- package/dist/ginger-r_BCOWSm.js +0 -2121
- package/dist/ginger-r_BCOWSm.js.map +0 -1
package/README.md
CHANGED
|
@@ -78,6 +78,7 @@ For docs beyond this README, use the repository links below:
|
|
|
78
78
|
- `@lucaismyname/ginger/remote`
|
|
79
79
|
- `@lucaismyname/ginger/crossfade`
|
|
80
80
|
- `@lucaismyname/ginger/experimental-gapless`
|
|
81
|
+
- `@lucaismyname/ginger/devtools`
|
|
81
82
|
|
|
82
83
|
### Equalizer
|
|
83
84
|
|
|
@@ -233,6 +234,35 @@ function CrossfadeSetup() {
|
|
|
233
234
|
|
|
234
235
|
For lower-level integrations, the subpath also exports **`attachCrossfadeGraph`**, **`scheduleCrossfade`**, and **`teardownCrossfadeGraph`** plus the related graph/curve types. Like EQ and spatial audio, crossfade attaches to the active Ginger media graph and should be torn down when you unmount or switch playback strategies.
|
|
235
236
|
|
|
237
|
+
### Devtools (`@lucaismyname/ginger/devtools`)
|
|
238
|
+
|
|
239
|
+
A debugging overlay for inspecting and controlling Ginger audio players at runtime. Supports **multiple providers** on the same page via a global registry — place a single `<GingerDevtools />` anywhere in your app and it auto-discovers every active `<Ginger.Provider>`.
|
|
240
|
+
|
|
241
|
+
```tsx
|
|
242
|
+
import { GingerDevtools } from "@lucaismyname/ginger/devtools";
|
|
243
|
+
|
|
244
|
+
function App() {
|
|
245
|
+
return (
|
|
246
|
+
<>
|
|
247
|
+
<Ginger.Provider debugLabel="Main Player" initialTracks={tracks}>
|
|
248
|
+
{/* ... */}
|
|
249
|
+
</Ginger.Provider>
|
|
250
|
+
|
|
251
|
+
<Ginger.Provider debugLabel="Ambient" initialTracks={ambientTracks}>
|
|
252
|
+
{/* ... */}
|
|
253
|
+
</Ginger.Provider>
|
|
254
|
+
|
|
255
|
+
{/* Single devtools instance — discovers both providers */}
|
|
256
|
+
<GingerDevtools />
|
|
257
|
+
</>
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
The overlay provides **bidirectional controls**: you can play/pause, seek, change volume, adjust playback rate, toggle repeat/shuffle, and click tracks in the queue — all changes apply to the live player instantly. State changes from the player are reflected in the devtools panel in real-time.
|
|
263
|
+
|
|
264
|
+
The panel uses Tailwind CSS via CDN (injected on mount, removed on unmount) and renders in a portal so it does not interfere with your app's layout or styles. Use the `debugLabel` prop on `<Ginger.Provider>` to give each player a human-readable tab name.
|
|
265
|
+
|
|
236
266
|
### Experimental Notice
|
|
237
267
|
|
|
238
268
|
`@lucaismyname/ginger/experimental-gapless` is intentionally non-production.
|
|
@@ -565,6 +595,7 @@ Props:
|
|
|
565
595
|
| `onSeek` | `(timeSeconds: number) => void` | `undefined` | Fires whenever `seek()` is invoked |
|
|
566
596
|
| `dir` | `"ltr" \| "rtl" \| "auto"` | locale-derived | Explicit provider layout direction |
|
|
567
597
|
| `prevRestartThresholdSeconds` | `number` | `3` | Previous restarts current track when `currentTime > threshold`; set `0` to always skip |
|
|
598
|
+
| `debugLabel` | `string` | `undefined` | Human-readable label shown in devtools tabs when multiple providers exist |
|
|
568
599
|
|
|
569
600
|
### `Ginger.Player`
|
|
570
601
|
|
|
@@ -1208,6 +1239,7 @@ New callbacks available on `Ginger.Provider`:
|
|
|
1208
1239
|
|
|
1209
1240
|
- `dir?: "ltr" | "rtl" | "auto"` — explicit layout direction; takes priority over the automatic RTL heuristic derived from locale strings
|
|
1210
1241
|
- `prevRestartThresholdSeconds?: number` — pressing previous restarts the current track when `currentTime > threshold` (default `3`); set to `0` to always skip to the previous track
|
|
1242
|
+
- `debugLabel?: string` — human-readable label shown in the devtools tab when multiple providers exist
|
|
1211
1243
|
|
|
1212
1244
|
### Queue mutation actions and single-track mode
|
|
1213
1245
|
|
|
@@ -1257,8 +1289,9 @@ Additional entrypoints:
|
|
|
1257
1289
|
- `@lucaismyname/ginger/remote`
|
|
1258
1290
|
- `@lucaismyname/ginger/crossfade`
|
|
1259
1291
|
- `@lucaismyname/ginger/experimental-gapless`
|
|
1292
|
+
- `@lucaismyname/ginger/devtools`
|
|
1260
1293
|
|
|
1261
|
-
See [Subpath Exports](#subpath-exports) for **`spatial`**, **`transcript`**, and **`
|
|
1294
|
+
See [Subpath Exports](#subpath-exports) for **`spatial`**, **`transcript`**, **`remote`**, and **`devtools`** usage. `experimental-gapless` is explicitly non-production and does not alter core playback.
|
|
1262
1295
|
|
|
1263
1296
|
## Notes
|
|
1264
1297
|
|
package/dist/client.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./ginger-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./ginger-B-W73LQC.cjs"),s=require("./useGinger-BMRLzjmr.cjs"),r=require("./useGingerChapterProgress-DLx-LayX.cjs"),a=require("./liveAudioGraph-0cpHD_Ic.cjs"),n=require("./selectors-CEGlYoFu.cjs"),i=require("./GingerSplitContexts-KSB0vQ5F.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=a.attachLiveAnalyser;exports.detachLiveAnalyser=a.detachLiveAnalyser;exports.setProcessingChain=a.setProcessingChain;exports.derivePlaybackUiState=n.derivePlaybackUiState;exports.gingerStateFromContextValues=i.gingerStateFromContextValues;exports.gingerStateFromContexts=i.gingerStateFromContexts;exports.useGingerMedia=i.useGingerMedia;exports.useGingerMediaControls=i.useGingerMediaControls;exports.useGingerPlayback=i.useGingerPlayback;exports.useGingerState=i.useGingerState;exports.useGingerTime=i.useGingerTime;
|
|
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 u, a as n, R as t, S as o, b as g, c as l, V as c, d as G, W as p, e as d, f as m, g as y, p as S, u as f, h, i as P, j as k, k as L, l as b } from "./ginger-
|
|
1
|
+
import { C as s, G as r, L as i, P as u, a as n, R as t, S as o, b as g, c as l, V as c, d as G, W as p, e as d, f as m, g as y, p as S, u as f, h, i as P, j as k, k as L, l as b } from "./ginger-BHu7Ofna.js";
|
|
2
2
|
import { u as C } from "./useGinger-DKrHZ4NU.js";
|
|
3
|
-
import { c as v, u as B, a as F, b as A, d as R, e as T, f as D, g as M, h as W, i as j } from "./useGingerChapterProgress-
|
|
3
|
+
import { c as v, u as B, a as F, b as A, d as R, e as T, f as D, g as M, h as W, i as j } from "./useGingerChapterProgress-DAIWjAtG.js";
|
|
4
4
|
import { a as z, d as H, s as I } from "./liveAudioGraph-DvPaxBCP.js";
|
|
5
5
|
import { d as N } from "./selectors-BT3WSsKN.js";
|
|
6
6
|
import { g as X, a as q, u as E, b as J, c as O, d as Q, e as Y } from "./GingerSplitContexts-DQ3rESBu.js";
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { GingerProviderProps } from '../types';
|
|
2
|
-
export declare function GingerProvider({ children, initialTracks, initialIndex, initialPlaylistMeta, initialShuffle, initialRepeatMode, initialPlaybackMode, initialPaused, initialVolume, initialMuted, initialPlaybackRate, initialStateKey, locale, mediaSession, beforePlay, onPlayBlocked, retryOnError, persistence, hydrateOnMount, resumeOnTrackChange, unstyled, asChild, className, style, dir: dirProp, prevRestartThresholdSeconds, onTrackChange, onPlay, onPause, onQueueEnd, onError, onVolumeChange, onPlaybackRateChange, onSeek, }: GingerProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare function GingerProvider({ children, initialTracks, initialIndex, initialPlaylistMeta, initialShuffle, initialRepeatMode, initialPlaybackMode, initialPaused, initialVolume, initialMuted, initialPlaybackRate, initialStateKey, locale, mediaSession, beforePlay, onPlayBlocked, retryOnError, persistence, hydrateOnMount, resumeOnTrackChange, unstyled, asChild, className, style, dir: dirProp, prevRestartThresholdSeconds, onTrackChange, onPlay, onPause, onQueueEnd, onError, onVolumeChange, onPlaybackRateChange, onSeek, debugLabel, }: GingerProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
3
3
|
//# sourceMappingURL=GingerProvider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GingerProvider.d.ts","sourceRoot":"","sources":["../../src/context/GingerProvider.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAEV,mBAAmB,EAMpB,MAAM,UAAU,CAAC;AA2BlB,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,aAAkB,EAClB,YAAgB,EAChB,mBAA0B,EAC1B,cAAsB,EACtB,iBAAyB,EACzB,mBAAgC,EAChC,aAAoB,EACpB,aAAiB,EACjB,YAAoB,EACpB,mBAAuB,EACvB,eAAe,EACf,MAAM,EACN,YAAoB,EACpB,UAAU,EACV,aAAa,EACb,YAAY,EACZ,WAAW,EACX,cAAsB,EACtB,mBAA2B,EAC3B,QAAgB,EAChB,OAAe,EACf,SAAS,EACT,KAAK,EACL,GAAG,EAAE,OAAO,EACZ,2BAA+B,EAC/B,aAAa,EACb,MAAM,EACN,OAAO,EACP,UAAU,EACV,OAAO,EACP,cAAc,EACd,oBAAoB,EACpB,MAAM,
|
|
1
|
+
{"version":3,"file":"GingerProvider.d.ts","sourceRoot":"","sources":["../../src/context/GingerProvider.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAEV,mBAAmB,EAMpB,MAAM,UAAU,CAAC;AA2BlB,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,aAAkB,EAClB,YAAgB,EAChB,mBAA0B,EAC1B,cAAsB,EACtB,iBAAyB,EACzB,mBAAgC,EAChC,aAAoB,EACpB,aAAiB,EACjB,YAAoB,EACpB,mBAAuB,EACvB,eAAe,EACf,MAAM,EACN,YAAoB,EACpB,UAAU,EACV,aAAa,EACb,YAAY,EACZ,WAAW,EACX,cAAsB,EACtB,mBAA2B,EAC3B,QAAgB,EAChB,OAAe,EACf,SAAS,EACT,KAAK,EACL,GAAG,EAAE,OAAO,EACZ,2BAA+B,EAC/B,aAAa,EACb,MAAM,EACN,OAAO,EACP,UAAU,EACV,OAAO,EACP,cAAc,EACd,oBAAoB,EACpB,MAAM,EACN,UAAU,GACX,EAAE,mBAAmB,2CAqyBrB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GingerDevtools.d.ts","sourceRoot":"","sources":["../../src/devtools/GingerDevtools.tsx"],"names":[],"mappings":"AAoVA,wBAAgB,cAAc,uCAuJ7B"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),s=require("react"),h=require("react-dom"),x=require("../formatTime-fm_QClmG.cjs"),u="__GINGER_DEVTOOLS__";let p=0;function f(){const n=new Map,t=new Set,r=()=>{for(const g of t)g(n)};return{register(g,d){p+=1;const i={id:g,label:d.label||`Player ${p}`,state:d.state,actions:d.actions,audioSrc:d.audioSrc,registeredAt:Date.now(),updatedAt:Date.now()};n.set(g,i),r()},unregister(g){n.delete(g)&&r()},update(g,d){const i=n.get(g);i&&(i.state=d.state,i.audioSrc=d.audioSrc,i.updatedAt=Date.now(),r())},subscribe(g){return t.add(g),()=>{t.delete(g)}},getAll(){return n}}}function b(){if(typeof window>"u")throw new Error("GingerDevtools requires a browser environment.");const n=window;let t=n[u];return t||(t=f(),n[u]=t),t}const m="https://cdn.tailwindcss.com";function j(){const n=s.useRef(null);s.useEffect(()=>{if(document.querySelector(`script[src="${m}"]`))return;const t=document.createElement("script");return t.src=m,t.async=!0,document.head.appendChild(t),n.current=t,()=>{var r;(r=n.current)!=null&&r.parentNode&&n.current.parentNode.removeChild(n.current)}},[])}function y(){const[n,t]=s.useState([]);return s.useEffect(()=>{const r=b(),g=d=>{t(Array.from(d.values()))};return g(r.getAll()),r.subscribe(g)},[]),n}function v({snap:n}){const{state:t,actions:r}=n,g=t.tracks[t.currentIndex];return e.jsxs("div",{className:"ginger-dt-space-y-2",children:[e.jsx("h4",{className:"ginger-dt-text-[10px] ginger-dt-font-semibold ginger-dt-uppercase ginger-dt-tracking-wider ginger-dt-text-orange-400",children:"Playback"}),e.jsxs("div",{className:"ginger-dt-flex ginger-dt-items-center ginger-dt-gap-1.5",children:[e.jsx("button",{type:"button",onClick:r.prev,className:"ginger-dt-rounded ginger-dt-bg-neutral-700 ginger-dt-px-2 ginger-dt-py-0.5 ginger-dt-text-[11px] hover:ginger-dt-bg-neutral-600 ginger-dt-transition-colors",title:"Previous",children:"⏮"}),e.jsx("button",{type:"button",onClick:r.togglePlayPause,className:"ginger-dt-rounded ginger-dt-bg-orange-600 ginger-dt-px-3 ginger-dt-py-0.5 ginger-dt-text-[11px] ginger-dt-font-medium hover:ginger-dt-bg-orange-500 ginger-dt-transition-colors",children:t.isPaused?"▶ Play":"⏸ Pause"}),e.jsx("button",{type:"button",onClick:r.next,className:"ginger-dt-rounded ginger-dt-bg-neutral-700 ginger-dt-px-2 ginger-dt-py-0.5 ginger-dt-text-[11px] hover:ginger-dt-bg-neutral-600 ginger-dt-transition-colors",title:"Next",children:"⏭"})]}),e.jsxs("div",{className:"ginger-dt-grid ginger-dt-grid-cols-2 ginger-dt-gap-x-3 ginger-dt-gap-y-1 ginger-dt-text-[11px]",children:[e.jsx(l,{label:"Track",value:g?`${t.currentIndex+1}/${t.tracks.length}`:"—"}),e.jsx(l,{label:"Mode",value:t.playbackMode,children:e.jsx("button",{type:"button",onClick:()=>r.setPlaybackMode(t.playbackMode==="playlist"?"single":"playlist"),className:"ginger-dt-ml-1 ginger-dt-text-orange-400 hover:ginger-dt-text-orange-300 ginger-dt-text-[10px]",children:"↻"})}),e.jsx(l,{label:"Repeat",value:t.repeatMode,children:e.jsx("button",{type:"button",onClick:r.cycleRepeat,className:"ginger-dt-ml-1 ginger-dt-text-orange-400 hover:ginger-dt-text-orange-300 ginger-dt-text-[10px]",children:"↻"})}),e.jsx(l,{label:"Shuffle",value:t.isShuffled?"on":"off",children:e.jsx("button",{type:"button",onClick:r.toggleShuffle,className:"ginger-dt-ml-1 ginger-dt-text-orange-400 hover:ginger-dt-text-orange-300 ginger-dt-text-[10px]",children:"↻"})})]})]})}function N({snap:n}){const{state:t,actions:r}=n,g=s.useCallback(i=>{r.seek(Number(i.target.value))},[r]),d=s.useCallback(i=>{r.setVolume(Number(i.target.value))},[r]);return e.jsxs("div",{className:"ginger-dt-space-y-2",children:[e.jsx("h4",{className:"ginger-dt-text-[10px] ginger-dt-font-semibold ginger-dt-uppercase ginger-dt-tracking-wider ginger-dt-text-orange-400",children:"Media"}),e.jsxs("div",{children:[e.jsxs("div",{className:"ginger-dt-flex ginger-dt-items-center ginger-dt-justify-between ginger-dt-text-[11px] ginger-dt-mb-0.5",children:[e.jsx("span",{className:"ginger-dt-text-neutral-400",children:"Time"}),e.jsxs("span",{children:[x.formatMmSs(t.currentTime)," / ",x.formatMmSs(t.duration)]})]}),e.jsx("input",{type:"range",min:0,max:t.duration||0,step:.1,value:t.currentTime,onChange:g,className:"ginger-dt-w-full ginger-dt-h-1.5 ginger-dt-accent-orange-500 ginger-dt-cursor-pointer"}),e.jsx("div",{className:"ginger-dt-w-full ginger-dt-h-1 ginger-dt-bg-neutral-700 ginger-dt-rounded-full ginger-dt-mt-1 ginger-dt-overflow-hidden",children:e.jsx("div",{className:"ginger-dt-h-full ginger-dt-bg-orange-800 ginger-dt-rounded-full ginger-dt-transition-all",style:{width:`${(t.bufferedFraction*100).toFixed(1)}%`}})}),e.jsxs("div",{className:"ginger-dt-text-[10px] ginger-dt-text-neutral-500 ginger-dt-mt-0.5",children:["Buffered: ",(t.bufferedFraction*100).toFixed(1),"%",t.isBuffering&&e.jsx("span",{className:"ginger-dt-ml-2 ginger-dt-text-yellow-400",children:"● buffering"})]})]}),e.jsxs("div",{children:[e.jsxs("div",{className:"ginger-dt-flex ginger-dt-items-center ginger-dt-justify-between ginger-dt-text-[11px] ginger-dt-mb-0.5",children:[e.jsx("span",{className:"ginger-dt-text-neutral-400",children:"Volume"}),e.jsxs("span",{className:"ginger-dt-flex ginger-dt-items-center ginger-dt-gap-1",children:[Math.round(t.volume*100),"%",e.jsx("button",{type:"button",onClick:r.toggleMute,className:`ginger-dt-text-[10px] ginger-dt-px-1 ginger-dt-rounded ${t.muted?"ginger-dt-bg-red-900 ginger-dt-text-red-300":"ginger-dt-bg-neutral-700 ginger-dt-text-neutral-300"}`,children:t.muted?"unmute":"mute"})]})]}),e.jsx("input",{type:"range",min:0,max:1,step:.01,value:t.volume,onChange:d,className:"ginger-dt-w-full ginger-dt-h-1.5 ginger-dt-accent-orange-500 ginger-dt-cursor-pointer"})]}),e.jsxs("div",{className:"ginger-dt-flex ginger-dt-items-center ginger-dt-gap-2 ginger-dt-text-[11px]",children:[e.jsx("span",{className:"ginger-dt-text-neutral-400",children:"Rate"}),e.jsx("div",{className:"ginger-dt-flex ginger-dt-gap-0.5",children:[.5,.75,1,1.25,1.5,2].map(i=>e.jsxs("button",{type:"button",onClick:()=>r.setPlaybackRate(i),className:`ginger-dt-px-1.5 ginger-dt-py-0.5 ginger-dt-rounded ginger-dt-text-[10px] ginger-dt-transition-colors ${t.playbackRate===i?"ginger-dt-bg-orange-600 ginger-dt-text-white":"ginger-dt-bg-neutral-700 hover:ginger-dt-bg-neutral-600 ginger-dt-text-neutral-300"}`,children:[i,"x"]},i))})]}),t.errorMessage&&e.jsx("div",{className:"ginger-dt-text-[11px] ginger-dt-text-red-400 ginger-dt-bg-red-950 ginger-dt-rounded ginger-dt-px-2 ginger-dt-py-1",children:t.errorMessage})]})}function w({snap:n}){const t=n.state.tracks[n.state.currentIndex];return t?e.jsxs("div",{className:"ginger-dt-space-y-2",children:[e.jsx("h4",{className:"ginger-dt-text-[10px] ginger-dt-font-semibold ginger-dt-uppercase ginger-dt-tracking-wider ginger-dt-text-orange-400",children:"Current Track"}),e.jsxs("div",{className:"ginger-dt-flex ginger-dt-gap-2",children:[t.artworkUrl&&e.jsx("img",{src:t.artworkUrl,alt:"",className:"ginger-dt-w-10 ginger-dt-h-10 ginger-dt-rounded ginger-dt-object-cover ginger-dt-flex-shrink-0"}),e.jsxs("div",{className:"ginger-dt-min-w-0 ginger-dt-text-[11px]",children:[e.jsx("div",{className:"ginger-dt-font-medium ginger-dt-truncate",children:t.title}),t.artist&&e.jsx("div",{className:"ginger-dt-text-neutral-400 ginger-dt-truncate",children:t.artist}),t.album&&e.jsx("div",{className:"ginger-dt-text-neutral-500 ginger-dt-truncate ginger-dt-text-[10px]",children:t.album})]})]}),e.jsxs("div",{className:"ginger-dt-grid ginger-dt-grid-cols-2 ginger-dt-gap-x-3 ginger-dt-gap-y-0.5 ginger-dt-text-[10px] ginger-dt-text-neutral-400",children:[e.jsxs("span",{children:["src: ",S(t.fileUrl)]}),t.chapters&&e.jsxs("span",{children:["chapters: ",t.chapters.length]}),t.lyricsTimed&&e.jsxs("span",{children:["lyrics: timed (",t.lyricsTimed.length,")"]}),t.lyrics&&!t.lyricsTimed&&e.jsx("span",{children:"lyrics: plain"})]})]}):e.jsxs("div",{className:"ginger-dt-space-y-2",children:[e.jsx("h4",{className:"ginger-dt-text-[10px] ginger-dt-font-semibold ginger-dt-uppercase ginger-dt-tracking-wider ginger-dt-text-orange-400",children:"Current Track"}),e.jsx("div",{className:"ginger-dt-text-[11px] ginger-dt-text-neutral-500 ginger-dt-italic",children:"No track loaded"})]})}function k({snap:n}){const{state:t,actions:r}=n;return e.jsxs("div",{className:"ginger-dt-space-y-2",children:[e.jsxs("h4",{className:"ginger-dt-text-[10px] ginger-dt-font-semibold ginger-dt-uppercase ginger-dt-tracking-wider ginger-dt-text-orange-400",children:["Queue (",t.tracks.length,")"]}),e.jsxs("div",{className:"ginger-dt-max-h-32 ginger-dt-overflow-y-auto ginger-dt-space-y-px ginger-dt-scrollbar-thin",children:[t.tracks.length===0&&e.jsx("div",{className:"ginger-dt-text-[11px] ginger-dt-text-neutral-500 ginger-dt-italic",children:"Empty queue"}),t.tracks.map((g,d)=>e.jsxs("button",{type:"button",onClick:()=>r.playTrackAt(d),className:`ginger-dt-w-full ginger-dt-text-left ginger-dt-px-2 ginger-dt-py-1 ginger-dt-rounded ginger-dt-text-[11px] ginger-dt-flex ginger-dt-items-center ginger-dt-gap-2 ginger-dt-transition-colors ${d===t.currentIndex?"ginger-dt-bg-orange-900/50 ginger-dt-text-orange-200":"hover:ginger-dt-bg-neutral-700/50 ginger-dt-text-neutral-300"}`,children:[e.jsx("span",{className:"ginger-dt-w-5 ginger-dt-text-right ginger-dt-text-[10px] ginger-dt-text-neutral-500 ginger-dt-flex-shrink-0",children:d===t.currentIndex?"▸":d+1}),e.jsx("span",{className:"ginger-dt-truncate",children:g.title}),g.artist&&e.jsx("span",{className:"ginger-dt-text-neutral-500 ginger-dt-truncate ginger-dt-text-[10px] ginger-dt-ml-auto ginger-dt-flex-shrink-0",children:g.artist})]},g.id??`${g.fileUrl}-${d}`))]})]})}function l({label:n,value:t,children:r}){return e.jsxs("div",{className:"ginger-dt-flex ginger-dt-items-center",children:[e.jsxs("span",{className:"ginger-dt-text-neutral-400",children:[n,":"]}),e.jsx("span",{className:"ginger-dt-ml-1 ginger-dt-font-mono",children:t}),r]})}function S(n,t=40){return n.length<=t?n:`…${n.slice(-t)}`}function C(){j();const n=y(),[t,r]=s.useState(!1),[g,d]=s.useState(null),i=n.find(a=>a.id===g)??n[0]??null;s.useEffect(()=>{!g&&n.length>0&&d(n[0].id),g&&!n.find(a=>a.id===g)&&n.length>0&&d(n[0].id)},[n,g]);const o=typeof document<"u"?document.body:null;return o?h.createPortal(e.jsxs("div",{style:{fontFamily:'ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace',zIndex:2147483647,position:"fixed",bottom:0,right:0},children:[!t&&e.jsxs("button",{type:"button",onClick:()=>r(!0),style:{position:"fixed",bottom:"12px",right:"12px",zIndex:2147483647,background:"#ea580c",color:"#fff",border:"none",borderRadius:"8px",padding:"6px 12px",fontSize:"12px",fontWeight:600,fontFamily:"inherit",cursor:"pointer",boxShadow:"0 4px 12px rgba(0,0,0,0.4)",display:"flex",alignItems:"center",gap:"6px"},children:[e.jsx("span",{style:{fontSize:"14px"},children:"🍊"}),"Ginger",n.length>0&&e.jsx("span",{style:{background:"rgba(255,255,255,0.2)",borderRadius:"4px",padding:"1px 5px",fontSize:"10px"},children:n.length})]}),t&&e.jsxs("div",{className:"ginger-dt-fixed ginger-dt-bottom-3 ginger-dt-right-3 ginger-dt-w-[380px] ginger-dt-max-h-[80vh] ginger-dt-bg-neutral-900 ginger-dt-text-neutral-100 ginger-dt-rounded-xl ginger-dt-shadow-2xl ginger-dt-border ginger-dt-border-neutral-700/50 ginger-dt-flex ginger-dt-flex-col ginger-dt-overflow-hidden",style:{zIndex:2147483647},children:[e.jsxs("div",{className:"ginger-dt-flex ginger-dt-items-center ginger-dt-justify-between ginger-dt-px-3 ginger-dt-py-2 ginger-dt-bg-neutral-800 ginger-dt-border-b ginger-dt-border-neutral-700/50",children:[e.jsxs("div",{className:"ginger-dt-flex ginger-dt-items-center ginger-dt-gap-2",children:[e.jsx("span",{className:"ginger-dt-text-sm",children:"🍊"}),e.jsx("span",{className:"ginger-dt-text-xs ginger-dt-font-semibold ginger-dt-tracking-wide",children:"Ginger Devtools"})]}),e.jsx("button",{type:"button",onClick:()=>r(!1),className:"ginger-dt-text-neutral-400 hover:ginger-dt-text-white ginger-dt-text-lg ginger-dt-leading-none ginger-dt-transition-colors",children:"×"})]}),n.length>1&&e.jsx("div",{className:"ginger-dt-flex ginger-dt-gap-0 ginger-dt-bg-neutral-800 ginger-dt-px-1 ginger-dt-border-b ginger-dt-border-neutral-700/50 ginger-dt-overflow-x-auto",children:n.map(a=>e.jsx("button",{type:"button",onClick:()=>d(a.id),className:`ginger-dt-px-3 ginger-dt-py-1.5 ginger-dt-text-[11px] ginger-dt-whitespace-nowrap ginger-dt-border-b-2 ginger-dt-transition-colors ${(i==null?void 0:i.id)===a.id?"ginger-dt-border-orange-500 ginger-dt-text-orange-300":"ginger-dt-border-transparent ginger-dt-text-neutral-400 hover:ginger-dt-text-neutral-200"}`,children:a.label},a.id))}),e.jsx("div",{className:"ginger-dt-flex-1 ginger-dt-overflow-y-auto ginger-dt-px-3 ginger-dt-py-3 ginger-dt-space-y-4",children:i?e.jsxs(e.Fragment,{children:[e.jsx(v,{snap:i}),e.jsx(c,{}),e.jsx(N,{snap:i}),e.jsx(c,{}),e.jsx(w,{snap:i}),e.jsx(c,{}),e.jsx(k,{snap:i})]}):e.jsxs("div",{className:"ginger-dt-text-[11px] ginger-dt-text-neutral-500 ginger-dt-text-center ginger-dt-py-8",children:["No Ginger providers detected.",e.jsx("br",{}),e.jsxs("span",{className:"ginger-dt-text-[10px]",children:["Add ","<Ginger.Provider>"," to your app."]})]})}),i&&e.jsxs("div",{className:"ginger-dt-px-3 ginger-dt-py-1.5 ginger-dt-bg-neutral-800 ginger-dt-border-t ginger-dt-border-neutral-700/50 ginger-dt-text-[10px] ginger-dt-text-neutral-500 ginger-dt-flex ginger-dt-justify-between",children:[e.jsxs("span",{children:["ID: ",i.id.slice(0,8),"…"]}),e.jsxs("span",{children:["Updated ",M(i.updatedAt)]})]})]})]}),o):null}function c(){return e.jsx("div",{className:"ginger-dt-border-t ginger-dt-border-neutral-700/30"})}function M(n){const t=Date.now()-n;return t<1e3?"just now":t<6e4?`${Math.floor(t/1e3)}s ago`:`${Math.floor(t/6e4)}m ago`}exports.GingerDevtools=C;
|
|
2
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../src/devtools/registry.ts","../../src/devtools/GingerDevtools.tsx"],"sourcesContent":["import type { GingerState, PlaybackMode, RepeatMode } from \"../types\";\n\nexport type ProviderActions = {\n play: () => void;\n pause: () => void;\n togglePlayPause: () => void;\n next: () => void;\n prev: () => void;\n seek: (time: number) => void;\n setVolume: (v: number) => void;\n setMuted: (m: boolean) => void;\n toggleMute: () => void;\n setPlaybackRate: (rate: number) => void;\n setRepeatMode: (mode: RepeatMode) => void;\n cycleRepeat: () => void;\n toggleShuffle: () => void;\n playTrackAt: (index: number) => void;\n setPlaybackMode: (mode: PlaybackMode) => void;\n};\n\nexport type ProviderSnapshot = {\n id: string;\n label: string;\n state: GingerState;\n actions: ProviderActions;\n audioSrc: string | null;\n registeredAt: number;\n updatedAt: number;\n};\n\ntype RegistrationPayload = {\n label?: string;\n state: GingerState;\n actions: ProviderActions;\n audioSrc: string | null;\n};\n\ntype UpdatePayload = {\n state: GingerState;\n audioSrc: string | null;\n};\n\ntype Listener = (snapshots: Map<string, ProviderSnapshot>) => void;\n\nexport type DevtoolsRegistry = {\n register: (id: string, payload: RegistrationPayload) => void;\n unregister: (id: string) => void;\n update: (id: string, payload: UpdatePayload) => void;\n subscribe: (listener: Listener) => () => void;\n getAll: () => Map<string, ProviderSnapshot>;\n};\n\nconst WINDOW_KEY = \"__GINGER_DEVTOOLS__\";\n\nlet counter = 0;\n\nfunction buildRegistry(): DevtoolsRegistry {\n const providers = new Map<string, ProviderSnapshot>();\n const listeners = new Set<Listener>();\n\n const notify = () => {\n for (const fn of listeners) {\n fn(providers);\n }\n };\n\n return {\n register(id, payload) {\n counter += 1;\n const snapshot: ProviderSnapshot = {\n id,\n label: payload.label || `Player ${counter}`,\n state: payload.state,\n actions: payload.actions,\n audioSrc: payload.audioSrc,\n registeredAt: Date.now(),\n updatedAt: Date.now(),\n };\n providers.set(id, snapshot);\n notify();\n },\n\n unregister(id) {\n if (providers.delete(id)) {\n notify();\n }\n },\n\n update(id, payload) {\n const existing = providers.get(id);\n if (!existing) return;\n existing.state = payload.state;\n existing.audioSrc = payload.audioSrc;\n existing.updatedAt = Date.now();\n notify();\n },\n\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n\n getAll() {\n return providers;\n },\n };\n}\n\nexport function getRegistry(): DevtoolsRegistry | null {\n if (typeof window === \"undefined\") return null;\n return (\n ((window as unknown as Record<string, unknown>)[WINDOW_KEY] as DevtoolsRegistry | null) ?? null\n );\n}\n\nexport function ensureRegistry(): DevtoolsRegistry {\n if (typeof window === \"undefined\") {\n throw new Error(\"GingerDevtools requires a browser environment.\");\n }\n const win = window as unknown as Record<string, unknown>;\n let reg = win[WINDOW_KEY] as DevtoolsRegistry | undefined;\n if (!reg) {\n reg = buildRegistry();\n win[WINDOW_KEY] = reg;\n }\n return reg;\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { formatMmSs } from \"../internal/formatTime\";\nimport type { ProviderSnapshot } from \"./registry\";\nimport { ensureRegistry } from \"./registry\";\n\nconst TAILWIND_CDN = \"https://cdn.tailwindcss.com\";\n\nfunction useTailwindCdn() {\n const scriptRef = useRef<HTMLScriptElement | null>(null);\n\n useEffect(() => {\n if (document.querySelector(`script[src=\"${TAILWIND_CDN}\"]`)) return;\n const script = document.createElement(\"script\");\n script.src = TAILWIND_CDN;\n script.async = true;\n document.head.appendChild(script);\n scriptRef.current = script;\n return () => {\n if (scriptRef.current?.parentNode) {\n scriptRef.current.parentNode.removeChild(scriptRef.current);\n }\n };\n }, []);\n}\n\nfunction useRegistrySnapshots() {\n const [snapshots, setSnapshots] = useState<ProviderSnapshot[]>([]);\n\n useEffect(() => {\n const registry = ensureRegistry();\n const sync = (map: Map<string, ProviderSnapshot>) => {\n setSnapshots(Array.from(map.values()));\n };\n sync(registry.getAll());\n return registry.subscribe(sync);\n }, []);\n\n return snapshots;\n}\n\n// ─── Sub-components for each section ─────────────────────────────────────────\n\nfunction PlaybackSection({ snap }: { snap: ProviderSnapshot }) {\n const { state, actions } = snap;\n const track = state.tracks[state.currentIndex];\n\n return (\n <div className=\"ginger-dt-space-y-2\">\n <h4 className=\"ginger-dt-text-[10px] ginger-dt-font-semibold ginger-dt-uppercase ginger-dt-tracking-wider ginger-dt-text-orange-400\">\n Playback\n </h4>\n <div className=\"ginger-dt-flex ginger-dt-items-center ginger-dt-gap-1.5\">\n <button\n type=\"button\"\n onClick={actions.prev}\n className=\"ginger-dt-rounded ginger-dt-bg-neutral-700 ginger-dt-px-2 ginger-dt-py-0.5 ginger-dt-text-[11px] hover:ginger-dt-bg-neutral-600 ginger-dt-transition-colors\"\n title=\"Previous\"\n >\n ⏮\n </button>\n <button\n type=\"button\"\n onClick={actions.togglePlayPause}\n className=\"ginger-dt-rounded ginger-dt-bg-orange-600 ginger-dt-px-3 ginger-dt-py-0.5 ginger-dt-text-[11px] ginger-dt-font-medium hover:ginger-dt-bg-orange-500 ginger-dt-transition-colors\"\n >\n {state.isPaused ? \"▶ Play\" : \"⏸ Pause\"}\n </button>\n <button\n type=\"button\"\n onClick={actions.next}\n className=\"ginger-dt-rounded ginger-dt-bg-neutral-700 ginger-dt-px-2 ginger-dt-py-0.5 ginger-dt-text-[11px] hover:ginger-dt-bg-neutral-600 ginger-dt-transition-colors\"\n title=\"Next\"\n >\n ⏭\n </button>\n </div>\n <div className=\"ginger-dt-grid ginger-dt-grid-cols-2 ginger-dt-gap-x-3 ginger-dt-gap-y-1 ginger-dt-text-[11px]\">\n <Row\n label=\"Track\"\n value={track ? `${state.currentIndex + 1}/${state.tracks.length}` : \"—\"}\n />\n <Row label=\"Mode\" value={state.playbackMode}>\n <button\n type=\"button\"\n onClick={() =>\n actions.setPlaybackMode(state.playbackMode === \"playlist\" ? \"single\" : \"playlist\")\n }\n className=\"ginger-dt-ml-1 ginger-dt-text-orange-400 hover:ginger-dt-text-orange-300 ginger-dt-text-[10px]\"\n >\n ↻\n </button>\n </Row>\n <Row label=\"Repeat\" value={state.repeatMode}>\n <button\n type=\"button\"\n onClick={actions.cycleRepeat}\n className=\"ginger-dt-ml-1 ginger-dt-text-orange-400 hover:ginger-dt-text-orange-300 ginger-dt-text-[10px]\"\n >\n ↻\n </button>\n </Row>\n <Row label=\"Shuffle\" value={state.isShuffled ? \"on\" : \"off\"}>\n <button\n type=\"button\"\n onClick={actions.toggleShuffle}\n className=\"ginger-dt-ml-1 ginger-dt-text-orange-400 hover:ginger-dt-text-orange-300 ginger-dt-text-[10px]\"\n >\n ↻\n </button>\n </Row>\n </div>\n </div>\n );\n}\n\nfunction MediaSection({ snap }: { snap: ProviderSnapshot }) {\n const { state, actions } = snap;\n\n const handleSeek = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n actions.seek(Number(e.target.value));\n },\n [actions],\n );\n\n const handleVolume = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n actions.setVolume(Number(e.target.value));\n },\n [actions],\n );\n\n return (\n <div className=\"ginger-dt-space-y-2\">\n <h4 className=\"ginger-dt-text-[10px] ginger-dt-font-semibold ginger-dt-uppercase ginger-dt-tracking-wider ginger-dt-text-orange-400\">\n Media\n </h4>\n {/* Seek */}\n <div>\n <div className=\"ginger-dt-flex ginger-dt-items-center ginger-dt-justify-between ginger-dt-text-[11px] ginger-dt-mb-0.5\">\n <span className=\"ginger-dt-text-neutral-400\">Time</span>\n <span>\n {formatMmSs(state.currentTime)} / {formatMmSs(state.duration)}\n </span>\n </div>\n <input\n type=\"range\"\n min={0}\n max={state.duration || 0}\n step={0.1}\n value={state.currentTime}\n onChange={handleSeek}\n className=\"ginger-dt-w-full ginger-dt-h-1.5 ginger-dt-accent-orange-500 ginger-dt-cursor-pointer\"\n />\n {/* Buffer bar */}\n <div className=\"ginger-dt-w-full ginger-dt-h-1 ginger-dt-bg-neutral-700 ginger-dt-rounded-full ginger-dt-mt-1 ginger-dt-overflow-hidden\">\n <div\n className=\"ginger-dt-h-full ginger-dt-bg-orange-800 ginger-dt-rounded-full ginger-dt-transition-all\"\n style={{ width: `${(state.bufferedFraction * 100).toFixed(1)}%` }}\n />\n </div>\n <div className=\"ginger-dt-text-[10px] ginger-dt-text-neutral-500 ginger-dt-mt-0.5\">\n Buffered: {(state.bufferedFraction * 100).toFixed(1)}%\n {state.isBuffering && (\n <span className=\"ginger-dt-ml-2 ginger-dt-text-yellow-400\">● buffering</span>\n )}\n </div>\n </div>\n\n {/* Volume */}\n <div>\n <div className=\"ginger-dt-flex ginger-dt-items-center ginger-dt-justify-between ginger-dt-text-[11px] ginger-dt-mb-0.5\">\n <span className=\"ginger-dt-text-neutral-400\">Volume</span>\n <span className=\"ginger-dt-flex ginger-dt-items-center ginger-dt-gap-1\">\n {Math.round(state.volume * 100)}%\n <button\n type=\"button\"\n onClick={actions.toggleMute}\n className={`ginger-dt-text-[10px] ginger-dt-px-1 ginger-dt-rounded ${state.muted ? \"ginger-dt-bg-red-900 ginger-dt-text-red-300\" : \"ginger-dt-bg-neutral-700 ginger-dt-text-neutral-300\"}`}\n >\n {state.muted ? \"unmute\" : \"mute\"}\n </button>\n </span>\n </div>\n <input\n type=\"range\"\n min={0}\n max={1}\n step={0.01}\n value={state.volume}\n onChange={handleVolume}\n className=\"ginger-dt-w-full ginger-dt-h-1.5 ginger-dt-accent-orange-500 ginger-dt-cursor-pointer\"\n />\n </div>\n\n {/* Playback rate */}\n <div className=\"ginger-dt-flex ginger-dt-items-center ginger-dt-gap-2 ginger-dt-text-[11px]\">\n <span className=\"ginger-dt-text-neutral-400\">Rate</span>\n <div className=\"ginger-dt-flex ginger-dt-gap-0.5\">\n {[0.5, 0.75, 1, 1.25, 1.5, 2].map((r) => (\n <button\n key={r}\n type=\"button\"\n onClick={() => actions.setPlaybackRate(r)}\n className={`ginger-dt-px-1.5 ginger-dt-py-0.5 ginger-dt-rounded ginger-dt-text-[10px] ginger-dt-transition-colors ${\n state.playbackRate === r\n ? \"ginger-dt-bg-orange-600 ginger-dt-text-white\"\n : \"ginger-dt-bg-neutral-700 hover:ginger-dt-bg-neutral-600 ginger-dt-text-neutral-300\"\n }`}\n >\n {r}x\n </button>\n ))}\n </div>\n </div>\n\n {/* Error */}\n {state.errorMessage && (\n <div className=\"ginger-dt-text-[11px] ginger-dt-text-red-400 ginger-dt-bg-red-950 ginger-dt-rounded ginger-dt-px-2 ginger-dt-py-1\">\n {state.errorMessage}\n </div>\n )}\n </div>\n );\n}\n\nfunction TrackSection({ snap }: { snap: ProviderSnapshot }) {\n const track = snap.state.tracks[snap.state.currentIndex];\n if (!track) {\n return (\n <div className=\"ginger-dt-space-y-2\">\n <h4 className=\"ginger-dt-text-[10px] ginger-dt-font-semibold ginger-dt-uppercase ginger-dt-tracking-wider ginger-dt-text-orange-400\">\n Current Track\n </h4>\n <div className=\"ginger-dt-text-[11px] ginger-dt-text-neutral-500 ginger-dt-italic\">\n No track loaded\n </div>\n </div>\n );\n }\n return (\n <div className=\"ginger-dt-space-y-2\">\n <h4 className=\"ginger-dt-text-[10px] ginger-dt-font-semibold ginger-dt-uppercase ginger-dt-tracking-wider ginger-dt-text-orange-400\">\n Current Track\n </h4>\n <div className=\"ginger-dt-flex ginger-dt-gap-2\">\n {track.artworkUrl && (\n <img\n src={track.artworkUrl}\n alt=\"\"\n className=\"ginger-dt-w-10 ginger-dt-h-10 ginger-dt-rounded ginger-dt-object-cover ginger-dt-flex-shrink-0\"\n />\n )}\n <div className=\"ginger-dt-min-w-0 ginger-dt-text-[11px]\">\n <div className=\"ginger-dt-font-medium ginger-dt-truncate\">{track.title}</div>\n {track.artist && (\n <div className=\"ginger-dt-text-neutral-400 ginger-dt-truncate\">{track.artist}</div>\n )}\n {track.album && (\n <div className=\"ginger-dt-text-neutral-500 ginger-dt-truncate ginger-dt-text-[10px]\">\n {track.album}\n </div>\n )}\n </div>\n </div>\n <div className=\"ginger-dt-grid ginger-dt-grid-cols-2 ginger-dt-gap-x-3 ginger-dt-gap-y-0.5 ginger-dt-text-[10px] ginger-dt-text-neutral-400\">\n <span>src: {truncateUrl(track.fileUrl)}</span>\n {track.chapters && <span>chapters: {track.chapters.length}</span>}\n {track.lyricsTimed && <span>lyrics: timed ({track.lyricsTimed.length})</span>}\n {track.lyrics && !track.lyricsTimed && <span>lyrics: plain</span>}\n </div>\n </div>\n );\n}\n\nfunction QueueSection({ snap }: { snap: ProviderSnapshot }) {\n const { state, actions } = snap;\n\n return (\n <div className=\"ginger-dt-space-y-2\">\n <h4 className=\"ginger-dt-text-[10px] ginger-dt-font-semibold ginger-dt-uppercase ginger-dt-tracking-wider ginger-dt-text-orange-400\">\n Queue ({state.tracks.length})\n </h4>\n <div className=\"ginger-dt-max-h-32 ginger-dt-overflow-y-auto ginger-dt-space-y-px ginger-dt-scrollbar-thin\">\n {state.tracks.length === 0 && (\n <div className=\"ginger-dt-text-[11px] ginger-dt-text-neutral-500 ginger-dt-italic\">\n Empty queue\n </div>\n )}\n {state.tracks.map((track, i) => (\n <button\n key={track.id ?? `${track.fileUrl}-${i}`}\n type=\"button\"\n onClick={() => actions.playTrackAt(i)}\n className={`ginger-dt-w-full ginger-dt-text-left ginger-dt-px-2 ginger-dt-py-1 ginger-dt-rounded ginger-dt-text-[11px] ginger-dt-flex ginger-dt-items-center ginger-dt-gap-2 ginger-dt-transition-colors ${\n i === state.currentIndex\n ? \"ginger-dt-bg-orange-900/50 ginger-dt-text-orange-200\"\n : \"hover:ginger-dt-bg-neutral-700/50 ginger-dt-text-neutral-300\"\n }`}\n >\n <span className=\"ginger-dt-w-5 ginger-dt-text-right ginger-dt-text-[10px] ginger-dt-text-neutral-500 ginger-dt-flex-shrink-0\">\n {i === state.currentIndex ? \"▸\" : i + 1}\n </span>\n <span className=\"ginger-dt-truncate\">{track.title}</span>\n {track.artist && (\n <span className=\"ginger-dt-text-neutral-500 ginger-dt-truncate ginger-dt-text-[10px] ginger-dt-ml-auto ginger-dt-flex-shrink-0\">\n {track.artist}\n </span>\n )}\n </button>\n ))}\n </div>\n </div>\n );\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction Row({\n label,\n value,\n children,\n}: { label: string; value: string; children?: React.ReactNode }) {\n return (\n <div className=\"ginger-dt-flex ginger-dt-items-center\">\n <span className=\"ginger-dt-text-neutral-400\">{label}:</span>\n <span className=\"ginger-dt-ml-1 ginger-dt-font-mono\">{value}</span>\n {children}\n </div>\n );\n}\n\nfunction truncateUrl(url: string, max = 40): string {\n if (url.length <= max) return url;\n return `…${url.slice(-max)}`;\n}\n\n// ─── Main Overlay ─────────────────────────────────────────────────────────────\n\nexport function GingerDevtools() {\n useTailwindCdn();\n const snapshots = useRegistrySnapshots();\n\n const [open, setOpen] = useState(false);\n const [activeTab, setActiveTab] = useState<string | null>(null);\n\n const activeSnap = snapshots.find((s) => s.id === activeTab) ?? snapshots[0] ?? null;\n\n useEffect(() => {\n if (!activeTab && snapshots.length > 0) {\n setActiveTab(snapshots[0].id);\n }\n if (activeTab && !snapshots.find((s) => s.id === activeTab) && snapshots.length > 0) {\n setActiveTab(snapshots[0].id);\n }\n }, [snapshots, activeTab]);\n\n const portalRoot = typeof document !== \"undefined\" ? document.body : null;\n if (!portalRoot) return null;\n\n return createPortal(\n <div\n style={{\n fontFamily: 'ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, monospace',\n zIndex: 2147483647,\n position: \"fixed\",\n bottom: 0,\n right: 0,\n }}\n >\n {/* Toggle button */}\n {!open && (\n <button\n type=\"button\"\n onClick={() => setOpen(true)}\n style={{\n position: \"fixed\",\n bottom: \"12px\",\n right: \"12px\",\n zIndex: 2147483647,\n background: \"#ea580c\",\n color: \"#fff\",\n border: \"none\",\n borderRadius: \"8px\",\n padding: \"6px 12px\",\n fontSize: \"12px\",\n fontWeight: 600,\n fontFamily: \"inherit\",\n cursor: \"pointer\",\n boxShadow: \"0 4px 12px rgba(0,0,0,0.4)\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"6px\",\n }}\n >\n <span style={{ fontSize: \"14px\" }}>🍊</span>\n Ginger\n {snapshots.length > 0 && (\n <span\n style={{\n background: \"rgba(255,255,255,0.2)\",\n borderRadius: \"4px\",\n padding: \"1px 5px\",\n fontSize: \"10px\",\n }}\n >\n {snapshots.length}\n </span>\n )}\n </button>\n )}\n\n {/* Panel */}\n {open && (\n <div\n className=\"ginger-dt-fixed ginger-dt-bottom-3 ginger-dt-right-3 ginger-dt-w-[380px] ginger-dt-max-h-[80vh] ginger-dt-bg-neutral-900 ginger-dt-text-neutral-100 ginger-dt-rounded-xl ginger-dt-shadow-2xl ginger-dt-border ginger-dt-border-neutral-700/50 ginger-dt-flex ginger-dt-flex-col ginger-dt-overflow-hidden\"\n style={{ zIndex: 2147483647 }}\n >\n {/* Header */}\n <div className=\"ginger-dt-flex ginger-dt-items-center ginger-dt-justify-between ginger-dt-px-3 ginger-dt-py-2 ginger-dt-bg-neutral-800 ginger-dt-border-b ginger-dt-border-neutral-700/50\">\n <div className=\"ginger-dt-flex ginger-dt-items-center ginger-dt-gap-2\">\n <span className=\"ginger-dt-text-sm\">🍊</span>\n <span className=\"ginger-dt-text-xs ginger-dt-font-semibold ginger-dt-tracking-wide\">\n Ginger Devtools\n </span>\n </div>\n <button\n type=\"button\"\n onClick={() => setOpen(false)}\n className=\"ginger-dt-text-neutral-400 hover:ginger-dt-text-white ginger-dt-text-lg ginger-dt-leading-none ginger-dt-transition-colors\"\n >\n ×\n </button>\n </div>\n\n {/* Tabs (when multiple providers) */}\n {snapshots.length > 1 && (\n <div className=\"ginger-dt-flex ginger-dt-gap-0 ginger-dt-bg-neutral-800 ginger-dt-px-1 ginger-dt-border-b ginger-dt-border-neutral-700/50 ginger-dt-overflow-x-auto\">\n {snapshots.map((s) => (\n <button\n key={s.id}\n type=\"button\"\n onClick={() => setActiveTab(s.id)}\n className={`ginger-dt-px-3 ginger-dt-py-1.5 ginger-dt-text-[11px] ginger-dt-whitespace-nowrap ginger-dt-border-b-2 ginger-dt-transition-colors ${\n activeSnap?.id === s.id\n ? \"ginger-dt-border-orange-500 ginger-dt-text-orange-300\"\n : \"ginger-dt-border-transparent ginger-dt-text-neutral-400 hover:ginger-dt-text-neutral-200\"\n }`}\n >\n {s.label}\n </button>\n ))}\n </div>\n )}\n\n {/* Content */}\n <div className=\"ginger-dt-flex-1 ginger-dt-overflow-y-auto ginger-dt-px-3 ginger-dt-py-3 ginger-dt-space-y-4\">\n {!activeSnap ? (\n <div className=\"ginger-dt-text-[11px] ginger-dt-text-neutral-500 ginger-dt-text-center ginger-dt-py-8\">\n No Ginger providers detected.\n <br />\n <span className=\"ginger-dt-text-[10px]\">\n Add {\"<Ginger.Provider>\"} to your app.\n </span>\n </div>\n ) : (\n <>\n <PlaybackSection snap={activeSnap} />\n <Divider />\n <MediaSection snap={activeSnap} />\n <Divider />\n <TrackSection snap={activeSnap} />\n <Divider />\n <QueueSection snap={activeSnap} />\n </>\n )}\n </div>\n\n {/* Footer */}\n {activeSnap && (\n <div className=\"ginger-dt-px-3 ginger-dt-py-1.5 ginger-dt-bg-neutral-800 ginger-dt-border-t ginger-dt-border-neutral-700/50 ginger-dt-text-[10px] ginger-dt-text-neutral-500 ginger-dt-flex ginger-dt-justify-between\">\n <span>ID: {activeSnap.id.slice(0, 8)}…</span>\n <span>Updated {msAgo(activeSnap.updatedAt)}</span>\n </div>\n )}\n </div>\n )}\n </div>,\n portalRoot,\n );\n}\n\nfunction Divider() {\n return <div className=\"ginger-dt-border-t ginger-dt-border-neutral-700/30\" />;\n}\n\nfunction msAgo(ts: number): string {\n const diff = Date.now() - ts;\n if (diff < 1000) return \"just now\";\n if (diff < 60_000) return `${Math.floor(diff / 1000)}s ago`;\n return `${Math.floor(diff / 60_000)}m ago`;\n}\n"],"names":["WINDOW_KEY","counter","buildRegistry","providers","listeners","notify","fn","id","payload","snapshot","existing","listener","ensureRegistry","win","reg","TAILWIND_CDN","useTailwindCdn","scriptRef","useRef","useEffect","script","_a","useRegistrySnapshots","snapshots","setSnapshots","useState","registry","sync","map","PlaybackSection","snap","state","actions","track","jsxs","jsx","Row","MediaSection","handleSeek","useCallback","e","handleVolume","formatMmSs","r","TrackSection","truncateUrl","QueueSection","i","label","value","children","url","max","GingerDevtools","open","setOpen","activeTab","setActiveTab","activeSnap","s","portalRoot","createPortal","Fragment","Divider","msAgo","ts","diff"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/devtools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
|