@stacks/api-toolkit 1.12.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/LICENSE +202 -0
- package/README.md +74 -0
- package/bin/api-toolkit-git-info.js +25 -0
- package/dist/fastify/cache.d.ts +31 -0
- package/dist/fastify/cache.js +63 -0
- package/dist/fastify/cache.js.map +1 -0
- package/dist/fastify/fastify.d.ts +16 -0
- package/dist/fastify/fastify.js +46 -0
- package/dist/fastify/fastify.js.map +1 -0
- package/dist/fastify/index.d.ts +4 -0
- package/dist/fastify/index.js +21 -0
- package/dist/fastify/index.js.map +1 -0
- package/dist/fastify/openapi.d.ts +13 -0
- package/dist/fastify/openapi.js +23 -0
- package/dist/fastify/openapi.js.map +1 -0
- package/dist/fastify/schemas.d.ts +9 -0
- package/dist/fastify/schemas.js +16 -0
- package/dist/fastify/schemas.js.map +1 -0
- package/dist/helpers/events.d.ts +52 -0
- package/dist/helpers/events.js +93 -0
- package/dist/helpers/events.js.map +1 -0
- package/dist/helpers/index.d.ts +7 -0
- package/dist/helpers/index.js +25 -0
- package/dist/helpers/index.js.map +1 -0
- package/dist/helpers/is-debugging.d.ts +1 -0
- package/dist/helpers/is-debugging.js +15 -0
- package/dist/helpers/is-debugging.js.map +1 -0
- package/dist/helpers/iterators.d.ts +27 -0
- package/dist/helpers/iterators.js +74 -0
- package/dist/helpers/iterators.js.map +1 -0
- package/dist/helpers/serialize-error.d.ts +20 -0
- package/dist/helpers/serialize-error.js +135 -0
- package/dist/helpers/serialize-error.js.map +1 -0
- package/dist/helpers/time.d.ts +54 -0
- package/dist/helpers/time.js +121 -0
- package/dist/helpers/time.js.map +1 -0
- package/dist/helpers/values.d.ts +68 -0
- package/dist/helpers/values.js +165 -0
- package/dist/helpers/values.js.map +1 -0
- package/dist/helpers/worker-thread-init.d.ts +1 -0
- package/dist/helpers/worker-thread-init.js +67 -0
- package/dist/helpers/worker-thread-init.js.map +1 -0
- package/dist/helpers/worker-thread-manager.d.ts +53 -0
- package/dist/helpers/worker-thread-manager.js +148 -0
- package/dist/helpers/worker-thread-manager.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/logger/index.d.ts +20 -0
- package/dist/logger/index.js +14 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/postgres/base-pg-store.d.ts +68 -0
- package/dist/postgres/base-pg-store.js +109 -0
- package/dist/postgres/base-pg-store.js.map +1 -0
- package/dist/postgres/connection.d.ts +62 -0
- package/dist/postgres/connection.js +126 -0
- package/dist/postgres/connection.js.map +1 -0
- package/dist/postgres/errors.d.ts +5 -0
- package/dist/postgres/errors.js +71 -0
- package/dist/postgres/errors.js.map +1 -0
- package/dist/postgres/index.d.ts +5 -0
- package/dist/postgres/index.js +22 -0
- package/dist/postgres/index.js.map +1 -0
- package/dist/postgres/migrations.d.ts +47 -0
- package/dist/postgres/migrations.js +134 -0
- package/dist/postgres/migrations.js.map +1 -0
- package/dist/postgres/types.d.ts +14 -0
- package/dist/postgres/types.js +48 -0
- package/dist/postgres/types.js.map +1 -0
- package/dist/profiler/index.d.ts +2 -0
- package/dist/profiler/index.js +19 -0
- package/dist/profiler/index.js.map +1 -0
- package/dist/profiler/inspector-util.d.ts +29 -0
- package/dist/profiler/inspector-util.js +268 -0
- package/dist/profiler/inspector-util.js.map +1 -0
- package/dist/profiler/server.d.ts +6 -0
- package/dist/profiler/server.js +186 -0
- package/dist/profiler/server.js.map +1 -0
- package/dist/server-version/index.d.ts +8 -0
- package/dist/server-version/index.js +33 -0
- package/dist/server-version/index.js.map +1 -0
- package/dist/shutdown-handler/index.d.ts +17 -0
- package/dist/shutdown-handler/index.js +82 -0
- package/dist/shutdown-handler/index.js.map +1 -0
- package/package.json +73 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.onceWhen = onceWhen;
|
|
4
|
+
const node_events_1 = require("node:events");
|
|
5
|
+
// This is a workaround for Node.js versions that do not support Symbol.dispose
|
|
6
|
+
const DisposeSymbol = Symbol.dispose ?? Symbol.for('nodejs.dispose');
|
|
7
|
+
/**
|
|
8
|
+
* Creates a Promise that resolves when the specified `eventName` is emitted by the `EventEmitter`
|
|
9
|
+
* and the provided predicate returns `true` for the emitted arguments.
|
|
10
|
+
*
|
|
11
|
+
* Similar to [`events.once`](https://nodejs.org/api/events.html#eventsonceemitter-name-options),
|
|
12
|
+
* but includes support for a predicate function to filter events. Only events for which
|
|
13
|
+
* the predicate returns `true` will cause the Promise to resolve.
|
|
14
|
+
*
|
|
15
|
+
* The resolved value is an array of the arguments emitted with the event.
|
|
16
|
+
*
|
|
17
|
+
* Supports typed `EventEmitter`s and optional cancellation via `AbortSignal`.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* import { EventEmitter } from 'node:events';
|
|
22
|
+
*
|
|
23
|
+
* const emitter = new EventEmitter<{
|
|
24
|
+
* myEvent: [id: number, msg: string];
|
|
25
|
+
* }>();
|
|
26
|
+
*
|
|
27
|
+
* setTimeout(() => {
|
|
28
|
+
* for (let i = 0; i <= 5; i++) {
|
|
29
|
+
* emitter.emit('myEvent', i, `Message ${i}`);
|
|
30
|
+
* }
|
|
31
|
+
* }, 100);
|
|
32
|
+
*
|
|
33
|
+
* const [id, msg] = await onceWhen(emitter, 'myEvent', (id, msg) => id === 3);
|
|
34
|
+
*
|
|
35
|
+
* // outputs: "Received event with id: 3, message: Message 3"
|
|
36
|
+
* console.log(`Received event with id: ${id}, message: ${msg}`);
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* import { EventEmitter } from 'node:events';
|
|
42
|
+
*
|
|
43
|
+
* const emitter = new EventEmitter<{ myEvent: [id: number, msg: string] }>();
|
|
44
|
+
*
|
|
45
|
+
* const signal = AbortSignal.timeout(10);
|
|
46
|
+
*
|
|
47
|
+
* setTimeout(() => emitter.emit('myEvent', 1, 'Hello'), 1000);
|
|
48
|
+
*
|
|
49
|
+
* const whenPromise = onceWhen(emitter, 'myEvent', id => id === 1, { signal });
|
|
50
|
+
*
|
|
51
|
+
* // This rejects because the signal is aborted before the event is emitted
|
|
52
|
+
* await expect(whenPromise).rejects.toThrow(signal.reason);
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
function onceWhen(emitter, eventName, predicate, options) {
|
|
56
|
+
return new Promise((resolve, reject) => {
|
|
57
|
+
// Immediate abort check
|
|
58
|
+
if (options?.signal?.aborted) {
|
|
59
|
+
reject(options.signal.reason ?? new Error('Aborted'));
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
// Cleanup helper: remove both the event listener and the abort listener
|
|
63
|
+
const cleanup = () => {
|
|
64
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
65
|
+
emitter.off(eventName, listener);
|
|
66
|
+
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
67
|
+
disposable?.[DisposeSymbol]();
|
|
68
|
+
};
|
|
69
|
+
// Abort handler
|
|
70
|
+
const onAbort = () => {
|
|
71
|
+
cleanup();
|
|
72
|
+
reject(options?.signal?.reason ?? new Error('Aborted'));
|
|
73
|
+
};
|
|
74
|
+
// Our event listener that checks the predicate
|
|
75
|
+
const listener = (...args) => {
|
|
76
|
+
try {
|
|
77
|
+
if (predicate(...args)) {
|
|
78
|
+
cleanup();
|
|
79
|
+
resolve(args);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
cleanup();
|
|
84
|
+
reject(err);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
// Install the AbortSignal listener via Node’s helper
|
|
89
|
+
const disposable = options?.signal ? (0, node_events_1.addAbortListener)(options.signal, onAbort) : undefined;
|
|
90
|
+
emitter.on(eventName, listener);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/helpers/events.ts"],"names":[],"mappings":";;AAqDA,4BAiDC;AAtGD,6CAA6D;AAE7D,+EAA+E;AAC/E,MAAM,aAAa,GAA0B,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;AAE5F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,SAAgB,QAAQ,CAItB,OAA+B,EAC/B,SAAY,EACZ,SAA4C,EAC5C,OAAkC;IAElC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,wBAAwB;QACxB,IAAI,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;YAC7B,MAAM,CAAE,OAAO,CAAC,MAAM,CAAC,MAAgB,IAAI,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;YACjE,OAAO;QACT,CAAC;QAED,wEAAwE;QACxE,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,mEAAmE;YAClE,OAAwB,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YACnD,mEAAmE;YACnE,UAAU,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC;QAChC,CAAC,CAAC;QAEF,gBAAgB;QAChB,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,OAAO,EAAE,CAAC;YACV,MAAM,CAAE,OAAO,EAAE,MAAM,EAAE,MAAgB,IAAI,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;QACrE,CAAC,CAAC;QAEF,+CAA+C;QAC/C,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAiB,EAAE,EAAE;YACxC,IAAI,CAAC;gBACH,IAAI,SAAS,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;oBACvB,OAAO,EAAE,CAAC;oBACV,OAAO,CAAC,IAAI,CAAC,CAAC;gBAChB,CAAC;YACH,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,EAAE,CAAC;gBACV,MAAM,CAAC,GAAY,CAAC,CAAC;gBACrB,OAAO;YACT,CAAC;QACH,CAAC,CAAC;QAEF,qDAAqD;QACrD,MAAM,UAAU,GAAG,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,IAAA,8BAAgB,EAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAE1F,OAAwB,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from './iterators';
|
|
2
|
+
export * from './time';
|
|
3
|
+
export * from './values';
|
|
4
|
+
export * from './is-debugging';
|
|
5
|
+
export * from './events';
|
|
6
|
+
export { WorkerThreadManager } from './worker-thread-manager';
|
|
7
|
+
export type { WorkerPoolModuleInterface } from './worker-thread-manager';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.WorkerThreadManager = void 0;
|
|
18
|
+
__exportStar(require("./iterators"), exports);
|
|
19
|
+
__exportStar(require("./time"), exports);
|
|
20
|
+
__exportStar(require("./values"), exports);
|
|
21
|
+
__exportStar(require("./is-debugging"), exports);
|
|
22
|
+
__exportStar(require("./events"), exports);
|
|
23
|
+
var worker_thread_manager_1 = require("./worker-thread-manager");
|
|
24
|
+
Object.defineProperty(exports, "WorkerThreadManager", { enumerable: true, get: function () { return worker_thread_manager_1.WorkerThreadManager; } });
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/helpers/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,8CAA4B;AAC5B,yCAAuB;AACvB,2CAAyB;AACzB,iDAA+B;AAC/B,2CAAyB;AACzB,iEAA8D;AAArD,4HAAA,mBAAmB,OAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function isDebugging(): boolean;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isDebugging = isDebugging;
|
|
4
|
+
/*
|
|
5
|
+
* Reliable way to check if we are debugging. Supports ts-node and other tools unlike some other
|
|
6
|
+
* approaches that check argv or env vars. It also lazy-loads the `node:inspector` module to avoid
|
|
7
|
+
* unnecessary overhead in production environments where this function might not be called.
|
|
8
|
+
*/
|
|
9
|
+
function isDebugging() {
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
11
|
+
const inspector = require('node:inspector');
|
|
12
|
+
const url = inspector.url();
|
|
13
|
+
return url !== undefined;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=is-debugging.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is-debugging.js","sourceRoot":"","sources":["../../src/helpers/is-debugging.ts"],"names":[],"mappings":";;AAKA,kCAMC;AAXD;;;;GAIG;AACH,SAAgB,WAAW;IAEzB,8DAA8D;IAC9D,MAAM,SAAS,GAAG,OAAO,CAAC,gBAAgB,CAAsB,CAAC;IACjE,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,EAAE,CAAC;IAC5B,OAAO,GAAG,KAAK,SAAS,CAAC;AAC3B,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Iterate over an array, yielding multiple items at a time. If the size of the given array
|
|
3
|
+
* is not divisible by the given batch size, then the length of the last items returned will
|
|
4
|
+
* be smaller than the given batch size, i.e.:
|
|
5
|
+
* ```typescript
|
|
6
|
+
* items.length % batchSize
|
|
7
|
+
* ```
|
|
8
|
+
* @param items - The array to iterate over.
|
|
9
|
+
* @param batchSize - Maximum number of items to return at a time.
|
|
10
|
+
* @param printBenchmark - If we should print benchmark of items per second
|
|
11
|
+
*/
|
|
12
|
+
export declare function batchIterate<T>(items: T[], batchSize: number, printBenchmark?: boolean): Generator<T[]>;
|
|
13
|
+
/**
|
|
14
|
+
* Iterate over an `AsyncIterable`, yielding multiple items at a time. If the size of the given
|
|
15
|
+
* array is not divisible by the given batch size, then the length of the last items returned will
|
|
16
|
+
* be smaller than the given batch size.
|
|
17
|
+
*
|
|
18
|
+
* @param items - AsyncIterable
|
|
19
|
+
* @param batchSize - Batch size
|
|
20
|
+
* @param printBenchmark - If we should print benchmark of items per second
|
|
21
|
+
*/
|
|
22
|
+
export declare function asyncBatchIterate<T>(items: AsyncIterable<T>, batchSize: number, printBenchmark?: boolean): AsyncGenerator<T[], void, unknown>;
|
|
23
|
+
/**
|
|
24
|
+
* Convert an `AsyncIterable` to a generator
|
|
25
|
+
* @param iter - AsyncIterable
|
|
26
|
+
*/
|
|
27
|
+
export declare function asyncIterableToGenerator<T>(iter: AsyncIterable<T>): AsyncGenerator<Awaited<T>, void, unknown>;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.batchIterate = batchIterate;
|
|
4
|
+
exports.asyncBatchIterate = asyncBatchIterate;
|
|
5
|
+
exports.asyncIterableToGenerator = asyncIterableToGenerator;
|
|
6
|
+
const logger_1 = require("../logger");
|
|
7
|
+
const values_1 = require("./values");
|
|
8
|
+
/**
|
|
9
|
+
* Iterate over an array, yielding multiple items at a time. If the size of the given array
|
|
10
|
+
* is not divisible by the given batch size, then the length of the last items returned will
|
|
11
|
+
* be smaller than the given batch size, i.e.:
|
|
12
|
+
* ```typescript
|
|
13
|
+
* items.length % batchSize
|
|
14
|
+
* ```
|
|
15
|
+
* @param items - The array to iterate over.
|
|
16
|
+
* @param batchSize - Maximum number of items to return at a time.
|
|
17
|
+
* @param printBenchmark - If we should print benchmark of items per second
|
|
18
|
+
*/
|
|
19
|
+
function* batchIterate(items, batchSize, printBenchmark = values_1.isDevEnv) {
|
|
20
|
+
if (items.length === 0)
|
|
21
|
+
return;
|
|
22
|
+
const startTime = Date.now();
|
|
23
|
+
for (let i = 0; i < items.length;) {
|
|
24
|
+
const itemsRemaining = items.length - i;
|
|
25
|
+
const sliceSize = Math.min(batchSize, itemsRemaining);
|
|
26
|
+
yield items.slice(i, i + sliceSize);
|
|
27
|
+
i += sliceSize;
|
|
28
|
+
}
|
|
29
|
+
if (printBenchmark) {
|
|
30
|
+
const itemsPerSecond = Math.round((items.length / (Date.now() - startTime)) * 1000);
|
|
31
|
+
const caller = new Error().stack?.split('at ')[3].trim();
|
|
32
|
+
logger_1.logger.debug(`Iterated ${itemsPerSecond} items/second at ${caller}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Iterate over an `AsyncIterable`, yielding multiple items at a time. If the size of the given
|
|
37
|
+
* array is not divisible by the given batch size, then the length of the last items returned will
|
|
38
|
+
* be smaller than the given batch size.
|
|
39
|
+
*
|
|
40
|
+
* @param items - AsyncIterable
|
|
41
|
+
* @param batchSize - Batch size
|
|
42
|
+
* @param printBenchmark - If we should print benchmark of items per second
|
|
43
|
+
*/
|
|
44
|
+
async function* asyncBatchIterate(items, batchSize, printBenchmark = values_1.isDevEnv) {
|
|
45
|
+
const startTime = Date.now();
|
|
46
|
+
let itemCount = 0;
|
|
47
|
+
let itemBatch = [];
|
|
48
|
+
for await (const item of items) {
|
|
49
|
+
itemBatch.push(item);
|
|
50
|
+
itemCount++;
|
|
51
|
+
if (itemBatch.length >= batchSize) {
|
|
52
|
+
yield itemBatch;
|
|
53
|
+
itemBatch = [];
|
|
54
|
+
if (printBenchmark) {
|
|
55
|
+
const itemsPerSecond = Math.round((itemCount / (Date.now() - startTime)) * 1000);
|
|
56
|
+
const caller = new Error().stack?.split('at ')[3].trim();
|
|
57
|
+
logger_1.logger.debug(`Iterated ${itemsPerSecond} items/second at ${caller}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (itemBatch.length > 0) {
|
|
62
|
+
yield itemBatch;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Convert an `AsyncIterable` to a generator
|
|
67
|
+
* @param iter - AsyncIterable
|
|
68
|
+
*/
|
|
69
|
+
async function* asyncIterableToGenerator(iter) {
|
|
70
|
+
for await (const entry of iter) {
|
|
71
|
+
yield entry;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=iterators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iterators.js","sourceRoot":"","sources":["../../src/helpers/iterators.ts"],"names":[],"mappings":";;AAcA,oCAkBC;AAWD,8CAwBC;AAMD,4DAIC;AA7ED,sCAAmC;AACnC,qCAAoC;AAEpC;;;;;;;;;;GAUG;AACH,QAAe,CAAC,CAAC,YAAY,CAC3B,KAAU,EACV,SAAiB,EACjB,cAAc,GAAG,iBAAQ;IAEzB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,GAAI,CAAC;QACnC,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;QACxC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QACtD,MAAM,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC;QACpC,CAAC,IAAI,SAAS,CAAC;IACjB,CAAC;IACD,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QACpF,MAAM,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACzD,eAAM,CAAC,KAAK,CAAC,YAAY,cAAc,oBAAoB,MAAM,EAAE,CAAC,CAAC;IACvE,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACI,KAAK,SAAS,CAAC,CAAC,iBAAiB,CACtC,KAAuB,EACvB,SAAiB,EACjB,cAAc,GAAG,iBAAQ;IAEzB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,SAAS,GAAQ,EAAE,CAAC;IACxB,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC/B,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,SAAS,EAAE,CAAC;QACZ,IAAI,SAAS,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC;YAClC,MAAM,SAAS,CAAC;YAChB,SAAS,GAAG,EAAE,CAAC;YACf,IAAI,cAAc,EAAE,CAAC;gBACnB,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;gBACjF,MAAM,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBACzD,eAAM,CAAC,KAAK,CAAC,YAAY,cAAc,oBAAoB,MAAM,EAAE,CAAC,CAAC;YACvE,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,SAAS,CAAC;IAClB,CAAC;AACH,CAAC;AAED;;;GAGG;AACI,KAAK,SAAS,CAAC,CAAC,wBAAwB,CAAI,IAAsB;IACvE,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;QAC/B,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom errors can only be deserialized correctly if they are registered here.
|
|
3
|
+
*/
|
|
4
|
+
export declare function addKnownErrorConstructor(constructor: new (message?: string, ..._arguments: unknown[]) => Error): void;
|
|
5
|
+
type SerializedError = {
|
|
6
|
+
constructorName: string;
|
|
7
|
+
name: string;
|
|
8
|
+
message: string;
|
|
9
|
+
stack: string;
|
|
10
|
+
[key: string]: any;
|
|
11
|
+
};
|
|
12
|
+
export type ErrorLike = {
|
|
13
|
+
name: string;
|
|
14
|
+
message: string;
|
|
15
|
+
stack: string;
|
|
16
|
+
};
|
|
17
|
+
export declare function isErrorLike(value: unknown): value is ErrorLike;
|
|
18
|
+
export declare function serializeError(subject: Error): SerializedError;
|
|
19
|
+
export declare function deserializeError(subject: ErrorLike): Error;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
3
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
4
|
+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.addKnownErrorConstructor = addKnownErrorConstructor;
|
|
7
|
+
exports.isErrorLike = isErrorLike;
|
|
8
|
+
exports.serializeError = serializeError;
|
|
9
|
+
exports.deserializeError = deserializeError;
|
|
10
|
+
const errorConstructors = new Map([
|
|
11
|
+
// Native ES errors https://262.ecma-international.org/12.0/#sec-well-known-intrinsic-objects
|
|
12
|
+
Error,
|
|
13
|
+
EvalError,
|
|
14
|
+
RangeError,
|
|
15
|
+
ReferenceError,
|
|
16
|
+
SyntaxError,
|
|
17
|
+
TypeError,
|
|
18
|
+
URIError,
|
|
19
|
+
AggregateError,
|
|
20
|
+
// Built-in errors
|
|
21
|
+
globalThis.DOMException,
|
|
22
|
+
// Node-specific errors https://nodejs.org/api/errors.html
|
|
23
|
+
globalThis.AssertionError,
|
|
24
|
+
globalThis.SystemError,
|
|
25
|
+
]
|
|
26
|
+
// Non-native Errors are used with `globalThis` because they might be missing. This filter drops them when undefined.
|
|
27
|
+
.filter(Boolean)
|
|
28
|
+
.map(constructor => [constructor.name, constructor]));
|
|
29
|
+
/**
|
|
30
|
+
* Custom errors can only be deserialized correctly if they are registered here.
|
|
31
|
+
*/
|
|
32
|
+
function addKnownErrorConstructor(constructor) {
|
|
33
|
+
try {
|
|
34
|
+
new constructor();
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
throw new Error(`The error constructor "${constructor.name}" is not compatible`, {
|
|
38
|
+
cause: error,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
errorConstructors.set(constructor.name, constructor);
|
|
42
|
+
}
|
|
43
|
+
const commonProperties = {
|
|
44
|
+
name: false,
|
|
45
|
+
message: false,
|
|
46
|
+
stack: false,
|
|
47
|
+
code: true,
|
|
48
|
+
cause: false,
|
|
49
|
+
errors: false,
|
|
50
|
+
};
|
|
51
|
+
function isErrorLike(value) {
|
|
52
|
+
return (typeof value === 'object' &&
|
|
53
|
+
value !== null &&
|
|
54
|
+
'name' in value &&
|
|
55
|
+
'message' in value &&
|
|
56
|
+
'stack' in value &&
|
|
57
|
+
typeof value.name === 'string' &&
|
|
58
|
+
typeof value.message === 'string' &&
|
|
59
|
+
typeof value.stack === 'string');
|
|
60
|
+
}
|
|
61
|
+
function serializeError(subject) {
|
|
62
|
+
if (!isErrorLike(subject)) {
|
|
63
|
+
// If the subject is not an error, for example `throw "boom", then we throw.
|
|
64
|
+
// This function should only be passed error objects, callers can use `isErrorLike`.
|
|
65
|
+
throw new TypeError('Failed to serialize error, expected an error object');
|
|
66
|
+
}
|
|
67
|
+
const data = {
|
|
68
|
+
constructorName: subject.constructor.name ?? 'Error', // new field
|
|
69
|
+
name: subject.name,
|
|
70
|
+
message: '',
|
|
71
|
+
stack: '',
|
|
72
|
+
};
|
|
73
|
+
for (const key of Object.keys(commonProperties)) {
|
|
74
|
+
if (key in subject)
|
|
75
|
+
data[key] = deepSerialize(subject[key]);
|
|
76
|
+
}
|
|
77
|
+
// Include any other enumerable own properties
|
|
78
|
+
for (const key of Object.keys(subject)) {
|
|
79
|
+
if (!(key in data))
|
|
80
|
+
data[key] = deepSerialize(subject[key]);
|
|
81
|
+
}
|
|
82
|
+
return data;
|
|
83
|
+
}
|
|
84
|
+
function deserializeError(subject) {
|
|
85
|
+
if (!isErrorLike(subject)) {
|
|
86
|
+
// If the subject is not an error, for example `throw "boom", then we throw.
|
|
87
|
+
// This function should only be passed error objects, callers can use `isErrorLike`.
|
|
88
|
+
throw new TypeError('Failed to desserialize error, expected an error object');
|
|
89
|
+
}
|
|
90
|
+
let con = errorConstructors.get(subject.constructorName ?? subject.name);
|
|
91
|
+
if (!con) {
|
|
92
|
+
// If the constructor is not found, use the generic Error constructor
|
|
93
|
+
con = Error;
|
|
94
|
+
console.error(`Error constructor "${subject.name}" not found during worker error deserialization, using generic Error constructor`);
|
|
95
|
+
}
|
|
96
|
+
const output = Object.create(con.prototype);
|
|
97
|
+
for (const [key, enumerable] of Object.entries(commonProperties)) {
|
|
98
|
+
if (key in subject) {
|
|
99
|
+
Object.defineProperty(output, key, {
|
|
100
|
+
enumerable,
|
|
101
|
+
configurable: true,
|
|
102
|
+
writable: true,
|
|
103
|
+
value: deepDeserialize(subject[key]),
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// Add any other properties (custom props not in commonProperties)
|
|
108
|
+
for (const key of Object.keys(subject)) {
|
|
109
|
+
if (!(key in commonProperties)) {
|
|
110
|
+
output[key] = deepDeserialize(subject[key]);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return output;
|
|
114
|
+
}
|
|
115
|
+
function deepSerialize(value) {
|
|
116
|
+
if (Array.isArray(value))
|
|
117
|
+
return value.map(deepSerialize);
|
|
118
|
+
if (isErrorLike(value))
|
|
119
|
+
return serializeError(value);
|
|
120
|
+
if (value && typeof value === 'object') {
|
|
121
|
+
return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, deepSerialize(v)]));
|
|
122
|
+
}
|
|
123
|
+
return value;
|
|
124
|
+
}
|
|
125
|
+
function deepDeserialize(value) {
|
|
126
|
+
if (Array.isArray(value))
|
|
127
|
+
return value.map(deepDeserialize);
|
|
128
|
+
if (isErrorLike(value))
|
|
129
|
+
return deserializeError(value);
|
|
130
|
+
if (value && typeof value === 'object') {
|
|
131
|
+
return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, deepDeserialize(v)]));
|
|
132
|
+
}
|
|
133
|
+
return value;
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=serialize-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialize-error.js","sourceRoot":"","sources":["../../src/helpers/serialize-error.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wait a set amount of milliseconds or until the timer is aborted.
|
|
3
|
+
* @param ms - Number of milliseconds to wait
|
|
4
|
+
* @param abort - Abort controller
|
|
5
|
+
* @returns Promise
|
|
6
|
+
*/
|
|
7
|
+
export declare function timeout(ms: number, abort?: AbortController | AbortSignal): Promise<void>;
|
|
8
|
+
/**
|
|
9
|
+
* Time the execution of an async function.
|
|
10
|
+
* @param fn - Async function
|
|
11
|
+
* @param onFinish - Callback with elapsed milliseconds
|
|
12
|
+
* @returns Promise
|
|
13
|
+
*/
|
|
14
|
+
export declare function time<T>(fn: () => Promise<T>, onFinish: (elapsedMs: number) => void): Promise<T>;
|
|
15
|
+
/**
|
|
16
|
+
* Set an execution time limit for a promise.
|
|
17
|
+
* @param promise - The promise being capped to `timeoutMs` max execution time
|
|
18
|
+
* @param timeoutMs - Timeout limit in milliseconds
|
|
19
|
+
* @param wait - If we should wait another `timeoutMs` period for `promise` to resolve
|
|
20
|
+
* @param waitHandler - If `wait` is `true`, this closure will be executed before waiting another
|
|
21
|
+
* `timeoutMs` cycle
|
|
22
|
+
* @returns `true` if `promise` ended gracefully, `false` if timeout was reached
|
|
23
|
+
*/
|
|
24
|
+
export declare function resolveOrTimeout(promise: Promise<void>, timeoutMs: number, wait?: boolean, waitHandler?: () => void): Promise<unknown>;
|
|
25
|
+
export interface Stopwatch {
|
|
26
|
+
/** Milliseconds since stopwatch was created. */
|
|
27
|
+
getElapsed: () => number;
|
|
28
|
+
/** Seconds since stopwatch was created. */
|
|
29
|
+
getElapsedSeconds: () => number;
|
|
30
|
+
getElapsedAndRestart: () => number;
|
|
31
|
+
restart(): void;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Start a `Stopwatch` that measures elapsed time based on `process.hrtime`.
|
|
35
|
+
* @returns Stopwatch
|
|
36
|
+
*/
|
|
37
|
+
export declare function stopwatch(): Stopwatch;
|
|
38
|
+
export type Waiter<T = void, E = Error> = Promise<T> & {
|
|
39
|
+
/** Alias for `resolve` */
|
|
40
|
+
finish: (result: T) => void;
|
|
41
|
+
resolve: (result: T) => void;
|
|
42
|
+
reject: (error: E) => void;
|
|
43
|
+
/** True if the promise is resolved or rejected */
|
|
44
|
+
isFinished: boolean;
|
|
45
|
+
/** True only if the promise is resolved */
|
|
46
|
+
isResolved: boolean;
|
|
47
|
+
/** True only if the promise is rejected */
|
|
48
|
+
isRejected: boolean;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Creates a `Waiter` promise that can be resolved or rejected at a later time.
|
|
52
|
+
* @returns Waiter
|
|
53
|
+
*/
|
|
54
|
+
export declare function waiter<T = void, E = Error>(): Waiter<T, E>;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.timeout = timeout;
|
|
4
|
+
exports.time = time;
|
|
5
|
+
exports.resolveOrTimeout = resolveOrTimeout;
|
|
6
|
+
exports.stopwatch = stopwatch;
|
|
7
|
+
exports.waiter = waiter;
|
|
8
|
+
const promises_1 = require("node:timers/promises");
|
|
9
|
+
/**
|
|
10
|
+
* Wait a set amount of milliseconds or until the timer is aborted.
|
|
11
|
+
* @param ms - Number of milliseconds to wait
|
|
12
|
+
* @param abort - Abort controller
|
|
13
|
+
* @returns Promise
|
|
14
|
+
*/
|
|
15
|
+
function timeout(ms, abort) {
|
|
16
|
+
const signal = abort && (abort instanceof AbortSignal ? abort : abort.signal);
|
|
17
|
+
return (0, promises_1.setTimeout)(ms, undefined, { signal });
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Time the execution of an async function.
|
|
21
|
+
* @param fn - Async function
|
|
22
|
+
* @param onFinish - Callback with elapsed milliseconds
|
|
23
|
+
* @returns Promise
|
|
24
|
+
*/
|
|
25
|
+
async function time(fn, onFinish) {
|
|
26
|
+
const watch = stopwatch();
|
|
27
|
+
try {
|
|
28
|
+
return await fn();
|
|
29
|
+
}
|
|
30
|
+
finally {
|
|
31
|
+
onFinish(watch.getElapsed());
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Set an execution time limit for a promise.
|
|
36
|
+
* @param promise - The promise being capped to `timeoutMs` max execution time
|
|
37
|
+
* @param timeoutMs - Timeout limit in milliseconds
|
|
38
|
+
* @param wait - If we should wait another `timeoutMs` period for `promise` to resolve
|
|
39
|
+
* @param waitHandler - If `wait` is `true`, this closure will be executed before waiting another
|
|
40
|
+
* `timeoutMs` cycle
|
|
41
|
+
* @returns `true` if `promise` ended gracefully, `false` if timeout was reached
|
|
42
|
+
*/
|
|
43
|
+
async function resolveOrTimeout(promise, timeoutMs, wait = false, waitHandler) {
|
|
44
|
+
let timer;
|
|
45
|
+
const result = await Promise.race([
|
|
46
|
+
new Promise((resolve, reject) => {
|
|
47
|
+
promise
|
|
48
|
+
.then(() => resolve(true))
|
|
49
|
+
.catch(error => reject(error))
|
|
50
|
+
.finally(() => clearTimeout(timer));
|
|
51
|
+
}),
|
|
52
|
+
new Promise((resolve, _) => {
|
|
53
|
+
timer = setInterval(() => {
|
|
54
|
+
if (!wait) {
|
|
55
|
+
clearTimeout(timer);
|
|
56
|
+
resolve(false);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (waitHandler) {
|
|
60
|
+
waitHandler();
|
|
61
|
+
}
|
|
62
|
+
}, timeoutMs);
|
|
63
|
+
}),
|
|
64
|
+
]);
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Start a `Stopwatch` that measures elapsed time based on `process.hrtime`.
|
|
69
|
+
* @returns Stopwatch
|
|
70
|
+
*/
|
|
71
|
+
function stopwatch() {
|
|
72
|
+
let start = process.hrtime.bigint();
|
|
73
|
+
const result = {
|
|
74
|
+
getElapsedSeconds: () => {
|
|
75
|
+
const elapsedMs = result.getElapsed();
|
|
76
|
+
return elapsedMs / 1000;
|
|
77
|
+
},
|
|
78
|
+
getElapsed: () => {
|
|
79
|
+
const end = process.hrtime.bigint();
|
|
80
|
+
return Number((end - start) / 1000000n);
|
|
81
|
+
},
|
|
82
|
+
getElapsedAndRestart: () => {
|
|
83
|
+
const end = process.hrtime.bigint();
|
|
84
|
+
const result = Number((end - start) / 1000000n);
|
|
85
|
+
start = process.hrtime.bigint();
|
|
86
|
+
return result;
|
|
87
|
+
},
|
|
88
|
+
restart: () => {
|
|
89
|
+
start = process.hrtime.bigint();
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
return result;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Creates a `Waiter` promise that can be resolved or rejected at a later time.
|
|
96
|
+
* @returns Waiter
|
|
97
|
+
*/
|
|
98
|
+
function waiter() {
|
|
99
|
+
let resolveFn;
|
|
100
|
+
let rejectFn;
|
|
101
|
+
const promise = new Promise((resolve, reject) => {
|
|
102
|
+
resolveFn = resolve;
|
|
103
|
+
rejectFn = reject;
|
|
104
|
+
});
|
|
105
|
+
const completer = {
|
|
106
|
+
finish: (result) => completer.resolve(result),
|
|
107
|
+
resolve: (result) => {
|
|
108
|
+
void Object.assign(promise, { isFinished: true, isResolved: true });
|
|
109
|
+
resolveFn(result);
|
|
110
|
+
},
|
|
111
|
+
reject: (error) => {
|
|
112
|
+
void Object.assign(promise, { isFinished: true, isRejected: true });
|
|
113
|
+
rejectFn(error);
|
|
114
|
+
},
|
|
115
|
+
isFinished: false,
|
|
116
|
+
isResolved: false,
|
|
117
|
+
isRejected: false,
|
|
118
|
+
};
|
|
119
|
+
return Object.assign(promise, completer);
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=time.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"time.js","sourceRoot":"","sources":["../../src/helpers/time.ts"],"names":[],"mappings":"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"}
|