evnty 5.0.0-rc.0 → 5.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 +191 -70
- package/build/callable.cjs +58 -3
- package/build/callable.cjs.map +1 -1
- package/build/callable.d.ts +19 -1
- package/build/callable.js +44 -0
- package/build/callable.js.map +1 -1
- package/build/event.cjs +45 -175
- package/build/event.cjs.map +1 -1
- package/build/event.d.ts +131 -290
- package/build/event.js +43 -176
- package/build/event.js.map +1 -1
- package/build/index.cjs +0 -1
- package/build/index.cjs.map +1 -1
- package/build/index.d.ts +0 -1
- package/build/index.js +0 -1
- package/build/index.js.map +1 -1
- package/build/iterator.cjs +44 -16
- package/build/iterator.cjs.map +1 -1
- package/build/iterator.d.ts +143 -4
- package/build/iterator.js +44 -16
- package/build/iterator.js.map +1 -1
- package/build/sequence.cjs +23 -48
- package/build/sequence.cjs.map +1 -1
- package/build/sequence.d.ts +106 -8
- package/build/sequence.js +24 -49
- package/build/sequence.js.map +1 -1
- package/build/signal.cjs +20 -36
- package/build/signal.cjs.map +1 -1
- package/build/signal.d.ts +92 -7
- package/build/signal.js +21 -37
- package/build/signal.js.map +1 -1
- package/build/types.cjs +11 -0
- package/build/types.cjs.map +1 -1
- package/build/types.d.ts +10 -13
- package/build/types.js +5 -1
- package/build/types.js.map +1 -1
- package/build/utils.cjs +10 -96
- package/build/utils.cjs.map +1 -1
- package/build/utils.d.ts +78 -6
- package/build/utils.js +10 -81
- package/build/utils.js.map +1 -1
- package/package.json +33 -35
- package/src/__tests__/example.js +2 -2
- package/src/index.ts +0 -1
- package/build/ring.cjs +0 -298
- package/build/ring.cjs.map +0 -1
- package/build/ring.d.ts +0 -31
- package/build/ring.js +0 -288
- package/build/ring.js.map +0 -1
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
[![Downloads][downloads-image]][npm-url]
|
|
7
7
|
[![Snyk][snyk-image]][snyk-url]
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Async-first, reactive event handling library for complex event flows with three powerful primitives: **Event** (multi-listener broadcast), **Signal** (promise-like coordination), and **Sequence** (async queue). Built for both browser and Node.js with full TypeScript support.
|
|
10
10
|
|
|
11
11
|
<div align="center">
|
|
12
12
|
<a href="https://github.com/3axap4ehko/evnty">
|
|
@@ -14,34 +14,117 @@
|
|
|
14
14
|
</a>
|
|
15
15
|
<br>
|
|
16
16
|
<br>
|
|
17
|
-
|
|
18
17
|
</div>
|
|
19
18
|
|
|
20
19
|
## Table of Contents
|
|
21
20
|
|
|
21
|
+
- [Core Concepts](#core-concepts)
|
|
22
22
|
- [Motivation](#motivation)
|
|
23
23
|
- [Features](#features)
|
|
24
24
|
- [Platform Support](#platform-support)
|
|
25
25
|
- [Installing](#installing)
|
|
26
26
|
- [Documentation](https://3axap4ehko.github.io/evnty/)
|
|
27
27
|
- [Examples](#examples)
|
|
28
|
-
- [Migration](#migration)
|
|
29
28
|
- [License](#license)
|
|
30
29
|
|
|
30
|
+
## Core Concepts
|
|
31
|
+
|
|
32
|
+
Evnty provides three complementary async primitives, each designed for specific patterns:
|
|
33
|
+
|
|
34
|
+
### 🔊 Event - Multi-Listener Broadcasting
|
|
35
|
+
Events allow multiple listeners to react to values. All registered listeners are called for each emission.
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
const clickEvent = createEvent<{ x: number, y: number }>();
|
|
39
|
+
|
|
40
|
+
// Multiple listeners can subscribe
|
|
41
|
+
clickEvent.on(({ x, y }) => console.log(`Click at ${x},${y}`));
|
|
42
|
+
clickEvent.on(({ x, y }) => updateUI(x, y));
|
|
43
|
+
|
|
44
|
+
// All listeners receive the value
|
|
45
|
+
clickEvent({ x: 100, y: 200 });
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Use Event when:**
|
|
49
|
+
- Multiple components need to react to the same occurrence
|
|
50
|
+
- You need pub/sub or observer pattern
|
|
51
|
+
- Listeners should persist across multiple emissions
|
|
52
|
+
|
|
53
|
+
### 📡 Signal - Promise-Based Coordination
|
|
54
|
+
Signals are for coordinating async operations. When a value is sent, ALL waiting consumers receive it (broadcast).
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
const signal = new Signal<string>();
|
|
58
|
+
|
|
59
|
+
// Multiple consumers can wait
|
|
60
|
+
const promise1 = signal.next();
|
|
61
|
+
const promise2 = signal.next();
|
|
62
|
+
|
|
63
|
+
// Send value - all waiting consumers receive it
|
|
64
|
+
signal('data');
|
|
65
|
+
const [result1, result2] = await Promise.all([promise1, promise2]);
|
|
66
|
+
// result1 === 'data' && result2 === 'data'
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**Use Signal when:**
|
|
70
|
+
- You need one-time notifications
|
|
71
|
+
- Multiple async operations need the same trigger
|
|
72
|
+
- Implementing async coordination patterns
|
|
73
|
+
|
|
74
|
+
### 📦 Sequence - Async Queue (FIFO)
|
|
75
|
+
Sequences are FIFO queues for single-consumer scenarios. Values are consumed in order, with backpressure support.
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
const taskQueue = new Sequence<Task>();
|
|
79
|
+
|
|
80
|
+
// Producer adds tasks
|
|
81
|
+
taskQueue(task1);
|
|
82
|
+
taskQueue(task2);
|
|
83
|
+
taskQueue(task3);
|
|
84
|
+
|
|
85
|
+
// Single consumer processes in order
|
|
86
|
+
for await (const task of taskQueue) {
|
|
87
|
+
await processTask(task); // task1, then task2, then task3
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Use Sequence when:**
|
|
92
|
+
- You need ordered processing (FIFO)
|
|
93
|
+
- Only one consumer should handle each value
|
|
94
|
+
- You want backpressure control with `reserve()`
|
|
95
|
+
|
|
96
|
+
### Key Differences
|
|
97
|
+
|
|
98
|
+
| | Event | Signal | Sequence |
|
|
99
|
+
|---|---|---|---|
|
|
100
|
+
| **Consumers** | Multiple persistent listeners | Multiple one-time receivers | Single consumer |
|
|
101
|
+
| **Delivery** | All listeners called | All waiting get same value | Each value consumed once |
|
|
102
|
+
| **Pattern** | Pub/Sub | Broadcast coordination | Queue/Stream |
|
|
103
|
+
| **Persistence** | Listeners stay registered | Resolves once per `next()` | Values queued until consumed |
|
|
104
|
+
|
|
31
105
|
## Motivation
|
|
32
106
|
|
|
33
|
-
|
|
107
|
+
Traditional event handling in JavaScript/TypeScript has limitations:
|
|
108
|
+
- String-based event names lack type safety
|
|
109
|
+
- No built-in async coordination primitives
|
|
110
|
+
- Missing functional transformations for event streams
|
|
111
|
+
- Complex patterns require extensive boilerplate
|
|
34
112
|
|
|
35
|
-
|
|
113
|
+
Evnty solves these problems by providing:
|
|
114
|
+
- **Type-safe events** with full TypeScript inference
|
|
115
|
+
- **Three specialized primitives** for different async patterns
|
|
116
|
+
- **Rich functional operators** (map, filter, reduce, debounce, batch, etc.)
|
|
117
|
+
- **Composable abstractions** that work together seamlessly
|
|
36
118
|
|
|
37
119
|
## Features
|
|
38
120
|
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
- Full TypeScript
|
|
42
|
-
-
|
|
43
|
-
-
|
|
44
|
-
-
|
|
121
|
+
- **Async-First Design**: Built from the ground up for asynchronous event handling with full Promise support
|
|
122
|
+
- **Functional Programming**: Rich set of operators including map, filter, reduce, debounce, batch, and expand for event stream transformations
|
|
123
|
+
- **Type-Safe**: Full TypeScript support with strong typing and inference throughout the event pipeline
|
|
124
|
+
- **Async Iteration**: Events can be consumed as async iterables using for-await-of loops
|
|
125
|
+
- **Event Composition**: Merge, combine, and transform multiple event streams into new events
|
|
126
|
+
- **Minimal Dependencies**: Lightweight with only essential dependencies for optimal bundle size
|
|
127
|
+
- **Universal**: Works seamlessly in both browser and Node.js environments, including service workers
|
|
45
128
|
|
|
46
129
|
## Platform Support
|
|
47
130
|
|
|
@@ -78,71 +161,109 @@ npm install evnty
|
|
|
78
161
|
|
|
79
162
|
## Examples
|
|
80
163
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
//
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
const
|
|
138
|
-
|
|
164
|
+
### Event - Multi-Listener Pattern
|
|
165
|
+
```typescript
|
|
166
|
+
import { createEvent } from 'evnty';
|
|
167
|
+
|
|
168
|
+
// Create a typed event
|
|
169
|
+
const userEvent = createEvent<{ id: number, name: string }>();
|
|
170
|
+
|
|
171
|
+
// Multiple listeners
|
|
172
|
+
userEvent.on(user => console.log('Logger:', user));
|
|
173
|
+
userEvent.on(user => updateUI(user));
|
|
174
|
+
userEvent.on(user => saveToCache(user));
|
|
175
|
+
|
|
176
|
+
// Emit - all listeners are called
|
|
177
|
+
userEvent({ id: 1, name: 'Alice' });
|
|
178
|
+
|
|
179
|
+
// Functional transformations
|
|
180
|
+
const adminEvent = userEvent
|
|
181
|
+
.filter(user => user.id < 100)
|
|
182
|
+
.map(user => ({ ...user, role: 'admin' }));
|
|
183
|
+
|
|
184
|
+
// Async iteration
|
|
185
|
+
for await (const user of userEvent) {
|
|
186
|
+
console.log('User event:', user);
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Signal - Async Coordination
|
|
191
|
+
```typescript
|
|
192
|
+
import { Signal } from 'evnty';
|
|
193
|
+
|
|
194
|
+
// Coordinate multiple async operations
|
|
195
|
+
const dataSignal = new Signal<Buffer>();
|
|
196
|
+
|
|
197
|
+
// Multiple operations wait for the same data
|
|
198
|
+
async function processA() {
|
|
199
|
+
const data = await dataSignal.next();
|
|
200
|
+
// Process data in way A
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
async function processB() {
|
|
204
|
+
const data = await dataSignal.next();
|
|
205
|
+
// Process data in way B
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Start both processors
|
|
209
|
+
Promise.all([processA(), processB()]);
|
|
210
|
+
|
|
211
|
+
// Both receive the same data when it arrives
|
|
212
|
+
dataSignal(Buffer.from('shared data'));
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Sequence - Task Queue
|
|
216
|
+
```typescript
|
|
217
|
+
import { Sequence } from 'evnty';
|
|
218
|
+
|
|
219
|
+
// Create a task queue
|
|
220
|
+
const taskQueue = new Sequence<() => Promise<void>>();
|
|
221
|
+
|
|
222
|
+
// Single consumer processes tasks in order
|
|
223
|
+
(async () => {
|
|
224
|
+
for await (const task of taskQueue) {
|
|
225
|
+
await task();
|
|
226
|
+
console.log('Task completed');
|
|
227
|
+
}
|
|
228
|
+
})();
|
|
229
|
+
|
|
230
|
+
// Multiple producers add tasks
|
|
231
|
+
taskQueue(async () => fetchData());
|
|
232
|
+
taskQueue(async () => processData());
|
|
233
|
+
taskQueue(async () => saveResults());
|
|
234
|
+
|
|
235
|
+
// Backpressure control
|
|
236
|
+
await taskQueue.reserve(10); // Wait until queue has ≤10 items
|
|
237
|
+
taskQueue(async () => nonUrgentTask());
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Combining Primitives
|
|
241
|
+
```typescript
|
|
242
|
+
// Event + Signal for request/response pattern
|
|
243
|
+
const requestEvent = createEvent<Request>();
|
|
244
|
+
const responseSignal = new Signal<Response>();
|
|
245
|
+
|
|
246
|
+
requestEvent.on(async (req) => {
|
|
247
|
+
const response = await handleRequest(req);
|
|
248
|
+
responseSignal(response);
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
// Event + Sequence for buffered processing
|
|
252
|
+
const dataEvent = createEvent<Data>();
|
|
253
|
+
const processQueue = new Sequence<Data>();
|
|
254
|
+
|
|
255
|
+
dataEvent.on(data => processQueue(data));
|
|
139
256
|
|
|
257
|
+
// Process with controlled concurrency
|
|
258
|
+
for await (const data of processQueue) {
|
|
259
|
+
await processWithRateLimit(data);
|
|
260
|
+
}
|
|
140
261
|
```
|
|
141
262
|
|
|
142
263
|
## License
|
|
143
264
|
|
|
144
265
|
License [The MIT License](./LICENSE)
|
|
145
|
-
Copyright (c)
|
|
266
|
+
Copyright (c) 2025 Ivan Zakharchanka
|
|
146
267
|
|
|
147
268
|
[npm-url]: https://www.npmjs.com/package/evnty
|
|
148
269
|
[downloads-image]: https://img.shields.io/npm/dw/evnty.svg?maxAge=43200
|
package/build/callable.cjs
CHANGED
|
@@ -2,16 +2,71 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", {
|
|
3
3
|
value: true
|
|
4
4
|
});
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get AsyncCallable () {
|
|
13
|
+
return AsyncCallable;
|
|
14
|
+
},
|
|
15
|
+
get Callable () {
|
|
8
16
|
return Callable;
|
|
17
|
+
},
|
|
18
|
+
get CallableAsyncIterator () {
|
|
19
|
+
return CallableAsyncIterator;
|
|
9
20
|
}
|
|
10
21
|
});
|
|
11
22
|
class Callable {
|
|
23
|
+
static{
|
|
24
|
+
Object.setPrototypeOf(Callable.prototype, Function.prototype);
|
|
25
|
+
}
|
|
12
26
|
constructor(func){
|
|
13
27
|
return Object.setPrototypeOf(func, new.target.prototype);
|
|
14
28
|
}
|
|
15
29
|
}
|
|
30
|
+
class AsyncCallable extends Callable {
|
|
31
|
+
constructor(func){
|
|
32
|
+
super(func);
|
|
33
|
+
}
|
|
34
|
+
catch(onrejected) {
|
|
35
|
+
return this.next().catch(onrejected);
|
|
36
|
+
}
|
|
37
|
+
finally(onfinally) {
|
|
38
|
+
return this.next().finally(onfinally);
|
|
39
|
+
}
|
|
40
|
+
then(onfulfilled, onrejected) {
|
|
41
|
+
return this.next().then(onfulfilled, onrejected);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
class CallableAsyncIterator extends AsyncCallable {
|
|
45
|
+
[Symbol.asyncIterator]() {
|
|
46
|
+
return {
|
|
47
|
+
next: async ()=>{
|
|
48
|
+
try {
|
|
49
|
+
const value = await this.next();
|
|
50
|
+
return {
|
|
51
|
+
value,
|
|
52
|
+
done: false
|
|
53
|
+
};
|
|
54
|
+
} catch {
|
|
55
|
+
return {
|
|
56
|
+
value: undefined,
|
|
57
|
+
done: true
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
return: ()=>{
|
|
62
|
+
this[Symbol.dispose]();
|
|
63
|
+
return Promise.resolve({
|
|
64
|
+
value: undefined,
|
|
65
|
+
done: true
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
16
71
|
|
|
17
72
|
//# sourceMappingURL=callable.cjs.map
|
package/build/callable.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/callable.ts"],"sourcesContent":["import { Fn } from './types.js';\n/**\n * @internal\n */\nexport interface Callable<T extends unknown[], R> {\n (...args: T): R;\n}\n\n/**\n * An abstract class that extends the built-in Function class. It allows instances of the class\n * to be called as functions. When an instance of Callable is called as a function, it will\n * call the function passed to its constructor with the same arguments.\n * @internal\n */\n\nexport abstract class Callable<T, R> {\n constructor(func: Fn<T, R>) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return Object.setPrototypeOf(func, new.target.prototype);\n }\n}\n"],"names":["
|
|
1
|
+
{"version":3,"sources":["../src/callable.ts"],"sourcesContent":["import { Fn, Promiseable } from './types.js';\n/**\n * @internal\n */\nexport interface Callable<T extends unknown[], R> {\n (...args: T): R;\n}\n\n/**\n * An abstract class that extends the built-in Function class. It allows instances of the class\n * to be called as functions. When an instance of Callable is called as a function, it will\n * call the function passed to its constructor with the same arguments.\n * @internal\n */\n\nexport abstract class Callable<T, R> {\n static {\n Object.setPrototypeOf(Callable.prototype, Function.prototype);\n }\n\n constructor(func: Fn<T, R>) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return Object.setPrototypeOf(func, new.target.prototype);\n }\n}\n\n/**\n * @internal\n */\nexport abstract class AsyncCallable<T, R> extends Callable<[T], R> implements Promiseable<T>, Promise<T> {\n constructor(func: Fn<[T], R>) {\n super(func);\n }\n\n abstract [Symbol.toStringTag]: string;\n abstract next(): Promise<T>;\n\n catch<OK = never>(onrejected?: ((reason: any) => OK | PromiseLike<OK>) | null): Promise<T | OK> {\n return this.next().catch(onrejected);\n }\n\n finally(onfinally?: (() => void) | null): Promise<T> {\n return this.next().finally(onfinally);\n }\n\n then<OK = T, ERR = never>(\n onfulfilled?: ((value: T) => OK | PromiseLike<OK>) | null,\n onrejected?: ((reason: unknown) => ERR | PromiseLike<ERR>) | null,\n ): Promise<OK | ERR> {\n return this.next().then(onfulfilled, onrejected);\n }\n}\n\n/**\n * @internal\n */\nexport abstract class CallableAsyncIterator<T, R> extends AsyncCallable<T, R> implements Promiseable<T>, Promise<T>, AsyncIterable<T>, Disposable {\n [Symbol.asyncIterator](): AsyncIterator<T, void, void> {\n return {\n next: async () => {\n try {\n const value = await this.next();\n return { value, done: false };\n } catch {\n return { value: undefined, done: true };\n }\n },\n return: () => {\n this[Symbol.dispose]();\n return Promise.resolve({ value: undefined, done: true });\n },\n };\n }\n abstract [Symbol.dispose](): void;\n}\n"],"names":["AsyncCallable","Callable","CallableAsyncIterator","Object","setPrototypeOf","prototype","Function","func","catch","onrejected","next","finally","onfinally","then","onfulfilled","Symbol","asyncIterator","value","done","undefined","return","dispose","Promise","resolve"],"mappings":";;;;;;;;;;;QA6BsBA;eAAAA;;QAdAC;eAAAA;;QAyCAC;eAAAA;;;AAzCf,MAAeD;IACpB,MAAO;QACLE,OAAOC,cAAc,CAACH,SAASI,SAAS,EAAEC,SAASD,SAAS;IAC9D,CAAC;IAED,YAAYE,IAAc,CAAE;QAE1B,OAAOJ,OAAOC,cAAc,CAACG,MAAM,WAAWF,SAAS;IACzD;AACF;AAKO,MAAeL,sBAA4BC;IAChD,YAAYM,IAAgB,CAAE;QAC5B,KAAK,CAACA;IACR;IAKAC,MAAkBC,UAA2D,EAAmB;QAC9F,OAAO,IAAI,CAACC,IAAI,GAAGF,KAAK,CAACC;IAC3B;IAEAE,QAAQC,SAA+B,EAAc;QACnD,OAAO,IAAI,CAACF,IAAI,GAAGC,OAAO,CAACC;IAC7B;IAEAC,KACEC,WAAyD,EACzDL,UAAiE,EAC9C;QACnB,OAAO,IAAI,CAACC,IAAI,GAAGG,IAAI,CAACC,aAAaL;IACvC;AACF;AAKO,MAAeP,8BAAoCF;IACxD,CAACe,OAAOC,aAAa,CAAC,GAAiC;QACrD,OAAO;YACLN,MAAM;gBACJ,IAAI;oBACF,MAAMO,QAAQ,MAAM,IAAI,CAACP,IAAI;oBAC7B,OAAO;wBAAEO;wBAAOC,MAAM;oBAAM;gBAC9B,EAAE,OAAM;oBACN,OAAO;wBAAED,OAAOE;wBAAWD,MAAM;oBAAK;gBACxC;YACF;YACAE,QAAQ;gBACN,IAAI,CAACL,OAAOM,OAAO,CAAC;gBACpB,OAAOC,QAAQC,OAAO,CAAC;oBAAEN,OAAOE;oBAAWD,MAAM;gBAAK;YACxD;QACF;IACF;AAEF"}
|
package/build/callable.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Fn } from './types.js';
|
|
1
|
+
import { Fn, Promiseable } from './types.js';
|
|
2
2
|
/**
|
|
3
3
|
* @internal
|
|
4
4
|
*/
|
|
@@ -14,3 +14,21 @@ export interface Callable<T extends unknown[], R> {
|
|
|
14
14
|
export declare abstract class Callable<T, R> {
|
|
15
15
|
constructor(func: Fn<T, R>);
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
export declare abstract class AsyncCallable<T, R> extends Callable<[T], R> implements Promiseable<T>, Promise<T> {
|
|
21
|
+
constructor(func: Fn<[T], R>);
|
|
22
|
+
abstract [Symbol.toStringTag]: string;
|
|
23
|
+
abstract next(): Promise<T>;
|
|
24
|
+
catch<OK = never>(onrejected?: ((reason: any) => OK | PromiseLike<OK>) | null): Promise<T | OK>;
|
|
25
|
+
finally(onfinally?: (() => void) | null): Promise<T>;
|
|
26
|
+
then<OK = T, ERR = never>(onfulfilled?: ((value: T) => OK | PromiseLike<OK>) | null, onrejected?: ((reason: unknown) => ERR | PromiseLike<ERR>) | null): Promise<OK | ERR>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* @internal
|
|
30
|
+
*/
|
|
31
|
+
export declare abstract class CallableAsyncIterator<T, R> extends AsyncCallable<T, R> implements Promiseable<T>, Promise<T>, AsyncIterable<T>, Disposable {
|
|
32
|
+
[Symbol.asyncIterator](): AsyncIterator<T, void, void>;
|
|
33
|
+
abstract [Symbol.dispose](): void;
|
|
34
|
+
}
|
package/build/callable.js
CHANGED
|
@@ -1,7 +1,51 @@
|
|
|
1
1
|
export class Callable {
|
|
2
|
+
static{
|
|
3
|
+
Object.setPrototypeOf(Callable.prototype, Function.prototype);
|
|
4
|
+
}
|
|
2
5
|
constructor(func){
|
|
3
6
|
return Object.setPrototypeOf(func, new.target.prototype);
|
|
4
7
|
}
|
|
5
8
|
}
|
|
9
|
+
export class AsyncCallable extends Callable {
|
|
10
|
+
constructor(func){
|
|
11
|
+
super(func);
|
|
12
|
+
}
|
|
13
|
+
catch(onrejected) {
|
|
14
|
+
return this.next().catch(onrejected);
|
|
15
|
+
}
|
|
16
|
+
finally(onfinally) {
|
|
17
|
+
return this.next().finally(onfinally);
|
|
18
|
+
}
|
|
19
|
+
then(onfulfilled, onrejected) {
|
|
20
|
+
return this.next().then(onfulfilled, onrejected);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export class CallableAsyncIterator extends AsyncCallable {
|
|
24
|
+
[Symbol.asyncIterator]() {
|
|
25
|
+
return {
|
|
26
|
+
next: async ()=>{
|
|
27
|
+
try {
|
|
28
|
+
const value = await this.next();
|
|
29
|
+
return {
|
|
30
|
+
value,
|
|
31
|
+
done: false
|
|
32
|
+
};
|
|
33
|
+
} catch {
|
|
34
|
+
return {
|
|
35
|
+
value: undefined,
|
|
36
|
+
done: true
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
return: ()=>{
|
|
41
|
+
this[Symbol.dispose]();
|
|
42
|
+
return Promise.resolve({
|
|
43
|
+
value: undefined,
|
|
44
|
+
done: true
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
6
50
|
|
|
7
51
|
//# sourceMappingURL=callable.js.map
|
package/build/callable.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/callable.ts"],"sourcesContent":["import { Fn } from './types.js';\n/**\n * @internal\n */\nexport interface Callable<T extends unknown[], R> {\n (...args: T): R;\n}\n\n/**\n * An abstract class that extends the built-in Function class. It allows instances of the class\n * to be called as functions. When an instance of Callable is called as a function, it will\n * call the function passed to its constructor with the same arguments.\n * @internal\n */\n\nexport abstract class Callable<T, R> {\n constructor(func: Fn<T, R>) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return Object.setPrototypeOf(func, new.target.prototype);\n }\n}\n"],"names":["Callable","
|
|
1
|
+
{"version":3,"sources":["../src/callable.ts"],"sourcesContent":["import { Fn, Promiseable } from './types.js';\n/**\n * @internal\n */\nexport interface Callable<T extends unknown[], R> {\n (...args: T): R;\n}\n\n/**\n * An abstract class that extends the built-in Function class. It allows instances of the class\n * to be called as functions. When an instance of Callable is called as a function, it will\n * call the function passed to its constructor with the same arguments.\n * @internal\n */\n\nexport abstract class Callable<T, R> {\n static {\n Object.setPrototypeOf(Callable.prototype, Function.prototype);\n }\n\n constructor(func: Fn<T, R>) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return Object.setPrototypeOf(func, new.target.prototype);\n }\n}\n\n/**\n * @internal\n */\nexport abstract class AsyncCallable<T, R> extends Callable<[T], R> implements Promiseable<T>, Promise<T> {\n constructor(func: Fn<[T], R>) {\n super(func);\n }\n\n abstract [Symbol.toStringTag]: string;\n abstract next(): Promise<T>;\n\n catch<OK = never>(onrejected?: ((reason: any) => OK | PromiseLike<OK>) | null): Promise<T | OK> {\n return this.next().catch(onrejected);\n }\n\n finally(onfinally?: (() => void) | null): Promise<T> {\n return this.next().finally(onfinally);\n }\n\n then<OK = T, ERR = never>(\n onfulfilled?: ((value: T) => OK | PromiseLike<OK>) | null,\n onrejected?: ((reason: unknown) => ERR | PromiseLike<ERR>) | null,\n ): Promise<OK | ERR> {\n return this.next().then(onfulfilled, onrejected);\n }\n}\n\n/**\n * @internal\n */\nexport abstract class CallableAsyncIterator<T, R> extends AsyncCallable<T, R> implements Promiseable<T>, Promise<T>, AsyncIterable<T>, Disposable {\n [Symbol.asyncIterator](): AsyncIterator<T, void, void> {\n return {\n next: async () => {\n try {\n const value = await this.next();\n return { value, done: false };\n } catch {\n return { value: undefined, done: true };\n }\n },\n return: () => {\n this[Symbol.dispose]();\n return Promise.resolve({ value: undefined, done: true });\n },\n };\n }\n abstract [Symbol.dispose](): void;\n}\n"],"names":["Callable","Object","setPrototypeOf","prototype","Function","func","AsyncCallable","catch","onrejected","next","finally","onfinally","then","onfulfilled","CallableAsyncIterator","Symbol","asyncIterator","value","done","undefined","return","dispose","Promise","resolve"],"mappings":"AAeA,OAAO,MAAeA;IACpB,MAAO;QACLC,OAAOC,cAAc,CAACF,SAASG,SAAS,EAAEC,SAASD,SAAS;IAC9D,CAAC;IAED,YAAYE,IAAc,CAAE;QAE1B,OAAOJ,OAAOC,cAAc,CAACG,MAAM,WAAWF,SAAS;IACzD;AACF;AAKA,OAAO,MAAeG,sBAA4BN;IAChD,YAAYK,IAAgB,CAAE;QAC5B,KAAK,CAACA;IACR;IAKAE,MAAkBC,UAA2D,EAAmB;QAC9F,OAAO,IAAI,CAACC,IAAI,GAAGF,KAAK,CAACC;IAC3B;IAEAE,QAAQC,SAA+B,EAAc;QACnD,OAAO,IAAI,CAACF,IAAI,GAAGC,OAAO,CAACC;IAC7B;IAEAC,KACEC,WAAyD,EACzDL,UAAiE,EAC9C;QACnB,OAAO,IAAI,CAACC,IAAI,GAAGG,IAAI,CAACC,aAAaL;IACvC;AACF;AAKA,OAAO,MAAeM,8BAAoCR;IACxD,CAACS,OAAOC,aAAa,CAAC,GAAiC;QACrD,OAAO;YACLP,MAAM;gBACJ,IAAI;oBACF,MAAMQ,QAAQ,MAAM,IAAI,CAACR,IAAI;oBAC7B,OAAO;wBAAEQ;wBAAOC,MAAM;oBAAM;gBAC9B,EAAE,OAAM;oBACN,OAAO;wBAAED,OAAOE;wBAAWD,MAAM;oBAAK;gBACxC;YACF;YACAE,QAAQ;gBACN,IAAI,CAACL,OAAOM,OAAO,CAAC;gBACpB,OAAOC,QAAQC,OAAO,CAAC;oBAAEN,OAAOE;oBAAWD,MAAM;gBAAK;YACxD;QACF;IACF;AAEF"}
|