emittery 1.0.3 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +18 -6
- package/index.js +45 -12
- package/package.json +1 -1
- package/readme.md +29 -6
package/index.d.ts
CHANGED
|
@@ -341,7 +341,8 @@ export default class Emittery<
|
|
|
341
341
|
*/
|
|
342
342
|
on<Name extends keyof AllEventData>(
|
|
343
343
|
eventName: Name | readonly Name[],
|
|
344
|
-
listener: (eventData: AllEventData[Name]) => void | Promise<void
|
|
344
|
+
listener: (eventData: AllEventData[Name]) => void | Promise<void>,
|
|
345
|
+
options?: {signal?: AbortSignal}
|
|
345
346
|
): UnsubscribeFunction;
|
|
346
347
|
|
|
347
348
|
/**
|
|
@@ -461,10 +462,12 @@ export default class Emittery<
|
|
|
461
462
|
): void;
|
|
462
463
|
|
|
463
464
|
/**
|
|
464
|
-
Subscribe to one or more events only once. It will be unsubscribed after the first
|
|
465
|
-
|
|
465
|
+
Subscribe to one or more events only once. It will be unsubscribed after the first event that matches the predicate (if provided).
|
|
466
|
+
|
|
467
|
+
@param eventName - The event name(s) to subscribe to.
|
|
468
|
+
@param predicate - Optional predicate function to filter event data. The event will only be emitted if the predicate returns true.
|
|
466
469
|
|
|
467
|
-
@returns The promise of event data when `eventName` is emitted. This promise is extended with an `off` method.
|
|
470
|
+
@returns The promise of event data when `eventName` is emitted and predicate matches (if provided). This promise is extended with an `off` method.
|
|
468
471
|
|
|
469
472
|
@example
|
|
470
473
|
```
|
|
@@ -481,11 +484,19 @@ export default class Emittery<
|
|
|
481
484
|
console.log(data);
|
|
482
485
|
});
|
|
483
486
|
|
|
487
|
+
// With predicate
|
|
488
|
+
emitter.once('data', data => data.ok === true).then(data => {
|
|
489
|
+
console.log(data);
|
|
490
|
+
//=> {ok: true, value: 42}
|
|
491
|
+
});
|
|
492
|
+
|
|
484
493
|
emitter.emit('🦄', '🌈'); // Logs `🌈` twice
|
|
485
494
|
emitter.emit('🐶', '🍖'); // Nothing happens
|
|
495
|
+
emitter.emit('data', {ok: false}); // Nothing happens
|
|
496
|
+
emitter.emit('data', {ok: true, value: 42}); // Logs {ok: true, value: 42}
|
|
486
497
|
```
|
|
487
498
|
*/
|
|
488
|
-
once<Name extends keyof AllEventData>(eventName: Name | readonly Name[]): EmitteryOncePromise<AllEventData[Name]>;
|
|
499
|
+
once<Name extends keyof AllEventData>(eventName: Name | readonly Name[], predicate?: (eventData: AllEventData[Name]) => boolean): EmitteryOncePromise<AllEventData[Name]>;
|
|
489
500
|
|
|
490
501
|
/**
|
|
491
502
|
Trigger an event asynchronously, optionally with some data. Listeners are called in the order they were added, but executed concurrently.
|
|
@@ -520,7 +531,8 @@ export default class Emittery<
|
|
|
520
531
|
listener: (
|
|
521
532
|
eventName: keyof EventData,
|
|
522
533
|
eventData: EventData[keyof EventData]
|
|
523
|
-
) => void | Promise<void
|
|
534
|
+
) => void | Promise<void>,
|
|
535
|
+
options?: {signal?: AbortSignal}
|
|
524
536
|
): UnsubscribeFunction;
|
|
525
537
|
|
|
526
538
|
/**
|
package/index.js
CHANGED
|
@@ -165,13 +165,15 @@ function defaultMethodNamesOrAssert(methodNames) {
|
|
|
165
165
|
const isMetaEvent = eventName => eventName === listenerAdded || eventName === listenerRemoved;
|
|
166
166
|
|
|
167
167
|
function emitMetaEvent(emitter, eventName, eventData) {
|
|
168
|
-
if (isMetaEvent(eventName)) {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
168
|
+
if (!isMetaEvent(eventName)) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
try {
|
|
173
|
+
canEmitMetaEvents = true;
|
|
174
|
+
emitter.emit(eventName, eventData);
|
|
175
|
+
} finally {
|
|
176
|
+
canEmitMetaEvents = false;
|
|
175
177
|
}
|
|
176
178
|
}
|
|
177
179
|
|
|
@@ -273,7 +275,7 @@ export default class Emittery {
|
|
|
273
275
|
}
|
|
274
276
|
}
|
|
275
277
|
|
|
276
|
-
on(eventNames, listener) {
|
|
278
|
+
on(eventNames, listener, {signal} = {}) {
|
|
277
279
|
assertListener(listener);
|
|
278
280
|
|
|
279
281
|
eventNames = Array.isArray(eventNames) ? eventNames : [eventNames];
|
|
@@ -295,7 +297,18 @@ export default class Emittery {
|
|
|
295
297
|
}
|
|
296
298
|
}
|
|
297
299
|
|
|
298
|
-
|
|
300
|
+
const off = () => {
|
|
301
|
+
this.off(eventNames, listener);
|
|
302
|
+
signal?.removeEventListener('abort', off);
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
signal?.addEventListener('abort', off, {once: true});
|
|
306
|
+
|
|
307
|
+
if (signal?.aborted) {
|
|
308
|
+
off();
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
return off;
|
|
299
312
|
}
|
|
300
313
|
|
|
301
314
|
off(eventNames, listener) {
|
|
@@ -321,11 +334,19 @@ export default class Emittery {
|
|
|
321
334
|
}
|
|
322
335
|
}
|
|
323
336
|
|
|
324
|
-
once(eventNames) {
|
|
337
|
+
once(eventNames, predicate) {
|
|
338
|
+
if (predicate !== undefined && typeof predicate !== 'function') {
|
|
339
|
+
throw new TypeError('predicate must be a function');
|
|
340
|
+
}
|
|
341
|
+
|
|
325
342
|
let off_;
|
|
326
343
|
|
|
327
344
|
const promise = new Promise(resolve => {
|
|
328
345
|
off_ = this.on(eventNames, data => {
|
|
346
|
+
if (predicate && !predicate(data)) {
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
|
|
329
350
|
off_();
|
|
330
351
|
resolve(data);
|
|
331
352
|
});
|
|
@@ -405,14 +426,26 @@ export default class Emittery {
|
|
|
405
426
|
/* eslint-enable no-await-in-loop */
|
|
406
427
|
}
|
|
407
428
|
|
|
408
|
-
onAny(listener) {
|
|
429
|
+
onAny(listener, {signal} = {}) {
|
|
409
430
|
assertListener(listener);
|
|
410
431
|
|
|
411
432
|
this.logIfDebugEnabled('subscribeAny', undefined, undefined);
|
|
412
433
|
|
|
413
434
|
anyMap.get(this).add(listener);
|
|
414
435
|
emitMetaEvent(this, listenerAdded, {listener});
|
|
415
|
-
|
|
436
|
+
|
|
437
|
+
const offAny = () => {
|
|
438
|
+
this.offAny(listener);
|
|
439
|
+
signal?.removeEventListener('abort', offAny);
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
signal?.addEventListener('abort', offAny, {once: true});
|
|
443
|
+
|
|
444
|
+
if (signal?.aborted) {
|
|
445
|
+
offAny();
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
return offAny;
|
|
416
449
|
}
|
|
417
450
|
|
|
418
451
|
anyEvent() {
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -197,7 +197,7 @@ emitter.emit('test');
|
|
|
197
197
|
//=> [subscribe]: test
|
|
198
198
|
```
|
|
199
199
|
|
|
200
|
-
#### on(eventName | eventName[], listener)
|
|
200
|
+
#### on(eventName | eventName[], listener, options?: {signal?: AbortSignal})
|
|
201
201
|
|
|
202
202
|
Subscribe to one or more events.
|
|
203
203
|
|
|
@@ -222,6 +222,21 @@ emitter.emit('🦄', '🌈'); // log => '🌈' x2
|
|
|
222
222
|
emitter.emit('🐶', '🍖'); // log => '🍖'
|
|
223
223
|
```
|
|
224
224
|
|
|
225
|
+
You can pass an [abort signal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) to unsubscribe too:
|
|
226
|
+
|
|
227
|
+
```js
|
|
228
|
+
import Emittery from 'emittery';
|
|
229
|
+
|
|
230
|
+
const abortController = new AbortController();
|
|
231
|
+
|
|
232
|
+
emitter.on('🐗', data => {
|
|
233
|
+
console.log(data);
|
|
234
|
+
}, {signal: abortController.signal});
|
|
235
|
+
|
|
236
|
+
abortController.abort();
|
|
237
|
+
emitter.emit('🐗', '🍞'); // nothing happens
|
|
238
|
+
```
|
|
239
|
+
|
|
225
240
|
##### Custom subscribable events
|
|
226
241
|
|
|
227
242
|
Emittery exports some symbols which represent "meta" events that can be passed to `Emitter.on` and similar methods.
|
|
@@ -282,11 +297,11 @@ await emitter.emit('🦊', 'c'); // Nothing happens
|
|
|
282
297
|
|
|
283
298
|
##### listener(data)
|
|
284
299
|
|
|
285
|
-
#### once(eventName | eventName[])
|
|
300
|
+
#### once(eventName | eventName[], predicate?)
|
|
286
301
|
|
|
287
|
-
Subscribe to one or more events only once. It will be unsubscribed after the first event.
|
|
302
|
+
Subscribe to one or more events only once. It will be unsubscribed after the first event that matches the predicate (if provided).
|
|
288
303
|
|
|
289
|
-
Returns a promise for the event data when `eventName` is emitted. This promise is extended with an `off` method.
|
|
304
|
+
Returns a promise for the event data when `eventName` is emitted and predicate matches (if provided). This promise is extended with an `off` method.
|
|
290
305
|
|
|
291
306
|
```js
|
|
292
307
|
import Emittery from 'emittery';
|
|
@@ -302,8 +317,16 @@ emitter.once(['🦄', '🐶']).then(data => {
|
|
|
302
317
|
console.log(data);
|
|
303
318
|
});
|
|
304
319
|
|
|
320
|
+
// With predicate
|
|
321
|
+
emitter.once('data', data => data.ok === true).then(data => {
|
|
322
|
+
console.log(data);
|
|
323
|
+
//=> {ok: true, value: 42}
|
|
324
|
+
});
|
|
325
|
+
|
|
305
326
|
emitter.emit('🦄', '🌈'); // Log => '🌈' x2
|
|
306
327
|
emitter.emit('🐶', '🍖'); // Nothing happens
|
|
328
|
+
emitter.emit('data', {ok: false}); // Nothing happens
|
|
329
|
+
emitter.emit('data', {ok: true, value: 42}); // Log => {ok: true, value: 42}
|
|
307
330
|
```
|
|
308
331
|
|
|
309
332
|
#### events(eventName)
|
|
@@ -399,11 +422,11 @@ Same as above, but it waits for each listener to resolve before triggering the n
|
|
|
399
422
|
|
|
400
423
|
If any of the listeners throw/reject, the returned promise will be rejected with the error and the remaining listeners will *not* be called.
|
|
401
424
|
|
|
402
|
-
#### onAny(listener)
|
|
425
|
+
#### onAny(listener, options?: {signal?: AbortSignal})
|
|
403
426
|
|
|
404
427
|
Subscribe to be notified about any event.
|
|
405
428
|
|
|
406
|
-
Returns a method to unsubscribe.
|
|
429
|
+
Returns a method to unsubscribe. Abort signal is respected too.
|
|
407
430
|
|
|
408
431
|
##### listener(eventName, data)
|
|
409
432
|
|