CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-p-event

Promisify an event by waiting for it to be emitted with support for async iteration and advanced event handling

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

p-event

p-event is a JavaScript library that promisifies event-based APIs by waiting for events to be emitted. It converts Node.js EventEmitter and DOM event patterns into Promise-based APIs for use with async/await, supporting advanced features like timeout handling, event filtering, cancellation, and async iteration.

Package Information

  • Package Name: p-event
  • Package Type: npm
  • Language: JavaScript (with TypeScript definitions)
  • Installation: npm install p-event

Core Imports

ES Modules:

import { pEvent, pEventMultiple, pEventIterator, TimeoutError } from 'p-event';

// Import specific types (TypeScript only)
import type { 
  Emitter, 
  CancelablePromise, 
  Options, 
  MultiArgumentsOptions,
  FilterFunction 
} from 'p-event';

CommonJS:

const { pEvent, pEventMultiple, pEventIterator, TimeoutError } = require('p-event');

Basic Usage

import { pEvent } from 'p-event';
import { EventEmitter } from 'node:events';

// Basic event promisification
const emitter = new EventEmitter();

try {
  // Wait for a single event
  const result = await pEvent(emitter, 'finish');
  console.log('Event emitted with:', result);
} catch (error) {
  // Handle error events or timeouts
  console.error('Event error:', error);
}

// DOM events in browser
await pEvent(document, 'DOMContentLoaded');
console.log('DOM ready');

Architecture

p-event is built around three core functions that provide different event handling patterns:

  • Single Event Promises: pEvent converts a single event emission into a Promise
  • Multiple Event Collection: pEventMultiple collects multiple event emissions into an array
  • Async Iteration: pEventIterator provides async iterator for continuous event streams
  • Universal Compatibility: Automatic detection of listener methods (on/off, addEventListener/removeEventListener)
  • Cancellation Support: All returned promises include .cancel() method for cleanup

Capabilities

Single Event Promisification

Core functionality for converting a single event emission into a Promise with full cancellation support.

function pEvent<EventName extends string | symbol, EmittedType extends unknown[]>(
  emitter: Emitter<EventName, EmittedType>,
  event: string | symbol | ReadonlyArray<string | symbol>,
  options: MultiArgumentsOptions<EmittedType>
): CancelablePromise<EmittedType>;

function pEvent<EventName extends string | symbol, EmittedType>(
  emitter: Emitter<EventName, [EmittedType]>,
  event: string | symbol | ReadonlyArray<string | symbol>,
  filter: FilterFunction<EmittedType>
): CancelablePromise<EmittedType>;

function pEvent<EventName extends string | symbol, EmittedType>(
  emitter: Emitter<EventName, [EmittedType]>,
  event: string | symbol | ReadonlyArray<string | symbol>,
  options?: Options<EmittedType>
): CancelablePromise<EmittedType>;

Usage Examples:

import { pEvent } from 'p-event';
import fs from 'node:fs';

// Basic usage
const stream = fs.createReadStream('file.txt');
await pEvent(stream, 'open');
console.log('File opened');

// With filter function
const result = await pEvent(emitter, 'data', value => value > 100);

// With options
const result = await pEvent(emitter, 'finish', {
  timeout: 5000,
  rejectionEvents: ['error', 'close'],
  multiArgs: true
});

// Cancellation
const promise = pEvent(emitter, 'finish');
// Later...
promise.cancel(); // Removes listeners and prevents settlement

Multiple Event Collection

Collects multiple event emissions before resolving to an array of values.

function pEventMultiple<EventName extends string | symbol, EmittedType extends unknown[]>(
  emitter: Emitter<EventName, EmittedType>,
  event: string | symbol | ReadonlyArray<string | symbol>,
  options: MultipleMultiArgumentsOptions<EmittedType>
): CancelablePromise<EmittedType[]>;

function pEventMultiple<EventName extends string | symbol, EmittedType>(
  emitter: Emitter<EventName, [EmittedType]>,
  event: string | symbol | ReadonlyArray<string | symbol>,
  options: MultipleOptions<EmittedType>
): CancelablePromise<EmittedType[]>;

type MultipleOptions<EmittedType extends unknown | unknown[]> = {
  /** Number of times the event needs to be emitted before promise resolves */
  readonly count: number;
  /** Whether to resolve the promise immediately (returned array will be mutated) */
  readonly resolveImmediately?: boolean;
} & Options<EmittedType>;

