@byloth/core 1.5.3 → 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.
Files changed (45) hide show
  1. package/dist/core.js +1468 -826
  2. package/dist/core.js.map +1 -1
  3. package/dist/core.umd.cjs +3 -3
  4. package/dist/core.umd.cjs.map +1 -1
  5. package/package.json +8 -10
  6. package/src/helpers.ts +10 -0
  7. package/src/index.ts +33 -16
  8. package/src/models/aggregators/aggregated-async-iterator.ts +129 -81
  9. package/src/models/aggregators/aggregated-iterator.ts +128 -82
  10. package/src/models/aggregators/index.ts +1 -3
  11. package/src/models/aggregators/reduced-iterator.ts +119 -31
  12. package/src/models/aggregators/types.ts +15 -10
  13. package/src/models/callbacks/callable-object.ts +23 -0
  14. package/src/models/callbacks/index.ts +5 -0
  15. package/src/models/callbacks/publisher.ts +45 -0
  16. package/src/models/callbacks/switchable-callback.ts +108 -0
  17. package/src/models/callbacks/types.ts +1 -0
  18. package/src/models/exceptions/core.ts +6 -7
  19. package/src/models/exceptions/index.ts +50 -10
  20. package/src/models/game-loop.ts +83 -0
  21. package/src/models/index.ts +10 -7
  22. package/src/models/iterators/smart-async-iterator.ts +112 -24
  23. package/src/models/iterators/smart-iterator.ts +108 -13
  24. package/src/models/iterators/types.ts +17 -7
  25. package/src/models/json/index.ts +3 -0
  26. package/src/models/{json-storage.ts → json/json-storage.ts} +40 -28
  27. package/src/models/json/types.ts +5 -0
  28. package/src/models/promises/deferred-promise.ts +1 -1
  29. package/src/models/promises/index.ts +3 -1
  30. package/src/models/promises/long-running-task.ts +294 -0
  31. package/src/models/promises/smart-promise.ts +6 -1
  32. package/src/models/promises/thenable.ts +97 -0
  33. package/src/models/promises/timed-promise.ts +1 -1
  34. package/src/models/promises/types.ts +2 -0
  35. package/src/models/timers/clock.ts +69 -0
  36. package/src/models/timers/countdown.ts +117 -0
  37. package/src/models/timers/index.ts +4 -0
  38. package/src/models/types.ts +20 -9
  39. package/src/utils/async.ts +9 -4
  40. package/src/utils/date.ts +7 -4
  41. package/src/utils/index.ts +2 -2
  42. package/src/utils/random.ts +4 -3
  43. package/src/models/aggregators/aggregator.ts +0 -46
  44. package/src/models/aggregators/async-aggregator.ts +0 -56
  45. package/src/models/subscribers.ts +0 -35
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@byloth/core",
3
- "version": "1.5.3",
3
+ "version": "2.0.0-rc.10",
4
4
  "description": "An unopinionated collection of useful functions and classes that I use widely in all my projects. 🔧",
5
5
  "keywords": [
6
6
  "Core",
@@ -47,21 +47,19 @@
47
47
  },
48
48
  "types": "./src/index.ts",
49
49
  "devDependencies": {
50
- "@byloth/eslint-config-typescript": "^2.8.1",
51
- "@types/node": "^20.14.11",
52
- "@typescript-eslint/eslint-plugin": "^7.16.1",
53
- "@typescript-eslint/parser": "^7.16.1",
54
- "eslint": "^8.57.0",
55
- "husky": "^9.1.1",
56
- "typescript": "^5.5.3",
57
- "vite": "^5.3.4"
50
+ "@byloth/eslint-config-typescript": "^3.0.3",
51
+ "@types/node": "^22.10.1",
52
+ "husky": "^9.1.7",
53
+ "typescript": "^5.7.2",
54
+ "vite": "^5.4.11"
58
55
  },
59
56
  "scripts": {
60
57
  "dev": "vite",
61
58
  "build": "vite build",
62
59
  "preview": "vite preview",
63
60
  "typecheck": "tsc",
64
- "lint": "eslint --ext .cjs,.js,.json,.ts --ignore-path .gitignore .",
61
+ "lint": "eslint .",
62
+ "test": "vitest",
65
63
  "ci": "pnpm install --frozen-lockfile"
66
64
  }
