evnty 1.5.3 → 2.0.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/src/index.ts CHANGED
@@ -4,27 +4,42 @@ export interface Unsubscribe {
4
4
  (): void;
5
5
  }
6
6
 
7
- export interface Listener<T extends unknown[], R = unknown> {
8
- (...args: T): MaybePromise<R | void>;
7
+ export interface Listener<T, R = unknown> {
8
+ (event: T): MaybePromise<R | void>;
9
9
  }
10
10
 
11
11
  export interface Dispose {
12
12
  (): void;
13
13
  }
14
14
 
15
- export interface Filter<T extends unknown[]> {
16
- (...args: T): MaybePromise<boolean>;
15
+ export interface Result<T, E> {
16
+ ok: boolean;
17
+ result: T | E;
17
18
  }
18
19
 
19
- export interface Mapper<T extends unknown[], R> {
20
- (...args: T): MaybePromise<R>;
20
+ export interface Resolver<T, P> {
21
+ (event: T): Promise<P>;
21
22
  }
22
23
 
23
- export interface Reducer<T extends unknown[], R> {
24
- (value: R, ...args: T): MaybePromise<R>;
24
+ export interface FilterFunction<T> {
25
+ (event: T): MaybePromise<boolean>;
25
26
  }
26
27
 
27
- export type Listeners<T extends unknown[], R> = Listener<T, R>[];
28
+ export interface Predicate<T, P extends T> {
29
+ (event: T): event is P;
30
+ }
31
+
32
+ export type Filter<T, P extends T> = Predicate<T, P> | FilterFunction<T>;
33
+
34
+ export interface Mapper<T, R> {
35
+ (event: T): MaybePromise<R>;
36
+ }
37
+
38
+ export interface Reducer<T, R> {
39
+ (result: R, event: T): MaybePromise<R>;
40
+ }
41
+
42
+ export type Listeners<T, R> = Listener<T, R>[];
28
43
 
29
44
  /**
30
45
  * An abstract class that extends the built-in Function class. It allows instances of the class
@@ -57,33 +72,33 @@ export class Dismiss extends FunctionExt {
57
72
 
58
73
  async after(task: Task): Promise<void> {
59
74
  await task();
60
- this();
75
+ await this();
61
76
  }
62
77
 
63
- afterTimes(count: number): () => void {
64
- return () => {
78
+ afterTimes(count: number): () => Promise<void> {
79
+ return async () => {
65
80
  if (!--count) {
66
- this();
81
+ await this();
67
82
  }
68
83
  };
69
84
  }
70
85
  }
71
86
 
72
- const eventEmitter = async <A extends unknown[], R>(listeners: Listeners<A, R>, ...args: A) => {
73
- return Promise.all(listeners.map((listener) => listener(...args)));
74
- };
87
+ const eventEmitter = <A, R>(listeners: Listeners<A, R>, event: A): Promise<(void | R)[]> => Promise.all(listeners.map((listener) => listener(event)));
75
88
 
76
- export interface Event<T extends unknown[], R> {
77
- (...args: T): Promise<(R | undefined)[]>;
89
+ type EventType<T> = T extends undefined ? void : T;
90
+
91
+ export interface Event<T = unknown, R = void> {
92
+ (event?: EventType<T>): Promise<(R | undefined)[]>;
78
93
  }
79
94
 
80
95
  export type EventParameters<T> = T extends Event<infer P, unknown> ? P : never;
81
96
 
82
- export type EventResult<T> = T extends Event<unknown[], infer R> ? R : never;
97
+ export type EventResult<T> = T extends Event<unknown, infer R> ? R : never;
83
98
 
84
- export type AllEventsParameters<T extends Event<unknown[], unknown>[]> = { [K in keyof T]: EventParameters<T[K]> }[number];
99
+ export type AllEventsParameters<T extends Event<unknown, unknown>[]> = { [K in keyof T]: EventParameters<T[K]> }[number];
85
100
 
86
- export type AllEventsResults<T extends Event<unknown[], unknown>[]> = { [K in keyof T]: EventResult<T[K]> }[number];
101
+ export type AllEventsResults<T extends Event<unknown, unknown>[]> = { [K in keyof T]: EventResult<T[K]> }[number];
87
102
 
88
103
  /**
89
104
  * A class representing an anonymous event that can be listened to or triggered.
@@ -91,37 +106,7 @@ export type AllEventsResults<T extends Event<unknown[], unknown>[]> = { [K in ke
91
106
  * @typeParam T - The tuple of arguments that the event takes.
92
107
  * @typeParam R - The return type of the event.
93
108
  */
94
- export class Event<T extends unknown[], R = void> extends FunctionExt {
95
- /**
96
- * Merges multiple events into a single event.
97
- * @example
98
- * const inputEvent = Event.merge(mouseEvent, keyboardEvent);
99
- *
100
- * @param events - The events to merge.
101
- * @returns The merged event.
102
- */
103
- static merge<Events extends Event<any[], any>[]>(...events: Events): Event<AllEventsParameters<Events>, AllEventsResults<Events>> {
104
- const mergedEvent = new Event<AllEventsParameters<Events>, AllEventsResults<Events>>();
105
- events.forEach((event) => event.on(mergedEvent));
106
- return mergedEvent;
107
- }
108
-
109
- /**
110
- * Creates an event that triggers at a specified interval.
111
- * @example
112
- * const tickEvent = Event.interval(1000);
113
- * tickEvent.on((tickNumber) => console.log(tickNumber));
114
- *
115
- * @param interval - The interval at which to trigger the event.
116
- * @returns The interval event.
117
- */
118
- static interval(interval: number): Event<[number], void> {
119
- let counter = 0;
120
- const intervalEvent = new Event<[number], void>(() => clearInterval(timerId));
121
- const timerId: ReturnType<typeof setInterval> = setInterval(() => intervalEvent(counter++), interval);
122
- return intervalEvent;
123
- }
124
-
109
+ export class Event<T, R> extends FunctionExt {
125
110
  /**
126
111
  * The array of listeners for the event.
127
112
  */
@@ -143,7 +128,7 @@ export class Event<T extends unknown[], R = void> extends FunctionExt {
143
128
  */
144
129
  constructor(dispose?: Dispose) {
145
130
  const listeners: Listeners<T, R> = [];
146
- const fn = (...args: T) => eventEmitter(listeners, ...args);
131
+ const fn = (event: T) => eventEmitter(listeners, event);
147
132
 
148
133
  super(fn);
149
134
  this.listeners = listeners;
@@ -206,9 +191,9 @@ export class Event<T extends unknown[], R = void> extends FunctionExt {
206
191
  * @returns An object that can be used to remove the listener.
207
192
  */
208
193
  once(listener: Listener<T, R>): Dismiss {
209
- const oneTimeListener = (...args: T) => {
194
+ const oneTimeListener = (event: T) => {
210
195
  this.off(oneTimeListener);
211
- return listener(...args);
196
+ return listener(event);
212
197
  };
213
198
  return this.on(oneTimeListener);
214
199
  }
@@ -224,8 +209,8 @@ export class Event<T extends unknown[], R = void> extends FunctionExt {
224
209
  * Returns a Promise that resolves with the first emitted by the event arguments.
225
210
  * @returns A Promise that resolves with the first emitted by the event.
226
211
  */
227
- toPromise(): Promise<T> {
228
- return new Promise((resolve) => this.once((...args) => resolve(args)));
212
+ onceAsync(): Promise<T> {
213
+ return new Promise((resolve) => this.once((event) => resolve(event)));
229
214
  }
230
215
 
231
216
  /**
@@ -236,13 +221,15 @@ export class Event<T extends unknown[], R = void> extends FunctionExt {
236
221
  * @param filter The filter function to apply to the event.
237
222
  * @returns A new event that only triggers when the provided filter function returns `true`.
238
223
  */
239
- filter<F extends T>(filter: Filter<T>): Event<F, R> {
240
- const dispose = this.on(async (...args: T) => {
241
- if (filteredEvent.size > 0 && (await filter(...args))) {
242
- await filteredEvent(...(args as F));
224
+ filter<P extends T>(predicate: Predicate<T, P>): Event<P, R>;
225
+ filter<P extends T>(filter: FilterFunction<T>): Event<P, R>;
226
+ filter<P extends T>(filter: Filter<T, P>): Event<P, R> {
227
+ const dispose = this.on(async (event: T) => {
228
+ if (filteredEvent.size > 0 && (await filter(event))) {
229
+ await filteredEvent(event as EventType<P>);
243
230
  }
244
231
  });
245
- const filteredEvent = new Event<F, R>(dispose);
232
+ const filteredEvent = new Event<P, R>(dispose);
246
233
  return filteredEvent;
247
234
  }
248
235
 
@@ -255,14 +242,16 @@ export class Event<T extends unknown[], R = void> extends FunctionExt {
255
242
  * @param filter - The filter function.
256
243
  * @returns A new event that will only be triggered once the provided filter function returns `true`.
257
244
  */
258
- first<F extends T>(filter: Filter<T>): Event<F, R> {
259
- const dispose = this.on(async (...args: T) => {
260
- if (filteredEvent.size > 0 && (await filter(...args))) {
261
- dispose();
262
- await filteredEvent(...(args as F));
245
+ first<P extends T>(predicate: Predicate<T, P>): Event<P, R>;
246
+ first<P extends T>(filter: FilterFunction<T>): Event<P, R>;
247
+ first<P extends T>(filter: Filter<T, P>): Event<P, R> {
248
+ const dispose = this.on(async (event: T) => {
249
+ if (filteredEvent.size > 0 && (await filter(event))) {
250
+ await dispose();
251
+ await filteredEvent(event as EventType<P>);
263
252
  }
264
253
  });
265
- const filteredEvent = new Event<F, R>(dispose);
254
+ const filteredEvent = new Event<P, R>(dispose);
266
255
  return filteredEvent;
267
256
  }
268
257
 
@@ -274,14 +263,14 @@ export class Event<T extends unknown[], R = void> extends FunctionExt {
274
263
  * @param mapper A function that maps the values of this event to a new value.
275
264
  * @returns A new event that emits the mapped values.
276
265
  */
277
- map<M, MR = unknown>(mapper: Mapper<T, M>): Event<[M], MR> {
278
- const dispose = this.on(async (...args) => {
266
+ map<M, MR = R>(mapper: Mapper<T, M>): Event<M, MR> {
267
+ const dispose = this.on(async (event) => {
279
268
  if (mappedEvent.size > 0) {
280
- const value = await mapper(...args);
281
- mappedEvent(value);
269
+ const value = await mapper(event);
270
+ await mappedEvent(value as EventType<M>);
282
271
  }
283
272
  });
284
- const mappedEvent = new Event<[M], MR>(dispose);
273
+ const mappedEvent = new Event<M, MR>(dispose);
285
274
  return mappedEvent;
286
275
  }
287
276
 
@@ -300,15 +289,15 @@ export class Event<T extends unknown[], R = void> extends FunctionExt {
300
289
  * @param {A} init The initial value of the accumulated value.
301
290
  * @returns {Event<[A], AR>} A new `Event` that emits the reduced value.
302
291
  */
303
- reduce<A, AR = unknown>(reducer: Reducer<T, A>, init: A): Event<[A], AR> {
292
+ reduce<A, AR = R>(reducer: Reducer<T, A>, init: A): Event<A, AR> {
304
293
  let value = init;
305
- const dispose = this.on(async (...args) => {
294
+ const dispose = this.on(async (event) => {
306
295
  if (reducedEvent.size > 0) {
307
- value = await reducer(value, ...args);
308
- reducedEvent(value);
296
+ value = await reducer(value, event);
297
+ await reducedEvent(value as EventType<A>);
309
298
  }
310
299
  });
311
- const reducedEvent = new Event<[A], AR>(dispose);
300
+ const reducedEvent = new Event<A, AR>(dispose);
312
301
  return reducedEvent;
313
302
  }
314
303
 
@@ -328,9 +317,9 @@ export class Event<T extends unknown[], R = void> extends FunctionExt {
328
317
  */
329
318
  debounce(interval: number): Event<T, R> {
330
319
  let timer: ReturnType<typeof setTimeout>;
331
- const dispose = this.on((...args) => {
320
+ const dispose = this.on((event) => {
332
321
  clearTimeout(timer);
333
- timer = setTimeout(() => debouncedEvent(...args), interval);
322
+ timer = setTimeout(() => debouncedEvent(event as EventType<T>), interval);
334
323
  });
335
324
  const debouncedEvent = new Event<T, R>(dispose);
336
325
  return debouncedEvent;
@@ -338,15 +327,33 @@ export class Event<T extends unknown[], R = void> extends FunctionExt {
338
327
  }
339
328
 
340
329
  /**
341
- * Returns a promise that resolves with the arguments passed to the first invocation of the given event.
330
+ * Merges multiple events into a single event.
331
+ * @example
332
+ * const inputEvent = Event.merge(mouseEvent, keyboardEvent);
333
+ *
334
+ * @param events - The events to merge.
335
+ * @returns The merged event.
336
+ */
337
+ export const merge = <Events extends Event<any, any>[]>(...events: Events): Event<AllEventsParameters<Events>, AllEventsResults<Events>> => {
338
+ const mergedEvent = new Event<AllEventsParameters<Events>, AllEventsResults<Events>>();
339
+ events.forEach((event) => event.on(mergedEvent));
340
+ return mergedEvent;
341
+ };
342
+
343
+ /**
344
+ * Creates an event that triggers at a specified interval.
342
345
  * @example
343
- * const [x, y] = await once(mouseEvent);
346
+ * const tickEvent = Event.interval(1000);
347
+ * tickEvent.on((tickNumber) => console.log(tickNumber));
344
348
  *
345
- * @param event The event to listen for.
346
- * @returns A promise that resolves with the arguments passed to the first invocation of the given event.
349
+ * @param interval - The interval at which to trigger the event.
350
+ * @returns The interval event.
347
351
  */
348
- export const once = <T extends unknown[], R = void>(event: Event<T, R>): Promise<T> => {
349
- return new Promise((resolve) => event.once((...args) => resolve(args)));
352
+ export const createInterval = <R = void>(interval: number): Event<number, R> => {
353
+ let counter = 0;
354
+ const intervalEvent = new Event<number, R>(() => clearInterval(timerId));
355
+ const timerId: ReturnType<typeof setInterval> = setInterval(() => intervalEvent(counter++), interval);
356
+ return intervalEvent;
350
357
  };
351
358
 
352
359
  /**
@@ -361,9 +368,7 @@ export const once = <T extends unknown[], R = void>(event: Event<T, R>): Promise
361
368
  * myEvent.on((str: string) => str.length);
362
369
  * await myEvent('hello'); // [5]
363
370
  */
364
- export const createEvent = <T extends unknown[], R = void>(): Event<T, R> => {
365
- return new Event<T, R>();
366
- };
371
+ export const createEvent = <T, R = void>(): Event<T, R> => new Event<T, R>();
367
372
 
368
373
  export default createEvent;
369
374
 
@@ -379,7 +384,14 @@ export type EventHandler<E> = E extends Event<infer T, infer R> ? Listener<T, R>
379
384
  *
380
385
  * @typeParam E The event type to filter.
381
386
  */
382
- export type EventFilter<E> = Filter<EventParameters<E>>;
387
+ export type EventFilter<E> = FilterFunction<EventParameters<E>>;
388
+
389
+ /**
390
+ * A type helper that extracts the event predicate type
391
+ *
392
+ * @typeParam E The event type to predicate.
393
+ */
394
+ export type EventPredicate<E, P extends EventParameters<E>> = Predicate<EventParameters<E>, P>;
383
395
 
384
396
  /**
385
397
  * A type helper that extracts the event mapper type