5.0 KiB
register — collector-pattern wiring entrypoint
(no submodules)
Purpose
This module is the only side-effecting entrypoint a consumer ever calls from
@suaveplan/audio-ir-room-plugin-club. It bridges three pieces that exist in
three separate packages: the in-memory IrRegistry from
@suaveplan/audio-ir-core (which holds manifest entries), a
MutableUriPluginRegistrar collector — typically built via
createUriPluginCollector() — that gathers UriPlugins before resolver
construction, and the bundleUriPlugin from
@suaveplan/storage-uri-plugin-bundle (which knows how to read this
package's bundled WAVs).
The package never auto-registers on import — every consumer calls
register(registry, collector) explicitly. Importing the package's barrel
without calling register is a no-op aside from loading the frozen
manifest constant. This matches the side-effect-free contract on all
@suaveplan/audio-ir-* content packages and matches the family-canon
shape established by audio-ir-room-plugin-pool.
Features
- Single call wires both the bundle adapter (via
target.use(plugin)) and the manifest registration (viaregisterManifest). RegisterOptions.fetch?: FetchLikelets Node-tier callers passnodeFileFetchsofile://reads work under undici's globalfetch.- Default
rootUrlresolves to the in-tarballfiles/directory viaimport.meta.url— works in both Node and any modern bundler that preserves package URLs. - No
createPlugin()separate step; noresolver.hasScheme("bundle")structural check; the collector pattern makes both unnecessary. - Errors from
registerManifest(AUDIO_IR.DUPLICATE_ID,AUDIO_IR.ID_PREFIX_MISMATCH, …) pass through verbatim.
Usage: Basic
import {
createIrRegistry,
createUriPluginCollector,
} from "@suaveplan/audio-ir-core";
import { register } from "@suaveplan/audio-ir-room-plugin-club";
import { createStorageUriResolver } from "@suaveplan/storage-uri";
const registry = createIrRegistry();
const collector = createUriPluginCollector();
register(registry, collector);
const resolver = createStorageUriResolver(collector.plugins);
// registry.has("club-club1") === true
// registry.has("club-club2") === true
Usage: Advanced
import {
createIrRegistry,
createUriPluginCollector,
} from "@suaveplan/audio-ir-core";
import { createIrLoader } from "@suaveplan/audio-ir-loader";
import { decodeWav } from "@suaveplan/audio-decode-wav";
import { register } from "@suaveplan/audio-ir-room-plugin-club";
import { createStorageUriResolver } from "@suaveplan/storage-uri";
import { nodeFileFetch } from "@suaveplan/storage-uri-plugin-bundle/node-fetch";
// Node.js: globalThis.fetch refuses file:// — wire nodeFileFetch.
const registry = createIrRegistry();
const collector = createUriPluginCollector();
register(registry, collector, { fetch: nodeFileFetch });
const resolver = createStorageUriResolver(collector.plugins);
const loader = createIrLoader({
registry,
resolver,
decoders: { wav: decodeWav },
});
const club1 = await loader.load("club-club1");
console.log(club1.channelData[0].length, "samples @", club1.sampleRate, "Hz");
API Reference
register(registry: IrRegistry, target: MutableUriPluginRegistrar, options?: RegisterOptions): void
Builds the package-scoped bundleUriPlugin, hands it to target.use(plugin),
then calls registerManifest(registry, manifest).
registry— anIrRegistryfrom@suaveplan/audio-ir-core.target— any object satisfyingMutableUriPluginRegistrar(use(plugin: UriPlugin): void). Typically built viacreateUriPluginCollector().options.fetch?: FetchLike— overrides the runtime fetch (passnodeFileFetchon Node sofile://URLs resolve).
Throws AUDIO_IR.DUPLICATE_ID if any manifest entry is already in the
registry.
interface RegisterOptions
readonly fetch?: FetchLike— see above.
Implementation Notes
new URL("../../files/", import.meta.url) is intentional — the
register/register.ts file lives at src/register/register.ts in the
source tree, and at dist/register/register.js after build. In both
cases two levels up lands on the package root, where files/ sits at
the same level as dist/ and src/. The trailing slash is required by
bundleUriPlugin's rootUrl validator.
The target.use(plugin) call happens before registerManifest(...) so
that even when registerManifest rejects (for example with
AUDIO_IR.DUPLICATE_ID on a double-register), the bundle plugin is
already in the caller's collector. This matches the family-canon
ordering established by audio-ir-room-plugin-pool and keeps the
collector observable when tests inspect it after a thrown error.
The double-register test relies on registerManifest calling
registry.register(entry, ctx) for each entry in declaration order. The
registry throws AUDIO_IR.DUPLICATE_ID on the first colliding id — for
this package, club-club1 — so the rethrown error is deterministic.