3.1 KiB
FileSourceAdapter
(no submodules)
Purpose
FileSourceAdapter is the server-tier entry point for reading audio files
into the universal AudioDocument model. It owns the path-sanitisation
boundary, dispatches to @suaveplan/audio-codecs decodeSource for
format detection and decode, and exposes both buffered (load,
loadMany) and streaming (createReadStream) modes through a single
injectable FsLike seam. The adapter implements no DSP itself — every
byte ends up routed through the universal codec layer.
Features
- Buffered
load(path, opts?)returns anAudioDocumentfrom a local path or anhttp/httpsURL. loadMany(paths, opts?)resolves aPromise.alloverload, preserving input order regardless of decode completion order.createReadStream(path)returns a WHATWGReadableStream<Uint8Array>backed by the injectedFsLike(ornode:fs.createReadStream).- Zod-validated options at every entry point; failures throw
AUDIO_ENGINE_SERVER.INVALID_OPTIONS. sanitizePathrejects empty / null-byte /..-traversal paths against the optionalrootDirboundary before any filesystem call is issued.AbortSignalpropagation — pre-aborted signals short-circuit withAUDIO_ENGINE_SERVER.ABORTED; mid-load aborts surface the same code via the codec layer.- OpenTelemetry instrumentation — span
file.load, counteraudio_engine_bytes_read_total, histogramaudio_engine_load_duration_ms. Inert without an exporter.
Usage: Basic
import { FileSourceAdapter } from "@suaveplan/audio-engine-server";
const source = new FileSourceAdapter();
const doc = await source.load("/tmp/sample.wav");
console.log(doc.sampleRate, doc.channels, doc.sourceLength);
Usage: Advanced
import { FileSourceAdapter, defaultFs } from "@suaveplan/audio-engine-server";
const source = new FileSourceAdapter({
fs: defaultFs,
rootDir: "/var/audio",
registry: customCodecRegistry,
});
const ctrl = new AbortController();
setTimeout(() => ctrl.abort(), 5000);
const docs = await source.loadMany(
["a.wav", "b.flac", "c.mp3"],
{ signal: ctrl.signal }
);
API Reference
new FileSourceAdapter(options?: FileSourceOptions)—fs,fetch,registry,rootDirall optional.load(path, opts?): Promise<AudioDocument>loadMany(paths, opts?): Promise<AudioDocument[]>createReadStream(path): ReadableStream<Uint8Array>
Implementation Notes
load distinguishes URL inputs via isHttpUrl; URL inputs are fetched
through the injected fetch and skip filesystem sanitisation. Local
paths pass through sanitizePath(path, rootDir) before any FsLike
call, so a path-traversal attempt throws INVALID_PATH before the
filesystem is touched. ENOENT from the underlying readFile is mapped
to FILE_NOT_FOUND; any other read error becomes IO_FAILED. Decode
failures from the codec layer are re-thrown as DECODE_FAILED unless the
inner error reports a stream abort, in which case the engine maps it to
AUDIO_ENGINE_SERVER.ABORTED to preserve the signal-aborted contract.