or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

async-iteration.mddebug-system.mdevent-emission.mdevent-subscription.mdindex.mdutilities.md
tile.json

event-subscription.mddocs/

Event Subscription

Core subscription functionality for listening to events with various patterns including single events, multiple events, and wildcard subscriptions.

Capabilities

Event Listener Registration

Subscribe to one or more events with automatic type safety and optional abort signal support.

/**
 * Subscribe to one or more events
 * @param eventName - Single event name or array of event names to listen for
 * @param listener - Function to call when events are emitted
 * @param options - Optional configuration with AbortSignal for cancellation
 * @returns Function to unsubscribe from the events
 */
on<Name extends keyof AllEventData>(
  eventName: Name | readonly Name[],
  listener: (eventData: AllEventData[Name]) => void | Promise<void>,
  options?: {signal?: AbortSignal}
): UnsubscribeFunction;

Usage Examples:

import Emittery from "emittery";

const emitter = new Emittery();

// Single event subscription
const unsubscribe = emitter.on('user-login', (user) => {
  console.log(`User ${user.name} logged in`);
});

// Multiple event subscription
emitter.on(['user-login', 'user-logout'], (data) => {
  console.log('User activity:', data);
});

// With AbortSignal for cancellation
const controller = new AbortController();
emitter.on('data', handleData, {signal: controller.signal});

// Cancel subscription
controller.abort();

// Manual unsubscription
unsubscribe();

One-Time Event Subscription

Subscribe to events that automatically unsubscribe after the first matching emission.

/**
 * Subscribe to one or more events only once
 * @param eventName - Single event name or array of event names
 * @param predicate - Optional filter function to conditionally handle events
 * @returns Promise that resolves with event data, extended with off() method
 */
once<Name extends keyof AllEventData>(
  eventName: Name | readonly Name[],
  predicate?: (eventData: AllEventData[Name]) => boolean
): EmitteryOncePromise<AllEventData[Name]>;

Usage Examples:

import Emittery from "emittery";

const emitter = new Emittery();

// Simple one-time subscription
const userData = await emitter.once('user-created');
console.log('New user:', userData);

// Multiple events - resolves on first match
const activity = await emitter.once(['login', 'logout']);

// With predicate filtering
const validUser = await emitter.once('user-data', (user) => user.isValid);

// Manual cancellation
const promise = emitter.once('long-operation');
setTimeout(() => promise.off(), 5000); // Cancel after 5 seconds

Wildcard Event Subscription

Subscribe to be notified about any event emitted by the emitter instance.

/**
 * Subscribe to be notified about any event
 * @param listener - Function called for every event with event name and data
 * @param options - Optional configuration with AbortSignal for cancellation
 * @returns Function to unsubscribe from all events
 */
onAny(
  listener: (eventName: keyof EventData, eventData: EventData[keyof EventData]) => void | Promise<void>,
  options?: {signal?: AbortSignal}
): UnsubscribeFunction;

Usage Examples:

import Emittery from "emittery";

const emitter = new Emittery();

// Log all events
const unsubscribeAll = emitter.onAny((eventName, data) => {
  console.log(`Event "${eventName}":`, data);
});

// With AbortSignal
const controller = new AbortController();
emitter.onAny((eventName, data) => {
  // Handle any event
}, {signal: controller.signal});

// Stop listening to all events
unsubscribeAll();

Remove Wildcard Subscription

Remove a previously registered onAny subscription.

/**
 * Remove an onAny subscription
 * @param listener - The exact listener function passed to onAny
 */
offAny(
  listener: (eventName: keyof EventData, eventData: EventData[keyof EventData]) => void | Promise<void>
): void;

Usage Examples:

import Emittery from "emittery";

const emitter = new Emittery();

const anyListener = (eventName, data) => {
  console.log(`Event: ${eventName}`, data);
};

emitter.onAny(anyListener);

// Later remove the specific listener
emitter.offAny(anyListener);

Meta Events

Emittery provides special meta-events that fire when listeners are added or removed:

// Available as static properties
static readonly listenerAdded: unique symbol;
static readonly listenerRemoved: unique symbol;

Usage Examples:

import Emittery from "emittery";

const emitter = new Emittery();

// Track when listeners are added
emitter.on(Emittery.listenerAdded, ({listener, eventName}) => {
  console.log(`Listener added for event: ${eventName}`);
});

// Track when listeners are removed
emitter.on(Emittery.listenerRemoved, ({listener, eventName}) => {
  console.log(`Listener removed for event: ${eventName}`);
});

// These will trigger the meta events
emitter.on('test', () => {});
emitter.off('test', () => {});

Type Safety

When using TypeScript, you can provide a type map for full type safety:

type EventMap = {
  'user-login': {id: string; name: string};
  'user-logout': {id: string};
  'error': Error;
  'ready': undefined;
};

const emitter = new Emittery<EventMap>();

// TypeScript will enforce correct event names and data types
emitter.on('user-login', (user) => {
  // user is typed as {id: string; name: string}
  console.log(user.name);
});

// This would cause a TypeScript error
// emitter.emit('user-login', 'invalid data');