type MultipleMultiArgumentsOptions<EmittedType extends unknown[]> = {
  readonly multiArgs: true;
} & MultipleOptions<EmittedType>;

Usage Examples:

import { pEventMultiple } from 'p-event';

// Collect 3 events
const results = await pEventMultiple(emitter, 'data', { count: 3 });
console.log(results); // [value1, value2, value3]

// Immediate resolution with mutable array
const promise = pEventMultiple(emitter, 'message', {
  count: Infinity,
  resolveImmediately: true
});
const results = await promise;
// results array is mutated as events are emitted

Async Event Iteration

Creates an async iterator for continuous event stream processing with automatic cleanup.

function pEventIterator<EventName extends string | symbol, EmittedType extends unknown[]>(
  emitter: Emitter<EventName, EmittedType>,
  event: string | symbol | ReadonlyArray<string | symbol>,
  options: IteratorMultiArgumentsOptions<EmittedType>
): AsyncIterableIterator<EmittedType>;

function pEventIterator<EventName extends string | symbol, EmittedType>(
  emitter: Emitter<EventName, [EmittedType]>,
  event: string | symbol | ReadonlyArray<string | symbol>,
  filter: FilterFunction<EmittedType>
): AsyncIterableIterator<EmittedType>;

function pEventIterator<EventName extends string | symbol, EmittedType>(
  emitter: Emitter<EventName, [EmittedType]>,
  event: string | symbol | ReadonlyArray<string | symbol>,
  options?: IteratorOptions<EmittedType>
): AsyncIterableIterator<EmittedType>;

type IteratorOptions<EmittedType extends unknown | unknown[]> = {
  /** Maximum number of events before iterator ends @default Infinity */
  readonly limit?: number;
  /** Events that will end the iterator @default [] */
  readonly resolutionEvents?: ReadonlyArray<string | symbol>;
} & Options<EmittedType>;

type IteratorMultiArgumentsOptions<EmittedType extends unknown[]> = {
  multiArgs: true;
} & IteratorOptions<EmittedType>;

Event Iteration

Base Types and Interfaces

type AddRemoveListener<EventName extends string | symbol, Arguments extends unknown[]> = (
  event: EventName,
  listener: (...arguments: Arguments) => void
) => void;

type Emitter<EventName extends string | symbol, EmittedType extends unknown[]> = {
  on?: AddRemoveListener<EventName, EmittedType>;
  addListener?: AddRemoveListener<EventName, EmittedType>;
  addEventListener?: AddRemoveListener<EventName, EmittedType>;
  off?: AddRemoveListener<EventName, EmittedType>;
  removeListener?: AddRemoveListener<EventName, EmittedType>;
  removeEventListener?: AddRemoveListener<EventName, EmittedType>;
};

type FilterFunction<ElementType extends unknown | unknown[]> = (
  value: ElementType
) => boolean;

type CancelablePromise<ResolveType> = {
  cancel(): void;
} & Promise<ResolveType>;

type Options<EmittedType extends unknown | unknown[]> = {
  /** Events that will reject the promise. @default ['error'] */
  readonly rejectionEvents?: ReadonlyArray<string | symbol>;
  /** Return array of all arguments from callback instead of just first argument. @default false */
  readonly multiArgs?: boolean;
  /** Time in milliseconds before timing out. @default Infinity */
  readonly timeout?: number;
  /** Filter function for accepting an event */
  readonly filter?: FilterFunction<EmittedType>;
  /** AbortSignal to abort waiting for the event */
  readonly signal?: AbortSignal;
};

type MultiArgumentsOptions<EmittedType extends unknown[]> = {
  readonly multiArgs: true;
} & Options<EmittedType>;

Error Handling

TimeoutError is exported from the p-timeout dependency:

export {TimeoutError} from 'p-timeout';

Usage:

import { pEvent, TimeoutError } from 'p-event';

try {
  await pEvent(emitter, 'finish', { timeout: 1000 });
} catch (error) {
  if (error instanceof TimeoutError) {
    console.log('Promise timed out');
  } else {
    console.log('Other error:', error);
  }
}

Install with Tessl CLI

npx tessl i tessl/npm-p-event
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/p-event@6.0.x
Publish Source
CLI
Badge
tessl/npm-p-event badge