6.3 KiB
6.3 KiB
Tasks: enterprise-audio-engine-browser
Change ID: enterprise-audio-engine-browser
Package: @suaveplan/audio-engine-browser
Target path: packages/audio/audio-engine-browser
Prerequisite packages on Verdaccio: @suaveplan/audio-core, @suaveplan/audio-timeline, @suaveplan/audio-transport, @suaveplan/audio-fx-plugin-base, @suaveplan/error, @suaveplan/events
1. Scaffold
- Create directory
packages/audio/audio-engine-browser/withsrc/,tests/,src/__benchmarks__/, and all feature subdirectories per the layout inproposal.md. - Write
package.jsonat version0.1.0with"type": "module","sideEffects": false, fullexportsmap, deps:@suaveplan/audio-core workspace:^,@suaveplan/audio-timeline workspace:^,@suaveplan/audio-transport workspace:^,@suaveplan/audio-fx-plugin-base workspace:^,@suaveplan/error workspace:^,@suaveplan/events workspace:^,standardized-audio-context. - Write
tsconfig.jsonextending@suaveplan/typescript-config/library.json. - Write
vitest.config.tsusingcreateTestConfig()from@suaveplan/testing/configwithhappy-domenvironment. - Add
lint,typecheck,test,test:coverage,build,docs:checkscripts.
2. Types + errors
- Write
src/adapter/browser-adapter.types.ts—BrowserAdapterOptions. - Write
src/graph/web-audio-graph.types.ts—AudioGraphSnapshot,AudioNodeType. - Write
src/worklet/worklet-manager.types.ts—WorkletManagerOptions,WorkletModuleOptions. - Write co-located
.mdfiles for each types module (≥200 words). - Write
src/error-codes.ts—defineCodes("AUDIO_ENGINE_BROWSER", [...])producingAUDIO_ENGINE_BROWSER.*code strings; exportBrowserAudioErrorCode,AUDIO_ENGINE_BROWSER_ERROR_METADATA,registerBrowserAudioErrorCodes(), and aBrowserAudioErrorclass extendingAudioErrorfrom@suaveplan/audio-core. - Write Zod schemas:
BrowserAdapterOptionsSchema,WorkletManagerOptionsSchema,WorkletModuleOptionsSchema,AudioGraphSnapshotSchema.
3. WebAudioGraph
- Implement
WebAudioGraphinsrc/graph/web-audio-graph.ts:addNode,removeNodewith ID-based registry.connect/disconnectwrappingAudioNode.connect/disconnect.snapshot()returns serializableAudioGraphSnapshot.restore(snapshot)recreates nodes and connections from a snapshot.
- Write
web-audio-graph.test.tsandweb-audio-graph.md.
4. AudioWorkletManager
- Implement
AudioWorkletManagerinsrc/worklet/worklet-manager.ts:addModulewith URL allow-list check.createNodereturnsAudioWorkletNode.postMessage/onMessagefor processor communication.isLoadedtracks loaded module URLs.
- Write
worklet-manager.test.tsandworklet-manager.md.
5. Html5AudioFallback
- Implement
Html5AudioFallbackinsrc/fallback/html5-fallback.ts:- Implements
TimelineAdapterusingHTMLAudioElement. - Supports: play, pause, seek, volume, loop.
- No FX, no analysis, no precise scheduling.
- All other adapter methods are no-ops or throw
BrowserAudioErrorfor unsupported operations.
- Implements
- Write
html5-fallback.test.tsandhtml5-fallback.md.
6. BrowserTimelineAdapter
- Implement
BrowserTimelineAdapterinsrc/adapter/browser-adapter.ts:init()createsAudioContextviastandardized-audio-context(or uses injectedcontext) and resumes it.setTracks,addTrack,removeTrack,updateTrackbuild per-track subgraphs:AudioBufferSourceNode→GainNode(clip) →GainNode(track) →StereoPannerNode→DynamicsCompressorNode→GainNode(master) →AnalyserNode→ destination.play,pause,stop,seekdriveAudioBufferSourceNodescheduling.- Mute/solo logic: when any track is soloed, all non-soloed tracks have gain set to 0.
setLoop,setMasterVolume,setTrackVolume,setTrackMute,setTrackSolo,setTrackPan,setTempoupdate graph parameters.lookAheadandppqnexposed as readonly properties.dispose()closes context and releases all nodes.
- Write
browser-adapter.test.ts(≤500 lines): init with injectedOfflineAudioContext, set tracks, play/stop, track volume/pan, mute/solo logic, loop, dispose. - Write
browser-adapter.md.
7. Offline render
- Implement
renderOfflineinsrc/offline/offline-render.ts:- Creates
OfflineAudioContextviastandardized-audio-context. - Instantiates
BrowserTimelineAdapterwith injected offline context. - Attaches adapter to
TimelineEngine, plays from 0, and returns renderedAudioBuffer.
- Creates
- Write
offline-render.test.tsandoffline-render.md.
8. FX plugin hosting
- Implement
createFxNodeutility insrc/adapter/browser-adapter.ts(or separatefx-host.tsif needed):- AudioNode path:
plugin.createAudioNode(context)returns nativeAudioNodechain. - Worklet path:
plugin.createWorkletProcessor()returns processor code; host wraps inAudioWorkletNodeviaAudioWorkletManager. - Fallback path:
ScriptProcessorNodewrapping block processor for main-thread fallback.
- AudioNode path:
- Write unit tests for all three FX hosting paths.
9. Benchmarks
- Write
src/__benchmarks__/graph.bench.ts— add 100 nodes, connect 200 edges, snapshot + restore. - Write
src/__benchmarks__/worklet.bench.ts— load 10 worklet modules, create 50 nodes.
10. Integration tests
- Write
tests/integration.test.ts— full browser adapter lifecycle with injectedOfflineAudioContext: init, set tracks with clips, play, verify graph structure, mute/solo behavior, offline render returnsAudioBufferwith expected length.
11. Docs + verify + publish
- All co-located
.mdfiles (≥200 words each). - Write
README.mdat package root. bunx turbo lint typecheck test --filter=@suaveplan/audio-engine-browser— green.bunx turbo test:coverage --filter=@suaveplan/audio-engine-browser— 100%.bun scripts/publish.ts --package @suaveplan/audio-engine-browser.- Fold
specs/audio-engine-browser/spec.mdintoopenspec/specs/audio-engine-browser/spec.md. - Archive to
openspec/archive/2026-05-14-enterprise-audio-engine-browser/.