@lucaismyname/ginger 0.0.1

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 (56) hide show
  1. package/LICENSE +21 -0
  2. package/dist/audio/GingerPlayer.d.ts +9 -0
  3. package/dist/audio/GingerPlayer.d.ts.map +1 -0
  4. package/dist/components/controls/Controls.d.ts +38 -0
  5. package/dist/components/controls/Controls.d.ts.map +1 -0
  6. package/dist/components/current/Artwork.d.ts +10 -0
  7. package/dist/components/current/Artwork.d.ts.map +1 -0
  8. package/dist/components/current/FileUrl.d.ts +10 -0
  9. package/dist/components/current/FileUrl.d.ts.map +1 -0
  10. package/dist/components/current/Lyrics.d.ts +12 -0
  11. package/dist/components/current/Lyrics.d.ts.map +1 -0
  12. package/dist/components/current/Playback.d.ts +17 -0
  13. package/dist/components/current/Playback.d.ts.map +1 -0
  14. package/dist/components/current/QueueMeta.d.ts +31 -0
  15. package/dist/components/current/QueueMeta.d.ts.map +1 -0
  16. package/dist/components/current/Time.d.ts +38 -0
  17. package/dist/components/current/Time.d.ts.map +1 -0
  18. package/dist/components/current/Year.d.ts +9 -0
  19. package/dist/components/current/Year.d.ts.map +1 -0
  20. package/dist/components/current/createTextDisplay.d.ts +8 -0
  21. package/dist/components/current/createTextDisplay.d.ts.map +1 -0
  22. package/dist/components/current/index.d.ts +9 -0
  23. package/dist/components/current/index.d.ts.map +1 -0
  24. package/dist/components/current/texts.d.ts +10 -0
  25. package/dist/components/current/texts.d.ts.map +1 -0
  26. package/dist/components/playlist/GingerPlaylist.d.ts +13 -0
  27. package/dist/components/playlist/GingerPlaylist.d.ts.map +1 -0
  28. package/dist/components/queue/QueueDisplay.d.ts +14 -0
  29. package/dist/components/queue/QueueDisplay.d.ts.map +1 -0
  30. package/dist/context/GingerContext.d.ts +27 -0
  31. package/dist/context/GingerContext.d.ts.map +1 -0
  32. package/dist/context/GingerProvider.d.ts +3 -0
  33. package/dist/context/GingerProvider.d.ts.map +1 -0
  34. package/dist/core/playbackReducer.d.ts +11 -0
  35. package/dist/core/playbackReducer.d.ts.map +1 -0
  36. package/dist/core/queue.d.ts +5 -0
  37. package/dist/core/queue.d.ts.map +1 -0
  38. package/dist/core/transitions.d.ts +20 -0
  39. package/dist/core/transitions.d.ts.map +1 -0
  40. package/dist/ginger.d.ts +52 -0
  41. package/dist/ginger.d.ts.map +1 -0
  42. package/dist/hooks/useGinger.d.ts +27 -0
  43. package/dist/hooks/useGinger.d.ts.map +1 -0
  44. package/dist/index.cjs +2 -0
  45. package/dist/index.cjs.map +1 -0
  46. package/dist/index.d.ts +13 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/dist/index.js +897 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/internal/formatTime.d.ts +2 -0
  51. package/dist/internal/formatTime.d.ts.map +1 -0
  52. package/dist/internal/selectors.d.ts +9 -0
  53. package/dist/internal/selectors.d.ts.map +1 -0
  54. package/dist/types.d.ts +141 -0
  55. package/dist/types.d.ts.map +1 -0
  56. package/package.json +45 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/context/GingerContext.tsx","../src/audio/GingerPlayer.tsx","../src/core/queue.ts","../src/core/transitions.ts","../src/internal/selectors.ts","../src/components/current/createTextDisplay.tsx","../src/components/current/texts.ts","../src/components/current/Year.tsx","../src/components/current/Lyrics.tsx","../src/components/current/FileUrl.tsx","../src/components/current/Artwork.tsx","../src/components/current/QueueMeta.tsx","../src/internal/formatTime.ts","../src/components/current/Time.tsx","../src/components/current/Playback.tsx","../src/components/controls/Controls.tsx","../src/components/playlist/GingerPlaylist.tsx","../src/components/queue/QueueDisplay.tsx","../src/core/playbackReducer.ts","../src/context/GingerProvider.tsx","../src/ginger.ts","../src/hooks/useGinger.ts"],"sourcesContent":["import { createContext, useContext, type Dispatch, type MutableRefObject } from \"react\";\nimport type { GingerAction, GingerState, PlaylistMeta, RepeatMode, Track } from \"../types\";\n\nexport type GingerContextValue = {\n state: GingerState;\n dispatch: Dispatch<GingerAction>;\n audioRef: MutableRefObject<HTMLAudioElement | null>;\n notifyEnded: () => void;\n play: () => void;\n pause: () => void;\n togglePlayPause: () => void;\n seek: (timeSeconds: number) => void;\n setVolume: (volume: number) => void;\n setMuted: (muted: boolean) => void;\n next: () => void;\n prev: () => void;\n setRepeatMode: (mode: RepeatMode) => void;\n cycleRepeat: () => void;\n toggleShuffle: () => void;\n setQueue: (tracks: Track[], currentIndex?: number) => void;\n playTrackAt: (index: number) => void;\n selectTrackAt: (index: number) => void;\n setPlaylistMeta: (meta: PlaylistMeta | null) => void;\n};\n\nconst GingerContext = createContext<GingerContextValue | null>(null);\n\nexport function useGingerContext(): GingerContextValue {\n const ctx = useContext(GingerContext);\n if (!ctx) throw new Error(\"Ginger components must be used within <Ginger.Provider>\");\n return ctx;\n}\n\nexport { GingerContext };\n","import { useEffect, type AudioHTMLAttributes, type CSSProperties } from \"react\";\nimport { useGingerContext } from \"../context/GingerContext\";\n\nexport type GingerPlayerProps = {\n className?: string;\n style?: CSSProperties;\n preload?: AudioHTMLAttributes<HTMLAudioElement>[\"preload\"];\n crossOrigin?: AudioHTMLAttributes<HTMLAudioElement>[\"crossOrigin\"];\n};\n\nfunction readBufferedFraction(el: HTMLAudioElement): number {\n const { buffered, duration } = el;\n if (!(duration > 0) || buffered.length === 0) return 0;\n return Math.min(1, buffered.end(buffered.length - 1) / duration);\n}\n\nexport function GingerPlayer({ className, style, preload = \"metadata\", crossOrigin }: GingerPlayerProps) {\n const { audioRef, dispatch, state, notifyEnded } = useGingerContext();\n const url = state.tracks[state.currentIndex]?.fileUrl ?? \"\";\n\n useEffect(() => {\n const el = audioRef.current;\n if (!el) return;\n if (!url) {\n el.removeAttribute(\"src\");\n return;\n }\n if (el.getAttribute(\"src\") !== url) {\n el.src = url;\n el.load();\n }\n }, [audioRef, state.currentIndex, state.tracks, url]);\n\n return (\n <audio\n ref={audioRef}\n className={className}\n style={style}\n preload={preload}\n crossOrigin={crossOrigin}\n controls={false}\n onTimeUpdate={(e) => {\n const el = e.currentTarget;\n dispatch({\n type: \"MEDIA_TIME_UPDATE\",\n payload: {\n currentTime: el.currentTime,\n duration: el.duration,\n bufferedFraction: readBufferedFraction(el),\n },\n });\n }}\n onLoadedMetadata={(e) => {\n const el = e.currentTarget;\n dispatch({\n type: \"MEDIA_LOADED_METADATA\",\n payload: {\n duration: el.duration,\n bufferedFraction: readBufferedFraction(el),\n },\n });\n }}\n onEnded={() => notifyEnded()}\n onPlay={() => dispatch({ type: \"MEDIA_PLAY\" })}\n onPause={() => dispatch({ type: \"MEDIA_PAUSE\" })}\n onWaiting={() => dispatch({ type: \"MEDIA_WAITING\" })}\n onCanPlay={() => dispatch({ type: \"MEDIA_CANPLAY\" })}\n onError={() => {\n const el = audioRef.current;\n const code = el?.error?.code;\n const message =\n code === 1\n ? \"MEDIA_ERR_ABORTED\"\n : code === 2\n ? \"MEDIA_ERR_NETWORK\"\n : code === 3\n ? \"MEDIA_ERR_DECODE\"\n : code === 4\n ? \"MEDIA_ERR_SRC_NOT_SUPPORTED\"\n : \"MEDIA_ERR_UNKNOWN\";\n dispatch({ type: \"MEDIA_ERROR\", payload: { message } });\n }}\n />\n );\n}\n","import type { Track } from \"../types\";\n\nexport function clampIndex(index: number, length: number): number {\n if (length <= 0) return 0;\n return Math.max(0, Math.min(length - 1, index));\n}\n\nexport function shuffleWithAnchor(tracks: Track[], anchorIndex: number): Track[] {\n if (tracks.length <= 1) return [...tracks];\n const anchor = tracks[anchorIndex];\n if (!anchor) return [...tracks];\n const rest = tracks.filter((_, i) => i !== anchorIndex);\n for (let i = rest.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [rest[i], rest[j]] = [rest[j]!, rest[i]!];\n }\n return [anchor, ...rest];\n}\n\nexport function findIndexByFileUrl(tracks: Track[], fileUrl: string): number {\n const i = tracks.findIndex((t) => t.fileUrl === fileUrl);\n return i === -1 ? 0 : i;\n}\n","import type { GingerState, RepeatMode, Track } from \"../types\";\nimport { clampIndex } from \"./queue\";\n\nexport type EndedTransition =\n | { kind: \"replay_same\" }\n | { kind: \"advance\"; nextIndex: number }\n | { kind: \"wrap\"; nextIndex: number }\n | { kind: \"stop\"; nextIndex: number };\n\nexport function computeEndedTransition(state: GingerState): EndedTransition {\n const { tracks, currentIndex, repeatMode } = state;\n const len = tracks.length;\n if (len === 0) return { kind: \"stop\", nextIndex: 0 };\n if (repeatMode === \"one\") return { kind: \"replay_same\" };\n if (currentIndex < len - 1) return { kind: \"advance\", nextIndex: currentIndex + 1 };\n if (repeatMode === \"all\") return { kind: \"wrap\", nextIndex: 0 };\n return { kind: \"stop\", nextIndex: clampIndex(currentIndex, len) };\n}\n\nexport function computeNextIndex(state: GingerState): number {\n const { tracks, currentIndex, repeatMode } = state;\n const len = tracks.length;\n if (len === 0) return 0;\n if (currentIndex < len - 1) return currentIndex + 1;\n if (repeatMode === \"all\") return 0;\n return clampIndex(currentIndex, len);\n}\n\nexport function computePrevIndex(state: GingerState): number {\n const { tracks, currentIndex, repeatMode } = state;\n const len = tracks.length;\n if (len === 0) return 0;\n if (currentIndex > 0) return currentIndex - 1;\n if (repeatMode === \"all\") return len - 1;\n return 0;\n}\n\nexport function cycleRepeatMode(mode: RepeatMode): RepeatMode {\n if (mode === \"off\") return \"all\";\n if (mode === \"all\") return \"one\";\n return \"off\";\n}\n\nexport function resolveArtworkUrl(track: Track | null, playlistArtwork?: string | null): string | undefined {\n return track?.artworkUrl ?? playlistArtwork ?? undefined;\n}\n\nexport function resolveAlbumLine(track: Track | null, playlistSubtitle?: string | null): string | undefined {\n return track?.album ?? playlistSubtitle ?? undefined;\n}\n","import type { GingerState, PlaybackUiState, Track } from \"../types\";\nimport { resolveAlbumLine, resolveArtworkUrl } from \"../core/transitions\";\n\nexport function getCurrentTrack(state: GingerState): Track | null {\n const t = state.tracks[state.currentIndex];\n return t ?? null;\n}\n\nexport function derivePlaybackUiState(state: GingerState): PlaybackUiState {\n if (state.errorMessage) return \"error\";\n if (state.tracks.length === 0) return \"idle\";\n if (state.isBuffering) return \"loading\";\n if (!state.isPaused) return \"playing\";\n if (\n Number.isFinite(state.duration) &&\n state.duration > 0 &&\n state.currentTime >= state.duration - 0.05\n ) {\n return \"ended\";\n }\n return \"paused\";\n}\n\nexport function effectiveDuration(state: GingerState): number {\n const d = state.duration;\n if (Number.isFinite(d) && d > 0) return d;\n const hint = state.tracks[state.currentIndex]?.durationSeconds;\n if (typeof hint === \"number\" && Number.isFinite(hint) && hint > 0) return hint;\n return 0;\n}\n\nexport function effectiveRemaining(state: GingerState): number {\n const dur = effectiveDuration(state);\n const rem = dur - state.currentTime;\n return Number.isFinite(rem) ? Math.max(0, rem) : 0;\n}\n\nexport function progressFraction(state: GingerState): number {\n const dur = effectiveDuration(state);\n if (!(dur > 0)) return 0;\n return Math.min(1, Math.max(0, state.currentTime / dur));\n}\n\nexport function resolvedArtwork(state: GingerState): string | undefined {\n const track = getCurrentTrack(state);\n return resolveArtworkUrl(track, state.playlistMeta?.artworkUrl);\n}\n\nexport function resolvedAlbumLine(state: GingerState): string | undefined {\n const track = getCurrentTrack(state);\n return resolveAlbumLine(track, state.playlistMeta?.subtitle);\n}\n","import type { ReactElement, ReactNode } from \"react\";\nimport type { DisplayBaseProps, GingerState, Track } from \"../../types\";\nimport { getCurrentTrack } from \"../../internal/selectors\";\nimport { useGingerContext } from \"../../context/GingerContext\";\n\nexport type TextDisplayProps = DisplayBaseProps & {\n children?: (value: string, state: GingerState) => ReactNode;\n};\n\nexport function createTextDisplay(\n displayName: string,\n select: (state: GingerState) => string | undefined,\n): (props: TextDisplayProps) => ReactElement | null {\n function Comp(props: TextDisplayProps) {\n const { state } = useGingerContext();\n const raw = select(state) ?? \"\";\n const value = raw.trim();\n const { className, style, fallback, empty, children } = props;\n if (!value) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n if (children) return <span className={className} style={style}>{children(value, state)}</span>;\n return (\n <span className={className} style={style}>\n {value}\n </span>\n );\n }\n Comp.displayName = displayName;\n return Comp;\n}\n\nexport function createTrackFieldDisplay(\n displayName: string,\n select: (track: Track | null) => string | undefined,\n): (props: TextDisplayProps) => ReactElement | null {\n return createTextDisplay(displayName, (state) => select(getCurrentTrack(state)));\n}\n","import { createTextDisplay, createTrackFieldDisplay } from \"./createTextDisplay\";\nimport { getCurrentTrack, resolvedAlbumLine } from \"../../internal/selectors\";\n\nexport const Title = createTrackFieldDisplay(\"Ginger.Current.Title\", (t) => t?.title);\nexport const Artist = createTrackFieldDisplay(\"Ginger.Current.Artist\", (t) => t?.artist);\nexport const Album = createTextDisplay(\"Ginger.Current.Album\", (s) => resolvedAlbumLine(s));\nexport const Description = createTrackFieldDisplay(\"Ginger.Current.Description\", (t) => t?.description);\nexport const Copyright = createTextDisplay(\"Ginger.Current.Copyright\", (s) => {\n const t = getCurrentTrack(s);\n return t?.copyright ?? s.playlistMeta?.copyright;\n});\nexport const Genre = createTrackFieldDisplay(\"Ginger.Current.Genre\", (t) => t?.genre);\nexport const Label = createTrackFieldDisplay(\"Ginger.Current.Label\", (t) => t?.label);\nexport const Isrc = createTrackFieldDisplay(\"Ginger.Current.Isrc\", (t) => t?.isrc);\nexport const TrackNumber = createTrackFieldDisplay(\"Ginger.Current.TrackNumber\", (t) =>\n t?.trackNumber != null ? String(t.trackNumber) : undefined,\n);\n","import type { TextDisplayProps } from \"./createTextDisplay\";\nimport { useGingerContext } from \"../../context/GingerContext\";\nimport { getCurrentTrack } from \"../../internal/selectors\";\n\nexport type YearProps = TextDisplayProps & {\n format?: (year: number) => string;\n};\n\nexport function Year({ className, style, fallback, empty, children, format }: YearProps) {\n const { state } = useGingerContext();\n const y = getCurrentTrack(state)?.year;\n if (typeof y !== \"number\" || !Number.isFinite(y)) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n const text = format ? format(y) : String(y);\n if (children) return <span className={className} style={style}>{children(text, state)}</span>;\n return (\n <span className={className} style={style}>\n {text}\n </span>\n );\n}\n\nYear.displayName = \"Ginger.Current.Year\";\n","import type { CSSProperties, ReactNode } from \"react\";\nimport type { DisplayBaseProps, GingerState } from \"../../types\";\nimport { useGingerContext } from \"../../context/GingerContext\";\nimport { getCurrentTrack } from \"../../internal/selectors\";\n\nexport type LyricsProps = DisplayBaseProps & {\n children?: (value: string, state: GingerState) => ReactNode;\n /** When true, preserves internal newlines; trims only leading/trailing whitespace */\n preserveWhitespace?: boolean;\n};\n\nexport function Lyrics({ className, style, fallback, empty, children, preserveWhitespace = true }: LyricsProps) {\n const { state } = useGingerContext();\n const raw = getCurrentTrack(state)?.lyrics ?? \"\";\n const value = preserveWhitespace ? raw.replace(/^\\s+|\\s+$/g, \"\") : raw.trim();\n if (!value) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n const whiteStyle: CSSProperties | undefined = preserveWhitespace ? { whiteSpace: \"pre-wrap\" } : undefined;\n if (children) return <span className={className} style={{ ...whiteStyle, ...style }}>{children(value, state)}</span>;\n return (\n <span className={className} style={{ ...whiteStyle, ...style }}>\n {value}\n </span>\n );\n}\n\nLyrics.displayName = \"Ginger.Current.Lyrics\";\n","import type { TextDisplayProps } from \"./createTextDisplay\";\nimport { useGingerContext } from \"../../context/GingerContext\";\nimport { getCurrentTrack } from \"../../internal/selectors\";\n\nexport type FileUrlProps = TextDisplayProps & {\n /** When false (default), renders nothing unless you explicitly opt in */\n visible?: boolean;\n};\n\nexport function FileUrl({ visible = false, className, style, fallback, empty, children }: FileUrlProps) {\n const { state } = useGingerContext();\n if (!visible) return null;\n const value = getCurrentTrack(state)?.fileUrl ?? \"\";\n if (!value) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n if (children) return <span className={className} style={style}>{children(value, state)}</span>;\n return (\n <span className={className} style={style}>\n {value}\n </span>\n );\n}\n\nFileUrl.displayName = \"Ginger.Current.FileUrl\";\n","import type { CSSProperties, ImgHTMLAttributes } from \"react\";\nimport type { DisplayBaseProps } from \"../../types\";\nimport { useGingerContext } from \"../../context/GingerContext\";\nimport { getCurrentTrack, resolvedArtwork } from \"../../internal/selectors\";\n\nexport type ArtworkProps = DisplayBaseProps &\n Pick<ImgHTMLAttributes<HTMLImageElement>, \"sizes\" | \"loading\" | \"onError\" | \"decoding\"> & {\n imgStyle?: CSSProperties;\n };\n\nexport function Artwork({ className, style, fallback, empty, sizes, loading, onError, decoding, imgStyle }: ArtworkProps) {\n const { state } = useGingerContext();\n const track = getCurrentTrack(state);\n const src = resolvedArtwork(state);\n if (!src) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n const alt = [track?.title, track?.artist].filter(Boolean).join(\" — \") || \"Artwork\";\n return (\n <span\n className={className}\n style={{\n display: \"inline-block\",\n background: \"var(--ginger-artwork-bg, #f3f4f6)\",\n borderRadius: \"var(--ginger-artwork-radius, 6px)\",\n overflow: \"hidden\",\n ...style,\n }}\n >\n <img\n src={src}\n alt={alt}\n sizes={sizes}\n loading={loading}\n decoding={decoding}\n onError={onError}\n style={{\n display: \"block\",\n width: \"100%\",\n height: \"100%\",\n objectFit: \"cover\",\n ...imgStyle,\n }}\n />\n </span>\n );\n}\n\nArtwork.displayName = \"Ginger.Current.Artwork\";\n","import type { ReactNode } from \"react\";\nimport type { DisplayBaseProps, GingerState } from \"../../types\";\nimport { useGingerContext } from \"../../context/GingerContext\";\n\nexport type QueueIndexProps = DisplayBaseProps & {\n base?: 0 | 1;\n children?: (value: string, state: GingerState) => ReactNode;\n};\n\nexport function QueueIndex({ base = 0, className, style, fallback, empty, children }: QueueIndexProps) {\n const { state } = useGingerContext();\n const len = state.tracks.length;\n if (len === 0) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n const value = String(state.currentIndex + base);\n if (children) return <span className={className} style={style}>{children(value, state)}</span>;\n return (\n <span className={className} style={style}>\n {value}\n </span>\n );\n}\n\nQueueIndex.displayName = \"Ginger.Current.QueueIndex\";\n\nexport type QueueLengthProps = DisplayBaseProps & {\n children?: (value: string, state: GingerState) => ReactNode;\n};\n\nexport function QueueLength({ className, style, fallback, empty, children }: QueueLengthProps) {\n const { state } = useGingerContext();\n const value = String(state.tracks.length);\n if (state.tracks.length === 0) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n if (children) return <span className={className} style={style}>{children(value, state)}</span>;\n return (\n <span className={className} style={style}>\n {value}\n </span>\n );\n}\n\nQueueLength.displayName = \"Ginger.Current.QueueLength\";\n\nexport type QueuePositionProps = DisplayBaseProps & {\n base?: 0 | 1;\n separator?: string;\n children?: (value: { index: string; length: string; label: string }, state: GingerState) => ReactNode;\n};\n\nexport function QueuePosition({\n base = 0,\n separator = \" / \",\n className,\n style,\n fallback,\n empty,\n children,\n}: QueuePositionProps) {\n const { state } = useGingerContext();\n const len = state.tracks.length;\n if (len === 0) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n const index = String(state.currentIndex + base);\n const length = String(len);\n const label = `${index}${separator}${length}`;\n if (children)\n return (\n <span className={className} style={style}>\n {children({ index, length, label }, state)}\n </span>\n );\n return (\n <span className={className} style={style}>\n {label}\n </span>\n );\n}\n\nQueuePosition.displayName = \"Ginger.Current.QueuePosition\";\n","export function formatMmSs(seconds: number): string {\n if (!Number.isFinite(seconds) || seconds < 0) return \"0:00\";\n const s = Math.floor(seconds % 60);\n const m = Math.floor(seconds / 60);\n return `${m}:${s.toString().padStart(2, \"0\")}`;\n}\n","import type { ReactElement, ReactNode } from \"react\";\nimport type { DisplayBaseProps, GingerState } from \"../../types\";\nimport { useGingerContext } from \"../../context/GingerContext\";\nimport { effectiveDuration, effectiveRemaining, progressFraction } from \"../../internal/selectors\";\nimport { formatMmSs } from \"../../internal/formatTime\";\n\nexport type TimeTextProps = DisplayBaseProps & {\n format?: (seconds: number) => string;\n children?: (value: string, state: GingerState) => ReactNode;\n};\n\nfunction renderTime(\n valueSeconds: number,\n state: GingerState,\n props: TimeTextProps,\n): ReactElement | null {\n const { className, style, fallback, empty, children, format = formatMmSs } = props;\n if (!(valueSeconds >= 0) || !Number.isFinite(valueSeconds)) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n const text = format(valueSeconds);\n if (children) return <span className={className} style={style}>{children(text, state)}</span>;\n return (\n <span className={className} style={style}>\n {text}\n </span>\n );\n}\n\nexport function Elapsed(props: TimeTextProps) {\n const { state } = useGingerContext();\n return renderTime(state.currentTime, state, props);\n}\n\nElapsed.displayName = \"Ginger.Current.Elapsed\";\n\nexport function Duration(props: TimeTextProps) {\n const { state } = useGingerContext();\n return renderTime(effectiveDuration(state), state, props);\n}\n\nDuration.displayName = \"Ginger.Current.Duration\";\n\nexport function Remaining(props: TimeTextProps) {\n const { state } = useGingerContext();\n return renderTime(effectiveRemaining(state), state, props);\n}\n\nRemaining.displayName = \"Ginger.Current.Remaining\";\n\nexport type ProgressProps = DisplayBaseProps & {\n children?: (value: { fraction: number; currentTime: number; duration: number }, state: GingerState) => ReactNode;\n};\n\nexport function Progress({ className, style, fallback, empty, children }: ProgressProps) {\n const { state } = useGingerContext();\n const duration = effectiveDuration(state);\n const fraction = progressFraction(state);\n if (!(duration > 0)) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n if (children)\n return (\n <span className={className} style={style}>\n {children({ fraction, currentTime: state.currentTime, duration }, state)}\n </span>\n );\n return (\n <span className={className} style={style}>\n {`${Math.round(fraction * 100)}%`}\n </span>\n );\n}\n\nProgress.displayName = \"Ginger.Current.Progress\";\n\nexport type TimeRailProps = DisplayBaseProps & {\n /** 0-1 height in px for the rail */\n height?: number;\n};\n\nexport function TimeRail({ className, style, height = 4 }: TimeRailProps) {\n const { state } = useGingerContext();\n const pct = `${Math.round(progressFraction(state) * 100)}%`;\n return (\n <div\n className={className}\n style={{\n width: \"100%\",\n height,\n background: \"var(--ginger-muted-color, #e5e7eb)\",\n borderRadius: 999,\n overflow: \"hidden\",\n ...style,\n }}\n aria-hidden\n >\n <div style={{ width: pct, height: \"100%\", background: \"var(--ginger-primary-color, #111827)\" }} />\n </div>\n );\n}\n\nTimeRail.displayName = \"Ginger.Current.TimeRail\";\n","import type { ReactNode } from \"react\";\nimport type { DisplayBaseProps, GingerState, PlaybackUiState } from \"../../types\";\nimport { useGingerContext } from \"../../context/GingerContext\";\nimport { derivePlaybackUiState } from \"../../internal/selectors\";\n\nexport type PlaybackStateProps = DisplayBaseProps & {\n children?: (value: PlaybackUiState, state: GingerState) => ReactNode;\n};\n\nexport function PlaybackState({ className, style, fallback, empty, children }: PlaybackStateProps) {\n const { state } = useGingerContext();\n const value = derivePlaybackUiState(state);\n if (children) return <span className={className} style={style}>{children(value, state)}</span>;\n return (\n <span className={className} style={style}>\n {value}\n </span>\n );\n}\n\nPlaybackState.displayName = \"Ginger.Current.PlaybackState\";\n\nexport type ErrorMessageProps = DisplayBaseProps & {\n children?: (value: string, state: GingerState) => ReactNode;\n};\n\nexport function ErrorMessage({ className, style, fallback, empty, children }: ErrorMessageProps) {\n const { state } = useGingerContext();\n const value = state.errorMessage ?? \"\";\n if (!value) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n if (children) return <span className={className} style={style}>{children(value, state)}</span>;\n return (\n <span className={className} style={style}>\n {value}\n </span>\n );\n}\n\nErrorMessage.displayName = \"Ginger.Current.ErrorMessage\";\n","import type { ButtonHTMLAttributes, CSSProperties, InputHTMLAttributes, ReactNode } from \"react\";\nimport { useGingerContext } from \"../../context/GingerContext\";\nimport type { RepeatMode } from \"../../types\";\n\nexport type PlayPauseProps = ButtonHTMLAttributes<HTMLButtonElement> & {\n /** Optional labels; still headless—defaults are text for a11y */\n playLabel?: ReactNode;\n pauseLabel?: ReactNode;\n};\n\nexport function PlayPause({ playLabel = \"Play\", pauseLabel = \"Pause\", type = \"button\", ...rest }: PlayPauseProps) {\n const { state, togglePlayPause } = useGingerContext();\n return (\n <button type={type} aria-label={state.isPaused ? \"Play\" : \"Pause\"} onClick={togglePlayPause} {...rest}>\n {state.isPaused ? playLabel : pauseLabel}\n </button>\n );\n}\n\nPlayPause.displayName = \"Ginger.Control.PlayPause\";\n\nconst repeatLabels: Record<RepeatMode, string> = {\n off: \"Repeat off\",\n all: \"Repeat all\",\n one: \"Repeat one\",\n};\n\nexport type RepeatProps = ButtonHTMLAttributes<HTMLButtonElement>;\n\nexport function Repeat({ type = \"button\", ...rest }: RepeatProps) {\n const { state, cycleRepeat } = useGingerContext();\n return (\n <button type={type} aria-label={repeatLabels[state.repeatMode]} onClick={cycleRepeat} {...rest}>\n {repeatLabels[state.repeatMode]}\n </button>\n );\n}\n\nRepeat.displayName = \"Ginger.Control.Repeat\";\n\nexport type NextProps = ButtonHTMLAttributes<HTMLButtonElement>;\nexport function Next({ type = \"button\", children = \"Next\", ...rest }: NextProps) {\n const { next } = useGingerContext();\n return (\n <button type={type} aria-label=\"Next track\" onClick={next} {...rest}>\n {children}\n </button>\n );\n}\nNext.displayName = \"Ginger.Control.Next\";\n\nexport type PreviousProps = ButtonHTMLAttributes<HTMLButtonElement>;\nexport function Previous({ type = \"button\", children = \"Previous\", ...rest }: PreviousProps) {\n const { prev } = useGingerContext();\n return (\n <button type={type} aria-label=\"Previous track\" onClick={prev} {...rest}>\n {children}\n </button>\n );\n}\nPrevious.displayName = \"Ginger.Control.Previous\";\n\nexport type ShuffleProps = ButtonHTMLAttributes<HTMLButtonElement>;\nexport function Shuffle({ type = \"button\", children = \"Shuffle\", ...rest }: ShuffleProps) {\n const { state, toggleShuffle } = useGingerContext();\n return (\n <button type={type} aria-pressed={state.isShuffled} aria-label=\"Shuffle\" onClick={toggleShuffle} {...rest}>\n {children}\n </button>\n );\n}\nShuffle.displayName = \"Ginger.Control.Shuffle\";\n\nexport type SeekBarProps = Omit<InputHTMLAttributes<HTMLInputElement>, \"type\" | \"value\" | \"onChange\"> & {\n inputStyle?: CSSProperties;\n};\n\nexport function SeekBar({ inputStyle, style, ...rest }: SeekBarProps) {\n const { state, seek } = useGingerContext();\n const duration = Number.isFinite(state.duration) && state.duration > 0 ? state.duration : 0;\n const value = duration > 0 ? state.currentTime : 0;\n return (\n <input\n type=\"range\"\n min={0}\n max={duration > 0 ? duration : 1}\n step=\"any\"\n value={Number.isFinite(value) ? value : 0}\n aria-label=\"Seek\"\n onChange={(e) => seek(Number(e.currentTarget.value))}\n style={{ width: \"100%\", ...style, ...inputStyle }}\n {...rest}\n />\n );\n}\n\nSeekBar.displayName = \"Ginger.Control.SeekBar\";\n","import type { CSSProperties, HTMLAttributes, ReactNode } from \"react\";\nimport { useGingerContext } from \"../../context/GingerContext\";\nimport type { Track } from \"../../types\";\n\nexport type GingerPlaylistProps = HTMLAttributes<HTMLUListElement> & {\n rowStyle?: CSSProperties;\n renderTrack?: (track: Track, index: number, isActive: boolean) => ReactNode;\n /** When true (default), clicking a row selects that index and starts playback */\n playOnSelect?: boolean;\n};\n\nexport function GingerPlaylist({\n rowStyle,\n renderTrack,\n playOnSelect = true,\n style,\n ...rest\n}: GingerPlaylistProps) {\n const { state, playTrackAt, selectTrackAt } = useGingerContext();\n return (\n <ul\n style={{\n listStyle: \"none\",\n margin: 0,\n padding: 0,\n fontFamily: \"var(--ginger-font-family, system-ui, sans-serif)\",\n fontSize: \"var(--ginger-font-size, 14px)\",\n color: \"var(--ginger-primary-color, #111827)\",\n ...style,\n }}\n {...rest}\n >\n {state.tracks.map((track, index) => {\n const active = index === state.currentIndex;\n return (\n <li key={`${track.fileUrl}-${index}`}>\n <button\n type=\"button\"\n onClick={() => {\n if (playOnSelect) playTrackAt(index);\n else selectTrackAt(index);\n }}\n style={{\n width: \"100%\",\n textAlign: \"left\",\n border: \"none\",\n background: active ? \"rgba(17, 24, 39, 0.06)\" : \"transparent\",\n color: \"inherit\",\n font: \"inherit\",\n cursor: \"pointer\",\n padding: \"var(--ginger-playlist-row-padding, 6px 8px)\",\n ...rowStyle,\n }}\n >\n {renderTrack ? (\n renderTrack(track, index, active)\n ) : (\n <span>\n {track.title}\n {track.artist ? ` — ${track.artist}` : \"\"}\n </span>\n )}\n </button>\n </li>\n );\n })}\n </ul>\n );\n}\n\nGingerPlaylist.displayName = \"Ginger.Playlist\";\n","import type { CSSProperties } from \"react\";\nimport type { DisplayBaseProps } from \"../../types\";\nimport { createTextDisplay } from \"../current/createTextDisplay\";\nimport { useGingerContext } from \"../../context/GingerContext\";\n\nexport const Title = createTextDisplay(\"Ginger.Queue.Title\", (s) => s.playlistMeta?.title);\nexport const Subtitle = createTextDisplay(\"Ginger.Queue.Subtitle\", (s) => s.playlistMeta?.subtitle);\nexport const Description = createTextDisplay(\"Ginger.Queue.Description\", (s) => s.playlistMeta?.description);\nexport const Copyright = createTextDisplay(\"Ginger.Queue.Copyright\", (s) => s.playlistMeta?.copyright);\n\nexport type QueueArtworkProps = DisplayBaseProps & {\n imgStyle?: CSSProperties;\n};\n\nexport function Artwork({ className, style, fallback, empty, imgStyle }: QueueArtworkProps) {\n const { state } = useGingerContext();\n const src = state.playlistMeta?.artworkUrl;\n if (!src) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n const alt = state.playlistMeta?.title ?? \"Playlist artwork\";\n return (\n <span\n className={className}\n style={{\n display: \"inline-block\",\n background: \"var(--ginger-artwork-bg, #f3f4f6)\",\n borderRadius: \"var(--ginger-artwork-radius, 6px)\",\n overflow: \"hidden\",\n ...style,\n }}\n >\n <img\n src={src}\n alt={alt}\n style={{\n display: \"block\",\n width: \"100%\",\n height: \"100%\",\n objectFit: \"cover\",\n ...imgStyle,\n }}\n />\n </span>\n );\n}\n\nArtwork.displayName = \"Ginger.Queue.Artwork\";\n","import type { GingerAction, GingerState, RepeatMode, Track } from \"../types\";\nimport { clampIndex, findIndexByFileUrl, shuffleWithAnchor } from \"./queue\";\nimport { computeNextIndex, computePrevIndex, cycleRepeatMode } from \"./transitions\";\n\nconst defaultMedia = {\n currentTime: 0,\n duration: 0,\n bufferedFraction: 0,\n isBuffering: false,\n errorMessage: null as string | null,\n};\n\nexport function createInitialState(params: {\n tracks: Track[];\n currentIndex?: number;\n playlistMeta?: GingerState[\"playlistMeta\"];\n isPaused?: boolean;\n isShuffled?: boolean;\n repeatMode?: RepeatMode;\n}): GingerState {\n const tracks = [...params.tracks];\n let currentIndex = clampIndex(params.currentIndex ?? 0, tracks.length);\n let originalTracks: Track[] | null = null;\n let ordered = tracks;\n\n if (params.isShuffled && tracks.length > 1) {\n originalTracks = [...tracks];\n ordered = shuffleWithAnchor(tracks, currentIndex);\n currentIndex = 0;\n }\n\n return {\n tracks: ordered,\n currentIndex,\n isPaused: params.isPaused ?? true,\n isShuffled: Boolean(params.isShuffled && ordered.length > 1),\n repeatMode: params.repeatMode ?? \"off\",\n originalTracks,\n playlistMeta: params.playlistMeta ?? null,\n ...defaultMedia,\n };\n}\n\nexport function gingerReducer(state: GingerState, action: GingerAction): GingerState {\n switch (action.type) {\n case \"INIT\": {\n const { tracks, currentIndex, playlistMeta, isPaused, isShuffled, repeatMode } = action.payload;\n return createInitialState({\n tracks,\n currentIndex,\n playlistMeta: playlistMeta ?? null,\n isPaused: isPaused ?? true,\n isShuffled: isShuffled ?? false,\n repeatMode: repeatMode ?? \"off\",\n });\n }\n case \"SET_QUEUE\": {\n const { tracks, currentIndex } = action.payload;\n const next = [...tracks];\n const idx = clampIndex(currentIndex ?? state.currentIndex, next.length);\n return {\n ...state,\n tracks: next,\n currentIndex: idx,\n ...defaultMedia,\n };\n }\n case \"SET_INDEX\": {\n const idx = clampIndex(action.payload.index, state.tracks.length);\n const ap = action.payload.autoPlay;\n const isPaused =\n ap === true ? false : ap === false ? true : state.isPaused;\n return {\n ...state,\n currentIndex: idx,\n ...defaultMedia,\n isPaused,\n };\n }\n case \"PLAY\":\n return { ...state, isPaused: false };\n case \"PAUSE\":\n return { ...state, isPaused: true };\n case \"TOGGLE_PAUSE\":\n return { ...state, isPaused: !state.isPaused };\n case \"SET_REPEAT\":\n return { ...state, repeatMode: action.payload };\n case \"CYCLE_REPEAT\":\n return { ...state, repeatMode: cycleRepeatMode(state.repeatMode) };\n case \"TOGGLE_SHUFFLE\": {\n if (state.tracks.length <= 1) return { ...state, isShuffled: false, originalTracks: null };\n if (!state.isShuffled) {\n const snapshot = [...state.tracks];\n const shuffled = shuffleWithAnchor(snapshot, state.currentIndex);\n return {\n ...state,\n isShuffled: true,\n originalTracks: snapshot,\n tracks: shuffled,\n currentIndex: 0,\n };\n }\n const restored = state.originalTracks ? [...state.originalTracks] : [...state.tracks];\n const current = state.tracks[state.currentIndex];\n const fileUrl = current?.fileUrl ?? \"\";\n const newIndex = findIndexByFileUrl(restored, fileUrl);\n return {\n ...state,\n isShuffled: false,\n originalTracks: null,\n tracks: restored,\n currentIndex: clampIndex(newIndex, restored.length),\n };\n }\n case \"NEXT\": {\n const nextIndex = computeNextIndex(state);\n const same = nextIndex === state.currentIndex;\n return {\n ...state,\n currentIndex: nextIndex,\n ...(same ? {} : defaultMedia),\n isPaused: same ? state.isPaused : false,\n };\n }\n case \"PREV\": {\n const prevIndex = computePrevIndex(state);\n const same = prevIndex === state.currentIndex;\n return {\n ...state,\n currentIndex: prevIndex,\n ...(same ? {} : defaultMedia),\n isPaused: same ? state.isPaused : false,\n };\n }\n case \"MEDIA_TIME_UPDATE\":\n return {\n ...state,\n currentTime: action.payload.currentTime,\n duration: Number.isFinite(action.payload.duration) ? action.payload.duration : state.duration,\n bufferedFraction: action.payload.bufferedFraction,\n isBuffering: false,\n };\n case \"MEDIA_LOADED_METADATA\":\n return {\n ...state,\n duration: Number.isFinite(action.payload.duration) ? action.payload.duration : state.duration,\n bufferedFraction: action.payload.bufferedFraction,\n errorMessage: null,\n };\n case \"SET_PLAYLIST_META\":\n return { ...state, playlistMeta: action.payload };\n case \"MEDIA_ERROR\":\n return {\n ...state,\n errorMessage: action.payload.message,\n isPaused: true,\n isBuffering: false,\n };\n case \"MEDIA_WAITING\":\n return { ...state, isBuffering: true };\n case \"MEDIA_CANPLAY\":\n return { ...state, isBuffering: false, errorMessage: null };\n case \"MEDIA_PLAY\":\n return { ...state, isPaused: false, isBuffering: false };\n case \"MEDIA_PAUSE\":\n return { ...state, isPaused: true };\n case \"RESET_MEDIA_TIMES\":\n return { ...state, currentTime: 0, duration: 0, bufferedFraction: 0 };\n default:\n return state;\n }\n}\n","import {\n useCallback,\n useEffect,\n useMemo,\n useReducer,\n useRef,\n type CSSProperties,\n} from \"react\";\nimport { computeEndedTransition } from \"../core/transitions\";\nimport { gingerReducer, createInitialState } from \"../core/playbackReducer\";\nimport type { GingerProviderProps, PlaylistMeta, RepeatMode, Track } from \"../types\";\nimport { GingerContext, type GingerContextValue } from \"./GingerContext\";\n\nconst defaultProviderStyle: CSSProperties = {\n [\"--ginger-primary-color\" as string]: \"#111827\",\n [\"--ginger-muted-color\" as string]: \"#6b7280\",\n [\"--ginger-font-size\" as string]: \"14px\",\n [\"--ginger-font-family\" as string]: \"system-ui, sans-serif\",\n [\"--ginger-playlist-row-padding\" as string]: \"6px 8px\",\n [\"--ginger-artwork-radius\" as string]: \"6px\",\n [\"--ginger-artwork-bg\" as string]: \"#f3f4f6\",\n};\n\nexport function GingerProvider({\n children,\n initialTracks = [],\n initialIndex = 0,\n initialPlaylistMeta = null,\n initialShuffle = false,\n initialRepeatMode = \"off\",\n initialPaused = true,\n className,\n style,\n onTrackChange,\n onPlay,\n onPause,\n onQueueEnd,\n onError,\n}: GingerProviderProps) {\n const audioRef = useRef<HTMLAudioElement | null>(null);\n const [state, dispatch] = useReducer(\n gingerReducer,\n undefined,\n () =>\n createInitialState({\n tracks: initialTracks,\n currentIndex: initialIndex,\n playlistMeta: initialPlaylistMeta,\n isPaused: initialPaused,\n isShuffled: initialShuffle,\n repeatMode: initialRepeatMode,\n }),\n );\n\n const currentTrack = state.tracks[state.currentIndex] ?? null;\n\n useEffect(() => {\n onTrackChange?.(currentTrack, state.currentIndex);\n }, [currentTrack, state.currentIndex, onTrackChange]);\n\n useEffect(() => {\n if (state.errorMessage) onError?.(state.errorMessage);\n }, [state.errorMessage, onError]);\n\n const prevPausedRef = useRef<boolean | undefined>(undefined);\n useEffect(() => {\n if (prevPausedRef.current === undefined) {\n prevPausedRef.current = state.isPaused;\n return;\n }\n if (prevPausedRef.current !== state.isPaused) {\n if (state.isPaused) onPause?.();\n else onPlay?.();\n }\n prevPausedRef.current = state.isPaused;\n }, [state.isPaused, onPause, onPlay]);\n\n const play = useCallback(() => {\n dispatch({ type: \"PLAY\" });\n void audioRef.current?.play().catch((e: unknown) => {\n dispatch({ type: \"PAUSE\" });\n const msg = e instanceof Error ? e.message : \"Playback failed\";\n onError?.(msg);\n });\n }, [onError]);\n\n const pause = useCallback(() => {\n dispatch({ type: \"PAUSE\" });\n audioRef.current?.pause();\n }, []);\n\n const togglePlayPause = useCallback(() => {\n if (state.isPaused) play();\n else pause();\n }, [pause, play, state.isPaused]);\n\n const seek = useCallback((timeSeconds: number) => {\n const el = audioRef.current;\n if (!el) return;\n if (!Number.isFinite(timeSeconds)) return;\n el.currentTime = Math.max(0, timeSeconds);\n }, []);\n\n const setVolume = useCallback((volume: number) => {\n const el = audioRef.current;\n if (!el) return;\n el.volume = Math.min(1, Math.max(0, volume));\n }, []);\n\n const setMuted = useCallback((muted: boolean) => {\n const el = audioRef.current;\n if (!el) return;\n el.muted = muted;\n }, []);\n\n const next = useCallback(() => {\n dispatch({ type: \"NEXT\" });\n }, []);\n\n const prev = useCallback(() => {\n dispatch({ type: \"PREV\" });\n }, []);\n\n const setRepeatMode = useCallback((mode: RepeatMode) => {\n dispatch({ type: \"SET_REPEAT\", payload: mode });\n }, []);\n\n const cycleRepeat = useCallback(() => {\n dispatch({ type: \"CYCLE_REPEAT\" });\n }, []);\n\n const toggleShuffle = useCallback(() => {\n dispatch({ type: \"TOGGLE_SHUFFLE\" });\n }, []);\n\n const setQueue = useCallback((tracks: Track[], currentIndex?: number) => {\n dispatch({ type: \"SET_QUEUE\", payload: { tracks, currentIndex } });\n }, []);\n\n const playTrackAt = useCallback((index: number) => {\n dispatch({ type: \"SET_INDEX\", payload: { index, autoPlay: true } });\n queueMicrotask(() => {\n void audioRef.current?.play().catch(() => {});\n });\n }, []);\n\n const selectTrackAt = useCallback((index: number) => {\n dispatch({ type: \"SET_INDEX\", payload: { index, autoPlay: false } });\n }, []);\n\n const setPlaylistMeta = useCallback((meta: PlaylistMeta | null) => {\n dispatch({ type: \"SET_PLAYLIST_META\", payload: meta });\n }, []);\n\n const currentUrl = state.tracks[state.currentIndex]?.fileUrl;\n\n useEffect(() => {\n const el = audioRef.current;\n if (!el) return;\n if (state.isPaused) el.pause();\n else\n void el.play().catch((e: unknown) => {\n dispatch({ type: \"PAUSE\" });\n const msg = e instanceof Error ? e.message : \"Playback failed\";\n onError?.(msg);\n });\n }, [state.isPaused, currentUrl, onError]);\n\n const notifyEnded = useCallback(() => {\n const transition = computeEndedTransition(state);\n if (transition.kind === \"replay_same\") {\n const el = audioRef.current;\n if (el) {\n el.currentTime = 0;\n void el.play().catch(() => {});\n }\n dispatch({ type: \"PLAY\" });\n return;\n }\n if (transition.kind === \"stop\") {\n dispatch({ type: \"PAUSE\" });\n onQueueEnd?.();\n return;\n }\n const nextIndex = transition.nextIndex;\n dispatch({ type: \"SET_INDEX\", payload: { index: nextIndex, autoPlay: true } });\n queueMicrotask(() => {\n void audioRef.current?.play().catch(() => {});\n });\n }, [onQueueEnd, state]);\n\n const value = useMemo<GingerContextValue>(\n () => ({\n state,\n dispatch,\n audioRef,\n notifyEnded,\n play,\n pause,\n togglePlayPause,\n seek,\n setVolume,\n setMuted,\n next,\n prev,\n setRepeatMode,\n cycleRepeat,\n toggleShuffle,\n setQueue,\n playTrackAt,\n selectTrackAt,\n setPlaylistMeta,\n }),\n [\n cycleRepeat,\n dispatch,\n next,\n notifyEnded,\n pause,\n play,\n playTrackAt,\n selectTrackAt,\n prev,\n seek,\n setMuted,\n setQueue,\n setRepeatMode,\n setPlaylistMeta,\n setVolume,\n state,\n togglePlayPause,\n toggleShuffle,\n ],\n );\n\n const mergedStyle = useMemo(() => ({ ...defaultProviderStyle, ...style }), [style]);\n\n return (\n <GingerContext.Provider value={value}>\n <div className={className} style={mergedStyle}>\n {children}\n </div>\n </GingerContext.Provider>\n );\n}\n","import { GingerPlayer } from \"./audio/GingerPlayer\";\nimport * as Current from \"./components/current\";\nimport * as Control from \"./components/controls/Controls\";\nimport { GingerPlaylist } from \"./components/playlist/GingerPlaylist\";\nimport * as Queue from \"./components/queue/QueueDisplay\";\nimport { GingerProvider } from \"./context/GingerProvider\";\n\nexport const Ginger = {\n Provider: GingerProvider,\n Player: GingerPlayer,\n Current: {\n Title: Current.Title,\n Artist: Current.Artist,\n Album: Current.Album,\n Description: Current.Description,\n Copyright: Current.Copyright,\n Genre: Current.Genre,\n Label: Current.Label,\n Isrc: Current.Isrc,\n TrackNumber: Current.TrackNumber,\n Year: Current.Year,\n Lyrics: Current.Lyrics,\n FileUrl: Current.FileUrl,\n Artwork: Current.Artwork,\n QueueIndex: Current.QueueIndex,\n QueueLength: Current.QueueLength,\n QueuePosition: Current.QueuePosition,\n Elapsed: Current.Elapsed,\n Duration: Current.Duration,\n Remaining: Current.Remaining,\n Progress: Current.Progress,\n TimeRail: Current.TimeRail,\n PlaybackState: Current.PlaybackState,\n ErrorMessage: Current.ErrorMessage,\n },\n Queue: {\n Title: Queue.Title,\n Subtitle: Queue.Subtitle,\n Description: Queue.Description,\n Copyright: Queue.Copyright,\n Artwork: Queue.Artwork,\n },\n Control: {\n PlayPause: Control.PlayPause,\n Repeat: Control.Repeat,\n Next: Control.Next,\n Previous: Control.Previous,\n Shuffle: Control.Shuffle,\n SeekBar: Control.SeekBar,\n },\n Playlist: GingerPlaylist,\n} as const;\n","import { useMemo } from \"react\";\nimport { useGingerContext } from \"../context/GingerContext\";\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 ctx = useGingerContext();\n const { state } = ctx;\n\n return useMemo(\n () => ({\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: ctx.play,\n pause: ctx.pause,\n togglePlayPause: ctx.togglePlayPause,\n seek: ctx.seek,\n setVolume: ctx.setVolume,\n setMuted: ctx.setMuted,\n next: ctx.next,\n prev: ctx.prev,\n setRepeatMode: ctx.setRepeatMode,\n cycleRepeat: ctx.cycleRepeat,\n toggleShuffle: ctx.toggleShuffle,\n setQueue: ctx.setQueue,\n playTrackAt: ctx.playTrackAt,\n selectTrackAt: ctx.selectTrackAt,\n setPlaylistMeta: ctx.setPlaylistMeta,\n dispatch: ctx.dispatch,\n }),\n [\n ctx.cycleRepeat,\n ctx.dispatch,\n ctx.next,\n ctx.pause,\n ctx.play,\n ctx.playTrackAt,\n ctx.selectTrackAt,\n ctx.prev,\n ctx.seek,\n ctx.setMuted,\n ctx.setPlaylistMeta,\n ctx.setQueue,\n ctx.setRepeatMode,\n ctx.setVolume,\n ctx.togglePlayPause,\n ctx.toggleShuffle,\n state,\n ],\n );\n}\n"],"names":["GingerContext","createContext","useGingerContext","ctx","useContext","readBufferedFraction","el","buffered","duration","GingerPlayer","className","style","preload","crossOrigin","audioRef","dispatch","state","notifyEnded","url","_a","useEffect","jsx","e","code","clampIndex","index","length","shuffleWithAnchor","tracks","anchorIndex","anchor","rest","_","i","j","findIndexByFileUrl","fileUrl","computeEndedTransition","currentIndex","repeatMode","len","computeNextIndex","computePrevIndex","cycleRepeatMode","mode","resolveArtworkUrl","track","playlistArtwork","resolveAlbumLine","playlistSubtitle","getCurrentTrack","derivePlaybackUiState","effectiveDuration","d","hint","effectiveRemaining","rem","progressFraction","dur","resolvedArtwork","resolvedAlbumLine","createTextDisplay","displayName","select","Comp","props","value","fallback","empty","children","node","createTrackFieldDisplay","Title","t","Artist","Album","s","Description","Copyright","Genre","Label","Isrc","TrackNumber","Year","format","y","text","Lyrics","preserveWhitespace","raw","whiteStyle","FileUrl","visible","Artwork","sizes","loading","onError","decoding","imgStyle","src","alt","QueueIndex","base","QueueLength","QueuePosition","separator","label","formatMmSs","seconds","renderTime","valueSeconds","Elapsed","Duration","Remaining","Progress","fraction","TimeRail","height","pct","PlaybackState","ErrorMessage","PlayPause","playLabel","pauseLabel","type","togglePlayPause","repeatLabels","Repeat","cycleRepeat","Next","next","Previous","prev","Shuffle","toggleShuffle","SeekBar","inputStyle","seek","GingerPlaylist","rowStyle","renderTrack","playOnSelect","playTrackAt","selectTrackAt","active","Subtitle","_b","defaultMedia","createInitialState","params","originalTracks","ordered","gingerReducer","action","playlistMeta","isPaused","isShuffled","idx","ap","snapshot","shuffled","restored","current","newIndex","nextIndex","same","prevIndex","defaultProviderStyle","GingerProvider","initialTracks","initialIndex","initialPlaylistMeta","initialShuffle","initialRepeatMode","initialPaused","onTrackChange","onPlay","onPause","onQueueEnd","useRef","useReducer","currentTrack","prevPausedRef","play","useCallback","msg","pause","timeSeconds","setVolume","volume","setMuted","muted","setRepeatMode","setQueue","setPlaylistMeta","meta","currentUrl","transition","useMemo","mergedStyle","Ginger","Current.Title","Current.Artist","Current.Album","Current.Description","Current.Copyright","Current.Genre","Current.Label","Current.Isrc","Current.TrackNumber","Current.Year","Current.Lyrics","Current.FileUrl","Current.Artwork","Current.QueueIndex","Current.QueueLength","Current.QueuePosition","Current.Elapsed","Current.Duration","Current.Remaining","Current.Progress","Current.TimeRail","Current.PlaybackState","Current.ErrorMessage","Queue.Title","Queue.Subtitle","Queue.Description","Queue.Copyright","Queue.Artwork","Control.PlayPause","Control.Repeat","Control.Next","Control.Previous","Control.Shuffle","Control.SeekBar","useGinger"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function formatMmSs(seconds: number): string;
2
+ //# sourceMappingURL=formatTime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatTime.d.ts","sourceRoot":"","sources":["../../src/internal/formatTime.ts"],"names":[],"mappings":"AAAA,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKlD"}
@@ -0,0 +1,9 @@
1
+ import { GingerState, PlaybackUiState, Track } from '../types';
2
+ export declare function getCurrentTrack(state: GingerState): Track | null;
3
+ export declare function derivePlaybackUiState(state: GingerState): PlaybackUiState;
4
+ export declare function effectiveDuration(state: GingerState): number;
5
+ export declare function effectiveRemaining(state: GingerState): number;
6
+ export declare function progressFraction(state: GingerState): number;
7
+ export declare function resolvedArtwork(state: GingerState): string | undefined;
8
+ export declare function resolvedAlbumLine(state: GingerState): string | undefined;
9
+ //# sourceMappingURL=selectors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selectors.d.ts","sourceRoot":"","sources":["../../src/internal/selectors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAGpE,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,KAAK,GAAG,IAAI,CAGhE;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,WAAW,GAAG,eAAe,CAazE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAM5D;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAI7D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAI3D;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAGtE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAGxE"}
@@ -0,0 +1,141 @@
1
+ import { CSSProperties, ReactNode } from 'react';
2
+ export type RepeatMode = "off" | "all" | "one";
3
+ export type Track = {
4
+ title: string;
5
+ fileUrl: string;
6
+ artist?: string;
7
+ copyright?: string;
8
+ description?: string;
9
+ album?: string;
10
+ artworkUrl?: string;
11
+ genre?: string;
12
+ year?: number;
13
+ label?: string;
14
+ isrc?: string;
15
+ trackNumber?: number;
16
+ lyrics?: string;
17
+ /** Hint before metadata loads; never overrides finite media duration */
18
+ durationSeconds?: number;
19
+ };
20
+ export type PlaylistMeta = {
21
+ id?: string;
22
+ title?: string;
23
+ subtitle?: string;
24
+ artworkUrl?: string;
25
+ copyright?: string;
26
+ description?: string;
27
+ };
28
+ export type PlaybackUiState = "idle" | "loading" | "playing" | "paused" | "ended" | "error";
29
+ export type GingerMediaSlice = {
30
+ currentTime: number;
31
+ duration: number;
32
+ bufferedFraction: number;
33
+ isBuffering: boolean;
34
+ errorMessage: string | null;
35
+ };
36
+ export type GingerPlaybackSlice = {
37
+ tracks: Track[];
38
+ currentIndex: number;
39
+ isPaused: boolean;
40
+ isShuffled: boolean;
41
+ repeatMode: RepeatMode;
42
+ /** Canonical order before shuffle was enabled; null when shuffle is off */
43
+ originalTracks: Track[] | null;
44
+ playlistMeta: PlaylistMeta | null;
45
+ };
46
+ export type GingerState = GingerPlaybackSlice & GingerMediaSlice;
47
+ export type GingerAction = {
48
+ type: "INIT";
49
+ payload: {
50
+ tracks: Track[];
51
+ currentIndex?: number;
52
+ playlistMeta?: PlaylistMeta | null;
53
+ isPaused?: boolean;
54
+ isShuffled?: boolean;
55
+ repeatMode?: RepeatMode;
56
+ };
57
+ } | {
58
+ type: "SET_QUEUE";
59
+ payload: {
60
+ tracks: Track[];
61
+ currentIndex?: number;
62
+ };
63
+ } | {
64
+ type: "SET_INDEX";
65
+ payload: {
66
+ index: number;
67
+ autoPlay?: boolean;
68
+ };
69
+ } | {
70
+ type: "PLAY";
71
+ } | {
72
+ type: "PAUSE";
73
+ } | {
74
+ type: "TOGGLE_PAUSE";
75
+ } | {
76
+ type: "SET_REPEAT";
77
+ payload: RepeatMode;
78
+ } | {
79
+ type: "CYCLE_REPEAT";
80
+ } | {
81
+ type: "TOGGLE_SHUFFLE";
82
+ } | {
83
+ type: "NEXT";
84
+ } | {
85
+ type: "PREV";
86
+ } | {
87
+ type: "MEDIA_TIME_UPDATE";
88
+ payload: {
89
+ currentTime: number;
90
+ duration: number;
91
+ bufferedFraction: number;
92
+ };
93
+ } | {
94
+ type: "MEDIA_LOADED_METADATA";
95
+ payload: {
96
+ duration: number;
97
+ bufferedFraction: number;
98
+ };
99
+ } | {
100
+ type: "SET_PLAYLIST_META";
101
+ payload: PlaylistMeta | null;
102
+ } | {
103
+ type: "MEDIA_ERROR";
104
+ payload: {
105
+ message: string;
106
+ };
107
+ } | {
108
+ type: "MEDIA_WAITING";
109
+ } | {
110
+ type: "MEDIA_CANPLAY";
111
+ } | {
112
+ type: "MEDIA_PLAY";
113
+ } | {
114
+ type: "MEDIA_PAUSE";
115
+ } | {
116
+ type: "RESET_MEDIA_TIMES";
117
+ };
118
+ export type GingerProviderProps = {
119
+ children: ReactNode;
120
+ initialTracks?: Track[];
121
+ initialIndex?: number;
122
+ initialPlaylistMeta?: PlaylistMeta | null;
123
+ /** When true, shuffle starts enabled (still applies shuffle transform on mount if tracks.length > 1) */
124
+ initialShuffle?: boolean;
125
+ initialRepeatMode?: RepeatMode;
126
+ initialPaused?: boolean;
127
+ className?: string;
128
+ style?: CSSProperties;
129
+ onTrackChange?: (track: Track | null, index: number) => void;
130
+ onPlay?: () => void;
131
+ onPause?: () => void;
132
+ onQueueEnd?: () => void;
133
+ onError?: (message: string) => void;
134
+ };
135
+ export type DisplayBaseProps = {
136
+ className?: string;
137
+ style?: CSSProperties;
138
+ fallback?: ReactNode;
139
+ empty?: ReactNode;
140
+ };
141
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@lucaismyname/ginger",
3
+ "version": "0.0.1",
4
+ "description": "Headless React audio player with compound components",
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "files": ["dist", "LICENSE"],
8
+ "main": "./dist/index.cjs",
9
+ "module": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js",
15
+ "require": "./dist/index.cjs"
16
+ }
17
+ },
18
+ "scripts": {
19
+ "build": "vite build",
20
+ "prepublishOnly": "npm run build"
21
+ },
22
+ "peerDependencies": {
23
+ "react": ">=18",
24
+ "react-dom": ">=18"
25
+ },
26
+ "peerDependenciesMeta": {
27
+ "react-dom": { "optional": true }
28
+ },
29
+ "devDependencies": {
30
+ "@types/react": "^18.3.12",
31
+ "@types/react-dom": "^18.3.1",
32
+ "@vitejs/plugin-react": "^4.3.4",
33
+ "react": "^18.3.1",
34
+ "react-dom": "^18.3.1",
35
+ "typescript": "^5.6.3",
36
+ "vite": "^5.4.11",
37
+ "vite-plugin-dts": "^4.3.0"
38
+ },
39
+ "keywords": ["react", "audio", "player", "headless", "playlist"],
40
+ "license": "MIT",
41
+ "repository": {
42
+ "type": "git",
43
+ "url": "https://github.com/lucaismyname/ginger"
44
+ }
45
+ }