Files
suaveplan/openspec/changes/archive/2026-05-15-enterprise-audio-sprite-packer/tasks.md
2026-05-27 23:29:53 +01:00

4.0 KiB
Raw Blame History

Tasks: enterprise-audio-sprite-packer

Change ID: enterprise-audio-sprite-packer Package: @suaveplan/audio-sprite-packer Target path: universal/compression/audio-sprite-packer Prerequisite packages on Verdaccio: @suaveplan/error, @suaveplan/types, @suaveplan/mime, @suaveplan/crypto-utils


1. Scaffold

  • Create directory universal/compression/audio-sprite-packer/ with src/, tests/, src/__benchmarks__/, and all feature subdirectories per the layout in proposal.md.
  • Write package.json at version 0.1.0 with "type": "module", "sideEffects": false, full exports map, deps: @suaveplan/error workspace:^, @suaveplan/types workspace:^, @suaveplan/mime workspace:^, @suaveplan/crypto-utils workspace:^, zod catalog:forms, @opentelemetry/api catalog:observability.
  • Write tsconfig.json extending @suaveplan/typescript-config/library.json.
  • Write vitest.config.ts using createTestConfig() from @suaveplan/testing/config.
  • Add lint, typecheck, test, test:coverage, build, docs:check scripts.

2. Types + errors

  • Write src/types/common.ts — AudioFormat, AudioClipInput, AudioSpriteEntry, AudioSpriteManifest, AudioSprite, PackOptions, AudioAdapter, AudioSpritePackerOptions.
  • Write src/types/common.md.
  • Write src/error-codes.ts — AudioSpriteErrorCode, AUDIO_SPRITE_ERROR_METADATA, registerAudioSpriteErrorCodes().
  • Write Zod schemas: AudioSpriteEntrySchema, AudioSpriteManifestSchema, PackOptionsSchema, AudioSpritePackerOptionsSchema.

3. NullAudioAdapter

  • Implement NullAudioAdapter — probe returns configurable fixture metadata (WAV, 44100 Hz, 2ch, 1.0 s), decode returns 44100 × 2 float32 zeros, encode returns input bytes, stripSilence returns input unchanged, normalise returns input unchanged.
  • Write null-adapter.test.ts and null-adapter.md.

4. Manifest utilities

  • Implement buildManifest(entries, packedBuffer): AudioSpriteManifest — assembles manifest including SHA-256 content hash via @suaveplan/crypto-utils.
  • Implement validateManifest(manifest): void — checks version, entries array non-empty, offsets non-overlapping.
  • Write manifest.test.ts and manifest.md.

5. AudioSpritePacker

  • Implement AudioSpritePacker.pack(clips, options, signal):
    1. Validate clips non-empty.
    2. For each clip: detect format (@suaveplan/mime), probe, decode PCM.
    3. If stripSilence, call adapter.stripSilence.
    4. If normalise, call adapter.normalise.
    5. Append silence padding (zero-fill float32 × sampleRate × silencePaddingMs / 1000).
    6. Encode all clips concatenated as single output buffer.
    7. Build manifest with byte offsets per clip.
    8. Return { data, manifest }.
  • Implement AudioSpritePacker.unpack(sprite, clipName) — slice-and-return using manifest offsets.
  • Wire AbortSignal propagation; throw on abort.
  • Wire OTel: span audio-sprite.pack, counter, histogram, compression ratio.
  • Write audio-sprite-packer.test.ts (≤500 lines): pack 3 clips, unpack each, abort, empty clips throws.
  • Write audio-sprite-packer.md.

6. Benchmarks

  • Write src/__benchmarks__/audio-sprite-packer.bench.ts — pack 10 clips, pack 50 clips (null adapter).

7. Tests

  • Write tests/integration.test.ts — full pack/unpack round-trip.
  • Write tests/property.test.ts (fast-check) — manifest entry count = clip count, unpack returns correct slice, silence padding duration.

8. Docs + verify + publish

  • All co-located .md files (≥200 words each).
  • Write README.md at package root.
  • bunx turbo lint typecheck test --filter=@suaveplan/audio-sprite-packer — green.
  • bunx turbo test:coverage --filter=@suaveplan/audio-sprite-packer — 100%.
  • bun scripts/publish.ts --package @suaveplan/audio-sprite-packer.
  • Archive to openspec/archive/2026-04-24-enterprise-audio-sprite-packer/.