threadsx 2.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.
Files changed (94) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +164 -0
  3. package/dist/common.d.ts +4 -0
  4. package/dist/common.js +16 -0
  5. package/dist/index.d.ts +7 -0
  6. package/dist/index.js +26 -0
  7. package/dist/master/get-bundle-url.browser.d.ts +3 -0
  8. package/dist/master/get-bundle-url.browser.js +28 -0
  9. package/dist/master/implementation.browser.d.ts +4 -0
  10. package/dist/master/implementation.browser.js +72 -0
  11. package/dist/master/implementation.d.ts +6 -0
  12. package/dist/master/implementation.js +51 -0
  13. package/dist/master/implementation.node.d.ts +4 -0
  14. package/dist/master/implementation.node.js +196 -0
  15. package/dist/master/index.d.ts +14 -0
  16. package/dist/master/index.js +15 -0
  17. package/dist/master/invocation-proxy.d.ts +3 -0
  18. package/dist/master/invocation-proxy.js +128 -0
  19. package/dist/master/pool-types.d.ts +65 -0
  20. package/dist/master/pool-types.js +15 -0
  21. package/dist/master/pool.d.ts +89 -0
  22. package/dist/master/pool.js +290 -0
  23. package/dist/master/register.d.ts +1 -0
  24. package/dist/master/register.js +9 -0
  25. package/dist/master/spawn.d.ts +20 -0
  26. package/dist/master/spawn.js +159 -0
  27. package/dist/master/thread.d.ts +12 -0
  28. package/dist/master/thread.js +22 -0
  29. package/dist/observable-promise.d.ts +38 -0
  30. package/dist/observable-promise.js +150 -0
  31. package/dist/observable.d.ts +19 -0
  32. package/dist/observable.js +40 -0
  33. package/dist/ponyfills.d.ts +8 -0
  34. package/dist/ponyfills.js +21 -0
  35. package/dist/promise.d.ts +5 -0
  36. package/dist/promise.js +27 -0
  37. package/dist/serializers.d.ts +16 -0
  38. package/dist/serializers.js +51 -0
  39. package/dist/symbols.d.ts +5 -0
  40. package/dist/symbols.js +8 -0
  41. package/dist/transferable.d.ts +42 -0
  42. package/dist/transferable.js +26 -0
  43. package/dist/types/master.d.ts +98 -0
  44. package/dist/types/master.js +12 -0
  45. package/dist/types/messages.d.ts +62 -0
  46. package/dist/types/messages.js +20 -0
  47. package/dist/types/worker.d.ts +11 -0
  48. package/dist/types/worker.js +2 -0
  49. package/dist/worker/bundle-entry.d.ts +1 -0
  50. package/dist/worker/bundle-entry.js +24 -0
  51. package/dist/worker/implementation.browser.d.ts +6 -0
  52. package/dist/worker/implementation.browser.js +25 -0
  53. package/dist/worker/implementation.d.ts +3 -0
  54. package/dist/worker/implementation.js +18 -0
  55. package/dist/worker/implementation.worker_threads.d.ts +8 -0
  56. package/dist/worker/implementation.worker_threads.js +42 -0
  57. package/dist/worker/index.d.ts +13 -0
  58. package/dist/worker/index.js +224 -0
  59. package/dist/worker_threads.d.ts +8 -0
  60. package/dist/worker_threads.js +16 -0
  61. package/dist-esm/common.js +11 -0
  62. package/dist-esm/index.js +5 -0
  63. package/dist-esm/master/get-bundle-url.browser.js +25 -0
  64. package/dist-esm/master/implementation.browser.js +67 -0
  65. package/dist-esm/master/implementation.js +15 -0
  66. package/dist-esm/master/implementation.node.js +155 -0
  67. package/dist-esm/master/index.js +9 -0
  68. package/dist-esm/master/invocation-proxy.js +121 -0
  69. package/dist-esm/master/pool-types.js +12 -0
  70. package/dist-esm/master/pool.js +283 -0
  71. package/dist-esm/master/register.js +7 -0
  72. package/dist-esm/master/spawn.js +153 -0
  73. package/dist-esm/master/thread.js +19 -0
  74. package/dist-esm/observable-promise.js +146 -0
  75. package/dist-esm/observable.js +36 -0
  76. package/dist-esm/ponyfills.js +18 -0
  77. package/dist-esm/promise.js +24 -0
  78. package/dist-esm/serializers.js +47 -0
  79. package/dist-esm/symbols.js +5 -0
  80. package/dist-esm/transferable.js +22 -0
  81. package/dist-esm/types/master.js +9 -0
  82. package/dist-esm/types/messages.js +17 -0
  83. package/dist-esm/types/worker.js +1 -0
  84. package/dist-esm/worker/bundle-entry.js +8 -0
  85. package/dist-esm/worker/implementation.browser.js +23 -0
  86. package/dist-esm/worker/implementation.js +13 -0
  87. package/dist-esm/worker/implementation.worker_threads.js +37 -0
  88. package/dist-esm/worker/index.js +215 -0
  89. package/dist-esm/worker_threads.js +13 -0
  90. package/index.mjs +4 -0
  91. package/observable.mjs +1 -0
  92. package/package.json +168 -0
  93. package/register.mjs +2 -0
  94. package/worker.mjs +1 -0
