Framework wrappers
The thin framework wrappers version independently of the core libraries they wrap.
@arraypress/waveform-player-astro
Section titled “@arraypress/waveform-player-astro”[Unreleased]
Section titled “[Unreleased]”Changed
Section titled “Changed”- Types are now sourced directly from the core
@arraypress/waveform-playerpackage — a single source of truth. The shared option types (WaveformStyle,ColorPreset,AudioMode,AudioPreload,ButtonAlign,WaveformMarker,WaveformPeaks) are re-exported from the core, andWaveformPlayerPropsnowextendsthe core’sWaveformPlayerOptionsinstead of re-declaring every option, so the two packages can no longer drift. Every previously-exported type name is preserved. - Bumped the
@arraypress/waveform-playerpeer (and dev) dependency to^1.8.0, which ships the hand-authoredindex.d.tsthese types adopt.
accessibleSeek,seekLabel,barRadius, and the gradient-array forms ofwaveformColor/progressColorare now exposed onWaveformPlayerProps(inherited from the core option surface), filling gaps where the previous hand-maintained copy had missed or drifted.
[0.1.2] — 2026-06-27
Section titled “[0.1.2] — 2026-06-27”Changed
Section titled “Changed”- Bumped the
@arraypress/waveform-playerpeer (and dev) dependency to^1.7.2. Consumers now get the native accessible keyboard / ARIA seek slider by default. No component API changes.
[0.1.1] — Unreleased
Section titled “[0.1.1] — Unreleased”Changed
Section titled “Changed”- Widened the
astropeerDependency to^6.0.0 || ^7.0.0for Astro 7 readiness. No runtime changes — the component is unaffected by the Astro 7 compiler / Vite 8 (Rolldown) upgrade.
[0.1.0] — Unreleased
Section titled “[0.1.0] — Unreleased”Initial release.
<WaveformPlayer>Astro component wrapping every option exposed by@arraypress/waveform-player1.6.x as a typed prop:- Audio source props (
url,audioMode,preload) - Waveform visualisation props (
waveformStyle,height,samples,barWidth,barSpacing,waveform) - Colour props (
colorPreset,waveformColor,progressColor,buttonColor,buttonHoverColor,textColor,textSecondaryColor,backgroundColor,borderColor) - Playback control props (
playbackRate,showPlaybackSpeed,playbackRates) - UI toggle props (
showControls,showInfo,showTime,showHoverTime,showBPM,buttonAlign) - Marker props (
markers,showMarkers) - Content metadata props (
title,subtitle,artwork,album) - Behaviour flags (
autoplay,singlePlay,playOnSeek,enableMediaSession) - Icon props (
playIcon,pauseIcon)
- Audio source props (
- Astro-specific
lazyprop that switches the init attribute todata-waveform-player-lazyand ships a single deduplicatedIntersectionObserverfor grids of many previews. - Astro-specific
id,class, andstylepass-throughs. - Public TypeScript types:
WaveformPlayerProps,WaveformStyle,WaveformMarker,WaveformPeaks,ColorPreset,AudioMode,AudioPreload,ButtonAlign. - Ambient declaration for
window.WaveformPlayerto type consumer scripts that reach for the global. - Vitest suite (29 tests) covering attribute mapping, omission semantics, JSON serialisation for array props, lazy-mount script presence, and pass-through props.
- Documentation: full prop reference, setup guide, seven usage
examples (
examples/basic.astro).
@arraypress/waveform-player-react
Section titled “@arraypress/waveform-player-react”[Unreleased]
Section titled “[Unreleased]”Changed
Section titled “Changed”- Public types are now adopted from the core
@arraypress/waveform-player(v1.8.0+), which ships a hand-authoredindex.d.ts. The shared option surface (WaveformStyle,ColorPreset,AudioMode,AudioPreload,ButtonAlign,WaveformMarker,WaveformPeaks) is re-exported from the core, andWaveformPlayerPropsnowextendsthe core’sWaveformPlayerOptionsinstead of re-declaring every field. The core is the single source of truth, so the wrapper’s types can no longer drift out of sync. Bumped the@arraypress/waveform-playerpeer (and dev) dependency to^1.8.0. - Callback props (
onLoad,onPlay,onPause,onEnd,onTimeUpdate,onError) and theWaveformPlayerHandle.instanceaccessor are now typed with the core’sWaveformPlayerclass instead ofunknown.
accessibleSeek,seekLabel,barRadius, and gradient-array waveform / progress colours (string[]) are now exposed as typed props — picked up for free by extending the core options and wired through to the underlying player.
Removed
Section titled “Removed”- Deleted
src/core-module-shim.d.ts, the loose ambientdeclare module '@arraypress/waveform-player'shim that only existed while the core had no shipped types.
[0.1.1] — 2026-06-27
Section titled “[0.1.1] — 2026-06-27”Changed
Section titled “Changed”- Bumped the
@arraypress/waveform-playerpeer (and dev) dependency to^1.7.2. Consumers now get the native accessible keyboard / ARIA seek slider by default. No component API changes.
[0.1.0] — Unreleased
Section titled “[0.1.0] — Unreleased”Initial release.
<WaveformPlayer>React component wrapping every option exposed by@arraypress/waveform-player1.6.x as a typed prop:- Audio source (
url,audioMode,preload) - Waveform visualisation (
waveformStyle,height,samples,barWidth,barSpacing,waveform) - Colours (
colorPreset,waveformColor,progressColor,buttonColor,buttonHoverColor,textColor,textSecondaryColor,backgroundColor,borderColor) - Playback (
playbackRate,showPlaybackSpeed,playbackRates) - UI toggles (
showControls,showInfo,showTime,showHoverTime,showBPM,buttonAlign) - Markers (
markers,showMarkers) - Metadata (
title,subtitle,artwork,album) - Behaviour (
autoplay,singlePlay,playOnSeek,enableMediaSession) - Icons (
playIcon,pauseIcon)
- Audio source (
- Callback props (
onLoad,onPlay,onPause,onEnd,onTimeUpdate,onError) that map to the library’s same-named option fields. Callbacks are deliberately NOT in the effect dep array, so a parent re-rendering with new inline functions doesn’t tear the player down. - React-specific extras:
id,className,style, andrefforwarding viaWaveformPlayerHandle. WaveformPlayerHandleimperative API on the forwarded ref —play(),pause(),togglePlay(),seekTo(),seekToPercent(),setVolume(),setPlaybackRate(),setPlayingState(),setProgress(),loadTrack(), plus the rawinstance.- SSR / RSC safe: the core library is loaded via dynamic
import('@arraypress/waveform-player')inside the effect so the browser-only audio surface never runs server-side. - Identity-prop re-mount: when any library-construction prop
changes (
url,audioMode, etc.), the wrapper destroys the existing instance and creates a new one with the updated options. Simpler and more correct than diffing every option + calling granular updaters. - Public TypeScript types:
WaveformPlayerProps,WaveformPlayerHandle,WaveformStyle,WaveformMarker,WaveformPeaks,ColorPreset,AudioMode,AudioPreload,ButtonAlign. - Ambient module shim for
@arraypress/waveform-playerso the wrapper typechecks cleanly until the core library ships its own.d.ts. - Vitest test suite (17 tests, jsdom +
@testing-library/react) covering mount, unmount destroy, option pass-through, callback forwarding, identity-prop re-mount, callback-churn protection, ref forwarding, and the full imperative handle surface. The core library is mocked at the module boundary because jsdom has no Web Audio API. - Dual ESM (
dist/index.js) + CJS (dist/index.cjs) build viatsup..d.tsfor both. React + the core library are externalised so they resolve to the consumer’s copies. - README with full prop reference, seven usage patterns, and the
imperative-ref control example.
examples/basic.tsxwith seven copy-paste-ready snippets.
@arraypress/waveform-player-vue
Section titled “@arraypress/waveform-player-vue”[0.1.0] — Unreleased
Section titled “[0.1.0] — Unreleased”Initial release.
<WaveformPlayer>Vue 3 component wrapping every option exposed by@arraypress/waveform-playeras a typed prop:- Audio source (
url,srcalias,audioMode,preload) - Waveform visualisation (
waveformStyle,height,samples,barWidth,barSpacing,barRadius,waveform) - Colours (
colorPreset,waveformColor,progressColor,buttonColor,buttonHoverColor,textColor,textSecondaryColor,backgroundColor,borderColor— strings orstring[]gradients) - Playback (
playbackRate,showPlaybackSpeed,playbackRates) - UI toggles (
showControls,showInfo,showTime,showHoverTime,showBPM,buttonAlign,accessibleSeek,seekLabel,errorText) - Markers (
markers,showMarkers) - Metadata (
title,subtitle,artwork,album) - Behaviour (
autoplay,singlePlay,playOnSeek,enableMediaSession) - Icons (
playIcon,pauseIcon)
- Audio source (
- Lifecycle emits (
load,play,pause,end,timeupdate,error), each forwarding the liveWaveformPlayerinstance. Wired through Vue’s stableemit, so listeners can change without tearing the player down. - Imperative API exposed via a template
ref(WaveformPlayerExpose):play(),pause(),togglePlay(),seekTo(),seekToPercent(),setVolume(),setPlaybackRate(),setPlayingState(),setProgress(),loadTrack(), plus the rawinstance. class,style, andidfall through to the host element via Vue’s attribute inheritance; the base classwfp-hostalways applies.- SSR / Nuxt safe: the core library is loaded via dynamic
import('@arraypress/waveform-player')insideonMountedso the browser-only audio surface never runs server-side. - Identity-prop re-mount: when any library-construction prop changes, the wrapper destroys the existing instance and creates a new one with the updated options. A monotonic mount token discards any in-flight async import that a newer mount (or unmount) has superseded.
- Public types are adopted from the core
@arraypress/waveform-player(WaveformStyle,ColorPreset,AudioMode,AudioPreload,ButtonAlign,WaveformMarker,WaveformPeaks), re-exported here so the wrapper’s types can never drift out of sync.WaveformPlayerPropsis derived from the core’sWaveformPlayerOptions. - Dual ESM (
dist/index.js) + CJS (dist/index.cjs) build viatsup, with.d.tsfor both. Vue + the core library are externalised so they resolve to the consumer’s copies. - Vitest test suite (jsdom +
@vue/test-utils) covering mount, option pass-through, thesrc → urlalias, boolean-prop omission, emit forwarding, destroy-on-unmount, identity-prop re-mount, and the exposed imperative API. The core is mocked at the module boundary because jsdom has no Web Audio API. - README with full prop reference, seven usage patterns, and the
imperative-ref control example.
examples/basic.vuewith seven copy-paste-ready snippets.
@arraypress/waveform-player-svelte
Section titled “@arraypress/waveform-player-svelte”[0.1.0] — Unreleased
Section titled “[0.1.0] — Unreleased”Initial release.
<WaveformPlayer>Svelte 5 component (built with runes) wrapping every option exposed by@arraypress/waveform-playeras a typed prop:- Audio source (
url,srcalias,audioMode,preload) - Waveform visualisation (
waveformStyle,height,samples,barWidth,barSpacing,barRadius,waveform) - Colours (
colorPreset,waveformColor,progressColor,buttonColor,buttonHoverColor,textColor,textSecondaryColor,backgroundColor,borderColor— strings orstring[]gradients) - Playback (
playbackRate,showPlaybackSpeed,playbackRates) - UI toggles (
showControls,showInfo,showTime,showHoverTime,showBPM,buttonAlign,accessibleSeek,seekLabel,errorText) - Markers (
markers,showMarkers) - Metadata (
title,subtitle,artwork,album) - Behaviour (
autoplay,singlePlay,playOnSeek,enableMediaSession) - Icons (
playIcon,pauseIcon)
- Audio source (
- Lowercase lifecycle callback props (
onload,onplay,onpause,onend,ontimeupdate,onerror), each forwarding the liveWaveformPlayerinstance. Wired through reactive closures, so changing a handler never tears the player down. - Imperative API exported by the component instance (reachable via
bind:this):play(),pause(),togglePlay(),seekTo(),seekToPercent(),setVolume(),setPlaybackRate(),setPlayingState(),setProgress(),loadTrack(), andgetInstance(). class,style,id, and other element attributes fall through to the host element via...rest; the base classwfp-hostalways applies.- SSR / SvelteKit safe: the core library is loaded via dynamic
import('@arraypress/waveform-player')inside a browser-only$effect, so the audio surface never runs server-side. - Identity-prop re-mount: a single
$effectreads every construction prop, so changing any of them destroys the existing instance and creates a new one. A monotonic mount token discards any in-flight async import that a newer mount (or unmount) has superseded. - Public types adopted from the core
@arraypress/waveform-player(WaveformStyle,ColorPreset,AudioMode,AudioPreload,ButtonAlign,WaveformMarker,WaveformPeaks), re-exported here so the wrapper’s types can never drift.WaveformPlayerPropsis derived from the core’sWaveformPlayerOptions. - Built with
svelte-package(dist/ships the preprocessed.svelte+ generated.d.ts). Svelte + the core library are peer dependencies. - Vitest test suite (jsdom +
@testing-library/svelte) covering mount, option pass-through, thesrc → urlalias, boolean-prop omission, callback forwarding, destroy-on-unmount, identity-prop re-mount, and the exported imperative API. The core is mocked at the module boundary because jsdom has no Web Audio API. - README with full prop reference, seven usage patterns, and the
imperative
bind:thiscontrol example.examples/Basic.sveltewith seven copy-paste-ready snippets.
@arraypress/waveform-bar-astro
Section titled “@arraypress/waveform-bar-astro”[0.2.0] — 2026-07-01
Section titled “[0.2.0] — 2026-07-01”Changed
Section titled “Changed”- Sync
WaveformBarConfigto the bar’smodeAPI:layout→mode('waveform' | 'classic'), removemaxWidth, addshowShuffle/shuffle. Matches@arraypress/waveform-bar1.7.0.
[0.1.3] — 2026-06-27
Section titled “[0.1.3] — 2026-06-27”Changed
Section titled “Changed”- Bumped the
@arraypress/waveform-playerpeer (and dev) dependency to^1.7.2, which adds the native accessible keyboard / ARIA seek slider to the underlying player. No component API changes.
[0.1.2] — Unreleased
Section titled “[0.1.2] — Unreleased”Changed
Section titled “Changed”- Widened the
astropeerDependency to^6.0.0 || ^7.0.0for Astro 7 readiness. No runtime changes — the component is unaffected by the Astro 7 compiler / Vite 8 (Rolldown) upgrade.
[0.1.1] — Unreleased
Section titled “[0.1.1] — Unreleased”<WaveformBarTrigger>’s default pause-icon SVG no longer carries an inlinestyle="display:none;". The previous value beat the core library’s class-based toggle (.wb-icon-swap.wb-playing .wb-show-pause { display: inline; }), leaving the pause icon permanently hidden once a track started playing. The library’s own CSS already covers the initial-hidden state via.wb-icon-swap .wb-show-pause { display: none; }, so the inline style is redundant as well as harmful.- Added two regression tests pinning the no-inline-display contract so the bug can’t return.
[0.1.0]
Section titled “[0.1.0]”Initial release.
<WaveformBar>— singleton mount component for the persistent bottom bar. Renders atransition:persisthost div and an inline init script that callswindow.WaveformBar.init(config)on everyastro:page-load. Relocates the library’s.waveform-barelement into the persist host so view transitions keep it onscreen between navigations.- Typed
WaveformBarConfigcovering every optionwindow.WaveformBar.init()accepts:- Persistence:
persist,autoResume,continuous,repeat - UI toggles:
showQueue,showPrevNext,showRepeat,showVolume,showMute,showTime,showTrackLink,showMeta,maxMeta - Theming:
theme,defaultArtwork - Waveform visualisation:
waveformStyle,waveformHeight,barWidth,barSpacing,waveformColor,progressColor,markerColor - Volume + persistence keys:
volume,storageKey - Server-side actions:
actions.favorite/actions.cartwithendpointURL + optionalmethod/headers
- Persistence:
<WaveformBarTrigger>— polymorphic click trigger. Renders a<button>by default; override viaas="a" | "div" | "span". Emits the fulldata-wb-*attribute contract:- Track identity:
url,id(falls back tourl),title,artist,album,artwork,link - Display chips:
duration,bpm,key,meta - Audio data:
waveform(peaks array, URL, or inline JSON),markers(DJ-mode chapters) - Initial state:
favorited,inCart - Behaviour:
mode='play' | 'queue',href(whenas="a"),ariaLabel,class,noDefaultIcons
- Track identity:
- Default slot ships the play / pause SVG pair the core library
toggles via
wb-show-play/wb-show-pauseclasses. Passing children replaces them. - Auto-generated
aria-labelwhen one isn’t supplied —Play {title}for play triggers,Add {title} to queuefor queue triggers. - Public TypeScript types:
WaveformBarProps,WaveformBarConfig,WaveformBarTriggerProps,WaveformBarTrackData,WaveformBarMarker,WaveformBarActions,WaveformBarAction,WaveformBarTheme,RepeatMode,TriggerMode,WaveformStyle. - Ambient declaration for
window.WaveformBarcovering the full public surface (play,pause,next,previous,addToQueue,setVolume,setRepeat,seekToMarker, etc.). - Vitest suite of 46 tests via Astro’s
experimental_AstroContainercovering attribute mapping, omission semantics, JSON serialisation for arrays, polymorphicas, default-slot behaviour, aria-label generation, and a kitchen-sink scenario. - Documentation: full README with setup, prop tables, every usage
pattern, and the
waveformbar:*custom-event API.examples/basic.astroreference page with six demonstrations.
@arraypress/waveform-bar-react
Section titled “@arraypress/waveform-bar-react”[0.2.0] — 2026-07-01
Section titled “[0.2.0] — 2026-07-01”Changed
Section titled “Changed”- Sync
WaveformBarConfigto the bar’smodeAPI:layout→mode('waveform' | 'classic'), removemaxWidth, addshowShuffle/shuffle. Matches@arraypress/waveform-bar1.7.0.
[0.1.1] — 2026-06-27
Section titled “[0.1.1] — 2026-06-27”Changed
Section titled “Changed”- Bumped the
@arraypress/waveform-playerpeer (and dev) dependency to^1.7.2for the native accessible keyboard / ARIA seek slider. No component API changes.
[0.1.0] — Unreleased
Section titled “[0.1.0] — Unreleased”Initial release.
<WaveformBar>— singleton mount component for the persistent bottom bar. Renders a persist host<div>and runswindow.WaveformBar.init(config)inside an effect. Tears down on unmount (StrictMode-safe) and re-inits only when the structural shape of the config changes — passing a fresh object reference with the same shape doesn’t trigger churn. Relocates the bar element into the persist host so route changes / re-renders don’t tear it down.<WaveformBarTrigger>— polymorphic click trigger. Defaults to<button>; override viaas="a" | "div" | "span". Emits the fulldata-wb-*attribute contract:- Track identity:
url,id,title,artist,album,artwork,link - Display chips:
duration,bpm,musicalKey,meta - Audio data:
waveform(peaks array, URL, or inline JSON),markers(DJ-mode chapters) - Initial state:
favorited,inCart - Behaviour:
mode='play' | 'queue',href(whenas="a"),aria-label,className,style,noDefaultIcons,children
- Track identity:
- Default
play / pauseSVG pair rendered as the trigger’s children when no custom content is passed. The library’swb-icon-swapCSS toggles them based on the active track state. - Auto-generated
aria-labelwhen one isn’t supplied —Play {title}for play triggers,Add {title} to queuefor queue triggers. - Public TypeScript types:
WaveformBarProps,WaveformBarConfig,WaveformBarTriggerProps,WaveformBarTrackData,WaveformBarMarker,WaveformBarActions,WaveformBarAction,WaveformBarTheme,RepeatMode,TriggerMode,WaveformStyle. - Ambient module shim for
@arraypress/waveform-barand@arraypress/waveform-playerso the wrapper typechecks cleanly until the core libraries ship.d.tsof their own. - SSR / RSC safe: the core library loads via dynamic
import()inside the effect, so the browser-only audio surface never evaluates server-side. - 46 Vitest tests via jsdom +
@testing-library/react:- 28 tests for
<WaveformBarTrigger>rendering + attribute mapping (no module mocking needed) - 18 tests for
<WaveformBar>lifecycle (window global mocked since jsdom has no Web Audio)
- 28 tests for
- Dual ESM (
dist/index.js) + CJS (dist/index.cjs) build viatsup..d.tsfor both. React + the two core libraries externalised so they resolve to the consumer’s copies. - README with full prop reference, seven usage patterns, and the
waveformbar:*custom-event API documented as the callback alternative. examples/basic.tsxwith seven copy-paste-ready snippets.
@arraypress/waveform-bar-vue
Section titled “@arraypress/waveform-bar-vue”[0.1.0] — Unreleased
Section titled “[0.1.0] — Unreleased”Initial release.
<WaveformBar>— singleton mount for the persistent bottom bar. Render once in your root layout. On mount it dynamically imports@arraypress/waveform-bar(SSR-safe) and callswindow.WaveformBar.init(config); re-inits when the config’s structural shape changes (compared viaJSON.stringify, so a fresh object with the same shape doesn’t churn); relocates the bar element into a persist host<div>; and callsdestroy()on unmount.config,persist,hostIdprops;class/stylefall through to the host (base classwb-host).<WaveformBarTrigger>— polymorphic (as="button" | "a" | "div" | "span", defaultbutton) click trigger that emits thedata-wb-*attribute contract the core library scans for. Maps track-data props (url,id,title,artist,album,artwork,link,duration,bpm,musicalKey,meta,waveform,markers,favorited,inCart) to attributes (arrays JSON-encoded; absent props emit no attribute).mode="play" | "queue",href(foras="a"),noDefaultIcons. Renders default play/pause SVGs unless slot content is provided. Auto-generates anaria-labelfromtitle.class, native listeners (@click), and other attributes fall through; the base classwb-icon-swapis always applied.- No lifecycle callback props — the bar dispatches every state change as a
bubbling
waveformbar:*CustomEvent; listen withaddEventListener. This keeps callbacks from forcing a bar re-init (matching the React wrapper). - Public types mirroring the core surface:
WaveformBarConfig,WaveformBarProps,WaveformBarTriggerProps,WaveformBarTrackData,WaveformBarMarker,WaveformBarActions,WaveformBarAction,WaveformBarTheme,RepeatMode,TriggerMode,WaveformStyle. - Dual ESM + CJS build via
tsupwith.d.tsfor both. Vue + the core libraries are peer dependencies. - Vitest test suite (jsdom +
@vue/test-utils, 13 tests) covering the singleton’s host render +init/ re-init /destroylifecycle, and the trigger’sdata-wb-*contract, polymorphism, modes, default-icon handling, class merge, and click forwarding.
@arraypress/waveform-bar-svelte
Section titled “@arraypress/waveform-bar-svelte”[0.1.0] — Unreleased
Section titled “[0.1.0] — Unreleased”Initial release.
<WaveformBar>— singleton mount (Svelte 5 runes) for the persistent bottom bar. Render once in your root layout. A browser-only$effectdynamically imports@arraypress/waveform-bar(SSR-safe) and callswindow.WaveformBar.init(config); a$derivedconfig key re-inits only when the config’s structural shape (orpersist) changes; the bar element is relocated into a persist host<div>;destroy()is called on unmount.config,persist,hostIdprops;class/ attributes fall through to the host (base classwb-host).<WaveformBarTrigger>— polymorphic (as="button" | "a" | "div" | "span"via<svelte:element>, defaultbutton) click trigger that emits thedata-wb-*attribute contract the core library scans for. Maps track-data props (url,id,title,artist,album,artwork,link,duration,bpm,musicalKey,meta,waveform,markers,favorited,inCart) to attributes (arrays JSON-encoded; absent props emit no attribute).mode="play" | "queue",href(foras="a"),noDefaultIcons. Renders default play/pause SVGs unless children are slotted. Auto-generates anaria-labelfromtitle.class, native listeners (onclick), and other attributes fall through via...rest; the base classwb-icon-swapis always applied.- No lifecycle callback props — the bar dispatches every state change as a
bubbling
waveformbar:*CustomEvent; listen withaddEventListener. - Public types mirroring the core surface:
WaveformBarConfig,WaveformBarProps,WaveformBarTriggerProps,WaveformBarTrackData,WaveformBarMarker,WaveformBarActions,WaveformBarAction,WaveformBarTheme,RepeatMode,TriggerMode,WaveformStyle. - Built with
svelte-package(dist/ships the preprocessed.svelte+ generated.d.ts). Svelte + the core libraries are peer dependencies. - Vitest test suite (jsdom +
@testing-library/svelte, 12 tests) covering the singleton’s host render +init/ re-init / no-churn /destroylifecycle, and the trigger’sdata-wb-*contract, polymorphism, modes, default-icon handling, class merge, and click forwarding.
@arraypress/waveform-playlist-astro
Section titled “@arraypress/waveform-playlist-astro”[0.1.0] — Initial release
Section titled “[0.1.0] — Initial release”<WaveformPlaylist>Astro component wrapping@arraypress/waveform-playlist. Renders the library’s nested markup contract — a[data-waveform-playlist]container with one[data-track]child per track and one[data-chapter]child per chapter — from a single typedtracksarray.- Typed props for the playlist’s own options:
layout('list' | 'minimal'),continuous,expandChapters,showDuration,showChapterMarkers(boolean | null),chapterMarkerColor,showPlayState.
- Typed pass-through of the WaveformPlayer options the playlist forwards
to its embedded player —
waveformStyle,height,samples,barWidth,barSpacing,barRadius,colorPreset, the colour options (including gradient-arraywaveformColor/progressColor),playbackRate,showPlaybackSpeed,playbackRates,showControls,showInfo,showTime,showHoverTime,showBPM,bpm,buttonAlign,buttonStyle,accessibleSeek,seekLabel,errorText,showMarkers,autoplay,singlePlay,playOnSeek,enableMediaSession,preload,playIcon,pauseIcon. The per-track content fields (url,title,subtitle,artwork,album,markers) live on eachtracksentry instead, and the player’slayout/audioModeare intentionally not exposed (the playlist ownsdata-layoutand always drives a self-mode player). - A typed
tracksarray (WaveformPlaylistTrackInput[]) with per-trackurl,title,subtitle,artwork,album,duration,markers, andchapters({ time, label, color? }). - Astro-specific
lazyprop that switches the init attribute todata-waveform-playlist-lazyand ships a single deduplicatedIntersectionObserverthat promotes the playlist on viewport entry, plus a non-lazyastro:page-loadre-init for Astro View Transitions. - Astro-specific
id,class, andstylepass-throughs (wfpl-hostis always applied to the container). - Public TypeScript types derived from the two core packages so they
never drift:
WaveformPlaylistProps,WaveformPlaylistTrackInput, and re-exports ofWaveformPlaylistOptions/WaveformPlaylistTrack/WaveformPlaylistChapter/WaveformPlaylistMarker(from the playlist core) andWaveformStyle/WaveformMarker/WaveformPeaks/ColorPreset/AudioMode/AudioPreload/ButtonAlign(from the player core). - Vitest suite covering container option serialisation, omission semantics, JSON serialisation for array props, per-track and per-chapter rendering, lazy-mount and View-Transitions script presence, and the Astro extras.
- Documentation: full prop reference, setup guide, and usage examples
(
examples/basic.astro).
@arraypress/waveform-playlist-react
Section titled “@arraypress/waveform-playlist-react”[0.1.0] — Unreleased
Section titled “[0.1.0] — Unreleased”Initial release.
<WaveformPlaylist>React component wrapping@arraypress/waveform-playlist:- A declarative, required
tracksarray (WaveformPlaylistTrackInput[]) rendered into the[data-track]/[data-chapter]child markup the playlist constructor parses on mount. Each track acceptsurl,title,subtitle,artwork,album,duration,markers, andchapters({ time, label, color? }, wheretimeis a seconds number or a'M:SS'string). - Playlist options as typed props:
layout('list' | 'minimal'),continuous,expandChapters,showDuration,showChapterMarkers,chapterMarkerColor,showPlayState. - Pass-through player options forwarded to the embedded player
(
waveformStyle,height,samples,barWidth,barSpacing,barRadius, colours,playbackRate,showPlaybackSpeed,playbackRates, UI toggles,accessibleSeek,seekLabel,errorText, behaviour flags, icons,audioMode,preload). - React-specific extras:
id,className,style, andrefforwarding viaWaveformPlaylistHandle.
- A declarative, required
WaveformPlaylistHandleimperative API on the forwarded ref —selectTrack(),seekToChapter(),nextTrack(),previousTrack(),getPlayer(),getCurrentTrackIndex(),getTracks(), plus the rawinstanceescape hatch.- SSR / RSC safe: the playlist library is loaded via dynamic
import('@arraypress/waveform-playlist')inside the effect so the browser-only audio surface never runs server-side. - Identity-prop re-mount: when any construction prop changes — the
serialised
tracks,layout,continuous, colours, sizing, etc. — the wrapper destroys the existing instance and creates a new one against the freshly-rendered markup. DOM-only props (className,style,id) do not trigger a re-mount. - The host container deliberately omits
data-waveform-playlistso the library’s global auto-init never double-mounts on top of the instance the wrapper creates explicitly. - Public TypeScript types:
WaveformPlaylistProps,WaveformPlaylistHandle,WaveformPlaylistTrackInput,WaveformPlaylistChapterInput, plus the re-exported core types (WaveformPlaylistOptions,WaveformPlaylistTrack,WaveformPlaylistChapter,WaveformPlaylistMarker,WaveformStyle,WaveformMarker,WaveformPeaks,ColorPreset,AudioMode,AudioPreload,ButtonAlign). - Vitest test suite (jsdom +
@testing-library/react) covering track / chapter markup rendering, mount, unmount destroy, option pass-through, identity-prop re-mount, ref forwarding, and the full imperative handle surface. The core library is mocked at the module boundary because jsdom has no Web Audio API. - Dual ESM (
dist/index.js) + CJS (dist/index.cjs) build viatsup, with.d.tsfor both. React and both@arraypress/waveform-*cores are externalised so they resolve to the consumer’s copies. - README with full prop reference and usage patterns, and
examples/basic.tsxwith seven copy-paste-ready snippets.
Peer dependencies
Section titled “Peer dependencies”@arraypress/waveform-playlist^1.3.0@arraypress/waveform-player^1.8.0react^18.0.0 || ^19.0.0
@arraypress/waveform-playlist-vue
Section titled “@arraypress/waveform-playlist-vue”[0.1.0] — Unreleased
Section titled “[0.1.0] — Unreleased”Initial release.
<WaveformPlaylist>Vue 3 component wrapping@arraypress/waveform-playlist:- Declarative
tracksprop (with optional per-trackchaptersandmarkers), rendered into the[data-track]/[data-chapter]markup the playlist constructor parses on mount. - Playlist options as typed props:
layout('list' | 'minimal'),continuous,expandChapters,showDuration,showChapterMarkers,chapterMarkerColor,showPlayState. - The full pass-through player-option surface (waveform style, sizing,
colours, playback, UI toggles, accessibility, icons) — inherited from
the core
WaveformPlayerOptionsviaOmit<>, minus per-track content fields (which come fromtracks).
- Declarative
- Imperative navigation API exposed via a template
ref(WaveformPlaylistExpose):selectTrack(),seekToChapter(),nextTrack(),previousTrack(),getPlayer(),getCurrentTrackIndex(),getTracks(), plus the rawinstance. class,style, andidfall through to the host element via Vue’s attribute inheritance; the base classwfp-hostalways applies.- SSR / Nuxt safe: the core library is loaded via dynamic
import('@arraypress/waveform-playlist')insideonMounted. - Identity-prop re-mount: any construction-prop change (a serialised
trackschange, layout, options, …) destroys and rebuilds the instance. A monotonic mount token discards a superseded in-flight import; the watcher usesflush: 'post'so the fresh markup is in the DOM before the constructor re-parses it. - No lifecycle emits — the playlist owns the embedded player’s callbacks
internally (matching the React wrapper). Observe playback via the
embedded player from
getPlayer(). - Public types adopted from both cores (
@arraypress/waveform-playlist+@arraypress/waveform-player), re-exported so they can never drift. - Dual ESM + CJS build via
tsupwith.d.tsfor both. Vue + both cores are peer dependencies. - Vitest test suite (jsdom +
@vue/test-utils) covering host + track markup rendering, option mapping (tracks excluded), boolean-prop omission, destroy-on-unmount, identity-prop re-mount, and the exposed navigation API. The core is mocked at the module boundary.
@arraypress/waveform-playlist-svelte
Section titled “@arraypress/waveform-playlist-svelte”[0.1.0] — Unreleased
Section titled “[0.1.0] — Unreleased”Initial release.
<WaveformPlaylist>Svelte 5 component (built with runes) wrapping@arraypress/waveform-playlist:- Declarative
tracksprop (with optional per-trackchaptersandmarkers), rendered into the[data-track]/[data-chapter]markup the playlist constructor parses on mount. - Playlist options as typed props:
layout('list' | 'minimal'),continuous,expandChapters,showDuration,showChapterMarkers,chapterMarkerColor,showPlayState. - The full pass-through player-option surface (waveform style, sizing,
colours, playback, UI toggles, accessibility, icons) — inherited from
the core
WaveformPlayerOptionsviaOmit<>, minus per-track content fields (which come fromtracks).
- Declarative
- Imperative navigation API exported by the component instance (reachable
via
bind:this):selectTrack(),seekToChapter(),nextTrack(),previousTrack(),getPlayer(),getCurrentTrackIndex(),getTracks(), andgetInstance(). class,style,id, and other element attributes fall through to the host element via...rest; the base classwfp-hostalways applies.- SSR / SvelteKit safe: the core library is loaded via dynamic
import('@arraypress/waveform-playlist')inside a browser-only$effect. - Identity-prop re-mount: a single
$effectreadsJSON.stringify(tracks)- every construction option, so any change destroys and rebuilds the instance over the freshly-rendered markup. A monotonic mount token discards a superseded in-flight import.
- Public types adopted from both cores (
@arraypress/waveform-playlist+@arraypress/waveform-player), re-exported so they can never drift. - Built with
svelte-package(dist/ships the preprocessed.svelte+ generated.d.ts). Svelte + both cores are peer dependencies. - Vitest test suite (jsdom +
@testing-library/svelte) covering host + track markup rendering, option mapping (tracks excluded), boolean-prop omission, destroy-on-unmount, identity-prop re-mount, and the exported navigation API. The core is mocked at the module boundary.