@just-io/utils 1.5.0 → 2.0.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/README.md +239 -6
- package/dist/cjs/deep-map.js +4 -4
- package/dist/cjs/event-emitter.js +41 -6
- package/dist/mjs/deep-map.js +4 -4
- package/dist/mjs/event-emitter.js +37 -4
- package/dist/types/event-emitter.d.ts +15 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,12 +1,245 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
@just-io/utils
|
|
2
|
+
==============
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
Lightweight TypeScript utility functions.
|
|
5
5
|
|
|
6
6
|
## Installation
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
```bash
|
|
9
|
+
npm install @just-io/utils
|
|
10
|
+
```
|
|
9
11
|
|
|
10
|
-
##
|
|
12
|
+
## Utilities
|
|
11
13
|
|
|
12
|
-
|
|
14
|
+
### debounce / debounceByKey
|
|
15
|
+
|
|
16
|
+
Debounce function calls with optional key-based grouping.
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { debounce, debounceByKey } from '@just-io/utils';
|
|
20
|
+
|
|
21
|
+
// Basic debounce - executes after delay with last arguments
|
|
22
|
+
function setFilterValue(values: string[]): void {
|
|
23
|
+
console.log('Filter:', values);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const debouncedSetFilterValue = debounce(setFilterValue, 1000);
|
|
27
|
+
|
|
28
|
+
debouncedSetFilterValue(['first']);
|
|
29
|
+
// wait 300ms...
|
|
30
|
+
debouncedSetFilterValue(['second']); // Only ['second'] executes after 1000ms
|
|
31
|
+
|
|
32
|
+
// Cancel pending execution
|
|
33
|
+
debouncedSetFilterValue.teardown();
|
|
34
|
+
|
|
35
|
+
// Key-based debounce - separate timers per extracted key
|
|
36
|
+
function notify(event: { type: string; at: number }): void {
|
|
37
|
+
console.log(event.type, event.at);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const debouncedNotify = debounceByKey(notify, (event) => event.type, 1000);
|
|
41
|
+
|
|
42
|
+
debouncedNotify({ type: 'change', at: 0 });
|
|
43
|
+
debouncedNotify({ type: 'update', at: 0 }); // Both execute - different keys
|
|
44
|
+
debouncedNotify({ type: 'change', at: 10 }); // Replaces first 'change', only at:10 executes
|
|
45
|
+
|
|
46
|
+
// Cancel by key or all
|
|
47
|
+
debouncedNotify.teardown({ type: 'change', at: 0 });
|
|
48
|
+
debouncedNotify.teardownAll();
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### memo / memoByKey
|
|
52
|
+
|
|
53
|
+
Memoize function calls - skip execution if arguments haven't changed.
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import { memo, memoByKey } from '@just-io/utils';
|
|
57
|
+
|
|
58
|
+
// Basic memo - only calls when extracted values change
|
|
59
|
+
function notify(event: { type: string; at: number }): void {
|
|
60
|
+
console.log(event.type, event.at);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const memoNotify = memo(notify, (event) => [event.type, event.at]);
|
|
64
|
+
|
|
65
|
+
memoNotify({ type: 'change', at: 0 }); // Executes
|
|
66
|
+
memoNotify({ type: 'change', at: 0 }); // Skipped - same values
|
|
67
|
+
memoNotify({ type: 'change', at: 1 }); // Executes - 'at' changed
|
|
68
|
+
|
|
69
|
+
// Only trigger on changes (skip first call)
|
|
70
|
+
function setFilterValue(values: string[]): void {
|
|
71
|
+
console.log('Filters changed:', values);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const memoSetFilterValue = memo(setFilterValue, (values) => values, true);
|
|
75
|
+
|
|
76
|
+
memoSetFilterValue([]); // Skipped (initial call)
|
|
77
|
+
memoSetFilterValue(['first']); // Executes (values changed)
|
|
78
|
+
|
|
79
|
+
// Key-based memo - separate memo state per key
|
|
80
|
+
function notifyChannel(channel: string, event: { type: string; at: number }): void {
|
|
81
|
+
console.log(channel, event);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const memoNotifyChannel = memoByKey(
|
|
85
|
+
notifyChannel,
|
|
86
|
+
(channel) => channel,
|
|
87
|
+
(channel, event) => [event.type, event.at],
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
memoNotifyChannel('channel1', { type: 'change', at: 0 }); // Executes
|
|
91
|
+
memoNotifyChannel('channel2', { type: 'change', at: 0 }); // Executes (different key)
|
|
92
|
+
memoNotifyChannel('channel1', { type: 'change', at: 0 }); // Skipped
|
|
93
|
+
memoNotifyChannel('channel1', { type: 'change', at: 10 }); // Executes (values changed)
|
|
94
|
+
|
|
95
|
+
// Key-based with onlyChanges
|
|
96
|
+
function setFilter(filter: string, values: string[]): void {
|
|
97
|
+
console.log(filter, values);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const memoSetFilter = memoByKey(
|
|
101
|
+
setFilter,
|
|
102
|
+
(filter) => filter,
|
|
103
|
+
(filter, values) => values,
|
|
104
|
+
true,
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
memoSetFilter('filter1', []); // Skipped (initial)
|
|
108
|
+
memoSetFilter('filter1', ['1']); // Executes (changed)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### DeepMap
|
|
112
|
+
|
|
113
|
+
Map with array keys (nested key paths). Useful for hierarchical data.
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
import { DeepMap } from '@just-io/utils';
|
|
117
|
+
|
|
118
|
+
// Create empty or with initial entries
|
|
119
|
+
const deepMap = new DeepMap<string, string>();
|
|
120
|
+
const withEntries = new DeepMap<string, string>([
|
|
121
|
+
[['one'], 'str'],
|
|
122
|
+
[['one', 'two'], 'str'],
|
|
123
|
+
]);
|
|
124
|
+
|
|
125
|
+
// Copy from another DeepMap
|
|
126
|
+
const copy = new DeepMap(withEntries);
|
|
127
|
+
|
|
128
|
+
// Set and get with array keys
|
|
129
|
+
deepMap.set([], 'root'); // Empty key path
|
|
130
|
+
deepMap.set(['one'], 'first');
|
|
131
|
+
deepMap.set(['one', 'two'], 'nested');
|
|
132
|
+
|
|
133
|
+
deepMap.get(['one']); // 'first'
|
|
134
|
+
deepMap.get(['one', 'two']); // 'nested'
|
|
135
|
+
deepMap.get(['missing']); // undefined
|
|
136
|
+
|
|
137
|
+
// Check existence
|
|
138
|
+
deepMap.has(['one']); // true
|
|
139
|
+
deepMap.has(['missing']); // false
|
|
140
|
+
|
|
141
|
+
// Delete entries
|
|
142
|
+
deepMap.delete(['one', 'two']); // returns true
|
|
143
|
+
deepMap.delete(['missing']); // returns false
|
|
144
|
+
|
|
145
|
+
// Take: get and delete in one operation
|
|
146
|
+
const value = deepMap.take(['one']); // 'first', now deleted
|
|
147
|
+
deepMap.take(['missing']); // undefined
|
|
148
|
+
|
|
149
|
+
// Size and clear
|
|
150
|
+
deepMap.size; // number of entries
|
|
151
|
+
deepMap.clear(); // remove all
|
|
152
|
+
|
|
153
|
+
// Iteration
|
|
154
|
+
deepMap.forEach((value, key) => console.log(key, value));
|
|
155
|
+
|
|
156
|
+
for (const [key, value] of deepMap) {
|
|
157
|
+
console.log(key, value);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
Array.from(deepMap.entries()); // [[key, value], ...]
|
|
161
|
+
Array.from(deepMap.keys()); // [key, ...]
|
|
162
|
+
Array.from(deepMap.values()); // [value, ...]
|
|
163
|
+
|
|
164
|
+
// Clone subtree (non-destructive)
|
|
165
|
+
deepMap.set(['one'], 'str');
|
|
166
|
+
deepMap.set(['one', 'two'], 'str');
|
|
167
|
+
const cloned = deepMap.clone(['one']);
|
|
168
|
+
// cloned: [[], 'str'], [['two'], 'str']
|
|
169
|
+
|
|
170
|
+
// Extract subtree (removes from original)
|
|
171
|
+
const extracted = deepMap.extract(['one']);
|
|
172
|
+
// extracted has the subtree, deepMap no longer has it
|
|
173
|
+
|
|
174
|
+
// Append entries under a prefix
|
|
175
|
+
deepMap.append(['one'], [[['two'], 'str']]);
|
|
176
|
+
// Result: [['one', 'two'], 'str']
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### EventEmitter / Notifier
|
|
180
|
+
|
|
181
|
+
Type-safe event handling.
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
import { EventEmitter, EventTuple, Notifier } from '@just-io/utils';
|
|
185
|
+
|
|
186
|
+
// Notifier - single event type
|
|
187
|
+
type Event = [first: string, second: string];
|
|
188
|
+
|
|
189
|
+
const notifier = new Notifier<Event>();
|
|
190
|
+
|
|
191
|
+
const handler = (first: string, second: string) => console.log(first, second);
|
|
192
|
+
notifier.subscribe(handler);
|
|
193
|
+
notifier.notify('a', 'b'); // logs: a b
|
|
194
|
+
|
|
195
|
+
// One-time subscription
|
|
196
|
+
notifier.subscribe((a, b) => console.log('once:', a, b), { once: true });
|
|
197
|
+
notifier.notify('x', 'y'); // Both handlers called
|
|
198
|
+
notifier.notify('x', 'y'); // Only permanent handler
|
|
199
|
+
|
|
200
|
+
notifier.unsubscribe(handler); // Remove specific
|
|
201
|
+
notifier.unsubscribeAll(); // Remove all
|
|
202
|
+
|
|
203
|
+
// EventEmitter - multiple named events
|
|
204
|
+
type EventMap = {
|
|
205
|
+
one: [first: number];
|
|
206
|
+
two: [first: string, second: number];
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
const emitter = new EventEmitter<EventMap>();
|
|
210
|
+
|
|
211
|
+
emitter.on('one', (first) => console.log('one:', first));
|
|
212
|
+
emitter.on('two', (first, second) => console.log('two:', first, second));
|
|
213
|
+
|
|
214
|
+
emitter.emit('one', 1);
|
|
215
|
+
emitter.emit('two', '1', 2);
|
|
216
|
+
|
|
217
|
+
// One-time listener
|
|
218
|
+
emitter.once('one', (first) => console.log('once:', first));
|
|
219
|
+
|
|
220
|
+
// Emit from tuple (useful for batching)
|
|
221
|
+
type ETuple = EventTuple<EventMap>;
|
|
222
|
+
const events: ETuple[] = [
|
|
223
|
+
['one', 1],
|
|
224
|
+
['two', '2', 1],
|
|
225
|
+
];
|
|
226
|
+
for (const event of events) {
|
|
227
|
+
emitter.emit(...event);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Unsubscribe
|
|
231
|
+
emitter.off('one', handler);
|
|
232
|
+
emitter.unsubscribeAll('one'); // Remove all 'one' handlers
|
|
233
|
+
emitter.unsubscribeAll(); // Remove all handlers
|
|
234
|
+
|
|
235
|
+
// Event store - batch events and emit later
|
|
236
|
+
const store = emitter.makeStore();
|
|
237
|
+
store.add('one', 1);
|
|
238
|
+
store.add('one', 2);
|
|
239
|
+
store.emit(); // Emits both events
|
|
240
|
+
store.emit(); // Does nothing (already emitted)
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## License
|
|
244
|
+
|
|
245
|
+
MIT
|
package/dist/cjs/deep-map.js
CHANGED
|
@@ -33,7 +33,7 @@ class DeepMap extends Map {
|
|
|
33
33
|
}
|
|
34
34
|
set(keys, value) {
|
|
35
35
|
let node = __classPrivateFieldGet(this, _DeepMap_rootNode, "f");
|
|
36
|
-
for (const key of
|
|
36
|
+
for (const key of Array.isArray(keys) ? keys : [keys]) {
|
|
37
37
|
if (!node.children.has(key)) {
|
|
38
38
|
node.children.set(key, {
|
|
39
39
|
children: new Map(),
|
|
@@ -50,7 +50,7 @@ class DeepMap extends Map {
|
|
|
50
50
|
}
|
|
51
51
|
has(keys) {
|
|
52
52
|
let node = __classPrivateFieldGet(this, _DeepMap_rootNode, "f");
|
|
53
|
-
for (const key of
|
|
53
|
+
for (const key of Array.isArray(keys) ? keys : [keys]) {
|
|
54
54
|
if (!node.children.has(key)) {
|
|
55
55
|
return false;
|
|
56
56
|
}
|
|
@@ -61,7 +61,7 @@ class DeepMap extends Map {
|
|
|
61
61
|
delete(keys) {
|
|
62
62
|
let node = __classPrivateFieldGet(this, _DeepMap_rootNode, "f");
|
|
63
63
|
const entries = [[undefined, __classPrivateFieldGet(this, _DeepMap_rootNode, "f")]];
|
|
64
|
-
for (const key of
|
|
64
|
+
for (const key of Array.isArray(keys) ? keys : [keys]) {
|
|
65
65
|
if (!node.children.has(key)) {
|
|
66
66
|
return false;
|
|
67
67
|
}
|
|
@@ -129,7 +129,7 @@ class DeepMap extends Map {
|
|
|
129
129
|
}
|
|
130
130
|
[(_DeepMap_rootNode = new WeakMap(), _DeepMap_instances = new WeakSet(), _DeepMap_node = function _DeepMap_node(keys) {
|
|
131
131
|
let node = __classPrivateFieldGet(this, _DeepMap_rootNode, "f");
|
|
132
|
-
for (const key of
|
|
132
|
+
for (const key of Array.isArray(keys) ? keys : [keys]) {
|
|
133
133
|
if (!node.children.has(key)) {
|
|
134
134
|
return undefined;
|
|
135
135
|
}
|
|
@@ -10,9 +10,9 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
|
|
|
10
10
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
11
11
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
12
12
|
};
|
|
13
|
-
var _Notifier_subscribers, _Notifier_onceSubscribers, _EventEmitter_subscribers, _EventEmitter_onceSubscribers;
|
|
13
|
+
var _Notifier_subscribers, _Notifier_onceSubscribers, _EventStore_eventEmitter, _EventStore_eventTuples, _EventEmitter_subscribers, _EventEmitter_onceSubscribers;
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.EventEmitter = exports.Notifier = void 0;
|
|
15
|
+
exports.EventEmitter = exports.EventStore = exports.Notifier = void 0;
|
|
16
16
|
class Notifier {
|
|
17
17
|
constructor() {
|
|
18
18
|
_Notifier_subscribers.set(this, new Set());
|
|
@@ -40,12 +40,38 @@ class Notifier {
|
|
|
40
40
|
}
|
|
41
41
|
});
|
|
42
42
|
}
|
|
43
|
-
|
|
43
|
+
unsubscribeAll() {
|
|
44
44
|
__classPrivateFieldSet(this, _Notifier_subscribers, new Set(), "f");
|
|
45
|
+
__classPrivateFieldSet(this, _Notifier_onceSubscribers, new WeakSet(), "f");
|
|
45
46
|
}
|
|
46
47
|
}
|
|
47
48
|
exports.Notifier = Notifier;
|
|
48
49
|
_Notifier_subscribers = new WeakMap(), _Notifier_onceSubscribers = new WeakMap();
|
|
50
|
+
class EventStore {
|
|
51
|
+
constructor(eventEmitter) {
|
|
52
|
+
_EventStore_eventEmitter.set(this, void 0);
|
|
53
|
+
_EventStore_eventTuples.set(this, []);
|
|
54
|
+
__classPrivateFieldSet(this, _EventStore_eventEmitter, eventEmitter, "f");
|
|
55
|
+
}
|
|
56
|
+
add(event, ...args) {
|
|
57
|
+
__classPrivateFieldGet(this, _EventStore_eventTuples, "f").push([event, ...args]);
|
|
58
|
+
}
|
|
59
|
+
emit() {
|
|
60
|
+
for (const eventTuple of __classPrivateFieldGet(this, _EventStore_eventTuples, "f")) {
|
|
61
|
+
__classPrivateFieldGet(this, _EventStore_eventEmitter, "f").emit(...eventTuple);
|
|
62
|
+
}
|
|
63
|
+
__classPrivateFieldSet(this, _EventStore_eventTuples, [], "f");
|
|
64
|
+
}
|
|
65
|
+
consume(eventStore) {
|
|
66
|
+
__classPrivateFieldGet(this, _EventStore_eventTuples, "f").push(...__classPrivateFieldGet(eventStore, _EventStore_eventTuples, "f"));
|
|
67
|
+
__classPrivateFieldSet(eventStore, _EventStore_eventTuples, [], "f");
|
|
68
|
+
}
|
|
69
|
+
clean() {
|
|
70
|
+
__classPrivateFieldSet(this, _EventStore_eventTuples, [], "f");
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
exports.EventStore = EventStore;
|
|
74
|
+
_EventStore_eventEmitter = new WeakMap(), _EventStore_eventTuples = new WeakMap();
|
|
49
75
|
class EventEmitter {
|
|
50
76
|
constructor() {
|
|
51
77
|
_EventEmitter_subscribers.set(this, {});
|
|
@@ -86,9 +112,18 @@ class EventEmitter {
|
|
|
86
112
|
}
|
|
87
113
|
});
|
|
88
114
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
115
|
+
unsubscribeAll(event) {
|
|
116
|
+
if (event) {
|
|
117
|
+
__classPrivateFieldGet(this, _EventEmitter_subscribers, "f")[event] = new Set();
|
|
118
|
+
__classPrivateFieldGet(this, _EventEmitter_onceSubscribers, "f")[event] = new WeakSet();
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
__classPrivateFieldSet(this, _EventEmitter_subscribers, {}, "f");
|
|
122
|
+
__classPrivateFieldSet(this, _EventEmitter_onceSubscribers, {}, "f");
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
makeStore() {
|
|
126
|
+
return new EventStore(this);
|
|
92
127
|
}
|
|
93
128
|
}
|
|
94
129
|
exports.EventEmitter = EventEmitter;
|
package/dist/mjs/deep-map.js
CHANGED
|
@@ -12,7 +12,7 @@ export class DeepMap extends Map {
|
|
|
12
12
|
}
|
|
13
13
|
#node(keys) {
|
|
14
14
|
let node = this.#rootNode;
|
|
15
|
-
for (const key of
|
|
15
|
+
for (const key of Array.isArray(keys) ? keys : [keys]) {
|
|
16
16
|
if (!node.children.has(key)) {
|
|
17
17
|
return undefined;
|
|
18
18
|
}
|
|
@@ -35,7 +35,7 @@ export class DeepMap extends Map {
|
|
|
35
35
|
}
|
|
36
36
|
set(keys, value) {
|
|
37
37
|
let node = this.#rootNode;
|
|
38
|
-
for (const key of
|
|
38
|
+
for (const key of Array.isArray(keys) ? keys : [keys]) {
|
|
39
39
|
if (!node.children.has(key)) {
|
|
40
40
|
node.children.set(key, {
|
|
41
41
|
children: new Map(),
|
|
@@ -51,7 +51,7 @@ export class DeepMap extends Map {
|
|
|
51
51
|
}
|
|
52
52
|
has(keys) {
|
|
53
53
|
let node = this.#rootNode;
|
|
54
|
-
for (const key of
|
|
54
|
+
for (const key of Array.isArray(keys) ? keys : [keys]) {
|
|
55
55
|
if (!node.children.has(key)) {
|
|
56
56
|
return false;
|
|
57
57
|
}
|
|
@@ -62,7 +62,7 @@ export class DeepMap extends Map {
|
|
|
62
62
|
delete(keys) {
|
|
63
63
|
let node = this.#rootNode;
|
|
64
64
|
const entries = [[undefined, this.#rootNode]];
|
|
65
|
-
for (const key of
|
|
65
|
+
for (const key of Array.isArray(keys) ? keys : [keys]) {
|
|
66
66
|
if (!node.children.has(key)) {
|
|
67
67
|
return false;
|
|
68
68
|
}
|
|
@@ -23,8 +23,32 @@ export class Notifier {
|
|
|
23
23
|
}
|
|
24
24
|
});
|
|
25
25
|
}
|
|
26
|
-
|
|
26
|
+
unsubscribeAll() {
|
|
27
27
|
this.#subscribers = new Set();
|
|
28
|
+
this.#onceSubscribers = new WeakSet();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export class EventStore {
|
|
32
|
+
#eventEmitter;
|
|
33
|
+
#eventTuples = [];
|
|
34
|
+
constructor(eventEmitter) {
|
|
35
|
+
this.#eventEmitter = eventEmitter;
|
|
36
|
+
}
|
|
37
|
+
add(event, ...args) {
|
|
38
|
+
this.#eventTuples.push([event, ...args]);
|
|
39
|
+
}
|
|
40
|
+
emit() {
|
|
41
|
+
for (const eventTuple of this.#eventTuples) {
|
|
42
|
+
this.#eventEmitter.emit(...eventTuple);
|
|
43
|
+
}
|
|
44
|
+
this.#eventTuples = [];
|
|
45
|
+
}
|
|
46
|
+
consume(eventStore) {
|
|
47
|
+
this.#eventTuples.push(...eventStore.#eventTuples);
|
|
48
|
+
eventStore.#eventTuples = [];
|
|
49
|
+
}
|
|
50
|
+
clean() {
|
|
51
|
+
this.#eventTuples = [];
|
|
28
52
|
}
|
|
29
53
|
}
|
|
30
54
|
export class EventEmitter {
|
|
@@ -63,8 +87,17 @@ export class EventEmitter {
|
|
|
63
87
|
}
|
|
64
88
|
});
|
|
65
89
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
90
|
+
unsubscribeAll(event) {
|
|
91
|
+
if (event) {
|
|
92
|
+
this.#subscribers[event] = new Set();
|
|
93
|
+
this.#onceSubscribers[event] = new WeakSet();
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
this.#subscribers = {};
|
|
97
|
+
this.#onceSubscribers = {};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
makeStore() {
|
|
101
|
+
return new EventStore(this);
|
|
69
102
|
}
|
|
70
103
|
}
|
|
@@ -13,7 +13,7 @@ export declare class Notifier<E extends unknown[]> implements Notifiable<E> {
|
|
|
13
13
|
}): this;
|
|
14
14
|
unsubscribe(subscriber: Subscriber<E>): boolean;
|
|
15
15
|
notify(...args: E): void;
|
|
16
|
-
|
|
16
|
+
unsubscribeAll(): void;
|
|
17
17
|
}
|
|
18
18
|
export type EventMap = Record<string, unknown[]>;
|
|
19
19
|
export interface Eventable<E extends EventMap> {
|
|
@@ -21,9 +21,18 @@ export interface Eventable<E extends EventMap> {
|
|
|
21
21
|
once<K extends keyof E>(event: K, subscriber: Subscriber<E[K]>): this;
|
|
22
22
|
off<K extends keyof E>(event: K, subscriber: Subscriber<E[K]>): boolean;
|
|
23
23
|
}
|
|
24
|
-
export type
|
|
24
|
+
export type EventTuple<E extends EventMap> = {
|
|
25
25
|
[K in keyof E]: [K, ...E[K]];
|
|
26
26
|
}[keyof E];
|
|
27
|
+
export declare class EventStore<E extends EventMap> {
|
|
28
|
+
#private;
|
|
29
|
+
constructor(eventEmitter: EventEmitter<E>);
|
|
30
|
+
add<K extends keyof E>(event: K, ...args: E[K]): void;
|
|
31
|
+
add(...eventTuple: EventTuple<E>): void;
|
|
32
|
+
emit(): void;
|
|
33
|
+
consume(eventStore: EventStore<E>): void;
|
|
34
|
+
clean(): void;
|
|
35
|
+
}
|
|
27
36
|
export declare class EventEmitter<E extends EventMap> implements Eventable<E> {
|
|
28
37
|
#private;
|
|
29
38
|
getSuscribers<K extends keyof E>(event: K): Set<Subscriber<E[K]>>;
|
|
@@ -31,6 +40,8 @@ export declare class EventEmitter<E extends EventMap> implements Eventable<E> {
|
|
|
31
40
|
once<K extends keyof E>(event: K, subscriber: Subscriber<E[K]>): this;
|
|
32
41
|
off<K extends keyof E>(event: K, subscriber: Subscriber<E[K]>): boolean;
|
|
33
42
|
emit<K extends keyof E>(event: K, ...args: E[K]): void;
|
|
34
|
-
emit(...
|
|
35
|
-
|
|
43
|
+
emit(...eventTuple: EventTuple<E>): void;
|
|
44
|
+
unsubscribeAll(): void;
|
|
45
|
+
unsubscribeAll<K extends keyof E>(event: K): void;
|
|
46
|
+
makeStore(): EventStore<E>;
|
|
36
47
|
}
|