@onoxm/event
v0.4.4
Published
Event library by Typescript
Downloads
883
Readme
@onoxm/event
A lightweight, type-safe event emitter library for TypeScript.
Features
- Type-safe: Full TypeScript generics support, event names and callback parameter types are automatically inferred.
- Lightweight: Built with private fields (
#), no extra runtime overhead. - Flexible API: Supports both factory function and class usage.
- Global Singleton: Optional singleton mode for cross-module shared event bus.
- Auto Unsubscribe:
on/oncereturn an unsubscribe function for easy cleanup.
Installation
npm install @onoxm/event
# or
pnpm add @onoxm/event
# or
yarn add @onoxm/eventPeer dependency:
@onoxm/utils(required when using global singleton mode).
Usage
1. Factory Function (Recommended)
Use an event map to get full type inference:
import { createEventEmitter } from '@onoxm/event'
const event = createEventEmitter({
LOGIN: {} as [username: string, password: string],
LOGOUT: {} as [reason: string],
CONSOLE: {} as [message: string, level: number],
})
// Emit - parameter types are inferred
event.emit('LOGIN', 'admin', '123456')
// Subscribe - callback parameters are inferred
const off = event.on('LOGIN', (username, password) => {
console.log(`${username} logged in`)
})
// Unsubscribe
off()2. Event Name Array (Weakly Typed)
For quick setup or when types are not a concern:
import { createEventEmitter } from '@onoxm/event'
const event = createEventEmitter(['API:LOGIN', 'API:CONSOLE'] as const)
event.on('API:LOGIN', (...args) => {
console.log('login event', args)
})
event.emit('API:LOGIN', 'admin', '123456')3. Global Singleton Mode
Pass isGlobal: true to share a single instance across modules:
// moduleA.ts
import { createEventEmitter } from '@onoxm/event'
export const event = createEventEmitter({
DATA_UPDATED: {} as [payload: unknown],
}, true) // <-- global singleton
// moduleB.ts (different file)
import { createEventEmitter } from '@onoxm/event'
const event = createEventEmitter({
DATA_UPDATED: {} as [payload: unknown],
}, true)
// Both `event` references point to the same instance,
// so events emitted in moduleA are received in moduleB.
event.on('DATA_UPDATED', (payload) => {
console.log('received', payload)
})API
createEventEmitter(eventMap, isGlobal?)
Creates an event emitter instance with full type inference.
- eventMap:
Record<string, unknown[]>— an object whose keys are event names and values are tuple types describing the callback parameters (use{} as [Tuple]syntax). - isGlobal:
boolean(optional, defaultfalse) — whentrue, returns a singleton instance shared across all calls with the same configuration.
Returns an emitter instance with the methods below.
createEventEmitter(eventNames, isGlobal?)
Overload that accepts an array of event names (weakly typed, callback params are any[]).
- eventNames:
string[] | readonly string[] - isGlobal:
boolean(optional, defaultfalse)
Returns an emitter instance with the methods below.
Emitter Instance Methods
The instance returned by createEventEmitter exposes the following methods:
emit(eventName, ...args)
Emits an event, calling all subscribed callbacks in subscription order.
- Throws if
eventNamewas not pre-registered.
on(eventName, callback)
Subscribes to an event.
- Returns an unsubscribe function: calling it removes the callback (equivalent to
off).
once(eventName, callback)
Subscribes to an event, but the callback is automatically removed after the first invocation.
- Returns an unsubscribe function.
off(eventName, callback)
Removes a specific callback from an event.
clear(eventName?)
- If
eventNameis provided, removes all callbacks for that event. - If
eventNameis omitted, removes all callbacks for all events.
Type Safety
The event-map form provides complete type inference for both emit and on:
const event = createEventEmitter({
LOGIN: {} as [username: string, password: string],
})
// ✅ OK
event.emit('LOGIN', 'admin', '123456')
// ❌ Type Error: too few arguments
event.emit('LOGIN', 'admin')
// ❌ Type Error: wrong type
event.emit('LOGIN', 'admin', 123)
// ✅ Callback params are inferred as (username: string, password: string)
event.on('LOGIN', (username, password) => {
// ...
})License
MIT © ONO