@@ -0,0 +1,98 @@
1
+ import { Observable } from "observable-fns";
2
+ import { ObservablePromise } from "../observable-promise";
3
+ import { $errors, $events, $terminate, $worker } from "../symbols";
4
+ import { TransferDescriptor } from "../transferable";
5
+ interface ObservableLikeSubscription {
6
+ unsubscribe(): any;
7
+ }
8
+ interface ObservableLike<T> {
9
+ subscribe(onNext: (value: T) => any, onError?: (error: any) => any, onComplete?: () => any): ObservableLikeSubscription;
10
+ subscribe(listeners: {
11
+ next?(value: T): any;
12
+ error?(error: any): any;
13
+ complete?(): any;
14
+ }): ObservableLikeSubscription;
15
+ }
16
+ export type StripAsync<Type> = Type extends Promise<infer PromiseBaseType> ? PromiseBaseType : Type extends ObservableLike<infer ObservableBaseType> ? ObservableBaseType : Type;
17
+ export type StripTransfer<Type> = Type extends TransferDescriptor<infer BaseType> ? BaseType : Type;
18
+ export type ModuleMethods = {
19
+ [methodName: string]: (...args: any) => any;
20
+ };
21
+ export type ProxyableArgs<Args extends any[]> = Args extends [arg0: infer Arg0, ...rest: infer RestArgs] ? [Arg0 extends Transferable ? Arg0 | TransferDescriptor<Arg0> : Arg0, ...RestArgs] : Args;
22
+ export type ProxyableFunction<Args extends any[], ReturnType> = Args extends [] ? () => ObservablePromise<StripTransfer<StripAsync<ReturnType>>> : (...args: ProxyableArgs<Args>) => ObservablePromise<StripTransfer<StripAsync<ReturnType>>>;
23
+ export type ModuleProxy<Methods extends ModuleMethods> = {
24
+ [method in keyof Methods]: ProxyableFunction<Parameters<Methods[method]>, ReturnType<Methods[method]>>;
25
+ };
26
+ export interface PrivateThreadProps {
27
+ [$errors]: Observable<Error>;
28
+ [$events]: Observable<WorkerEvent>;
29
+ [$terminate]: () => Promise<void>;
30
+ [$worker]: Worker;
31
+ }
32
+ export type FunctionThread<Args extends any[] = any[], ReturnType = any> = ProxyableFunction<Args, ReturnType> & PrivateThreadProps;
33
+ export type ModuleThread<Methods extends ModuleMethods = any> = ModuleProxy<Methods> & PrivateThreadProps;
34
+ interface AnyFunctionThread extends PrivateThreadProps {
35
+ (...args: any[]): ObservablePromise<any>;
36
+ }
37
+ interface AnyModuleThread extends PrivateThreadProps {
38
+ }
39
+ /** Worker thread. Either a `FunctionThread` or a `ModuleThread`. */
40
+ export type Thread = AnyFunctionThread | AnyModuleThread;
41
+ export type TransferList = Transferable[];
42
+ /** Worker instance. Either a web worker or a node.js Worker provided by `worker_threads`. */
43
+ export interface Worker extends EventTarget {
44
+ postMessage(value: any, transferList?: TransferList): void;
45
+ /** In node.js the return type is a Promise, while in the browser it is void */
46
+ terminate(callback?: (error?: Error, exitCode?: number) => void): void | Promise<number>;
47
+ }
48
+ export interface ThreadsWorkerOptions extends WorkerOptions {
49
+ /** Prefix for the path passed to the Worker constructor. Web worker only. */
50
+ _baseURL?: string;
51
+ /** Resource limits passed on to Node worker_threads */
52
+ resourceLimits?: {
53
+ /** The maximum size of the main heap in MB. */
54
+ maxOldGenerationSizeMb?: number;
55
+ /** The maximum size of a heap space for recently created objects. */
56
+ maxYoungGenerationSizeMb?: number;
57
+ /** The size of a pre-allocated memory range used for generated code. */
58
+ codeRangeSizeMb?: number;
59
+ };
60
+ /** Data passed on to node.js worker_threads. */
61
+ workerData?: any;
62
+ /** Whether to apply CORS protection workaround. Defaults to true. */
63
+ CORSWorkaround?: boolean;
64
+ }
65
+ /** Worker implementation. Either web worker or a node.js Worker class. */
66
+ export declare class WorkerImplementation extends EventTarget implements Worker {
67
+ constructor(path: string | URL, options?: ThreadsWorkerOptions);
68
+ postMessage(value: any, transferList?: TransferList): void;
69
+ terminate(): void | Promise<number>;
70
+ }
71
+ /** Class to spawn workers from a blob or source string. */
72
+ export declare class BlobWorker extends WorkerImplementation {
73
+ constructor(blob: Blob, options?: ThreadsWorkerOptions);
74
+ static fromText(source: string, options?: ThreadsWorkerOptions): WorkerImplementation;
75
+ }
76
+ export interface ImplementationExport {
77
+ blob: typeof BlobWorker;
78
+ default: typeof WorkerImplementation;
79
+ }
80
+ /** Event as emitted by worker thread. Subscribe to using `Thread.events(thread)`. */
81
+ export declare enum WorkerEventType {
82
+ internalError = "internalError",
83
+ message = "message",
84
+ termination = "termination"
85
+ }
86
+ export interface WorkerInternalErrorEvent {
87
+ type: WorkerEventType.internalError;
88
+ error: Error;
89
+ }
90
+ export interface WorkerMessageEvent<Data> {
91
+ type: WorkerEventType.message;
92
+ data: Data;
93
+ }
94
+ export interface WorkerTerminationEvent {
95
+ type: WorkerEventType.termination;
96
+ }
97
+ export type WorkerEvent = WorkerInternalErrorEvent | WorkerMessageEvent<any> | WorkerTerminationEvent;
98
+ export {};
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ /// <reference lib="dom" />
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.WorkerEventType = void 0;
5
+ const symbols_1 = require("../symbols");
6
+ /** Event as emitted by worker thread. Subscribe to using `Thread.events(thread)`. */
7
+ var WorkerEventType;
8
+ (function (WorkerEventType) {
9
+ WorkerEventType["internalError"] = "internalError";
10
+ WorkerEventType["message"] = "message";
11
+ WorkerEventType["termination"] = "termination";
12
+ })(WorkerEventType || (exports.WorkerEventType = WorkerEventType = {}));
@@ -0,0 +1,62 @@
1
+ export interface SerializedError {
2
+ __error_marker: "$$error";
3
+ message: string;
4
+ name: string;
5
+ stack?: string;
6
+ }
7
+ export declare enum MasterMessageType {
8
+ cancel = "cancel",
9
+ run = "run"
10
+ }
11
+ export type MasterJobCancelMessage = {
12
+ type: MasterMessageType.cancel;
13
+ uid: number;
14
+ };
15
+ export type MasterJobRunMessage = {
16
+ type: MasterMessageType.run;
17
+ uid: number;
18
+ method?: string;
19
+ args: any[];
20
+ };
21
+ export type MasterSentMessage = MasterJobCancelMessage | MasterJobRunMessage;
22
+ export declare enum WorkerMessageType {
23
+ error = "error",
24
+ init = "init",
25
+ result = "result",
26
+ running = "running",
27
+ uncaughtError = "uncaughtError"
28
+ }
29
+ export type WorkerUncaughtErrorMessage = {
30
+ type: WorkerMessageType.uncaughtError;
31
+ error: {
32
+ message: string;
33
+ name: string;
34
+ stack?: string;
35
+ };
36
+ };
37
+ export type WorkerInitMessage = {
38
+ type: WorkerMessageType.init;
39
+ exposed: {
40
+ type: "function";
41
+ } | {
42
+ type: "module";
43
+ methods: string[];
44
+ };
45
+ };
46
+ export type WorkerJobErrorMessage = {
47
+ type: WorkerMessageType.error;
48
+ uid: number;
49
+ error: SerializedError;
50
+ };
51
+ export type WorkerJobResultMessage = {
52
+ type: WorkerMessageType.result;
53
+ uid: number;
54
+ complete?: true;
55
+ payload?: any;
56
+ };
57
+ export type WorkerJobStartMessage = {
58
+ type: WorkerMessageType.running;
59
+ uid: number;
60
+ resultType: "observable" | "promise";
61
+ };
62
+ export type WorkerSentMessage = WorkerInitMessage | WorkerJobErrorMessage | WorkerJobResultMessage | WorkerJobStartMessage | WorkerUncaughtErrorMessage;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WorkerMessageType = exports.MasterMessageType = void 0;
4
+ /////////////////////////////
5
+ // Messages sent by master:
6
+ var MasterMessageType;
7
+ (function (MasterMessageType) {
8
+ MasterMessageType["cancel"] = "cancel";
9
+ MasterMessageType["run"] = "run";
10
+ })(MasterMessageType || (exports.MasterMessageType = MasterMessageType = {}));
11
+ ////////////////////////////
12
+ // Messages sent by worker:
13
+ var WorkerMessageType;
14
+ (function (WorkerMessageType) {
15
+ WorkerMessageType["error"] = "error";
16
+ WorkerMessageType["init"] = "init";
17
+ WorkerMessageType["result"] = "result";
18
+ WorkerMessageType["running"] = "running";
19
+ WorkerMessageType["uncaughtError"] = "uncaughtError";
20
+ })(WorkerMessageType || (exports.WorkerMessageType = WorkerMessageType = {}));
@@ -0,0 +1,11 @@
1
+ type UnsubscribeFn = () => void;
2
+ export interface AbstractedWorkerAPI {
3
+ isWorkerRuntime(): boolean;
4
+ postMessageToMaster(message: any, transferList?: Transferable[]): void;
5
+ subscribeToMasterMessages(onMessage: (data: any) => void): UnsubscribeFn;
6
+ }
7
+ export type WorkerFunction = ((...args: any[]) => any) | (() => any);
8
+ export type WorkerModule<Keys extends string> = {
9
+ [key in Keys]: WorkerFunction;
10
+ };
11
+ export {};
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1 @@
1
+ export * from "./index";
@@ -0,0 +1,24 @@
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
+ const index_1 = require("./index");
18
+ __exportStar(require("./index"), exports);
19
+ if (typeof global !== "undefined") {
20
+ global.expose = index_1.expose;
21
+ }
22
+ if (typeof self !== "undefined") {
23
+ self.expose = index_1.expose;
24
+ }
@@ -0,0 +1,6 @@
1
+ declare const _default: {
2
+ isWorkerRuntime: () => boolean;
3
+ postMessageToMaster: (message: any, transferList?: Transferable[]) => void;
4
+ subscribeToMasterMessages: (onMessage: (data: any) => void) => () => void;
5
+ };
6
+ export default _default;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ /// <reference lib="dom" />
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const isWorkerRuntime = function isWorkerRuntime() {
5
+ const isWindowContext = typeof self !== "undefined" && typeof Window !== "undefined" && self instanceof Window;
6
+ return typeof self !== "undefined" && typeof self.postMessage === "function" && !isWindowContext;
7
+ };
8
+ const postMessageToMaster = function postMessageToMaster(data, transferList) {
9
+ self.postMessage(data, transferList);
10
+ };
11
+ const subscribeToMasterMessages = function subscribeToMasterMessages(onMessage) {
12
+ const messageHandler = (messageEvent) => {
13
+ onMessage(messageEvent.data);
14
+ };
15
+ const unsubscribe = () => {
16
+ self.removeEventListener("message", messageHandler);
17
+ };
18
+ self.addEventListener("message", messageHandler);
19
+ return unsubscribe;
20
+ };
21
+ exports.default = {
22
+ isWorkerRuntime,
23
+ postMessageToMaster,
24
+ subscribeToMasterMessages
25
+ };
@@ -0,0 +1,3 @@
1
+ import { AbstractedWorkerAPI } from "../types/worker";
2
+ declare const _default: AbstractedWorkerAPI;
3
+ export default _default;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ /*
3
+ * This file is only a stub to make './implementation' resolve to the right module.
4
+ */
5
+ var __importDefault = (this && this.__importDefault) || function (mod) {
6
+ return (mod && mod.__esModule) ? mod : { "default": mod };
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ const implementation_browser_1 = __importDefault(require("./implementation.browser"));
10
+ const implementation_worker_threads_1 = __importDefault(require("./implementation.worker_threads"));
11
+ const runningInNode = typeof process !== 'undefined' && process.arch !== 'browser' && 'pid' in process;
12
+ function selectNodeImplementation() {
13
+ implementation_worker_threads_1.default.testImplementation();
14
+ return implementation_worker_threads_1.default;
15
+ }
16
+ exports.default = runningInNode
17
+ ? selectNodeImplementation()
18
+ : implementation_browser_1.default;
@@ -0,0 +1,8 @@
1
+ declare function testImplementation(): void;
2
+ declare const _default: {
3
+ isWorkerRuntime: () => boolean;
4
+ postMessageToMaster: (message: any, transferList?: Transferable[]) => void;
5
+ subscribeToMasterMessages: (onMessage: (data: any) => void) => () => void;
6
+ testImplementation: typeof testImplementation;
7
+ };
8
+ export default _default;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const worker_threads_1 = __importDefault(require("../worker_threads"));
7
+ function assertMessagePort(port) {
8
+ if (!port) {
9
+ throw Error("Invariant violation: MessagePort to parent is not available.");
10
+ }
11
+ return port;
12
+ }
13
+ const isWorkerRuntime = function isWorkerRuntime() {
14
+ return !(0, worker_threads_1.default)().isMainThread;
15
+ };
16
+ const postMessageToMaster = function postMessageToMaster(data, transferList) {
17
+ assertMessagePort((0, worker_threads_1.default)().parentPort).postMessage(data, transferList);
18
+ };
19
+ const subscribeToMasterMessages = function subscribeToMasterMessages(onMessage) {
20
+ const parentPort = (0, worker_threads_1.default)().parentPort;
21
+ if (!parentPort) {
22
+ throw Error("Invariant violation: MessagePort to parent is not available.");
23
+ }
24
+ const messageHandler = (message) => {
25
+ onMessage(message);
26
+ };
27
+ const unsubscribe = () => {
28
+ assertMessagePort(parentPort).off("message", messageHandler);
29
+ };
30
+ assertMessagePort(parentPort).on("message", messageHandler);
31
+ return unsubscribe;
32
+ };
33
+ function testImplementation() {
34
+ // Will throw if `worker_threads` are not available
35
+ (0, worker_threads_1.default)();
36
+ }
37
+ exports.default = {
38
+ isWorkerRuntime,
39
+ postMessageToMaster,
40
+ subscribeToMasterMessages,
41
+ testImplementation
42
+ };
@@ -0,0 +1,13 @@
1
+ import { WorkerFunction, WorkerModule } from "../types/worker";
2
+ export { registerSerializer } from "../common";
3
+ export { Transfer } from "../transferable";
4
+ /** Returns `true` if this code is currently running in a worker. */
5
+ export declare const isWorkerRuntime: () => boolean;
6
+ /**
7
+ * Expose a function or a module (an object whose values are functions)
8
+ * to the main thread. Must be called exactly once in every worker thread
9
+ * to signal its API to the main thread.
10
+ *
11
+ * @param exposed Function or object whose values are functions
12
+ */
13
+ export declare function expose(exposed: WorkerFunction | WorkerModule<any>): void;
@@ -0,0 +1,224 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.isWorkerRuntime = exports.Transfer = exports.registerSerializer = void 0;
16
+ exports.expose = expose;
17
+ const common_1 = require("../common");
18
+ const transferable_1 = require("../transferable");
19
+ const messages_1 = require("../types/messages");
20
+ const implementation_1 = __importDefault(require("./implementation"));
21
+ var common_2 = require("../common");
22
+ Object.defineProperty(exports, "registerSerializer", { enumerable: true, get: function () { return common_2.registerSerializer; } });
23
+ var transferable_2 = require("../transferable");
24
+ Object.defineProperty(exports, "Transfer", { enumerable: true, get: function () { return transferable_2.Transfer; } });
25
+ /** Returns `true` if this code is currently running in a worker. */
26
+ exports.isWorkerRuntime = implementation_1.default.isWorkerRuntime;
27
+ let exposeCalled = false;
28
+ const activeSubscriptions = new Map();
29
+ const isMasterJobCancelMessage = (thing) => thing && thing.type === messages_1.MasterMessageType.cancel;
30
+ const isMasterJobRunMessage = (thing) => thing && thing.type === messages_1.MasterMessageType.run;
31
+ /**
32
+ * Detects observables via the `Symbol.observable` / `@@observable` interop protocol.
33
+ * Inlined from the `is-observable` package (which is now ESM-only) to keep the
34
+ * CommonJS build working without an extra dependency.
35
+ */
36
+ function isInteropObservable(thing) {
37
+ if (!thing) {
38
+ return false;
39
+ }
40
+ const observableSymbol = Symbol.observable;
41
+ if (typeof observableSymbol === "symbol" && typeof thing[observableSymbol] === "function") {
42
+ return thing === thing[observableSymbol]();
43
+ }
44
+ if (typeof thing["@@observable"] === "function") {
45
+ return thing === thing["@@observable"]();
46
+ }
47
+ return false;
48
+ }
49
+ /**
50
+ * There are issues with interop observable detection not recognizing zen-observable's instances.
51
+ * We are using `observable-fns`, but it's based on zen-observable, too.
52
+ */
53
+ const isObservable = (thing) => isInteropObservable(thing) || isZenObservable(thing);
54
+ function isZenObservable(thing) {
55
+ return thing && typeof thing === "object" && typeof thing.subscribe === "function";
56
+ }
57
+ function deconstructTransfer(thing) {
58
+ return (0, transferable_1.isTransferDescriptor)(thing)
59
+ ? { payload: thing.send, transferables: thing.transferables }
60
+ : { payload: thing, transferables: undefined };
61
+ }
62
+ function postFunctionInitMessage() {
63
+ const initMessage = {
64
+ type: messages_1.WorkerMessageType.init,
65
+ exposed: {
66
+ type: "function"
67
+ }
68
+ };
69
+ implementation_1.default.postMessageToMaster(initMessage);
70
+ }
71
+ function postModuleInitMessage(methodNames) {
72
+ const initMessage = {
73
+ type: messages_1.WorkerMessageType.init,
74
+ exposed: {
75
+ type: "module",
76
+ methods: methodNames
77
+ }
78
+ };
79
+ implementation_1.default.postMessageToMaster(initMessage);
80
+ }
81
+ function postJobErrorMessage(uid, rawError) {
82
+ const { payload: error, transferables } = deconstructTransfer(rawError);
83
+ const errorMessage = {
84
+ type: messages_1.WorkerMessageType.error,
85
+ uid,
86
+ error: (0, common_1.serialize)(error)
87
+ };
88
+ implementation_1.default.postMessageToMaster(errorMessage, transferables);
89
+ }
90
+ function postJobResultMessage(uid, completed, resultValue) {
91
+ const { payload, transferables } = deconstructTransfer(resultValue);
92
+ const resultMessage = {
93
+ type: messages_1.WorkerMessageType.result,
94
+ uid,
95
+ complete: completed ? true : undefined,
96
+ payload
97
+ };
98
+ implementation_1.default.postMessageToMaster(resultMessage, transferables);
99
+ }
100
+ function postJobStartMessage(uid, resultType) {
101
+ const startMessage = {
102
+ type: messages_1.WorkerMessageType.running,
103
+ uid,
104
+ resultType
105
+ };
106
+ implementation_1.default.postMessageToMaster(startMessage);
107
+ }
108
+ function postUncaughtErrorMessage(error) {
109
+ try {
110
+ const errorMessage = {
111
+ type: messages_1.WorkerMessageType.uncaughtError,
112
+ error: (0, common_1.serialize)(error)
113
+ };
114
+ implementation_1.default.postMessageToMaster(errorMessage);
115
+ }
116
+ catch (subError) {
117
+ console.error("Not reporting uncaught error back to master thread as it " +
118
+ "occured while reporting an uncaught error already." +
119
+ "\nLatest error:", subError, "\nOriginal error:", error);
120
+ }
121
+ }
122
+ function runFunction(jobUID, fn, args) {
123
+ return __awaiter(this, void 0, void 0, function* () {
124
+ let syncResult;
125
+ try {
126
+ syncResult = fn(...args);
127
+ }
128
+ catch (error) {
129
+ return postJobErrorMessage(jobUID, error);
130
+ }
131
+ const resultType = isObservable(syncResult) ? "observable" : "promise";
132
+ postJobStartMessage(jobUID, resultType);
133
+ if (isObservable(syncResult)) {
134
+ const subscription = syncResult.subscribe(value => postJobResultMessage(jobUID, false, (0, common_1.serialize)(value)), error => {
135
+ postJobErrorMessage(jobUID, (0, common_1.serialize)(error));
136
+ activeSubscriptions.delete(jobUID);
137
+ }, () => {
138
+ postJobResultMessage(jobUID, true);
139
+ activeSubscriptions.delete(jobUID);
140
+ });
141
+ activeSubscriptions.set(jobUID, subscription);
142
+ }
143
+ else {
144
+ try {
145
+ const result = yield syncResult;
146
+ postJobResultMessage(jobUID, true, (0, common_1.serialize)(result));
147
+ }
148
+ catch (error) {
149
+ postJobErrorMessage(jobUID, (0, common_1.serialize)(error));
150
+ }
151
+ }
152
+ });
153
+ }
154
+ /**
155
+ * Expose a function or a module (an object whose values are functions)
156
+ * to the main thread. Must be called exactly once in every worker thread
157
+ * to signal its API to the main thread.
158
+ *
159
+ * @param exposed Function or object whose values are functions
160
+ */
161
+ function expose(exposed) {
162
+ if (!implementation_1.default.isWorkerRuntime()) {
163
+ throw Error("expose() called in the master thread.");
164
+ }
165
+ if (exposeCalled) {
166
+ throw Error("expose() called more than once. This is not possible. Pass an object to expose() if you want to expose multiple functions.");
167
+ }
168
+ exposeCalled = true;
169
+ if (typeof exposed === "function") {
170
+ implementation_1.default.subscribeToMasterMessages(messageData => {
171
+ if (isMasterJobRunMessage(messageData) && !messageData.method) {
172
+ runFunction(messageData.uid, exposed, messageData.args.map(common_1.deserialize));
173
+ }
174
+ });
175
+ postFunctionInitMessage();
176
+ }
177
+ else if (typeof exposed === "object" && exposed) {
178
+ implementation_1.default.subscribeToMasterMessages(messageData => {
179
+ if (isMasterJobRunMessage(messageData) && messageData.method) {
180
+ runFunction(messageData.uid, exposed[messageData.method], messageData.args.map(common_1.deserialize));
181
+ }
182
+ });
183
+ const methodNames = Object.keys(exposed).filter(key => typeof exposed[key] === "function");
184
+ postModuleInitMessage(methodNames);
185
+ }
186
+ else {
187
+ throw Error(`Invalid argument passed to expose(). Expected a function or an object, got: ${exposed}`);
188
+ }
189
+ implementation_1.default.subscribeToMasterMessages(messageData => {
190
+ if (isMasterJobCancelMessage(messageData)) {
191
+ const jobUID = messageData.uid;
192
+ const subscription = activeSubscriptions.get(jobUID);
193
+ if (subscription) {
194
+ subscription.unsubscribe();
195
+ activeSubscriptions.delete(jobUID);
196
+ }
197
+ }
198
+ });
199
+ }
200
+ if (typeof self !== "undefined" && typeof self.addEventListener === "function" && implementation_1.default.isWorkerRuntime()) {
201
+ self.addEventListener("error", event => {
202
+ // Post with some delay, so the master had some time to subscribe to messages
203
+ setTimeout(() => postUncaughtErrorMessage(event.error || event), 250);
204
+ });
205
+ self.addEventListener("unhandledrejection", event => {
206
+ const error = event.reason;
207
+ if (error && typeof error.message === "string") {
208
+ // Post with some delay, so the master had some time to subscribe to messages
209
+ setTimeout(() => postUncaughtErrorMessage(error), 250);
210
+ }
211
+ });
212
+ }
213
+ if (typeof process !== "undefined" && typeof process.on === "function" && implementation_1.default.isWorkerRuntime()) {
214
+ process.on("uncaughtException", (error) => {
215
+ // Post with some delay, so the master had some time to subscribe to messages
216
+ setTimeout(() => postUncaughtErrorMessage(error), 250);
217
+ });
218
+ process.on("unhandledRejection", (error) => {
219
+ if (error && typeof error.message === "string") {
220
+ // Post with some delay, so the master had some time to subscribe to messages
221
+ setTimeout(() => postUncaughtErrorMessage(error), 250);
222
+ }
223
+ });
224
+ }
@@ -0,0 +1,8 @@
1
+ type MessagePort = any;
2
+ interface WorkerThreadsModule {
3
+ MessagePort: typeof MessagePort;
4
+ isMainThread: boolean;
5
+ parentPort: MessagePort;
6
+ }
7
+ export default function getImplementation(): WorkerThreadsModule;
8
+ export {};
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ // Webpack hack
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.default = getImplementation;
5
+ let implementation;
6
+ function selectImplementation() {
7
+ return typeof __non_webpack_require__ === "function"
8
+ ? __non_webpack_require__("worker_threads")
9
+ : eval("require")("worker_threads");
10
+ }
11
+ function getImplementation() {
12
+ if (!implementation) {
13
+ implementation = selectImplementation();
14
+ }
15
+ return implementation;
16
+ }
@@ -0,0 +1,11 @@
1
+ import { extendSerializer, DefaultSerializer } from "./serializers";
2
+ let registeredSerializer = DefaultSerializer;
3
+ export function registerSerializer(serializer) {
4
+ registeredSerializer = extendSerializer(registeredSerializer, serializer);
5
+ }
6
+ export function deserialize(message) {
7
+ return registeredSerializer.deserialize(message);
8
+ }
9
+ export function serialize(input) {
10
+ return registeredSerializer.serialize(input);
11
+ }
@@ -0,0 +1,5 @@
1
+ export { registerSerializer } from "./common";
2
+ export * from "./master/index";
3
+ export { expose } from "./worker/index";
4
+ export { DefaultSerializer } from "./serializers";
5
+ export { Transfer } from "./transferable";
@@ -0,0 +1,25 @@
1
+ // Source: <https://github.com/parcel-bundler/parcel/blob/master/packages/core/parcel-bundler/src/builtins/bundle-url.js>
2
+ let bundleURL;
3
+ function getBundleURLCached() {
4
+ if (!bundleURL) {
5
+ bundleURL = getBundleURL();
6
+ }
7
+ return bundleURL;
8
+ }
9
+ function getBundleURL() {
10
+ // Attempt to find the URL of the current script and use that as the base URL
11
+ try {
12
+ throw new Error;
13
+ }
14
+ catch (err) {
15
+ const matches = ("" + err.stack).match(/(https?|file|ftp|chrome-extension|moz-extension):\/\/[^)\n]+/g);
16
+ if (matches) {
17
+ return getBaseURL(matches[0]);
18
+ }
19
+ }
20
+ return "/";
21
+ }
22
+ function getBaseURL(url) {
23
+ return ("" + url).replace(/^((?:https?|file|ftp|chrome-extension|moz-extension):\/\/.+)?\/[^/]+(?:\?.*)?$/, '$1') + '/';
24
+ }
25
+ export { getBaseURL, getBundleURLCached as getBundleURL };