evnty 3.0.39 → 4.0.0-rc-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/LICENSE +18 -10
- package/README.md +386 -116
- package/build/index.cjs +179 -129
- package/build/index.cjs.map +1 -1
- package/build/index.d.ts +225 -180
- package/build/index.js +173 -126
- package/build/index.js.map +1 -1
- package/package.json +29 -26
- package/src/index.ts +383 -277
package/LICENSE
CHANGED
|
@@ -1,13 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
The MIT License (MIT)
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
you may not use this file except in compliance with the License.
|
|
5
|
-
You may obtain a copy of the License at
|
|
3
|
+
Copyright (c) 2019-2024 Ivan Zakharchanka
|
|
6
4
|
|
|
7
|
-
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -14,19 +14,40 @@
|
|
|
14
14
|
- [Features](#features)
|
|
15
15
|
- [Platform Support](#platform-support)
|
|
16
16
|
- [Installing](#installing)
|
|
17
|
-
- [
|
|
18
|
-
- [
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
17
|
+
- [API](#api)
|
|
18
|
+
- [Event](#event)
|
|
19
|
+
- [constructor(dispose?: Callback)](#constructordispose-callback)
|
|
20
|
+
- [error(): Event<unknown>](#error-eventunknown)
|
|
21
|
+
- [size(): number](#size-number)
|
|
22
|
+
- [lacks(listener: Listener<T, R>): boolean](#lackslistener-listenert-r-boolean)
|
|
23
|
+
- [has(listener: Listener<T, R>): boolean](#haslistener-listenert-r-boolean)
|
|
24
|
+
- [off(listener: Listener<T, R>): this](#offlistener-listenert-r-this)
|
|
25
|
+
- [on(listener: Listener<T, R>): Unsubscribe](#onlistener-listenert-r-unsubscribe)
|
|
26
|
+
- [once(listener: Listener<T, R>): Unsubscribe](#oncelistener-listenert-r-unsubscribe)
|
|
27
|
+
- [clear(): this](#clear-this)
|
|
28
|
+
- [then(onfulfilled, onrejected): Promise<TResult1 | TResult2>](#thenonfulfilled-onrejected-promisetresult1--tresult2)
|
|
29
|
+
- [promise(): Promise<T>](#promise-promiset)
|
|
30
|
+
- [Symbol.asyncIterator(): AsyncIterator<T>](#symbolasynciterator-asynciteratort)
|
|
31
|
+
- [pipe(generator): Event<PT, R>](#pipegenerator-eventpt-r)
|
|
32
|
+
- [generator(generator): AsyncGenerator<Awaited<PT>, void, unknown>](#generatorgenerator-asyncgeneratorawaitedpt-void-unknown)
|
|
33
|
+
- [filter(predicate: Predicate<T, P>): Event<P, R>](#filterpredicate-predicatet-p-eventp-r)
|
|
34
|
+
- [filter(filter: FilterFunction<T>): Event<P, R>](#filterfilter-filterfunctiont-eventp-r)
|
|
35
|
+
- [filter(filter: Filter<T, P>): Event<P, R>](#filterfilter-filtert-p-eventp-r)
|
|
36
|
+
- [first(predicate: Predicate<T, P>): Event<P, R>](#firstpredicate-predicatet-p-eventp-r)
|
|
37
|
+
- [first(filter: FilterFunction<T>): Event<P, R>](#firstfilter-filterfunctiont-eventp-r)
|
|
38
|
+
- [first(filter: Filter<T, P>): Event<P, R>](#firstfilter-filtert-p-eventp-r)
|
|
39
|
+
- [map(mapper: Mapper<T, M>): Event<Awaited<M>, MR>](#mapmapper-mappert-m-eventawaitedm-mr)
|
|
40
|
+
- [reduce(reducer: Reducer<T, A>, init?: A): Event<Awaited<A>, AR>](#reducereducer-reducert-a-init-a-eventawaiteda-ar)
|
|
41
|
+
- [reduce(reducer: Reducer<T, A>, ...init: unknown[]): Event<Awaited<A>, AR>](#reducereducer-reducert-a-init-unknown-eventawaiteda-ar)
|
|
42
|
+
- [expand(expander: Expander<T, ET[]>): Event<Awaited<ET>, ER>](#expandexpander-expandert-et-eventawaitedet-er)
|
|
43
|
+
- [orchestrate(conductor: Event<any, any>): Event<T, R>](#orchestrateconductor-eventany-any-eventt-r)
|
|
44
|
+
- [debounce(interval: number): Event<Awaited<T>, unknown>](#debounceinterval-number-eventawaitedt-unknown)
|
|
45
|
+
- [throttle(interval: number): Event<Awaited<T>, unknown>](#throttleinterval-number-eventawaitedt-unknown)
|
|
46
|
+
- [batch(interval: number, size?: number): Event<T[], R>](#batchinterval-number-size-number-eventt-r)
|
|
47
|
+
- [queue(): Queue<T>](#queue-queuet)
|
|
48
|
+
- [merge(...events: Events): Event<AllEventsParameters<Events>, AllEventsResults<Events>>](#mergeevents-events-eventalleventsparametersevents-alleventsresultsevents)
|
|
49
|
+
- [createInterval(interval: number): Event<number, R>](#createintervalinterval-number-eventnumber-r)
|
|
50
|
+
- [createEvent(): Event<T, R>](#createevent-eventt-r)
|
|
30
51
|
- [Examples](#examples)
|
|
31
52
|
- [Migration](#migration)
|
|
32
53
|
- [License](#license)
|
|
@@ -79,66 +100,277 @@ Using npm:
|
|
|
79
100
|
npm install evnty
|
|
80
101
|
```
|
|
81
102
|
|
|
82
|
-
##
|
|
103
|
+
## API
|
|
83
104
|
|
|
84
|
-
###
|
|
105
|
+
### `Event`
|
|
85
106
|
|
|
86
|
-
|
|
107
|
+
A class representing an anonymous event that can be listened to or triggered.
|
|
87
108
|
|
|
88
|
-
|
|
89
|
-
|
|
109
|
+
- @template T - The event type.
|
|
110
|
+
- @template R - The return type of the event.
|
|
90
111
|
|
|
91
|
-
|
|
92
|
-
const clickEvent = createEvent<ClickEvent>();
|
|
112
|
+
#### `constructor(dispose?: Callback)`
|
|
93
113
|
|
|
94
|
-
|
|
95
|
-
const keyPressEvent = createEvent<KeyPressEvent>();
|
|
114
|
+
Creates a new event.
|
|
96
115
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
116
|
+
- @param dispose - A function to call on the event disposal.
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
// Create a click event.
|
|
120
|
+
const clickEvent = new Event<[x: number, y: number], void>();
|
|
121
|
+
clickEvent.on(([x, y]) => console.log(`Clicked at ${x}, ${y}`));
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
#### `error(): Event<unknown>`
|
|
125
|
+
|
|
126
|
+
Error event that emits errors.
|
|
127
|
+
|
|
128
|
+
- @returns {Event<unknown>} The error event.
|
|
129
|
+
|
|
130
|
+
#### `size(): number`
|
|
131
|
+
|
|
132
|
+
The number of listeners for the event.
|
|
133
|
+
|
|
134
|
+
- @readonly
|
|
135
|
+
- @type {number}
|
|
136
|
+
|
|
137
|
+
#### `lacks(listener: Listener<T, R>): boolean`
|
|
138
|
+
|
|
139
|
+
Checks if the given listener is NOT registered for this event.
|
|
140
|
+
|
|
141
|
+
- @param listener - The listener function to check against the registered listeners.
|
|
142
|
+
- @returns `true` if the listener is not already registered; otherwise, `false`.
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
// Check if a listener is not already added
|
|
146
|
+
if (event.lacks(myListener)) {
|
|
147
|
+
event.on(myListener);
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
#### `has(listener: Listener<T, R>): boolean`
|
|
152
|
+
|
|
153
|
+
Checks if the given listener is registered for this event.
|
|
154
|
+
|
|
155
|
+
- @param listener - The listener function to check.
|
|
156
|
+
- @returns `true` if the listener is currently registered; otherwise, `false`.
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
// Verify if a listener is registered
|
|
160
|
+
if (event.has(myListener)) {
|
|
161
|
+
console.log('Listener is already registered');
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
#### `off(listener: Listener<T, R>): this`
|
|
166
|
+
|
|
167
|
+
Removes a specific listener from this event.
|
|
168
|
+
|
|
169
|
+
- @param listener - The listener to remove.
|
|
170
|
+
- @returns The event instance, allowing for method chaining.
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
// Remove a listener
|
|
174
|
+
event.off(myListener);
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
#### `on(listener: Listener<T, R>): Unsubscribe`
|
|
178
|
+
|
|
179
|
+
Registers a listener that gets triggered whenever the event is emitted.
|
|
180
|
+
This is the primary method for adding event handlers that will react to the event being triggered.
|
|
181
|
+
|
|
182
|
+
- @param listener - The function to call when the event occurs.
|
|
183
|
+
- @returns An object that can be used to unsubscribe the listener, ensuring easy cleanup.
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
// Add a listener to an event
|
|
187
|
+
const unsubscribe = event.on((data) => {
|
|
188
|
+
console.log('Event data:', data);
|
|
189
|
+
});
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
#### `once(listener: Listener<T, R>): Unsubscribe`
|
|
193
|
+
|
|
194
|
+
Adds a listener that will be called only once the next time the event is emitted.
|
|
195
|
+
This method is useful for one-time notifications or single-trigger scenarios.
|
|
196
|
+
|
|
197
|
+
- @param listener - The listener to trigger once.
|
|
198
|
+
- @returns An object that can be used to remove the listener if the event has not yet occurred.
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
// Register a one-time listener
|
|
202
|
+
const onceUnsubscribe = event.once((data) => {
|
|
203
|
+
console.log('Received data once:', data);
|
|
204
|
+
});
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
#### `clear(): this`
|
|
208
|
+
|
|
209
|
+
Removes all listeners from the event, effectively resetting it. This is useful when you need to
|
|
210
|
+
cleanly dispose of all event handlers to prevent memory leaks or unwanted triggerings after certain conditions.
|
|
211
|
+
|
|
212
|
+
- @returns {this} The instance of the event, allowing for method chaining.
|
|
213
|
+
|
|
214
|
+
```typescript
|
|
215
|
+
const myEvent = new Event();
|
|
216
|
+
myEvent.on((data) => console.log(data));
|
|
217
|
+
myEvent.clear(); // Clears all listeners
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
#### `then(onfulfilled, onrejected): Promise<TResult1 | TResult2>`
|
|
221
|
+
|
|
222
|
+
Enables the `Event` to be used in a Promise chain, resolving with the first emitted value.
|
|
223
|
+
|
|
224
|
+
- @template TResult1 - The type of the fulfilled value returned by `onfulfilled` (defaults to the event's type).
|
|
225
|
+
- @template TResult2 - The type of the rejected value returned by `onrejected` (defaults to `never`).
|
|
226
|
+
- @param onfulfilled - A function called when the event emits its first value.
|
|
227
|
+
- @param onrejected - A function called if an error occurs before the event emits.
|
|
228
|
+
- @returns A Promise that resolves with the result of `onfulfilled` or `onrejected`.
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
const clickEvent = new Event<[number, number]>();
|
|
232
|
+
await clickEvent;
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
#### `promise(): Promise<T>`
|
|
236
|
+
|
|
237
|
+
A promise that resolves with the first emitted value from this event.
|
|
238
|
+
|
|
239
|
+
- @returns {Promise<T>} The promise value.
|
|
240
|
+
|
|
241
|
+
#### `Symbol.asyncIterator(): AsyncIterator<T>`
|
|
242
|
+
|
|
243
|
+
Makes this event iterable using `for await...of` loops.
|
|
244
|
+
|
|
245
|
+
- @returns An async iterator that yields values as they are emitted by this event.
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
// Assuming an event that emits numbers
|
|
249
|
+
const numberEvent = new Event<number>();
|
|
250
|
+
(async () => {
|
|
251
|
+
for await (const num of numberEvent) {
|
|
252
|
+
console.log('Number:', num);
|
|
253
|
+
}
|
|
254
|
+
})();
|
|
255
|
+
await numberEvent(1);
|
|
256
|
+
await numberEvent(2);
|
|
257
|
+
await numberEvent(3);
|
|
100
258
|
```
|
|
101
259
|
|
|
102
|
-
|
|
260
|
+
#### `pipe(generator): Event<PT, R>`
|
|
261
|
+
|
|
262
|
+
Transforms the event's values using a generator function, creating a new `Event` that emits the transformed values.
|
|
263
|
+
|
|
264
|
+
- @template PT - The type of values emitted by the transformed `Event`.
|
|
265
|
+
- @template PR - The return type of the listeners of the transformed `Event`.
|
|
266
|
+
- @param generator - A function that takes the original event's value and returns a generator (sync or async) that yields the transformed values.
|
|
267
|
+
- @returns A new `Event` instance that emits the transformed values.
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
const numbersEvent = new Event<number>();
|
|
271
|
+
const evenNumbersEvent = numbersEvent.pipe(function* (value) {
|
|
272
|
+
if (value % 2 === 0) {
|
|
273
|
+
yield value;
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
evenNumbersEvent.on((evenNumber) => console.log(evenNumber));
|
|
277
|
+
await numbersEvent(1);
|
|
278
|
+
await numbersEvent(2);
|
|
279
|
+
await numbersEvent(3);
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
#### `generator(generator): AsyncGenerator<Awaited<PT>, void, unknown>`
|
|
283
|
+
|
|
284
|
+
Creates an async generator that yields values as they are emitted by this event.
|
|
285
|
+
|
|
286
|
+
- @template PT - The type of values yielded by the async generator.
|
|
287
|
+
- @param generator - An optional function that takes the original event's value and returns a generator (sync or async)
|
|
288
|
+
that yields values to include in the async generator.
|
|
289
|
+
- @returns An async generator that yields values from this event as they occur.
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
const numbersEvent = new Event<number>();
|
|
293
|
+
const evenNumbersEvent = numbersEvent.pipe(function* (value) {
|
|
294
|
+
if (value % 2 === 0) {
|
|
295
|
+
yield value;
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
evenNumbersEvent.on((evenNumber) => console.log(evenNumber));
|
|
299
|
+
await numbersEvent(1);
|
|
300
|
+
await numbersEvent(2);
|
|
301
|
+
await numbersEvent(3);
|
|
302
|
+
```
|
|
103
303
|
|
|
104
|
-
|
|
105
|
-
Supports predicate type guard function and filter function as a more concise variant.
|
|
304
|
+
#### `filter(predicate: Predicate<T, P>): Event<P, R>`
|
|
106
305
|
|
|
107
|
-
|
|
108
|
-
import { Predicate } from 'evnty';
|
|
306
|
+
#### `filter(filter: FilterFunction<T>): Event<P, R>`
|
|
109
307
|
|
|
110
|
-
|
|
111
|
-
type LeftClickEvent = ClickEvent & { button: 1 };
|
|
308
|
+
#### `filter(filter: Filter<T, P>): Event<P, R>`
|
|
112
309
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
const spacePressPredicatedEvent = keyPressEvent.filter(spacePredicate);
|
|
116
|
-
// event type is inferred from the explicitly specified type
|
|
117
|
-
const spacePressFilteredEvent = keyPressEvent.filter<SpacePressEvent>(({ key }) => key === 'Space');
|
|
310
|
+
Filters events, creating a new event that only triggers when the provided filter function returns `true`.
|
|
311
|
+
This method can be used to selectively process events that meet certain criteria.
|
|
118
312
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const
|
|
313
|
+
- @param {Filter<T, P>} predicate The filter function or predicate to apply to each event.
|
|
314
|
+
- @returns {Event<P, R>} A new event that only triggers for filtered events.
|
|
315
|
+
|
|
316
|
+
```typescript
|
|
317
|
+
const keyPressedEvent = new Event<string>();
|
|
318
|
+
const enterPressedEvent = keyPressedEvent.filter((key) => key === 'Enter');
|
|
319
|
+
enterPressedEvent.on(() => console.log('Enter key was pressed.'));
|
|
124
320
|
```
|
|
125
321
|
|
|
126
|
-
|
|
322
|
+
#### `first(predicate: Predicate<T, P>): Event<P, R>`
|
|
323
|
+
|
|
324
|
+
#### `first(filter: FilterFunction<T>): Event<P, R>`
|
|
325
|
+
|
|
326
|
+
#### `first(filter: Filter<T, P>): Event<P, R>`
|
|
127
327
|
|
|
128
|
-
|
|
328
|
+
Creates a new event that will only be triggered once when the provided filter function returns `true`.
|
|
329
|
+
This method is useful for handling one-time conditions in a stream of events.
|
|
129
330
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
const
|
|
331
|
+
- @param {Filter<T, P>} predicate - The filter function or predicate.
|
|
332
|
+
- @returns {Event<P, R>} A new event that will be triggered only once when the filter condition is met.
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
const sizeChangeEvent = new Event<number>();
|
|
336
|
+
const sizeReachedEvent = sizeChangeEvent.first((size) => size > 1024);
|
|
337
|
+
sizeReachedEvent.on(() => console.log('Size threshold exceeded.'));
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
#### `map(mapper: Mapper<T, M>): Event<Awaited<M>, MR>`
|
|
341
|
+
|
|
342
|
+
Transforms the data emitted by this event using a mapping function. Each emitted event is processed by the `mapper`
|
|
343
|
+
function, which returns a new value that is then emitted by the returned `Event` instance. This is useful for data transformation
|
|
344
|
+
or adapting the event's data structure.
|
|
345
|
+
|
|
346
|
+
- @template M The type of data that the mapper function will produce.
|
|
347
|
+
- @template MR The type of data emitted by the mapped event, usually related to or the same as `M`.
|
|
348
|
+
- @param {Mapper<T, M>} mapper A function that takes the original event data and returns the transformed data.
|
|
349
|
+
- @returns {Event<M, MR>} A new `Event` instance that emits the mapped values.
|
|
350
|
+
|
|
351
|
+
```typescript
|
|
352
|
+
// Assuming an event that emits numbers, create a new event that emits their squares.
|
|
353
|
+
const numberEvent = new Event<number>();
|
|
354
|
+
const squaredEvent = numberEvent.map(num => num num);
|
|
355
|
+
squaredEvent.on(squared => console.log('Squared number:', squared));
|
|
356
|
+
await numberEvent(5); // Logs: "Squared number: 25"
|
|
135
357
|
```
|
|
136
358
|
|
|
137
|
-
|
|
359
|
+
#### `reduce(reducer: Reducer<T, A>, init?: A): Event<Awaited<A>, AR>`
|
|
360
|
+
|
|
361
|
+
#### `reduce(reducer: Reducer<T, A>, ...init: unknown[]): Event<Awaited<A>, AR>`
|
|
362
|
+
|
|
363
|
+
Accumulates the values emitted by this event using a reducer function, starting from an initial value. The reducer
|
|
364
|
+
function takes the accumulated value and the latest emitted event data, then returns a new accumulated value. This
|
|
365
|
+
new value is then emitted by the returned `Event` instance. This is particularly useful for accumulating state over time.
|
|
138
366
|
|
|
139
|
-
|
|
367
|
+
- @template A The type of the accumulator value.
|
|
368
|
+
- @template AR The type of data emitted by the reduced event, usually the same as `A`.
|
|
369
|
+
- @param {Reducer<T, A>} reducer A function that takes the current accumulated value and the new event data, returning the new accumulated value.
|
|
370
|
+
- @param {A} init The initial value of the accumulator.
|
|
371
|
+
- @returns {Event<A, AR>} A new `Event` instance that emits the reduced value.
|
|
140
372
|
|
|
141
|
-
```
|
|
373
|
+
```typescript
|
|
142
374
|
const sumEvent = numberEvent.reduce((a, b) => a + b, 0);
|
|
143
375
|
sumEvent.on((sum) => console.log(sum)); // 1, 3, 6
|
|
144
376
|
await sumEvent(1);
|
|
@@ -146,133 +378,177 @@ await sumEvent(2);
|
|
|
146
378
|
await sumEvent(3);
|
|
147
379
|
```
|
|
148
380
|
|
|
149
|
-
|
|
381
|
+
#### `expand(expander: Expander<T, ET[]>): Event<Awaited<ET>, ER>`
|
|
150
382
|
|
|
151
383
|
Transforms each event's data into multiple events using an expander function. The expander function takes
|
|
152
384
|
the original event's data and returns an array of new data elements, each of which will be emitted individually
|
|
153
385
|
by the returned `Event` instance. This method is useful for scenarios where an event's data can naturally
|
|
154
386
|
be expanded into multiple, separate pieces of data which should each trigger further processing independently.
|
|
155
387
|
|
|
156
|
-
|
|
388
|
+
- @template ET - The type of data elements in the array returned by the expander function.
|
|
389
|
+
- @template ER - The type of responses emitted by the expanded event, usually related to or the same as `ET`.
|
|
390
|
+
- @param {Expander<T, ET[]>} expander - A function that takes the original event data and returns an array of new data elements.
|
|
391
|
+
- @returns {Event<ET, ER>} - A new `Event` instance that emits each value from the array returned by the expander function.
|
|
392
|
+
|
|
393
|
+
```typescript
|
|
157
394
|
// Assuming an event that emits a sentence, create a new event that emits each word from the sentence separately.
|
|
158
395
|
const sentenceEvent = new Event<string>();
|
|
159
|
-
const wordEvent = sentenceEvent.expand(sentence => sentence.split(' '));
|
|
160
|
-
wordEvent.on(word => console.log('Word:', word));
|
|
396
|
+
const wordEvent = sentenceEvent.expand((sentence) => sentence.split(' '));
|
|
397
|
+
wordEvent.on((word) => console.log('Word:', word));
|
|
161
398
|
await sentenceEvent('Hello world'); // Logs: "Word: Hello", "Word: world"
|
|
162
399
|
```
|
|
163
400
|
|
|
164
|
-
|
|
401
|
+
#### `orchestrate(conductor: Event<any, any>): Event<T, R>`
|
|
165
402
|
|
|
166
403
|
Creates a new event that emits values based on a conductor event. The orchestrated event will emit the last value
|
|
167
404
|
captured from the original event each time the conductor event is triggered. This method is useful for synchronizing
|
|
168
405
|
events, where the emission of one event controls the timing of another.
|
|
169
406
|
|
|
170
|
-
|
|
407
|
+
- @template T The type of data emitted by the original event.
|
|
408
|
+
- @template R The type of data emitted by the orchestrated event, usually the same as `T`.
|
|
409
|
+
- @param {Event<unknown, unknown>} conductor An event that signals when the orchestrated event should emit.
|
|
410
|
+
- @returns {Event<T, R>} An orchestrated event that emits values based on the conductor's trigger.
|
|
411
|
+
|
|
412
|
+
```typescript
|
|
171
413
|
const rightClickPositionEvent = mouseMoveEvent.orchestrate(mouseRightClickEvent);
|
|
414
|
+
```
|
|
172
415
|
|
|
416
|
+
```typescript
|
|
173
417
|
// An event that emits whenever a "tick" event occurs.
|
|
174
418
|
const tickEvent = new Event<void>();
|
|
175
419
|
const dataEvent = new Event<string>();
|
|
176
420
|
const synchronizedEvent = dataEvent.orchestrate(tickEvent);
|
|
177
|
-
synchronizedEvent.on(data => console.log('Data on tick:', data));
|
|
421
|
+
synchronizedEvent.on((data) => console.log('Data on tick:', data));
|
|
178
422
|
await dataEvent('Hello');
|
|
179
423
|
await dataEvent('World!');
|
|
180
424
|
await tickEvent(); // Logs: "Data on tick: World!"
|
|
181
425
|
```
|
|
182
426
|
|
|
183
|
-
|
|
427
|
+
#### `debounce(interval: number): Event<Awaited<T>, unknown>`
|
|
184
428
|
|
|
185
429
|
Creates a debounced event that delays triggering until after a specified interval has elapsed
|
|
186
430
|
following the last time it was invoked. This method is particularly useful for limiting the rate
|
|
187
431
|
at which a function is executed. Common use cases include handling rapid user inputs, window resizing,
|
|
188
432
|
or scroll events.
|
|
189
433
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
await
|
|
197
|
-
await
|
|
434
|
+
- @param {number} interval - The amount of time to wait (in milliseconds) before firing the debounced event.
|
|
435
|
+
- @returns {Event<T, R>} An event of debounced events.
|
|
436
|
+
|
|
437
|
+
```typescript
|
|
438
|
+
const debouncedEvent = textInputEvent.debounce(100);
|
|
439
|
+
debouncedEvent.on((str) => console.log(str)); // only 'text' is emitted
|
|
440
|
+
await event('t');
|
|
441
|
+
await event('te');
|
|
442
|
+
await event('tex');
|
|
443
|
+
await event('text');
|
|
198
444
|
```
|
|
199
445
|
|
|
200
|
-
|
|
446
|
+
#### `throttle(interval: number): Event<Awaited<T>, unknown>`
|
|
201
447
|
|
|
202
|
-
|
|
203
|
-
time intervals or when the batch reaches a predefined size. This method is useful for grouping
|
|
204
|
-
a high volume of events into manageable chunks, such as logging or processing data in bulk.
|
|
448
|
+
Creates a throttled event that emits values at most once per specified interval.
|
|
205
449
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
450
|
+
This is useful for controlling the rate of event emissions, especially for high-frequency events.
|
|
451
|
+
The throttled event will immediately emit the first value, and then only emit subsequent values
|
|
452
|
+
if the specified interval has passed since the last emission.
|
|
453
|
+
|
|
454
|
+
- @param interval - The time interval (in milliseconds) between allowed emissions.
|
|
455
|
+
- @returns A new Event that emits throttled values.
|
|
456
|
+
|
|
457
|
+
```typescript
|
|
458
|
+
const scrollEvent = new Event();
|
|
459
|
+
const throttledScroll = scrollEvent.throttle(100); // Emit at most every 100ms
|
|
460
|
+
throttledScroll.on(() => console.log('Throttled scroll event'));
|
|
214
461
|
```
|
|
215
462
|
|
|
216
|
-
|
|
217
|
-
Transforms an event into an AsyncIterable that yields values as they are emitted by the event. This allows for the consumption
|
|
218
|
-
of event data using async iteration mechanisms. The iterator generated will yield all emitted values until the event
|
|
219
|
-
signals it should no longer be active.
|
|
463
|
+
#### `batch(interval: number, size?: number): Event<T[], R>`
|
|
220
464
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
const numberIterable = numberEvent.generator();
|
|
465
|
+
Aggregates multiple event emissions into batches and emits the batched events either at specified
|
|
466
|
+
time intervals or when the batch reaches a predefined size. This method is useful for grouping
|
|
467
|
+
a high volume of events into manageable chunks, such as logging or processing data in bulk.
|
|
225
468
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
469
|
+
- @param {number} interval - The time in milliseconds between batch emissions.
|
|
470
|
+
- @param {number} [size] - Optional. The maximum size of each batch. If specified, triggers a batch emission
|
|
471
|
+
once the batch reaches this size, regardless of the interval.
|
|
472
|
+
- @returns {Event<T[], R>} An event of the batched results.
|
|
229
473
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
474
|
+
```typescript
|
|
475
|
+
// Batch messages for bulk processing every 1 second or when 10 messages are collected
|
|
476
|
+
const messageEvent = createEvent<string, void>();
|
|
477
|
+
const batchedMessageEvent = messageEvent.batch(1000, 10);
|
|
478
|
+
batchedMessageEvent.on((messages) => console.log('Batched Messages:', messages));
|
|
233
479
|
```
|
|
234
480
|
|
|
235
|
-
|
|
481
|
+
#### `queue(): Queue<T>`
|
|
236
482
|
|
|
237
483
|
Creates a queue from the event, where each emitted value is sequentially processed. The returned object allows popping elements
|
|
238
484
|
from the queue, ensuring that elements are handled one at a time. This method is ideal for scenarios where order and sequential processing are critical.
|
|
239
485
|
|
|
240
|
-
|
|
486
|
+
- @returns {Queue<T>} An object representing the queue. The 'pop' method retrieves the next element from the queue, while 'stop' halts further processing.
|
|
487
|
+
|
|
488
|
+
```typescript
|
|
241
489
|
// Queueing tasks for sequential execution
|
|
242
490
|
const taskEvent = new Event<string>();
|
|
243
491
|
const taskQueue = taskEvent.queue();
|
|
492
|
+
(async () => {
|
|
493
|
+
console.log('Processing:', await taskQueue.pop()); // Processing: Task 1
|
|
494
|
+
console.log('Processing:', await taskQueue.pop()); // Processing: Task 2
|
|
495
|
+
})();
|
|
244
496
|
await taskEvent('Task 1');
|
|
245
497
|
await taskEvent('Task 2');
|
|
246
|
-
console.log('Processing:', await taskQueue.pop()); // Processing: Task 1
|
|
247
|
-
console.log('Processing:', await taskQueue.pop()); // Processing: Task 2
|
|
248
498
|
```
|
|
249
499
|
|
|
250
|
-
### merge
|
|
500
|
+
### `merge(...events: Events): Event<AllEventsParameters<Events>, AllEventsResults<Events>>`
|
|
251
501
|
|
|
252
502
|
Merges multiple events into a single event. This function takes any number of `Event` instances
|
|
253
503
|
and returns a new `Event` that triggers whenever any of the input events trigger. The parameters
|
|
254
504
|
and results of the merged event are derived from the input events, providing a flexible way to
|
|
255
505
|
handle multiple sources of events in a unified manner.
|
|
256
506
|
|
|
507
|
+
- @template Events - An array of `Event` instances.
|
|
508
|
+
- @param {...Events} events - A rest parameter that takes multiple events to be merged.
|
|
509
|
+
- @returns {Event<AllEventsParameters<Events>, AllEventsResults<Events>>} - Returns a new `Event` instance
|
|
510
|
+
that triggers with the parameters and results of any of the merged input events.
|
|
257
511
|
|
|
258
|
-
```
|
|
259
|
-
import { merge } from 'evnty';
|
|
260
|
-
|
|
512
|
+
```typescript
|
|
261
513
|
// Merging mouse and keyboard events into a single event
|
|
262
514
|
const mouseEvent = createEvent<MouseEvent>();
|
|
263
515
|
const keyboardEvent = createEvent<KeyboardEvent>();
|
|
264
516
|
const inputEvent = merge(mouseEvent, keyboardEvent);
|
|
265
|
-
inputEvent.on(event => console.log('Input event:', event));
|
|
517
|
+
inputEvent.on((event) => console.log('Input event:', event));
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
### `createInterval(interval: number): Event<number, R>`
|
|
521
|
+
|
|
522
|
+
Creates a periodic event that triggers at a specified interval. The event will automatically emit
|
|
523
|
+
an incrementing counter value each time it triggers, starting from zero. This function is useful
|
|
524
|
+
for creating time-based triggers within an application, such as updating UI elements, polling,
|
|
525
|
+
or any other timed operation.
|
|
526
|
+
|
|
527
|
+
- @template R - The return type of the event handler function, defaulting to `void`.
|
|
528
|
+
- @param {number} interval - The interval in milliseconds at which the event should trigger.
|
|
529
|
+
- @returns {Event<number, R>} - An `Event` instance that triggers at the specified interval,
|
|
530
|
+
emitting an incrementing counter value.
|
|
531
|
+
|
|
532
|
+
```typescript
|
|
533
|
+
// Creating an interval event that logs a message every second
|
|
534
|
+
const tickEvent = createInterval(1000);
|
|
535
|
+
tickEvent.on((tickNumber) => console.log('Tick:', tickNumber));
|
|
266
536
|
```
|
|
267
537
|
|
|
268
|
-
###
|
|
538
|
+
### `createEvent(): Event<T, R>`
|
|
269
539
|
|
|
270
|
-
Creates
|
|
540
|
+
Creates a new instance of the `Event` class, which allows for the registration of event handlers that get called when the event is emitted.
|
|
541
|
+
This factory function simplifies the creation of events by encapsulating the instantiation logic, providing a clean and simple API for event creation.
|
|
271
542
|
|
|
272
|
-
|
|
273
|
-
|
|
543
|
+
- @typeParam T - The tuple of argument types that the event will accept.
|
|
544
|
+
- @typeParam R - The return type of the event handler function, which is emitted after processing the event data.
|
|
545
|
+
- @returns {Event<T, R>} - A new instance of the `Event` class, ready to have listeners added to it.
|
|
274
546
|
|
|
275
|
-
|
|
547
|
+
```typescript
|
|
548
|
+
// Create a new event that accepts a string and returns the string length
|
|
549
|
+
const myEvent = createEvent<string, number>();
|
|
550
|
+
myEvent.on((str: string) => str.length);
|
|
551
|
+
myEvent('hello').then((results) => console.log(results)); // Logs: [5]
|
|
276
552
|
```
|
|
277
553
|
|
|
278
554
|
## Examples
|
|
@@ -338,16 +614,10 @@ const messagesBatchEvent = messageEvent.batch(100);
|
|
|
338
614
|
|
|
339
615
|
```
|
|
340
616
|
|
|
341
|
-
## Migration
|
|
342
|
-
|
|
343
|
-
### From v1 to v2
|
|
344
|
-
|
|
345
|
-
A breaking change has been made: events no longer accept a list of arguments. Now, each event accepts a single argument, so simply wrap your arguments in an object. This decision was taken to leverage the benefits of predicate type guards.
|
|
346
|
-
|
|
347
617
|
## License
|
|
348
618
|
|
|
349
|
-
License [
|
|
350
|
-
Copyright (c)
|
|
619
|
+
License [MIT](./LICENSE)
|
|
620
|
+
Copyright (c) 2024 Ivan Zakharchanka
|
|
351
621
|
|
|
352
622
|
[npm-url]: https://www.npmjs.com/package/evnty
|
|
353
623
|
[downloads-image]: https://img.shields.io/npm/dw/evnty.svg?maxAge=43200
|