first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,76 @@
# FileSinkAdapter
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
`FileSinkAdapter` is the server-tier exit point for `AudioDocument`
instances: it encodes a document through `@suaveplan/audio-codecs` for
the requested format and writes the resulting bytes through the injected
`FsLike` seam. Like `FileSourceAdapter`, the sink owns the
path-sanitisation boundary and exposes both buffered (`save`,
`saveMany`) and streaming (`createWriteStream`) modes.
## Features
- Buffered `save(doc, path, format, opts?)` runs the codec encoder via
`encodeTo`, concatenates the resulting chunks, and writes the file —
creating parent directories implicitly.
- `saveMany(docs, pathFormat, format, opts?)` parallel-encodes a list of
documents, expanding `%d` in the path template per index.
- `createWriteStream(path)` returns a WHATWG `WritableStream<Uint8Array>`
backed by `node:fs.createWriteStream` (or the injected `FsLike`).
- Zod-validated options; failures throw `AUDIO_ENGINE_SERVER.INVALID_OPTIONS`.
- `sanitizePath` runs before any filesystem call.
- Unknown / unregistered format → `AUDIO_ENGINE_SERVER.ENCODE_FAILED`.
- Underlying write errors → `AUDIO_ENGINE_SERVER.IO_FAILED`.
- OpenTelemetry instrumentation — span `file.save`, counter
`audio_engine_bytes_written_total`, histogram
`audio_engine_save_duration_ms`.
## Usage: Basic
```ts
import { FileSinkAdapter } from "@suaveplan/audio-engine-server";
const sink = new FileSinkAdapter();
await sink.save(doc, "/tmp/out.flac", "flac");
```
## Usage: Advanced
```ts
const sink = new FileSinkAdapter({ rootDir: "/var/exports" });
const writer = sink.createWriteStream("session.wav");
await pcmStream.pipeTo(writer);
await sink.saveMany(
[trackA, trackB, trackC],
"stem-%d.wav",
"wav",
{ bitDepth: 24 }
);
```
## API Reference
- `new FileSinkAdapter(options?: FileSinkOptions)` — `fs`, `registry`,
`rootDir` optional.
- `save(doc, path, format, opts?): Promise<void>`
- `saveMany(docs, pathFormat, format?, opts?): Promise<void>`
- `createWriteStream(path): WritableStream<Uint8Array>`
## Implementation Notes
The buffered `save` collects encoder chunks into an array, computes the
total length, and writes a single concatenated buffer; the codec layer
already streams internally so this is a small one-time copy. `saveMany`
substitutes the literal `%d` token in `pathFormat` with the document's
index. Unknown codec formats surface from the codec layer as
`AUDIO_CODECS.NOT_SUPPORTED`; the sink re-throws them as
`AUDIO_ENGINE_SERVER.ENCODE_FAILED` with the offending format in
`context`. Underlying `node:fs` write failures (`EACCES`, `ENOSPC`, etc.)
become `AUDIO_ENGINE_SERVER.IO_FAILED` with the resolved absolute path in
`context`.