evnty 1.5.2 → 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/README.md +139 -16
- package/build/index.cjs +39 -43
- package/build/index.cjs.map +1 -1
- package/build/index.d.ts +58 -47
- package/build/index.js +34 -41
- package/build/index.js.map +1 -1
- package/package.json +21 -13
- package/src/__tests__/example.js +45 -0
- package/src/__tests__/index.ts +383 -0
- package/src/index.ts +102 -90
package/src/index.ts
CHANGED
|
@@ -4,27 +4,42 @@ export interface Unsubscribe {
|
|
|
4
4
|
(): void;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
export interface Listener<T
|
|
8
|
-
(
|
|
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
|
|
16
|
-
|
|
15
|
+
export interface Result<T, E> {
|
|
16
|
+
ok: boolean;
|
|
17
|
+
result: T | E;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
|
-
export interface
|
|
20
|
-
(
|
|
20
|
+
export interface Resolver<T, P> {
|
|
21
|
+
(event: T): Promise<P>;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
|
-
export interface
|
|
24
|
-
(
|
|
24
|
+
export interface FilterFunction<T> {
|
|
25
|
+
(event: T): MaybePromise<boolean>;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
export
|
|
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 =
|
|
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
|
-
|
|
77
|
-
|
|
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
|
|
97
|
+
export type EventResult<T> = T extends Event<unknown, infer R> ? R : never;
|
|
83
98
|
|
|
84
|
-
export type AllEventsParameters<T extends Event<unknown
|
|
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
|
|
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
|
|
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 = (
|
|
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 = (
|
|
194
|
+
const oneTimeListener = (event: T) => {
|
|
210
195
|
this.off(oneTimeListener);
|
|
211
|
-
return listener(
|
|
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
|
-
|
|
228
|
-
return new Promise((resolve) => this.once((
|
|
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<
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
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<
|
|
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<
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
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<
|
|
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 =
|
|
278
|
-
const dispose = this.on(async (
|
|
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(
|
|
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<
|
|
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 =
|
|
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 (
|
|
294
|
+
const dispose = this.on(async (event) => {
|
|
306
295
|
if (reducedEvent.size > 0) {
|
|
307
|
-
value = await reducer(value,
|
|
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<
|
|
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((
|
|
320
|
+
const dispose = this.on((event) => {
|
|
332
321
|
clearTimeout(timer);
|
|
333
|
-
timer = setTimeout(() => debouncedEvent(
|
|
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
|
-
*
|
|
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
|
|
346
|
+
* const tickEvent = Event.interval(1000);
|
|
347
|
+
* tickEvent.on((tickNumber) => console.log(tickNumber));
|
|
344
348
|
*
|
|
345
|
-
* @param
|
|
346
|
-
* @returns
|
|
349
|
+
* @param interval - The interval at which to trigger the event.
|
|
350
|
+
* @returns The interval event.
|
|
347
351
|
*/
|
|
348
|
-
export const
|
|
349
|
-
|
|
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
|
|
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> =
|
|
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
|