Yieldless
Reference

yieldless/event

Await one EventTarget or EventEmitter event with abort-aware cleanup.

yieldless/event is for the small boundary where callback-style events meet async application code. It waits for one event, cleans up listeners, and can return the result in tuple form.

It supports browser-style EventTarget objects and Node-style EventEmitter objects without adding an event abstraction of its own.

Exports

  • onceEvent(source, eventName, options): Promise<T>
  • onceEventSafe(source, eventName, options): Promise<SafeResult<T, E>>
  • type OnceEventOptions = { signal?, rejectOn? }
  • type EventSourceLike = EventTargetLike | EventEmitterLike

EventTarget

import { onceEventSafe } from "yieldless/event";

const [error, event] = await onceEventSafe(button, "click", { signal });

EventEmitter

import { onceEvent } from "yieldless/event";

const socket = await onceEvent<Socket>(server, "connection", { signal });

For EventEmitter-like sources, error events reject the wait by default. Disable or customize that behavior with rejectOn.

const value = await onceEvent(emitter, "error", {
  rejectOn: false,
});

Behavior notes

  • Listener cleanup happens on success, rejection, and abort.
  • EventEmitter payloads resolve to the single argument when one argument is emitted, or the full argument array when multiple values are emitted.
  • EventTarget event names must be strings.
  • onceEventSafe() wraps success and failure in the normal Yieldless tuple shape.

Good

Use onceEventSafe() when the event wait is one step in a tuple flow.

const [error, event] = await onceEventSafe<Event>(socket, "open", {
  signal,
});

if (error) return [error, null] as const;

Use rejectOn to make domain-specific failure events reject the wait.

await onceEvent(stream, "ready", {
  rejectOn: "close",
  signal,
});

Avoid

Do not create one-off promises without listener cleanup.

await new Promise((resolve) => {
  emitter.once("ready", resolve);
});

That pattern usually forgets abort handling and error-event cleanup.

On this page