evnty 4.5.78 → 4.6.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/build/index.cjs +182 -61
- package/build/index.cjs.map +1 -1
- package/build/index.d.ts +46 -5
- package/build/index.js +176 -61
- package/build/index.js.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +214 -55
package/src/index.ts
CHANGED
|
@@ -9,25 +9,29 @@ export interface Callback<R = void> extends Fn<[], MaybePromise<R>> {}
|
|
|
9
9
|
export interface Listener<T, R = unknown> extends Fn<[T], MaybePromise<R | void>> {}
|
|
10
10
|
|
|
11
11
|
export interface FilterFunction<T> {
|
|
12
|
-
(
|
|
12
|
+
(value: T): MaybePromise<boolean>;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export interface Predicate<T, P extends T> {
|
|
16
|
-
(
|
|
16
|
+
(value: T): value is P;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export type Filter<T, P extends T> = Predicate<T, P> | FilterFunction<T>;
|
|
20
20
|
|
|
21
21
|
export interface Mapper<T, R> {
|
|
22
|
-
(
|
|
22
|
+
(value: T): MaybePromise<R>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface AsyncGenerable<T, R> {
|
|
26
|
+
(value: T): AsyncGenerator<R, void, unknown>;
|
|
23
27
|
}
|
|
24
28
|
|
|
25
29
|
export interface Reducer<T, R> {
|
|
26
|
-
(result: R,
|
|
30
|
+
(result: R, value: T): MaybePromise<R>;
|
|
27
31
|
}
|
|
28
32
|
|
|
29
33
|
export interface Expander<T, R> {
|
|
30
|
-
(
|
|
34
|
+
(value: T): MaybePromise<R>;
|
|
31
35
|
}
|
|
32
36
|
|
|
33
37
|
/**
|
|
@@ -105,6 +109,178 @@ export abstract class Callable<T, R> {
|
|
|
105
109
|
return Object.setPrototypeOf(func, new.target.prototype);
|
|
106
110
|
}
|
|
107
111
|
}
|
|
112
|
+
/*
|
|
113
|
+
* @internal
|
|
114
|
+
*/
|
|
115
|
+
export interface AsyncIterableCombinators<T> {
|
|
116
|
+
filter<U extends T>(filter: Filter<T, U>): AsyncIterableCombinators<Awaited<U>>;
|
|
117
|
+
map<U>(mapper: Mapper<T, U>): AsyncIterableCombinators<Awaited<U>>;
|
|
118
|
+
reduce<U>(reducer: Reducer<T, U>): AsyncIterableCombinators<Awaited<U>>;
|
|
119
|
+
expand<U>(expander: Mapper<T, U[]>): AsyncIterableCombinators<Awaited<U>>;
|
|
120
|
+
pipe<U>(expander: AsyncGenerable<T, U>): AsyncIterableCombinators<Awaited<U>>;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/*
|
|
124
|
+
* @internal
|
|
125
|
+
*/
|
|
126
|
+
export interface EventSource<T> extends Callable<[T], boolean>, Promise<T>, AsyncIterable<T> {
|
|
127
|
+
next(): Promise<T>;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/*
|
|
131
|
+
* @internal
|
|
132
|
+
*/
|
|
133
|
+
export class Signal<T> extends Callable<[T], boolean> implements Promise<T>, AsyncIterable<T> {
|
|
134
|
+
private rx?: PromiseWithResolvers<T>;
|
|
135
|
+
|
|
136
|
+
constructor(private readonly abortSignal?: AbortSignal) {
|
|
137
|
+
super((value: T) => {
|
|
138
|
+
if (this.rx) {
|
|
139
|
+
this.rx.resolve(value);
|
|
140
|
+
this.rx = undefined;
|
|
141
|
+
return true;
|
|
142
|
+
} else {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
this.abortSignal?.addEventListener(
|
|
147
|
+
'abort',
|
|
148
|
+
() => {
|
|
149
|
+
this.rx?.reject(this.abortSignal!.reason);
|
|
150
|
+
this.rx = undefined;
|
|
151
|
+
},
|
|
152
|
+
{ once: true },
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
get [Symbol.toStringTag](): string {
|
|
157
|
+
return `Signal(${this.abortSignal?.aborted ? 'stopped' : 'active'})`;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
get promise(): Promise<T> {
|
|
161
|
+
return this.next();
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
async next() {
|
|
165
|
+
if (this.abortSignal?.aborted) {
|
|
166
|
+
return Promise.reject(this.abortSignal.reason);
|
|
167
|
+
}
|
|
168
|
+
if (!this.rx) {
|
|
169
|
+
this.rx = Promise.withResolvers<T>();
|
|
170
|
+
}
|
|
171
|
+
return this.rx.promise;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
catch<OK = never>(onrejected?: ((reason: any) => OK | PromiseLike<OK>) | null | undefined): Promise<T | OK> {
|
|
175
|
+
return this.promise.catch(onrejected);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
finally(onfinally?: (() => void) | null | undefined): Promise<T> {
|
|
179
|
+
return this.promise.finally(onfinally);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
then<OK = T, ERR = never>(
|
|
183
|
+
onfulfilled?: ((value: T) => OK | PromiseLike<OK>) | null | undefined,
|
|
184
|
+
onrejected?: ((reason: unknown) => ERR | PromiseLike<ERR>) | null | undefined,
|
|
185
|
+
): Promise<OK | ERR> {
|
|
186
|
+
return this.promise.then(onfulfilled, onrejected);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
[Symbol.asyncIterator](): AsyncIterator<T, void, void> {
|
|
190
|
+
return {
|
|
191
|
+
next: async () => {
|
|
192
|
+
try {
|
|
193
|
+
const value = await this;
|
|
194
|
+
return { value, done: false };
|
|
195
|
+
} catch {
|
|
196
|
+
return { value: undefined, done: true };
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
return: () => {
|
|
200
|
+
return Promise.resolve({ value: undefined, done: true });
|
|
201
|
+
},
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* @internal
|
|
208
|
+
*/
|
|
209
|
+
export class Sequence<T> extends Callable<[T], boolean> implements Promise<T>, AsyncIterable<T> {
|
|
210
|
+
private sequence: T[];
|
|
211
|
+
private nextSignal: Signal<boolean>;
|
|
212
|
+
|
|
213
|
+
constructor(private readonly abortSignal?: AbortSignal) {
|
|
214
|
+
super((value: T) => {
|
|
215
|
+
if (this.abortSignal?.aborted) {
|
|
216
|
+
this.nextSignal(false);
|
|
217
|
+
return false;
|
|
218
|
+
} else {
|
|
219
|
+
this.sequence.push(value);
|
|
220
|
+
if (this.sequence.length === 1) {
|
|
221
|
+
this.nextSignal(true);
|
|
222
|
+
}
|
|
223
|
+
return true;
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
this.sequence = [];
|
|
227
|
+
this.nextSignal = new Signal<boolean>(this.abortSignal);
|
|
228
|
+
this.abortSignal?.addEventListener(
|
|
229
|
+
'abort',
|
|
230
|
+
() => {
|
|
231
|
+
this.nextSignal(false);
|
|
232
|
+
},
|
|
233
|
+
{ once: true },
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
get [Symbol.toStringTag](): string {
|
|
238
|
+
return `Sequence(${this.abortSignal?.aborted ? 'stopped' : 'active'})`;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
get promise(): Promise<T> {
|
|
242
|
+
return this.next();
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
async next(): Promise<T> {
|
|
246
|
+
if (!this.sequence.length) {
|
|
247
|
+
await this.nextSignal;
|
|
248
|
+
}
|
|
249
|
+
return this.sequence.shift()!;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
catch<OK = never>(onrejected?: ((reason: any) => OK | PromiseLike<OK>) | null | undefined): Promise<T | OK> {
|
|
253
|
+
return this.promise.catch(onrejected);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
finally(onfinally?: (() => void) | null | undefined): Promise<T> {
|
|
257
|
+
return this.promise.finally(onfinally);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
then<OK = T, ERR = never>(
|
|
261
|
+
onfulfilled?: ((value: T) => OK | PromiseLike<OK>) | null | undefined,
|
|
262
|
+
onrejected?: ((reason: unknown) => ERR | PromiseLike<ERR>) | null | undefined,
|
|
263
|
+
): Promise<OK | ERR> {
|
|
264
|
+
return this.promise.then(onfulfilled, onrejected);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
[Symbol.asyncIterator](): AsyncIterator<T, void, void> {
|
|
268
|
+
return {
|
|
269
|
+
next: async () => {
|
|
270
|
+
try {
|
|
271
|
+
const value = await this;
|
|
272
|
+
return { value, done: false };
|
|
273
|
+
} catch {
|
|
274
|
+
return { value: undefined, done: true };
|
|
275
|
+
}
|
|
276
|
+
},
|
|
277
|
+
return: () => {
|
|
278
|
+
this.nextSignal(false);
|
|
279
|
+
return Promise.resolve({ value: undefined, done: true });
|
|
280
|
+
},
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
}
|
|
108
284
|
|
|
109
285
|
/**
|
|
110
286
|
* @internal
|
|
@@ -421,41 +597,23 @@ export class Event<T = unknown, R = unknown> extends Callable<[T], Promise<(void
|
|
|
421
597
|
* ```
|
|
422
598
|
*/
|
|
423
599
|
[Symbol.asyncIterator](): AsyncIterator<T> {
|
|
424
|
-
const
|
|
425
|
-
const
|
|
426
|
-
const emitEvent =
|
|
427
|
-
|
|
428
|
-
await hasNextEvent(true);
|
|
600
|
+
const ctrl = new AbortController();
|
|
601
|
+
const sequence = new Sequence<T>(ctrl.signal);
|
|
602
|
+
const emitEvent = (value: T) => {
|
|
603
|
+
sequence(value);
|
|
429
604
|
};
|
|
430
|
-
const unsubscribe = this.on(emitEvent).pre(
|
|
431
|
-
|
|
432
|
-
removeListener(this.hooks, spy);
|
|
433
|
-
queue.splice(0);
|
|
605
|
+
const unsubscribe = this.on(emitEvent).pre(() => {
|
|
606
|
+
ctrl.abort('done');
|
|
434
607
|
});
|
|
435
608
|
|
|
436
609
|
const spy: (typeof this.hooks)[number] = (target = emitEvent, action) => {
|
|
437
610
|
if (target === emitEvent && action === HookType.Remove) {
|
|
438
|
-
void hasNextEvent(false);
|
|
439
611
|
void unsubscribe();
|
|
440
612
|
}
|
|
441
613
|
};
|
|
442
614
|
|
|
443
615
|
this.hooks.push(spy);
|
|
444
|
-
return
|
|
445
|
-
async next() {
|
|
446
|
-
if (!hasNextEvent.disposed) {
|
|
447
|
-
const next = queue.length || (await hasNextEvent);
|
|
448
|
-
if (next) {
|
|
449
|
-
return { value: queue.shift()!, done: false };
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
return { value: undefined, done: true };
|
|
453
|
-
},
|
|
454
|
-
async return(value: unknown) {
|
|
455
|
-
await unsubscribe();
|
|
456
|
-
return { value, done: true };
|
|
457
|
-
},
|
|
458
|
-
};
|
|
616
|
+
return sequence[Symbol.asyncIterator]();
|
|
459
617
|
}
|
|
460
618
|
|
|
461
619
|
/**
|
|
@@ -491,15 +649,15 @@ export class Event<T = unknown, R = unknown> extends Callable<[T], Promise<(void
|
|
|
491
649
|
};
|
|
492
650
|
|
|
493
651
|
const unsubscribe = this.on(emitEvent).pre(() => {
|
|
494
|
-
removeListener(this.hooks,
|
|
652
|
+
removeListener(this.hooks, hook);
|
|
495
653
|
});
|
|
496
654
|
|
|
497
|
-
const
|
|
655
|
+
const hook: (typeof this.hooks)[number] = (target = emitEvent, action) => {
|
|
498
656
|
if (target === emitEvent && action === HookType.Remove) {
|
|
499
657
|
void unsubscribe();
|
|
500
658
|
}
|
|
501
659
|
};
|
|
502
|
-
this.hooks.push(
|
|
660
|
+
this.hooks.push(hook);
|
|
503
661
|
|
|
504
662
|
const result = new Event<PT, R>(unsubscribe);
|
|
505
663
|
return result;
|
|
@@ -850,43 +1008,40 @@ export class Event<T = unknown, R = unknown> extends Callable<[T], Promise<(void
|
|
|
850
1008
|
*
|
|
851
1009
|
*/
|
|
852
1010
|
queue(): Queue<T> {
|
|
853
|
-
const
|
|
854
|
-
|
|
855
|
-
const
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
1011
|
+
const ctrl = new AbortController();
|
|
1012
|
+
const sequence = new Sequence<T>(ctrl.signal);
|
|
1013
|
+
const onEvent = (value: T) => {
|
|
1014
|
+
sequence(value);
|
|
1015
|
+
};
|
|
1016
|
+
const unsubscribe = this.on(onEvent).pre(() => {
|
|
1017
|
+
ctrl.abort('done');
|
|
860
1018
|
});
|
|
861
1019
|
|
|
862
|
-
const pop = async () =>
|
|
863
|
-
if (!queue.length) {
|
|
864
|
-
await valueEvent;
|
|
865
|
-
}
|
|
866
|
-
return queue.shift()!;
|
|
867
|
-
};
|
|
868
|
-
const stop = async () => {
|
|
869
|
-
await unsubscribe();
|
|
870
|
-
done = true;
|
|
871
|
-
await valueEvent();
|
|
872
|
-
};
|
|
1020
|
+
const pop = async () => await sequence;
|
|
873
1021
|
|
|
874
1022
|
return {
|
|
875
1023
|
pop,
|
|
876
|
-
stop
|
|
1024
|
+
stop: async () => {
|
|
1025
|
+
await unsubscribe();
|
|
1026
|
+
},
|
|
877
1027
|
get stopped() {
|
|
878
|
-
return
|
|
1028
|
+
return ctrl.signal.aborted;
|
|
879
1029
|
},
|
|
880
1030
|
then<TResult1 = T, TResult2 = never>(
|
|
881
1031
|
onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null | undefined,
|
|
882
1032
|
onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null | undefined,
|
|
883
1033
|
): Promise<TResult1 | TResult2> {
|
|
884
|
-
return
|
|
1034
|
+
return pop().then(onfulfilled, onrejected);
|
|
885
1035
|
},
|
|
886
1036
|
[Symbol.asyncIterator]() {
|
|
887
1037
|
return {
|
|
888
1038
|
next: async () => {
|
|
889
|
-
|
|
1039
|
+
try {
|
|
1040
|
+
const value = await pop();
|
|
1041
|
+
return { value, done: false };
|
|
1042
|
+
} catch {
|
|
1043
|
+
return { value: undefined, done: true };
|
|
1044
|
+
}
|
|
890
1045
|
},
|
|
891
1046
|
};
|
|
892
1047
|
},
|
|
@@ -933,6 +1088,10 @@ export const merge = <Events extends Event<any, any>[]>(...events: Events): Even
|
|
|
933
1088
|
return mergedEvent;
|
|
934
1089
|
};
|
|
935
1090
|
|
|
1091
|
+
//export const fromIterator = (iterator: Iterator<T>): Event<T> {
|
|
1092
|
+
//
|
|
1093
|
+
//}
|
|
1094
|
+
|
|
936
1095
|
/**
|
|
937
1096
|
* Creates a periodic event that triggers at a specified interval. The event will automatically emit
|
|
938
1097
|
* an incrementing counter value each time it triggers, starting from zero. This function is useful
|