Initial Commit
This commit is contained in:
110
packages/media/audio-ir/audio-ir-core/README.md
Normal file
110
packages/media/audio-ir/audio-ir-core/README.md
Normal 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.
|
||||
|
||||
Reference in New Issue
Block a user