@minimaltech/node-infra 0.3.16 → 0.3.18
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/common/types.d.ts +1 -0
- package/dist/helpers/queue/bullmq.helper.d.ts +10 -8
- package/dist/helpers/queue/bullmq.helper.js +8 -2
- package/dist/helpers/queue/bullmq.helper.js.map +1 -1
- package/dist/helpers/queue/queue.helper.d.ts +55 -23
- package/dist/helpers/queue/queue.helper.js +209 -59
- package/dist/helpers/queue/queue.helper.js.map +1 -1
- package/dist/utilities/index.d.ts +1 -0
- package/dist/utilities/index.js +1 -0
- package/dist/utilities/index.js.map +1 -1
- package/dist/utilities/promise.utility.d.ts +10 -0
- package/dist/utilities/promise.utility.js +33 -0
- package/dist/utilities/promise.utility.js.map +1 -0
- package/package.json +1 -1
package/dist/common/types.d.ts
CHANGED
@@ -29,6 +29,7 @@ export type IdType = string | number;
|
|
29
29
|
export type AnyType = any;
|
30
30
|
export type AnyObject = Record<string | symbol | number, any>;
|
31
31
|
export type ValueOrPromise<T> = T | Promise<T>;
|
32
|
+
export type ValueOf<T> = T[keyof T];
|
32
33
|
export type NullableType = undefined | null | void;
|
33
34
|
export type TRelationType = 'belongsTo' | 'hasOne' | 'hasMany' | 'hasManyThrough';
|
34
35
|
export type TBullQueueRole = 'queue' | 'worker';
|
@@ -2,28 +2,30 @@ import { Job, Queue, Worker } from 'bullmq';
|
|
2
2
|
import Redis from 'ioredis';
|
3
3
|
import { TBullQueueRole } from '../../common/types';
|
4
4
|
import { BaseHelper } from '../../base/base.helper';
|
5
|
-
interface IBullMQOptions {
|
5
|
+
interface IBullMQOptions<TQueueElement = any, TQueueResult = any> {
|
6
6
|
queueName: string;
|
7
7
|
identifier: string;
|
8
8
|
role: TBullQueueRole;
|
9
9
|
connection: Redis;
|
10
10
|
numberOfWorker?: number;
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
lockDuration?: number;
|
12
|
+
onWorkerData?: (job: Job<TQueueElement, TQueueResult>) => Promise<any>;
|
13
|
+
onWorkerDataCompleted?: (job: Job<TQueueElement, TQueueResult>, result: any) => Promise<void>;
|
14
|
+
onWorkerDataFail?: (job: Job<TQueueElement, TQueueResult> | undefined, error: Error) => Promise<void>;
|
14
15
|
}
|
15
|
-
export declare class BullMQHelper extends BaseHelper {
|
16
|
+
export declare class BullMQHelper<TQueueElement = any, TQueueResult = any> extends BaseHelper {
|
16
17
|
private queueName;
|
17
18
|
private role;
|
18
19
|
private connection;
|
19
|
-
queue: Queue
|
20
|
-
worker: Worker
|
20
|
+
queue: Queue<TQueueElement, TQueueResult>;
|
21
|
+
worker: Worker<TQueueElement, TQueueResult>;
|
21
22
|
private numberOfWorker;
|
23
|
+
private lockDuration;
|
22
24
|
private onWorkerData?;
|
23
25
|
private onWorkerDataCompleted?;
|
24
26
|
private onWorkerDataFail?;
|
25
27
|
constructor(options: IBullMQOptions);
|
26
|
-
static newInstance(opts: IBullMQOptions): BullMQHelper
|
28
|
+
static newInstance<T = any, R = any>(opts: IBullMQOptions): BullMQHelper<T, R>;
|
27
29
|
configureQueue(): void;
|
28
30
|
configureWorker(): void;
|
29
31
|
configure(): void;
|
@@ -16,11 +16,13 @@ class BullMQHelper extends base_helper_1.BaseHelper {
|
|
16
16
|
constructor(options) {
|
17
17
|
super({ scope: BullMQHelper.name, identifier: options.identifier });
|
18
18
|
this.numberOfWorker = 1;
|
19
|
-
|
19
|
+
this.lockDuration = 90 * 60 * 1000;
|
20
|
+
const { queueName, connection, role, numberOfWorker = 1, lockDuration = 90 * 60 * 1000, onWorkerData, onWorkerDataCompleted, onWorkerDataFail, } = options;
|
20
21
|
this.queueName = queueName;
|
21
22
|
this.role = role;
|
22
23
|
this.connection = connection;
|
23
24
|
this.numberOfWorker = numberOfWorker;
|
25
|
+
this.lockDuration = lockDuration;
|
24
26
|
this.onWorkerData = onWorkerData;
|
25
27
|
this.onWorkerDataCompleted = onWorkerDataCompleted;
|
26
28
|
this.onWorkerDataFail = onWorkerDataFail;
|
@@ -54,7 +56,11 @@ class BullMQHelper extends base_helper_1.BaseHelper {
|
|
54
56
|
}
|
55
57
|
const { id, name, data } = job;
|
56
58
|
this.logger.info('[onWorkerData][%s] queue: %s | id: %s | name: %s | data: %j', this.identifier, this.queueName, id, name, data);
|
57
|
-
}), {
|
59
|
+
}), {
|
60
|
+
connection: this.connection,
|
61
|
+
concurrency: this.numberOfWorker,
|
62
|
+
lockDuration: this.lockDuration,
|
63
|
+
});
|
58
64
|
this.worker.on('completed', (job, result) => {
|
59
65
|
var _a;
|
60
66
|
(_a = this.onWorkerDataCompleted) === null || _a === void 0 ? void 0 : _a.call(this, job, result).then(() => {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"bullmq.helper.js","sourceRoot":"","sources":["../../../src/helpers/queue/bullmq.helper.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,mCAA4C;AAG5C,oDAAgD;
|
1
|
+
{"version":3,"file":"bullmq.helper.js","sourceRoot":"","sources":["../../../src/helpers/queue/bullmq.helper.ts"],"names":[],"mappings":"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"}
|
@@ -1,31 +1,63 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
import { BaseHelper } from '../../base/base.helper';
|
2
|
+
import { ValueOf, ValueOrPromise } from '../../common/types';
|
3
|
+
export declare class QueueStatuses {
|
4
|
+
static readonly WAITING = "000_WAITING";
|
5
|
+
static readonly PROCESSING = "100_PROCESSING";
|
6
|
+
static readonly LOCKED = "200_LOCKED";
|
7
|
+
static readonly SETTLED = "300_SETTLED";
|
8
|
+
static readonly SCHEME_SET: Set<string>;
|
9
|
+
static isValid(scheme: string): boolean;
|
5
10
|
}
|
6
|
-
export
|
11
|
+
export type TQueueStatus = ValueOf<Omit<typeof QueueStatuses, 'isValid' | 'SCHEME_SET'>>;
|
12
|
+
export type TQueueElement<T> = {
|
13
|
+
isLocked: boolean;
|
14
|
+
payload: T;
|
15
|
+
};
|
16
|
+
interface IQueueCallback<TElementPayload> {
|
17
|
+
autoDispatch?: boolean;
|
18
|
+
onMessage?: (opts: {
|
19
|
+
identifier: string;
|
20
|
+
queueElement: TQueueElement<TElementPayload>;
|
21
|
+
}) => ValueOrPromise<void>;
|
22
|
+
onDataEnqueue?: (opts: {
|
23
|
+
identifier: string;
|
24
|
+
queueElement: TQueueElement<TElementPayload>;
|
25
|
+
}) => ValueOrPromise<void>;
|
26
|
+
onDataDequeue?: (opts: {
|
27
|
+
identifier: string;
|
28
|
+
queueElement: TQueueElement<TElementPayload>;
|
29
|
+
}) => ValueOrPromise<void>;
|
30
|
+
}
|
31
|
+
export declare class QueueHelper<TElementPayload> extends BaseHelper {
|
7
32
|
identifier: string;
|
8
|
-
storage: Array<
|
33
|
+
storage: Array<TQueueElement<TElementPayload>>;
|
34
|
+
private processingEvents;
|
35
|
+
private generator;
|
36
|
+
private totalEvent;
|
37
|
+
private autoDispatch;
|
38
|
+
private state;
|
39
|
+
private isSettleRequested;
|
40
|
+
private onMessage?;
|
9
41
|
private onDataEnqueue?;
|
10
42
|
private onDataDequeue?;
|
11
|
-
constructor(opts: IQueueCallback<
|
43
|
+
constructor(opts: IQueueCallback<TElementPayload> & {
|
12
44
|
identifier: string;
|
13
45
|
});
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
46
|
+
private handleMessage;
|
47
|
+
private _messageListener;
|
48
|
+
nextMessage(): void;
|
49
|
+
enqueue(payload: TElementPayload): Promise<void>;
|
50
|
+
dequeue(): TQueueElement<TElementPayload> | undefined;
|
51
|
+
lock(): void;
|
52
|
+
unlock(opts: {
|
53
|
+
shouldProcessNextElement?: boolean;
|
54
|
+
}): void;
|
55
|
+
settle(): void;
|
56
|
+
isSettled(): boolean;
|
57
|
+
close(): void;
|
58
|
+
getElementAt(position: number): TQueueElement<TElementPayload>;
|
59
|
+
getState(): TQueueStatus;
|
60
|
+
getTotalEvent(): number;
|
61
|
+
getProcessingEvents(): Set<TQueueElement<TElementPayload>>;
|
30
62
|
}
|
31
63
|
export {};
|
@@ -1,90 +1,240 @@
|
|
1
1
|
"use strict";
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
9
|
+
});
|
10
|
+
};
|
2
11
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
13
|
};
|
14
|
+
var _a;
|
5
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.
|
16
|
+
exports.QueueHelper = exports.QueueStatuses = void 0;
|
17
|
+
const base_helper_1 = require("../../base/base.helper");
|
7
18
|
const isEmpty_1 = __importDefault(require("lodash/isEmpty"));
|
8
|
-
const omit_1 = __importDefault(require("lodash/omit"));
|
9
19
|
// --------------------------------------------------------
|
10
|
-
class
|
20
|
+
class QueueStatuses {
|
21
|
+
static isValid(scheme) {
|
22
|
+
return this.SCHEME_SET.has(scheme);
|
23
|
+
}
|
24
|
+
}
|
25
|
+
exports.QueueStatuses = QueueStatuses;
|
26
|
+
_a = QueueStatuses;
|
27
|
+
QueueStatuses.WAITING = '000_WAITING';
|
28
|
+
QueueStatuses.PROCESSING = '100_PROCESSING';
|
29
|
+
QueueStatuses.LOCKED = '200_LOCKED';
|
30
|
+
QueueStatuses.SETTLED = '300_SETTLED';
|
31
|
+
QueueStatuses.SCHEME_SET = new Set([_a.WAITING, _a.PROCESSING, _a.LOCKED, _a.SETTLED]);
|
32
|
+
// --------------------------------------------------------
|
33
|
+
class QueueHelper extends base_helper_1.BaseHelper {
|
11
34
|
constructor(opts) {
|
12
|
-
|
13
|
-
|
14
|
-
this.
|
15
|
-
this.
|
35
|
+
var _b;
|
36
|
+
super({ scope: `${QueueHelper.name}_${opts.identifier}`, identifier: opts.identifier });
|
37
|
+
this.autoDispatch = true;
|
38
|
+
this.state = QueueStatuses.WAITING;
|
39
|
+
this.identifier = opts.identifier;
|
16
40
|
this.storage = [];
|
41
|
+
this.processingEvents = new Set([]);
|
42
|
+
this.generator = this._messageListener();
|
43
|
+
this.totalEvent = 0;
|
44
|
+
this.autoDispatch = (_b = opts.autoDispatch) !== null && _b !== void 0 ? _b : true;
|
45
|
+
this.state = QueueStatuses.WAITING;
|
46
|
+
this.isSettleRequested = false;
|
47
|
+
this.onMessage = opts.onMessage;
|
48
|
+
this.onDataEnqueue = opts.onDataEnqueue;
|
49
|
+
this.onDataDequeue = opts.onDataDequeue;
|
50
|
+
}
|
51
|
+
handleMessage() {
|
52
|
+
return __awaiter(this, void 0, void 0, function* () {
|
53
|
+
var _b;
|
54
|
+
const current = this.getElementAt(0);
|
55
|
+
if (!current) {
|
56
|
+
this.logger.warn('[handleMessage] current: %j | Invalid current message to handle!', current);
|
57
|
+
return;
|
58
|
+
}
|
59
|
+
const { isLocked, payload } = current;
|
60
|
+
if (isLocked) {
|
61
|
+
this.logger.info('[handle] Skip LOCKED message | Payload: %j', payload);
|
62
|
+
return;
|
63
|
+
}
|
64
|
+
if (this.state !== QueueStatuses.LOCKED && this.state !== QueueStatuses.SETTLED) {
|
65
|
+
this.state = QueueStatuses.PROCESSING;
|
66
|
+
}
|
67
|
+
this.getElementAt(0).isLocked = true;
|
68
|
+
this.processingEvents.add(this.getElementAt(0));
|
69
|
+
yield ((_b = this.onMessage) === null || _b === void 0 ? void 0 : _b.call(this, { identifier: this.identifier, queueElement: this.getElementAt(0) }));
|
70
|
+
const doneElement = this.dequeue();
|
71
|
+
if (doneElement) {
|
72
|
+
this.processingEvents.delete(doneElement);
|
73
|
+
}
|
74
|
+
if (this.state !== QueueStatuses.LOCKED && this.state !== QueueStatuses.SETTLED) {
|
75
|
+
this.state = QueueStatuses.WAITING;
|
76
|
+
}
|
77
|
+
if (!this.storage.length) {
|
78
|
+
if (this.isSettleRequested) {
|
79
|
+
this.state = QueueStatuses.SETTLED;
|
80
|
+
}
|
81
|
+
return;
|
82
|
+
}
|
83
|
+
this.nextMessage();
|
84
|
+
});
|
17
85
|
}
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
86
|
+
*_messageListener() {
|
87
|
+
if (!this.onMessage) {
|
88
|
+
this.logger.warn('[_messageListener] Queue has no onMessage listener | Skip initializing message iterator!');
|
89
|
+
return;
|
22
90
|
}
|
23
|
-
|
24
|
-
|
25
|
-
(_a = this.onDataEnqueue) === null || _a === void 0 ? void 0 : _a.call(this, this.identifier, value);
|
91
|
+
while (true) {
|
92
|
+
yield this.handleMessage();
|
26
93
|
}
|
27
94
|
}
|
95
|
+
nextMessage() {
|
96
|
+
if (this.state !== QueueStatuses.WAITING) {
|
97
|
+
/* this.logger.warn(
|
98
|
+
'[nextMessage] currentState: %s | Skip request next message | Invalid queue state to request next message!',
|
99
|
+
this.state,
|
100
|
+
); */
|
101
|
+
return;
|
102
|
+
}
|
103
|
+
this.generator.next();
|
104
|
+
}
|
105
|
+
enqueue(payload) {
|
106
|
+
return __awaiter(this, void 0, void 0, function* () {
|
107
|
+
var _b;
|
108
|
+
if (this.isSettleRequested || this.state === QueueStatuses.SETTLED) {
|
109
|
+
this.logger.error('[enqueue] isSettled: %s | currentState: %s | Queue was SETTLED | No more element acceptable', this.isSettleRequested, this.state);
|
110
|
+
return;
|
111
|
+
}
|
112
|
+
if (!this.storage) {
|
113
|
+
this.storage = [];
|
114
|
+
}
|
115
|
+
if (!payload) {
|
116
|
+
return;
|
117
|
+
}
|
118
|
+
const queueElement = { isLocked: false, payload };
|
119
|
+
this.storage.push(queueElement);
|
120
|
+
this.totalEvent++;
|
121
|
+
yield ((_b = this.onDataEnqueue) === null || _b === void 0 ? void 0 : _b.call(this, { identifier: this.identifier, queueElement: queueElement }));
|
122
|
+
if (this.autoDispatch) {
|
123
|
+
this.nextMessage();
|
124
|
+
}
|
125
|
+
});
|
126
|
+
}
|
28
127
|
dequeue() {
|
29
|
-
var
|
30
|
-
const value =
|
128
|
+
var _b;
|
129
|
+
const value = this.storage.shift();
|
31
130
|
if (value && !(0, isEmpty_1.default)(value)) {
|
32
|
-
(_b = this.onDataDequeue) === null || _b === void 0 ? void 0 : _b.call(this, this.identifier, value);
|
131
|
+
(_b = this.onDataDequeue) === null || _b === void 0 ? void 0 : _b.call(this, { identifier: this.identifier, queueElement: value });
|
33
132
|
}
|
34
133
|
return value;
|
35
134
|
}
|
36
|
-
|
37
|
-
|
38
|
-
|
135
|
+
lock() {
|
136
|
+
if (this.state >= QueueStatuses.LOCKED) {
|
137
|
+
this.logger.error('[lock] isSettled | currentState: %s | Invalid queue state to request lock queue!', this.isSettleRequested, this.state);
|
138
|
+
return;
|
139
|
+
}
|
140
|
+
this.state = QueueStatuses.LOCKED;
|
39
141
|
}
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
// private onTriggerRetry?: (identifier: string) => void;
|
45
|
-
constructor(opts) {
|
46
|
-
const { onDataEnqueue, onDataDequeue,
|
47
|
-
// onTriggerRetry
|
48
|
-
} = opts;
|
49
|
-
this.onDataEnqueue = onDataEnqueue;
|
50
|
-
this.onDataDequeue = onDataDequeue;
|
51
|
-
// this.onTriggerRetry = onTriggerRetry;
|
52
|
-
this.storage = {};
|
53
|
-
}
|
54
|
-
enqueue(identifier, value) {
|
55
|
-
var _a;
|
56
|
-
if (!this.storage[identifier]) {
|
57
|
-
this.storage[identifier] = new QueueHelper({ identifier });
|
142
|
+
unlock(opts) {
|
143
|
+
if (this.state > QueueStatuses.LOCKED) {
|
144
|
+
this.logger.error('[unlock] isSettled | currentState: %s | Invalid queue state to request unlock queue!', this.isSettleRequested, this.state);
|
145
|
+
return;
|
58
146
|
}
|
59
|
-
|
60
|
-
|
61
|
-
|
147
|
+
const { shouldProcessNextElement = true } = opts;
|
148
|
+
this.state = QueueStatuses.WAITING;
|
149
|
+
if (!shouldProcessNextElement) {
|
150
|
+
return;
|
62
151
|
}
|
152
|
+
this.nextMessage();
|
63
153
|
}
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
(_b = this.onDataDequeue) === null || _b === void 0 ? void 0 : _b.call(this, identifier, value);
|
154
|
+
settle() {
|
155
|
+
this.isSettleRequested = true;
|
156
|
+
if (this.state !== QueueStatuses.PROCESSING) {
|
157
|
+
this.state = QueueStatuses.SETTLED;
|
69
158
|
}
|
70
|
-
return value;
|
71
159
|
}
|
72
|
-
|
73
|
-
return this.storage
|
160
|
+
isSettled() {
|
161
|
+
return this.state === QueueStatuses.SETTLED && !this.storage.length;
|
162
|
+
}
|
163
|
+
close() {
|
164
|
+
this.settle();
|
165
|
+
this.generator.return({
|
166
|
+
state: this.state,
|
167
|
+
totalEvent: this.totalEvent,
|
168
|
+
});
|
74
169
|
}
|
75
|
-
|
76
|
-
|
77
|
-
return (_a = this.storage[identifier]) === null || _a === void 0 ? void 0 : _a.getElementAt(0);
|
170
|
+
getElementAt(position) {
|
171
|
+
return this.storage[position];
|
78
172
|
}
|
79
|
-
|
80
|
-
return this.
|
173
|
+
getState() {
|
174
|
+
return this.state;
|
81
175
|
}
|
82
|
-
|
83
|
-
|
176
|
+
getTotalEvent() {
|
177
|
+
return this.totalEvent;
|
84
178
|
}
|
85
|
-
|
86
|
-
return this.
|
179
|
+
getProcessingEvents() {
|
180
|
+
return this.processingEvents;
|
87
181
|
}
|
88
182
|
}
|
89
|
-
exports.
|
183
|
+
exports.QueueHelper = QueueHelper;
|
184
|
+
// --------------------------------------------------------
|
185
|
+
/* export class MultiQueueHelper<ElementType> {
|
186
|
+
public storage: Record<string, QueueHelper<ElementType>>;
|
187
|
+
|
188
|
+
private onDataEnqueue?: (identifier: string, payload: ElementType) => void;
|
189
|
+
private onDataDequeue?: (identifier: string, payload: ElementType) => void;
|
190
|
+
|
191
|
+
constructor(opts: IQueueCallback<ElementType>) {
|
192
|
+
const { onDataEnqueue, onDataDequeue } = opts;
|
193
|
+
this.onDataEnqueue = onDataEnqueue;
|
194
|
+
this.onDataDequeue = onDataDequeue;
|
195
|
+
this.storage = {};
|
196
|
+
}
|
197
|
+
|
198
|
+
enqueue(identifier: string, value: ElementType) {
|
199
|
+
if (!this.storage[identifier]) {
|
200
|
+
this.storage[identifier] = new QueueHelper({ identifier });
|
201
|
+
}
|
202
|
+
|
203
|
+
this.storage[identifier].enqueue(value);
|
204
|
+
|
205
|
+
if (value && !isEmpty(value)) {
|
206
|
+
this.onDataEnqueue?.(identifier, value);
|
207
|
+
}
|
208
|
+
}
|
209
|
+
|
210
|
+
dequeue(identifier: string): ElementType | undefined {
|
211
|
+
const value = this.storage[identifier]?.dequeue();
|
212
|
+
|
213
|
+
if (value && !isEmpty(value)) {
|
214
|
+
this.onDataDequeue?.(identifier, value);
|
215
|
+
}
|
216
|
+
|
217
|
+
return value;
|
218
|
+
}
|
219
|
+
|
220
|
+
getElementAt(identifier: string, position = 0) {
|
221
|
+
return this.storage[identifier].getElementAt(position);
|
222
|
+
}
|
223
|
+
|
224
|
+
getCurrentData(identifier: string) {
|
225
|
+
return this.storage[identifier]?.getElementAt(0);
|
226
|
+
}
|
227
|
+
|
228
|
+
getQueue(identifier: string) {
|
229
|
+
return this.storage[identifier];
|
230
|
+
}
|
231
|
+
|
232
|
+
removeQueue(queue: string) {
|
233
|
+
this.storage = omit(this.storage, [queue]);
|
234
|
+
}
|
235
|
+
|
236
|
+
mapData() {
|
237
|
+
return this.storage;
|
238
|
+
}
|
239
|
+
} */
|
90
240
|
//# sourceMappingURL=queue.helper.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"queue.helper.js","sourceRoot":"","sources":["../../../src/helpers/queue/queue.helper.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"queue.helper.js","sourceRoot":"","sources":["../../../src/helpers/queue/queue.helper.ts"],"names":[],"mappings":"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"}
|
package/dist/utilities/index.js
CHANGED
@@ -19,6 +19,7 @@ __exportStar(require("./date.utility"), exports);
|
|
19
19
|
__exportStar(require("./error.utility"), exports);
|
20
20
|
__exportStar(require("./parse.utility"), exports);
|
21
21
|
__exportStar(require("./performance.utility"), exports);
|
22
|
+
__exportStar(require("./promise.utility"), exports);
|
22
23
|
__exportStar(require("./request.utility"), exports);
|
23
24
|
__exportStar(require("./url.utility"), exports);
|
24
25
|
//# sourceMappingURL=index.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utilities/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,mDAAiC;AACjC,iDAA+B;AAC/B,kDAAgC;AAChC,kDAAgC;AAChC,wDAAsC;AACtC,oDAAkC;AAClC,gDAA8B"}
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utilities/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,mDAAiC;AACjC,iDAA+B;AAC/B,kDAAgC;AAChC,kDAAgC;AAChC,wDAAsC;AACtC,oDAAkC;AAClC,oDAAkC;AAClC,gDAA8B"}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import { ValueOrPromise } from '../common';
|
2
|
+
type TTask<T> = () => Promise<T>;
|
3
|
+
export declare const executePromiseWithLimit: <T>(opts: {
|
4
|
+
tasks: Array<TTask<T>>;
|
5
|
+
limit: number;
|
6
|
+
onTaskDone?: <R>(opts: {
|
7
|
+
result: R;
|
8
|
+
}) => ValueOrPromise<void>;
|
9
|
+
}) => Promise<Awaited<T>[]>;
|
10
|
+
export {};
|
@@ -0,0 +1,33 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
9
|
+
});
|
10
|
+
};
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
12
|
+
exports.executePromiseWithLimit = void 0;
|
13
|
+
const executePromiseWithLimit = (opts) => __awaiter(void 0, void 0, void 0, function* () {
|
14
|
+
const { tasks, limit, onTaskDone } = opts;
|
15
|
+
const results = [];
|
16
|
+
const executing = new Set();
|
17
|
+
for (const task of tasks) {
|
18
|
+
const promise = task().then(result => {
|
19
|
+
executing.delete(promise);
|
20
|
+
return result;
|
21
|
+
});
|
22
|
+
executing.add(promise);
|
23
|
+
results.push(promise);
|
24
|
+
if (executing.size >= limit) {
|
25
|
+
const done = yield Promise.race(executing);
|
26
|
+
onTaskDone === null || onTaskDone === void 0 ? void 0 : onTaskDone({ result: done });
|
27
|
+
}
|
28
|
+
}
|
29
|
+
yield Promise.all(executing);
|
30
|
+
return Promise.all(results);
|
31
|
+
});
|
32
|
+
exports.executePromiseWithLimit = executePromiseWithLimit;
|
33
|
+
//# sourceMappingURL=promise.utility.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"promise.utility.js","sourceRoot":"","sources":["../../src/utilities/promise.utility.ts"],"names":[],"mappings":";;;;;;;;;;;;AAIO,MAAM,uBAAuB,GAAG,CAAU,IAIhD,EAAE,EAAE;IACH,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IAE1C,MAAM,OAAO,GAAG,EAAE,CAAC;IACnB,MAAM,SAAS,GAAG,IAAI,GAAG,EAAE,CAAC;IAE5B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;YACnC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAC1B,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC,CAAC;QAEH,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACvB,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAEtB,IAAI,SAAS,CAAC,IAAI,IAAI,KAAK,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC3C,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED,MAAM,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC7B,OAAO,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAC9B,CAAC,CAAA,CAAC;AA3BW,QAAA,uBAAuB,2BA2BlC"}
|