@bluelibs/runner 2.2.3 → 3.0.0
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 +1315 -942
- package/dist/common.types.d.ts +20 -0
- package/dist/common.types.js +4 -0
- package/dist/common.types.js.map +1 -0
- package/dist/context.d.ts +34 -0
- package/dist/context.js +58 -0
- package/dist/context.js.map +1 -0
- package/dist/define.d.ts +22 -3
- package/dist/define.js +52 -8
- package/dist/define.js.map +1 -1
- package/dist/defs.d.ts +52 -31
- package/dist/defs.js +10 -2
- package/dist/defs.js.map +1 -1
- package/dist/errors.js +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/event.types.d.ts +18 -0
- package/dist/event.types.js +4 -0
- package/dist/event.types.js.map +1 -0
- package/dist/examples/registrator-example.d.ts +122 -0
- package/dist/examples/registrator-example.js +147 -0
- package/dist/examples/registrator-example.js.map +1 -0
- package/dist/globals/globalEvents.d.ts +41 -0
- package/dist/globals/globalEvents.js +94 -0
- package/dist/globals/globalEvents.js.map +1 -0
- package/dist/globals/globalMiddleware.d.ts +23 -0
- package/dist/globals/globalMiddleware.js +15 -0
- package/dist/globals/globalMiddleware.js.map +1 -0
- package/dist/globals/globalResources.d.ts +27 -0
- package/dist/globals/globalResources.js +47 -0
- package/dist/globals/globalResources.js.map +1 -0
- package/dist/globals/middleware/cache.middleware.d.ts +34 -0
- package/dist/globals/middleware/cache.middleware.js +85 -0
- package/dist/globals/middleware/cache.middleware.js.map +1 -0
- package/dist/globals/middleware/requireContext.middleware.d.ts +6 -0
- package/dist/globals/middleware/requireContext.middleware.js +25 -0
- package/dist/globals/middleware/requireContext.middleware.js.map +1 -0
- package/dist/globals/middleware/retry.middleware.d.ts +20 -0
- package/dist/globals/middleware/retry.middleware.js +34 -0
- package/dist/globals/middleware/retry.middleware.js.map +1 -0
- package/dist/globals/resources/queue.resource.d.ts +7 -0
- package/dist/globals/resources/queue.resource.js +31 -0
- package/dist/globals/resources/queue.resource.js.map +1 -0
- package/dist/index.d.ts +45 -9
- package/dist/index.js +14 -9
- package/dist/index.js.map +1 -1
- package/dist/middleware.types.d.ts +40 -0
- package/dist/middleware.types.js +4 -0
- package/dist/middleware.types.js.map +1 -0
- package/dist/models/DependencyProcessor.d.ts +2 -1
- package/dist/models/DependencyProcessor.js +11 -13
- package/dist/models/DependencyProcessor.js.map +1 -1
- package/dist/models/EventManager.d.ts +5 -0
- package/dist/models/EventManager.js +44 -2
- package/dist/models/EventManager.js.map +1 -1
- package/dist/models/Logger.d.ts +30 -12
- package/dist/models/Logger.js +130 -42
- package/dist/models/Logger.js.map +1 -1
- package/dist/models/OverrideManager.d.ts +13 -0
- package/dist/models/OverrideManager.js +70 -0
- package/dist/models/OverrideManager.js.map +1 -0
- package/dist/models/Queue.d.ts +25 -0
- package/dist/models/Queue.js +54 -0
- package/dist/models/Queue.js.map +1 -0
- package/dist/models/ResourceInitializer.d.ts +5 -2
- package/dist/models/ResourceInitializer.js +20 -14
- package/dist/models/ResourceInitializer.js.map +1 -1
- package/dist/models/Semaphore.d.ts +61 -0
- package/dist/models/Semaphore.js +166 -0
- package/dist/models/Semaphore.js.map +1 -0
- package/dist/models/Store.d.ts +17 -72
- package/dist/models/Store.js +71 -269
- package/dist/models/Store.js.map +1 -1
- package/dist/models/StoreConstants.d.ts +11 -0
- package/dist/models/StoreConstants.js +18 -0
- package/dist/models/StoreConstants.js.map +1 -0
- package/dist/models/StoreRegistry.d.ts +25 -0
- package/dist/models/StoreRegistry.js +171 -0
- package/dist/models/StoreRegistry.js.map +1 -0
- package/dist/models/StoreTypes.d.ts +21 -0
- package/dist/models/StoreTypes.js +3 -0
- package/dist/models/StoreTypes.js.map +1 -0
- package/dist/models/StoreValidator.d.ts +10 -0
- package/dist/models/StoreValidator.js +41 -0
- package/dist/models/StoreValidator.js.map +1 -0
- package/dist/models/TaskRunner.js +39 -24
- package/dist/models/TaskRunner.js.map +1 -1
- package/dist/models/VarStore.d.ts +17 -0
- package/dist/models/VarStore.js +60 -0
- package/dist/models/VarStore.js.map +1 -0
- package/dist/models/index.d.ts +3 -0
- package/dist/models/index.js +3 -0
- package/dist/models/index.js.map +1 -1
- package/dist/resource.types.d.ts +31 -0
- package/dist/resource.types.js +3 -0
- package/dist/resource.types.js.map +1 -0
- package/dist/run.d.ts +4 -1
- package/dist/run.js +6 -3
- package/dist/run.js.map +1 -1
- package/dist/symbols.d.ts +24 -0
- package/dist/symbols.js +29 -0
- package/dist/symbols.js.map +1 -0
- package/dist/task.types.d.ts +55 -0
- package/dist/task.types.js +23 -0
- package/dist/task.types.js.map +1 -0
- package/dist/tools/registratorId.d.ts +4 -0
- package/dist/tools/registratorId.js +40 -0
- package/dist/tools/registratorId.js.map +1 -0
- package/dist/tools/simpleHash.d.ts +9 -0
- package/dist/tools/simpleHash.js +34 -0
- package/dist/tools/simpleHash.js.map +1 -0
- package/dist/types/base-interfaces.d.ts +18 -0
- package/dist/types/base-interfaces.js +6 -0
- package/dist/types/base-interfaces.js.map +1 -0
- package/dist/types/base.d.ts +13 -0
- package/dist/types/base.js +3 -0
- package/dist/types/base.js.map +1 -0
- package/dist/types/dependencies.d.ts +22 -0
- package/dist/types/dependencies.js +3 -0
- package/dist/types/dependencies.js.map +1 -0
- package/dist/types/dependency-core.d.ts +14 -0
- package/dist/types/dependency-core.js +5 -0
- package/dist/types/dependency-core.js.map +1 -0
- package/dist/types/events.d.ts +52 -0
- package/dist/types/events.js +6 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/hooks.d.ts +16 -0
- package/dist/types/hooks.js +5 -0
- package/dist/types/hooks.js.map +1 -0
- package/dist/types/index.d.ts +14 -0
- package/dist/types/index.js +27 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/meta.d.ts +13 -0
- package/dist/types/meta.js +5 -0
- package/dist/types/meta.js.map +1 -0
- package/dist/types/middleware.d.ts +38 -0
- package/dist/types/middleware.js +6 -0
- package/dist/types/middleware.js.map +1 -0
- package/dist/types/registerable.d.ts +10 -0
- package/dist/types/registerable.js +5 -0
- package/dist/types/registerable.js.map +1 -0
- package/dist/types/resources.d.ts +44 -0
- package/dist/types/resources.js +5 -0
- package/dist/types/resources.js.map +1 -0
- package/dist/types/symbols.d.ts +24 -0
- package/dist/types/symbols.js +30 -0
- package/dist/types/symbols.js.map +1 -0
- package/dist/types/tasks.d.ts +41 -0
- package/dist/types/tasks.js +5 -0
- package/dist/types/tasks.js.map +1 -0
- package/dist/types/utilities.d.ts +7 -0
- package/dist/types/utilities.js +5 -0
- package/dist/types/utilities.js.map +1 -0
- package/package.json +10 -6
- package/src/__tests__/benchmark/benchmark.test.ts +1 -1
- package/src/__tests__/context.test.ts +91 -0
- package/src/__tests__/errors.test.ts +8 -5
- package/src/__tests__/globalEvents.test.ts +1 -1
- package/src/__tests__/globals/cache.middleware.test.ts +772 -0
- package/src/__tests__/globals/queue.resource.test.ts +141 -0
- package/src/__tests__/globals/requireContext.middleware.test.ts +98 -0
- package/src/__tests__/globals/retry.middleware.test.ts +157 -0
- package/src/__tests__/index.helper.test.ts +55 -0
- package/src/__tests__/models/EventManager.test.ts +144 -0
- package/src/__tests__/models/Logger.test.ts +291 -34
- package/src/__tests__/models/Queue.test.ts +189 -0
- package/src/__tests__/models/ResourceInitializer.test.ts +8 -6
- package/src/__tests__/models/Semaphore.test.ts +713 -0
- package/src/__tests__/models/Store.test.ts +40 -0
- package/src/__tests__/models/TaskRunner.test.ts +86 -5
- package/src/__tests__/run.middleware.test.ts +166 -12
- package/src/__tests__/run.overrides.test.ts +13 -10
- package/src/__tests__/run.test.ts +363 -12
- package/src/__tests__/setOutput.test.ts +244 -0
- package/src/__tests__/tools/getCallerFile.test.ts +9 -9
- package/src/__tests__/typesafety.test.ts +54 -39
- package/src/context.ts +86 -0
- package/src/define.ts +84 -14
- package/src/defs.ts +91 -41
- package/src/errors.ts +3 -1
- package/src/{globalEvents.ts → globals/globalEvents.ts} +13 -12
- package/src/globals/globalMiddleware.ts +14 -0
- package/src/{globalResources.ts → globals/globalResources.ts} +14 -10
- package/src/globals/middleware/cache.middleware.ts +115 -0
- package/src/globals/middleware/requireContext.middleware.ts +36 -0
- package/src/globals/middleware/retry.middleware.ts +56 -0
- package/src/globals/resources/queue.resource.ts +34 -0
- package/src/index.ts +9 -5
- package/src/models/DependencyProcessor.ts +36 -40
- package/src/models/EventManager.ts +45 -5
- package/src/models/Logger.ts +170 -48
- package/src/models/OverrideManager.ts +84 -0
- package/src/models/Queue.ts +66 -0
- package/src/models/ResourceInitializer.ts +38 -20
- package/src/models/Semaphore.ts +208 -0
- package/src/models/Store.ts +94 -342
- package/src/models/StoreConstants.ts +17 -0
- package/src/models/StoreRegistry.ts +217 -0
- package/src/models/StoreTypes.ts +46 -0
- package/src/models/StoreValidator.ts +38 -0
- package/src/models/TaskRunner.ts +53 -40
- package/src/models/index.ts +3 -0
- package/src/run.ts +7 -4
- package/src/__tests__/index.ts +0 -15
- package/src/examples/express-mongo/index.ts +0 -1
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
interface WaitingOperation {
|
|
2
|
+
resolve: () => void;
|
|
3
|
+
reject: (error: Error) => void;
|
|
4
|
+
timeout?: NodeJS.Timeout;
|
|
5
|
+
abortController?: AbortController;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A semaphore that limits the number of concurrent operations.
|
|
10
|
+
* Used to prevent connection pool exhaustion by limiting concurrent
|
|
11
|
+
* database operations to the pool size.
|
|
12
|
+
*/
|
|
13
|
+
export class Semaphore {
|
|
14
|
+
private permits: number;
|
|
15
|
+
private readonly waitingQueue: Array<WaitingOperation> = [];
|
|
16
|
+
private disposed = false;
|
|
17
|
+
private readonly maxPermits: number;
|
|
18
|
+
|
|
19
|
+
constructor(maxPermits: number) {
|
|
20
|
+
if (maxPermits <= 0) {
|
|
21
|
+
throw new Error("maxPermits must be greater than 0");
|
|
22
|
+
}
|
|
23
|
+
this.permits = maxPermits;
|
|
24
|
+
this.maxPermits = maxPermits;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Acquire a permit. If no permits are available, waits until one becomes available.
|
|
29
|
+
*/
|
|
30
|
+
async acquire(options?: {
|
|
31
|
+
timeout?: number;
|
|
32
|
+
signal?: AbortSignal;
|
|
33
|
+
}): Promise<void> {
|
|
34
|
+
if (this.disposed) {
|
|
35
|
+
throw new Error("Semaphore has been disposed");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (options?.signal?.aborted) {
|
|
39
|
+
throw new Error("Operation was aborted");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (this.permits > 0) {
|
|
43
|
+
this.permits--;
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// No permits available, wait in queue
|
|
48
|
+
return new Promise<void>((resolve, reject) => {
|
|
49
|
+
const operation: WaitingOperation = { resolve, reject };
|
|
50
|
+
|
|
51
|
+
// Set up timeout if provided
|
|
52
|
+
if (options?.timeout && options.timeout > 0) {
|
|
53
|
+
operation.timeout = setTimeout(() => {
|
|
54
|
+
this.removeFromQueue(operation);
|
|
55
|
+
reject(
|
|
56
|
+
new Error(`Semaphore acquire timeout after ${options.timeout}ms`)
|
|
57
|
+
);
|
|
58
|
+
}, options.timeout);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Set up abort signal if provided
|
|
62
|
+
if (options?.signal) {
|
|
63
|
+
const abortHandler = () => {
|
|
64
|
+
this.removeFromQueue(operation);
|
|
65
|
+
reject(new Error("Operation was aborted"));
|
|
66
|
+
};
|
|
67
|
+
options.signal.addEventListener("abort", abortHandler, { once: true });
|
|
68
|
+
|
|
69
|
+
// Clean up the abort listener when operation completes
|
|
70
|
+
const originalResolve = operation.resolve;
|
|
71
|
+
const originalReject = operation.reject;
|
|
72
|
+
|
|
73
|
+
operation.resolve = () => {
|
|
74
|
+
options.signal!.removeEventListener("abort", abortHandler);
|
|
75
|
+
originalResolve();
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
operation.reject = (error: Error) => {
|
|
79
|
+
options.signal!.removeEventListener("abort", abortHandler);
|
|
80
|
+
originalReject(error);
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
this.waitingQueue.push(operation);
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Release a permit, allowing waiting operations to proceed.
|
|
90
|
+
*/
|
|
91
|
+
release(): void {
|
|
92
|
+
if (this.disposed) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (this.waitingQueue.length > 0) {
|
|
97
|
+
// Give permit directly to next waiting operation
|
|
98
|
+
const nextOperation = this.waitingQueue.shift()!;
|
|
99
|
+
|
|
100
|
+
// Clear timeout if it exists
|
|
101
|
+
if (nextOperation.timeout) {
|
|
102
|
+
clearTimeout(nextOperation.timeout);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
nextOperation.resolve();
|
|
106
|
+
} else {
|
|
107
|
+
// No one waiting, increment available permits (but don't exceed max)
|
|
108
|
+
this.permits = Math.min(this.permits + 1, this.maxPermits);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
private removeFromQueue(operation: WaitingOperation): void {
|
|
113
|
+
const index = this.waitingQueue.indexOf(operation);
|
|
114
|
+
if (index !== -1) {
|
|
115
|
+
this.waitingQueue.splice(index, 1);
|
|
116
|
+
|
|
117
|
+
// Clear timeout if it exists
|
|
118
|
+
if (operation.timeout) {
|
|
119
|
+
clearTimeout(operation.timeout);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Execute a function with a permit, automatically releasing it afterwards.
|
|
126
|
+
*/
|
|
127
|
+
async withPermit<T>(
|
|
128
|
+
fn: () => Promise<T>,
|
|
129
|
+
options?: { timeout?: number; signal?: AbortSignal }
|
|
130
|
+
): Promise<T> {
|
|
131
|
+
await this.acquire(options);
|
|
132
|
+
try {
|
|
133
|
+
return await fn();
|
|
134
|
+
} finally {
|
|
135
|
+
this.release();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Dispose the semaphore, rejecting all waiting operations and preventing new ones.
|
|
141
|
+
*/
|
|
142
|
+
dispose(): void {
|
|
143
|
+
if (this.disposed) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
this.disposed = true;
|
|
148
|
+
|
|
149
|
+
// Reject all waiting operations
|
|
150
|
+
while (this.waitingQueue.length > 0) {
|
|
151
|
+
const operation = this.waitingQueue.shift()!;
|
|
152
|
+
|
|
153
|
+
// Clear timeout if it exists
|
|
154
|
+
if (operation.timeout) {
|
|
155
|
+
clearTimeout(operation.timeout);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
operation.reject(new Error("Semaphore has been disposed"));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Get current number of available permits (for debugging)
|
|
164
|
+
*/
|
|
165
|
+
getAvailablePermits(): number {
|
|
166
|
+
return this.permits;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Get current number of waiting operations (for debugging)
|
|
171
|
+
*/
|
|
172
|
+
getWaitingCount(): number {
|
|
173
|
+
return this.waitingQueue.length;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Get maximum number of permits
|
|
178
|
+
*/
|
|
179
|
+
getMaxPermits(): number {
|
|
180
|
+
return this.maxPermits;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Check if the semaphore has been disposed
|
|
185
|
+
*/
|
|
186
|
+
isDisposed(): boolean {
|
|
187
|
+
return this.disposed;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Get metrics about the current state of the semaphore
|
|
192
|
+
*/
|
|
193
|
+
getMetrics(): {
|
|
194
|
+
availablePermits: number;
|
|
195
|
+
waitingCount: number;
|
|
196
|
+
maxPermits: number;
|
|
197
|
+
utilization: number;
|
|
198
|
+
disposed: boolean;
|
|
199
|
+
} {
|
|
200
|
+
return {
|
|
201
|
+
availablePermits: this.permits,
|
|
202
|
+
waitingCount: this.waitingQueue.length,
|
|
203
|
+
maxPermits: this.maxPermits,
|
|
204
|
+
utilization: (this.maxPermits - this.permits) / this.maxPermits,
|
|
205
|
+
disposed: this.disposed,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
}
|