velocious 1.0.619 → 1.0.621
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/README.md +1 -1
- package/build/background-jobs/store.js +1 -1
- package/build/configuration.js +1 -1
- package/build/environment-handlers/base.js +8 -0
- package/build/environment-handlers/node.js +12 -0
- package/build/src/background-jobs/store.js +1 -1
- package/build/src/configuration.js +2 -2
- package/build/src/environment-handlers/base.d.ts +7 -0
- package/build/src/environment-handlers/base.d.ts.map +1 -1
- package/build/src/environment-handlers/base.js +8 -1
- package/build/src/environment-handlers/node.d.ts +7 -0
- package/build/src/environment-handlers/node.d.ts.map +1 -1
- package/build/src/environment-handlers/node.js +12 -1
- package/build/src/testing/shared-transaction-connection-coordinator.d.ts +5 -1
- package/build/src/testing/shared-transaction-connection-coordinator.d.ts.map +1 -1
- package/build/src/testing/shared-transaction-connection-coordinator.js +81 -14
- package/build/src/testing/test.d.ts +1 -1
- package/build/src/testing/test.d.ts.map +1 -1
- package/build/src/testing/test.js +2 -2
- package/build/testing/shared-transaction-connection-coordinator.js +93 -12
- package/build/testing/test.js +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -1
- package/src/background-jobs/store.js +1 -1
- package/src/configuration.js +1 -1
- package/src/environment-handlers/base.js +8 -0
- package/src/environment-handlers/node.js +12 -0
- package/src/testing/shared-transaction-connection-coordinator.js +93 -12
- package/src/testing/test.js +1 -1
- package/build/src/testing/wait-for-event.d.ts +0 -46
- package/build/src/testing/wait-for-event.d.ts.map +0 -1
- package/build/src/testing/wait-for-event.js +0 -64
- package/build/testing/wait-for-event.js +0 -72
- package/src/testing/wait-for-event.js +0 -72
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
/**
|
|
3
|
-
* @typedef {object} WaitForEventOptions
|
|
4
|
-
* @property {number} [timeoutMs] Timeout in milliseconds (default: 5000).
|
|
5
|
-
* @property {(...args: Array<ReturnType<typeof JSON.parse>>) => boolean} [filter] Only resolve when this predicate returns true for the emitted arguments.
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* @typedef {object} EventEmitterLike
|
|
9
|
-
* @property {(event: string, listener: (...args: Array<ReturnType<typeof JSON.parse>>) => void) => void} on Registers a listener.
|
|
10
|
-
* @property {(event: string, listener: (...args: Array<ReturnType<typeof JSON.parse>>) => void) => void} off Removes a listener.
|
|
11
|
-
*/
|
|
12
|
-
/**
|
|
13
|
-
* Resolves the moment `eventName` fires on `emitter` — optionally only when `filter`
|
|
14
|
-
* matches the emitted arguments — instead of sleeping a fixed duration. Rejects with a
|
|
15
|
-
* timeout error if the event does not fire within `timeoutMs`. The listener is always
|
|
16
|
-
* removed (on resolve and on timeout).
|
|
17
|
-
*
|
|
18
|
-
* Use this to await a real signal (a background job finishing, a model update, a
|
|
19
|
-
* websocket message) rather than guessing a delay. To poll an arbitrary condition
|
|
20
|
-
* instead of a discrete event, use awaitery's `waitFor`.
|
|
21
|
-
* @param {EventEmitterLike} emitter - Event emitter exposing `on`/`off` (Node EventEmitter, eventemitter3, velocious `testEvents`, ...).
|
|
22
|
-
* @param {string} eventName - The event to wait for.
|
|
23
|
-
* @param {WaitForEventOptions} [options] - Options.
|
|
24
|
-
* @returns {Promise<ReturnType<typeof JSON.parse>>} - Resolves with the single emitted argument, an array when the event emits multiple, or undefined when it emits none.
|
|
25
|
-
*/
|
|
26
|
-
export default function waitForEvent(emitter, eventName, options = {}) {
|
|
27
|
-
const { timeoutMs = 5000, filter } = options;
|
|
28
|
-
return new Promise((resolve, reject) => {
|
|
29
|
-
/** @type {ReturnType<typeof setTimeout>} */
|
|
30
|
-
let timer;
|
|
31
|
-
/**
|
|
32
|
-
* Resolves the wait when a matching event fires, removing itself first. A filter
|
|
33
|
-
* that throws (e.g. it assumes an event shape an intermediate emission doesn't
|
|
34
|
-
* have) rejects immediately rather than leaving the waiter pending until timeout.
|
|
35
|
-
* @param {...ReturnType<typeof JSON.parse>} args - Emitted arguments.
|
|
36
|
-
* @returns {void}
|
|
37
|
-
*/
|
|
38
|
-
const listener = (...args) => {
|
|
39
|
-
if (filter) {
|
|
40
|
-
let matched;
|
|
41
|
-
try {
|
|
42
|
-
matched = filter(...args);
|
|
43
|
-
}
|
|
44
|
-
catch (error) {
|
|
45
|
-
clearTimeout(timer);
|
|
46
|
-
emitter.off(eventName, listener);
|
|
47
|
-
reject(error);
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
if (!matched)
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
clearTimeout(timer);
|
|
54
|
-
emitter.off(eventName, listener);
|
|
55
|
-
resolve(args.length > 1 ? args : args[0]);
|
|
56
|
-
};
|
|
57
|
-
timer = setTimeout(() => {
|
|
58
|
-
emitter.off(eventName, listener);
|
|
59
|
-
reject(new Error(`Timed out after ${timeoutMs}ms waiting for event ${JSON.stringify(eventName)}`));
|
|
60
|
-
}, timeoutMs);
|
|
61
|
-
emitter.on(eventName, listener);
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FpdC1mb3ItZXZlbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdGVzdGluZy93YWl0LWZvci1ldmVudC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVo7Ozs7R0FJRztBQUVIOzs7O0dBSUc7QUFFSDs7Ozs7Ozs7Ozs7OztHQWFHO0FBQ0gsTUFBTSxDQUFDLE9BQU8sVUFBVSxZQUFZLENBQUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxPQUFPLEdBQUcsRUFBRTtJQUNuRSxNQUFNLEVBQUMsU0FBUyxHQUFHLElBQUksRUFBRSxNQUFNLEVBQUMsR0FBRyxPQUFPLENBQUE7SUFFMUMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtRQUNyQyw0Q0FBNEM7UUFDNUMsSUFBSSxLQUFLLENBQUE7UUFFVDs7Ozs7O1dBTUc7UUFDSCxNQUFNLFFBQVEsR0FBRyxDQUFDLEdBQUcsSUFBSSxFQUFFLEVBQUU7WUFDM0IsSUFBSSxNQUFNLEVBQUUsQ0FBQztnQkFDWCxJQUFJLE9BQU8sQ0FBQTtnQkFFWCxJQUFJLENBQUM7b0JBQ0gsT0FBTyxHQUFHLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFBO2dCQUMzQixDQUFDO2dCQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7b0JBQ2YsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFBO29CQUNuQixPQUFPLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxRQUFRLENBQUMsQ0FBQTtvQkFDaEMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFBO29CQUViLE9BQU07Z0JBQ1IsQ0FBQztnQkFFRCxJQUFJLENBQUMsT0FBTztvQkFBRSxPQUFNO1lBQ3RCLENBQUM7WUFFRCxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUE7WUFDbkIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUE7WUFDaEMsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBQzNDLENBQUMsQ0FBQTtRQUVELEtBQUssR0FBRyxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ3RCLE9BQU8sQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFBO1lBQ2hDLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyxtQkFBbUIsU0FBUyx3QkFBd0IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQTtRQUNwRyxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUE7UUFFYixPQUFPLENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxRQUFRLENBQUMsQ0FBQTtJQUNqQyxDQUFDLENBQUMsQ0FBQTtBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuLyoqXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBXYWl0Rm9yRXZlbnRPcHRpb25zXG4gKiBAcHJvcGVydHkge251bWJlcn0gW3RpbWVvdXRNc10gVGltZW91dCBpbiBtaWxsaXNlY29uZHMgKGRlZmF1bHQ6IDUwMDApLlxuICogQHByb3BlcnR5IHsoLi4uYXJnczogQXJyYXk8UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4+KSA9PiBib29sZWFufSBbZmlsdGVyXSBPbmx5IHJlc29sdmUgd2hlbiB0aGlzIHByZWRpY2F0ZSByZXR1cm5zIHRydWUgZm9yIHRoZSBlbWl0dGVkIGFyZ3VtZW50cy5cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtvYmplY3R9IEV2ZW50RW1pdHRlckxpa2VcbiAqIEBwcm9wZXJ0eSB7KGV2ZW50OiBzdHJpbmcsIGxpc3RlbmVyOiAoLi4uYXJnczogQXJyYXk8UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4+KSA9PiB2b2lkKSA9PiB2b2lkfSBvbiBSZWdpc3RlcnMgYSBsaXN0ZW5lci5cbiAqIEBwcm9wZXJ0eSB7KGV2ZW50OiBzdHJpbmcsIGxpc3RlbmVyOiAoLi4uYXJnczogQXJyYXk8UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4+KSA9PiB2b2lkKSA9PiB2b2lkfSBvZmYgUmVtb3ZlcyBhIGxpc3RlbmVyLlxuICovXG5cbi8qKlxuICogUmVzb2x2ZXMgdGhlIG1vbWVudCBgZXZlbnROYW1lYCBmaXJlcyBvbiBgZW1pdHRlcmAg4oCUIG9wdGlvbmFsbHkgb25seSB3aGVuIGBmaWx0ZXJgXG4gKiBtYXRjaGVzIHRoZSBlbWl0dGVkIGFyZ3VtZW50cyDigJQgaW5zdGVhZCBvZiBzbGVlcGluZyBhIGZpeGVkIGR1cmF0aW9uLiBSZWplY3RzIHdpdGggYVxuICogdGltZW91dCBlcnJvciBpZiB0aGUgZXZlbnQgZG9lcyBub3QgZmlyZSB3aXRoaW4gYHRpbWVvdXRNc2AuIFRoZSBsaXN0ZW5lciBpcyBhbHdheXNcbiAqIHJlbW92ZWQgKG9uIHJlc29sdmUgYW5kIG9uIHRpbWVvdXQpLlxuICpcbiAqIFVzZSB0aGlzIHRvIGF3YWl0IGEgcmVhbCBzaWduYWwgKGEgYmFja2dyb3VuZCBqb2IgZmluaXNoaW5nLCBhIG1vZGVsIHVwZGF0ZSwgYVxuICogd2Vic29ja2V0IG1lc3NhZ2UpIHJhdGhlciB0aGFuIGd1ZXNzaW5nIGEgZGVsYXkuIFRvIHBvbGwgYW4gYXJiaXRyYXJ5IGNvbmRpdGlvblxuICogaW5zdGVhZCBvZiBhIGRpc2NyZXRlIGV2ZW50LCB1c2UgYXdhaXRlcnkncyBgd2FpdEZvcmAuXG4gKiBAcGFyYW0ge0V2ZW50RW1pdHRlckxpa2V9IGVtaXR0ZXIgLSBFdmVudCBlbWl0dGVyIGV4cG9zaW5nIGBvbmAvYG9mZmAgKE5vZGUgRXZlbnRFbWl0dGVyLCBldmVudGVtaXR0ZXIzLCB2ZWxvY2lvdXMgYHRlc3RFdmVudHNgLCAuLi4pLlxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZSAtIFRoZSBldmVudCB0byB3YWl0IGZvci5cbiAqIEBwYXJhbSB7V2FpdEZvckV2ZW50T3B0aW9uc30gW29wdGlvbnNdIC0gT3B0aW9ucy5cbiAqIEByZXR1cm5zIHtQcm9taXNlPFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+Pn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBzaW5nbGUgZW1pdHRlZCBhcmd1bWVudCwgYW4gYXJyYXkgd2hlbiB0aGUgZXZlbnQgZW1pdHMgbXVsdGlwbGUsIG9yIHVuZGVmaW5lZCB3aGVuIGl0IGVtaXRzIG5vbmUuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHdhaXRGb3JFdmVudChlbWl0dGVyLCBldmVudE5hbWUsIG9wdGlvbnMgPSB7fSkge1xuICBjb25zdCB7dGltZW91dE1zID0gNTAwMCwgZmlsdGVyfSA9IG9wdGlvbnNcblxuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIC8qKiBAdHlwZSB7UmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD59ICovXG4gICAgbGV0IHRpbWVyXG5cbiAgICAvKipcbiAgICAgKiBSZXNvbHZlcyB0aGUgd2FpdCB3aGVuIGEgbWF0Y2hpbmcgZXZlbnQgZmlyZXMsIHJlbW92aW5nIGl0c2VsZiBmaXJzdC4gQSBmaWx0ZXJcbiAgICAgKiB0aGF0IHRocm93cyAoZS5nLiBpdCBhc3N1bWVzIGFuIGV2ZW50IHNoYXBlIGFuIGludGVybWVkaWF0ZSBlbWlzc2lvbiBkb2Vzbid0XG4gICAgICogaGF2ZSkgcmVqZWN0cyBpbW1lZGlhdGVseSByYXRoZXIgdGhhbiBsZWF2aW5nIHRoZSB3YWl0ZXIgcGVuZGluZyB1bnRpbCB0aW1lb3V0LlxuICAgICAqIEBwYXJhbSB7Li4uUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59IGFyZ3MgLSBFbWl0dGVkIGFyZ3VtZW50cy5cbiAgICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICAgKi9cbiAgICBjb25zdCBsaXN0ZW5lciA9ICguLi5hcmdzKSA9PiB7XG4gICAgICBpZiAoZmlsdGVyKSB7XG4gICAgICAgIGxldCBtYXRjaGVkXG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBtYXRjaGVkID0gZmlsdGVyKC4uLmFyZ3MpXG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKVxuICAgICAgICAgIGVtaXR0ZXIub2ZmKGV2ZW50TmFtZSwgbGlzdGVuZXIpXG4gICAgICAgICAgcmVqZWN0KGVycm9yKVxuXG4gICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIW1hdGNoZWQpIHJldHVyblxuICAgICAgfVxuXG4gICAgICBjbGVhclRpbWVvdXQodGltZXIpXG4gICAgICBlbWl0dGVyLm9mZihldmVudE5hbWUsIGxpc3RlbmVyKVxuICAgICAgcmVzb2x2ZShhcmdzLmxlbmd0aCA+IDEgPyBhcmdzIDogYXJnc1swXSlcbiAgICB9XG5cbiAgICB0aW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgZW1pdHRlci5vZmYoZXZlbnROYW1lLCBsaXN0ZW5lcilcbiAgICAgIHJlamVjdChuZXcgRXJyb3IoYFRpbWVkIG91dCBhZnRlciAke3RpbWVvdXRNc31tcyB3YWl0aW5nIGZvciBldmVudCAke0pTT04uc3RyaW5naWZ5KGV2ZW50TmFtZSl9YCkpXG4gICAgfSwgdGltZW91dE1zKVxuXG4gICAgZW1pdHRlci5vbihldmVudE5hbWUsIGxpc3RlbmVyKVxuICB9KVxufVxuIl19
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @typedef {object} WaitForEventOptions
|
|
5
|
-
* @property {number} [timeoutMs] Timeout in milliseconds (default: 5000).
|
|
6
|
-
* @property {(...args: Array<ReturnType<typeof JSON.parse>>) => boolean} [filter] Only resolve when this predicate returns true for the emitted arguments.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* @typedef {object} EventEmitterLike
|
|
11
|
-
* @property {(event: string, listener: (...args: Array<ReturnType<typeof JSON.parse>>) => void) => void} on Registers a listener.
|
|
12
|
-
* @property {(event: string, listener: (...args: Array<ReturnType<typeof JSON.parse>>) => void) => void} off Removes a listener.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Resolves the moment `eventName` fires on `emitter` — optionally only when `filter`
|
|
17
|
-
* matches the emitted arguments — instead of sleeping a fixed duration. Rejects with a
|
|
18
|
-
* timeout error if the event does not fire within `timeoutMs`. The listener is always
|
|
19
|
-
* removed (on resolve and on timeout).
|
|
20
|
-
*
|
|
21
|
-
* Use this to await a real signal (a background job finishing, a model update, a
|
|
22
|
-
* websocket message) rather than guessing a delay. To poll an arbitrary condition
|
|
23
|
-
* instead of a discrete event, use awaitery's `waitFor`.
|
|
24
|
-
* @param {EventEmitterLike} emitter - Event emitter exposing `on`/`off` (Node EventEmitter, eventemitter3, velocious `testEvents`, ...).
|
|
25
|
-
* @param {string} eventName - The event to wait for.
|
|
26
|
-
* @param {WaitForEventOptions} [options] - Options.
|
|
27
|
-
* @returns {Promise<ReturnType<typeof JSON.parse>>} - Resolves with the single emitted argument, an array when the event emits multiple, or undefined when it emits none.
|
|
28
|
-
*/
|
|
29
|
-
export default function waitForEvent(emitter, eventName, options = {}) {
|
|
30
|
-
const {timeoutMs = 5000, filter} = options
|
|
31
|
-
|
|
32
|
-
return new Promise((resolve, reject) => {
|
|
33
|
-
/** @type {ReturnType<typeof setTimeout>} */
|
|
34
|
-
let timer
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Resolves the wait when a matching event fires, removing itself first. A filter
|
|
38
|
-
* that throws (e.g. it assumes an event shape an intermediate emission doesn't
|
|
39
|
-
* have) rejects immediately rather than leaving the waiter pending until timeout.
|
|
40
|
-
* @param {...ReturnType<typeof JSON.parse>} args - Emitted arguments.
|
|
41
|
-
* @returns {void}
|
|
42
|
-
*/
|
|
43
|
-
const listener = (...args) => {
|
|
44
|
-
if (filter) {
|
|
45
|
-
let matched
|
|
46
|
-
|
|
47
|
-
try {
|
|
48
|
-
matched = filter(...args)
|
|
49
|
-
} catch (error) {
|
|
50
|
-
clearTimeout(timer)
|
|
51
|
-
emitter.off(eventName, listener)
|
|
52
|
-
reject(error)
|
|
53
|
-
|
|
54
|
-
return
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (!matched) return
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
clearTimeout(timer)
|
|
61
|
-
emitter.off(eventName, listener)
|
|
62
|
-
resolve(args.length > 1 ? args : args[0])
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
timer = setTimeout(() => {
|
|
66
|
-
emitter.off(eventName, listener)
|
|
67
|
-
reject(new Error(`Timed out after ${timeoutMs}ms waiting for event ${JSON.stringify(eventName)}`))
|
|
68
|
-
}, timeoutMs)
|
|
69
|
-
|
|
70
|
-
emitter.on(eventName, listener)
|
|
71
|
-
})
|
|
72
|
-
}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @typedef {object} WaitForEventOptions
|
|
5
|
-
* @property {number} [timeoutMs] Timeout in milliseconds (default: 5000).
|
|
6
|
-
* @property {(...args: Array<ReturnType<typeof JSON.parse>>) => boolean} [filter] Only resolve when this predicate returns true for the emitted arguments.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* @typedef {object} EventEmitterLike
|
|
11
|
-
* @property {(event: string, listener: (...args: Array<ReturnType<typeof JSON.parse>>) => void) => void} on Registers a listener.
|
|
12
|
-
* @property {(event: string, listener: (...args: Array<ReturnType<typeof JSON.parse>>) => void) => void} off Removes a listener.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Resolves the moment `eventName` fires on `emitter` — optionally only when `filter`
|
|
17
|
-
* matches the emitted arguments — instead of sleeping a fixed duration. Rejects with a
|
|
18
|
-
* timeout error if the event does not fire within `timeoutMs`. The listener is always
|
|
19
|
-
* removed (on resolve and on timeout).
|
|
20
|
-
*
|
|
21
|
-
* Use this to await a real signal (a background job finishing, a model update, a
|
|
22
|
-
* websocket message) rather than guessing a delay. To poll an arbitrary condition
|
|
23
|
-
* instead of a discrete event, use awaitery's `waitFor`.
|
|
24
|
-
* @param {EventEmitterLike} emitter - Event emitter exposing `on`/`off` (Node EventEmitter, eventemitter3, velocious `testEvents`, ...).
|
|
25
|
-
* @param {string} eventName - The event to wait for.
|
|
26
|
-
* @param {WaitForEventOptions} [options] - Options.
|
|
27
|
-
* @returns {Promise<ReturnType<typeof JSON.parse>>} - Resolves with the single emitted argument, an array when the event emits multiple, or undefined when it emits none.
|
|
28
|
-
*/
|
|
29
|
-
export default function waitForEvent(emitter, eventName, options = {}) {
|
|
30
|
-
const {timeoutMs = 5000, filter} = options
|
|
31
|
-
|
|
32
|
-
return new Promise((resolve, reject) => {
|
|
33
|
-
/** @type {ReturnType<typeof setTimeout>} */
|
|
34
|
-
let timer
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Resolves the wait when a matching event fires, removing itself first. A filter
|
|
38
|
-
* that throws (e.g. it assumes an event shape an intermediate emission doesn't
|
|
39
|
-
* have) rejects immediately rather than leaving the waiter pending until timeout.
|
|
40
|
-
* @param {...ReturnType<typeof JSON.parse>} args - Emitted arguments.
|
|
41
|
-
* @returns {void}
|
|
42
|
-
*/
|
|
43
|
-
const listener = (...args) => {
|
|
44
|
-
if (filter) {
|
|
45
|
-
let matched
|
|
46
|
-
|
|
47
|
-
try {
|
|
48
|
-
matched = filter(...args)
|
|
49
|
-
} catch (error) {
|
|
50
|
-
clearTimeout(timer)
|
|
51
|
-
emitter.off(eventName, listener)
|
|
52
|
-
reject(error)
|
|
53
|
-
|
|
54
|
-
return
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (!matched) return
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
clearTimeout(timer)
|
|
61
|
-
emitter.off(eventName, listener)
|
|
62
|
-
resolve(args.length > 1 ? args : args[0])
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
timer = setTimeout(() => {
|
|
66
|
-
emitter.off(eventName, listener)
|
|
67
|
-
reject(new Error(`Timed out after ${timeoutMs}ms waiting for event ${JSON.stringify(eventName)}`))
|
|
68
|
-
}, timeoutMs)
|
|
69
|
-
|
|
70
|
-
emitter.on(eventName, listener)
|
|
71
|
-
})
|
|
72
|
-
}
|