6.0 KiB
@suaveplan/audio-ir-core - Foundation contract for the @suaveplan audio-ir family: ImpulseResponse / IrManifestEntry / IrManifest Zod schemas, in-memory IrRegistry, AUDIO_IR.* error-code registry, and OpenTelemetry surface. Universal; zero @suaveplan/audio-* runtime deps.
Foundation contract for the @suaveplan/audio-ir-* family. Universal;
zero @suaveplan/audio-* runtime deps. Every sibling package
(audio-ir-loader, audio-ir-{mic,speaker,room}-plugin-<name>) consumes
this package.
Documentation tree
- error-codes — Defines the closed registry of every error code the
@suaveplan/audio-ir-coreruntime is allowed to throw, plus the `A…- error-codes — Defines the closed registry of every error code the
@suaveplan/audio-ir-coreruntime is allowed to throw, plus the `A…
- error-codes — Defines the closed registry of every error code the
- otel — Owns every span, counter, and observable gauge the registry emits. The foundation is the layer that knows about the reg…
- otel — Owns every span, counter, and observable gauge the registry emits. The foundation is the layer that knows about the reg…
- registrar —
MutableUriPluginRegistraris the canonical collector interface everyaudio-ir-{family}-plugin-<name>content packag…- registrar —
MutableUriPluginRegistraris the canonical collector interface everyaudio-ir-{family}-plugin-<name>content packag…
- registrar —
- registry — In-memory
Map<string, IrManifestEntry>registry — the central seam between content packages (which register entries)…- register-manifest — Thin iterator over
manifest.entriesthat calls `registry.register(entry, { manifestSlug: manifest.packageSlug, manife… - registry — In-memory
Map<string, IrManifestEntry>registry — the central seam between content packages (which register entries)…
- register-manifest — Thin iterator over
- impulse-response — Defines the in-memory shape of a fully-decoded impulse response — the value
@suaveplan/audio-ir-loader.load(id)retur… - manifest-entry — Defines the on-the-wire shape of a single entry inside an
IrManifest. An entry is the smallest unit a content package… - manifest — Defines the on-the-wire shape of a complete IR manifest — the package-level contract a content package (e.g. `audio-ir-…
What ships
ImpulseResponse/IrManifestEntry/IrManifestZod schemas — all frozen on parse, with cross-field refinements (ID-prefix coherence, family coherence, channel-count + duration coherence).createIrRegistry()→IrRegistrywithregister,has,get,list,clear.registerManifest(registry, manifest)bulk helper.AUDIO_IR.*error-code registry — exactly five codes, every one reachable from a real production call site.- OpenTelemetry surface —
audio_ir.registrations_total,audio_ir.lookups_total,audio_ir.errors_total,audio_ir.registry_size{family}.
Modules
| Module | Subpath | Docs |
|---|---|---|
| Manifest entry schema | ./types |
src/types/manifest-entry.md |
| Manifest schema | ./types |
src/types/manifest.md |
ImpulseResponse schema |
./types |
src/types/impulse-response.md |
AUDIO_IR.* codes |
./error-codes |
src/error-codes/error-codes.md |
| In-memory registry | ./registry |
src/registry/registry.md |
registerManifest helper |
./registry |
src/registry/register-manifest.md |
| OTel instruments | ./otel |
src/otel/otel.md |
| URI plugin registrar | ./registrar |
src/registrar/registrar.md |
Design
The cross-cutting design for the IR family lives in
That file is the source of truth for the family layering, ID derivation rule, URI strategy, and OTel split.
Quick install
This package is wave-0 foundation — depended on, not depending on, the rest of the audio-ir family. Pull it directly:
import {
createIrRegistry,
IrManifestSchema,
registerManifest,
} from "@suaveplan/audio-ir-core";
const registry = createIrRegistry();
const manifest = IrManifestSchema.parse(rawManifestFromContentPackage);
registerManifest(registry, manifest);
Composing IR content packages
Every audio-ir-{family}-plugin-<name> content package exposes a
register(registry, collector, options?) function. collector is a
MutableUriPluginRegistrar — a one-method object { use(plugin) }. Pre-
construct a collector, call every content package's register(...), then
hand the gathered plugins snapshot to createStorageUriResolver once:
import {
createIrRegistry,
createUriPluginCollector,
} from "@suaveplan/audio-ir-core";
import { register as registerClub } from "@suaveplan/audio-ir-room-plugin-club";
import { register as registerPool } from "@suaveplan/audio-ir-room-plugin-pool";
import { createStorageUriResolver } from "@suaveplan/storage-uri";
const registry = createIrRegistry();
const collector = createUriPluginCollector();
// Each content package calls collector.use(plugin) for every bundle plugin.
registerPool(registry, collector);
registerClub(registry, collector);
// `collector.plugins` is a frozen snapshot — safe to hand off directly.
const resolver = createStorageUriResolver({ plugins: collector.plugins });
The collector is order-preserving and snapshot-frozen, so consumers can
compose multiple content packages — or fan out to multiple resolvers
(parent + inner, sharded, future builder) — without each content package
needing to agree on resolver shape. See
src/registrar/registrar.md for the full
API reference.