evnty 4.5.79 → 4.6.1

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/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
- (event: T): MaybePromise<boolean>;
12
+ (value: T): MaybePromise<boolean>;
13
13
  }
14
14
 
15
15
  export interface Predicate<T, P extends T> {
16
- (event: T): event is P;
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
- (event: T): MaybePromise<R>;
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, event: T): MaybePromise<R>;
30
+ (result: R, value: T): MaybePromise<R>;
27
31
  }
28
32
 
29
33
  export interface Expander<T, R> {
30
- (event: T): MaybePromise<R>;
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 queue: T[] = [];
425
- const hasNextEvent = new Event<boolean>();
426
- const emitEvent = async (value: T) => {
427
- queue.push(value);
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(async () => {
431
- await hasNextEvent.dispose();
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, spy);
652
+ removeListener(this.hooks, hook);
495
653
  });
496
654
 
497
- const spy: (typeof this.hooks)[number] = (target = emitEvent, action) => {
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(spy);
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 queue: T[] = [];
854
- let done = false;
855
- const valueEvent = new Event<void>();
856
-
857
- const unsubscribe = this.on(async (value) => {
858
- queue.push(value);
859
- await valueEvent();
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 done;
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 this.pop().then(onfulfilled, onrejected);
1034
+ return pop().then(onfulfilled, onrejected);
885
1035
  },
886
1036
  [Symbol.asyncIterator]() {
887
1037
  return {
888
1038
  next: async () => {
889
- return { value: await pop(), done };
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