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,110 @@
# @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.
<!-- begin:auto-docs -->
## Documentation tree
- [error-codes](./src/error-codes/error-codes.md) — Defines the closed registry of every error code the `@suaveplan/audio-ir-core` runtime is allowed to throw, plus the `A…
- [error-codes](./src/error-codes/error-codes.md) — Defines the closed registry of every error code the `@suaveplan/audio-ir-core` runtime is allowed to throw, plus the `A…
- [otel](./src/otel/otel.md) — Owns every span, counter, and observable gauge the registry emits. The foundation is the layer that knows about the reg…
- [otel](./src/otel/otel.md) — Owns every span, counter, and observable gauge the registry emits. The foundation is the layer that knows about the reg…
- [registrar](./src/registrar/registrar.md) — `MutableUriPluginRegistrar` is the canonical collector interface every `audio-ir-{family}-plugin-<name>` content packag…
- [registrar](./src/registrar/registrar.md) — `MutableUriPluginRegistrar` is the canonical collector interface every `audio-ir-{family}-plugin-<name>` content packag…
- [registry](./src/registry/registry.md) — In-memory `Map<string, IrManifestEntry>` registry — the central seam between content packages (which register entries)…
- [register-manifest](./src/registry/register-manifest.md) — Thin iterator over `manifest.entries` that calls `registry.register(entry, { manifestSlug: manifest.packageSlug, manife…
- [registry](./src/registry/registry.md) — In-memory `Map<string, IrManifestEntry>` registry — the central seam between content packages (which register entries)…
- [impulse-response](./src/types/impulse-response.md) — Defines the in-memory shape of a fully-decoded impulse response — the value `@suaveplan/audio-ir-loader.load(id)` retur…
- [manifest-entry](./src/types/manifest-entry.md) — Defines the on-the-wire shape of a single entry inside an `IrManifest`. An entry is the smallest unit a content package…
- [manifest](./src/types/manifest.md) — Defines the on-the-wire shape of a complete IR manifest — the package-level contract a content package (e.g. `audio-ir-…
<!-- end:auto-docs -->
## What ships
- `ImpulseResponse` / `IrManifestEntry` / `IrManifest` Zod schemas — all
frozen on parse, with cross-field refinements (ID-prefix coherence,
family coherence, channel-count + duration coherence).
- `createIrRegistry()` → `IrRegistry` with `register`, `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`](./src/types/manifest-entry.md) |
| Manifest schema | `./types` | [`src/types/manifest.md`](./src/types/manifest.md) |
| `ImpulseResponse` schema | `./types` | [`src/types/impulse-response.md`](./src/types/impulse-response.md) |
| `AUDIO_IR.*` codes | `./error-codes` | [`src/error-codes/error-codes.md`](./src/error-codes/error-codes.md) |
| In-memory registry | `./registry` | [`src/registry/registry.md`](./src/registry/registry.md) |
| `registerManifest` helper | `./registry` | [`src/registry/register-manifest.md`](./src/registry/register-manifest.md) |
| OTel instruments | `./otel` | [`src/otel/otel.md`](./src/otel/otel.md) |
| URI plugin registrar | `./registrar` | [`src/registrar/registrar.md`](./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:
```ts
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:
```ts
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`](./src/registrar/registrar.md) for the full
API reference.