@bimetal/channel
v0.35.0
Published
Generic pluggable notification-channel abstraction. Domain-agnostic send-to-recipient with a capability model and a zero-dependency template renderer. In-process default, external adapters (Webhook, Slack, Email, SMS, …) implement the same Channel interfa
Maintainers
Readme
@bimetal/channel
Generic pluggable notification-channel abstraction. Domain-agnostic „send-to-recipient" mit Capability-Modell + abhängigkeitsfreiem Template-Renderer. In-Process-Default; externe Adapter (Webhook, Slack, Email, SMS, …) implementieren das gleiche Interface.
Zero external dependencies. Zero @bimetal/* dependencies. Standort im Stack neben @bimetal/broker: beide sind Transport-Primitive, keine domain-spezifischen Packages.
Installation
npm install @bimetal/channelWhat's Inside
Types
Channel<TMessage = ChannelMessage>—send(recipient, message),capabilities, optionalclose(). Adapter hängen NUR hieran, nicht am Alerting-Kern.ChannelMessage—{ subject?, body, meta? }. Pre-rendert; der Channel schickt sie unverändert.ChannelCapabilities—{ batch, retries }. Einzige Quelle der Wahrheit für Adapter-Fähigkeiten.Recipient,Template
Default-Template (zero-dep)
interpolate(template, data)— minimaler{{pfad}}-Renderer, prototype-sicher (Object.hasOwn). Bewusst kein Handlebars/Mustache — das verletzt „zero external deps". Eine App klinkt einen eigenen Renderer über dasTemplate-Interface ein.defaultTemplate—Template-Implementierung überinterpolate.
In-Process-Default
createInProcessChannel(options?)— Test-Collector mitsent()/clear(); optionalerfail-Hook simuliert Zustellfehler. Beweist die Verdrahtung ohne Netzwerk/Credentials.
Geteilter HTTP-Helfer (für die HTTP-Adapter)
httpSend(req, options?)— POST über dasfetch-Global;fetchist injizierbar (HttpSendOptions.fetch), also unit-testbar ohne Netzwerk. Per-Request-Timeout viaAbortController(timeoutMs, Default 10s) — ein hängender Provider blockiert nie den Orchestrator-Tick.ChannelHttpError— Zustellfehler mit HTTP-Status..messageist body-frei (HTTP <status>) — sicher zum Persistieren in einem Event-Log; der gekappte Provider-Body liegt nur auf.detail(transiente Diagnose). Hält Credential-/PII-Echos aus unveränderlichen Logs heraus.
Designprinzipien
- Generic over
TMessage: kein DomainEvent-/Alert-Lock-in. Der Channel kennt weder Event-Sourcing noch Kalender. - Capabilities zuerst: Adapter-Unterschiede (
batch,retries) werden explizit kommuniziert, nicht durch An-/Abwesenheit von Methoden. - Body-freie Fehler: ein non-2xx wirft
ChannelHttpErrormit body-freier message — die Security-Eigenschaft, auf der der Alerting-Fehlervertrag aufsetzt. - Zero-dep Template: der Default-Renderer ist absichtlich minimal; mächtigere Engines sind App-Sache über das Interface.
License
Apache License 2.0
