@xylabs/threads 4.4.35 → 4.5.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/dist/enum.d.ts +5 -0
- package/dist/enum.js +7 -0
- package/dist/esm/enum.js +7 -0
- package/dist/esm/master/pool-types.js +11 -11
- package/dist/esm/master/pool.js +6 -4
- package/dist/esm/types/master.js +6 -6
- package/dist/esm/types/messages.js +12 -13
- package/dist/master/pool-types.d.ts +21 -18
- package/dist/master/pool-types.js +11 -11
- package/dist/master/pool.d.ts +10 -1
- package/dist/master/pool.js +6 -4
- package/dist/types/master.d.ts +13 -11
- package/dist/types/master.js +6 -6
- package/dist/types/messages.d.ts +22 -18
- package/dist/types/messages.js +12 -13
- package/package.json +6 -7
- package/src/enum.ts +87 -0
- package/src/master/pool-types.ts +22 -18
- package/src/master/pool.ts +7 -5
- package/src/types/master.ts +14 -12
- package/src/types/messages.ts +26 -18
- package/dist/esm/ponyfills.js +0 -20
- package/dist/ponyfills.d.ts +0 -8
- package/dist/ponyfills.js +0 -20
- package/src/ponyfills.ts +0 -31
package/dist/enum.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const Enum: <const T extends Record<string | number | symbol, unknown>>(obj: Readonly<T>) => Enum<T>;
|
|
2
|
+
export type Enum<T extends Readonly<Record<string | number | symbol, unknown>>> = {
|
|
3
|
+
readonly [K in keyof T]: T[K];
|
|
4
|
+
};
|
|
5
|
+
export type EnumValue<T extends Record<string | number | symbol, unknown>, K = Enum<T>> = K[keyof K];
|
package/dist/enum.js
ADDED
package/dist/esm/enum.js
ADDED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PoolEventType = void 0;
|
|
4
|
-
|
|
5
|
-
(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
})
|
|
4
|
+
const enum_1 = require("../enum");
|
|
5
|
+
exports.PoolEventType = (0, enum_1.Enum)({
|
|
6
|
+
initialized: 'initialized',
|
|
7
|
+
taskCanceled: 'taskCanceled',
|
|
8
|
+
taskCompleted: 'taskCompleted',
|
|
9
|
+
taskFailed: 'taskFailed',
|
|
10
|
+
taskQueued: 'taskQueued',
|
|
11
|
+
taskQueueDrained: 'taskQueueDrained',
|
|
12
|
+
taskStart: 'taskStart',
|
|
13
|
+
terminated: 'terminated',
|
|
14
|
+
});
|
package/dist/esm/master/pool.js
CHANGED
|
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.Thread = exports.PoolEventType = exports.Pool = void 0;
|
|
7
7
|
const debug_1 = __importDefault(require("debug"));
|
|
8
8
|
const observable_fns_1 = require("observable-fns");
|
|
9
|
-
const ponyfills_1 = require("../ponyfills");
|
|
10
9
|
const implementation_1 = require("./implementation");
|
|
11
10
|
const pool_types_1 = require("./pool-types");
|
|
12
11
|
const thread_1 = require("./thread");
|
|
@@ -121,7 +120,10 @@ class WorkerPool {
|
|
|
121
120
|
this.eventSubject.next({ type: pool_types_1.PoolEventType.taskQueueDrained });
|
|
122
121
|
return;
|
|
123
122
|
}
|
|
124
|
-
this.run(availableWorker, nextTask)
|
|
123
|
+
this.run(availableWorker, nextTask).catch((error) => {
|
|
124
|
+
this.debug('Error while running task:', error);
|
|
125
|
+
this.eventSubject.error(error);
|
|
126
|
+
});
|
|
125
127
|
}
|
|
126
128
|
taskCompletion(taskID) {
|
|
127
129
|
return new Promise((resolve, reject) => {
|
|
@@ -153,7 +155,7 @@ class WorkerPool {
|
|
|
153
155
|
throw this.initErrors[0];
|
|
154
156
|
}
|
|
155
157
|
if (allowResolvingImmediately && this.taskQueue.length === 0) {
|
|
156
|
-
await
|
|
158
|
+
await Promise.allSettled(getCurrentlyRunningTasks());
|
|
157
159
|
return taskFailures;
|
|
158
160
|
}
|
|
159
161
|
await new Promise((resolve, reject) => {
|
|
@@ -167,7 +169,7 @@ class WorkerPool {
|
|
|
167
169
|
},
|
|
168
170
|
});
|
|
169
171
|
});
|
|
170
|
-
await
|
|
172
|
+
await Promise.allSettled(getCurrentlyRunningTasks());
|
|
171
173
|
failureSubscription.unsubscribe();
|
|
172
174
|
return taskFailures;
|
|
173
175
|
}
|
package/dist/esm/types/master.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.WorkerEventType = void 0;
|
|
4
|
-
|
|
5
|
-
(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
})
|
|
4
|
+
const enum_1 = require("../enum");
|
|
5
|
+
exports.WorkerEventType = (0, enum_1.Enum)({
|
|
6
|
+
internalError: 'internalError',
|
|
7
|
+
message: 'message',
|
|
8
|
+
termination: 'termination',
|
|
9
|
+
});
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.WorkerMessageType = exports.MasterMessageType = void 0;
|
|
4
|
-
|
|
5
|
-
(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
})
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
})(WorkerMessageType || (exports.WorkerMessageType = WorkerMessageType = {}));
|
|
4
|
+
const enum_1 = require("../enum");
|
|
5
|
+
exports.MasterMessageType = (0, enum_1.Enum)({
|
|
6
|
+
cancel: 'cancel',
|
|
7
|
+
run: 'run',
|
|
8
|
+
});
|
|
9
|
+
exports.WorkerMessageType = (0, enum_1.Enum)({
|
|
10
|
+
error: 'error',
|
|
11
|
+
init: 'init',
|
|
12
|
+
result: 'result',
|
|
13
|
+
running: 'running',
|
|
14
|
+
uncaughtError: 'uncaughtError',
|
|
15
|
+
});
|
|
@@ -1,42 +1,45 @@
|
|
|
1
|
+
import type { EnumValue } from '../enum';
|
|
2
|
+
import { Enum } from '../enum';
|
|
1
3
|
import type { Thread } from './thread';
|
|
2
|
-
export declare
|
|
3
|
-
initialized
|
|
4
|
-
taskCanceled
|
|
5
|
-
taskCompleted
|
|
6
|
-
taskFailed
|
|
7
|
-
taskQueued
|
|
8
|
-
taskQueueDrained
|
|
9
|
-
taskStart
|
|
10
|
-
terminated
|
|
11
|
-
}
|
|
4
|
+
export declare const PoolEventType: Enum<{
|
|
5
|
+
initialized: "initialized";
|
|
6
|
+
taskCanceled: "taskCanceled";
|
|
7
|
+
taskCompleted: "taskCompleted";
|
|
8
|
+
taskFailed: "taskFailed";
|
|
9
|
+
taskQueued: "taskQueued";
|
|
10
|
+
taskQueueDrained: "taskQueueDrained";
|
|
11
|
+
taskStart: "taskStart";
|
|
12
|
+
terminated: "terminated";
|
|
13
|
+
}>;
|
|
14
|
+
export type PoolEventType = EnumValue<typeof PoolEventType>;
|
|
12
15
|
export type TaskRunFunction<ThreadType extends Thread, Return> = (worker: ThreadType) => Promise<Return>;
|
|
13
16
|
export type PoolEvent<ThreadType extends Thread> = {
|
|
14
|
-
type:
|
|
17
|
+
type: 'initialized';
|
|
15
18
|
size: number;
|
|
16
19
|
} | {
|
|
17
|
-
type:
|
|
20
|
+
type: 'taskQueued';
|
|
18
21
|
taskID: number;
|
|
19
22
|
} | {
|
|
20
|
-
type:
|
|
23
|
+
type: 'taskQueueDrained';
|
|
21
24
|
} | {
|
|
22
|
-
type:
|
|
25
|
+
type: 'taskStart';
|
|
23
26
|
taskID: number;
|
|
24
27
|
workerID: number;
|
|
25
28
|
} | {
|
|
26
|
-
type:
|
|
29
|
+
type: 'taskCompleted';
|
|
27
30
|
returnValue: any;
|
|
28
31
|
taskID: number;
|
|
29
32
|
workerID: number;
|
|
30
33
|
} | {
|
|
31
|
-
type:
|
|
34
|
+
type: 'taskFailed';
|
|
32
35
|
error: Error;
|
|
33
36
|
taskID: number;
|
|
34
37
|
workerID: number;
|
|
35
38
|
} | {
|
|
36
|
-
type:
|
|
39
|
+
type: 'taskCanceled';
|
|
37
40
|
taskID: number;
|
|
38
41
|
} | {
|
|
39
|
-
type:
|
|
42
|
+
type: 'terminated';
|
|
40
43
|
remainingQueue: Array<QueuedTask<ThreadType, any>>;
|
|
41
44
|
};
|
|
42
45
|
export interface WorkerDescriptor<ThreadType extends Thread> {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PoolEventType = void 0;
|
|
4
|
-
|
|
5
|
-
(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
})
|
|
4
|
+
const enum_1 = require("../enum");
|
|
5
|
+
exports.PoolEventType = (0, enum_1.Enum)({
|
|
6
|
+
initialized: 'initialized',
|
|
7
|
+
taskCanceled: 'taskCanceled',
|
|
8
|
+
taskCompleted: 'taskCompleted',
|
|
9
|
+
taskFailed: 'taskFailed',
|
|
10
|
+
taskQueued: 'taskQueued',
|
|
11
|
+
taskQueueDrained: 'taskQueueDrained',
|
|
12
|
+
taskStart: 'taskStart',
|
|
13
|
+
terminated: 'terminated',
|
|
14
|
+
});
|
package/dist/master/pool.d.ts
CHANGED
|
@@ -20,7 +20,16 @@ interface PoolOptions {
|
|
|
20
20
|
size?: number;
|
|
21
21
|
}
|
|
22
22
|
declare class WorkerPool<ThreadType extends Thread> implements Pool<ThreadType> {
|
|
23
|
-
static EventType:
|
|
23
|
+
static EventType: import("../enum").Enum<{
|
|
24
|
+
initialized: "initialized";
|
|
25
|
+
taskCanceled: "taskCanceled";
|
|
26
|
+
taskCompleted: "taskCompleted";
|
|
27
|
+
taskFailed: "taskFailed";
|
|
28
|
+
taskQueued: "taskQueued";
|
|
29
|
+
taskQueueDrained: "taskQueueDrained";
|
|
30
|
+
taskStart: "taskStart";
|
|
31
|
+
terminated: "terminated";
|
|
32
|
+
}>;
|
|
24
33
|
private readonly debug;
|
|
25
34
|
private readonly eventObservable;
|
|
26
35
|
private readonly options;
|
package/dist/master/pool.js
CHANGED
|
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.Thread = exports.PoolEventType = exports.Pool = void 0;
|
|
7
7
|
const debug_1 = __importDefault(require("debug"));
|
|
8
8
|
const observable_fns_1 = require("observable-fns");
|
|
9
|
-
const ponyfills_1 = require("../ponyfills");
|
|
10
9
|
const implementation_1 = require("./implementation");
|
|
11
10
|
const pool_types_1 = require("./pool-types");
|
|
12
11
|
const thread_1 = require("./thread");
|
|
@@ -121,7 +120,10 @@ class WorkerPool {
|
|
|
121
120
|
this.eventSubject.next({ type: pool_types_1.PoolEventType.taskQueueDrained });
|
|
122
121
|
return;
|
|
123
122
|
}
|
|
124
|
-
this.run(availableWorker, nextTask)
|
|
123
|
+
this.run(availableWorker, nextTask).catch((error) => {
|
|
124
|
+
this.debug('Error while running task:', error);
|
|
125
|
+
this.eventSubject.error(error);
|
|
126
|
+
});
|
|
125
127
|
}
|
|
126
128
|
taskCompletion(taskID) {
|
|
127
129
|
return new Promise((resolve, reject) => {
|
|
@@ -153,7 +155,7 @@ class WorkerPool {
|
|
|
153
155
|
throw this.initErrors[0];
|
|
154
156
|
}
|
|
155
157
|
if (allowResolvingImmediately && this.taskQueue.length === 0) {
|
|
156
|
-
await
|
|
158
|
+
await Promise.allSettled(getCurrentlyRunningTasks());
|
|
157
159
|
return taskFailures;
|
|
158
160
|
}
|
|
159
161
|
await new Promise((resolve, reject) => {
|
|
@@ -167,7 +169,7 @@ class WorkerPool {
|
|
|
167
169
|
},
|
|
168
170
|
});
|
|
169
171
|
});
|
|
170
|
-
await
|
|
172
|
+
await Promise.allSettled(getCurrentlyRunningTasks());
|
|
171
173
|
failureSubscription.unsubscribe();
|
|
172
174
|
return taskFailures;
|
|
173
175
|
}
|
package/dist/types/master.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { Observable } from 'observable-fns';
|
|
2
|
+
import type { EnumValue } from '../enum';
|
|
3
|
+
import { Enum } from '../enum';
|
|
2
4
|
import type { ObservablePromise } from '../observable-promise';
|
|
3
5
|
import type { $errors, $events, $terminate, $worker } from '../symbols';
|
|
4
6
|
import type { TransferDescriptor } from '../transferable';
|
|
@@ -37,9 +39,8 @@ interface AnyFunctionThread extends PrivateThreadProps {
|
|
|
37
39
|
interface AnyModuleThread extends PrivateThreadProps {
|
|
38
40
|
}
|
|
39
41
|
export type Thread = AnyFunctionThread | AnyModuleThread;
|
|
40
|
-
export type TransferList = Transferable[];
|
|
41
42
|
export interface Worker extends EventTarget {
|
|
42
|
-
postMessage(value: any, transferList?:
|
|
43
|
+
postMessage(value: any, transferList?: Transferable[]): void;
|
|
43
44
|
terminate(callback?: (error?: Error, exitCode?: number) => void): void | Promise<number>;
|
|
44
45
|
}
|
|
45
46
|
export interface ThreadsWorkerOptions extends WorkerOptions {
|
|
@@ -54,7 +55,7 @@ export interface ThreadsWorkerOptions extends WorkerOptions {
|
|
|
54
55
|
}
|
|
55
56
|
export declare class WorkerImplementation extends EventTarget implements Worker {
|
|
56
57
|
constructor(path: string, options?: ThreadsWorkerOptions);
|
|
57
|
-
postMessage(value: any, transferList?:
|
|
58
|
+
postMessage(value: any, transferList?: Transferable[]): void;
|
|
58
59
|
terminate(): void | Promise<number>;
|
|
59
60
|
}
|
|
60
61
|
export declare class BlobWorker extends WorkerImplementation {
|
|
@@ -65,21 +66,22 @@ export interface ImplementationExport {
|
|
|
65
66
|
blob: typeof BlobWorker;
|
|
66
67
|
default: typeof WorkerImplementation;
|
|
67
68
|
}
|
|
68
|
-
export declare
|
|
69
|
-
internalError
|
|
70
|
-
message
|
|
71
|
-
termination
|
|
72
|
-
}
|
|
69
|
+
export declare const WorkerEventType: Enum<{
|
|
70
|
+
internalError: "internalError";
|
|
71
|
+
message: "message";
|
|
72
|
+
termination: "termination";
|
|
73
|
+
}>;
|
|
74
|
+
export type WorkerEventType = EnumValue<typeof WorkerEventType>;
|
|
73
75
|
export interface WorkerInternalErrorEvent {
|
|
74
76
|
error: Error;
|
|
75
|
-
type:
|
|
77
|
+
type: 'internalError';
|
|
76
78
|
}
|
|
77
79
|
export interface WorkerMessageEvent<Data> {
|
|
78
80
|
data: Data;
|
|
79
|
-
type:
|
|
81
|
+
type: 'message';
|
|
80
82
|
}
|
|
81
83
|
export interface WorkerTerminationEvent {
|
|
82
|
-
type:
|
|
84
|
+
type: 'termination';
|
|
83
85
|
}
|
|
84
86
|
export type WorkerEvent = WorkerInternalErrorEvent | WorkerMessageEvent<any> | WorkerTerminationEvent;
|
|
85
87
|
export {};
|
package/dist/types/master.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.WorkerEventType = void 0;
|
|
4
|
-
|
|
5
|
-
(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
})
|
|
4
|
+
const enum_1 = require("../enum");
|
|
5
|
+
exports.WorkerEventType = (0, enum_1.Enum)({
|
|
6
|
+
internalError: 'internalError',
|
|
7
|
+
message: 'message',
|
|
8
|
+
termination: 'termination',
|
|
9
|
+
});
|
package/dist/types/messages.d.ts
CHANGED
|
@@ -1,32 +1,36 @@
|
|
|
1
|
+
import type { EnumValue } from '../enum';
|
|
2
|
+
import { Enum } from '../enum';
|
|
1
3
|
export interface SerializedError {
|
|
2
4
|
__error_marker: '$$error';
|
|
3
5
|
message: string;
|
|
4
6
|
name: string;
|
|
5
7
|
stack?: string;
|
|
6
8
|
}
|
|
7
|
-
export declare
|
|
8
|
-
cancel
|
|
9
|
-
run
|
|
10
|
-
}
|
|
9
|
+
export declare const MasterMessageType: Enum<{
|
|
10
|
+
cancel: "cancel";
|
|
11
|
+
run: "run";
|
|
12
|
+
}>;
|
|
13
|
+
export type MasterMessageType = EnumValue<typeof MasterMessageType>;
|
|
11
14
|
export type MasterJobCancelMessage = {
|
|
12
|
-
type:
|
|
15
|
+
type: 'cancel';
|
|
13
16
|
uid: number;
|
|
14
17
|
};
|
|
15
18
|
export type MasterJobRunMessage = {
|
|
16
|
-
type:
|
|
19
|
+
type: 'run';
|
|
17
20
|
uid: number;
|
|
18
21
|
method?: string;
|
|
19
22
|
args: any[];
|
|
20
23
|
};
|
|
21
|
-
export declare
|
|
22
|
-
error
|
|
23
|
-
init
|
|
24
|
-
result
|
|
25
|
-
running
|
|
26
|
-
uncaughtError
|
|
27
|
-
}
|
|
24
|
+
export declare const WorkerMessageType: Enum<{
|
|
25
|
+
error: "error";
|
|
26
|
+
init: "init";
|
|
27
|
+
result: "result";
|
|
28
|
+
running: "running";
|
|
29
|
+
uncaughtError: "uncaughtError";
|
|
30
|
+
}>;
|
|
31
|
+
export type WorkerMessageType = EnumValue<typeof WorkerMessageType>;
|
|
28
32
|
export type WorkerUncaughtErrorMessage = {
|
|
29
|
-
type:
|
|
33
|
+
type: 'uncaughtError';
|
|
30
34
|
error: {
|
|
31
35
|
message: string;
|
|
32
36
|
name: string;
|
|
@@ -34,7 +38,7 @@ export type WorkerUncaughtErrorMessage = {
|
|
|
34
38
|
};
|
|
35
39
|
};
|
|
36
40
|
export type WorkerInitMessage = {
|
|
37
|
-
type:
|
|
41
|
+
type: 'init';
|
|
38
42
|
exposed: {
|
|
39
43
|
type: 'function';
|
|
40
44
|
} | {
|
|
@@ -43,18 +47,18 @@ export type WorkerInitMessage = {
|
|
|
43
47
|
};
|
|
44
48
|
};
|
|
45
49
|
export type WorkerJobErrorMessage = {
|
|
46
|
-
type:
|
|
50
|
+
type: 'error';
|
|
47
51
|
uid: number;
|
|
48
52
|
error: SerializedError;
|
|
49
53
|
};
|
|
50
54
|
export type WorkerJobResultMessage = {
|
|
51
|
-
type:
|
|
55
|
+
type: 'result';
|
|
52
56
|
uid: number;
|
|
53
57
|
complete?: true;
|
|
54
58
|
payload?: any;
|
|
55
59
|
};
|
|
56
60
|
export type WorkerJobStartMessage = {
|
|
57
|
-
type:
|
|
61
|
+
type: 'running';
|
|
58
62
|
uid: number;
|
|
59
63
|
resultType: 'observable' | 'promise';
|
|
60
64
|
};
|
package/dist/types/messages.js
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.WorkerMessageType = exports.MasterMessageType = void 0;
|
|
4
|
-
|
|
5
|
-
(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
})
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
})(WorkerMessageType || (exports.WorkerMessageType = WorkerMessageType = {}));
|
|
4
|
+
const enum_1 = require("../enum");
|
|
5
|
+
exports.MasterMessageType = (0, enum_1.Enum)({
|
|
6
|
+
cancel: 'cancel',
|
|
7
|
+
run: 'run',
|
|
8
|
+
});
|
|
9
|
+
exports.WorkerMessageType = (0, enum_1.Enum)({
|
|
10
|
+
error: 'error',
|
|
11
|
+
init: 'init',
|
|
12
|
+
result: 'result',
|
|
13
|
+
running: 'running',
|
|
14
|
+
uncaughtError: 'uncaughtError',
|
|
15
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xylabs/threads",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.5.0",
|
|
4
4
|
"description": "Web workers & worker threads as simple as a function call",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -91,22 +91,21 @@
|
|
|
91
91
|
"observable-fns": "^0.6.1"
|
|
92
92
|
},
|
|
93
93
|
"devDependencies": {
|
|
94
|
-
"@babel/types": "^7.26.
|
|
94
|
+
"@babel/types": "^7.26.5",
|
|
95
95
|
"@rollup/plugin-commonjs": "^28.0.2",
|
|
96
96
|
"@rollup/plugin-node-resolve": "^16.0.0",
|
|
97
97
|
"@types/debug": "^4.1.12",
|
|
98
|
-
"@types/node": "^22.10.
|
|
98
|
+
"@types/node": "^22.10.7",
|
|
99
99
|
"@xylabs/ts-scripts-yarn3": "^4.2.6",
|
|
100
100
|
"cross-env": "^7.0.3",
|
|
101
101
|
"puppet-run": "^0.11.4",
|
|
102
102
|
"raw-loader": "^4.0.2",
|
|
103
103
|
"rimraf": "^6.0.1",
|
|
104
|
-
"rollup": "^4.
|
|
104
|
+
"rollup": "^4.31.0",
|
|
105
105
|
"threads-plugin": "^1.4.0",
|
|
106
106
|
"tiny-worker": "^2.3.0",
|
|
107
|
-
"
|
|
108
|
-
"
|
|
109
|
-
"vitest": "^2.1.8",
|
|
107
|
+
"typescript": "^5.7.3",
|
|
108
|
+
"vitest": "^3.0.3",
|
|
110
109
|
"webpack": "^5.97.1"
|
|
111
110
|
},
|
|
112
111
|
"optionalDependencies": {
|
package/src/enum.ts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transforms a given record object into a readonly "enum-like" structure while preserving
|
|
3
|
+
* the literal types of its values. This allows you to use the returned object both at runtime
|
|
4
|
+
* (for lookups) and at compile time (for strongly typed values).
|
|
5
|
+
*
|
|
6
|
+
* To maintain literal types (i.e., prevent them from being widened to `string`, `number`, etc.),
|
|
7
|
+
* ensure you annotate your object with `as const` before passing it to `Enum`.
|
|
8
|
+
*
|
|
9
|
+
* @template T - A record type with string keys and any kind of values.
|
|
10
|
+
* @param obj - A readonly record object annotated with `as const`.
|
|
11
|
+
* @returns A readonly version of the provided record, preserving exact literal value types.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* // Defining a record with literal types using as const:
|
|
16
|
+
* const DnsRecordType = Enum({
|
|
17
|
+
* A: 1,
|
|
18
|
+
* AAAA: 28,
|
|
19
|
+
* CAA: 257,
|
|
20
|
+
* CNAME: 5,
|
|
21
|
+
* DNAME: 39,
|
|
22
|
+
* MX: 15,
|
|
23
|
+
* NS: 2,
|
|
24
|
+
* PTR: 12,
|
|
25
|
+
* SOA: 6,
|
|
26
|
+
* SPF: 99,
|
|
27
|
+
* SRV: 33,
|
|
28
|
+
* TXT: 16,
|
|
29
|
+
* } as const);
|
|
30
|
+
*
|
|
31
|
+
* // DnsRecordType is now a readonly object:
|
|
32
|
+
* // {
|
|
33
|
+
* // readonly A: 1;
|
|
34
|
+
* // readonly AAAA: 28;
|
|
35
|
+
* // readonly CAA: 257;
|
|
36
|
+
* // readonly CNAME: 5;
|
|
37
|
+
* // readonly DNAME: 39;
|
|
38
|
+
* // readonly MX: 15;
|
|
39
|
+
* // readonly NS: 2;
|
|
40
|
+
* // readonly PTR: 12;
|
|
41
|
+
* // readonly SOA: 6;
|
|
42
|
+
* // readonly SPF: 99;
|
|
43
|
+
* // readonly SRV: 33;
|
|
44
|
+
* // readonly TXT: 16;
|
|
45
|
+
* // }
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export const Enum = <const T extends Record<string | number | symbol, unknown>>(obj: Readonly<T>): Enum<T> => {
|
|
49
|
+
return obj
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* A utility type that, given a `Record<string, unknown>`, returns a readonly version
|
|
54
|
+
* of that record. This results in a type where all properties of `T` are readonly.
|
|
55
|
+
*
|
|
56
|
+
* @template T - The record type to make readonly.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```typescript
|
|
60
|
+
* // Given a record:
|
|
61
|
+
* export const DnsRecordType = Enum({
|
|
62
|
+
* A: 1,
|
|
63
|
+
* AAAA: 28,
|
|
64
|
+
* CAA: 257,
|
|
65
|
+
* CNAME: 5,
|
|
66
|
+
* DNAME: 39,
|
|
67
|
+
* MX: 15,
|
|
68
|
+
* NS: 2,
|
|
69
|
+
* PTR: 12,
|
|
70
|
+
* SOA: 6,
|
|
71
|
+
* SPF: 99,
|
|
72
|
+
* SRV: 33,
|
|
73
|
+
* TXT: 16,
|
|
74
|
+
* })
|
|
75
|
+
*
|
|
76
|
+
* // Now the type inference will preserve the literal types:
|
|
77
|
+
* export type DnsRecordType = Enum<typeof DnsRecordType>
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
export type Enum<T extends Readonly<Record<string | number | symbol, unknown>>> = {
|
|
81
|
+
readonly [K in keyof T]: T[K]
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* A utility type that, given an `Enum` object, returns the union of its values.
|
|
86
|
+
*/
|
|
87
|
+
export type EnumValue<T extends Record<string | number | symbol, unknown>, K = Enum<T>> = K[keyof K]
|
package/src/master/pool-types.ts
CHANGED
|
@@ -1,57 +1,61 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
/* eslint-disable @typescript-eslint/member-ordering */
|
|
3
|
+
import type { EnumValue } from '../enum'
|
|
4
|
+
import { Enum } from '../enum'
|
|
3
5
|
import type { Thread } from './thread'
|
|
4
6
|
|
|
5
7
|
/** Pool event type. Specifies the type of each `PoolEvent`. */
|
|
6
|
-
export
|
|
7
|
-
initialized
|
|
8
|
-
taskCanceled
|
|
9
|
-
taskCompleted
|
|
10
|
-
taskFailed
|
|
11
|
-
taskQueued
|
|
12
|
-
taskQueueDrained
|
|
13
|
-
taskStart
|
|
14
|
-
terminated
|
|
15
|
-
}
|
|
8
|
+
export const PoolEventType = Enum({
|
|
9
|
+
initialized: 'initialized',
|
|
10
|
+
taskCanceled: 'taskCanceled',
|
|
11
|
+
taskCompleted: 'taskCompleted',
|
|
12
|
+
taskFailed: 'taskFailed',
|
|
13
|
+
taskQueued: 'taskQueued',
|
|
14
|
+
taskQueueDrained: 'taskQueueDrained',
|
|
15
|
+
taskStart: 'taskStart',
|
|
16
|
+
terminated: 'terminated',
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
export type PoolEventType = EnumValue<typeof PoolEventType>
|
|
16
20
|
|
|
17
21
|
export type TaskRunFunction<ThreadType extends Thread, Return> = (worker: ThreadType) => Promise<Return>
|
|
18
22
|
|
|
19
23
|
/** Pool event. Subscribe to those events using `pool.events()`. Useful for debugging. */
|
|
20
24
|
export type PoolEvent<ThreadType extends Thread> =
|
|
21
25
|
| {
|
|
22
|
-
type:
|
|
26
|
+
type: 'initialized'
|
|
23
27
|
size: number
|
|
24
28
|
}
|
|
25
29
|
| {
|
|
26
|
-
type:
|
|
30
|
+
type: 'taskQueued'
|
|
27
31
|
taskID: number
|
|
28
32
|
}
|
|
29
33
|
| {
|
|
30
|
-
type:
|
|
34
|
+
type: 'taskQueueDrained'
|
|
31
35
|
}
|
|
32
36
|
| {
|
|
33
|
-
type:
|
|
37
|
+
type: 'taskStart'
|
|
34
38
|
taskID: number
|
|
35
39
|
workerID: number
|
|
36
40
|
}
|
|
37
41
|
| {
|
|
38
|
-
type:
|
|
42
|
+
type: 'taskCompleted'
|
|
39
43
|
returnValue: any
|
|
40
44
|
taskID: number
|
|
41
45
|
workerID: number
|
|
42
46
|
}
|
|
43
47
|
| {
|
|
44
|
-
type:
|
|
48
|
+
type: 'taskFailed'
|
|
45
49
|
error: Error
|
|
46
50
|
taskID: number
|
|
47
51
|
workerID: number
|
|
48
52
|
}
|
|
49
53
|
| {
|
|
50
|
-
type:
|
|
54
|
+
type: 'taskCanceled'
|
|
51
55
|
taskID: number
|
|
52
56
|
}
|
|
53
57
|
| {
|
|
54
|
-
type:
|
|
58
|
+
type: 'terminated'
|
|
55
59
|
remainingQueue: Array<QueuedTask<ThreadType, any>>
|
|
56
60
|
}
|
|
57
61
|
|
package/src/master/pool.ts
CHANGED
|
@@ -6,13 +6,12 @@
|
|
|
6
6
|
/* eslint-disable unicorn/no-array-reduce */
|
|
7
7
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
8
8
|
/* eslint-disable @typescript-eslint/no-namespace */
|
|
9
|
-
|
|
9
|
+
|
|
10
10
|
import DebugLogger from 'debug'
|
|
11
11
|
import {
|
|
12
12
|
multicast, Observable, Subject,
|
|
13
13
|
} from 'observable-fns'
|
|
14
14
|
|
|
15
|
-
import { allSettled } from '../ponyfills'
|
|
16
15
|
import { defaultPoolSize } from './implementation'
|
|
17
16
|
import type {
|
|
18
17
|
PoolEvent, QueuedTask, TaskRunFunction, WorkerDescriptor,
|
|
@@ -224,7 +223,10 @@ class WorkerPool<ThreadType extends Thread> implements Pool<ThreadType> {
|
|
|
224
223
|
return
|
|
225
224
|
}
|
|
226
225
|
|
|
227
|
-
this.run(availableWorker, nextTask)
|
|
226
|
+
this.run(availableWorker, nextTask).catch((error) => {
|
|
227
|
+
this.debug('Error while running task:', error)
|
|
228
|
+
this.eventSubject.error(error)
|
|
229
|
+
})
|
|
228
230
|
}
|
|
229
231
|
|
|
230
232
|
private taskCompletion(taskID: number) {
|
|
@@ -259,7 +261,7 @@ class WorkerPool<ThreadType extends Thread> implements Pool<ThreadType> {
|
|
|
259
261
|
throw this.initErrors[0]
|
|
260
262
|
}
|
|
261
263
|
if (allowResolvingImmediately && this.taskQueue.length === 0) {
|
|
262
|
-
await allSettled(getCurrentlyRunningTasks())
|
|
264
|
+
await Promise.allSettled(getCurrentlyRunningTasks())
|
|
263
265
|
return taskFailures
|
|
264
266
|
}
|
|
265
267
|
|
|
@@ -275,7 +277,7 @@ class WorkerPool<ThreadType extends Thread> implements Pool<ThreadType> {
|
|
|
275
277
|
})
|
|
276
278
|
})
|
|
277
279
|
|
|
278
|
-
await allSettled(getCurrentlyRunningTasks())
|
|
280
|
+
await Promise.allSettled(getCurrentlyRunningTasks())
|
|
279
281
|
failureSubscription.unsubscribe()
|
|
280
282
|
|
|
281
283
|
return taskFailures
|
package/src/types/master.ts
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
// See <https://github.com/microsoft/TypeScript/issues/28009>
|
|
7
7
|
import type { Observable } from 'observable-fns'
|
|
8
8
|
|
|
9
|
+
import type { EnumValue } from '../enum'
|
|
10
|
+
import { Enum } from '../enum'
|
|
9
11
|
import type { ObservablePromise } from '../observable-promise'
|
|
10
12
|
import type {
|
|
11
13
|
$errors, $events, $terminate, $worker,
|
|
@@ -64,11 +66,9 @@ interface AnyModuleThread extends PrivateThreadProps {
|
|
|
64
66
|
/** Worker thread. Either a `FunctionThread` or a `ModuleThread`. */
|
|
65
67
|
export type Thread = AnyFunctionThread | AnyModuleThread
|
|
66
68
|
|
|
67
|
-
export type TransferList = Transferable[]
|
|
68
|
-
|
|
69
69
|
/** Worker instance. Either a web worker or a node.js Worker provided by `worker_threads` or `tiny-worker`. */
|
|
70
70
|
export interface Worker extends EventTarget {
|
|
71
|
-
postMessage(value: any, transferList?:
|
|
71
|
+
postMessage(value: any, transferList?: Transferable[]): void
|
|
72
72
|
/** In nodejs 10+ return type is Promise while with tiny-worker and in browser return type is void */
|
|
73
73
|
terminate(callback?: (error?: Error, exitCode?: number) => void): void | Promise<number>
|
|
74
74
|
}
|
|
@@ -93,7 +93,7 @@ export interface ThreadsWorkerOptions extends WorkerOptions {
|
|
|
93
93
|
/** Worker implementation. Either web worker or a node.js Worker class. */
|
|
94
94
|
export declare class WorkerImplementation extends EventTarget implements Worker {
|
|
95
95
|
constructor(path: string, options?: ThreadsWorkerOptions)
|
|
96
|
-
postMessage(value: any, transferList?:
|
|
96
|
+
postMessage(value: any, transferList?: Transferable[]): void
|
|
97
97
|
terminate(): void | Promise<number>
|
|
98
98
|
}
|
|
99
99
|
|
|
@@ -109,24 +109,26 @@ export interface ImplementationExport {
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
/** Event as emitted by worker thread. Subscribe to using `Thread.events(thread)`. */
|
|
112
|
-
export
|
|
113
|
-
internalError
|
|
114
|
-
message
|
|
115
|
-
termination
|
|
116
|
-
}
|
|
112
|
+
export const WorkerEventType = Enum({
|
|
113
|
+
internalError: 'internalError',
|
|
114
|
+
message: 'message',
|
|
115
|
+
termination: 'termination',
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
export type WorkerEventType = EnumValue<typeof WorkerEventType>
|
|
117
119
|
|
|
118
120
|
export interface WorkerInternalErrorEvent {
|
|
119
121
|
error: Error
|
|
120
|
-
type:
|
|
122
|
+
type: 'internalError'
|
|
121
123
|
}
|
|
122
124
|
|
|
123
125
|
export interface WorkerMessageEvent<Data> {
|
|
124
126
|
data: Data
|
|
125
|
-
type:
|
|
127
|
+
type: 'message'
|
|
126
128
|
}
|
|
127
129
|
|
|
128
130
|
export interface WorkerTerminationEvent {
|
|
129
|
-
type:
|
|
131
|
+
type: 'termination'
|
|
130
132
|
}
|
|
131
133
|
|
|
132
134
|
export type WorkerEvent = WorkerInternalErrorEvent | WorkerMessageEvent<any> | WorkerTerminationEvent
|
package/src/types/messages.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
|
|
3
|
+
import type { EnumValue } from '../enum'
|
|
4
|
+
import { Enum } from '../enum'
|
|
5
|
+
|
|
2
6
|
/* eslint-disable @typescript-eslint/member-ordering */
|
|
3
7
|
export interface SerializedError {
|
|
4
8
|
__error_marker: '$$error'
|
|
@@ -10,18 +14,20 @@ export interface SerializedError {
|
|
|
10
14
|
/////////////////////////////
|
|
11
15
|
// Messages sent by master:
|
|
12
16
|
|
|
13
|
-
export
|
|
14
|
-
cancel
|
|
15
|
-
run
|
|
16
|
-
}
|
|
17
|
+
export const MasterMessageType = Enum({
|
|
18
|
+
cancel: 'cancel',
|
|
19
|
+
run: 'run',
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
export type MasterMessageType = EnumValue<typeof MasterMessageType>
|
|
17
23
|
|
|
18
24
|
export type MasterJobCancelMessage = {
|
|
19
|
-
type:
|
|
25
|
+
type: 'cancel'
|
|
20
26
|
uid: number
|
|
21
27
|
}
|
|
22
28
|
|
|
23
29
|
export type MasterJobRunMessage = {
|
|
24
|
-
type:
|
|
30
|
+
type: 'run'
|
|
25
31
|
uid: number
|
|
26
32
|
method?: string
|
|
27
33
|
args: any[]
|
|
@@ -30,16 +36,18 @@ export type MasterJobRunMessage = {
|
|
|
30
36
|
////////////////////////////
|
|
31
37
|
// Messages sent by worker:
|
|
32
38
|
|
|
33
|
-
export
|
|
34
|
-
error
|
|
35
|
-
init
|
|
36
|
-
result
|
|
37
|
-
running
|
|
38
|
-
uncaughtError
|
|
39
|
-
}
|
|
39
|
+
export const WorkerMessageType = Enum({
|
|
40
|
+
error: 'error',
|
|
41
|
+
init: 'init',
|
|
42
|
+
result: 'result',
|
|
43
|
+
running: 'running',
|
|
44
|
+
uncaughtError: 'uncaughtError',
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
export type WorkerMessageType = EnumValue<typeof WorkerMessageType>
|
|
40
48
|
|
|
41
49
|
export type WorkerUncaughtErrorMessage = {
|
|
42
|
-
type:
|
|
50
|
+
type: 'uncaughtError'
|
|
43
51
|
error: {
|
|
44
52
|
message: string
|
|
45
53
|
name: string
|
|
@@ -48,25 +56,25 @@ export type WorkerUncaughtErrorMessage = {
|
|
|
48
56
|
}
|
|
49
57
|
|
|
50
58
|
export type WorkerInitMessage = {
|
|
51
|
-
type:
|
|
59
|
+
type: 'init'
|
|
52
60
|
exposed: { type: 'function' } | { type: 'module'; methods: string[] }
|
|
53
61
|
}
|
|
54
62
|
|
|
55
63
|
export type WorkerJobErrorMessage = {
|
|
56
|
-
type:
|
|
64
|
+
type: 'error'
|
|
57
65
|
uid: number
|
|
58
66
|
error: SerializedError
|
|
59
67
|
}
|
|
60
68
|
|
|
61
69
|
export type WorkerJobResultMessage = {
|
|
62
|
-
type:
|
|
70
|
+
type: 'result'
|
|
63
71
|
uid: number
|
|
64
72
|
complete?: true
|
|
65
73
|
payload?: any
|
|
66
74
|
}
|
|
67
75
|
|
|
68
76
|
export type WorkerJobStartMessage = {
|
|
69
|
-
type:
|
|
77
|
+
type: 'running'
|
|
70
78
|
uid: number
|
|
71
79
|
resultType: 'observable' | 'promise'
|
|
72
80
|
}
|
package/dist/esm/ponyfills.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.allSettled = allSettled;
|
|
4
|
-
function allSettled(values) {
|
|
5
|
-
return Promise.all(values.map((item) => {
|
|
6
|
-
const onFulfill = (value) => {
|
|
7
|
-
return { status: 'fulfilled', value };
|
|
8
|
-
};
|
|
9
|
-
const onReject = (reason) => {
|
|
10
|
-
return { reason, status: 'rejected' };
|
|
11
|
-
};
|
|
12
|
-
const itemPromise = Promise.resolve(item);
|
|
13
|
-
try {
|
|
14
|
-
return itemPromise.then(onFulfill, onReject);
|
|
15
|
-
}
|
|
16
|
-
catch (error) {
|
|
17
|
-
return Promise.reject(error);
|
|
18
|
-
}
|
|
19
|
-
}));
|
|
20
|
-
}
|
package/dist/ponyfills.d.ts
DELETED
package/dist/ponyfills.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.allSettled = allSettled;
|
|
4
|
-
function allSettled(values) {
|
|
5
|
-
return Promise.all(values.map((item) => {
|
|
6
|
-
const onFulfill = (value) => {
|
|
7
|
-
return { status: 'fulfilled', value };
|
|
8
|
-
};
|
|
9
|
-
const onReject = (reason) => {
|
|
10
|
-
return { reason, status: 'rejected' };
|
|
11
|
-
};
|
|
12
|
-
const itemPromise = Promise.resolve(item);
|
|
13
|
-
try {
|
|
14
|
-
return itemPromise.then(onFulfill, onReject);
|
|
15
|
-
}
|
|
16
|
-
catch (error) {
|
|
17
|
-
return Promise.reject(error);
|
|
18
|
-
}
|
|
19
|
-
}));
|
|
20
|
-
}
|
package/src/ponyfills.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
-
export type SettlementResult<T> =
|
|
3
|
-
| {
|
|
4
|
-
status: 'fulfilled'
|
|
5
|
-
value: T
|
|
6
|
-
}
|
|
7
|
-
| {
|
|
8
|
-
reason: any
|
|
9
|
-
status: 'rejected'
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// Based on <https://github.com/es-shims/Promise.allSettled/blob/master/implementation.js>
|
|
13
|
-
export function allSettled<T>(values: T[]): Promise<Array<SettlementResult<T>>> {
|
|
14
|
-
return Promise.all(
|
|
15
|
-
values.map((item) => {
|
|
16
|
-
const onFulfill = (value: T) => {
|
|
17
|
-
return { status: 'fulfilled', value } as const
|
|
18
|
-
}
|
|
19
|
-
const onReject = (reason: any) => {
|
|
20
|
-
return { reason, status: 'rejected' } as const
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const itemPromise = Promise.resolve(item)
|
|
24
|
-
try {
|
|
25
|
-
return itemPromise.then(onFulfill, onReject)
|
|
26
|
-
} catch (error) {
|
|
27
|
-
return Promise.reject(error)
|
|
28
|
-
}
|
|
29
|
-
}),
|
|
30
|
-
)
|
|
31
|
-
}
|