Registries & Layers
A registry is an immutable collection of capability bindings. registry()
makes an empty one; .layer() and .augment() each return a new registry
with the binding added: the original is never touched. You build registries up,
then hand them to scope() or mycl().
A layer is one binding
Section titled “A layer is one binding”.layer(capability, value) binds a single capability: one layer. Because
every call returns a fresh registry, chaining .layer(...).layer(...) simply
threads each new registry into the next call. Nothing mutates, so you can branch
off a shared base and the branches stay independent.
Inspecting a registry
Section titled “Inspecting a registry”A registry has two read-only methods for introspection, useful in tests, tooling, and debugging:
.has(capability)returns whether the registry binds that capability..bindings()returns aReadonlyMapof every binding, keyed by capability.
Composing registries
Section titled “Composing registries”Registries compose: pass several to mycl() or scope() and they fold into
one resolved registry, the form a scope dispatches against. When two
registries bind the same capability, the later one wins; augments accumulate
across all of them. Don’t confuse composition with .layer(): .layer() adds
one binding to one registry, while composition combines whole registries.
(The primitive underneath, merge, lives on @mycl/core/factory for
kernel authors; the everyday surface composes
for you.)
Testing without mocks
Section titled “Testing without mocks”Immutability makes a registry the natural test seam. Keep the code under test exactly as it ships and bind a test registry that swaps its I/O capabilities for in-memory stand-ins. No mock library, no module patching: the capability surface is the seam.
The example passes only because both swaps took: if the test registry missed
sendEmail, the real default would throw. That is the seam doing its job.
Where next
Section titled “Where next”- Factories: bundle registries once and build instances with
mycl(). - Layer strategies: make multiple bindings for one capability combine instead of overwrite.
- Scopes: how a resolved registry becomes active at call time.