@byloth/core 1.3.0-rc.2 → 1.3.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@byloth/core",
3
- "version": "1.3.0-rc.2",
3
+ "version": "1.3.1",
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",
@@ -56,11 +56,11 @@
56
56
  "ci": "yarn install --frozen-lockfile"
57
57
  },
58
58
  "devDependencies": {
59
- "@byloth/eslint-config-typescript": "^2.6.8",
60
- "@typescript-eslint/eslint-plugin": "^6.19.1",
61
- "@typescript-eslint/parser": "^6.19.1",
62
- "eslint": "^8.56.0",
63
- "typescript": "^5.3.3",
64
- "vite": "^5.0.12"
59
+ "@byloth/eslint-config-typescript": "^2.7.0",
60
+ "@typescript-eslint/eslint-plugin": "^7.2.0",
61
+ "@typescript-eslint/parser": "^7.2.0",
62
+ "eslint": "^8.57.0",
63
+ "typescript": "^5.4.2",
64
+ "vite": "^5.1.6"
65
65
  }
66
66
  }
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- export const VERSION = "1.3.0-rc.2";
1
+ export const VERSION = "1.3.1";
2
2
 
3
3
  export {
4
4
  AggregatedIterator,
@@ -8,6 +8,7 @@ export {
8
8
  JsonStorage,
9
9
  ReducedIterator,
10
10
  SmartIterator,
11
+ SmartPromise,
11
12
  Subscribers
12
13
 
13
14
  } from "./models/index.js";
@@ -2,14 +2,13 @@ import Exception from "./exception.js";
2
2
  import SmartIterator from "./smart-iterator.js";
3
3
  import Aggregator, { AggregatedIterator, ReducedIterator } from "./aggregators/index.js";
4
4
 
5
- import DeferredPromise from "./deferred-promise.js";
6
5
  import JsonStorage from "./json-storage.js";
7
6
  import Subscribers from "./subscribers.js";
8
7
 
8
+ export { DeferredPromise, SmartPromise } from "./promises/index.js";
9
9
  export {
10
10
  AggregatedIterator,
11
11
  Aggregator,
12
- DeferredPromise,
13
12
  Exception,
14
13
  JsonStorage,
15
14
  ReducedIterator,
@@ -0,0 +1,117 @@
1
+ import type {
2
+ PromiseResolver,
3
+ PromiseRejecter,
4
+ FulfilledHandler,
5
+ RejectedHandler,
6
+ PromiseExecutor
7
+
8
+ } from "../../types.js";
9
+
10
+ export default class DeferredPromise<T = void, E = unknown, F = T, R = never>
11
+ {
12
+ protected _isPending: boolean;
13
+ protected _isFulfilled: boolean;
14
+ protected _isRejected: boolean;
15
+
16
+ protected _resolve!: PromiseResolver<T>;
17
+ protected _reject!: PromiseRejecter<E>;
18
+
19
+ protected _promise: Promise<F | R>;
20
+
21
+ public constructor(onFulfilled?: FulfilledHandler<T, F> | null, onRejected?: RejectedHandler<E, R> | null)
22
+ {
23
+ this._isPending = true;
24
+ this._isFulfilled = false;
25
+ this._isRejected = false;
26
+
27
+ let _resolve: PromiseResolver<T>;
28
+ let _reject: PromiseRejecter<E>;
29
+
30
+ const executor: PromiseExecutor<T, E> = (resolve, reject) =>
31
+ {
32
+ _resolve = resolve;
33
+ _reject = reject;
34
+ };
35
+
36
+ let _onFulfilled: FulfilledHandler<T, F>;
37
+ if (onFulfilled)
38
+ {
39
+ _onFulfilled = (value) =>
40
+ {
41
+ this._isPending = false;
42
+ this._isFulfilled = true;
43
+
44
+ return onFulfilled!(value);
45
+ };
46
+ }
47
+ else
48
+ {
49
+ _onFulfilled = (value) =>
50
+ {
51
+ this._isPending = false;
52
+ this._isFulfilled = true;
53
+
54
+ return (value as unknown) as F;
55
+ };
56
+ }
57
+
58
+ let _onRejected: RejectedHandler<E, R>;
59
+ if (onRejected)
60
+ {
61
+ _onRejected = (reason) =>
62
+ {
63
+ this._isPending = false;
64
+ this._isRejected = true;
65
+
66
+ return onRejected!(reason);
67
+ };
68
+ }
69
+ else
70
+ {
71
+ _onRejected = (reason) =>
72
+ {
73
+ this._isPending = false;
74
+ this._isRejected = true;
75
+
76
+ return (reason as unknown) as R;
77
+ };
78
+ }
79
+
80
+ this._promise = new Promise<T>(executor)
81
+ .then(_onFulfilled, _onRejected);
82
+
83
+ this._resolve = _resolve!;
84
+ this._reject = _reject!;
85
+ }
86
+
87
+ public get isPending(): boolean { return this._isPending; }
88
+ public get isFulfilled(): boolean { return this._isFulfilled; }
89
+ public get isRejected(): boolean { return this._isRejected; }
90
+
91
+ public get resolve(): PromiseResolver<T> { return this._resolve; }
92
+ public get reject(): PromiseRejecter<E> { return this._reject; }
93
+
94
+ public then<N = F | R, H = R>(
95
+ onFulfilled?: FulfilledHandler<F | R, N> | null,
96
+ onRejected?: RejectedHandler<R, H> | null): Promise<N | H>
97
+ {
98
+ return this._promise.then(onFulfilled, onRejected);
99
+ }
100
+ public catch<H = R>(onRejected?: RejectedHandler<R, H> | null): Promise<F | R | H>
101
+ {
102
+ return this._promise.catch(onRejected);
103
+ }
104
+ public finally(onFinally?: (() => void) | null): Promise<F | R>
105
+ {
106
+ return this._promise.finally(onFinally);
107
+ }
108
+
109
+ public watch(promise: Promise<T>): this
110
+ {
111
+ promise.then(this.resolve, this.reject);
112
+
113
+ return this;
114
+ }
115
+
116
+ public get [Symbol.toStringTag]() { return "DeferredPromise"; }
117
+ }
@@ -0,0 +1,4 @@
1
+ import DeferredPromise from "./deferred-promise.js";
2
+ import SmartPromise from "./smart-promise.js";
3
+
4
+ export { DeferredPromise, SmartPromise };
@@ -0,0 +1,56 @@
1
+ import type { FulfilledHandler, PromiseExecutor, RejectedHandler } from "../../types.js";
2
+
3
+ export default class SmartPromise<T = void, E = unknown>
4
+ {
5
+ protected _isPending: boolean;
6
+ protected _isFulfilled: boolean;
7
+ protected _isRejected: boolean;
8
+
9
+ protected _promise: Promise<T | E>;
10
+
11
+ public constructor(executor: PromiseExecutor<T, E>)
12
+ {
13
+ this._isPending = true;
14
+ this._isFulfilled = false;
15
+ this._isRejected = false;
16
+
17
+ const _resolve = (result: T): T =>
18
+ {
19
+ this._isPending = false;
20
+ this._isFulfilled = true;
21
+
22
+ return result;
23
+ };
24
+ const _reject = (reason: E): E =>
25
+ {
26
+ this._isPending = false;
27
+ this._isRejected = true;
28
+
29
+ return reason;
30
+ };
31
+
32
+ this._promise = new Promise<T>(executor)
33
+ .then(_resolve, _reject);
34
+ }
35
+
36
+ public get isPending(): boolean { return this._isPending; }
37
+ public get isFulfilled(): boolean { return this._isFulfilled; }
38
+ public get isRejected(): boolean { return this._isRejected; }
39
+
40
+ public then<F = T, R = E>(
41
+ onFulfilled?: FulfilledHandler<T | E, F> | null,
42
+ onRejected?: RejectedHandler<E, R> | null): Promise<F | R>
43
+ {
44
+ return this._promise.then(onFulfilled, onRejected);
45
+ }
46
+ public catch<R = E>(onRejected?: RejectedHandler<E, R> | null): Promise<T | E | R>
47
+ {
48
+ return this._promise.catch(onRejected);
49
+ }
50
+ public finally(onFinally?: (() => void) | null): Promise<T | E>
51
+ {
52
+ return this._promise.finally(onFinally);
53
+ }
54
+
55
+ public get [Symbol.toStringTag]() { return "SmartPromise"; }
56
+ }
package/src/types.ts CHANGED
@@ -10,7 +10,7 @@ export type MaybePromise<T> = T | PromiseLike<T>;
10
10
  export type FulfilledHandler<T = void, R = T> = (value: T) => MaybePromise<R>;
11
11
  export type RejectedHandler<E = unknown, R = never> = (reason: E) => MaybePromise<R>;
12
12
 
13
- export type PromiseResolver<T = void> = (result?: MaybePromise<T>) => void;
13
+ export type PromiseResolver<T = void> = (result: MaybePromise<T>) => void;
14
14
  export type PromiseRejecter<E = unknown> = (reason?: MaybePromise<E>) => void;
15
15
  export type PromiseExecutor<T = void, E = unknown> = (resolve: PromiseResolver<T>, reject: PromiseRejecter<E>) => void;
16
16
 
@@ -1,384 +0,0 @@
1
- export function aggregate<V>(elements: Iterable<V>)
2
- {
3
- type Iteratee<K> = (element: V, index: number) => K;
4
-
5
- function byKey<K extends string | number | symbol>(iteratee: Iteratee<K>)
6
- {
7
- function countToMap()
8
- {
9
- const counts = new Map<K, number>();
10
-
11
- let index = 0;
12
- for (const element of elements)
13
- {
14
- const key = iteratee(element, index);
15
-
16
- if (counts.has(key))
17
- {
18
- counts.set(key, counts.get(key)! + 1);
19
- }
20
- else
21
- {
22
- counts.set(key, 1);
23
- }
24
-
25
- index += 1;
26
- }
27
-
28
- return counts;
29
- }
30
- function countToDict()
31
- {
32
- const mapCounts = countToMap();
33
- const dictCounts = { } as Record<K, number>;
34
-
35
- for (const [key, _count] of mapCounts.entries())
36
- {
37
- dictCounts[key] = _count;
38
- }
39
-
40
- return dictCounts;
41
- }
42
- function count()
43
- {
44
- return Array.from(countToMap().values());
45
- }
46
-
47
- function groupToMap()
48
- {
49
- const groups = new Map<K, V[]>();
50
-
51
- let index = 0;
52
- for (const element of elements)
53
- {
54
- const key = iteratee(element, index);
55
-
56
- if (groups.has(key))
57
- {
58
- groups.get(key)!
59
- .push(element);
60
- }
61
- else
62
- {
63
- groups.set(key, [element]);
64
- }
65
-
66
- index += 1;
67
- }
68
-
69
- return groups;
70
- }
71
- function groupToDict()
72
- {
73
- const mapGroups = groupToMap();
74
- const dictGroup = { } as Record<K, V[]>;
75
-
76
- for (const [key, _group] of mapGroups.entries())
77
- {
78
- dictGroup[key] = _group;
79
- }
80
-
81
- return dictGroup;
82
- }
83
- function group()
84
- {
85
- return Array.from(groupToMap().values());
86
- }
87
-
88
- type Reducer<R = V> = (key: K, group: R | undefined, element: V, index: number) => R;
89
-
90
- function reduceToMap<R = V>(reducer: Reducer<R>, initialValue?: R | undefined)
91
- {
92
- const counts = new Map<K, number>();
93
- const groups = new Map<K, R>();
94
-
95
- let index = 0;
96
- for (const element of elements)
97
- {
98
- let _count = 0;
99
- let _group = initialValue;
100
-
101
- const key = iteratee(element, index);
102
- if (groups.has(key))
103
- {
104
- _count = counts.get(key)!;
105
- _group = groups.get(key)!;
106
- }
107
-
108
- _group = reducer(key, _group, element, _count);
109
-
110
- counts.set(key, _count + 1);
111
- groups.set(key, _group);
112
-
113
- index += 1;
114
- }
115
-
116
- return groups;
117
- }
118
- function reduceToDict<R = V>(reducer: Reducer<R>, initialValue?: R | undefined)
119
- {
120
- const mapGroups = reduceToMap(reducer, initialValue);
121
- const dictGroup = { } as Record<K, R>;
122
-
123
- for (const [key, _group] of mapGroups.entries())
124
- {
125
- dictGroup[key] = _group;
126
- }
127
-
128
- return dictGroup;
129
- }
130
- function reduce<R = V>(reducer: Reducer<R>, initialValue?: R | undefined)
131
- {
132
- return Array.from(reduceToMap(reducer, initialValue).values());
133
- }
134
-
135
- async function asyncReduceToMap<R = V>(reducer: Reducer<Promise<R>>, initialValue?: Promise<R> | undefined)
136
- {
137
- const awaitedGroups = new Map<K, R>();
138
- const asyncGroups = reduceToMap(reducer, initialValue);
139
-
140
- for (const [key, asyncGroup] of asyncGroups.entries())
141
- {
142
- awaitedGroups.set(key, await asyncGroup);
143
- }
144
-
145
- return awaitedGroups;
146
- }
147
- async function asyncReduceToDict<R = V>(reducer: Reducer<Promise<R>>, initialValue?: Promise<R> | undefined)
148
- {
149
- const mapGroups = reduceToMap(reducer, initialValue);
150
- const dictGroup = { } as Record<K, R>;
151
-
152
- for (const [key, _group] of mapGroups.entries())
153
- {
154
- dictGroup[key] = await _group;
155
- }
156
-
157
- return dictGroup;
158
- }
159
- function asyncReduce<R = V>(reducer: Reducer<Promise<R>>, initialValue?: Promise<R> | undefined)
160
- {
161
- return Promise.all(reduce(reducer, initialValue));
162
- }
163
-
164
- return {
165
- count,
166
- countToMap,
167
- countToDict,
168
- group,
169
- groupToMap,
170
- groupToDict,
171
- reduce,
172
- reduceToMap,
173
- reduceToDict,
174
- asyncReduce,
175
- asyncReduceToMap,
176
- asyncReduceToDict
177
- };
178
- }
179
- function byAsyncKey<K extends string | number | symbol>(iteratee: Iteratee<Promise<K>>)
180
- {
181
- async function countToMap()
182
- {
183
- const counts = new Map<K, number>();
184
-
185
- let index = 0;
186
- for (const element of elements)
187
- {
188
- const key = await iteratee(element, index);
189
-
190
- if (counts.has(key))
191
- {
192
- counts.set(key, counts.get(key)! + 1);
193
- }
194
- else
195
- {
196
- counts.set(key, 1);
197
- }
198
-
199
- index += 1;
200
- }
201
-
202
- return counts;
203
- }
204
- async function countToDict()
205
- {
206
- const mapCounts = await countToMap();
207
- const dictCounts = { } as Record<K, number>;
208
-
209
- for (const [key, _count] of mapCounts.entries())
210
- {
211
- dictCounts[key] = _count;
212
- }
213
-
214
- return dictCounts;
215
- }
216
- async function count()
217
- {
218
- const counts = await countToMap();
219
-
220
- return Array.from(counts.values());
221
- }
222
-
223
- async function groupToMap()
224
- {
225
- const groups = new Map<K, V[]>();
226
-
227
- let index = 0;
228
- for (const element of elements)
229
- {
230
- const key = await iteratee(element, index);
231
-
232
- if (groups.has(key))
233
- {
234
- groups.get(key)!
235
- .push(element);
236
- }
237
- else
238
- {
239
- groups.set(key, [element]);
240
- }
241
-
242
- index += 1;
243
- }
244
-
245
- return groups;
246
- }
247
- async function groupToDict()
248
- {
249
- const mapGroups = await groupToMap();
250
- const dictGroup = { } as Record<K, V[]>;
251
-
252
- for (const [key, _group] of mapGroups.entries())
253
- {
254
- dictGroup[key] = _group;
255
- }
256
-
257
- return dictGroup;
258
- }
259
- async function group()
260
- {
261
- const groups = await groupToMap();
262
-
263
- return Array.from(groups.values());
264
- }
265
-
266
- type Reducer<R = V> = (key: K, group: R | undefined, element: V, index: number) => R;
267
-
268
- async function reduceToMap<R = V>(reducer: Reducer<R>, initialValue?: R | undefined)
269
- {
270
- const counts = new Map<K, number>();
271
- const groups = new Map<K, R>();
272
-
273
- let index = 0;
274
- for (const element of elements)
275
- {
276
- let _count = 0;
277
- let _group = initialValue;
278
-
279
- const key = await iteratee(element, index);
280
- if (groups.has(key))
281
- {
282
- _count = counts.get(key)!;
283
- _group = groups.get(key)!;
284
- }
285
-
286
- _group = reducer(key, _group, element, _count);
287
-
288
- counts.set(key, _count + 1);
289
- groups.set(key, _group);
290
-
291
- index += 1;
292
- }
293
-
294
- return groups;
295
- }
296
- async function reduceToDict<R = V>(reducer: Reducer<R>, initialValue?: R | undefined)
297
- {
298
- const mapGroups = await reduceToMap(reducer, initialValue);
299
- const dictGroup = { } as Record<K, R>;
300
-
301
- for (const [key, _group] of mapGroups.entries())
302
- {
303
- dictGroup[key] = _group;
304
- }
305
-
306
- return dictGroup;
307
- }
308
- async function reduce<R = V>(reducer: Reducer<R>, initialValue?: R | undefined)
309
- {
310
- const groups = await reduceToMap(reducer, initialValue);
311
-
312
- return Array.from(groups.values());
313
- }
314
-
315
- async function asyncReduceToMap<R = V>(reducer: Reducer<Promise<R>>, initialValue?: Promise<R> | undefined)
316
- {
317
- const awaitedGroups = new Map<K, R>();
318
- const asyncGroups = await reduceToMap(reducer, initialValue);
319
-
320
- for (const [key, asyncGroup] of asyncGroups.entries())
321
- {
322
- awaitedGroups.set(key, await asyncGroup);
323
- }
324
-
325
- return awaitedGroups;
326
- }
327
- async function asyncReduceToDict<R = V>(reducer: Reducer<Promise<R>>, initialValue?: Promise<R> | undefined)
328
- {
329
- const mapGroups = await reduceToMap(reducer, initialValue);
330
- const dictGroup = { } as Record<K, R>;
331
-
332
- for (const [key, _group] of mapGroups.entries())
333
- {
334
- dictGroup[key] = await _group;
335
- }
336
-
337
- return dictGroup;
338
- }
339
- async function asyncReduce<R = V>(reducer: Reducer<Promise<R>>, initialValue?: Promise<R> | undefined)
340
- {
341
- const groups = await reduce(reducer, initialValue);
342
-
343
- return Promise.all(groups);
344
- }
345
-
346
- return {
347
- count,
348
- countToMap,
349
- countToDict,
350
- group,
351
- groupToMap,
352
- groupToDict,
353
- reduce,
354
- reduceToMap,
355
- reduceToDict,
356
- asyncReduce,
357
- asyncReduceToMap,
358
- asyncReduceToDict
359
- };
360
- }
361
-
362
- type Mapper<R> = (element: V, index: number) => R;
363
-
364
- function map<R>(mapper: Mapper<R>)
365
- {
366
- const mapping: R[] = [];
367
-
368
- let index = 0;
369
- for (const element of elements)
370
- {
371
- mapping.push(mapper(element, index));
372
-
373
- index += 1;
374
- }
375
-
376
- return mapping;
377
- }
378
- async function asyncMap<R>(mapper: Mapper<Promise<R>>)
379
- {
380
- return await Promise.all(map(mapper));
381
- }
382
-
383
- return { byKey, byAsyncKey, map, asyncMap };
384
- }
@@ -1,61 +0,0 @@
1
- import type { PromiseResolver, PromiseRejecter, FulfilledHandler, RejectedHandler } from "../types.js";
2
-
3
- export default class DeferredPromise<T = void, E = unknown, F = T, R = never>
4
- {
5
- protected _resolve!: PromiseResolver<T>;
6
- protected _reject!: PromiseRejecter<E>;
7
-
8
- protected _promise: Promise<F | R>;
9
-
10
- public constructor(onFulfilled?: FulfilledHandler<T, F> | null, onRejected?: RejectedHandler<E, R> | null)
11
- {
12
- let _resolve: PromiseResolver<T>;
13
- let _reject: PromiseRejecter<E>;
14
-
15
- this._promise = new Promise<T>((resolve, reject) =>
16
- {
17
- _resolve = resolve as PromiseResolver<T>;
18
- _reject = reject as PromiseRejecter<E>;
19
-
20
- }).then(onFulfilled, onRejected);
21
-
22
- this._resolve = _resolve!;
23
- this._reject = _reject!;
24
- }
25
-
26
- public get resolve(): PromiseResolver<T>
27
- {
28
- return this._resolve;
29
- }
30
- public get reject(): PromiseRejecter<E>
31
- {
32
- return this._reject;
33
- }
34
-
35
- public then<N = F | R, H = R>(
36
- onFulfilled?: FulfilledHandler<F | R, N> | null,
37
- onRejected?: RejectedHandler<R, H> | null): Promise<N | H>
38
- {
39
- return this._promise.then(onFulfilled, onRejected);
40
- }
41
- public catch<H = R>(onRejected?: RejectedHandler<R, H> | null): Promise<F | R | H>
42
- {
43
- return this._promise.catch(onRejected);
44
- }
45
- public finally(onFinally?: (() => void) | null): Promise<F | R>
46
- {
47
- return this._promise.finally(onFinally);
48
- }
49
-
50
- public watch(promise: Promise<T>): this
51
- {
52
- promise.then(this.resolve, this.reject);
53
-
54
- return this;
55
- }
56
-
57
- public get [Symbol.toStringTag]()
58
- {
59
- return "DeferredPromise";
60
- }
61
- }