@simplysm/core-common 13.0.69 → 13.0.71
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 +66 -267
- package/dist/common.types.d.ts +14 -14
- package/dist/errors/argument-error.d.ts +10 -10
- package/dist/errors/argument-error.d.ts.map +1 -1
- package/dist/errors/argument-error.js +2 -2
- package/dist/errors/argument-error.js.map +1 -1
- package/dist/errors/not-implemented-error.d.ts +8 -8
- package/dist/errors/not-implemented-error.js +2 -2
- package/dist/errors/not-implemented-error.js.map +1 -1
- package/dist/errors/sd-error.d.ts +10 -10
- package/dist/errors/sd-error.d.ts.map +1 -1
- package/dist/errors/timeout-error.d.ts +10 -10
- package/dist/errors/timeout-error.js +3 -3
- package/dist/errors/timeout-error.js.map +1 -1
- package/dist/extensions/arr-ext.d.ts +2 -2
- package/dist/extensions/arr-ext.helpers.d.ts +8 -8
- package/dist/extensions/arr-ext.helpers.js +1 -1
- package/dist/extensions/arr-ext.helpers.js.map +1 -1
- package/dist/extensions/arr-ext.js +13 -13
- package/dist/extensions/arr-ext.js.map +1 -1
- package/dist/extensions/arr-ext.types.d.ts +57 -57
- package/dist/extensions/arr-ext.types.d.ts.map +1 -1
- package/dist/extensions/map-ext.d.ts +16 -16
- package/dist/extensions/set-ext.d.ts +11 -11
- package/dist/features/debounce-queue.d.ts +17 -15
- package/dist/features/debounce-queue.d.ts.map +1 -1
- package/dist/features/debounce-queue.js +6 -6
- package/dist/features/debounce-queue.js.map +1 -1
- package/dist/features/event-emitter.d.ts +20 -20
- package/dist/features/event-emitter.js +17 -17
- package/dist/features/serial-queue.d.ts +11 -11
- package/dist/features/serial-queue.js +5 -5
- package/dist/features/serial-queue.js.map +1 -1
- package/dist/globals.d.ts +4 -4
- package/dist/types/date-only.d.ts +64 -64
- package/dist/types/date-only.d.ts.map +1 -1
- package/dist/types/date-only.js +63 -63
- package/dist/types/date-time.d.ts +37 -37
- package/dist/types/date-time.d.ts.map +1 -1
- package/dist/types/date-time.js +54 -37
- package/dist/types/date-time.js.map +1 -1
- package/dist/types/lazy-gc-map.d.ts +26 -26
- package/dist/types/lazy-gc-map.d.ts.map +1 -1
- package/dist/types/lazy-gc-map.js +26 -26
- package/dist/types/lazy-gc-map.js.map +1 -1
- package/dist/types/time.d.ts +25 -25
- package/dist/types/time.d.ts.map +1 -1
- package/dist/types/time.js +25 -25
- package/dist/types/time.js.map +1 -1
- package/dist/types/uuid.d.ts +11 -11
- package/dist/types/uuid.d.ts.map +1 -1
- package/dist/types/uuid.js +12 -12
- package/dist/types/uuid.js.map +1 -1
- package/dist/utils/bytes.d.ts +17 -17
- package/dist/utils/bytes.js +4 -4
- package/dist/utils/bytes.js.map +1 -1
- package/dist/utils/date-format.d.ts +45 -45
- package/dist/utils/date-format.js +1 -1
- package/dist/utils/date-format.js.map +1 -1
- package/dist/utils/error.d.ts +4 -4
- package/dist/utils/json.d.ts +17 -17
- package/dist/utils/json.js +3 -3
- package/dist/utils/json.js.map +1 -1
- package/dist/utils/num.d.ts +23 -23
- package/dist/utils/obj.d.ts +111 -111
- package/dist/utils/obj.d.ts.map +1 -1
- package/dist/utils/obj.js +3 -3
- package/dist/utils/obj.js.map +1 -1
- package/dist/utils/path.d.ts +10 -10
- package/dist/utils/primitive.d.ts +5 -5
- package/dist/utils/primitive.js +1 -1
- package/dist/utils/primitive.js.map +1 -1
- package/dist/utils/str.d.ts +46 -46
- package/dist/utils/str.d.ts.map +1 -1
- package/dist/utils/str.js +5 -5
- package/dist/utils/str.js.map +1 -1
- package/dist/utils/template-strings.d.ts +26 -26
- package/dist/utils/transferable.d.ts +18 -18
- package/dist/utils/transferable.js +1 -1
- package/dist/utils/transferable.js.map +1 -1
- package/dist/utils/wait.d.ts +9 -9
- package/dist/utils/xml.d.ts +13 -13
- package/dist/utils/xml.d.ts.map +1 -1
- package/dist/utils/xml.js +1 -0
- package/dist/utils/xml.js.map +1 -1
- package/dist/zip/sd-zip.d.ts +22 -22
- package/dist/zip/sd-zip.js +16 -16
- package/package.json +4 -4
- package/src/common.types.ts +17 -17
- package/src/errors/argument-error.ts +15 -15
- package/src/errors/not-implemented-error.ts +9 -9
- package/src/errors/sd-error.ts +12 -12
- package/src/errors/timeout-error.ts +12 -12
- package/src/extensions/arr-ext.helpers.ts +10 -10
- package/src/extensions/arr-ext.ts +57 -57
- package/src/extensions/arr-ext.types.ts +59 -59
- package/src/extensions/map-ext.ts +16 -16
- package/src/extensions/set-ext.ts +11 -11
- package/src/features/debounce-queue.ts +21 -19
- package/src/features/event-emitter.ts +25 -25
- package/src/features/serial-queue.ts +13 -13
- package/src/globals.ts +4 -4
- package/src/index.ts +1 -1
- package/src/types/date-only.ts +83 -83
- package/src/types/date-time.ts +64 -44
- package/src/types/lazy-gc-map.ts +45 -45
- package/src/types/time.ts +34 -34
- package/src/types/uuid.ts +17 -17
- package/src/utils/bytes.ts +35 -35
- package/src/utils/date-format.ts +65 -65
- package/src/utils/error.ts +4 -4
- package/src/utils/json.ts +39 -39
- package/src/utils/num.ts +23 -23
- package/src/utils/obj.ts +138 -138
- package/src/utils/path.ts +10 -10
- package/src/utils/primitive.ts +6 -6
- package/src/utils/str.ts +260 -261
- package/src/utils/template-strings.ts +29 -29
- package/src/utils/transferable.ts +284 -284
- package/src/utils/wait.ts +10 -10
- package/src/utils/xml.ts +20 -19
- package/src/zip/sd-zip.ts +25 -25
- package/tests/errors/errors.spec.ts +80 -0
- package/tests/extensions/array-extension.spec.ts +796 -0
- package/tests/extensions/map-extension.spec.ts +147 -0
- package/tests/extensions/set-extension.spec.ts +74 -0
- package/tests/types/date-only.spec.ts +638 -0
- package/tests/types/date-time.spec.ts +391 -0
- package/tests/types/lazy-gc-map.spec.ts +692 -0
- package/tests/types/time.spec.ts +559 -0
- package/tests/types/uuid.spec.ts +74 -0
- package/tests/utils/bytes-utils.spec.ts +230 -0
- package/tests/utils/date-format.spec.ts +373 -0
- package/tests/utils/debounce-queue.spec.ts +272 -0
- package/tests/utils/json.spec.ts +486 -0
- package/tests/utils/number.spec.ts +157 -0
- package/tests/utils/object.spec.ts +829 -0
- package/tests/utils/path.spec.ts +78 -0
- package/tests/utils/primitive.spec.ts +43 -0
- package/tests/utils/sd-event-emitter.spec.ts +216 -0
- package/tests/utils/serial-queue.spec.ts +365 -0
- package/tests/utils/string.spec.ts +281 -0
- package/tests/utils/template-strings.spec.ts +57 -0
- package/tests/utils/transferable.spec.ts +703 -0
- package/tests/utils/wait.spec.ts +145 -0
- package/tests/utils/xml.spec.ts +146 -0
- package/tests/zip/sd-zip.spec.ts +238 -0
- package/docs/extensions.md +0 -503
- package/docs/features.md +0 -109
- package/docs/types.md +0 -486
- package/docs/utils.md +0 -780
|
@@ -1,53 +1,53 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Map
|
|
2
|
+
* Map extension methods
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
declare global {
|
|
6
6
|
interface Map<K, V> {
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* If no value exists for key, set new value and return it
|
|
9
9
|
*
|
|
10
10
|
* @remarks
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
11
|
+
* **Caution**: If V type is a function (e.g., `Map<string, () => void>`),
|
|
12
|
+
* passing the function directly as the second argument will be recognized as a factory and called.
|
|
13
|
+
* To store the function itself as a value, wrap it in a factory.
|
|
14
14
|
*
|
|
15
15
|
* @example
|
|
16
16
|
* ```typescript
|
|
17
|
-
* //
|
|
17
|
+
* // Regular values
|
|
18
18
|
* map.getOrCreate("key", 0);
|
|
19
19
|
* map.getOrCreate("key", []);
|
|
20
20
|
*
|
|
21
|
-
* //
|
|
21
|
+
* // Factory function (for expensive computations)
|
|
22
22
|
* map.getOrCreate("key", () => expensiveComputation());
|
|
23
23
|
*
|
|
24
|
-
* //
|
|
24
|
+
* // Storing function as value
|
|
25
25
|
* const fnMap = new Map<string, () => void>();
|
|
26
26
|
* const myFn = () => console.log("hello");
|
|
27
|
-
* fnMap.getOrCreate("key", () => myFn); //
|
|
27
|
+
* fnMap.getOrCreate("key", () => myFn); // Wrap in factory
|
|
28
28
|
* ```
|
|
29
29
|
*/
|
|
30
30
|
getOrCreate(key: K, newValue: V): V;
|
|
31
31
|
getOrCreate(key: K, newValueFn: () => V): V;
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
|
-
*
|
|
34
|
+
* Update value for key using function
|
|
35
35
|
*
|
|
36
|
-
* @param key
|
|
37
|
-
* @param updateFn
|
|
36
|
+
* @param key Key to update
|
|
37
|
+
* @param updateFn Function that receives current value and returns new value (undefined if key doesn't exist)
|
|
38
38
|
*
|
|
39
39
|
* @remarks
|
|
40
|
-
*
|
|
41
|
-
*
|
|
40
|
+
* updateFn is called even if key doesn't exist, setting new value.
|
|
41
|
+
* Useful for calculations based on existing value (counter increment, add to array, etc).
|
|
42
42
|
*
|
|
43
43
|
* @example
|
|
44
44
|
* ```typescript
|
|
45
45
|
* const countMap = new Map<string, number>();
|
|
46
46
|
*
|
|
47
|
-
* //
|
|
47
|
+
* // Increment counter
|
|
48
48
|
* countMap.update("key", (v) => (v ?? 0) + 1);
|
|
49
49
|
*
|
|
50
|
-
* //
|
|
50
|
+
* // Add item to array
|
|
51
51
|
* const arrayMap = new Map<string, string[]>();
|
|
52
52
|
* arrayMap.update("key", (v) => [...(v ?? []), "item"]);
|
|
53
53
|
* ```
|
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Set
|
|
2
|
+
* Set extension methods
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
declare global {
|
|
6
6
|
interface Set<T> {
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Add multiple values at once
|
|
9
9
|
*/
|
|
10
10
|
adds(...values: T[]): this;
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
13
|
+
* Toggle value (remove if exists, add if not)
|
|
14
14
|
*
|
|
15
|
-
* @param value
|
|
16
|
-
* @param addOrDel
|
|
17
|
-
* @returns this (
|
|
15
|
+
* @param value Value to toggle
|
|
16
|
+
* @param addOrDel Force add ("add") or remove ("del") (if omitted, toggle automatically)
|
|
17
|
+
* @returns this (method chaining available)
|
|
18
18
|
*
|
|
19
19
|
* @remarks
|
|
20
|
-
* addOrDel
|
|
20
|
+
* addOrDel parameter allows concise expression of conditional add/remove.
|
|
21
21
|
*
|
|
22
22
|
* @example
|
|
23
23
|
* ```typescript
|
|
24
24
|
* const set = new Set<number>([1, 2, 3]);
|
|
25
25
|
*
|
|
26
|
-
* set.toggle(2); // 2
|
|
27
|
-
* set.toggle(4); // 4
|
|
26
|
+
* set.toggle(2); // 2 exists, so remove → {1, 3}
|
|
27
|
+
* set.toggle(4); // 4 doesn't exist, so add → {1, 3, 4}
|
|
28
28
|
*
|
|
29
|
-
* //
|
|
29
|
+
* // Conditional toggle
|
|
30
30
|
* const isAdmin = true;
|
|
31
|
-
* set.toggle(5, isAdmin ? "add" : "del"); //
|
|
31
|
+
* set.toggle(5, isAdmin ? "add" : "del"); // Force add
|
|
32
32
|
* ```
|
|
33
33
|
*/
|
|
34
34
|
toggle(value: T, addOrDel?: "add" | "del"): this;
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Asynchronous debounce queue
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* When called multiple times within a short time, only the last request is executed
|
|
5
|
+
* and previous requests are ignored. Useful for input field auto-complete,
|
|
6
|
+
* batching consecutive state changes, and more.
|
|
6
7
|
*
|
|
7
8
|
* @remarks
|
|
8
|
-
*
|
|
9
|
-
*
|
|
9
|
+
* Requests added during execution are processed immediately after the current execution
|
|
10
|
+
* completes without debounce delay. This is an intentional design to ensure that
|
|
11
|
+
* requests arriving before execution completes are not missed.
|
|
10
12
|
*
|
|
11
13
|
* @example
|
|
12
|
-
* const queue = new DebounceQueue(300); // 300ms
|
|
13
|
-
* queue.run(() => console.log("1")); //
|
|
14
|
-
* queue.run(() => console.log("2")); //
|
|
15
|
-
* queue.run(() => console.log("3")); //
|
|
14
|
+
* const queue = new DebounceQueue(300); // 300ms delay
|
|
15
|
+
* queue.run(() => console.log("1")); // ignored
|
|
16
|
+
* queue.run(() => console.log("2")); // ignored
|
|
17
|
+
* queue.run(() => console.log("3")); // executed after 300ms
|
|
16
18
|
*
|
|
17
19
|
* @example
|
|
18
|
-
* //
|
|
20
|
+
* // Error handling
|
|
19
21
|
* queue.on("error", (err) => console.error(err));
|
|
20
22
|
*/
|
|
21
23
|
import { SdError } from "../errors/sd-error";
|
|
@@ -35,14 +37,14 @@ export class DebounceQueue extends EventEmitter<DebounceQueueEvents> {
|
|
|
35
37
|
private _timer: ReturnType<typeof setTimeout> | undefined;
|
|
36
38
|
|
|
37
39
|
/**
|
|
38
|
-
* @param _delay
|
|
40
|
+
* @param _delay Debounce delay time (milliseconds). If omitted, executes immediately (next event loop)
|
|
39
41
|
*/
|
|
40
42
|
constructor(private readonly _delay?: number) {
|
|
41
43
|
super();
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
/**
|
|
45
|
-
*
|
|
47
|
+
* Clean up pending tasks and timers
|
|
46
48
|
*/
|
|
47
49
|
override dispose(): void {
|
|
48
50
|
this._isDisposed = true;
|
|
@@ -55,15 +57,15 @@ export class DebounceQueue extends EventEmitter<DebounceQueueEvents> {
|
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
/**
|
|
58
|
-
* using
|
|
60
|
+
* Supports using statement
|
|
59
61
|
*/
|
|
60
62
|
override [Symbol.dispose](): void {
|
|
61
63
|
this.dispose();
|
|
62
64
|
}
|
|
63
65
|
|
|
64
66
|
/**
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
+
* Add a function to the queue
|
|
68
|
+
* If there was a previously added function, it will be replaced
|
|
67
69
|
*/
|
|
68
70
|
run(fn: () => void | Promise<void>): void {
|
|
69
71
|
if (this._isDisposed) return;
|
|
@@ -89,8 +91,8 @@ export class DebounceQueue extends EventEmitter<DebounceQueueEvents> {
|
|
|
89
91
|
this._timer = undefined;
|
|
90
92
|
|
|
91
93
|
try {
|
|
92
|
-
//
|
|
93
|
-
//
|
|
94
|
+
// If a new request comes in during execution, process it immediately without debounce delay
|
|
95
|
+
// This is an intentional design to process requests that arrived before execution completes immediately after execution
|
|
94
96
|
while (this._pendingFn) {
|
|
95
97
|
const currentFn = this._pendingFn;
|
|
96
98
|
this._pendingFn = undefined;
|
|
@@ -99,9 +101,9 @@ export class DebounceQueue extends EventEmitter<DebounceQueueEvents> {
|
|
|
99
101
|
await currentFn();
|
|
100
102
|
} catch (err) {
|
|
101
103
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
102
|
-
const sdError = new SdError(error, "
|
|
104
|
+
const sdError = new SdError(error, "Error occurred while executing task");
|
|
103
105
|
|
|
104
|
-
//
|
|
106
|
+
// If there are listeners, emit as event; otherwise log
|
|
105
107
|
if (this.listenerCount("error") > 0) {
|
|
106
108
|
this.emit("error", sdError);
|
|
107
109
|
} else {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* EventTarget
|
|
2
|
+
* EventTarget wrapper - provides EventEmitter-like API
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* A type-safe event emitter that can be used in both browsers and Node.js.
|
|
5
|
+
* Internally implemented using EventTarget.
|
|
6
6
|
*
|
|
7
|
-
* @typeParam TEvents
|
|
7
|
+
* @typeParam TEvents Event type map. Keys are event names, values are event data types
|
|
8
8
|
*
|
|
9
9
|
* @example
|
|
10
10
|
* interface MyEvents {
|
|
@@ -18,32 +18,32 @@
|
|
|
18
18
|
* const emitter = new MyEmitter();
|
|
19
19
|
* emitter.on("data", (data) => console.log(data)); // data: string
|
|
20
20
|
* emitter.emit("data", "hello");
|
|
21
|
-
* emitter.emit("done"); // void
|
|
21
|
+
* emitter.emit("done"); // void type is called without arguments
|
|
22
22
|
*/
|
|
23
23
|
export class EventEmitter<
|
|
24
24
|
TEvents extends { [K in keyof TEvents]: unknown } = Record<string, unknown>,
|
|
25
25
|
> {
|
|
26
26
|
private readonly _target = new EventTarget();
|
|
27
|
-
//
|
|
28
|
-
//
|
|
27
|
+
// Manage listener maps by event type (same listener can be registered to different events)
|
|
28
|
+
// Use Function type for polymorphic listener management
|
|
29
29
|
private readonly _listenerMap = new Map<string, Map<Function, (e: Event) => void>>();
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
|
-
*
|
|
32
|
+
* Register an event listener
|
|
33
33
|
*
|
|
34
|
-
* @param type
|
|
35
|
-
* @param listener
|
|
36
|
-
* @note
|
|
34
|
+
* @param type Event type
|
|
35
|
+
* @param listener Event handler
|
|
36
|
+
* @note Duplicate registration of the same listener to the same event is ignored
|
|
37
37
|
*/
|
|
38
38
|
on<K extends keyof TEvents & string>(type: K, listener: (data: TEvents[K]) => void): void {
|
|
39
|
-
//
|
|
39
|
+
// Get or create map for event type
|
|
40
40
|
let typeMap = this._listenerMap.get(type);
|
|
41
41
|
if (!typeMap) {
|
|
42
42
|
typeMap = new Map();
|
|
43
43
|
this._listenerMap.set(type, typeMap);
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
//
|
|
46
|
+
// If listener is already registered to this event, ignore it (prevent duplicate registration)
|
|
47
47
|
if (typeMap.has(listener)) return;
|
|
48
48
|
|
|
49
49
|
const wrappedListener = (e: Event) => listener((e as CustomEvent).detail);
|
|
@@ -52,10 +52,10 @@ export class EventEmitter<
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
/**
|
|
55
|
-
*
|
|
55
|
+
* Remove an event listener
|
|
56
56
|
*
|
|
57
|
-
* @param type
|
|
58
|
-
* @param listener
|
|
57
|
+
* @param type Event type
|
|
58
|
+
* @param listener Event handler to remove
|
|
59
59
|
*/
|
|
60
60
|
off<K extends keyof TEvents & string>(type: K, listener: (data: TEvents[K]) => void): void {
|
|
61
61
|
const typeMap = this._listenerMap.get(type);
|
|
@@ -66,7 +66,7 @@ export class EventEmitter<
|
|
|
66
66
|
this._target.removeEventListener(type, wrappedListener);
|
|
67
67
|
typeMap.delete(listener);
|
|
68
68
|
|
|
69
|
-
//
|
|
69
|
+
// Clean up empty map
|
|
70
70
|
if (typeMap.size === 0) {
|
|
71
71
|
this._listenerMap.delete(type);
|
|
72
72
|
}
|
|
@@ -74,10 +74,10 @@ export class EventEmitter<
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
/**
|
|
77
|
-
*
|
|
77
|
+
* Emit an event
|
|
78
78
|
*
|
|
79
|
-
* @param type
|
|
80
|
-
* @param args
|
|
79
|
+
* @param type Event type
|
|
80
|
+
* @param args Event data (omitted if void type)
|
|
81
81
|
*/
|
|
82
82
|
emit<K extends keyof TEvents & string>(
|
|
83
83
|
type: K,
|
|
@@ -87,17 +87,17 @@ export class EventEmitter<
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
/**
|
|
90
|
-
*
|
|
90
|
+
* Return the number of listeners for a specific event
|
|
91
91
|
*
|
|
92
|
-
* @param type
|
|
93
|
-
* @returns
|
|
92
|
+
* @param type Event type
|
|
93
|
+
* @returns Number of registered listeners
|
|
94
94
|
*/
|
|
95
95
|
listenerCount<K extends keyof TEvents & string>(type: K): number {
|
|
96
96
|
return this._listenerMap.get(type)?.size ?? 0;
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
/**
|
|
100
|
-
*
|
|
100
|
+
* Remove all event listeners
|
|
101
101
|
*/
|
|
102
102
|
dispose(): void {
|
|
103
103
|
for (const [type, typeMap] of this._listenerMap) {
|
|
@@ -109,7 +109,7 @@ export class EventEmitter<
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
/**
|
|
112
|
-
* using
|
|
112
|
+
* Supports using statement
|
|
113
113
|
*/
|
|
114
114
|
[Symbol.dispose](): void {
|
|
115
115
|
this.dispose();
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Asynchronous serial queue
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Functions added to the queue are executed sequentially.
|
|
5
|
+
* The next task starts only after one task completes.
|
|
6
|
+
* Subsequent tasks continue to execute even if an error occurs.
|
|
7
7
|
*
|
|
8
8
|
* @example
|
|
9
9
|
* const queue = new SerialQueue();
|
|
10
10
|
* queue.run(async () => { await fetch("/api/1"); });
|
|
11
|
-
* queue.run(async () => { await fetch("/api/2"); }); //
|
|
12
|
-
* queue.run(async () => { await fetch("/api/3"); }); //
|
|
11
|
+
* queue.run(async () => { await fetch("/api/2"); }); // executed after 1 completes
|
|
12
|
+
* queue.run(async () => { await fetch("/api/3"); }); // executed after 2 completes
|
|
13
13
|
*
|
|
14
14
|
* @example
|
|
15
|
-
* //
|
|
15
|
+
* // Error handling
|
|
16
16
|
* queue.on("error", (err) => console.error(err));
|
|
17
17
|
*/
|
|
18
18
|
import { SdError } from "../errors/sd-error";
|
|
@@ -31,14 +31,14 @@ export class SerialQueue extends EventEmitter<SerialQueueEvents> {
|
|
|
31
31
|
private _isQueueRunning = false;
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
|
-
* @param _gap
|
|
34
|
+
* @param _gap Gap between each task (ms)
|
|
35
35
|
*/
|
|
36
36
|
constructor(private readonly _gap: number = 0) {
|
|
37
37
|
super();
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
/**
|
|
41
|
-
*
|
|
41
|
+
* Clear pending queue (currently executing task will complete)
|
|
42
42
|
*/
|
|
43
43
|
override dispose(): void {
|
|
44
44
|
this._queue.length = 0;
|
|
@@ -46,14 +46,14 @@ export class SerialQueue extends EventEmitter<SerialQueueEvents> {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
|
-
* using
|
|
49
|
+
* Supports using statement
|
|
50
50
|
*/
|
|
51
51
|
override [Symbol.dispose](): void {
|
|
52
52
|
this.dispose();
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
/**
|
|
56
|
-
*
|
|
56
|
+
* Add a function to the queue and execute it
|
|
57
57
|
*/
|
|
58
58
|
run(fn: () => void | Promise<void>): void {
|
|
59
59
|
this._queue.push(fn);
|
|
@@ -73,9 +73,9 @@ export class SerialQueue extends EventEmitter<SerialQueueEvents> {
|
|
|
73
73
|
await fn();
|
|
74
74
|
} catch (err) {
|
|
75
75
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
76
|
-
const sdError = new SdError(error, "
|
|
76
|
+
const sdError = new SdError(error, "Error occurred while executing queue task");
|
|
77
77
|
|
|
78
|
-
//
|
|
78
|
+
// If there are listeners, emit as event; otherwise log
|
|
79
79
|
if (this.listenerCount("error") > 0) {
|
|
80
80
|
this.emit("error", sdError);
|
|
81
81
|
} else {
|
package/src/globals.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Whether development mode is enabled
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* -
|
|
6
|
-
* -
|
|
4
|
+
* Substituted at build time:
|
|
5
|
+
* - Library build: Not substituted (kept as-is)
|
|
6
|
+
* - Client/Server build: Substituted with `define: { '__DEV__': 'true/false' }`
|
|
7
7
|
*/
|
|
8
8
|
export {};
|
|
9
9
|
|
package/src/index.ts
CHANGED