Standard library / events · on the one-page reference
events
Experimental — new this milestone, not yet covered by the conformance suite; manually smoke-tested only. Pure in-memory state, no syscalls, works identically on native and WebAssembly.
A statically-typed EventEmitter<T>,
built the same way Map/Set are (a real,
dedicated type, not a plain class). A practical subset of
Node's
events module, with one necessary departure: Node lets
one emitter mix wildly different listener payload types across
event names ('data' gets a Buffer, 'error'
gets an Error) with no static checking at all. Lumen can't express that
without reflection, so every event name on one
EventEmitter<T> instance shares the same payload type
T — event names are still real string keys, just
constrained to one shared type. A program that genuinely needs
different payload shapes creates two separate emitters (or wraps both
shapes in one union/record T).
~3.5× faster than Node's native
EventEmitter on a tight emit loop: 10M emit()
calls to one listener, compiled with --release-fast,
measured around 43ms versus Node 20's ~160ms for the equivalent loop.
No hidden-class/property-lookup machinery to warm up (a native binary
starts at full speed), and listener dispatch goes through a plain
function-pointer call rather than V8's more general call machinery.
| API | Notes |
|---|---|
new EventEmitter<T>() | construct an emitter for payload type T |
.on(name, listener) | (string, (T) => void) → void — registers a listener |
.once(name, listener) | (string, (T) => void) → void — fires at most once, then is dropped |
.emit(name, value) | (string, T) → void — calls every listener for name, in registration order |
.removeAllListeners(name?) | (string?) → void — clears one name, or every name if omitted |
.listenerCount(name) | string → int |
function onGreeting(msg: string): void {
console.log(msg);
}
const emitter = new EventEmitter<string>();
emitter.on("greet", onGreeting);
emitter.emit("greet", "hello"); // hello
console.log(emitter.listenerCount("greet")); // 1
Not guaranteed-safe: adding or removing a listener for the same event name from inside one of that name's own listeners, while it's still being emitted. Straightforward use (register listeners up front, emit later) is unaffected.