Promisify an event by waiting for it to be emitted with support for async iteration and advanced event handling
npx @tessl/cli install tessl/npm-p-event@6.0.00
# p-event
1
2
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.
3
4
## Package Information
5
6
- **Package Name**: p-event
7
- **Package Type**: npm
8
- **Language**: JavaScript (with TypeScript definitions)
9
- **Installation**: `npm install p-event`
10
11
## Core Imports
12
13
ES Modules:
14
15
```typescript
16
import { pEvent, pEventMultiple, pEventIterator, TimeoutError } from 'p-event';
17
18
// Import specific types (TypeScript only)
19
import type {
20
Emitter,
21
CancelablePromise,
22
Options,
23
MultiArgumentsOptions,
24
FilterFunction
25
} from 'p-event';
26
```
27
28
CommonJS:
29
30
```javascript
31
const { pEvent, pEventMultiple, pEventIterator, TimeoutError } = require('p-event');
32
```
33
34
## Basic Usage
35
36
```javascript
37
import { pEvent } from 'p-event';
38
import { EventEmitter } from 'node:events';
39
40
// Basic event promisification
41
const emitter = new EventEmitter();
42
43
try {
44
// Wait for a single event
45
const result = await pEvent(emitter, 'finish');
46
console.log('Event emitted with:', result);
47
} catch (error) {
48
// Handle error events or timeouts
49
console.error('Event error:', error);
50
}
51
52
// DOM events in browser
53
await pEvent(document, 'DOMContentLoaded');
54
console.log('DOM ready');
55
```
56
57
## Architecture
58
59
p-event is built around three core functions that provide different event handling patterns:
60
61
- **Single Event Promises**: `pEvent` converts a single event emission into a Promise
62
- **Multiple Event Collection**: `pEventMultiple` collects multiple event emissions into an array
63
- **Async Iteration**: `pEventIterator` provides async iterator for continuous event streams
64
- **Universal Compatibility**: Automatic detection of listener methods (on/off, addEventListener/removeEventListener)
65
- **Cancellation Support**: All returned promises include `.cancel()` method for cleanup
66
67
## Capabilities
68
69
### Single Event Promisification
70
71
Core functionality for converting a single event emission into a Promise with full cancellation support.
72
73
```typescript { .api }
74
function pEvent<EventName extends string | symbol, EmittedType extends unknown[]>(
75
emitter: Emitter<EventName, EmittedType>,
76
event: string | symbol | ReadonlyArray<string | symbol>,
77
options: MultiArgumentsOptions<EmittedType>
78
): CancelablePromise<EmittedType>;
79
80
function pEvent<EventName extends string | symbol, EmittedType>(
81
emitter: Emitter<EventName, [EmittedType]>,
82
event: string | symbol | ReadonlyArray<string | symbol>,
83
filter: FilterFunction<EmittedType>
84
): CancelablePromise<EmittedType>;
85
86
function pEvent<EventName extends string | symbol, EmittedType>(
87
emitter: Emitter<EventName, [EmittedType]>,
88
event: string | symbol | ReadonlyArray<string | symbol>,
89
options?: Options<EmittedType>
90
): CancelablePromise<EmittedType>;
91
```
92
93
**Usage Examples:**
94
95
```javascript
96
import { pEvent } from 'p-event';
97
import fs from 'node:fs';
98
99
// Basic usage
100
const stream = fs.createReadStream('file.txt');
101
await pEvent(stream, 'open');
102
console.log('File opened');
103
104
// With filter function
105
const result = await pEvent(emitter, 'data', value => value > 100);
106
107
// With options
108
const result = await pEvent(emitter, 'finish', {
109
timeout: 5000,
110
rejectionEvents: ['error', 'close'],
111
multiArgs: true
112
});
113
114
// Cancellation
115
const promise = pEvent(emitter, 'finish');
116
// Later...
117
promise.cancel(); // Removes listeners and prevents settlement
118
```
119
120
### Multiple Event Collection
121
122
Collects multiple event emissions before resolving to an array of values.
123
124
```typescript { .api }
125
function pEventMultiple<EventName extends string | symbol, EmittedType extends unknown[]>(
126
emitter: Emitter<EventName, EmittedType>,
127
event: string | symbol | ReadonlyArray<string | symbol>,
128
options: MultipleMultiArgumentsOptions<EmittedType>
129
): CancelablePromise<EmittedType[]>;
130
131
function pEventMultiple<EventName extends string | symbol, EmittedType>(
132
emitter: Emitter<EventName, [EmittedType]>,
133
event: string | symbol | ReadonlyArray<string | symbol>,
134
options: MultipleOptions<EmittedType>
135
): CancelablePromise<EmittedType[]>;
136
137
type MultipleOptions<EmittedType extends unknown | unknown[]> = {
138
/** Number of times the event needs to be emitted before promise resolves */
139
readonly count: number;
140
/** Whether to resolve the promise immediately (returned array will be mutated) */
141
readonly resolveImmediately?: boolean;
142
} & Options<EmittedType>;
143
144
type MultipleMultiArgumentsOptions<EmittedType extends unknown[]> = {
145
readonly multiArgs: true;
146
} & MultipleOptions<EmittedType>;
147
```
148
149
**Usage Examples:**
150
151
```javascript
152
import { pEventMultiple } from 'p-event';
153
154
// Collect 3 events
155
const results = await pEventMultiple(emitter, 'data', { count: 3 });
156
console.log(results); // [value1, value2, value3]
157
158
// Immediate resolution with mutable array
159
const promise = pEventMultiple(emitter, 'message', {
160
count: Infinity,
161
resolveImmediately: true
162
});
163
const results = await promise;
164
// results array is mutated as events are emitted
165
```
166
167
### Async Event Iteration
168
169
Creates an async iterator for continuous event stream processing with automatic cleanup.
170
171
```typescript { .api }
172
function pEventIterator<EventName extends string | symbol, EmittedType extends unknown[]>(
173
emitter: Emitter<EventName, EmittedType>,
174
event: string | symbol | ReadonlyArray<string | symbol>,
175
options: IteratorMultiArgumentsOptions<EmittedType>
176
): AsyncIterableIterator<EmittedType>;
177
178
function pEventIterator<EventName extends string | symbol, EmittedType>(
179
emitter: Emitter<EventName, [EmittedType]>,
180
event: string | symbol | ReadonlyArray<string | symbol>,
181
filter: FilterFunction<EmittedType>
182
): AsyncIterableIterator<EmittedType>;
183
184
function pEventIterator<EventName extends string | symbol, EmittedType>(
185
emitter: Emitter<EventName, [EmittedType]>,
186
event: string | symbol | ReadonlyArray<string | symbol>,
187
options?: IteratorOptions<EmittedType>
188
): AsyncIterableIterator<EmittedType>;
189
190
type IteratorOptions<EmittedType extends unknown | unknown[]> = {
191
/** Maximum number of events before iterator ends @default Infinity */
192
readonly limit?: number;
193
/** Events that will end the iterator @default [] */
194
readonly resolutionEvents?: ReadonlyArray<string | symbol>;
195
} & Options<EmittedType>;
196
197
type IteratorMultiArgumentsOptions<EmittedType extends unknown[]> = {
198
multiArgs: true;
199
} & IteratorOptions<EmittedType>;
200
```
201
202
[Event Iteration](./iteration.md)
203
204
## Base Types and Interfaces
205
206
```typescript { .api }
207
type AddRemoveListener<EventName extends string | symbol, Arguments extends unknown[]> = (
208
event: EventName,
209
listener: (...arguments: Arguments) => void
210
) => void;
211
212
type Emitter<EventName extends string | symbol, EmittedType extends unknown[]> = {
213
on?: AddRemoveListener<EventName, EmittedType>;
214
addListener?: AddRemoveListener<EventName, EmittedType>;
215
addEventListener?: AddRemoveListener<EventName, EmittedType>;
216
off?: AddRemoveListener<EventName, EmittedType>;
217
removeListener?: AddRemoveListener<EventName, EmittedType>;
218
removeEventListener?: AddRemoveListener<EventName, EmittedType>;
219
};
220
221
type FilterFunction<ElementType extends unknown | unknown[]> = (
222
value: ElementType
223
) => boolean;
224
225
type CancelablePromise<ResolveType> = {
226
cancel(): void;
227
} & Promise<ResolveType>;
228
229
type Options<EmittedType extends unknown | unknown[]> = {
230
/** Events that will reject the promise. @default ['error'] */
231
readonly rejectionEvents?: ReadonlyArray<string | symbol>;
232
/** Return array of all arguments from callback instead of just first argument. @default false */
233
readonly multiArgs?: boolean;
234
/** Time in milliseconds before timing out. @default Infinity */
235
readonly timeout?: number;
236
/** Filter function for accepting an event */
237
readonly filter?: FilterFunction<EmittedType>;
238
/** AbortSignal to abort waiting for the event */
239
readonly signal?: AbortSignal;
240
};
241
242
type MultiArgumentsOptions<EmittedType extends unknown[]> = {
243
readonly multiArgs: true;
244
} & Options<EmittedType>;
245
```
246
247
## Error Handling
248
249
TimeoutError is exported from the p-timeout dependency:
250
251
```typescript { .api }
252
export {TimeoutError} from 'p-timeout';
253
```
254
255
**Usage:**
256
257
```javascript
258
import { pEvent, TimeoutError } from 'p-event';
259
260
try {
261
await pEvent(emitter, 'finish', { timeout: 1000 });
262
} catch (error) {
263
if (error instanceof TimeoutError) {
264
console.log('Promise timed out');
265
} else {
266
console.log('Other error:', error);
267
}
268
}
269
```