Move docs/ package mirror into document-navigator plugin

Relocate the ~6k-file docs tree from the repo root into
plugins/document-navigator/docs/ so the plugin is self-contained and
portable. docs/superpowers/ (specs and plans) stays at the repo root.

Moved via cp+rm rather than git mv because directory rename() fails with
EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the
identical-content files at commit time.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-30 01:10:00 +01:00
parent fe3fedf42e
commit 9bf56a806b
6022 changed files with 12437 additions and 0 deletions

View File

@@ -0,0 +1,123 @@
# `decode/decode-source`
Universal decode entry point — the single function callers use to turn
any `Source` into a decoded `AudioDocument`.
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
`decodeSource` is the top-level public-facing decode API. Callers do
not need to know about codec registries, format detection, or
runtime-gated source resolution — they pass in a `Source` (string,
URL, ArrayBuffer, Uint8Array, or ReadableStream) plus optional
hints/callbacks, and receive a fully-decoded `AudioDocument` from the
default registry (which ships every native + WASM codec).
The companion `progressiveDecode` provides the same surface but is the
hook for future per-chunk-fed decoders that allow editing the
document while decoding is still in progress. The current
implementation falls back to a full-buffer decode for every codec
because none of the native or WASM wrappers expose
`createDecoder` factories yet — the contract is in place so a future
streaming-aware codec can plug in without callers changing their
code.
## Features
- Accepts any `Source` variant — bytes, URL, file path, stream.
- Optional `opts.format` overrides detection (use when callers know
the format and want to skip the magic-byte sniff).
- Optional `opts.budget` projects required memory before allocating
pages — if projection exceeds the budget the call aborts with
`AUDIO_CODECS.BUDGET_EXCEEDED` carrying the projected and budgeted
byte counts in `context`.
- Optional `opts.signal` (AbortSignal) — checked before resolution,
before format detection, and before page allocation. Aborts throw
`AUDIO_CODECS.STREAM_ERROR`.
- Optional `opts.notify()` fires once the first page is materialised;
`opts.ondata(delta)` fires per decoded block delta. Useful for
progress UI on long-running decodes.
- Optional `opts.registry` lets callers inject a pre-configured
`CodecRegistry` (e.g. with extra codecs) instead of using the
default.
- Zod-validated options — invalid `budget` (non-positive number) or
any other schema violation throws `AUDIO_CODECS.INVALID_SOURCE` with
the Zod issue list in `context`.
## Usage: Basic Example
```ts
import { decodeSource } from "@suaveplan/audio-codecs/decode/decode-source";
const doc = await decodeSource(wavBytes);
console.log(doc.sourceLength, doc.sampleRate);
```
## Usage: Advanced Example
Decode a stream with a memory budget, abort signal, and progress
callbacks:
```ts
import { decodeSource } from "@suaveplan/audio-codecs/decode/decode-source";
const ctrl = new AbortController();
const ui = makeProgressUi();
const doc = await decodeSource(
fetch("https://cdn/audio.flac").then((r) => r.body!),
{
budget: 500 * 1024 * 1024, // 500 MB cap
signal: ctrl.signal,
notify: () => ui.startedDecoding(),
ondata: ({ samples }) => ui.updateProgress(samples),
}
);
```
## API Reference
- `interface DecodeSourceOpts { format?, budget?, signal?, notify?,
ondata?, registry? }`.
- `const DecodeSourceOptsSchema` — Zod schema for the options object.
- `async function decodeSource(source: Source, opts?:
DecodeSourceOpts): Promise<AudioDocument>` — throws
`INVALID_SOURCE` for invalid options or unrecognised source values;
`UNKNOWN_FORMAT` if detection finds no codec and `opts.format` is
also missing; `BUDGET_EXCEEDED` if projected memory exceeds
`opts.budget`; `STREAM_ERROR` for AbortSignal cancellation.
- `async function progressiveDecode(source, opts?, registry?):
Promise<AudioDocument>` — same surface as `decodeSource` plus an
optional positional `registry` for callers that prefer not to pass
it via `opts.registry`.
- `re-export CodecRegistry` — convenience so consumers needing custom
codec registration can import it from the same subpath.
## Implementation Notes
- The default registry is constructed lazily via a top-level promise
(`DEFAULT_REGISTRY_PROMISE`) so the side-effects of registering ten
codecs only happen the first time the registry is needed. Imports
of the package barrel itself don't trigger codec registration.
- `opts.signal` is checked at every coarse-grained boundary —
before resolution, after registry availability, before detection.
Codec-internal aborts are codec-specific and not covered by this
function.
- The budget projection uses `sampleRate * channels * sampleCount * 4`
(4 bytes per float32 sample) as an upper bound. For compressed
sources the actual decoded size depends on the codec's expansion
ratio; the projection assumes a conservative 5× expansion of input
bytes which catches the common cases (MP3, FLAC, Opus all
decompress within 5×) without false positives for raw WAV.
- `progressiveDecode` is currently equivalent to `decodeSource` —
the streaming-page-fill behaviour described in the spec
("editable before decode completes") requires codec `createDecoder`
factories which only WAV currently exposes. The function name and
signature reserve the contract so future streaming-aware codecs
drop in without API changes.
- Both functions are async — even when the input is fully in-memory,
format detection and codec dispatch involve at least one microtask
boundary because the codec methods are async.