@kiruse/typed-events
v1.1.4
Published
Alternate event system designed for TypeScript
Downloads
257
Readme
@kiruse/typed-events
Type-safe event system for TypeScript with result propagation and handler composition.
Installation
npm install @kiruse/typed-eventsUsage
Basic Event
import { Event } from '@kiruse/typed-events';
// First generic: event arguments type
// Second generic: optional result type (propagated through handlers)
const click = Event<{ x: number; y: number }, number>();
// Register handler
const unsub = click((event, args) => {
console.log(`Clicked at ${args.x}, ${args.y}`);
event.result ??= 0;
event.result++; // Increment click count
return; // Can return promise for async events
});
// Emit event
const result = await click.emit({ x: 100, y: 200 });
console.log(result.result); // 1
// Unsubscribe
unsub();One-time Handlers
const event = Event<{ value: string }>();
// Execute handler once, then auto-unsubscribe
event.once((e, args) => {
console.log('First emission:', args.value);
});
// Execute handler once, but only if predicate passes
event.oncePred((e) => e.args.value.startsWith('valid'), (e, args) => {
console.log('Matched:', args.value);
});Waiting for Events
const event = Event<{ id: number }>();
// Wait for next event (any)
const next = await event.wait();
// Wait with timeout (throws on timeout)
try {
await event.wait(5000); // 5 second timeout
} catch {
console.log('Timed out');
}
// Wait for matching predicate
const matched = await event.expect((e) => e.args.id > 100);
// Async convenience methods
const args = await event.async(); // Wait for any event
const args = await event.asyncPred((e) => e.args.id > 100); // Wait for matchingSync Events
Synchronous events that don't return promises:
import { SyncEvent } from '@kiruse/typed-events';
const sync = SyncEvent<{ data: string }>();
sync((e, args) => {
console.log(args.data);
});
// Returns event directly, not Promise
const result = sync.emit({ data: 'test' });Event Composition
Handlers can modify event.result, which accumulates through the handler chain:
const calc = Event<{ a: number; b: number }, number>();
calc((e, args) => {
e.result = args.a + args.b; // 10 + 5 = 15
});
calc((e) => {
e.result *= 2; // 15 * 2 = 30
});
const result = await calc.emit({ a: 10, b: 5 });
console.log(result.result); // 30Event Cancellation
Handlers can mark events as canceled:
const event = Event<{ action: string }>();
event((e, args) => {
if (args.action === 'abort') {
e.canceled = true;
}
});
const result = await event.emit({ action: 'abort' });
console.log(result.canceled); // trueAPI
Event Properties
event.args- Arguments passed to emitevent.result- Accumulated result (starts undefined)event.canceled- Whether any handler canceled the event
Event Methods
event(handler)- Register handler, returns unsubscribe functionevent.once(handler)- Register one-time handlerevent.oncePred(pred, handler)- Register conditional one-time handlerevent.emit(args, result?)- Fire event, returns event instanceevent.wait(timeout?)- Promise resolving on next eventevent.expect(pred, timeout?)- Promise resolving when predicate matchesevent.async()- Promise resolving with args on next eventevent.asyncPred(pred, timeout?)- Promise resolving with args when pred matches
Types
Event<Args, Result>- Async event (default)SyncEvent<Args, Result>- Synchronous eventAsyncEvent<Args, Result>- Alias for EventEventHandler<Args, Result, IsAsync>- Handler function typeEventInstance<Args, Result, IsAsync>- Event instance typeUnsub- Unsubscribe function
License
MIT
