3.7 KiB
3.7 KiB
@suaveplan/events v1.1.0 — Port Missing Capabilities from Suaveplan
Status: Active
Target: @suaveplan/events 0.0.0 → additive capabilities, no breaking changes
Source: /home/ubuntu/web/suaveplan/openspec/changes/events-v1.1.0/
Why
The genesis EventBus was a cut-down redesign of suaveplan's EventEmitter. While it introduced improvements (interceptor API, BoundedQueue, idempotent listeners, deterministic injection), it was missing several capabilities that suaveplan had already proven necessary:
- No event buffering for late subscribers — plugins attaching after lifecycle transitions miss historical events.
- No wildcard pattern matching — observers must enumerate every event name.
- No async iteration — consumers manually manage
on/offinstead offor await. - No
prependListener— impossible to insert a listener at the head. - No listener introspection —
listeners()/listenerCount()absent. - No
once()→off()round-trip —off(type, originalListener)fails foronceregistrations. - No concurrency control on
emitAsync— one slow listener blocks the chain. - No
maxListenerswarning — memory leaks go undetected. - No global
errorSink— caller must inspectEmitResult.errorsor errors are lost. - No
Symbol.dispose— no RAII cleanup viausing.
These gaps force consumers to reinvent the missing primitives downstream.
What changes
Core EventBus additions
bufferSizeoption — replays the last N events to subscribers that attach after emission.wildcardoption — subscribe toplugin:*and match allplugin:ready,plugin:error, etc.iter(type, signal?)— async iterable over events, compatible withfor await.prepend(type, listener)— insert listener at the head of the dispatch queue.listeners(type)/listenerCount(type)— introspection without exposing internals.offAll(type?)— remove all listeners for a type, or everything.once()WeakMap tracking —off(type, originalListener)works foronceregistrations.concurrencyoption onemitAsync—sequential(default),parallel,allSettled.maxListeners+errorSink— warnings and centralised error routing.Symbol.disposeonEventBusandUnsubscribehandles.EVENTS.LISTENER.MAX_EXCEEDEDerror code.
Non-goals
- No breaking changes to existing
EventBusAPI. - No
BoundedQueueintegration intoEventBusdispatch — remains a standalone utility. - No changes to companion packages (
events-otel,events-schema,events-metrics,events-transport) unless required by API additions.
Impact
Affected dependents
Run bunx turbo ls --filter=...@suaveplan/events to enumerate. All additive surface, so no downstream code changes required. Verified by running downstream test suites.
@suaveplan/crypto-vault— no action needed (usesEventBusdirectly, doesn't touch changed surface)@suaveplan/network— no action needed (usesEventBus+BoundedQueue, unchanged)@suaveplan/storage— no action needed@suaveplan/packer— no action needed@suaveplan/fsm— no action needed@suaveplan/retry— no action needed@suaveplan/migration— no action needed (type-only import)@suaveplan/config— no action needed@suaveplan/events-schema— no action needed (type-only import)@suaveplan/events-metrics— no action needed (type-only import)@suaveplan/events-otel— no action needed (type-only import)@suaveplan/events-transport— no action needed (type-only import)
Migration
No migration needed — purely additive.