@emmvish/stable-request 1.4.2 → 1.5.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/dist/constants/index.d.ts.map +1 -1
- package/dist/constants/index.js +4 -1
- package/dist/constants/index.js.map +1 -1
- package/dist/core/stable-api-gateway.d.ts.map +1 -1
- package/dist/core/stable-api-gateway.js +4 -1
- package/dist/core/stable-api-gateway.js.map +1 -1
- package/dist/core/stable-request.d.ts.map +1 -1
- package/dist/core/stable-request.js +8 -2
- package/dist/core/stable-request.js.map +1 -1
- package/dist/core/stable-workflow.d.ts.map +1 -1
- package/dist/core/stable-workflow.js +13 -5
- package/dist/core/stable-workflow.js.map +1 -1
- package/dist/enums/index.d.ts +5 -0
- package/dist/enums/index.d.ts.map +1 -1
- package/dist/enums/index.js +6 -0
- package/dist/enums/index.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +42 -5
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utilities/cache-manager.d.ts +28 -0
- package/dist/utilities/cache-manager.d.ts.map +1 -0
- package/dist/utilities/cache-manager.js +177 -0
- package/dist/utilities/cache-manager.js.map +1 -0
- package/dist/utilities/circuit-breaker.d.ts +38 -0
- package/dist/utilities/circuit-breaker.d.ts.map +1 -0
- package/dist/utilities/circuit-breaker.js +148 -0
- package/dist/utilities/circuit-breaker.js.map +1 -0
- package/dist/utilities/concurrency-limiter.d.ts +11 -0
- package/dist/utilities/concurrency-limiter.d.ts.map +1 -0
- package/dist/utilities/concurrency-limiter.js +38 -0
- package/dist/utilities/concurrency-limiter.js.map +1 -0
- package/dist/utilities/execute-concurrently.d.ts.map +1 -1
- package/dist/utilities/execute-concurrently.js +63 -8
- package/dist/utilities/execute-concurrently.js.map +1 -1
- package/dist/utilities/execute-phase.d.ts.map +1 -1
- package/dist/utilities/execute-phase.js +9 -0
- package/dist/utilities/execute-phase.js.map +1 -1
- package/dist/utilities/execute-sequentially.d.ts.map +1 -1
- package/dist/utilities/execute-sequentially.js +33 -7
- package/dist/utilities/execute-sequentially.js.map +1 -1
- package/dist/utilities/index.d.ts +4 -0
- package/dist/utilities/index.d.ts.map +1 -1
- package/dist/utilities/index.js +4 -0
- package/dist/utilities/index.js.map +1 -1
- package/dist/utilities/prepare-api-request-options.d.ts.map +1 -1
- package/dist/utilities/prepare-api-request-options.js.map +1 -1
- package/dist/utilities/rate-limiter.d.ts +21 -0
- package/dist/utilities/rate-limiter.d.ts.map +1 -0
- package/dist/utilities/rate-limiter.js +72 -0
- package/dist/utilities/rate-limiter.js.map +1 -0
- package/dist/utilities/req-fn.d.ts +2 -2
- package/dist/utilities/req-fn.d.ts.map +1 -1
- package/dist/utilities/req-fn.js +32 -6
- package/dist/utilities/req-fn.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import crypto from 'crypto';
|
|
2
|
+
export class CacheManager {
|
|
3
|
+
cache;
|
|
4
|
+
config;
|
|
5
|
+
accessOrder = [];
|
|
6
|
+
constructor(config) {
|
|
7
|
+
this.cache = new Map();
|
|
8
|
+
this.config = {
|
|
9
|
+
enabled: config.enabled,
|
|
10
|
+
ttl: config.ttl ?? 300000,
|
|
11
|
+
respectCacheControl: config.respectCacheControl ?? true,
|
|
12
|
+
cacheableStatusCodes: config.cacheableStatusCodes ?? [200, 203, 204, 206, 300, 301, 404, 405, 410, 414, 501],
|
|
13
|
+
maxSize: config.maxSize ?? 100,
|
|
14
|
+
excludeMethods: config.excludeMethods ?? ['POST', 'PUT', 'PATCH', 'DELETE'],
|
|
15
|
+
keyGenerator: config.keyGenerator
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
generateKey(reqConfig) {
|
|
19
|
+
if (this.config.keyGenerator) {
|
|
20
|
+
return this.config.keyGenerator(reqConfig);
|
|
21
|
+
}
|
|
22
|
+
const method = (reqConfig.method || 'GET').toUpperCase();
|
|
23
|
+
const url = reqConfig.url || '';
|
|
24
|
+
const params = reqConfig.params ? JSON.stringify(reqConfig.params) : '';
|
|
25
|
+
const relevantHeaders = ['accept', 'accept-encoding', 'accept-language', 'authorization'];
|
|
26
|
+
const headers = reqConfig.headers || {};
|
|
27
|
+
const headerString = relevantHeaders
|
|
28
|
+
.filter(h => headers[h])
|
|
29
|
+
.map(h => `${h}:${headers[h]}`)
|
|
30
|
+
.join('|');
|
|
31
|
+
const keyString = `${method}:${url}:${params}:${headerString}`;
|
|
32
|
+
return crypto.createHash('sha256').update(keyString).digest('hex');
|
|
33
|
+
}
|
|
34
|
+
shouldCacheMethod(method) {
|
|
35
|
+
if (!method)
|
|
36
|
+
return true;
|
|
37
|
+
return !this.config.excludeMethods.includes(method.toUpperCase());
|
|
38
|
+
}
|
|
39
|
+
shouldCacheStatus(status) {
|
|
40
|
+
return this.config.cacheableStatusCodes.includes(status);
|
|
41
|
+
}
|
|
42
|
+
parseCacheControl(headers) {
|
|
43
|
+
if (!this.config.respectCacheControl) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
const cacheControl = headers['cache-control'] || headers['Cache-Control'];
|
|
47
|
+
if (cacheControl && typeof cacheControl === 'string') {
|
|
48
|
+
if (cacheControl.includes('no-cache') || cacheControl.includes('no-store')) {
|
|
49
|
+
return 0;
|
|
50
|
+
}
|
|
51
|
+
const maxAgeMatch = cacheControl.match(/max-age=(\d+)/);
|
|
52
|
+
if (maxAgeMatch) {
|
|
53
|
+
return parseInt(maxAgeMatch[1]) * 1000;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// Check Expires header if no cache-control max-age was found
|
|
57
|
+
const expires = headers['expires'] || headers['Expires'];
|
|
58
|
+
if (expires) {
|
|
59
|
+
const expiresDate = new Date(expires);
|
|
60
|
+
const now = new Date();
|
|
61
|
+
const ttl = expiresDate.getTime() - now.getTime();
|
|
62
|
+
return ttl > 0 ? ttl : 0;
|
|
63
|
+
}
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
get(reqConfig) {
|
|
67
|
+
if (!this.config.enabled) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
if (!this.shouldCacheMethod(reqConfig.method)) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
const key = this.generateKey(reqConfig);
|
|
74
|
+
const cached = this.cache.get(key);
|
|
75
|
+
if (!cached) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
const now = Date.now();
|
|
79
|
+
if (now > cached.expiresAt) {
|
|
80
|
+
this.cache.delete(key);
|
|
81
|
+
this.accessOrder = this.accessOrder.filter(k => k !== key);
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
this.accessOrder = this.accessOrder.filter(k => k !== key);
|
|
85
|
+
this.accessOrder.push(key);
|
|
86
|
+
return cached;
|
|
87
|
+
}
|
|
88
|
+
set(reqConfig, data, status, statusText, headers) {
|
|
89
|
+
if (!this.config.enabled) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (!this.shouldCacheMethod(reqConfig.method)) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (!this.shouldCacheStatus(status)) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const key = this.generateKey(reqConfig);
|
|
99
|
+
const now = Date.now();
|
|
100
|
+
let ttl = this.config.ttl;
|
|
101
|
+
const cacheControlTtl = this.parseCacheControl(headers);
|
|
102
|
+
if (cacheControlTtl !== null) {
|
|
103
|
+
if (cacheControlTtl === 0) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
ttl = cacheControlTtl;
|
|
107
|
+
}
|
|
108
|
+
const cached = {
|
|
109
|
+
data,
|
|
110
|
+
status,
|
|
111
|
+
statusText,
|
|
112
|
+
headers,
|
|
113
|
+
timestamp: now,
|
|
114
|
+
expiresAt: now + ttl
|
|
115
|
+
};
|
|
116
|
+
if (this.cache.size >= this.config.maxSize) {
|
|
117
|
+
const oldestKey = this.accessOrder.shift();
|
|
118
|
+
if (oldestKey) {
|
|
119
|
+
this.cache.delete(oldestKey);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
this.cache.set(key, cached);
|
|
123
|
+
this.accessOrder.push(key);
|
|
124
|
+
}
|
|
125
|
+
clear() {
|
|
126
|
+
this.cache.clear();
|
|
127
|
+
this.accessOrder = [];
|
|
128
|
+
}
|
|
129
|
+
delete(reqConfig) {
|
|
130
|
+
const key = this.generateKey(reqConfig);
|
|
131
|
+
this.accessOrder = this.accessOrder.filter(k => k !== key);
|
|
132
|
+
return this.cache.delete(key);
|
|
133
|
+
}
|
|
134
|
+
getStats() {
|
|
135
|
+
const now = Date.now();
|
|
136
|
+
const entries = Array.from(this.cache.entries());
|
|
137
|
+
const validEntries = entries.filter(([_, cached]) => now <= cached.expiresAt);
|
|
138
|
+
return {
|
|
139
|
+
size: this.cache.size,
|
|
140
|
+
validEntries: validEntries.length,
|
|
141
|
+
expiredEntries: this.cache.size - validEntries.length,
|
|
142
|
+
maxSize: this.config.maxSize,
|
|
143
|
+
oldestEntry: entries.length > 0
|
|
144
|
+
? Math.min(...entries.map(([_, cached]) => cached.timestamp))
|
|
145
|
+
: null,
|
|
146
|
+
newestEntry: entries.length > 0
|
|
147
|
+
? Math.max(...entries.map(([_, cached]) => cached.timestamp))
|
|
148
|
+
: null
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
prune() {
|
|
152
|
+
const now = Date.now();
|
|
153
|
+
let prunedCount = 0;
|
|
154
|
+
for (const [key, cached] of this.cache.entries()) {
|
|
155
|
+
if (now > cached.expiresAt) {
|
|
156
|
+
this.cache.delete(key);
|
|
157
|
+
this.accessOrder = this.accessOrder.filter(k => k !== key);
|
|
158
|
+
prunedCount++;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return prunedCount;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
let globalCacheManager = null;
|
|
165
|
+
export function getGlobalCacheManager(config) {
|
|
166
|
+
if (!globalCacheManager && config) {
|
|
167
|
+
globalCacheManager = new CacheManager(config);
|
|
168
|
+
}
|
|
169
|
+
return globalCacheManager;
|
|
170
|
+
}
|
|
171
|
+
export function resetGlobalCacheManager() {
|
|
172
|
+
if (globalCacheManager) {
|
|
173
|
+
globalCacheManager.clear();
|
|
174
|
+
}
|
|
175
|
+
globalCacheManager = null;
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=cache-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-manager.js","sourceRoot":"","sources":["../../src/utilities/cache-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { CircuitBreakerConfig } from '../types/index.js';
|
|
2
|
+
import { CircuitBreakerState } from '../enums/index.js';
|
|
3
|
+
export declare class CircuitBreaker {
|
|
4
|
+
private state;
|
|
5
|
+
private readonly config;
|
|
6
|
+
private totalRequests;
|
|
7
|
+
private failedRequests;
|
|
8
|
+
private successfulRequests;
|
|
9
|
+
private lastFailureTime;
|
|
10
|
+
private halfOpenRequests;
|
|
11
|
+
private halfOpenSuccesses;
|
|
12
|
+
private halfOpenFailures;
|
|
13
|
+
constructor(config: CircuitBreakerConfig);
|
|
14
|
+
canExecute(): Promise<boolean>;
|
|
15
|
+
recordSuccess(): void;
|
|
16
|
+
recordFailure(): void;
|
|
17
|
+
private checkThreshold;
|
|
18
|
+
private checkHalfOpenTransition;
|
|
19
|
+
private transitionToClosed;
|
|
20
|
+
private transitionToOpen;
|
|
21
|
+
private transitionToHalfOpen;
|
|
22
|
+
private resetCounters;
|
|
23
|
+
private resetHalfOpenCounters;
|
|
24
|
+
getState(): {
|
|
25
|
+
state: CircuitBreakerState;
|
|
26
|
+
totalRequests: number;
|
|
27
|
+
failedRequests: number;
|
|
28
|
+
successfulRequests: number;
|
|
29
|
+
failurePercentage: number;
|
|
30
|
+
config: Required<CircuitBreakerConfig>;
|
|
31
|
+
};
|
|
32
|
+
reset(): void;
|
|
33
|
+
execute<T>(fn: () => Promise<T>): Promise<T>;
|
|
34
|
+
}
|
|
35
|
+
export declare class CircuitBreakerOpenError extends Error {
|
|
36
|
+
constructor(message: string);
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=circuit-breaker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circuit-breaker.d.ts","sourceRoot":"","sources":["../../src/utilities/circuit-breaker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,qBAAa,cAAc;IACvB,OAAO,CAAC,KAAK,CAAmD;IAChE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiC;IAExD,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,cAAc,CAAa;IACnC,OAAO,CAAC,kBAAkB,CAAa;IAEvC,OAAO,CAAC,eAAe,CAAa;IACpC,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,iBAAiB,CAAa;IACtC,OAAO,CAAC,gBAAgB,CAAa;gBAEzB,MAAM,EAAE,oBAAoB;IAUlC,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAqBpC,aAAa,IAAI,IAAI;IAerB,aAAa,IAAI,IAAI;IAcrB,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,uBAAuB;IAY/B,OAAO,CAAC,kBAAkB;IAM1B,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,oBAAoB;IAK5B,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,qBAAqB;IAM7B,QAAQ,IAAI;QACR,KAAK,EAAE,mBAAmB,CAAC;QAC3B,aAAa,EAAE,MAAM,CAAC;QACtB,cAAc,EAAE,MAAM,CAAC;QACvB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,iBAAiB,EAAE,MAAM,CAAC;QAC1B,MAAM,EAAE,QAAQ,CAAC,oBAAoB,CAAC,CAAC;KAC1C;IAaD,KAAK,IAAI,IAAI;IAOP,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;CAkBrD;AAED,qBAAa,uBAAwB,SAAQ,KAAK;gBAClC,OAAO,EAAE,MAAM;CAI9B"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { CircuitBreakerState } from '../enums/index.js';
|
|
2
|
+
export class CircuitBreaker {
|
|
3
|
+
state = CircuitBreakerState.CLOSED;
|
|
4
|
+
config;
|
|
5
|
+
totalRequests = 0;
|
|
6
|
+
failedRequests = 0;
|
|
7
|
+
successfulRequests = 0;
|
|
8
|
+
lastFailureTime = 0;
|
|
9
|
+
halfOpenRequests = 0;
|
|
10
|
+
halfOpenSuccesses = 0;
|
|
11
|
+
halfOpenFailures = 0;
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.config = {
|
|
14
|
+
failureThresholdPercentage: Math.max(0, Math.min(100, config.failureThresholdPercentage)),
|
|
15
|
+
minimumRequests: Math.max(1, config.minimumRequests),
|
|
16
|
+
recoveryTimeoutMs: Math.max(100, config.recoveryTimeoutMs),
|
|
17
|
+
successThresholdPercentage: config.successThresholdPercentage ?? 50,
|
|
18
|
+
halfOpenMaxRequests: config.halfOpenMaxRequests ?? 5
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
async canExecute() {
|
|
22
|
+
if (this.state === CircuitBreakerState.CLOSED) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
if (this.state === CircuitBreakerState.OPEN) {
|
|
26
|
+
const timeSinceLastFailure = Date.now() - this.lastFailureTime;
|
|
27
|
+
if (timeSinceLastFailure >= this.config.recoveryTimeoutMs) {
|
|
28
|
+
this.transitionToHalfOpen();
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
if (this.state === CircuitBreakerState.HALF_OPEN) {
|
|
34
|
+
return this.halfOpenRequests < this.config.halfOpenMaxRequests;
|
|
35
|
+
}
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
recordSuccess() {
|
|
39
|
+
this.totalRequests++;
|
|
40
|
+
this.successfulRequests++;
|
|
41
|
+
if (this.state === CircuitBreakerState.HALF_OPEN) {
|
|
42
|
+
this.halfOpenSuccesses++;
|
|
43
|
+
this.halfOpenRequests++;
|
|
44
|
+
this.checkHalfOpenTransition();
|
|
45
|
+
}
|
|
46
|
+
else if (this.state === CircuitBreakerState.CLOSED) {
|
|
47
|
+
if (this.totalRequests >= this.config.minimumRequests * 10) {
|
|
48
|
+
this.resetCounters();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
recordFailure() {
|
|
53
|
+
this.totalRequests++;
|
|
54
|
+
this.failedRequests++;
|
|
55
|
+
this.lastFailureTime = Date.now();
|
|
56
|
+
if (this.state === CircuitBreakerState.HALF_OPEN) {
|
|
57
|
+
this.halfOpenFailures++;
|
|
58
|
+
this.halfOpenRequests++;
|
|
59
|
+
this.checkHalfOpenTransition();
|
|
60
|
+
}
|
|
61
|
+
else if (this.state === CircuitBreakerState.CLOSED) {
|
|
62
|
+
this.checkThreshold();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
checkThreshold() {
|
|
66
|
+
if (this.totalRequests < this.config.minimumRequests) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const failurePercentage = (this.failedRequests / this.totalRequests) * 100;
|
|
70
|
+
if (failurePercentage >= this.config.failureThresholdPercentage) {
|
|
71
|
+
this.transitionToOpen();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
checkHalfOpenTransition() {
|
|
75
|
+
if (this.halfOpenRequests >= this.config.halfOpenMaxRequests) {
|
|
76
|
+
const successPercentage = (this.halfOpenSuccesses / this.halfOpenRequests) * 100;
|
|
77
|
+
if (successPercentage >= this.config.successThresholdPercentage) {
|
|
78
|
+
this.transitionToClosed();
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
this.transitionToOpen();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
transitionToClosed() {
|
|
86
|
+
this.state = CircuitBreakerState.CLOSED;
|
|
87
|
+
this.resetCounters();
|
|
88
|
+
this.resetHalfOpenCounters();
|
|
89
|
+
}
|
|
90
|
+
transitionToOpen() {
|
|
91
|
+
this.state = CircuitBreakerState.OPEN;
|
|
92
|
+
this.resetHalfOpenCounters();
|
|
93
|
+
}
|
|
94
|
+
transitionToHalfOpen() {
|
|
95
|
+
this.state = CircuitBreakerState.HALF_OPEN;
|
|
96
|
+
this.resetHalfOpenCounters();
|
|
97
|
+
}
|
|
98
|
+
resetCounters() {
|
|
99
|
+
this.totalRequests = 0;
|
|
100
|
+
this.failedRequests = 0;
|
|
101
|
+
this.successfulRequests = 0;
|
|
102
|
+
}
|
|
103
|
+
resetHalfOpenCounters() {
|
|
104
|
+
this.halfOpenRequests = 0;
|
|
105
|
+
this.halfOpenSuccesses = 0;
|
|
106
|
+
this.halfOpenFailures = 0;
|
|
107
|
+
}
|
|
108
|
+
getState() {
|
|
109
|
+
return {
|
|
110
|
+
state: this.state,
|
|
111
|
+
totalRequests: this.totalRequests,
|
|
112
|
+
failedRequests: this.failedRequests,
|
|
113
|
+
successfulRequests: this.successfulRequests,
|
|
114
|
+
failurePercentage: this.totalRequests > 0
|
|
115
|
+
? (this.failedRequests / this.totalRequests) * 100
|
|
116
|
+
: 0,
|
|
117
|
+
config: this.config
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
reset() {
|
|
121
|
+
this.state = CircuitBreakerState.CLOSED;
|
|
122
|
+
this.resetCounters();
|
|
123
|
+
this.resetHalfOpenCounters();
|
|
124
|
+
this.lastFailureTime = 0;
|
|
125
|
+
}
|
|
126
|
+
async execute(fn) {
|
|
127
|
+
const canExecute = await this.canExecute();
|
|
128
|
+
if (!canExecute) {
|
|
129
|
+
throw new CircuitBreakerOpenError(`Circuit breaker is ${this.state}. Request blocked.`);
|
|
130
|
+
}
|
|
131
|
+
try {
|
|
132
|
+
const result = await fn();
|
|
133
|
+
this.recordSuccess();
|
|
134
|
+
return result;
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
this.recordFailure();
|
|
138
|
+
throw error;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
export class CircuitBreakerOpenError extends Error {
|
|
143
|
+
constructor(message) {
|
|
144
|
+
super(message);
|
|
145
|
+
this.name = 'CircuitBreakerOpenError';
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=circuit-breaker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circuit-breaker.js","sourceRoot":"","sources":["../../src/utilities/circuit-breaker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare class ConcurrencyLimiter {
|
|
2
|
+
private readonly limit;
|
|
3
|
+
private running;
|
|
4
|
+
private readonly queue;
|
|
5
|
+
constructor(limit: number);
|
|
6
|
+
private acquire;
|
|
7
|
+
private release;
|
|
8
|
+
execute<T>(fn: () => Promise<T>): Promise<T>;
|
|
9
|
+
executeAll<T>(fns: Array<() => Promise<T>>): Promise<T[]>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=concurrency-limiter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"concurrency-limiter.d.ts","sourceRoot":"","sources":["../../src/utilities/concurrency-limiter.ts"],"names":[],"mappings":"AAAA,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAyB;gBAEnC,KAAK,EAAE,MAAM;YAIX,OAAO;IAWrB,OAAO,CAAC,OAAO;IAST,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAS5C,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;CAGlE"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export class ConcurrencyLimiter {
|
|
2
|
+
limit;
|
|
3
|
+
running = 0;
|
|
4
|
+
queue = [];
|
|
5
|
+
constructor(limit) {
|
|
6
|
+
this.limit = Math.max(1, Math.floor(limit));
|
|
7
|
+
}
|
|
8
|
+
async acquire() {
|
|
9
|
+
if (this.running < this.limit) {
|
|
10
|
+
this.running++;
|
|
11
|
+
return Promise.resolve();
|
|
12
|
+
}
|
|
13
|
+
return new Promise((resolve) => {
|
|
14
|
+
this.queue.push(resolve);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
release() {
|
|
18
|
+
this.running--;
|
|
19
|
+
const next = this.queue.shift();
|
|
20
|
+
if (next) {
|
|
21
|
+
this.running++;
|
|
22
|
+
next();
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
async execute(fn) {
|
|
26
|
+
await this.acquire();
|
|
27
|
+
try {
|
|
28
|
+
return await fn();
|
|
29
|
+
}
|
|
30
|
+
finally {
|
|
31
|
+
this.release();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
async executeAll(fns) {
|
|
35
|
+
return Promise.all(fns.map(fn => this.execute(fn)));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=concurrency-limiter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"concurrency-limiter.js","sourceRoot":"","sources":["../../src/utilities/concurrency-limiter.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,kBAAkB;IACV,KAAK,CAAS;IACvB,OAAO,GAAW,CAAC,CAAC;IACX,KAAK,GAAsB,EAAE,CAAC;IAE/C,YAAY,KAAa;QACrB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IAChD,CAAC;IAEO,KAAK,CAAC,OAAO;QACjB,IAAI,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;YAC5B,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;QAC7B,CAAC;QAED,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YACjC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,OAAO;QACX,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAChC,IAAI,IAAI,EAAE,CAAC;YACP,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,IAAI,EAAE,CAAC;QACX,CAAC;IACL,CAAC;IAED,KAAK,CAAC,OAAO,CAAI,EAAoB;QACjC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACrB,IAAI,CAAC;YACD,OAAO,MAAM,EAAE,EAAE,CAAC;QACtB,CAAC;gBAAS,CAAC;YACP,IAAI,CAAC,OAAO,EAAE,CAAC;QACnB,CAAC;IACL,CAAC;IAED,KAAK,CAAC,UAAU,CAAI,GAA4B;QAC5C,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACxD,CAAC;CACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute-concurrently.d.ts","sourceRoot":"","sources":["../../src/utilities/execute-concurrently.ts"],"names":[],"mappings":"AACA,OAAO,EACH,mBAAmB,EACnB,oBAAoB,EACpB,oCAAoC,EACvC,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"execute-concurrently.d.ts","sourceRoot":"","sources":["../../src/utilities/execute-concurrently.ts"],"names":[],"mappings":"AACA,OAAO,EACH,mBAAmB,EACnB,oBAAoB,EACpB,oCAAoC,EACvC,MAAM,mBAAmB,CAAC;AAO3B,wBAAsB,mBAAmB,CAAC,eAAe,GAAG,GAAG,EAAE,gBAAgB,GAAG,GAAG,EACnF,QAAQ,GAAE,mBAAmB,CAAC,eAAe,EAAE,gBAAgB,CAAC,EAAO,EACvE,uBAAuB,GAAE,oCAAoC,CAAC,eAAe,EAAE,gBAAgB,CAAM,GACtG,OAAO,CAAC,oBAAoB,CAAC,gBAAgB,CAAC,EAAE,CAAC,CA+GnD"}
|
|
@@ -1,16 +1,67 @@
|
|
|
1
1
|
import { stableRequest } from "../core/index.js";
|
|
2
2
|
import { prepareApiRequestData } from "./prepare-api-request-data.js";
|
|
3
3
|
import { prepareApiRequestOptions } from "./prepare-api-request-options.js";
|
|
4
|
+
import { ConcurrencyLimiter } from "./concurrency-limiter.js";
|
|
5
|
+
import { RateLimiter } from "./rate-limiter.js";
|
|
6
|
+
import { CircuitBreaker, CircuitBreakerOpenError } from "./circuit-breaker.js";
|
|
4
7
|
export async function executeConcurrently(requests = [], requestExecutionOptions = {}) {
|
|
5
8
|
const responses = [];
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
// Support both config and instance
|
|
10
|
+
const circuitBreaker = requestExecutionOptions.circuitBreaker
|
|
11
|
+
? (requestExecutionOptions.circuitBreaker instanceof CircuitBreaker
|
|
12
|
+
? requestExecutionOptions.circuitBreaker
|
|
13
|
+
: new CircuitBreaker(requestExecutionOptions.circuitBreaker))
|
|
14
|
+
: null;
|
|
15
|
+
const requestFunctions = requests.map((req) => {
|
|
16
|
+
return async () => {
|
|
17
|
+
if (circuitBreaker) {
|
|
18
|
+
const canExecute = await circuitBreaker.canExecute();
|
|
19
|
+
if (!canExecute) {
|
|
20
|
+
throw new CircuitBreakerOpenError(`Circuit breaker is ${circuitBreaker.getState().state}. Request blocked.`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
const finalRequestOptions = {
|
|
24
|
+
reqData: prepareApiRequestData(req, requestExecutionOptions),
|
|
25
|
+
...prepareApiRequestOptions(req, requestExecutionOptions),
|
|
26
|
+
commonBuffer: requestExecutionOptions.sharedBuffer ?? req.requestOptions.commonBuffer
|
|
27
|
+
};
|
|
28
|
+
try {
|
|
29
|
+
const result = await stableRequest(finalRequestOptions);
|
|
30
|
+
if (circuitBreaker) {
|
|
31
|
+
circuitBreaker.recordSuccess();
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
if (circuitBreaker && !(error instanceof CircuitBreakerOpenError)) {
|
|
37
|
+
circuitBreaker.recordFailure();
|
|
38
|
+
}
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
12
41
|
};
|
|
13
|
-
|
|
42
|
+
});
|
|
43
|
+
let stableRequests;
|
|
44
|
+
const hasConcurrencyLimit = requestExecutionOptions.maxConcurrentRequests &&
|
|
45
|
+
requestExecutionOptions.maxConcurrentRequests > 0 &&
|
|
46
|
+
requestExecutionOptions.maxConcurrentRequests < requests.length;
|
|
47
|
+
const hasRateLimit = requestExecutionOptions.rateLimit &&
|
|
48
|
+
requestExecutionOptions.rateLimit.maxRequests > 0 &&
|
|
49
|
+
requestExecutionOptions.rateLimit.windowMs > 0;
|
|
50
|
+
if (hasConcurrencyLimit && hasRateLimit) {
|
|
51
|
+
const concurrencyLimiter = new ConcurrencyLimiter(requestExecutionOptions.maxConcurrentRequests);
|
|
52
|
+
const rateLimiter = new RateLimiter(requestExecutionOptions.rateLimit.maxRequests, requestExecutionOptions.rateLimit.windowMs);
|
|
53
|
+
stableRequests = requestFunctions.map(fn => concurrencyLimiter.execute(() => rateLimiter.execute(fn)));
|
|
54
|
+
}
|
|
55
|
+
else if (hasConcurrencyLimit) {
|
|
56
|
+
const concurrencyLimiter = new ConcurrencyLimiter(requestExecutionOptions.maxConcurrentRequests);
|
|
57
|
+
stableRequests = requestFunctions.map(fn => concurrencyLimiter.execute(fn));
|
|
58
|
+
}
|
|
59
|
+
else if (hasRateLimit) {
|
|
60
|
+
const rateLimiter = new RateLimiter(requestExecutionOptions.rateLimit.maxRequests, requestExecutionOptions.rateLimit.windowMs);
|
|
61
|
+
stableRequests = requestFunctions.map(fn => rateLimiter.execute(fn));
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
stableRequests = requestFunctions.map(fn => fn());
|
|
14
65
|
}
|
|
15
66
|
const settledResponses = await Promise.allSettled(stableRequests);
|
|
16
67
|
for (let i = 0; i < settledResponses.length; i++) {
|
|
@@ -30,11 +81,15 @@ export async function executeConcurrently(requests = [], requestExecutionOptions
|
|
|
30
81
|
});
|
|
31
82
|
}
|
|
32
83
|
else {
|
|
84
|
+
const error = res.reason;
|
|
85
|
+
const isCircuitBreakerError = error instanceof CircuitBreakerOpenError;
|
|
33
86
|
responses.push({
|
|
34
87
|
requestId: req.id,
|
|
35
88
|
...(req.groupId && { groupId: req.groupId }),
|
|
36
89
|
success: false,
|
|
37
|
-
error:
|
|
90
|
+
error: isCircuitBreakerError
|
|
91
|
+
? `Circuit breaker open: ${error.message}`
|
|
92
|
+
: (error?.message || 'An error occurred! Error description is unavailable.')
|
|
38
93
|
});
|
|
39
94
|
}
|
|
40
95
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute-concurrently.js","sourceRoot":"","sources":["../../src/utilities/execute-concurrently.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAMjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"execute-concurrently.js","sourceRoot":"","sources":["../../src/utilities/execute-concurrently.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute-phase.d.ts","sourceRoot":"","sources":["../../src/utilities/execute-phase.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,wBAAsB,YAAY,CAAC,eAAe,GAAG,GAAG,EAAE,gBAAgB,GAAG,GAAG,EAC5E,KAAK,EAAE,qBAAqB,CAAC,eAAe,EAAE,gBAAgB,CAAC,EAC/D,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,oBAAoB,EAAE,GAAG,EACzB,aAAa,EAAE,GAAG,EAAE,EACpB,eAAe,EAAE,OAAO,EACxB,qBAAqB,EAAE,QAAQ,EAC/B,oBAAoB,EAAE,MAAM,EAC5B,kBAAkB,EAAE,GAAG,EACvB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"execute-phase.d.ts","sourceRoot":"","sources":["../../src/utilities/execute-phase.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,wBAAsB,YAAY,CAAC,eAAe,GAAG,GAAG,EAAE,gBAAgB,GAAG,GAAG,EAC5E,KAAK,EAAE,qBAAqB,CAAC,eAAe,EAAE,gBAAgB,CAAC,EAC/D,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,oBAAoB,EAAE,GAAG,EACzB,aAAa,EAAE,GAAG,EAAE,EACpB,eAAe,EAAE,OAAO,EACxB,qBAAqB,EAAE,QAAQ,EAC/B,oBAAoB,EAAE,MAAM,EAC5B,kBAAkB,EAAE,GAAG,EACvB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;;;;;;;;;;GA2ErC"}
|
|
@@ -11,6 +11,15 @@ export async function executePhase(phase, phaseIndex, workflowId, commonGatewayO
|
|
|
11
11
|
requestGroups,
|
|
12
12
|
sharedBuffer
|
|
13
13
|
};
|
|
14
|
+
if (phase.maxConcurrentRequests !== undefined) {
|
|
15
|
+
phaseGatewayOptions.maxConcurrentRequests = phase.maxConcurrentRequests;
|
|
16
|
+
}
|
|
17
|
+
if (phase.rateLimit !== undefined) {
|
|
18
|
+
phaseGatewayOptions.rateLimit = phase.rateLimit;
|
|
19
|
+
}
|
|
20
|
+
if (phase.circuitBreaker !== undefined) {
|
|
21
|
+
phaseGatewayOptions.circuitBreaker = phase.circuitBreaker;
|
|
22
|
+
}
|
|
14
23
|
const phaseResponses = await stableApiGateway(phase.requests, phaseGatewayOptions);
|
|
15
24
|
const phaseExecutionTime = Date.now() - phaseStartTime;
|
|
16
25
|
const phaseSuccessCount = phaseResponses.filter(r => r.success).length;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute-phase.js","sourceRoot":"","sources":["../../src/utilities/execute-phase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAC;AAGjF,MAAM,CAAC,KAAK,UAAU,YAAY,CAC9B,KAA+D,EAC/D,UAAkB,EAClB,UAAkB,EAClB,oBAAyB,EACzB,aAAoB,EACpB,eAAwB,EACxB,qBAA+B,EAC/B,oBAA4B,EAC5B,kBAAuB,EACvB,YAAkC;IAElC,MAAM,OAAO,GAAG,KAAK,CAAC,EAAE,IAAI,SAAS,UAAU,GAAG,CAAC,EAAE,CAAC;IACtD,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAElC,MAAM,mBAAmB,GAAG;QACxB,GAAG,oBAAoB;QACvB,GAAG,CAAC,KAAK,CAAC,YAAY,IAAI,EAAE,CAAC;QAC7B,mBAAmB,EAAE,KAAK,CAAC,mBAAmB,IAAI,IAAI;QACtD,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,IAAI,KAAK;QACjD,aAAa;QACb,YAAY;KACf,CAAC;IAEF,MAAM,cAAc,GAAG,MAAM,gBAAgB,CACzC,KAAK,CAAC,QAAQ,EACd,mBAAmB,CACtB,CAAC;IAEF,MAAM,kBAAkB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,cAAc,CAAC;IACvD,MAAM,iBAAiB,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IACvE,MAAM,iBAAiB,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IAExE,MAAM,WAAW,GAAG;QAChB,OAAO;QACP,UAAU;QACV,OAAO,EAAE,iBAAiB,KAAK,CAAC;QAChC,aAAa,EAAE,kBAAkB;QACjC,SAAS,EAAE,IAAI,IAAI,CAAC,cAAc,CAAC,CAAC,WAAW,EAAE;QACjD,aAAa,EAAE,cAAc,CAAC,MAAM;QACpC,kBAAkB,EAAE,iBAAiB;QACrC,cAAc,EAAE,iBAAiB;QACjC,SAAS,EAAE,cAAc;KAC5B,CAAC;IAEF,IAAI,eAAe,EAAE,CAAC;QAClB,OAAO,CAAC,IAAI,CACR,8BAA8B,UAAU,WAAW,OAAO,aAAa,EACvE,GAAG,iBAAiB,IAAI,cAAc,CAAC,MAAM,aAAa,EAC1D,IAAI,kBAAkB,KAAK,CAC9B,CAAC;IACN,CAAC;IAED,IAAI,qBAAqB,EAAE,CAAC;QACxB,IAAI,CAAC;YACD,MAAM,4BAA4B,CAC9B,qBAAqB,EAAE;gBACnB,UAAU;gBACV,WAAW;gBACX,oBAAoB;gBACpB,MAAM,EAAE,kBAAkB,EAAE,2BAA2B;gBACvD,YAAY;aACf,CACJ,CAAC;QACN,CAAC;QAAC,OAAO,SAAS,EAAE,CAAC;YACjB,OAAO,CAAC,KAAK,CACT,8BAA8B,UAAU,wCAAwC,EAChF,SAAS,CACZ,CAAC;QACN,CAAC;IACL,CAAC;IAED,OAAO,WAAW,CAAC;AACvB,CAAC"}
|
|
1
|
+
{"version":3,"file":"execute-phase.js","sourceRoot":"","sources":["../../src/utilities/execute-phase.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAC;AAGjF,MAAM,CAAC,KAAK,UAAU,YAAY,CAC9B,KAA+D,EAC/D,UAAkB,EAClB,UAAkB,EAClB,oBAAyB,EACzB,aAAoB,EACpB,eAAwB,EACxB,qBAA+B,EAC/B,oBAA4B,EAC5B,kBAAuB,EACvB,YAAkC;IAElC,MAAM,OAAO,GAAG,KAAK,CAAC,EAAE,IAAI,SAAS,UAAU,GAAG,CAAC,EAAE,CAAC;IACtD,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAElC,MAAM,mBAAmB,GAAG;QACxB,GAAG,oBAAoB;QACvB,GAAG,CAAC,KAAK,CAAC,YAAY,IAAI,EAAE,CAAC;QAC7B,mBAAmB,EAAE,KAAK,CAAC,mBAAmB,IAAI,IAAI;QACtD,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,IAAI,KAAK;QACjD,aAAa;QACb,YAAY;KACf,CAAC;IAEF,IAAI,KAAK,CAAC,qBAAqB,KAAK,SAAS,EAAE,CAAC;QAC5C,mBAAmB,CAAC,qBAAqB,GAAG,KAAK,CAAC,qBAAqB,CAAC;IAC5E,CAAC;IAED,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QAChC,mBAAmB,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;IACpD,CAAC;IAED,IAAI,KAAK,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;QACrC,mBAAmB,CAAC,cAAc,GAAG,KAAK,CAAC,cAAc,CAAC;IAC9D,CAAC;IAED,MAAM,cAAc,GAAG,MAAM,gBAAgB,CACzC,KAAK,CAAC,QAAQ,EACd,mBAAmB,CACtB,CAAC;IAEF,MAAM,kBAAkB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,cAAc,CAAC;IACvD,MAAM,iBAAiB,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IACvE,MAAM,iBAAiB,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IAExE,MAAM,WAAW,GAAG;QAChB,OAAO;QACP,UAAU;QACV,OAAO,EAAE,iBAAiB,KAAK,CAAC;QAChC,aAAa,EAAE,kBAAkB;QACjC,SAAS,EAAE,IAAI,IAAI,CAAC,cAAc,CAAC,CAAC,WAAW,EAAE;QACjD,aAAa,EAAE,cAAc,CAAC,MAAM;QACpC,kBAAkB,EAAE,iBAAiB;QACrC,cAAc,EAAE,iBAAiB;QACjC,SAAS,EAAE,cAAc;KAC5B,CAAC;IAEF,IAAI,eAAe,EAAE,CAAC;QAClB,OAAO,CAAC,IAAI,CACR,8BAA8B,UAAU,WAAW,OAAO,aAAa,EACvE,GAAG,iBAAiB,IAAI,cAAc,CAAC,MAAM,aAAa,EAC1D,IAAI,kBAAkB,KAAK,CAC9B,CAAC;IACN,CAAC;IAED,IAAI,qBAAqB,EAAE,CAAC;QACxB,IAAI,CAAC;YACD,MAAM,4BAA4B,CAC9B,qBAAqB,EAAE;gBACnB,UAAU;gBACV,WAAW;gBACX,oBAAoB;gBACpB,MAAM,EAAE,kBAAkB,EAAE,2BAA2B;gBACvD,YAAY;aACf,CACJ,CAAC;QACN,CAAC;QAAC,OAAO,SAAS,EAAE,CAAC;YACjB,OAAO,CAAC,KAAK,CACT,8BAA8B,UAAU,wCAAwC,EAChF,SAAS,CACZ,CAAC;QACN,CAAC;IACL,CAAC;IAED,OAAO,WAAW,CAAC;AACvB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute-sequentially.d.ts","sourceRoot":"","sources":["../../src/utilities/execute-sequentially.ts"],"names":[],"mappings":"AAGA,OAAO,EACH,mBAAmB,EACnB,oBAAoB,EACpB,oCAAoC,EACvC,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"execute-sequentially.d.ts","sourceRoot":"","sources":["../../src/utilities/execute-sequentially.ts"],"names":[],"mappings":"AAGA,OAAO,EACH,mBAAmB,EACnB,oBAAoB,EACpB,oCAAoC,EACvC,MAAM,mBAAmB,CAAC;AAG3B,wBAAsB,mBAAmB,CAAC,eAAe,GAAG,GAAG,EAAE,gBAAgB,GAAG,GAAG,EACnF,QAAQ,GAAE,mBAAmB,CAAC,eAAe,EAAE,gBAAgB,CAAC,EAAO,EACvE,uBAAuB,GAAE,oCAAoC,CAAC,eAAe,EAAE,gBAAgB,CAAM,GACtG,OAAO,CAAC,oBAAoB,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAqEnD"}
|