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

iteration.mddocs/

Event Iteration

Async iteration functionality for continuous event stream processing with automatic cleanup and limit controls.

This document uses types defined in the main p-event documentation.

Capabilities

Event Iterator Creation

Creates an async iterator that yields event values as they are emitted.

/**
 * Creates an async iterator for event streams
 * @param emitter - Event emitter object
 * @param event - Event name(s) to listen for
 * @param options - Iterator configuration options
 * @returns AsyncIterableIterator that yields event values
 */
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>;

Usage Examples:

import { pEventIterator } from 'p-event';

// Basic iteration
const iterator = pEventIterator(emitter, 'data');
for await (const data of iterator) {
  console.log('Received:', data);
  
  // Break condition
  if (data.complete) break;
}

// With limit
const limitedIterator = pEventIterator(emitter, 'message', { limit: 10 });
for await (const message of limitedIterator) {
  console.log('Message:', message);
}
// Automatically stops after 10 messages

// With resolution events
const iterator = pEventIterator(emitter, 'data', {
  resolutionEvents: ['end', 'close']
});
for await (const data of iterator) {
  console.log('Data:', data);
}
// Stops when 'end' or 'close' events are emitted

Iterator Control Methods

The async iterator provides standard iterator methods for control flow.

interface AsyncIterableIterator<T> {
  /** Get next value from the iterator */
  next(): Promise<IteratorResult<T>>;
  /** Manually end the iterator and return a value */
  return(value?: T): Promise<IteratorResult<T>>;
  /** Make the object iterable in for-await loops */
  [Symbol.asyncIterator](): AsyncIterableIterator<T>;
}

interface IteratorResult<T> {
  done: boolean;
  value: T | undefined;
}

Manual Iterator Control:

import { pEventIterator } from 'p-event';

const iterator = pEventIterator(emitter, 'data');

// Manual iteration
while (true) {
  const { done, value } = await iterator.next();
  
  if (done) {
    console.log('Iterator finished');
    break;
  }
  
  console.log('Received value:', value);
  
  // Manual termination
  if (value.shouldStop) {
    await iterator.return('stopped');
    break;
  }
}

Advanced Iterator Patterns

Complex event processing patterns using iterator options and controls.

Backpressure Handling:

// Iterator handles backpressure by queuing events
const iterator = pEventIterator(emitter, 'data');

// Emit events faster than processing
emitter.emit('data', 'value1');
emitter.emit('data', 'value2');
emitter.emit('data', 'value3');

// Values are queued and retrieved in order
console.log(await iterator.next()); // { done: false, value: 'value1' }
console.log(await iterator.next()); // { done: false, value: 'value2' }
console.log(await iterator.next()); // { done: false, value: 'value3' }

Multiple Event Names:

// Listen to multiple events
const iterator = pEventIterator(emitter, ['data', 'message', 'info']);

for await (const value of iterator) {
  // Receives values from any of the specified events
  console.log('Event value:', value);
}

Filter with Multi-Arguments:

// Complex filtering with multiple arguments
const iterator = pEventIterator(emitter, 'complex', {
  multiArgs: true,
  filter: ([type, data, metadata]) => {
    return type === 'important' && data.priority > 5;
  }
});

for await (const [type, data, metadata] of iterator) {
  console.log('Important event:', { type, data, metadata });
}

Zero Limit Iterator:

// Iterator with limit 0 immediately ends
const iterator = pEventIterator(emitter, 'data', { limit: 0 });

const result = await iterator.next();
console.log(result); // { done: true, value: undefined }

Error Handling in Iterators

Event-based error handling within iterator loops.

import { pEventIterator } from 'p-event';

try {
  const iterator = pEventIterator(emitter, 'data', {
    rejectionEvents: ['error'],
    timeout: 5000
  });
  
  for await (const data of iterator) {
    console.log('Processing:', data);
  }
} catch (error) {
  if (error instanceof TimeoutError) {
    console.log('Iterator timed out');
  } else {
    console.log('Iterator error:', error);
  }
}

AbortSignal Integration

Integration with standard Web API cancellation patterns.

// Using AbortController for cancellation
const controller = new AbortController();

setTimeout(() => {
  controller.abort('timeout');
}, 10000);

try {
  const iterator = pEventIterator(emitter, 'data', {
    signal: controller.signal
  });
  
  for await (const data of iterator) {
    console.log('Data:', data);
  }
} catch (error) {
  console.log('Aborted:', error.message); // 'timeout'
}

Install with Tessl CLI

npx tessl i tessl/npm-p-event

docs

index.md

iteration.md

tile.json