@byloth/core 2.0.0-rc.1 → 2.0.0-rc.10
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/dist/core.js +1379 -894
- package/dist/core.js.map +1 -1
- package/dist/core.umd.cjs +3 -3
- package/dist/core.umd.cjs.map +1 -1
- package/package.json +8 -10
- package/src/helpers.ts +7 -0
- package/src/index.ts +19 -14
- package/src/models/aggregators/aggregated-async-iterator.ts +129 -81
- package/src/models/aggregators/aggregated-iterator.ts +128 -82
- package/src/models/aggregators/index.ts +1 -3
- package/src/models/aggregators/reduced-iterator.ts +118 -30
- package/src/models/aggregators/types.ts +15 -10
- package/src/models/callbacks/callable-object.ts +23 -0
- package/src/models/callbacks/index.ts +5 -0
- package/src/models/callbacks/publisher.ts +45 -0
- package/src/models/callbacks/switchable-callback.ts +108 -0
- package/src/models/callbacks/types.ts +1 -0
- package/src/models/exceptions/core.ts +3 -3
- package/src/models/exceptions/index.ts +13 -13
- package/src/models/game-loop.ts +9 -9
- package/src/models/index.ts +3 -6
- package/src/models/iterators/smart-async-iterator.ts +109 -23
- package/src/models/iterators/smart-iterator.ts +105 -12
- package/src/models/iterators/types.ts +17 -7
- package/src/models/json/json-storage.ts +2 -3
- package/src/models/json/types.ts +3 -1
- package/src/models/promises/deferred-promise.ts +1 -1
- package/src/models/promises/index.ts +3 -1
- package/src/models/promises/long-running-task.ts +294 -0
- package/src/models/promises/smart-promise.ts +6 -1
- package/src/models/promises/thenable.ts +97 -0
- package/src/models/promises/timed-promise.ts +1 -1
- package/src/models/promises/types.ts +2 -0
- package/src/models/timers/clock.ts +29 -7
- package/src/models/timers/countdown.ts +56 -20
- package/src/models/types.ts +12 -10
- package/src/utils/async.ts +9 -4
- package/src/utils/date.ts +3 -0
- package/src/utils/index.ts +1 -1
- package/src/utils/random.ts +4 -3
- package/src/models/aggregators/aggregator.ts +0 -46
- package/src/models/aggregators/async-aggregator.ts +0 -56
- package/src/models/publisher.ts +0 -39
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { SmartIterator } from "../iterators/index.js";
|
|
2
|
-
import type { GeneratorFunction } from "../iterators/types.js";
|
|
2
|
+
import type { GeneratorFunction, IteratorLike } from "../iterators/types.js";
|
|
3
3
|
|
|
4
4
|
import ReducedIterator from "./reduced-iterator.js";
|
|
5
|
-
import type {
|
|
5
|
+
import type { KeyedIteratee, KeyedTypeGuardIteratee, KeyedReducer } from "./types.js";
|
|
6
6
|
|
|
7
7
|
export default class AggregatedIterator<K extends PropertyKey, T>
|
|
8
8
|
{
|
|
@@ -11,58 +11,52 @@ export default class AggregatedIterator<K extends PropertyKey, T>
|
|
|
11
11
|
public constructor(iterable: Iterable<[K, T]>);
|
|
12
12
|
public constructor(iterator: Iterator<[K, T]>);
|
|
13
13
|
public constructor(generatorFn: GeneratorFunction<[K, T]>);
|
|
14
|
-
public constructor(argument:
|
|
15
|
-
public constructor(argument:
|
|
14
|
+
public constructor(argument: IteratorLike<[K, T]> | GeneratorFunction<[K, T]>);
|
|
15
|
+
public constructor(argument: IteratorLike<[K, T]> | GeneratorFunction<[K, T]>)
|
|
16
16
|
{
|
|
17
17
|
this._elements = new SmartIterator(argument);
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
public every(predicate:
|
|
20
|
+
public every(predicate: KeyedIteratee<K, T, boolean>): ReducedIterator<K, boolean>
|
|
21
21
|
{
|
|
22
|
-
const
|
|
22
|
+
const values = new Map<K, [number, boolean]>();
|
|
23
23
|
|
|
24
24
|
for (const [key, element] of this._elements)
|
|
25
25
|
{
|
|
26
|
-
const [index, result] =
|
|
26
|
+
const [index, result] = values.get(key) ?? [0, true];
|
|
27
27
|
|
|
28
28
|
if (!(result)) { continue; }
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
values.set(key, [index + 1, predicate(key, element, index)]);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
return new ReducedIterator(function* ()
|
|
34
34
|
{
|
|
35
|
-
for (const [key, [_, result]] of
|
|
36
|
-
{
|
|
37
|
-
yield [key, result];
|
|
38
|
-
}
|
|
35
|
+
for (const [key, [_, result]] of values) { yield [key, result]; }
|
|
39
36
|
});
|
|
40
37
|
}
|
|
41
|
-
public some(predicate:
|
|
38
|
+
public some(predicate: KeyedIteratee<K, T, boolean>): ReducedIterator<K, boolean>
|
|
42
39
|
{
|
|
43
|
-
const
|
|
40
|
+
const values = new Map<K, [number, boolean]>();
|
|
44
41
|
|
|
45
42
|
for (const [key, element] of this._elements)
|
|
46
43
|
{
|
|
47
|
-
const [index, result] =
|
|
44
|
+
const [index, result] = values.get(key) ?? [0, false];
|
|
48
45
|
|
|
49
46
|
if (result) { continue; }
|
|
50
47
|
|
|
51
|
-
|
|
48
|
+
values.set(key, [index + 1, predicate(key, element, index)]);
|
|
52
49
|
}
|
|
53
50
|
|
|
54
51
|
return new ReducedIterator(function* ()
|
|
55
52
|
{
|
|
56
|
-
for (const [key, [_, result]] of
|
|
57
|
-
{
|
|
58
|
-
yield [key, result];
|
|
59
|
-
}
|
|
53
|
+
for (const [key, [_, result]] of values) { yield [key, result]; }
|
|
60
54
|
});
|
|
61
55
|
}
|
|
62
56
|
|
|
63
|
-
public filter(predicate:
|
|
64
|
-
public filter<S extends T>(predicate:
|
|
65
|
-
public filter(predicate:
|
|
57
|
+
public filter(predicate: KeyedIteratee<K, T, boolean>): AggregatedIterator<K, T>;
|
|
58
|
+
public filter<S extends T>(predicate: KeyedTypeGuardIteratee<K, T, S>): AggregatedIterator<K, S>;
|
|
59
|
+
public filter(predicate: KeyedIteratee<K, T, boolean>): AggregatedIterator<K, T>
|
|
66
60
|
{
|
|
67
61
|
const elements = this._elements;
|
|
68
62
|
|
|
@@ -74,13 +68,13 @@ export default class AggregatedIterator<K extends PropertyKey, T>
|
|
|
74
68
|
{
|
|
75
69
|
const index = indexes.get(key) ?? 0;
|
|
76
70
|
|
|
77
|
-
indexes.set(key, index + 1);
|
|
78
|
-
|
|
79
71
|
if (predicate(key, element, index)) { yield [key, element]; }
|
|
72
|
+
|
|
73
|
+
indexes.set(key, index + 1);
|
|
80
74
|
}
|
|
81
75
|
});
|
|
82
76
|
}
|
|
83
|
-
public map<V>(iteratee:
|
|
77
|
+
public map<V>(iteratee: KeyedIteratee<K, T, V>): AggregatedIterator<K, V>
|
|
84
78
|
{
|
|
85
79
|
const elements = this._elements;
|
|
86
80
|
|
|
@@ -92,29 +86,24 @@ export default class AggregatedIterator<K extends PropertyKey, T>
|
|
|
92
86
|
{
|
|
93
87
|
const index = indexes.get(key) ?? 0;
|
|
94
88
|
|
|
95
|
-
indexes.set(key, index + 1);
|
|
96
|
-
|
|
97
89
|
yield [key, iteratee(key, element, index)];
|
|
90
|
+
|
|
91
|
+
indexes.set(key, index + 1);
|
|
98
92
|
}
|
|
99
93
|
});
|
|
100
94
|
}
|
|
101
|
-
public reduce(reducer:
|
|
102
|
-
public reduce<A>(reducer:
|
|
103
|
-
public reduce<A>(reducer:
|
|
95
|
+
public reduce(reducer: KeyedReducer<K, T, T>): ReducedIterator<K, T>;
|
|
96
|
+
public reduce<A>(reducer: KeyedReducer<K, T, A>, initialValue: (key: K) => A): ReducedIterator<K, A>;
|
|
97
|
+
public reduce<A>(reducer: KeyedReducer<K, T, A>, initialValue?: (key: K) => A): ReducedIterator<K, A>
|
|
104
98
|
{
|
|
105
|
-
const
|
|
99
|
+
const values = new Map<K, [number, A]>();
|
|
106
100
|
|
|
107
101
|
for (const [key, element] of this._elements)
|
|
108
102
|
{
|
|
109
103
|
let index: number;
|
|
110
104
|
let accumulator: A;
|
|
111
105
|
|
|
112
|
-
if (
|
|
113
|
-
{
|
|
114
|
-
[index, accumulator] = accumulators.get(key)!;
|
|
115
|
-
|
|
116
|
-
index += 1;
|
|
117
|
-
}
|
|
106
|
+
if (values.has(key)) { [index, accumulator] = values.get(key)!; }
|
|
118
107
|
else if (initialValue !== undefined)
|
|
119
108
|
{
|
|
120
109
|
index = 0;
|
|
@@ -122,103 +111,161 @@ export default class AggregatedIterator<K extends PropertyKey, T>
|
|
|
122
111
|
}
|
|
123
112
|
else
|
|
124
113
|
{
|
|
125
|
-
|
|
114
|
+
values.set(key, [0, (element as unknown) as A]);
|
|
126
115
|
|
|
127
116
|
continue;
|
|
128
117
|
}
|
|
129
118
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
accumulators.set(key, [index, accumulator]);
|
|
119
|
+
values.set(key, [index + 1, reducer(key, accumulator, element, index)]);
|
|
133
120
|
}
|
|
134
121
|
|
|
135
122
|
return new ReducedIterator(function* ()
|
|
136
123
|
{
|
|
137
|
-
for (const [key, [_, accumulator]] of
|
|
138
|
-
{
|
|
139
|
-
yield [key, accumulator];
|
|
140
|
-
}
|
|
124
|
+
for (const [key, [_, accumulator]] of values) { yield [key, accumulator]; }
|
|
141
125
|
});
|
|
142
126
|
}
|
|
143
127
|
|
|
144
|
-
public
|
|
128
|
+
public flatMap<V>(iteratee: KeyedIteratee<K, T, Iterable<V>>): AggregatedIterator<K, V>
|
|
145
129
|
{
|
|
146
130
|
const elements = this._elements;
|
|
147
131
|
|
|
148
132
|
return new AggregatedIterator(function* ()
|
|
149
133
|
{
|
|
150
|
-
const
|
|
134
|
+
const indexes = new Map<K, number>();
|
|
151
135
|
|
|
152
136
|
for (const [key, element] of elements)
|
|
153
137
|
{
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
if (values.has(element)) { continue; }
|
|
138
|
+
const index = indexes.get(key) ?? 0;
|
|
139
|
+
const values = iteratee(key, element, index);
|
|
157
140
|
|
|
158
|
-
values
|
|
159
|
-
keys.set(key, values);
|
|
141
|
+
for (const value of values) { yield [key, value]; }
|
|
160
142
|
|
|
161
|
-
|
|
143
|
+
indexes.set(key, index + 1);
|
|
162
144
|
}
|
|
163
145
|
});
|
|
164
146
|
}
|
|
165
147
|
|
|
166
|
-
public count
|
|
148
|
+
public drop(count: number): AggregatedIterator<K, T>
|
|
167
149
|
{
|
|
168
|
-
const
|
|
150
|
+
const elements = this._elements;
|
|
169
151
|
|
|
170
|
-
|
|
152
|
+
return new AggregatedIterator(function* ()
|
|
171
153
|
{
|
|
172
|
-
const
|
|
154
|
+
const indexes = new Map<K, number>();
|
|
173
155
|
|
|
174
|
-
|
|
175
|
-
|
|
156
|
+
for (const [key, element] of elements)
|
|
157
|
+
{
|
|
158
|
+
const index = indexes.get(key) ?? 0;
|
|
159
|
+
if (index < count)
|
|
160
|
+
{
|
|
161
|
+
indexes.set(key, index + 1);
|
|
176
162
|
|
|
177
|
-
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
yield [key, element];
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
public take(limit: number): AggregatedIterator<K, T>
|
|
171
|
+
{
|
|
172
|
+
const elements = this._elements;
|
|
173
|
+
|
|
174
|
+
return new AggregatedIterator(function* ()
|
|
178
175
|
{
|
|
179
|
-
|
|
176
|
+
const indexes = new Map<K, number>();
|
|
177
|
+
|
|
178
|
+
for (const [key, element] of elements)
|
|
180
179
|
{
|
|
181
|
-
|
|
180
|
+
const index = indexes.get(key) ?? 0;
|
|
181
|
+
if (index >= limit) { continue; }
|
|
182
|
+
|
|
183
|
+
yield [key, element];
|
|
184
|
+
|
|
185
|
+
indexes.set(key, index + 1);
|
|
182
186
|
}
|
|
183
187
|
});
|
|
184
188
|
}
|
|
185
|
-
|
|
189
|
+
|
|
190
|
+
public find(predicate: KeyedIteratee<K, T, boolean>): ReducedIterator<K, T | undefined>;
|
|
191
|
+
public find<S extends T>(predicate: KeyedTypeGuardIteratee<K, T, S>): ReducedIterator<K, S | undefined>;
|
|
192
|
+
public find(predicate: KeyedIteratee<K, T, boolean>): ReducedIterator<K, T | undefined>
|
|
186
193
|
{
|
|
187
|
-
const
|
|
194
|
+
const values = new Map<K, [number, T | undefined]>();
|
|
188
195
|
|
|
189
196
|
for (const [key, element] of this._elements)
|
|
190
197
|
{
|
|
191
|
-
|
|
198
|
+
let [index, finding] = values.get(key) ?? [0, undefined];
|
|
192
199
|
|
|
193
|
-
|
|
200
|
+
if (finding !== undefined) { continue; }
|
|
201
|
+
if (predicate(key, element, index)) { finding = element; }
|
|
202
|
+
|
|
203
|
+
values.set(key, [index + 1, finding]);
|
|
194
204
|
}
|
|
195
205
|
|
|
196
206
|
return new ReducedIterator(function* ()
|
|
197
207
|
{
|
|
198
|
-
for (const [key,
|
|
208
|
+
for (const [key, [_, finding]] of values) { yield [key, finding]; }
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
public enumerate(): AggregatedIterator<K, [number, T]>
|
|
213
|
+
{
|
|
214
|
+
return this.map((_, value, index) => [index, value]);
|
|
215
|
+
}
|
|
216
|
+
public unique(): AggregatedIterator<K, T>
|
|
217
|
+
{
|
|
218
|
+
const elements = this._elements;
|
|
219
|
+
|
|
220
|
+
return new AggregatedIterator(function* ()
|
|
221
|
+
{
|
|
222
|
+
const keys = new Map<K, Set<T>>();
|
|
223
|
+
|
|
224
|
+
for (const [key, element] of elements)
|
|
199
225
|
{
|
|
226
|
+
const values = keys.get(key) ?? new Set<T>();
|
|
227
|
+
|
|
228
|
+
if (values.has(element)) { continue; }
|
|
229
|
+
|
|
230
|
+
values.add(element);
|
|
231
|
+
keys.set(key, values);
|
|
232
|
+
|
|
200
233
|
yield [key, element];
|
|
201
234
|
}
|
|
202
235
|
});
|
|
203
236
|
}
|
|
204
|
-
|
|
237
|
+
|
|
238
|
+
public count(): ReducedIterator<K, number>
|
|
205
239
|
{
|
|
206
|
-
const
|
|
240
|
+
const counters = new Map<K, number>();
|
|
207
241
|
|
|
208
|
-
for (const [key
|
|
242
|
+
for (const [key] of this._elements)
|
|
209
243
|
{
|
|
210
|
-
|
|
244
|
+
const count = counters.get(key) ?? 0;
|
|
245
|
+
|
|
246
|
+
counters.set(key, count + 1);
|
|
211
247
|
}
|
|
212
248
|
|
|
213
249
|
return new ReducedIterator(function* ()
|
|
214
250
|
{
|
|
215
|
-
for (const [key,
|
|
216
|
-
{
|
|
217
|
-
yield [key, element];
|
|
218
|
-
}
|
|
251
|
+
for (const [key, count] of counters) { yield [key, count]; }
|
|
219
252
|
});
|
|
220
253
|
}
|
|
221
254
|
|
|
255
|
+
public forEach(iteratee: KeyedIteratee<K, T>): void
|
|
256
|
+
{
|
|
257
|
+
const indexes = new Map<K, number>();
|
|
258
|
+
|
|
259
|
+
for (const [key, element] of this._elements)
|
|
260
|
+
{
|
|
261
|
+
const index = indexes.get(key) ?? 0;
|
|
262
|
+
|
|
263
|
+
iteratee(key, element, index);
|
|
264
|
+
|
|
265
|
+
indexes.set(key, index + 1);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
222
269
|
public keys(): SmartIterator<K>
|
|
223
270
|
{
|
|
224
271
|
const elements = this._elements;
|
|
@@ -246,16 +293,15 @@ export default class AggregatedIterator<K extends PropertyKey, T>
|
|
|
246
293
|
|
|
247
294
|
return new SmartIterator<T>(function* ()
|
|
248
295
|
{
|
|
249
|
-
for (const [_, element] of elements)
|
|
250
|
-
{
|
|
251
|
-
yield element;
|
|
252
|
-
}
|
|
296
|
+
for (const [_, element] of elements) { yield element; }
|
|
253
297
|
});
|
|
254
298
|
}
|
|
255
299
|
|
|
256
300
|
public toArray(): T[][]
|
|
257
301
|
{
|
|
258
|
-
|
|
302
|
+
const map = this.toMap();
|
|
303
|
+
|
|
304
|
+
return Array.from(map.values());
|
|
259
305
|
}
|
|
260
306
|
public toMap(): Map<K, T[]>
|
|
261
307
|
{
|
|
@@ -286,5 +332,5 @@ export default class AggregatedIterator<K extends PropertyKey, T>
|
|
|
286
332
|
return groups;
|
|
287
333
|
}
|
|
288
334
|
|
|
289
|
-
public
|
|
335
|
+
public readonly [Symbol.toStringTag]: string = "AggregatedIterator";
|
|
290
336
|
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import Aggregator from "./aggregator.js";
|
|
2
|
-
import AsyncAggregator from "./async-aggregator.js";
|
|
3
1
|
import AggregatedIterator from "./aggregated-iterator.js";
|
|
4
2
|
import AggregatedAsyncIterator from "./aggregated-async-iterator.js";
|
|
5
3
|
import ReducedIterator from "./reduced-iterator.js";
|
|
6
4
|
|
|
7
|
-
export {
|
|
5
|
+
export { AggregatedIterator, AggregatedAsyncIterator, ReducedIterator };
|
|
@@ -2,7 +2,8 @@ import { ValueException } from "../exceptions/index.js";
|
|
|
2
2
|
import { SmartIterator } from "../iterators/index.js";
|
|
3
3
|
import type { GeneratorFunction } from "../iterators/types.js";
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import AggregatedIterator from "./aggregated-iterator.js";
|
|
6
|
+
import type { KeyedIteratee, KeyedReducer, KeyedTypeGuardIteratee } from "./types.js";
|
|
6
7
|
|
|
7
8
|
export default class ReducedIterator<K extends PropertyKey, T>
|
|
8
9
|
{
|
|
@@ -17,56 +18,64 @@ export default class ReducedIterator<K extends PropertyKey, T>
|
|
|
17
18
|
this._elements = new SmartIterator(argument);
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
public
|
|
21
|
-
public filter<S extends T>(predicate: KeyTypeGuardIteratee<K, T, S>): ReducedIterator<K, S>;
|
|
22
|
-
public filter(predicate: KeyIteratee<K, T, boolean>): ReducedIterator<K, T>
|
|
21
|
+
public every(predicate: KeyedIteratee<K, T, boolean>): boolean
|
|
23
22
|
{
|
|
24
|
-
const
|
|
23
|
+
for (const [index, [key, element]] of this._elements.enumerate())
|
|
24
|
+
{
|
|
25
|
+
if (!(predicate(key, element, index))) { return false; }
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
public some(predicate: KeyedIteratee<K, T, boolean>): boolean
|
|
31
|
+
{
|
|
32
|
+
for (const [index, [key, element]] of this._elements.enumerate())
|
|
33
|
+
{
|
|
34
|
+
if (predicate(key, element, index)) { return true; }
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public filter(predicate: KeyedIteratee<K, T, boolean>): ReducedIterator<K, T>;
|
|
41
|
+
public filter<S extends T>(predicate: KeyedTypeGuardIteratee<K, T, S>): ReducedIterator<K, S>;
|
|
42
|
+
public filter(predicate: KeyedIteratee<K, T, boolean>): ReducedIterator<K, T>
|
|
43
|
+
{
|
|
44
|
+
const elements = this._elements.enumerate();
|
|
25
45
|
|
|
26
46
|
return new ReducedIterator(function* ()
|
|
27
47
|
{
|
|
28
|
-
for (const [index, [key, element]] of elements
|
|
48
|
+
for (const [index, [key, element]] of elements)
|
|
29
49
|
{
|
|
30
|
-
if (predicate(key, element, index))
|
|
31
|
-
{
|
|
32
|
-
yield [key, element];
|
|
33
|
-
}
|
|
50
|
+
if (predicate(key, element, index)) { yield [key, element]; }
|
|
34
51
|
}
|
|
35
52
|
});
|
|
36
53
|
}
|
|
37
|
-
public map<V>(iteratee:
|
|
54
|
+
public map<V>(iteratee: KeyedIteratee<K, T, V>): ReducedIterator<K, V>
|
|
38
55
|
{
|
|
39
|
-
const elements = this._elements;
|
|
56
|
+
const elements = this._elements.enumerate();
|
|
40
57
|
|
|
41
58
|
return new ReducedIterator(function* ()
|
|
42
59
|
{
|
|
43
|
-
for (const [index, [key, element]] of elements
|
|
60
|
+
for (const [index, [key, element]] of elements)
|
|
44
61
|
{
|
|
45
62
|
yield [key, iteratee(key, element, index)];
|
|
46
63
|
}
|
|
47
64
|
});
|
|
48
65
|
}
|
|
49
|
-
public reduce(reducer:
|
|
50
|
-
public reduce<A>(reducer:
|
|
51
|
-
public reduce<A>(reducer:
|
|
66
|
+
public reduce(reducer: KeyedReducer<K, T, T>): T;
|
|
67
|
+
public reduce<A>(reducer: KeyedReducer<K, T, A>, initialValue: A): A;
|
|
68
|
+
public reduce<A>(reducer: KeyedReducer<K, T, A>, initialValue?: A): A
|
|
52
69
|
{
|
|
53
70
|
let index = 0;
|
|
54
|
-
let accumulator
|
|
55
|
-
|
|
56
|
-
if (initialValue !== undefined)
|
|
71
|
+
let accumulator = initialValue;
|
|
72
|
+
if (accumulator === undefined)
|
|
57
73
|
{
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
else
|
|
61
|
-
{
|
|
62
|
-
const firstElement = this._elements.next();
|
|
63
|
-
if (firstElement.done)
|
|
64
|
-
{
|
|
65
|
-
throw new ValueException("Cannot reduce an empty iterator without an initial value.");
|
|
66
|
-
}
|
|
74
|
+
const result = this._elements.next();
|
|
75
|
+
if (result.done) { throw new ValueException("Cannot reduce an empty iterator without an initial value."); }
|
|
67
76
|
|
|
77
|
+
accumulator = (result.value[1] as unknown) as A;
|
|
68
78
|
index += 1;
|
|
69
|
-
accumulator = (firstElement.value[1] as unknown) as A;
|
|
70
79
|
}
|
|
71
80
|
|
|
72
81
|
for (const [key, element] of this._elements)
|
|
@@ -79,6 +88,85 @@ export default class ReducedIterator<K extends PropertyKey, T>
|
|
|
79
88
|
return accumulator;
|
|
80
89
|
}
|
|
81
90
|
|
|
91
|
+
public flatMap<V>(iteratee: KeyedIteratee<K, T, Iterable<V>>): AggregatedIterator<K, V>
|
|
92
|
+
{
|
|
93
|
+
const elements = this._elements.enumerate();
|
|
94
|
+
|
|
95
|
+
return new AggregatedIterator(function* ()
|
|
96
|
+
{
|
|
97
|
+
for (const [index, [key, element]] of elements)
|
|
98
|
+
{
|
|
99
|
+
for (const value of iteratee(key, element, index)) { yield [key, value]; }
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
public drop(count: number): ReducedIterator<K, T>
|
|
105
|
+
{
|
|
106
|
+
const elements = this._elements.enumerate();
|
|
107
|
+
|
|
108
|
+
return new ReducedIterator(function* ()
|
|
109
|
+
{
|
|
110
|
+
for (const [index, [key, element]] of elements)
|
|
111
|
+
{
|
|
112
|
+
if (index >= count) { yield [key, element]; }
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
public take(count: number): ReducedIterator<K, T>
|
|
117
|
+
{
|
|
118
|
+
const elements = this._elements.enumerate();
|
|
119
|
+
|
|
120
|
+
return new ReducedIterator(function* ()
|
|
121
|
+
{
|
|
122
|
+
for (const [index, [key, element]] of elements)
|
|
123
|
+
{
|
|
124
|
+
if (index >= count) { break; }
|
|
125
|
+
|
|
126
|
+
yield [key, element];
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
public enumerate(): ReducedIterator<K, [number, T]>
|
|
132
|
+
{
|
|
133
|
+
return this.map((_, element, index) => [index, element]);
|
|
134
|
+
}
|
|
135
|
+
public unique(): ReducedIterator<K, T>
|
|
136
|
+
{
|
|
137
|
+
const elements = this._elements;
|
|
138
|
+
|
|
139
|
+
return new ReducedIterator(function* ()
|
|
140
|
+
{
|
|
141
|
+
const values = new Set<T>();
|
|
142
|
+
|
|
143
|
+
for (const [key, element] of elements)
|
|
144
|
+
{
|
|
145
|
+
if (values.has(element)) { continue; }
|
|
146
|
+
values.add(element);
|
|
147
|
+
|
|
148
|
+
yield [key, element];
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
public count(): number
|
|
154
|
+
{
|
|
155
|
+
let index = 0;
|
|
156
|
+
|
|
157
|
+
for (const _ of this._elements) { index += 1; }
|
|
158
|
+
|
|
159
|
+
return index;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
public forEach(iteratee: KeyedIteratee<K, T>): void
|
|
163
|
+
{
|
|
164
|
+
for (const [index, [key, element]] of this._elements.enumerate())
|
|
165
|
+
{
|
|
166
|
+
iteratee(key, element, index);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
82
170
|
public keys(): SmartIterator<K>
|
|
83
171
|
{
|
|
84
172
|
const elements = this._elements;
|
|
@@ -121,5 +209,5 @@ export default class ReducedIterator<K extends PropertyKey, T>
|
|
|
121
209
|
return Object.fromEntries(this.items()) as Record<K, T>;
|
|
122
210
|
}
|
|
123
211
|
|
|
124
|
-
public
|
|
212
|
+
public readonly [Symbol.toStringTag]: string = "ReducedIterator";
|
|
125
213
|
}
|
|
@@ -1,14 +1,19 @@
|
|
|
1
|
+
/* eslint-disable max-len */
|
|
2
|
+
|
|
1
3
|
import type { MaybePromise } from "../promises/types.js";
|
|
2
4
|
|
|
3
|
-
export type
|
|
4
|
-
export type
|
|
5
|
-
|
|
5
|
+
export type KeyedIteratee<K extends PropertyKey, T, R = void> = (key: K, value: T, index: number) => R;
|
|
6
|
+
export type AsyncKeyedIteratee<K extends PropertyKey, T, R = void> = (key: K, value: T, index: number) => Promise<R>;
|
|
7
|
+
export type MaybeAsyncKeyedIteratee<K extends PropertyKey, T, R = void> = (key: K, value: T, index: number) => MaybePromise<R>;
|
|
8
|
+
|
|
9
|
+
export type KeyedTypeGuardIteratee<K extends PropertyKey, T, R extends T> = (key: K, value: T, index: number) => value is R;
|
|
10
|
+
|
|
11
|
+
// @ts-expect-error - This is an asyncronous type guard keyed-iteratee that guarantees the return value is a promise.
|
|
12
|
+
export type AsyncKeyedTypeGuardIteratee<K extends PropertyKey, T, R extends T> = (key: K, value: T, index: number) => value is Promise<R>;
|
|
6
13
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export type MaybeAsyncKeyTypeGuardIteratee<K extends PropertyKey, T, R extends T> =
|
|
10
|
-
(key: K, value: MaybePromise<T>, index: number) => value is Awaited<R>;
|
|
14
|
+
// @ts-expect-error - This may be an asyncronous type guard keyed-iteratee that guarantees the return value may be a promise.
|
|
15
|
+
export type MaybeAsyncKeyedTypeGuardIteratee<K extends PropertyKey, T, R extends T> = (key: K, value: T, index: number) => value is MaybePromise<R>;
|
|
11
16
|
|
|
12
|
-
export type
|
|
13
|
-
export type
|
|
14
|
-
|
|
17
|
+
export type KeyedReducer<K extends PropertyKey, T, A> = (key: K, accumulator: A, value: T, index: number) => A;
|
|
18
|
+
export type AsyncKeyedReducer<K extends PropertyKey, T, A> = (key: K, accumulator: A, value: T, index: number) => Promise<A>;
|
|
19
|
+
export type MaybeAsyncKeyedReducer<K extends PropertyKey, T, A> = (key: K, accumulator: A, value: T, index: number) => MaybePromise<A>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
|
|
3
|
+
import type { Callback } from "./types.js";
|
|
4
|
+
|
|
5
|
+
export const SmartFunction = (Function as unknown) as
|
|
6
|
+
new<T extends Callback<any[], any> = () => void>(...args: string[]) =>
|
|
7
|
+
(...args: Parameters<T>) => ReturnType<T>;
|
|
8
|
+
|
|
9
|
+
export default abstract class CallableObject<T extends Callback<any[], any> = () => void>
|
|
10
|
+
extends SmartFunction<T>
|
|
11
|
+
{
|
|
12
|
+
public constructor()
|
|
13
|
+
{
|
|
14
|
+
super(`return this.invoke(...arguments);`);
|
|
15
|
+
|
|
16
|
+
const self = this.bind(this);
|
|
17
|
+
Object.setPrototypeOf(this, self);
|
|
18
|
+
|
|
19
|
+
return self as this;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public abstract invoke(...args: Parameters<T>): ReturnType<T>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { ReferenceException } from "../exceptions/index.js";
|
|
2
|
+
|
|
3
|
+
import type { Callback } from "./types.js";
|
|
4
|
+
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6
|
+
export default class Publisher<T extends { [K in keyof T]: Callback<any[], any> } = Record<string, Callback>>
|
|
7
|
+
{
|
|
8
|
+
protected _subscribers: Map<keyof T, Callback<unknown[], unknown>[]>;
|
|
9
|
+
|
|
10
|
+
public constructor()
|
|
11
|
+
{
|
|
12
|
+
this._subscribers = new Map();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public subscribe<K extends keyof T>(event: K, subscriber: T[K]): () => void
|
|
16
|
+
{
|
|
17
|
+
if (!(this._subscribers.has(event))) { this._subscribers.set(event, []); }
|
|
18
|
+
|
|
19
|
+
const subscribers = this._subscribers.get(event)!;
|
|
20
|
+
subscribers.push(subscriber);
|
|
21
|
+
|
|
22
|
+
return () =>
|
|
23
|
+
{
|
|
24
|
+
const index = subscribers.indexOf(subscriber);
|
|
25
|
+
if (index < 0)
|
|
26
|
+
{
|
|
27
|
+
throw new ReferenceException("Unable to unsubscribe the required subscriber. " +
|
|
28
|
+
"The subscription was already unsubscribed.");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
subscribers.splice(index, 1);
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public publish<K extends keyof T>(event: K, ...args: Parameters<T[K]>): ReturnType<T[K]>[]
|
|
36
|
+
{
|
|
37
|
+
const subscribers = this._subscribers.get(event);
|
|
38
|
+
if (!(subscribers)) { return []; }
|
|
39
|
+
|
|
40
|
+
return subscribers.slice()
|
|
41
|
+
.map((subscriber) => subscriber(...args)) as ReturnType<T[K]>[];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public readonly [Symbol.toStringTag]: string = "Publisher";
|
|
45
|
+
}
|