UNPKG

2.41 kBJavaScriptView Raw
1import { isFunction, noop } from '@polkadot/util';
2export class Combinator {
3 __internal__allHasFired = false;
4 __internal__callback;
5 __internal__fired = [];
6 __internal__fns = [];
7 __internal__isActive = true;
8 __internal__results = [];
9 __internal__subscriptions = [];
10 constructor(fns, callback) {
11 this.__internal__callback = callback;
12 // eslint-disable-next-line @typescript-eslint/no-floating-promises, @typescript-eslint/require-await
13 this.__internal__subscriptions = fns.map(async (input, index) => {
14 const [fn, ...args] = Array.isArray(input)
15 ? input
16 : [input];
17 this.__internal__fired.push(false);
18 this.__internal__fns.push(fn);
19 // Not quite 100% how to have a variable number at the front here
20 // eslint-disable-next-line @typescript-eslint/no-unsafe-return,@typescript-eslint/ban-types
21 return fn(...args, this._createCallback(index));
22 });
23 }
24 _allHasFired() {
25 this.__internal__allHasFired ||= this.__internal__fired.filter((hasFired) => !hasFired).length === 0;
26 return this.__internal__allHasFired;
27 }
28 _createCallback(index) {
29 return (value) => {
30 this.__internal__fired[index] = true;
31 this.__internal__results[index] = value;
32 this._triggerUpdate();
33 };
34 }
35 _triggerUpdate() {
36 if (!this.__internal__isActive || !isFunction(this.__internal__callback) || !this._allHasFired()) {
37 return;
38 }
39 try {
40 Promise
41 .resolve(this.__internal__callback(this.__internal__results))
42 .catch(noop);
43 }
44 catch {
45 // swallow, we don't want the handler to trip us up
46 }
47 }
48 unsubscribe() {
49 if (!this.__internal__isActive) {
50 return;
51 }
52 this.__internal__isActive = false;
53 Promise
54 .all(this.__internal__subscriptions.map(async (subscription) => {
55 try {
56 const unsubscribe = await subscription;
57 if (isFunction(unsubscribe)) {
58 unsubscribe();
59 }
60 }
61 catch {
62 // ignore
63 }
64 })).catch(() => {
65 // ignore, already ignored above, should never throw
66 });
67 }
68}