@lucaismyname/ginger 0.0.1 → 0.0.3
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/dist/audio/GingerPlayer.d.ts.map +1 -1
- package/dist/components/controls/Controls.d.ts +24 -1
- package/dist/components/controls/Controls.d.ts.map +1 -1
- package/dist/components/playlist/GingerPlaylist.d.ts +28 -3
- package/dist/components/playlist/GingerPlaylist.d.ts.map +1 -1
- package/dist/context/GingerContext.d.ts +2 -0
- package/dist/context/GingerContext.d.ts.map +1 -1
- package/dist/context/GingerProvider.d.ts +1 -1
- package/dist/context/GingerProvider.d.ts.map +1 -1
- package/dist/core/playbackReducer.d.ts +5 -0
- package/dist/core/playbackReducer.d.ts.map +1 -1
- package/dist/ginger.d.ts +45 -41
- package/dist/ginger.d.ts.map +1 -1
- package/dist/hooks/useGinger.d.ts +2 -0
- package/dist/hooks/useGinger.d.ts.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +678 -510
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +31 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","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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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","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 toggleMute: () => void;\n setPlaybackRate: (rate: number) => 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 el.volume = state.volume;\n el.muted = state.muted;\n el.playbackRate = state.playbackRate;\n }, [audioRef, state.volume, state.muted, state.playbackRate]);\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 onVolumeChange={(e) => {\n const el = e.currentTarget;\n dispatch({\n type: \"MEDIA_VOLUME_SYNC\",\n payload: { volume: el.volume, muted: el.muted },\n });\n }}\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 { useMemo } from \"react\";\nimport type {\n ButtonHTMLAttributes,\n CSSProperties,\n InputHTMLAttributes,\n ReactNode,\n SelectHTMLAttributes,\n} 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\nexport type VolumeProps = Omit<InputHTMLAttributes<HTMLInputElement>, \"type\" | \"value\" | \"onChange\"> & {\n inputStyle?: CSSProperties;\n};\n\nexport function Volume({ inputStyle, style, ...rest }: VolumeProps) {\n const { state, setVolume } = useGingerContext();\n return (\n <input\n type=\"range\"\n min={0}\n max={1}\n step=\"any\"\n value={state.volume}\n aria-label=\"Volume\"\n onChange={(e) => setVolume(Number(e.currentTarget.value))}\n style={{ width: \"100%\", ...style, ...inputStyle }}\n {...rest}\n />\n );\n}\n\nVolume.displayName = \"Ginger.Control.Volume\";\n\nexport type MuteProps = ButtonHTMLAttributes<HTMLButtonElement> & {\n muteLabel?: ReactNode;\n unmuteLabel?: ReactNode;\n};\n\nexport function Mute({\n muteLabel = \"Mute\",\n unmuteLabel = \"Unmute\",\n type = \"button\",\n ...rest\n}: MuteProps) {\n const { state, toggleMute } = useGingerContext();\n return (\n <button\n type={type}\n aria-pressed={state.muted}\n aria-label={state.muted ? \"Unmute\" : \"Mute\"}\n onClick={toggleMute}\n {...rest}\n >\n {state.muted ? unmuteLabel : muteLabel}\n </button>\n );\n}\n\nMute.displayName = \"Ginger.Control.Mute\";\n\nconst defaultRates = [0.5, 0.75, 1, 1.25, 1.5, 2] as const;\n\nexport type PlaybackRateProps = Omit<SelectHTMLAttributes<HTMLSelectElement>, \"value\" | \"onChange\"> & {\n /** Playback speed options (default: 0.5 … 2) */\n rates?: readonly number[];\n};\n\nexport function PlaybackRate({ rates = defaultRates, style, ...rest }: PlaybackRateProps) {\n const { state, setPlaybackRate } = useGingerContext();\n const options = useMemo(\n () => Array.from(new Set([...rates, state.playbackRate])).sort((a, b) => a - b),\n [rates, state.playbackRate],\n );\n return (\n <select\n aria-label=\"Playback speed\"\n value={String(state.playbackRate)}\n style={style}\n onChange={(e) => setPlaybackRate(Number(e.currentTarget.value))}\n {...rest}\n >\n {options.map((r) => (\n <option key={r} value={String(r)}>\n {r === 1 ? \"1× normal\" : `${r}×`}\n </option>\n ))}\n </select>\n );\n}\n\nPlaybackRate.displayName = \"Ginger.Control.PlaybackRate\";\n","import {\n createContext,\n useContext,\n type ButtonHTMLAttributes,\n type CSSProperties,\n type HTMLAttributes,\n type LiHTMLAttributes,\n type ReactNode,\n} from \"react\";\nimport { useGingerContext } from \"../../context/GingerContext\";\nimport type { Track } from \"../../types\";\n\nexport type GingerPlaylistConfig = {\n playOnSelect: boolean;\n};\n\nconst GingerPlaylistConfigContext = createContext<GingerPlaylistConfig | null>(null);\n\nfunction usePlaylistConfig(): GingerPlaylistConfig {\n const ctx = useContext(GingerPlaylistConfigContext);\n if (!ctx) {\n throw new Error(\"Ginger.Playlist.Track must be used inside <Ginger.Playlist>\");\n }\n return ctx;\n}\n\nexport type GingerPlaylistProps = Omit<HTMLAttributes<HTMLUListElement>, \"children\"> & {\n children?: ReactNode;\n rowStyle?: CSSProperties;\n /**\n * Used only in **auto** mode (no custom `children`). Ignored when you pass custom `children`\n * (manual mode); use `Ginger.Playlist.Track` for each row instead.\n */\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\n/**\n * - **Auto mode** (no `children`): maps `state.tracks` to rows (optional `renderTrack`).\n * - **Manual mode** (`children` defined): renders `<ul>{children}</ul>`; map `state.tracks` yourself\n * with `Ginger.Playlist.Track` for each index.\n */\nexport function GingerPlaylist({\n children,\n rowStyle,\n renderTrack,\n playOnSelect = true,\n style,\n ...rest\n}: GingerPlaylistProps) {\n const { state, playTrackAt, selectTrackAt } = useGingerContext();\n\n const listStyle: CSSProperties = {\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\n const manual = children !== undefined;\n\n if (manual) {\n return (\n <GingerPlaylistConfigContext.Provider value={{ playOnSelect }}>\n <ul style={listStyle} {...rest}>\n {children}\n </ul>\n </GingerPlaylistConfigContext.Provider>\n );\n }\n\n return (\n <GingerPlaylistConfigContext.Provider value={{ playOnSelect }}>\n <ul style={listStyle} {...rest}>\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 </GingerPlaylistConfigContext.Provider>\n );\n}\n\nGingerPlaylist.displayName = \"Ginger.Playlist\";\n\nexport type GingerPlaylistTrackProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"type\"> & {\n index: number;\n /** Optional wrapper for the row; defaults to a plain `<li>` */\n liProps?: LiHTMLAttributes<HTMLLIElement>;\n};\n\nexport function GingerPlaylistTrack({\n index,\n className,\n style,\n children,\n liProps,\n onClick,\n ...buttonRest\n}: GingerPlaylistTrackProps) {\n const { playOnSelect } = usePlaylistConfig();\n const { state, playTrackAt, selectTrackAt } = useGingerContext();\n const active = index === state.currentIndex;\n const track = state.tracks[index];\n const defaultLabel =\n track != null ? (\n <span>\n {track.title}\n {track.artist ? ` — ${track.artist}` : \"\"}\n </span>\n ) : null;\n\n return (\n <li {...liProps}>\n <button\n type=\"button\"\n aria-current={active ? \"true\" : undefined}\n data-ginger-active={active || undefined}\n className={className}\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 ...style,\n }}\n {...buttonRest}\n onClick={(e) => {\n onClick?.(e);\n if (e.defaultPrevented) return;\n if (playOnSelect) playTrackAt(index);\n else selectTrackAt(index);\n }}\n >\n {children ?? defaultLabel}\n </button>\n </li>\n );\n}\n\nGingerPlaylistTrack.displayName = \"Ginger.Playlist.Track\";\n\nexport const GingerPlaylistCompound = Object.assign(GingerPlaylist, {\n Track: GingerPlaylistTrack,\n});\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\nexport function clampVolume(v: number): number {\n if (!Number.isFinite(v)) return 1;\n return Math.min(1, Math.max(0, v));\n}\n\nexport function clampPlaybackRate(r: number): number {\n if (!Number.isFinite(r)) return 1;\n return Math.min(4, Math.max(0.25, r));\n}\n\n/** Reset when the active track / position changes; keeps volume / mute / speed */\nconst resetTimingOnly = {\n currentTime: 0,\n duration: 0,\n bufferedFraction: 0,\n isBuffering: false,\n errorMessage: null as string | null,\n};\n\nconst defaultMedia = {\n ...resetTimingOnly,\n volume: 1,\n muted: false,\n playbackRate: 1,\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 volume?: number;\n muted?: boolean;\n playbackRate?: number;\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 volume: clampVolume(params.volume ?? 1),\n muted: params.muted ?? false,\n playbackRate: clampPlaybackRate(params.playbackRate ?? 1),\n };\n}\n\nexport function gingerReducer(state: GingerState, action: GingerAction): GingerState {\n switch (action.type) {\n case \"INIT\": {\n const {\n tracks,\n currentIndex,\n playlistMeta,\n isPaused,\n isShuffled,\n repeatMode,\n volume,\n muted,\n playbackRate,\n } = 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 volume,\n muted,\n playbackRate,\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 ...resetTimingOnly,\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 ...resetTimingOnly,\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 ? {} : resetTimingOnly),\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 ? {} : resetTimingOnly),\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 case \"SET_VOLUME\":\n return { ...state, volume: clampVolume(action.payload) };\n case \"SET_MUTED\":\n return { ...state, muted: action.payload };\n case \"TOGGLE_MUTE\":\n return { ...state, muted: !state.muted };\n case \"SET_PLAYBACK_RATE\":\n return { ...state, playbackRate: clampPlaybackRate(action.payload) };\n case \"MEDIA_VOLUME_SYNC\": {\n const { volume, muted } = action.payload;\n const v = clampVolume(volume);\n if (v === state.volume && muted === state.muted) return state;\n return { ...state, volume: v, muted };\n }\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 { clampPlaybackRate, clampVolume, 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 initialVolume = 1,\n initialMuted = false,\n initialPlaybackRate = 1,\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 volume: initialVolume,\n muted: initialMuted,\n playbackRate: initialPlaybackRate,\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 dispatch({ type: \"SET_VOLUME\", payload: clampVolume(volume) });\n }, []);\n\n const setMuted = useCallback((muted: boolean) => {\n dispatch({ type: \"SET_MUTED\", payload: muted });\n }, []);\n\n const toggleMute = useCallback(() => {\n dispatch({ type: \"TOGGLE_MUTE\" });\n }, []);\n\n const setPlaybackRate = useCallback((rate: number) => {\n dispatch({ type: \"SET_PLAYBACK_RATE\", payload: clampPlaybackRate(rate) });\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 toggleMute,\n setPlaybackRate,\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 setPlaybackRate,\n setQueue,\n setRepeatMode,\n setPlaylistMeta,\n setVolume,\n state,\n toggleMute,\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 { GingerPlaylistCompound } 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 Volume: Control.Volume,\n Mute: Control.Mute,\n PlaybackRate: Control.PlaybackRate,\n },\n Playlist: GingerPlaylistCompound,\n};\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 toggleMute: ctx.toggleMute,\n setPlaybackRate: ctx.setPlaybackRate,\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.setPlaybackRate,\n ctx.setPlaylistMeta,\n ctx.setQueue,\n ctx.setRepeatMode,\n ctx.setVolume,\n ctx.toggleMute,\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","t","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","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","Volume","setVolume","Mute","muteLabel","unmuteLabel","toggleMute","defaultRates","PlaybackRate","rates","setPlaybackRate","options","useMemo","a","b","r","GingerPlaylistConfigContext","usePlaylistConfig","GingerPlaylist","rowStyle","renderTrack","playOnSelect","playTrackAt","selectTrackAt","listStyle","active","GingerPlaylistTrack","liProps","onClick","buttonRest","defaultLabel","jsxs","GingerPlaylistCompound","Subtitle","_b","clampVolume","v","clampPlaybackRate","resetTimingOnly","defaultMedia","createInitialState","params","originalTracks","ordered","gingerReducer","action","playlistMeta","isPaused","isShuffled","volume","muted","playbackRate","idx","ap","snapshot","shuffled","restored","current","newIndex","nextIndex","same","prevIndex","defaultProviderStyle","GingerProvider","initialTracks","initialIndex","initialPlaylistMeta","initialShuffle","initialRepeatMode","initialPaused","initialVolume","initialMuted","initialPlaybackRate","onTrackChange","onPlay","onPause","onQueueEnd","useRef","useReducer","currentTrack","prevPausedRef","play","useCallback","msg","pause","timeSeconds","setMuted","rate","setRepeatMode","setQueue","setPlaylistMeta","meta","currentUrl","transition","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","Control.Volume","Control.Mute","Control.PlaybackRate","useGinger"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,12 +2,12 @@ export { Ginger } from './ginger';
|
|
|
2
2
|
export { useGinger } from './hooks/useGinger';
|
|
3
3
|
export type { DisplayBaseProps, GingerMediaSlice, GingerPlaybackSlice, GingerProviderProps, GingerState, PlaybackUiState, PlaylistMeta, RepeatMode, Track, } from './types';
|
|
4
4
|
export type { GingerPlayerProps } from './audio/GingerPlayer';
|
|
5
|
-
export type { GingerPlaylistProps } from './components/playlist/GingerPlaylist';
|
|
5
|
+
export type { GingerPlaylistProps, GingerPlaylistTrackProps, } from './components/playlist/GingerPlaylist';
|
|
6
6
|
export type { ErrorMessageProps, PlaybackStateProps, } from './components/current/Playback';
|
|
7
7
|
export type { ArtworkProps as CurrentArtworkProps } from './components/current/Artwork';
|
|
8
8
|
export type { FileUrlProps } from './components/current/FileUrl';
|
|
9
9
|
export type { LyricsProps } from './components/current/Lyrics';
|
|
10
10
|
export type { ProgressProps, TimeRailProps, TimeTextProps } from './components/current/Time';
|
|
11
11
|
export type { QueueArtworkProps } from './components/queue/QueueDisplay';
|
|
12
|
-
export type { NextProps, PlayPauseProps, PreviousProps, RepeatProps, SeekBarProps, ShuffleProps, } from './components/controls/Controls';
|
|
12
|
+
export type { MuteProps, NextProps, PlaybackRateProps, PlayPauseProps, PreviousProps, RepeatProps, SeekBarProps, ShuffleProps, VolumeProps, } from './components/controls/Controls';
|
|
13
13
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,WAAW,EACX,eAAe,EACf,YAAY,EACZ,UAAU,EACV,KAAK,GACN,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,WAAW,EACX,eAAe,EACf,YAAY,EACZ,UAAU,EACV,KAAK,GACN,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,YAAY,EACV,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,sCAAsC,CAAC;AAC9C,YAAY,EACV,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,+BAA+B,CAAC;AACvC,YAAY,EAAE,YAAY,IAAI,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACxF,YAAY,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,YAAY,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC7F,YAAY,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACzE,YAAY,EACV,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,WAAW,GACZ,MAAM,gCAAgC,CAAC"}
|