@wexample/js-helpers 0.0.12 → 0.0.15
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 +1 -1
- package/dist/Helper/Queue.cjs +84 -0
- package/dist/Helper/Queue.cjs.map +1 -0
- package/dist/Helper/Queue.d.cts +35 -0
- package/dist/Helper/Queue.d.ts +35 -0
- package/dist/Helper/Queue.js +82 -0
- package/dist/Helper/Queue.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/Helper/Queue.ts
|
|
4
|
+
var Queue = class {
|
|
5
|
+
constructor(options) {
|
|
6
|
+
this.queue = [];
|
|
7
|
+
this.activeCount = 0;
|
|
8
|
+
this.paused = false;
|
|
9
|
+
this.worker = options.worker;
|
|
10
|
+
this.concurrency = Math.max(1, options.concurrency ?? 1);
|
|
11
|
+
this.autoStart = options.autoStart ?? true;
|
|
12
|
+
this.callbacks = {
|
|
13
|
+
onItemStart: options.onItemStart,
|
|
14
|
+
onItemSuccess: options.onItemSuccess,
|
|
15
|
+
onItemError: options.onItemError,
|
|
16
|
+
onItemDone: options.onItemDone,
|
|
17
|
+
onDrain: options.onDrain
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
enqueue(item) {
|
|
21
|
+
this.queue.push(item);
|
|
22
|
+
if (this.autoStart) {
|
|
23
|
+
this.pump();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
enqueueMany(items) {
|
|
27
|
+
this.queue.push(...items);
|
|
28
|
+
if (this.autoStart) {
|
|
29
|
+
this.pump();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
pause() {
|
|
33
|
+
this.paused = true;
|
|
34
|
+
}
|
|
35
|
+
resume() {
|
|
36
|
+
if (!this.paused) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
this.paused = false;
|
|
40
|
+
this.pump();
|
|
41
|
+
}
|
|
42
|
+
clear() {
|
|
43
|
+
this.queue = [];
|
|
44
|
+
}
|
|
45
|
+
size() {
|
|
46
|
+
return this.queue.length;
|
|
47
|
+
}
|
|
48
|
+
active() {
|
|
49
|
+
return this.activeCount;
|
|
50
|
+
}
|
|
51
|
+
isIdle() {
|
|
52
|
+
return this.queue.length === 0 && this.activeCount === 0;
|
|
53
|
+
}
|
|
54
|
+
pump() {
|
|
55
|
+
if (this.paused) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
while (this.activeCount < this.concurrency && this.queue.length > 0) {
|
|
59
|
+
const item = this.queue.shift();
|
|
60
|
+
this.runItem(item);
|
|
61
|
+
}
|
|
62
|
+
if (this.isIdle()) {
|
|
63
|
+
this.callbacks.onDrain?.();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async runItem(item) {
|
|
67
|
+
this.activeCount += 1;
|
|
68
|
+
this.callbacks.onItemStart?.(item);
|
|
69
|
+
try {
|
|
70
|
+
const result = await this.worker(item);
|
|
71
|
+
this.callbacks.onItemSuccess?.(item, result);
|
|
72
|
+
} catch (error) {
|
|
73
|
+
this.callbacks.onItemError?.(item, error);
|
|
74
|
+
} finally {
|
|
75
|
+
this.callbacks.onItemDone?.(item);
|
|
76
|
+
this.activeCount -= 1;
|
|
77
|
+
this.pump();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
module.exports = Queue;
|
|
83
|
+
//# sourceMappingURL=Queue.cjs.map
|
|
84
|
+
//# sourceMappingURL=Queue.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/Helper/Queue.ts"],"names":[],"mappings":"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","file":"Queue.cjs","sourcesContent":["export type QueueWorker<TItem, TResult = unknown> = (item: TItem) => Promise<TResult> | TResult;\n\nexport type QueueCallbacks<TItem, TResult = unknown> = {\n onItemStart?: (item: TItem) => void;\n onItemSuccess?: (item: TItem, result: TResult) => void;\n onItemError?: (item: TItem, error: unknown) => void;\n onItemDone?: (item: TItem) => void;\n onDrain?: () => void;\n};\n\nexport type QueueOptions<TItem, TResult = unknown> = QueueCallbacks<TItem, TResult> & {\n worker: QueueWorker<TItem, TResult>;\n concurrency?: number;\n autoStart?: boolean;\n};\n\nexport default class Queue<TItem, TResult = unknown> {\n private queue: TItem[] = [];\n private activeCount = 0;\n private paused = false;\n private readonly worker: QueueWorker<TItem, TResult>;\n private readonly concurrency: number;\n private readonly autoStart: boolean;\n private readonly callbacks: QueueCallbacks<TItem, TResult>;\n\n constructor(options: QueueOptions<TItem, TResult>) {\n this.worker = options.worker;\n this.concurrency = Math.max(1, options.concurrency ?? 1);\n this.autoStart = options.autoStart ?? true;\n this.callbacks = {\n onItemStart: options.onItemStart,\n onItemSuccess: options.onItemSuccess,\n onItemError: options.onItemError,\n onItemDone: options.onItemDone,\n onDrain: options.onDrain,\n };\n }\n\n enqueue(item: TItem): void {\n this.queue.push(item);\n if (this.autoStart) {\n this.pump();\n }\n }\n\n enqueueMany(items: TItem[]): void {\n this.queue.push(...items);\n if (this.autoStart) {\n this.pump();\n }\n }\n\n pause(): void {\n this.paused = true;\n }\n\n resume(): void {\n if (!this.paused) {\n return;\n }\n\n this.paused = false;\n this.pump();\n }\n\n clear(): void {\n this.queue = [];\n }\n\n size(): number {\n return this.queue.length;\n }\n\n active(): number {\n return this.activeCount;\n }\n\n isIdle(): boolean {\n return this.queue.length === 0 && this.activeCount === 0;\n }\n\n private pump(): void {\n if (this.paused) {\n return;\n }\n\n while (this.activeCount < this.concurrency && this.queue.length > 0) {\n const item = this.queue.shift() as TItem;\n this.runItem(item);\n }\n\n if (this.isIdle()) {\n this.callbacks.onDrain?.();\n }\n }\n\n private async runItem(item: TItem): Promise<void> {\n this.activeCount += 1;\n this.callbacks.onItemStart?.(item);\n\n try {\n const result = await this.worker(item);\n this.callbacks.onItemSuccess?.(item, result);\n } catch (error) {\n this.callbacks.onItemError?.(item, error);\n } finally {\n this.callbacks.onItemDone?.(item);\n this.activeCount -= 1;\n this.pump();\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
type QueueWorker<TItem, TResult = unknown> = (item: TItem) => Promise<TResult> | TResult;
|
|
2
|
+
type QueueCallbacks<TItem, TResult = unknown> = {
|
|
3
|
+
onItemStart?: (item: TItem) => void;
|
|
4
|
+
onItemSuccess?: (item: TItem, result: TResult) => void;
|
|
5
|
+
onItemError?: (item: TItem, error: unknown) => void;
|
|
6
|
+
onItemDone?: (item: TItem) => void;
|
|
7
|
+
onDrain?: () => void;
|
|
8
|
+
};
|
|
9
|
+
type QueueOptions<TItem, TResult = unknown> = QueueCallbacks<TItem, TResult> & {
|
|
10
|
+
worker: QueueWorker<TItem, TResult>;
|
|
11
|
+
concurrency?: number;
|
|
12
|
+
autoStart?: boolean;
|
|
13
|
+
};
|
|
14
|
+
declare class Queue<TItem, TResult = unknown> {
|
|
15
|
+
private queue;
|
|
16
|
+
private activeCount;
|
|
17
|
+
private paused;
|
|
18
|
+
private readonly worker;
|
|
19
|
+
private readonly concurrency;
|
|
20
|
+
private readonly autoStart;
|
|
21
|
+
private readonly callbacks;
|
|
22
|
+
constructor(options: QueueOptions<TItem, TResult>);
|
|
23
|
+
enqueue(item: TItem): void;
|
|
24
|
+
enqueueMany(items: TItem[]): void;
|
|
25
|
+
pause(): void;
|
|
26
|
+
resume(): void;
|
|
27
|
+
clear(): void;
|
|
28
|
+
size(): number;
|
|
29
|
+
active(): number;
|
|
30
|
+
isIdle(): boolean;
|
|
31
|
+
private pump;
|
|
32
|
+
private runItem;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export { type QueueCallbacks, type QueueOptions, type QueueWorker, Queue as default };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
type QueueWorker<TItem, TResult = unknown> = (item: TItem) => Promise<TResult> | TResult;
|
|
2
|
+
type QueueCallbacks<TItem, TResult = unknown> = {
|
|
3
|
+
onItemStart?: (item: TItem) => void;
|
|
4
|
+
onItemSuccess?: (item: TItem, result: TResult) => void;
|
|
5
|
+
onItemError?: (item: TItem, error: unknown) => void;
|
|
6
|
+
onItemDone?: (item: TItem) => void;
|
|
7
|
+
onDrain?: () => void;
|
|
8
|
+
};
|
|
9
|
+
type QueueOptions<TItem, TResult = unknown> = QueueCallbacks<TItem, TResult> & {
|
|
10
|
+
worker: QueueWorker<TItem, TResult>;
|
|
11
|
+
concurrency?: number;
|
|
12
|
+
autoStart?: boolean;
|
|
13
|
+
};
|
|
14
|
+
declare class Queue<TItem, TResult = unknown> {
|
|
15
|
+
private queue;
|
|
16
|
+
private activeCount;
|
|
17
|
+
private paused;
|
|
18
|
+
private readonly worker;
|
|
19
|
+
private readonly concurrency;
|
|
20
|
+
private readonly autoStart;
|
|
21
|
+
private readonly callbacks;
|
|
22
|
+
constructor(options: QueueOptions<TItem, TResult>);
|
|
23
|
+
enqueue(item: TItem): void;
|
|
24
|
+
enqueueMany(items: TItem[]): void;
|
|
25
|
+
pause(): void;
|
|
26
|
+
resume(): void;
|
|
27
|
+
clear(): void;
|
|
28
|
+
size(): number;
|
|
29
|
+
active(): number;
|
|
30
|
+
isIdle(): boolean;
|
|
31
|
+
private pump;
|
|
32
|
+
private runItem;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export { type QueueCallbacks, type QueueOptions, type QueueWorker, Queue as default };
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// src/Helper/Queue.ts
|
|
2
|
+
var Queue = class {
|
|
3
|
+
constructor(options) {
|
|
4
|
+
this.queue = [];
|
|
5
|
+
this.activeCount = 0;
|
|
6
|
+
this.paused = false;
|
|
7
|
+
this.worker = options.worker;
|
|
8
|
+
this.concurrency = Math.max(1, options.concurrency ?? 1);
|
|
9
|
+
this.autoStart = options.autoStart ?? true;
|
|
10
|
+
this.callbacks = {
|
|
11
|
+
onItemStart: options.onItemStart,
|
|
12
|
+
onItemSuccess: options.onItemSuccess,
|
|
13
|
+
onItemError: options.onItemError,
|
|
14
|
+
onItemDone: options.onItemDone,
|
|
15
|
+
onDrain: options.onDrain
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
enqueue(item) {
|
|
19
|
+
this.queue.push(item);
|
|
20
|
+
if (this.autoStart) {
|
|
21
|
+
this.pump();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
enqueueMany(items) {
|
|
25
|
+
this.queue.push(...items);
|
|
26
|
+
if (this.autoStart) {
|
|
27
|
+
this.pump();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
pause() {
|
|
31
|
+
this.paused = true;
|
|
32
|
+
}
|
|
33
|
+
resume() {
|
|
34
|
+
if (!this.paused) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
this.paused = false;
|
|
38
|
+
this.pump();
|
|
39
|
+
}
|
|
40
|
+
clear() {
|
|
41
|
+
this.queue = [];
|
|
42
|
+
}
|
|
43
|
+
size() {
|
|
44
|
+
return this.queue.length;
|
|
45
|
+
}
|
|
46
|
+
active() {
|
|
47
|
+
return this.activeCount;
|
|
48
|
+
}
|
|
49
|
+
isIdle() {
|
|
50
|
+
return this.queue.length === 0 && this.activeCount === 0;
|
|
51
|
+
}
|
|
52
|
+
pump() {
|
|
53
|
+
if (this.paused) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
while (this.activeCount < this.concurrency && this.queue.length > 0) {
|
|
57
|
+
const item = this.queue.shift();
|
|
58
|
+
this.runItem(item);
|
|
59
|
+
}
|
|
60
|
+
if (this.isIdle()) {
|
|
61
|
+
this.callbacks.onDrain?.();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async runItem(item) {
|
|
65
|
+
this.activeCount += 1;
|
|
66
|
+
this.callbacks.onItemStart?.(item);
|
|
67
|
+
try {
|
|
68
|
+
const result = await this.worker(item);
|
|
69
|
+
this.callbacks.onItemSuccess?.(item, result);
|
|
70
|
+
} catch (error) {
|
|
71
|
+
this.callbacks.onItemError?.(item, error);
|
|
72
|
+
} finally {
|
|
73
|
+
this.callbacks.onItemDone?.(item);
|
|
74
|
+
this.activeCount -= 1;
|
|
75
|
+
this.pump();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export { Queue as default };
|
|
81
|
+
//# sourceMappingURL=Queue.js.map
|
|
82
|
+
//# sourceMappingURL=Queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/Helper/Queue.ts"],"names":[],"mappings":"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","file":"Queue.js","sourcesContent":["export type QueueWorker<TItem, TResult = unknown> = (item: TItem) => Promise<TResult> | TResult;\n\nexport type QueueCallbacks<TItem, TResult = unknown> = {\n onItemStart?: (item: TItem) => void;\n onItemSuccess?: (item: TItem, result: TResult) => void;\n onItemError?: (item: TItem, error: unknown) => void;\n onItemDone?: (item: TItem) => void;\n onDrain?: () => void;\n};\n\nexport type QueueOptions<TItem, TResult = unknown> = QueueCallbacks<TItem, TResult> & {\n worker: QueueWorker<TItem, TResult>;\n concurrency?: number;\n autoStart?: boolean;\n};\n\nexport default class Queue<TItem, TResult = unknown> {\n private queue: TItem[] = [];\n private activeCount = 0;\n private paused = false;\n private readonly worker: QueueWorker<TItem, TResult>;\n private readonly concurrency: number;\n private readonly autoStart: boolean;\n private readonly callbacks: QueueCallbacks<TItem, TResult>;\n\n constructor(options: QueueOptions<TItem, TResult>) {\n this.worker = options.worker;\n this.concurrency = Math.max(1, options.concurrency ?? 1);\n this.autoStart = options.autoStart ?? true;\n this.callbacks = {\n onItemStart: options.onItemStart,\n onItemSuccess: options.onItemSuccess,\n onItemError: options.onItemError,\n onItemDone: options.onItemDone,\n onDrain: options.onDrain,\n };\n }\n\n enqueue(item: TItem): void {\n this.queue.push(item);\n if (this.autoStart) {\n this.pump();\n }\n }\n\n enqueueMany(items: TItem[]): void {\n this.queue.push(...items);\n if (this.autoStart) {\n this.pump();\n }\n }\n\n pause(): void {\n this.paused = true;\n }\n\n resume(): void {\n if (!this.paused) {\n return;\n }\n\n this.paused = false;\n this.pump();\n }\n\n clear(): void {\n this.queue = [];\n }\n\n size(): number {\n return this.queue.length;\n }\n\n active(): number {\n return this.activeCount;\n }\n\n isIdle(): boolean {\n return this.queue.length === 0 && this.activeCount === 0;\n }\n\n private pump(): void {\n if (this.paused) {\n return;\n }\n\n while (this.activeCount < this.concurrency && this.queue.length > 0) {\n const item = this.queue.shift() as TItem;\n this.runItem(item);\n }\n\n if (this.isIdle()) {\n this.callbacks.onDrain?.();\n }\n }\n\n private async runItem(item: TItem): Promise<void> {\n this.activeCount += 1;\n this.callbacks.onItemStart?.(item);\n\n try {\n const result = await this.worker(item);\n this.callbacks.onItemSuccess?.(item, result);\n } catch (error) {\n this.callbacks.onItemError?.(item, error);\n } finally {\n this.callbacks.onItemDone?.(item);\n this.activeCount -= 1;\n this.pump();\n }\n }\n}\n"]}
|