67
65
  }
package/src/helpers.ts ADDED
@@ -0,0 +1,10 @@
1
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
2
+
3
+ // @ts-ignore
4
+ export const isBrowser = ((typeof window !== "undefined") && (typeof window.document !== "undefined"));
5
+
6
+ // @ts-ignore
7
+ export const isNode = ((typeof process !== "undefined") && (process.versions?.node));
8
+
9
+ // @ts-ignore
10
+ export const isWebWorker = ((typeof self === "object") && (self.constructor?.name === "DedicatedWorkerGlobalScope"));
package/src/index.ts CHANGED
@@ -1,28 +1,38 @@
1
- export const VERSION = "1.5.3";
1
+ export const VERSION = "2.0.0-rc.10";
2
2
 
3
3
  export type { Constructor, Interval, Timeout } from "./core/types.js";
4
4
 
5
+ export { isBrowser, isNode, isWebWorker } from "./helpers.js";
6
+
5
7
  export {
6
8
  AggregatedIterator,
7
9
  AggregatedAsyncIterator,
8
- Aggregator,
9
- AsyncAggregator,
10
+ CallableObject,
11
+ Clock,
12
+ Countdown,
10
13
  DeferredPromise,
11
14
  Exception,
12
15
  FatalErrorException,
16
+ FileException,
17
+ FileExistsException,
13
18
  FileNotFoundException,
14
- JsonStorage,
19
+ GameLoop,
20
+ JSONStorage,
15
21
  KeyException,
22
+ LongRunningTask,
16
23
  NotImplementedException,
17
24
  NetworkException,
18
25
  PermissionException,
26
+ Publisher,
27
+ RangeException,
19
28
  ReducedIterator,
20
29
  ReferenceException,
21
30
  RuntimeException,
22
31
  SmartIterator,
23
32
  SmartAsyncIterator,
24
33
  SmartPromise,
25
- Subscribers,
34
+ SwitchableCallback,
35
+ Thenable,
26
36
  TimeoutException,
27
37
  TimedPromise,
28
38
  TypeException,
@@ -32,20 +42,26 @@ export {
32
42
 
33
43
  export type {
34
44
  AsyncGeneratorFunction,
35
- AsyncIterLike,
45
+ AsyncIteratorLike,
46
+ Callback,
36
47
  FulfilledHandler,
37
48
  GeneratorFunction,
38
49
  Iteratee,
39
- IterLike,
40
- KeyIteratee,
41
- KeyReducer,
42
- KeyTypeGuardIteratee,
43
- MaybeAsyncKeyIteratee,
44
- MaybeAsyncKeyReducer,
45
- MaybeAsyncKeyTypeGuardIteratee,
46
- MaybeAsyncReducer,
50
+ IteratorLike,
51
+ JSONArray,
52
+ JSONObject,
53
+ JSONValue,
54
+ KeyedIteratee,
55
+ KeyedReducer,
56
+ KeyedTypeGuardIteratee,
57
+ LongRunningTaskOptions,
58
+ MaybeAsyncKeyedIteratee,
59
+ MaybeAsyncKeyedReducer,
60
+ MaybeAsyncKeyedTypeGuardIteratee,
61
+ MaybeAsyncGeneratorFunction,
47
62
  MaybeAsyncIteratee,
48
- MaybeAsyncIterLike,
63
+ MaybeAsyncIteratorLike,
64
+ MaybeAsyncReducer,
49
65
  MaybeAsyncTypeGuardIteratee,
50
66
  MaybePromise,
51
67
  PromiseExecutor,
@@ -66,7 +82,7 @@ export {
66
82
  dateDifference,
67
83
  dateRange,
68
84
  dateRound,
69
- DateUnit,
85
+ TimeUnit,
70
86
  enumerate,
71
87
  hash,
72
88
  loadScript,
@@ -76,6 +92,7 @@ export {
76
92
  shuffle,
77
93
  sum,
78
94
  unique,
95
+ yieldToEventLoop,
79
96
  zip
80
97
 
81
98
  } from "./utils/index.js";
@@ -1,9 +1,15 @@
1
1
  import { SmartAsyncIterator } from "../iterators/index.js";
2
- import type { AsyncGeneratorFunction, GeneratorFunction, MaybeAsyncIterLike } from "../iterators/types.js";
2
+ import type {
3
+ GeneratorFunction,
4
+ AsyncGeneratorFunction,
5
+ MaybeAsyncGeneratorFunction,
6
+ MaybeAsyncIteratorLike
7
+
8
+ } from "../iterators/types.js";
3
9
  import type { MaybePromise } from "../types.js";
4
10
 
5
11
  import ReducedIterator from "./reduced-iterator.js";
6
- import type { MaybeAsyncKeyIteratee, MaybeAsyncKeyTypeGuardIteratee, MaybeAsyncKeyReducer } from "./types.js";
12
+ import type { MaybeAsyncKeyedIteratee, MaybeAsyncKeyedTypeGuardIteratee, MaybeAsyncKeyedReducer } from "./types.js";
7
13
 
8
14
  export default class AggregatedAsyncIterator<K extends PropertyKey, T>
9
15
  {
@@ -15,58 +21,52 @@ export default class AggregatedAsyncIterator<K extends PropertyKey, T>
15
21
  public constructor(iterator: AsyncIterator<[K, T]>);
16
22
  public constructor(generatorFn: GeneratorFunction<[K, T]>);
17
23
  public constructor(generatorFn: AsyncGeneratorFunction<[K, T]>);
18
- public constructor(argument: MaybeAsyncIterLike<[K, T]>);
19
- public constructor(argument: MaybeAsyncIterLike<[K, T]>)
24
+ public constructor(argument: MaybeAsyncIteratorLike<[K, T]> | MaybeAsyncGeneratorFunction<[K, T]>);
25
+ public constructor(argument: MaybeAsyncIteratorLike<[K, T]> | MaybeAsyncGeneratorFunction<[K, T]>)
20
26
  {
21
27
  this._elements = new SmartAsyncIterator(argument);
22
28
  }
23
29
 
24
- public async every(predicate: MaybeAsyncKeyIteratee<K, T, boolean>): Promise<ReducedIterator<K, boolean>>
30
+ public async every(predicate: MaybeAsyncKeyedIteratee<K, T, boolean>): Promise<ReducedIterator<K, boolean>>
25
31
  {
26
- const indexes = new Map<K, [number, boolean]>();
32
+ const values = new Map<K, [number, boolean]>();
27
33
 
28
34
  for await (const [key, element] of this._elements)
29
35
  {
30
- const [index, result] = indexes.get(key) ?? [0, true];
36
+ const [index, result] = values.get(key) ?? [0, true];
31
37
 
32
38
  if (!(result)) { continue; }
33
39
 
34
- indexes.set(key, [index + 1, await predicate(key, element, index)]);
40
+ values.set(key, [index + 1, await predicate(key, element, index)]);
35
41
  }
36
42
 
37
43
  return new ReducedIterator(function* ()
38
44
  {
39
- for (const [key, [_, result]] of indexes)
40
- {
41
- yield [key, result];
42
- }
45
+ for (const [key, [_, result]] of values) { yield [key, result]; }
43
46
  });
44
47
  }
45
- public async some(predicate: MaybeAsyncKeyIteratee<K, T, boolean>): Promise<ReducedIterator<K, boolean>>
48
+ public async some(predicate: MaybeAsyncKeyedIteratee<K, T, boolean>): Promise<ReducedIterator<K, boolean>>
46
49
  {
47
- const indexes = new Map<K, [number, boolean]>();
50
+ const values = new Map<K, [number, boolean]>();
48
51
 
49
52
  for await (const [key, element] of this._elements)
50
53
  {
51
- const [index, result] = indexes.get(key) ?? [0, false];
54
+ const [index, result] = values.get(key) ?? [0, false];
52
55
 
53
56
  if (result) { continue; }
54
57
 
55
- indexes.set(key, [index + 1, await predicate(key, element, index)]);
58
+ values.set(key, [index + 1, await predicate(key, element, index)]);
56
59
  }
57
60
 
58
61
  return new ReducedIterator(function* ()
59
62
  {
60
- for (const [key, [_, result]] of indexes)
61
- {
62
- yield [key, result];
63
- }
63
+ for (const [key, [_, result]] of values) { yield [key, result]; }
64
64
  });
65
65
  }
66
66
 
67
- public filter(predicate: MaybeAsyncKeyIteratee<K, T, boolean>): AggregatedAsyncIterator<K, T>;
68
- public filter<S extends T>(predicate: MaybeAsyncKeyTypeGuardIteratee<K, T, S>): AggregatedAsyncIterator<K, S>;
69
- public filter(predicate: MaybeAsyncKeyIteratee<K, T, boolean>): AggregatedAsyncIterator<K, T>
67
+ public filter(predicate: MaybeAsyncKeyedIteratee<K, T, boolean>): AggregatedAsyncIterator<K, T>;
68
+ public filter<S extends T>(predicate: MaybeAsyncKeyedTypeGuardIteratee<K, T, S>): AggregatedAsyncIterator<K, S>;
69
+ public filter(predicate: MaybeAsyncKeyedIteratee<K, T, boolean>): AggregatedAsyncIterator<K, T>
70
70
  {
71
71
  const elements = this._elements;
72
72
 
@@ -78,13 +78,13 @@ export default class AggregatedAsyncIterator<K extends PropertyKey, T>
78
78
  {
79
79
  const index = indexes.get(key) ?? 0;
80
80
 
81
- indexes.set(key, index + 1);
82
-
83
81
  if (await predicate(key, element, index)) { yield [key, element]; }
82
+
83
+ indexes.set(key, index + 1);
84
84
  }
85
85
  });
86
86
  }
87
- public map<V>(iteratee: MaybeAsyncKeyIteratee<K, T, V>): AggregatedAsyncIterator<K, V>
87
+ public map<V>(iteratee: MaybeAsyncKeyedIteratee<K, T, V>): AggregatedAsyncIterator<K, V>
88
88
  {
89
89
  const elements = this._elements;
90
90
 
@@ -96,31 +96,26 @@ export default class AggregatedAsyncIterator<K extends PropertyKey, T>
96
96
  {
97
97
  const index = indexes.get(key) ?? 0;
98
98
 
99
- indexes.set(key, index + 1);
100
-
101
99
  yield [key, await iteratee(key, element, index)];
100
+
101
+ indexes.set(key, index + 1);
102
102
  }
103
103
  });
104
104
  }
105
- public async reduce(reducer: MaybeAsyncKeyReducer<K, T, T>): Promise<ReducedIterator<K, T>>;
106
- public async reduce<A>(reducer: MaybeAsyncKeyReducer<K, T, A>, initialValue: (key: K) => MaybePromise<A>)
105
+ public async reduce(reducer: MaybeAsyncKeyedReducer<K, T, T>): Promise<ReducedIterator<K, T>>;
106
+ public async reduce<A>(reducer: MaybeAsyncKeyedReducer<K, T, A>, initialValue: (key: K) => MaybePromise<A>)
107
107
  : Promise<ReducedIterator<K, A>>;
108
- public async reduce<A>(reducer: MaybeAsyncKeyReducer<K, T, A>, initialValue?: (key: K) => MaybePromise<A>)
108
+ public async reduce<A>(reducer: MaybeAsyncKeyedReducer<K, T, A>, initialValue?: (key: K) => MaybePromise<A>)
109
109
  : Promise<ReducedIterator<K, A>>
110
110
  {
111
- const accumulators = new Map<K, [number, A]>();
111
+ const values = new Map<K, [number, A]>();
112
112
 
113
113
  for await (const [key, element] of this._elements)
114
114
  {
115
115
  let index: number;
116
116
  let accumulator: A;
117
117
 
118
- if (accumulators.has(key))
119
- {
120
- [index, accumulator] = accumulators.get(key)!;
121
-
122
- index += 1;
123
- }
118
+ if (values.has(key)) { [index, accumulator] = values.get(key)!; }
124
119
  else if (initialValue !== undefined)
125
120
  {
126
121
  index = 0;
@@ -128,103 +123,159 @@ export default class AggregatedAsyncIterator<K extends PropertyKey, T>
128
123
  }
129
124
  else
130
125
  {
131
- accumulators.set(key, [0, (element as unknown) as A]);
126
+ values.set(key, [0, (element as unknown) as A]);
132
127
 
133
128
  continue;
134
129
  }
135
130
 
136
- accumulator = await reducer(key, accumulator, element, index);
137
-
138
- accumulators.set(key, [index, accumulator]);
131
+ values.set(key, [index + 1, await reducer(key, accumulator, element, index)]);
139
132
  }
140
133
 
141
134
  return new ReducedIterator(function* ()
142
135
  {
143
- for (const [key, [_, accumulator]] of accumulators)
136
+ for (const [key, [_, accumulator]] of values) { yield [key, accumulator]; }
137
+ });
138
+ }
139
+
140
+ public flatMap<V>(iteratee: MaybeAsyncKeyedIteratee<K, T, Iterable<V>>): AggregatedAsyncIterator<K, V>
141
+ {
142
+ const elements = this._elements;
143
+
144
+ return new AggregatedAsyncIterator(async function* (): AsyncGenerator<[K, V]>
145
+ {
146
+ const indexes = new Map<K, number>();
147
+
148
+ for await (const [key, element] of elements)
144
149
  {
145
- yield [key, accumulator];
150
+ const index = indexes.get(key) ?? 0;
151
+ const values = await iteratee(key, element, index);
152
+
153
+ for await (const value of values) { yield [key, value]; }
154
+
155
+ indexes.set(key, index + 1);
146
156
  }
147
157
  });
148
158
  }
149
159
 
150
- public unique(): AggregatedAsyncIterator<K, T>
160
+ public drop(count: number): AggregatedAsyncIterator<K, T>
151
161
  {
152
162
  const elements = this._elements;
153
163
 
154
164
  return new AggregatedAsyncIterator(async function* (): AsyncGenerator<[K, T]>
155
165
  {
156
- const keys = new Map<K, Set<T>>();
166
+ const indexes = new Map<K, number>();
157
167
 
158
168
  for await (const [key, element] of elements)
159
169
  {
160
- const values = keys.get(key) ?? new Set<T>();
161
-
162
- if (values.has(element)) { continue; }
170
+ const index = indexes.get(key) ?? 0;
171
+ if (index < count)
172
+ {
173
+ indexes.set(key, index + 1);
163
174
 
164
- values.add(element);
165
- keys.set(key, values);
175
+ continue;
176
+ }
166
177
 
167
178
  yield [key, element];
168
179
  }
169
180
  });
170
181
  }
171
-
172
- public async count(): Promise<ReducedIterator<K, number>>
182
+ public take(limit: number): AggregatedAsyncIterator<K, T>
173
183
  {
174
- const counters = new Map<K, number>();
184
+ const elements = this._elements;
175
185
 
176
- for await (const [key] of this._elements)
186
+ return new AggregatedAsyncIterator(async function* (): AsyncGenerator<[K, T]>
177
187
  {
178
- const count = counters.get(key) ?? 0;
179
-
180
- counters.set(key, count + 1);
181
- }
188
+ const indexes = new Map<K, number>();
182
189
 
183
- return new ReducedIterator(function* ()
184
- {
185
- for (const [key, count] of counters)
190
+ for await (const [key, element] of elements)
186
191
  {
187
- yield [key, count];
192
+ const index = indexes.get(key) ?? 0;
193
+ if (index >= limit) { continue; }
194
+
195
+ yield [key, element];
196
+
197
+ indexes.set(key, index + 1);
188
198
  }
189
199
  });
190
200
  }
191
- public async first(): Promise<ReducedIterator<K, T>>
201
+
202
+ public async find(predicate: MaybeAsyncKeyedIteratee<K, T, boolean>): Promise<ReducedIterator<K, T | undefined>>;
203
+ public async find<S extends T>(predicate: MaybeAsyncKeyedTypeGuardIteratee<K, T, S>)
204
+ : Promise<ReducedIterator<K, S | undefined>>;
205
+
206
+ public async find(predicate: MaybeAsyncKeyedIteratee<K, T, boolean>): Promise<ReducedIterator<K, T | undefined>>
192
207
  {
193
- const firsts = new Map<K, T>();
208
+ const values = new Map<K, [number, T | undefined]>();
194
209
 
195
210
  for await (const [key, element] of this._elements)
196
211
  {
197
- if (firsts.has(key)) { continue; }
212
+ let [index, finding] = values.get(key) ?? [0, undefined];
198
213
 
199
- firsts.set(key, element);
214
+ if (finding !== undefined) { continue; }
215
+ if (await predicate(key, element, index)) { finding = element; }
216
+
217
+ values.set(key, [index + 1, finding]);
200
218
  }
201
219
 
202
220
  return new ReducedIterator(function* ()
203
221
  {
204
- for (const [key, element] of firsts)
222
+ for (const [key, [_, finding]] of values) { yield [key, finding]; }
223
+ });
224
+ }
225
+
226
+ public unique(): AggregatedAsyncIterator<K, T>
227
+ {
228
+ const elements = this._elements;
229
+
230
+ return new AggregatedAsyncIterator(async function* (): AsyncGenerator<[K, T]>
231
+ {
232
+ const keys = new Map<K, Set<T>>();
233
+
234
+ for await (const [key, element] of elements)
205
235
  {
236
+ const values = keys.get(key) ?? new Set<T>();
237
+
238
+ if (values.has(element)) { continue; }
239
+
240
+ values.add(element);
241
+ keys.set(key, values);
242
+
206
243
  yield [key, element];
207
244
  }
208
245
  });
209
246
  }
210
- public async last(): Promise<ReducedIterator<K, T>>
247
+
248
+ public async count(): Promise<ReducedIterator<K, number>>
211
249
  {
212
- const lasts = new Map<K, T>();
250
+ const counters = new Map<K, number>();
213
251
 
214
- for await (const [key, element] of this._elements)
252
+ for await (const [key] of this._elements)
215
253
  {
216
- lasts.set(key, element);
254
+ const count = counters.get(key) ?? 0;
255
+
256
+ counters.set(key, count + 1);
217
257
  }
218
258
 
219
259
  return new ReducedIterator(function* ()
220
260
  {
221
- for (const [key, element] of lasts)
222
- {
223
- yield [key, element];
224
- }
261
+ for (const [key, count] of counters) { yield [key, count]; }
225
262
  });
226
263
  }
227
264
 
265
+ public async forEach(iteratee: MaybeAsyncKeyedIteratee<K, T>): Promise<void>
266
+ {
267
+ const indexes = new Map<K, number>();
268
+
269
+ for await (const [key, element] of this._elements)
270
+ {
271
+ const index = indexes.get(key) ?? 0;
272
+
273
+ iteratee(key, element, index);
274
+
275
+ indexes.set(key, index + 1);
276
+ }
277
+ }
278
+
228
279
  public keys(): SmartAsyncIterator<K>
229
280
  {
230
281
  const elements = this._elements;
@@ -252,10 +303,7 @@ export default class AggregatedAsyncIterator<K extends PropertyKey, T>
252
303
 
253
304
  return new SmartAsyncIterator<T>(async function* ()
254
305
  {
255
- for await (const [_, element] of elements)
256
- {
257
- yield element;
258
- }
306
+ for await (const [_, element] of elements) { yield element; }
259
307
  });
260
308
  }
261
309
 
@@ -294,5 +342,5 @@ export default class AggregatedAsyncIterator<K extends PropertyKey, T>
294
342
  return groups;
295
343
  }
296
344
 
297
- public get [Symbol.toStringTag]() { return "AggregatedAsyncIterator"; }
345
+ public readonly [Symbol.toStringTag]: string = "AggregatedAsyncIterator";
298
346
  }