# `binary` _(no submodules)_ ## Purpose This module owns ffmpeg-binary discovery for `@suaveplan/audio-codec-ffmpeg-native`. It implements a fixed four-step precedence chain — caller-supplied provider, explicit absolute path, dynamically imported `@ffmpeg-installer/ffmpeg` optional dependency, then PATH-based discovery — and memoises successful resolutions by options-object identity so that high-traffic decode/encode pipelines pay the resolution cost exactly once per shared options bundle. The resolver throws `AudioCodecFfmpegNativeError("AUDIO_CODEC_FFMPEG_NATIVE.BINARY_MISSING")` when every step fails, which lets the codec surface an actionable error to the caller instead of waiting for a downstream `ENOENT` from `child_process.spawn`. ## Features - Strict precedence: provider → explicit path → installer → PATH lookup. - Promise-returning provider supported (sync providers also accepted). - Dynamic `import("@ffmpeg-installer/ffmpeg")` so the optional dependency is never a hard requirement at module load. - Test-injectable `installerLoader` and `pathLookup` hooks decouple resolution from real filesystem state. - `BINARY_MISSING` error code on full-chain failure with no leaked stack from the underlying optional-dep failure. - WeakMap-keyed memoisation that automatically GCs entries when the caller drops their options reference. ## Usage: Basic ```ts import { resolveBinary } from "@suaveplan/audio-codec-ffmpeg-native/binary/binary"; const { path, source } = await resolveBinary(); console.log(`Using ffmpeg at ${path} via ${source}`); ``` ## Usage: Advanced ```ts import { resolveBinary } from "@suaveplan/audio-codec-ffmpeg-native/binary/binary"; const opts = { binaryProvider: async () => process.env.FFMPEG_PATH ?? "", binaryPath: "/usr/local/bin/ffmpeg", installerLoader: async () => ({ path: "/opt/ffmpeg" }), pathLookup: () => "/usr/bin/ffmpeg", } as const; const first = await resolveBinary(opts); const second = await resolveBinary(opts); // memoised — no re-resolution. ``` ## API Reference - `resolveBinary(opts?): Promise` — returns `{ path, source }`. - `BinaryResolverOptions` — `binaryProvider`, `binaryPath`, `installerLoader`, `pathLookup` (all optional; first match wins per the precedence chain). - `ResolvedBinary.source` — `"provider" | "explicit" | "installer" | "path"`. ## Implementation Notes The four-step chain is hard-coded — there is no plugin slot — because deviation in precedence would silently change which binary actually runs on production servers. Empty strings are treated as "miss" so callers can write `() => ""` in a provider to opt into the next strategy without throwing. The installer is imported via dynamic `import()` because static imports would make `@ffmpeg-installer/ffmpeg` a hard dependency rather than the optional one the spec requires. Any failure inside the installer load (missing module, platform mismatch, exec-bit stripped) is swallowed and the chain advances — the only surfaced error is `BINARY_MISSING` after the entire chain misses. Memoisation uses a `WeakMap` keyed by the options object reference; callers who want forced re-resolution pass a fresh options bundle.