Initial Commit
This commit is contained in:
75
openspec/archive/2026-05-02-events-v1.1.0-port/proposal.md
Normal file
75
openspec/archive/2026-05-02-events-v1.1.0-port/proposal.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# `@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`/`off` instead of `for 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 for `once` registrations.
|
||||
- No concurrency control on `emitAsync` — one slow listener blocks the chain.
|
||||
- No `maxListeners` warning — memory leaks go undetected.
|
||||
- No global `errorSink` — caller must inspect `EmitResult.errors` or errors are lost.
|
||||
- No `Symbol.dispose` — no RAII cleanup via `using`.
|
||||
|
||||
These gaps force consumers to reinvent the missing primitives downstream.
|
||||
|
||||
---
|
||||
|
||||
## What changes
|
||||
|
||||
### Core `EventBus` additions
|
||||
|
||||
1. **`bufferSize` option** — replays the last N events to subscribers that attach after emission.
|
||||
2. **`wildcard` option** — subscribe to `plugin:*` and match all `plugin:ready`, `plugin:error`, etc.
|
||||
3. **`iter(type, signal?)`** — async iterable over events, compatible with `for await`.
|
||||
4. **`prepend(type, listener)`** — insert listener at the head of the dispatch queue.
|
||||
5. **`listeners(type)` / `listenerCount(type)`** — introspection without exposing internals.
|
||||
6. **`offAll(type?)`** — remove all listeners for a type, or everything.
|
||||
7. **`once()` WeakMap tracking** — `off(type, originalListener)` works for `once` registrations.
|
||||
8. **`concurrency` option on `emitAsync`** — `sequential` (default), `parallel`, `allSettled`.
|
||||
9. **`maxListeners` + `errorSink`** — warnings and centralised error routing.
|
||||
10. **`Symbol.dispose`** on `EventBus` and `Unsubscribe` handles.
|
||||
11. **`EVENTS.LISTENER.MAX_EXCEEDED`** error code.
|
||||
|
||||
### Non-goals
|
||||
|
||||
- No breaking changes to existing `EventBus` API.
|
||||
- No `BoundedQueue` integration into `EventBus` dispatch — 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 (uses `EventBus` directly, doesn't touch changed surface)
|
||||
- `@suaveplan/network` — no action needed (uses `EventBus` + `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.
|
||||
Reference in New Issue
Block a user