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,159 @@
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.spawn = spawn;
16
+ const debug_1 = __importDefault(require("debug"));
17
+ const observable_fns_1 = require("observable-fns");
18
+ const common_1 = require("../common");
19
+ const promise_1 = require("../promise");
20
+ const symbols_1 = require("../symbols");
21
+ const master_1 = require("../types/master");
22
+ const invocation_proxy_1 = require("./invocation-proxy");
23
+ const debugMessages = (0, debug_1.default)("threads:master:messages");
24
+ const debugSpawn = (0, debug_1.default)("threads:master:spawn");
25
+ const debugThreadUtils = (0, debug_1.default)("threads:master:thread-utils");
26
+ const isInitMessage = (data) => data && data.type === "init";
27
+ const isUncaughtErrorMessage = (data) => data && data.type === "uncaughtError";
28
+ const initMessageTimeout = typeof process !== "undefined" && typeof process.env !== "undefined" && process.env.THREADS_WORKER_INIT_TIMEOUT
29
+ ? Number.parseInt(process.env.THREADS_WORKER_INIT_TIMEOUT, 10)
30
+ : 10000;
31
+ function withTimeout(promise, timeoutInMs, errorMessage) {
32
+ return __awaiter(this, void 0, void 0, function* () {
33
+ let timeoutHandle;
34
+ const timeout = new Promise((resolve, reject) => {
35
+ timeoutHandle = setTimeout(() => reject(Error(errorMessage)), timeoutInMs);
36
+ });
37
+ try {
38
+ return yield Promise.race([
39
+ promise,
40
+ timeout
41
+ ]);
42
+ }
43
+ finally {
44
+ // Always clear the timer, even when `promise` rejects. Otherwise a pending
45
+ // timeout keeps the event loop alive until it fires (which on a failed
46
+ // spawn showed up as ava "failed to exit" on slower runners).
47
+ clearTimeout(timeoutHandle);
48
+ }
49
+ });
50
+ }
51
+ function receiveInitMessage(worker) {
52
+ return new Promise((resolve, reject) => {
53
+ const messageHandler = ((event) => {
54
+ debugMessages("Message from worker before finishing initialization:", event.data);
55
+ if (isInitMessage(event.data)) {
56
+ worker.removeEventListener("message", messageHandler);
57
+ resolve(event.data);
58
+ }
59
+ else if (isUncaughtErrorMessage(event.data)) {
60
+ worker.removeEventListener("message", messageHandler);
61
+ reject((0, common_1.deserialize)(event.data.error));
62
+ }
63
+ });
64
+ worker.addEventListener("message", messageHandler);
65
+ });
66
+ }
67
+ function createEventObservable(worker, workerTermination) {
68
+ return new observable_fns_1.Observable(observer => {
69
+ const messageHandler = ((messageEvent) => {
70
+ const workerEvent = {
71
+ type: master_1.WorkerEventType.message,
72
+ data: messageEvent.data
73
+ };
74
+ observer.next(workerEvent);
75
+ });
76
+ const rejectionHandler = ((errorEvent) => {
77
+ debugThreadUtils("Unhandled promise rejection event in thread:", errorEvent);
78
+ const workerEvent = {
79
+ type: master_1.WorkerEventType.internalError,
80
+ error: Error(errorEvent.reason)
81
+ };
82
+ observer.next(workerEvent);
83
+ });
84
+ worker.addEventListener("message", messageHandler);
85
+ worker.addEventListener("unhandledrejection", rejectionHandler);
86
+ workerTermination.then(() => {
87
+ const terminationEvent = {
88
+ type: master_1.WorkerEventType.termination
89
+ };
90
+ worker.removeEventListener("message", messageHandler);
91
+ worker.removeEventListener("unhandledrejection", rejectionHandler);
92
+ observer.next(terminationEvent);
93
+ observer.complete();
94
+ });
95
+ });
96
+ }
97
+ function createTerminator(worker) {
98
+ const [termination, resolver] = (0, promise_1.createPromiseWithResolver)();
99
+ const terminate = () => __awaiter(this, void 0, void 0, function* () {
100
+ debugThreadUtils("Terminating worker");
101
+ // Newer versions of worker_threads workers return a promise
102
+ yield worker.terminate();
103
+ resolver();
104
+ });
105
+ return { terminate, termination };
106
+ }
107
+ function setPrivateThreadProps(raw, worker, workerEvents, terminate) {
108
+ const workerErrors = workerEvents
109
+ .filter(event => event.type === master_1.WorkerEventType.internalError)
110
+ .map(errorEvent => errorEvent.error);
111
+ return Object.assign(raw, {
112
+ [symbols_1.$errors]: workerErrors,
113
+ [symbols_1.$events]: workerEvents,
114
+ [symbols_1.$terminate]: terminate,
115
+ [symbols_1.$worker]: worker
116
+ });
117
+ }
118
+ /**
119
+ * Spawn a new thread. Takes a fresh worker instance, wraps it in a thin
120
+ * abstraction layer to provide the transparent API and verifies that
121
+ * the worker has initialized successfully.
122
+ *
123
+ * @param worker Instance of `Worker`. Either a web worker or a `worker_threads` worker.
124
+ * @param [options]
125
+ * @param [options.timeout] Init message timeout. Default: 10000 or set by environment variable.
126
+ */
127
+ function spawn(worker, options) {
128
+ return __awaiter(this, void 0, void 0, function* () {
129
+ var _a, _b;
130
+ debugSpawn("Initializing new thread");
131
+ const timeout = options && options.timeout ? options.timeout : initMessageTimeout;
132
+ let initMessage;
133
+ try {
134
+ initMessage = yield withTimeout(receiveInitMessage(worker), timeout, `Timeout: Did not receive an init message from worker after ${timeout}ms. Make sure the worker calls expose().`);
135
+ }
136
+ catch (error) {
137
+ // The worker failed to initialise (e.g. it threw before calling expose(),
138
+ // or never sent an init message). Tear it down so it does not leak a live
139
+ // worker handle and keep the process from exiting.
140
+ yield Promise.resolve((_b = (_a = worker).terminate) === null || _b === void 0 ? void 0 : _b.call(_a)).catch(() => undefined);
141
+ throw error;
142
+ }
143
+ const exposed = initMessage.exposed;
144
+ const { termination, terminate } = createTerminator(worker);
145
+ const events = createEventObservable(worker, termination);
146
+ if (exposed.type === "function") {
147
+ const proxy = (0, invocation_proxy_1.createProxyFunction)(worker);
148
+ return setPrivateThreadProps(proxy, worker, events, terminate);
149
+ }
150
+ else if (exposed.type === "module") {
151
+ const proxy = (0, invocation_proxy_1.createProxyModule)(worker, exposed.methods);
152
+ return setPrivateThreadProps(proxy, worker, events, terminate);
153
+ }
154
+ else {
155
+ const type = exposed.type;
156
+ throw Error(`Worker init message states unexpected type of expose(): ${type}`);
157
+ }
158
+ });
159
+ }
@@ -0,0 +1,12 @@
1
+ import { Observable } from "observable-fns";
2
+ import { Thread as ThreadType, WorkerEvent } from "../types/master";
3
+ export type Thread = ThreadType;
4
+ /** Thread utility functions. Use them to manage or inspect a `spawn()`-ed thread. */
5
+ export declare const Thread: {
6
+ /** Return an observable that can be used to subscribe to all errors happening in the thread. */
7
+ errors<ThreadT extends ThreadType>(thread: ThreadT): Observable<Error>;
8
+ /** Return an observable that can be used to subscribe to internal events happening in the thread. Useful for debugging. */
9
+ events<ThreadT extends ThreadType>(thread: ThreadT): Observable<WorkerEvent>;
10
+ /** Terminate a thread. Remember to terminate every thread when you are done using it. */
11
+ terminate<ThreadT extends ThreadType>(thread: ThreadT): Promise<void>;
12
+ };
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Thread = void 0;
4
+ const symbols_1 = require("../symbols");
5
+ function fail(message) {
6
+ throw Error(message);
7
+ }
8
+ /** Thread utility functions. Use them to manage or inspect a `spawn()`-ed thread. */
9
+ exports.Thread = {
10
+ /** Return an observable that can be used to subscribe to all errors happening in the thread. */
11
+ errors(thread) {
12
+ return thread[symbols_1.$errors] || fail("Error observable not found. Make sure to pass a thread instance as returned by the spawn() promise.");
13
+ },
14
+ /** Return an observable that can be used to subscribe to internal events happening in the thread. Useful for debugging. */
15
+ events(thread) {
16
+ return thread[symbols_1.$events] || fail("Events observable not found. Make sure to pass a thread instance as returned by the spawn() promise.");
17
+ },
18
+ /** Terminate a thread. Remember to terminate every thread when you are done using it. */
19
+ terminate(thread) {
20
+ return thread[symbols_1.$terminate]();
21
+ }
22
+ };
@@ -0,0 +1,38 @@
1
+ import { Observable, ObservableLike, SubscriptionObserver } from "observable-fns";
2
+ type Initializer<T> = (observer: SubscriptionObserver<T>) => UnsubscribeFn | void;
3
+ type Thenable<T> = {
4
+ then: (onFulfilled?: (value: T) => any, onRejected?: (error: any) => any) => any;
5
+ };
6
+ type UnsubscribeFn = () => void;
7
+ /**
8
+ * Creates a hybrid, combining the APIs of an Observable and a Promise.
9
+ *
10
+ * It is used to proxy async process states when we are initially not sure
11
+ * if that async process will yield values once (-> Promise) or multiple
12
+ * times (-> Observable).
13
+ *
14
+ * Note that the observable promise inherits some of the observable's characteristics:
15
+ * The `init` function will be called *once for every time anyone subscribes to it*.
16
+ *
17
+ * If this is undesired, derive a hot observable from it using `makeHot()` and
18
+ * subscribe to that.
19
+ */
20
+ export declare class ObservablePromise<T> extends Observable<T> implements Promise<T> {
21
+ private initHasRun;
22
+ private fulfillmentCallbacks;
23
+ private rejectionCallbacks;
24
+ private firstValue;
25
+ private firstValueSet;
26
+ private rejection;
27
+ private state;
28
+ readonly [Symbol.toStringTag]: "[object ObservablePromise]";
29
+ constructor(init: Initializer<T>);
30
+ private onNext;
31
+ private onError;
32
+ private onCompletion;
33
+ then<TResult1 = T, TResult2 = never>(onFulfilledRaw?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onRejectedRaw?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2>;
34
+ catch<Result = never>(onRejected: ((error: Error) => Promise<Result> | Result) | null | undefined): Promise<Result>;
35
+ finally(onCompleted?: (() => void) | null | undefined): Promise<T>;
36
+ static from<T>(thing: Observable<T> | ObservableLike<T> | ArrayLike<T> | Thenable<T>): ObservablePromise<T>;
37
+ }
38
+ export {};
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.ObservablePromise = void 0;
5
+ const observable_fns_1 = require("observable-fns");
6
+ const doNothing = () => undefined;
7
+ const returnInput = (input) => input;
8
+ const runDeferred = (fn) => Promise.resolve().then(fn);
9
+ function fail(error) {
10
+ throw error;
11
+ }
12
+ function isThenable(thing) {
13
+ return thing && typeof thing.then === "function";
14
+ }
15
+ /**
16
+ * Creates a hybrid, combining the APIs of an Observable and a Promise.
17
+ *
18
+ * It is used to proxy async process states when we are initially not sure
19
+ * if that async process will yield values once (-> Promise) or multiple
20
+ * times (-> Observable).
21
+ *
22
+ * Note that the observable promise inherits some of the observable's characteristics:
23
+ * The `init` function will be called *once for every time anyone subscribes to it*.
24
+ *
25
+ * If this is undesired, derive a hot observable from it using `makeHot()` and
26
+ * subscribe to that.
27
+ */
28
+ class ObservablePromise extends observable_fns_1.Observable {
29
+ constructor(init) {
30
+ super((originalObserver) => {
31
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
32
+ const self = this;
33
+ const observer = Object.assign(Object.assign({}, originalObserver), { complete() {
34
+ originalObserver.complete();
35
+ self.onCompletion();
36
+ },
37
+ error(error) {
38
+ originalObserver.error(error);
39
+ self.onError(error);
40
+ },
41
+ next(value) {
42
+ originalObserver.next(value);
43
+ self.onNext(value);
44
+ } });
45
+ try {
46
+ this.initHasRun = true;
47
+ return init(observer);
48
+ }
49
+ catch (error) {
50
+ observer.error(error);
51
+ }
52
+ });
53
+ this.initHasRun = false;
54
+ this.fulfillmentCallbacks = [];
55
+ this.rejectionCallbacks = [];
56
+ this.firstValueSet = false;
57
+ this.state = "pending";
58
+ this[_a] = "[object ObservablePromise]";
59
+ }
60
+ onNext(value) {
61
+ if (!this.firstValueSet) {
62
+ this.firstValue = value;
63
+ this.firstValueSet = true;
64
+ }
65
+ }
66
+ onError(error) {
67
+ this.state = "rejected";
68
+ this.rejection = error;
69
+ for (const onRejected of this.rejectionCallbacks) {
70
+ // Promisifying the call to turn errors into unhandled promise rejections
71
+ // instead of them failing sync and cancelling the iteration
72
+ runDeferred(() => onRejected(error));
73
+ }
74
+ }
75
+ onCompletion() {
76
+ this.state = "fulfilled";
77
+ for (const onFulfilled of this.fulfillmentCallbacks) {
78
+ // Promisifying the call to turn errors into unhandled promise rejections
79
+ // instead of them failing sync and cancelling the iteration
80
+ runDeferred(() => onFulfilled(this.firstValue));
81
+ }
82
+ }
83
+ then(onFulfilledRaw, onRejectedRaw) {
84
+ const onFulfilled = onFulfilledRaw || returnInput;
85
+ const onRejected = onRejectedRaw || fail;
86
+ let onRejectedCalled = false;
87
+ return new Promise((resolve, reject) => {
88
+ const rejectionCallback = (error) => {
89
+ if (onRejectedCalled)
90
+ return;
91
+ onRejectedCalled = true;
92
+ try {
93
+ resolve(onRejected(error));
94
+ }
95
+ catch (anotherError) {
96
+ reject(anotherError);
97
+ }
98
+ };
99
+ const fulfillmentCallback = (value) => {
100
+ try {
101
+ resolve(onFulfilled(value));
102
+ }
103
+ catch (error) {
104
+ rejectionCallback(error);
105
+ }
106
+ };
107
+ if (!this.initHasRun) {
108
+ this.subscribe({ error: rejectionCallback });
109
+ }
110
+ if (this.state === "fulfilled") {
111
+ return resolve(onFulfilled(this.firstValue));
112
+ }
113
+ if (this.state === "rejected") {
114
+ onRejectedCalled = true;
115
+ return resolve(onRejected(this.rejection));
116
+ }
117
+ this.fulfillmentCallbacks.push(fulfillmentCallback);
118
+ this.rejectionCallbacks.push(rejectionCallback);
119
+ });
120
+ }
121
+ catch(onRejected) {
122
+ return this.then(undefined, onRejected);
123
+ }
124
+ finally(onCompleted) {
125
+ const handler = onCompleted || doNothing;
126
+ return this.then((value) => {
127
+ handler();
128
+ return value;
129
+ }, () => handler());
130
+ }
131
+ static from(thing) {
132
+ if (isThenable(thing)) {
133
+ return new ObservablePromise(observer => {
134
+ const onFulfilled = (value) => {
135
+ observer.next(value);
136
+ observer.complete();
137
+ };
138
+ const onRejected = (error) => {
139
+ observer.error(error);
140
+ };
141
+ thing.then(onFulfilled, onRejected);
142
+ });
143
+ }
144
+ else {
145
+ return super.from(thing);
146
+ }
147
+ }
148
+ }
149
+ exports.ObservablePromise = ObservablePromise;
150
+ _a = Symbol.toStringTag;
@@ -0,0 +1,19 @@
1
+ import { Observable, ObservableLike } from "observable-fns";
2
+ export { Observable };
3
+ declare const $observers: unique symbol;
4
+ /**
5
+ * Observable subject. Implements the Observable interface, but also exposes
6
+ * the `next()`, `error()`, `complete()` methods to initiate observable
7
+ * updates "from the outside".
8
+ *
9
+ * Use `Observable.from(subject)` to derive an observable that proxies all
10
+ * values, errors and the completion raised on this subject, but does not
11
+ * expose the `next()`, `error()`, `complete()` methods.
12
+ */
13
+ export declare class Subject<T> extends Observable<T> implements ObservableLike<T> {
14
+ private [$observers];
15
+ constructor();
16
+ complete(): void;
17
+ error(error: any): void;
18
+ next(value: T): void;
19
+ }
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Subject = exports.Observable = void 0;
4
+ const observable_fns_1 = require("observable-fns");
5
+ Object.defineProperty(exports, "Observable", { enumerable: true, get: function () { return observable_fns_1.Observable; } });
6
+ const $observers = Symbol("observers");
7
+ /**
8
+ * Observable subject. Implements the Observable interface, but also exposes
9
+ * the `next()`, `error()`, `complete()` methods to initiate observable
10
+ * updates "from the outside".
11
+ *
12
+ * Use `Observable.from(subject)` to derive an observable that proxies all
13
+ * values, errors and the completion raised on this subject, but does not
14
+ * expose the `next()`, `error()`, `complete()` methods.
15
+ */
16
+ class Subject extends observable_fns_1.Observable {
17
+ constructor() {
18
+ super(observer => {
19
+ this[$observers] = [
20
+ ...(this[$observers] || []),
21
+ observer
22
+ ];
23
+ const unsubscribe = () => {
24
+ this[$observers] = this[$observers].filter(someObserver => someObserver !== observer);
25
+ };
26
+ return unsubscribe;
27
+ });
28
+ this[$observers] = [];
29
+ }
30
+ complete() {
31
+ this[$observers].forEach(observer => observer.complete());
32
+ }
33
+ error(error) {
34
+ this[$observers].forEach(observer => observer.error(error));
35
+ }
36
+ next(value) {
37
+ this[$observers].forEach(observer => observer.next(value));
38
+ }
39
+ }
40
+ exports.Subject = Subject;
@@ -0,0 +1,8 @@
1
+ export type SettlementResult<T> = {
2
+ status: "fulfilled";
3
+ value: T;
4
+ } | {
5
+ status: "rejected";
6
+ reason: any;
7
+ };
8
+ export declare function allSettled<T>(values: T[]): Promise<Array<SettlementResult<T>>>;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.allSettled = allSettled;
4
+ // Based on <https://github.com/es-shims/Promise.allSettled/blob/master/implementation.js>
5
+ function allSettled(values) {
6
+ return Promise.all(values.map(item => {
7
+ const onFulfill = (value) => {
8
+ return { status: 'fulfilled', value };
9
+ };
10
+ const onReject = (reason) => {
11
+ return { status: 'rejected', reason };
12
+ };
13
+ const itemPromise = Promise.resolve(item);
14
+ try {
15
+ return itemPromise.then(onFulfill, onReject);
16
+ }
17
+ catch (error) {
18
+ return Promise.reject(error);
19
+ }
20
+ }));
21
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Creates a new promise and exposes its resolver function.
3
+ * Use with care!
4
+ */
5
+ export declare function createPromiseWithResolver<T>(): [Promise<T>, (result: T) => void];
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createPromiseWithResolver = createPromiseWithResolver;
4
+ const doNothing = () => undefined;
5
+ /**
6
+ * Creates a new promise and exposes its resolver function.
7
+ * Use with care!
8
+ */
9
+ function createPromiseWithResolver() {
10
+ let alreadyResolved = false;
11
+ let resolvedTo;
12
+ let resolver = doNothing;
13
+ const promise = new Promise(resolve => {
14
+ if (alreadyResolved) {
15
+ resolve(resolvedTo);
16
+ }
17
+ else {
18
+ resolver = resolve;
19
+ }
20
+ });
21
+ const exposedResolver = (value) => {
22
+ alreadyResolved = true;
23
+ resolvedTo = value;
24
+ resolver(resolvedTo);
25
+ };
26
+ return [promise, exposedResolver];
27
+ }
@@ -0,0 +1,16 @@
1
+ export interface Serializer<Msg = JsonSerializable, Input = any> {
2
+ deserialize(message: Msg): Input;
3
+ serialize(input: Input): Msg;
4
+ }
5
+ export interface SerializerImplementation<Msg = JsonSerializable, Input = any> {
6
+ deserialize(message: Msg, defaultDeserialize: ((msg: Msg) => Input)): Input;
7
+ serialize(input: Input, defaultSerialize: ((inp: Input) => Msg)): Msg;
8
+ }
9
+ export declare function extendSerializer<MessageType, InputType = any>(extend: Serializer<MessageType, InputType>, implementation: SerializerImplementation<MessageType, InputType>): Serializer<MessageType, InputType>;
10
+ type JsonSerializablePrimitive = string | number | boolean | null;
11
+ type JsonSerializableObject = {
12
+ [key: string]: JsonSerializablePrimitive | JsonSerializablePrimitive[] | JsonSerializableObject | JsonSerializableObject[] | undefined;
13
+ };
14
+ export type JsonSerializable = JsonSerializablePrimitive | JsonSerializablePrimitive[] | JsonSerializableObject | JsonSerializableObject[];
15
+ export declare const DefaultSerializer: Serializer<JsonSerializable>;
16
+ export {};
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DefaultSerializer = void 0;
4
+ exports.extendSerializer = extendSerializer;
5
+ function extendSerializer(extend, implementation) {
6
+ const fallbackDeserializer = extend.deserialize.bind(extend);
7
+ const fallbackSerializer = extend.serialize.bind(extend);
8
+ return {
9
+ deserialize(message) {
10
+ return implementation.deserialize(message, fallbackDeserializer);
11
+ },
12
+ serialize(input) {
13
+ return implementation.serialize(input, fallbackSerializer);
14
+ }
15
+ };
16
+ }
17
+ const DefaultErrorSerializer = {
18
+ deserialize(message) {
19
+ return Object.assign(Error(message.message), {
20
+ name: message.name,
21
+ stack: message.stack
22
+ });
23
+ },
24
+ serialize(error) {
25
+ return {
26
+ __error_marker: "$$error",
27
+ message: error.message,
28
+ name: error.name,
29
+ stack: error.stack
30
+ };
31
+ }
32
+ };
33
+ const isSerializedError = (thing) => thing && typeof thing === "object" && "__error_marker" in thing && thing.__error_marker === "$$error";
34
+ exports.DefaultSerializer = {
35
+ deserialize(message) {
36
+ if (isSerializedError(message)) {
37
+ return DefaultErrorSerializer.deserialize(message);
38
+ }
39
+ else {
40
+ return message;
41
+ }
42
+ },
43
+ serialize(input) {
44
+ if (input instanceof Error) {
45
+ return DefaultErrorSerializer.serialize(input);
46
+ }
47
+ else {
48
+ return input;
49
+ }
50
+ }
51
+ };
@@ -0,0 +1,5 @@
1
+ export declare const $errors: unique symbol;
2
+ export declare const $events: unique symbol;
3
+ export declare const $terminate: unique symbol;
4
+ export declare const $transferable: unique symbol;
5
+ export declare const $worker: unique symbol;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.$worker = exports.$transferable = exports.$terminate = exports.$events = exports.$errors = void 0;
4
+ exports.$errors = Symbol("thread.errors");
5
+ exports.$events = Symbol("thread.events");
6
+ exports.$terminate = Symbol("thread.terminate");
7
+ exports.$transferable = Symbol("thread.transferable");
8
+ exports.$worker = Symbol("thread.worker");
@@ -0,0 +1,42 @@
1
+ import { $transferable } from "./symbols";
2
+ export interface TransferDescriptor<T = any> {
3
+ [$transferable]: true;
4
+ send: T;
5
+ transferables: Transferable[];
6
+ }
7
+ export declare function isTransferDescriptor(thing: any): thing is TransferDescriptor;
8
+ /**
9
+ * Mark a transferable object as such, so it will no be serialized and
10
+ * deserialized on messaging with the main thread, but to transfer
11
+ * ownership of it to the receiving thread.
12
+ *
13
+ * Only works with array buffers, message ports and few more special
14
+ * types of objects, but it's much faster than serializing and
15
+ * deserializing them.
16
+ *
17
+ * Note:
18
+ * The transferable object cannot be accessed by this thread again
19
+ * unless the receiving thread transfers it back again!
20
+ *
21
+ * @param transferable Array buffer, message port or similar.
22
+ * @see <https://developers.google.com/web/updates/2011/12/Transferable-Objects-Lightning-Fast>
23
+ */
24
+ export declare function Transfer(transferable: Transferable): TransferDescriptor;
25
+ /**
26
+ * Mark transferable objects within an arbitrary object or array as
27
+ * being a transferable object. They will then not be serialized
28
+ * and deserialized on messaging with the main thread, but ownership
29
+ * of them will be tranferred to the receiving thread.
30
+ *
31
+ * Only array buffers, message ports and few more special types of
32
+ * objects can be transferred, but it's much faster than serializing and
33
+ * deserializing them.
34
+ *
35
+ * Note:
36
+ * The transferable object cannot be accessed by this thread again
37
+ * unless the receiving thread transfers it back again!
38
+ *
39
+ * @param transferable Array buffer, message port or similar.
40
+ * @see <https://developers.google.com/web/updates/2011/12/Transferable-Objects-Lightning-Fast>
41
+ */
42
+ export declare function Transfer<T>(payload: T, transferables: Transferable[]): TransferDescriptor;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isTransferDescriptor = isTransferDescriptor;
4
+ exports.Transfer = Transfer;
5
+ const symbols_1 = require("./symbols");
6
+ function isTransferable(thing) {
7
+ if (!thing || typeof thing !== "object")
8
+ return false;
9
+ // Don't check too thoroughly, since the list of transferable things in JS might grow over time
10
+ return true;
11
+ }
12
+ function isTransferDescriptor(thing) {
13
+ return thing && typeof thing === "object" && thing[symbols_1.$transferable];
14
+ }
15
+ function Transfer(payload, transferables) {
16
+ if (!transferables) {
17
+ if (!isTransferable(payload))
18
+ throw Error();
19
+ transferables = [payload];
20
+ }
21
+ return {
22
+ [symbols_1.$transferable]: true,
23
+ send: payload,
24
+ transferables
25
+ };
26
+ }