@nhtio/adk/batteries/media/contracts
Generic engine contracts for the media pipeline battery — the seams every implementation (bundled or BYO) plugs into.
Remarks
Engines are seams, not policies. An engine is a self-declaring capability provider: it states exactly which transforms it supports — ConvertCapability edges (input MIME patterns to output format tokens), MutateCapability groups (same-format content transforms), and EditCapability groups (structural document operations) — and the pipeline dispatches against those declarations. There are only three capability shapes because there are only three things a media engine ever does: change the format, change the content, or restructure the document. OCR is a convert (image to text). Transcription is a convert (PCM to text). Decoding audio is a convert (container to PCM). Generating a blank file is a convert (from EMPTY_MIME — the source format happens to be nothing). Resizing is a mutate. Inserting a worksheet row is an edit. A new capability is a new edge in the data, never a new contract.
Engines are supplied to createMediaPipeline as a flat ordered array and resolved eagerly at construction (declarations drive verb narrowing, so they must be known up front). Bundled engines stay cheap to resolve: their heavy peer dependencies load lazily inside the capability methods, on first actual use.
All contracts are duck-typed: validation guards check structure, not class identity, so a consumer can implement an interface from scratch or adapt an existing client. Contracts are enforced at runtime — construction validates every engine and every declared capability and throws E_INVALID_MEDIA_PIPELINE_CONFIG naming the offending index when a value fails.
Two further contracts exist so that even "run a binary" and "give a binary a file" are movable seams rather than Node assumptions:
- BinaryExecutor — how an invocation runs. The bundled
execa_executorwraps execa; a browser/remote/sandbox executor satisfies the same contract. - ScratchWorkspace — bytes ⇄ executor-visible paths. A sibling of
ByteStore, NOT aByteStore: byte stores promise in-process readers, while binaries are foreign processes that need real paths. The bundledfs_workspaceusesnode:fs/promisesvia an async resolver; any implementation whose paths the chosen executor can see is valid — that compatibility is the consumer's composition decision.
Interfaces
| Interface | Description |
|---|---|
| AsrConvertOptions | Options understood by transcription-flavored converts (PCM_MIME → txt/srt/vtt/json). |
| BinaryExecResult | The settled result of a BinaryExecutor.exec call. |
| BinaryExecutor | Runs a binary invocation to completion. How and where it runs — local child process, remote runner, sandbox, container, a browser-side WASI shim — is the implementation's business. |
| BinaryInvocation | A single binary invocation handed to a BinaryExecutor. |
| ConvertCapability | One uniform block of an engine's conversion matrix: every format token in to is producible from every input matching from. |
| ConvertOptions | The options bag carried by a ConvertRequest — one typed, augmentable interface merging every documented convention. |
| ConvertOutput | One output of a convert — most converts yield exactly one; images yields many. |
| ConvertRequest | A format-changing request handed to a ConvertCapability. |
| ConvertResult | The settled result of a convert. |
| EditCapability | A structural document-editing capability group: every op in ops is applicable to every input matching over. |
| EditRequest | A structural document operation handed to an EditCapability: one named op with its verb-table args, applied to in-memory bytes. Unlike the fused MutateRequest (which folds adjacent image transforms into one decode/encode), edits run one op per request — a worksheet splice is not a pixel pass and gains nothing from fusion. |
| EditResult | The settled result of an edit: the restructured bytes plus optional change counts. |
| EditSummary | Counts an edit reports back for result summaries. |
| EngineBytesResult | Common result shape for engines that transform bytes to bytes. |
| ImagesConvertOptions | Options understood by embedded-image extraction converts (application/pdf → images). |
| MediaEngine | A self-declaring media engine: an id for error messages plus the capabilities it provides. At least one capability entry is required. |
| MutateCapability | A same-format content-transform capability group. |
| MutateRequest | A same-format content transform handed to a MutateCapability — the fused image request: adjacent image.* steps fold into ONE request so a resize→rotate→format chain costs a single decode/encode. |
| OcrConvertOptions | Options understood by OCR-flavored converts (image/* → txt/hocr/json). |
| ScratchWorkspace | Bytes ⇄ executor-visible paths. The seam that lets binary-backed engines exchange files with the process (or remote runner) that executes them. |
Type Aliases
| Type Alias | Description |
|---|---|
| EngineResolver | A value-or-resolver: the canonical way to supply an engine. Resolvers may be sync or async (dynamic import) and may resolve to the value directly or a { default: value } module namespace. Engine resolvers run eagerly at pipeline construction — the engine module itself is cheap; heavy peer dependencies load lazily inside capability methods. |
| MimePattern | An input-matching pattern: an exact MIME type (application/pdf), a family wildcard (image/*), or a virtual MIME such as PCM_MIME. |
| ScratchWorkspaceFactory | A factory for per-execution scratch workspaces. Engines mint one workspace per invocation so concurrent executions never share a directory. |
Variables
| Variable | Description |
|---|---|
| EMPTY_MIME | The virtual source MIME type for media generation — the single seam through which new media comes into existence. An engine that can mint a blank/seed file declares converts: [{ from: [EMPTY_MIME], to: [...] }] and receives a ConvertRequest with zero bytes; the format token in to names what gets created. |
| PCM_MIME | The virtual MIME type for decoded mono PCM audio — the intermediate between an audio container and a transcription. Bytes are little-endian Float32 samples in [-1, 1]; a ConvertOutput carrying PCM must set meta.sampleRate (Hz). |
Functions
| Function | Description |
|---|---|
| bytesToPcm | Read PCM samples back out of transport bytes. |
| implementsBinaryExecutor | true when value structurally implements BinaryExecutor. |
| implementsConvertCapability | true when value structurally implements ConvertCapability. |
| implementsEditCapability | true when value structurally implements EditCapability. |
| implementsMediaEngine | true when value structurally implements MediaEngine: a string id plus at least one well-formed capability entry. Every declared entry must pass its capability guard. |
| implementsMutateCapability | true when value structurally implements MutateCapability. |
| implementsScratchWorkspace | true when value structurally implements ScratchWorkspace. |
| pcmToBytes | Pack PCM samples into transport bytes for a ConvertOutput. |