@ariestools/threads 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +946 -0
- package/dist/browser/common.d.ts +22 -0
- package/dist/browser/common.d.ts.map +1 -0
- package/dist/browser/index-browser.d.ts +9 -0
- package/dist/browser/index-browser.d.ts.map +1 -0
- package/dist/browser/index-browser.mjs +844 -0
- package/dist/browser/index-browser.mjs.map +7 -0
- package/dist/browser/index-node.d.ts +9 -0
- package/dist/browser/index-node.d.ts.map +1 -0
- package/dist/browser/isObservable.d.ts +2 -0
- package/dist/browser/isObservable.d.ts.map +1 -0
- package/dist/browser/master/get-bundle-url.browser.d.ts +4 -0
- package/dist/browser/master/get-bundle-url.browser.d.ts.map +1 -0
- package/dist/browser/master/implementation.browser.d.ts +14 -0
- package/dist/browser/master/implementation.browser.d.ts.map +1 -0
- package/dist/browser/master/implementation.browser.mjs +90 -0
- package/dist/browser/master/implementation.browser.mjs.map +7 -0
- package/dist/browser/master/implementation.node.d.ts +14 -0
- package/dist/browser/master/implementation.node.d.ts.map +1 -0
- package/dist/browser/master/index-browser.d.ts +13 -0
- package/dist/browser/master/index-browser.d.ts.map +1 -0
- package/dist/browser/master/index-browser.mjs +813 -0
- package/dist/browser/master/index-browser.mjs.map +7 -0
- package/dist/browser/master/index-node.d.ts +13 -0
- package/dist/browser/master/index-node.d.ts.map +1 -0
- package/dist/browser/master/invocation-proxy.d.ts +16 -0
- package/dist/browser/master/invocation-proxy.d.ts.map +1 -0
- package/dist/browser/master/pool-browser.d.ts +93 -0
- package/dist/browser/master/pool-browser.d.ts.map +1 -0
- package/dist/browser/master/pool-browser.mjs +308 -0
- package/dist/browser/master/pool-browser.mjs.map +7 -0
- package/dist/browser/master/pool-node.d.ts +93 -0
- package/dist/browser/master/pool-node.d.ts.map +1 -0
- package/dist/browser/master/pool-types.d.ts +68 -0
- package/dist/browser/master/pool-types.d.ts.map +1 -0
- package/dist/browser/master/register.d.ts +2 -0
- package/dist/browser/master/register.d.ts.map +1 -0
- package/dist/browser/master/spawn.d.ts +22 -0
- package/dist/browser/master/spawn.d.ts.map +1 -0
- package/dist/browser/master/thread.d.ts +14 -0
- package/dist/browser/master/thread.d.ts.map +1 -0
- package/dist/browser/observable-promise.d.ts +41 -0
- package/dist/browser/observable-promise.d.ts.map +1 -0
- package/dist/browser/observable.d.ts +24 -0
- package/dist/browser/observable.d.ts.map +1 -0
- package/dist/browser/promise.d.ts +6 -0
- package/dist/browser/promise.d.ts.map +1 -0
- package/dist/browser/serializers.d.ts +27 -0
- package/dist/browser/serializers.d.ts.map +1 -0
- package/dist/browser/symbols.d.ts +11 -0
- package/dist/browser/symbols.d.ts.map +1 -0
- package/dist/browser/transferable.d.ts +49 -0
- package/dist/browser/transferable.d.ts.map +1 -0
- package/dist/browser/types/master.d.ts +111 -0
- package/dist/browser/types/master.d.ts.map +1 -0
- package/dist/browser/types/messages.d.ts +71 -0
- package/dist/browser/types/messages.d.ts.map +1 -0
- package/dist/browser/types/worker.d.ts +13 -0
- package/dist/browser/types/worker.d.ts.map +1 -0
- package/dist/browser/worker/WorkerGlobalScope.d.ts +7 -0
- package/dist/browser/worker/WorkerGlobalScope.d.ts.map +1 -0
- package/dist/browser/worker/expose.d.ts +10 -0
- package/dist/browser/worker/expose.d.ts.map +1 -0
- package/dist/browser/worker/worker.browser.d.ts +20 -0
- package/dist/browser/worker/worker.browser.d.ts.map +1 -0
- package/dist/browser/worker/worker.browser.mjs +300 -0
- package/dist/browser/worker/worker.browser.mjs.map +7 -0
- package/dist/browser/worker/worker.node.d.ts +34 -0
- package/dist/browser/worker/worker.node.d.ts.map +1 -0
- package/dist/neutral/common.d.ts +22 -0
- package/dist/neutral/common.d.ts.map +1 -0
- package/dist/neutral/index-browser.d.ts +9 -0
- package/dist/neutral/index-browser.d.ts.map +1 -0
- package/dist/neutral/index-node.d.ts +9 -0
- package/dist/neutral/index-node.d.ts.map +1 -0
- package/dist/neutral/isObservable.d.ts +2 -0
- package/dist/neutral/isObservable.d.ts.map +1 -0
- package/dist/neutral/master/get-bundle-url.browser.d.ts +4 -0
- package/dist/neutral/master/get-bundle-url.browser.d.ts.map +1 -0
- package/dist/neutral/master/implementation.browser.d.ts +14 -0
- package/dist/neutral/master/implementation.browser.d.ts.map +1 -0
- package/dist/neutral/master/implementation.node.d.ts +14 -0
- package/dist/neutral/master/implementation.node.d.ts.map +1 -0
- package/dist/neutral/master/index-browser.d.ts +13 -0
- package/dist/neutral/master/index-browser.d.ts.map +1 -0
- package/dist/neutral/master/index-node.d.ts +13 -0
- package/dist/neutral/master/index-node.d.ts.map +1 -0
- package/dist/neutral/master/invocation-proxy.d.ts +16 -0
- package/dist/neutral/master/invocation-proxy.d.ts.map +1 -0
- package/dist/neutral/master/pool-browser.d.ts +93 -0
- package/dist/neutral/master/pool-browser.d.ts.map +1 -0
- package/dist/neutral/master/pool-node.d.ts +93 -0
- package/dist/neutral/master/pool-node.d.ts.map +1 -0
- package/dist/neutral/master/pool-types.d.ts +68 -0
- package/dist/neutral/master/pool-types.d.ts.map +1 -0
- package/dist/neutral/master/register.d.ts +2 -0
- package/dist/neutral/master/register.d.ts.map +1 -0
- package/dist/neutral/master/spawn.d.ts +22 -0
- package/dist/neutral/master/spawn.d.ts.map +1 -0
- package/dist/neutral/master/spawn.mjs +424 -0
- package/dist/neutral/master/spawn.mjs.map +7 -0
- package/dist/neutral/master/thread.d.ts +14 -0
- package/dist/neutral/master/thread.d.ts.map +1 -0
- package/dist/neutral/master/thread.mjs +24 -0
- package/dist/neutral/master/thread.mjs.map +7 -0
- package/dist/neutral/observable-promise.d.ts +41 -0
- package/dist/neutral/observable-promise.d.ts.map +1 -0
- package/dist/neutral/observable-promise.mjs +142 -0
- package/dist/neutral/observable-promise.mjs.map +7 -0
- package/dist/neutral/observable.d.ts +24 -0
- package/dist/neutral/observable.d.ts.map +1 -0
- package/dist/neutral/observable.mjs +32 -0
- package/dist/neutral/observable.mjs.map +7 -0
- package/dist/neutral/promise.d.ts +6 -0
- package/dist/neutral/promise.d.ts.map +1 -0
- package/dist/neutral/serializers.d.ts +27 -0
- package/dist/neutral/serializers.d.ts.map +1 -0
- package/dist/neutral/symbols.d.ts +11 -0
- package/dist/neutral/symbols.d.ts.map +1 -0
- package/dist/neutral/transferable.d.ts +49 -0
- package/dist/neutral/transferable.d.ts.map +1 -0
- package/dist/neutral/types/master.d.ts +111 -0
- package/dist/neutral/types/master.d.ts.map +1 -0
- package/dist/neutral/types/messages.d.ts +71 -0
- package/dist/neutral/types/messages.d.ts.map +1 -0
- package/dist/neutral/types/messages.mjs +19 -0
- package/dist/neutral/types/messages.mjs.map +7 -0
- package/dist/neutral/types/worker.d.ts +13 -0
- package/dist/neutral/types/worker.d.ts.map +1 -0
- package/dist/neutral/worker/WorkerGlobalScope.d.ts +7 -0
- package/dist/neutral/worker/WorkerGlobalScope.d.ts.map +1 -0
- package/dist/neutral/worker/expose.d.ts +10 -0
- package/dist/neutral/worker/expose.d.ts.map +1 -0
- package/dist/neutral/worker/worker.browser.d.ts +20 -0
- package/dist/neutral/worker/worker.browser.d.ts.map +1 -0
- package/dist/neutral/worker/worker.node.d.ts +34 -0
- package/dist/neutral/worker/worker.node.d.ts.map +1 -0
- package/dist/node/common.d.ts +22 -0
- package/dist/node/common.d.ts.map +1 -0
- package/dist/node/index-browser.d.ts +9 -0
- package/dist/node/index-browser.d.ts.map +1 -0
- package/dist/node/index-node.d.ts +9 -0
- package/dist/node/index-node.d.ts.map +1 -0
- package/dist/node/index-node.mjs +839 -0
- package/dist/node/index-node.mjs.map +7 -0
- package/dist/node/isObservable.d.ts +2 -0
- package/dist/node/isObservable.d.ts.map +1 -0
- package/dist/node/master/get-bundle-url.browser.d.ts +4 -0
- package/dist/node/master/get-bundle-url.browser.d.ts.map +1 -0
- package/dist/node/master/implementation.browser.d.ts +14 -0
- package/dist/node/master/implementation.browser.d.ts.map +1 -0
- package/dist/node/master/implementation.node.d.ts +14 -0
- package/dist/node/master/implementation.node.d.ts.map +1 -0
- package/dist/node/master/implementation.node.mjs +82 -0
- package/dist/node/master/implementation.node.mjs.map +7 -0
- package/dist/node/master/index-browser.d.ts +13 -0
- package/dist/node/master/index-browser.d.ts.map +1 -0
- package/dist/node/master/index-node.d.ts +13 -0
- package/dist/node/master/index-node.d.ts.map +1 -0
- package/dist/node/master/index-node.mjs +808 -0
- package/dist/node/master/index-node.mjs.map +7 -0
- package/dist/node/master/invocation-proxy.d.ts +16 -0
- package/dist/node/master/invocation-proxy.d.ts.map +1 -0
- package/dist/node/master/pool-browser.d.ts +93 -0
- package/dist/node/master/pool-browser.d.ts.map +1 -0
- package/dist/node/master/pool-node.d.ts +93 -0
- package/dist/node/master/pool-node.d.ts.map +1 -0
- package/dist/node/master/pool-node.mjs +309 -0
- package/dist/node/master/pool-node.mjs.map +7 -0
- package/dist/node/master/pool-types.d.ts +68 -0
- package/dist/node/master/pool-types.d.ts.map +1 -0
- package/dist/node/master/register.d.ts +2 -0
- package/dist/node/master/register.d.ts.map +1 -0
- package/dist/node/master/register.mjs +87 -0
- package/dist/node/master/register.mjs.map +7 -0
- package/dist/node/master/spawn.d.ts +22 -0
- package/dist/node/master/spawn.d.ts.map +1 -0
- package/dist/node/master/thread.d.ts +14 -0
- package/dist/node/master/thread.d.ts.map +1 -0
- package/dist/node/observable-promise.d.ts +41 -0
- package/dist/node/observable-promise.d.ts.map +1 -0
- package/dist/node/observable.d.ts +24 -0
- package/dist/node/observable.d.ts.map +1 -0
- package/dist/node/promise.d.ts +6 -0
- package/dist/node/promise.d.ts.map +1 -0
- package/dist/node/serializers.d.ts +27 -0
- package/dist/node/serializers.d.ts.map +1 -0
- package/dist/node/symbols.d.ts +11 -0
- package/dist/node/symbols.d.ts.map +1 -0
- package/dist/node/transferable.d.ts +49 -0
- package/dist/node/transferable.d.ts.map +1 -0
- package/dist/node/types/master.d.ts +111 -0
- package/dist/node/types/master.d.ts.map +1 -0
- package/dist/node/types/messages.d.ts +71 -0
- package/dist/node/types/messages.d.ts.map +1 -0
- package/dist/node/types/worker.d.ts +13 -0
- package/dist/node/types/worker.d.ts.map +1 -0
- package/dist/node/worker/WorkerGlobalScope.d.ts +7 -0
- package/dist/node/worker/WorkerGlobalScope.d.ts.map +1 -0
- package/dist/node/worker/expose.d.ts +10 -0
- package/dist/node/worker/expose.d.ts.map +1 -0
- package/dist/node/worker/worker.browser.d.ts +20 -0
- package/dist/node/worker/worker.browser.d.ts.map +1 -0
- package/dist/node/worker/worker.node.d.ts +34 -0
- package/dist/node/worker/worker.node.d.ts.map +1 -0
- package/dist/node/worker/worker.node.mjs +313 -0
- package/dist/node/worker/worker.node.mjs.map +7 -0
- package/package.json +147 -0
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
// src/master/spawn.ts
|
|
2
|
+
import DebugLogger2 from "debug";
|
|
3
|
+
import { Observable as Observable3 } from "observable-fns";
|
|
4
|
+
|
|
5
|
+
// src/serializers.ts
|
|
6
|
+
var DefaultErrorSerializer = {
|
|
7
|
+
deserialize: (message) => {
|
|
8
|
+
const error = Object.create(Error.prototype);
|
|
9
|
+
error.message = message.message;
|
|
10
|
+
error.name = message.name;
|
|
11
|
+
error.stack = message.stack;
|
|
12
|
+
return error;
|
|
13
|
+
},
|
|
14
|
+
serialize: (error) => ({
|
|
15
|
+
__error_marker: "$$error",
|
|
16
|
+
message: error.message,
|
|
17
|
+
name: error.name,
|
|
18
|
+
stack: error.stack
|
|
19
|
+
})
|
|
20
|
+
};
|
|
21
|
+
var isSerializedError = (thing) => thing != null && typeof thing === "object" && "__error_marker" in thing && thing.__error_marker === "$$error";
|
|
22
|
+
var DefaultSerializer = {
|
|
23
|
+
deserialize: (message) => isSerializedError(message) ? DefaultErrorSerializer.deserialize(message) : message,
|
|
24
|
+
serialize: (input) => input instanceof Error ? DefaultErrorSerializer.serialize(input) : input
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// src/common.ts
|
|
28
|
+
globalThis.registeredSerializer = globalThis.registeredSerializer ?? DefaultSerializer;
|
|
29
|
+
function deserialize(message) {
|
|
30
|
+
return globalThis.registeredSerializer.deserialize(message);
|
|
31
|
+
}
|
|
32
|
+
function serialize(input) {
|
|
33
|
+
return globalThis.registeredSerializer.serialize(input);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// src/promise.ts
|
|
37
|
+
var doNothing = () => void 0;
|
|
38
|
+
function createPromiseWithResolver() {
|
|
39
|
+
let alreadyResolved = false;
|
|
40
|
+
let resolvedTo;
|
|
41
|
+
let resolver = doNothing;
|
|
42
|
+
const promise = new Promise((resolve) => {
|
|
43
|
+
if (alreadyResolved) {
|
|
44
|
+
resolve(resolvedTo);
|
|
45
|
+
} else {
|
|
46
|
+
resolver = resolve;
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
const exposedResolver = (value) => {
|
|
50
|
+
alreadyResolved = true;
|
|
51
|
+
resolvedTo = value;
|
|
52
|
+
resolver(resolvedTo);
|
|
53
|
+
};
|
|
54
|
+
return [promise, exposedResolver];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// src/symbols.ts
|
|
58
|
+
var $errors = /* @__PURE__ */ Symbol("thread.errors");
|
|
59
|
+
var $events = /* @__PURE__ */ Symbol("thread.events");
|
|
60
|
+
var $terminate = /* @__PURE__ */ Symbol("thread.terminate");
|
|
61
|
+
var $transferable = /* @__PURE__ */ Symbol("thread.transferable");
|
|
62
|
+
var $worker = /* @__PURE__ */ Symbol("thread.worker");
|
|
63
|
+
|
|
64
|
+
// src/master/invocation-proxy.ts
|
|
65
|
+
import DebugLogger from "debug";
|
|
66
|
+
import { multicast, Observable as Observable2 } from "observable-fns";
|
|
67
|
+
|
|
68
|
+
// src/observable-promise.ts
|
|
69
|
+
import { Observable } from "observable-fns";
|
|
70
|
+
var doNothing2 = () => {
|
|
71
|
+
};
|
|
72
|
+
var returnInput = (input) => input;
|
|
73
|
+
var runDeferred = (fn) => {
|
|
74
|
+
void (async () => {
|
|
75
|
+
await Promise.resolve();
|
|
76
|
+
fn();
|
|
77
|
+
})();
|
|
78
|
+
};
|
|
79
|
+
function fail(error) {
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
function isThenable(thing) {
|
|
83
|
+
return thing != null && typeof thing.then === "function";
|
|
84
|
+
}
|
|
85
|
+
var ObservablePromise = class _ObservablePromise extends Observable {
|
|
86
|
+
[Symbol.toStringTag] = "[object ObservablePromise]";
|
|
87
|
+
initHasRun = false;
|
|
88
|
+
fulfillmentCallbacks = [];
|
|
89
|
+
rejectionCallbacks = [];
|
|
90
|
+
firstValue;
|
|
91
|
+
firstValueSet = false;
|
|
92
|
+
rejection;
|
|
93
|
+
state = "pending";
|
|
94
|
+
constructor(init) {
|
|
95
|
+
super((originalObserver) => {
|
|
96
|
+
const self = this;
|
|
97
|
+
const observer = {
|
|
98
|
+
...originalObserver,
|
|
99
|
+
complete() {
|
|
100
|
+
originalObserver.complete();
|
|
101
|
+
self.onCompletion();
|
|
102
|
+
},
|
|
103
|
+
error(error) {
|
|
104
|
+
originalObserver.error(error);
|
|
105
|
+
self.onError(error);
|
|
106
|
+
},
|
|
107
|
+
next(value) {
|
|
108
|
+
originalObserver.next(value);
|
|
109
|
+
self.onNext(value);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
try {
|
|
113
|
+
this.initHasRun = true;
|
|
114
|
+
return init(observer);
|
|
115
|
+
} catch (error) {
|
|
116
|
+
observer.error(error);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
onNext(value) {
|
|
121
|
+
if (this.firstValueSet) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
this.firstValue = value;
|
|
125
|
+
this.firstValueSet = true;
|
|
126
|
+
}
|
|
127
|
+
onError(error) {
|
|
128
|
+
this.state = "rejected";
|
|
129
|
+
this.rejection = error;
|
|
130
|
+
for (const onRejected of this.rejectionCallbacks) {
|
|
131
|
+
runDeferred(() => onRejected(error));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
onCompletion() {
|
|
135
|
+
this.state = "fulfilled";
|
|
136
|
+
for (const onFulfilled of this.fulfillmentCallbacks) {
|
|
137
|
+
runDeferred(() => onFulfilled(this.firstValue));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
createPromise(onFulfilledRaw, onRejectedRaw) {
|
|
141
|
+
const onFulfilled = onFulfilledRaw || returnInput;
|
|
142
|
+
const onRejected = onRejectedRaw || fail;
|
|
143
|
+
let onRejectedCalled = false;
|
|
144
|
+
return new Promise((resolve, reject) => {
|
|
145
|
+
const rejectionCallback = (error) => {
|
|
146
|
+
if (onRejectedCalled) return;
|
|
147
|
+
onRejectedCalled = true;
|
|
148
|
+
try {
|
|
149
|
+
resolve(onRejected(error));
|
|
150
|
+
} catch (anotherError) {
|
|
151
|
+
reject(anotherError);
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
const fulfillmentCallback = (value) => {
|
|
155
|
+
try {
|
|
156
|
+
resolve(onFulfilled(value));
|
|
157
|
+
} catch (ex) {
|
|
158
|
+
const error = ex;
|
|
159
|
+
rejectionCallback(error);
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
if (!this.initHasRun) {
|
|
163
|
+
this.subscribe({ error: rejectionCallback });
|
|
164
|
+
}
|
|
165
|
+
if (this.state === "fulfilled") {
|
|
166
|
+
return resolve(onFulfilled(this.firstValue));
|
|
167
|
+
}
|
|
168
|
+
if (this.state === "rejected") {
|
|
169
|
+
onRejectedCalled = true;
|
|
170
|
+
return resolve(onRejected(this.rejection));
|
|
171
|
+
}
|
|
172
|
+
this.fulfillmentCallbacks.push(fulfillmentCallback);
|
|
173
|
+
this.rejectionCallbacks.push(rejectionCallback);
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
then(onFulfilledRaw, onRejectedRaw) {
|
|
177
|
+
return this.createPromise(onFulfilledRaw, onRejectedRaw);
|
|
178
|
+
}
|
|
179
|
+
catch(onRejected) {
|
|
180
|
+
return this.createPromise(void 0, onRejected);
|
|
181
|
+
}
|
|
182
|
+
finally(onCompleted) {
|
|
183
|
+
const handler = onCompleted || doNothing2;
|
|
184
|
+
return this.createPromise(
|
|
185
|
+
(value) => {
|
|
186
|
+
handler();
|
|
187
|
+
return value;
|
|
188
|
+
},
|
|
189
|
+
() => handler()
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
static from(thing) {
|
|
193
|
+
return isThenable(thing) ? new _ObservablePromise((observer) => {
|
|
194
|
+
void (async () => {
|
|
195
|
+
try {
|
|
196
|
+
const value = await thing;
|
|
197
|
+
observer.next(value);
|
|
198
|
+
observer.complete();
|
|
199
|
+
} catch (error) {
|
|
200
|
+
observer.error(error);
|
|
201
|
+
}
|
|
202
|
+
})();
|
|
203
|
+
}) : super.from(thing);
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
// src/transferable.ts
|
|
208
|
+
function isTransferDescriptor(thing) {
|
|
209
|
+
return thing != null && typeof thing === "object" && Reflect.get(thing, $transferable) === true;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// src/master/invocation-proxy.ts
|
|
213
|
+
var debugMessages = DebugLogger("threads:master:messages");
|
|
214
|
+
var nextJobUID = 1;
|
|
215
|
+
var dedupe = (array) => [...new Set(array)];
|
|
216
|
+
var isJobErrorMessage = (data) => data?.type === "error" /* error */;
|
|
217
|
+
var isJobResultMessage = (data) => data?.type === "result" /* result */;
|
|
218
|
+
var isJobStartMessage = (data) => data?.type === "running" /* running */;
|
|
219
|
+
function createObservableForJob(worker, jobUID) {
|
|
220
|
+
return new Observable2((observer) => {
|
|
221
|
+
let asyncType;
|
|
222
|
+
const messageHandler = ((event) => {
|
|
223
|
+
debugMessages("Message from worker:", event.data);
|
|
224
|
+
if (event.data?.uid !== jobUID) return;
|
|
225
|
+
if (isJobStartMessage(event.data)) {
|
|
226
|
+
asyncType = event.data.resultType;
|
|
227
|
+
} else if (isJobResultMessage(event.data)) {
|
|
228
|
+
if (asyncType === "promise") {
|
|
229
|
+
if (event.data.payload !== void 0) {
|
|
230
|
+
observer.next(deserialize(event.data.payload));
|
|
231
|
+
}
|
|
232
|
+
observer.complete();
|
|
233
|
+
worker.removeEventListener("message", messageHandler);
|
|
234
|
+
} else {
|
|
235
|
+
if (event.data.payload !== void 0) {
|
|
236
|
+
observer.next(deserialize(event.data.payload));
|
|
237
|
+
}
|
|
238
|
+
if (event.data.complete) {
|
|
239
|
+
observer.complete();
|
|
240
|
+
worker.removeEventListener("message", messageHandler);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
} else if (isJobErrorMessage(event.data)) {
|
|
244
|
+
const error = deserialize(event.data.error);
|
|
245
|
+
if (asyncType === "promise" || asyncType === void 0) {
|
|
246
|
+
observer.error(error);
|
|
247
|
+
} else {
|
|
248
|
+
observer.error(error);
|
|
249
|
+
}
|
|
250
|
+
worker.removeEventListener("message", messageHandler);
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
worker.addEventListener("message", messageHandler);
|
|
254
|
+
return () => {
|
|
255
|
+
if (asyncType === "observable" || asyncType === void 0) {
|
|
256
|
+
const cancelMessage = {
|
|
257
|
+
type: "cancel" /* cancel */,
|
|
258
|
+
uid: jobUID
|
|
259
|
+
};
|
|
260
|
+
worker.postMessage(cancelMessage);
|
|
261
|
+
}
|
|
262
|
+
worker.removeEventListener("message", messageHandler);
|
|
263
|
+
};
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
function prepareArguments(rawArgs) {
|
|
267
|
+
if (rawArgs.length === 0) {
|
|
268
|
+
return {
|
|
269
|
+
args: [],
|
|
270
|
+
transferables: []
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
const args = [];
|
|
274
|
+
const transferables = [];
|
|
275
|
+
for (const arg of rawArgs) {
|
|
276
|
+
if (isTransferDescriptor(arg)) {
|
|
277
|
+
args.push(serialize(arg.send));
|
|
278
|
+
transferables.push(...arg.transferables);
|
|
279
|
+
} else {
|
|
280
|
+
args.push(serialize(arg));
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return {
|
|
284
|
+
args,
|
|
285
|
+
transferables: transferables.length === 0 ? transferables : dedupe(transferables)
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
function createProxyFunction(worker, method) {
|
|
289
|
+
return ((...rawArgs) => {
|
|
290
|
+
const uid = nextJobUID++;
|
|
291
|
+
const { args, transferables } = prepareArguments(rawArgs);
|
|
292
|
+
const runMessage = {
|
|
293
|
+
args,
|
|
294
|
+
method,
|
|
295
|
+
type: "run" /* run */,
|
|
296
|
+
uid
|
|
297
|
+
};
|
|
298
|
+
debugMessages("Sending command to run function to worker:", runMessage);
|
|
299
|
+
try {
|
|
300
|
+
worker.postMessage(runMessage, transferables);
|
|
301
|
+
} catch (error) {
|
|
302
|
+
return ObservablePromise.from(Promise.reject(error));
|
|
303
|
+
}
|
|
304
|
+
return ObservablePromise.from(multicast(createObservableForJob(worker, uid)));
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
function createProxyModule(worker, methodNames) {
|
|
308
|
+
const proxy = {};
|
|
309
|
+
for (const methodName of methodNames) {
|
|
310
|
+
proxy[methodName] = createProxyFunction(worker, methodName);
|
|
311
|
+
}
|
|
312
|
+
return proxy;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// src/master/spawn.ts
|
|
316
|
+
var debugMessages2 = DebugLogger2("threads:master:messages");
|
|
317
|
+
var debugSpawn = DebugLogger2("threads:master:spawn");
|
|
318
|
+
var debugThreadUtils = DebugLogger2("threads:master:thread-utils");
|
|
319
|
+
var isInitMessage = (data) => data?.type === "init";
|
|
320
|
+
var isUncaughtErrorMessage = (data) => data?.type === "uncaughtError";
|
|
321
|
+
var workerInitTimeout = globalThis.process?.env?.THREADS_WORKER_INIT_TIMEOUT;
|
|
322
|
+
var initMessageTimeout = workerInitTimeout !== void 0 && workerInitTimeout !== "" ? Number(workerInitTimeout) : 1e4;
|
|
323
|
+
async function withTimeout(promise, timeoutInMs, errorMessage) {
|
|
324
|
+
let timeoutHandle;
|
|
325
|
+
const timeout = new Promise((resolve, reject) => {
|
|
326
|
+
timeoutHandle = setTimeout(() => reject(new Error(errorMessage)), timeoutInMs);
|
|
327
|
+
});
|
|
328
|
+
const result = await Promise.race([promise, timeout]);
|
|
329
|
+
clearTimeout(timeoutHandle);
|
|
330
|
+
return result;
|
|
331
|
+
}
|
|
332
|
+
function receiveInitMessage(worker) {
|
|
333
|
+
return new Promise((resolve, reject) => {
|
|
334
|
+
const messageHandler = ((event) => {
|
|
335
|
+
debugMessages2("Message from worker before finishing initialization:", event.data);
|
|
336
|
+
if (isInitMessage(event.data)) {
|
|
337
|
+
worker.removeEventListener("message", messageHandler);
|
|
338
|
+
resolve(event.data);
|
|
339
|
+
} else if (isUncaughtErrorMessage(event.data)) {
|
|
340
|
+
worker.removeEventListener("message", messageHandler);
|
|
341
|
+
reject(deserialize(event.data.error));
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
worker.addEventListener("message", messageHandler);
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
function createEventObservable(worker, workerTermination) {
|
|
348
|
+
return new Observable3((observer) => {
|
|
349
|
+
const messageHandler = ((messageEvent) => {
|
|
350
|
+
const workerEvent = {
|
|
351
|
+
data: messageEvent.data,
|
|
352
|
+
type: "message" /* message */
|
|
353
|
+
};
|
|
354
|
+
observer.next(workerEvent);
|
|
355
|
+
});
|
|
356
|
+
const rejectionHandler = ((errorEvent) => {
|
|
357
|
+
debugThreadUtils("Unhandled promise rejection event in thread:", errorEvent);
|
|
358
|
+
const workerEvent = {
|
|
359
|
+
error: new Error(errorEvent.reason),
|
|
360
|
+
type: "internalError" /* internalError */
|
|
361
|
+
};
|
|
362
|
+
observer.next(workerEvent);
|
|
363
|
+
});
|
|
364
|
+
worker.addEventListener("message", messageHandler);
|
|
365
|
+
worker.addEventListener("unhandledrejection", rejectionHandler);
|
|
366
|
+
void (async () => {
|
|
367
|
+
await workerTermination;
|
|
368
|
+
const terminationEvent = { type: "termination" /* termination */ };
|
|
369
|
+
worker.removeEventListener("message", messageHandler);
|
|
370
|
+
worker.removeEventListener("unhandledrejection", rejectionHandler);
|
|
371
|
+
observer.next(terminationEvent);
|
|
372
|
+
observer.complete();
|
|
373
|
+
})();
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
function createTerminator(worker) {
|
|
377
|
+
const [termination, resolver] = createPromiseWithResolver();
|
|
378
|
+
const terminate = async () => {
|
|
379
|
+
debugThreadUtils("Terminating worker");
|
|
380
|
+
await worker.terminate();
|
|
381
|
+
resolver();
|
|
382
|
+
};
|
|
383
|
+
return { terminate, termination };
|
|
384
|
+
}
|
|
385
|
+
function setPrivateThreadProps(raw, worker, workerEvents, terminate) {
|
|
386
|
+
const workerErrors = workerEvents.filter((event) => event.type === "internalError" /* internalError */).map((errorEvent) => errorEvent.error);
|
|
387
|
+
const result = raw;
|
|
388
|
+
const privateProps = [
|
|
389
|
+
[$errors, { enumerable: false, value: workerErrors }],
|
|
390
|
+
[$events, { enumerable: false, value: workerEvents }],
|
|
391
|
+
[$terminate, { enumerable: false, value: terminate }],
|
|
392
|
+
[$worker, { enumerable: false, value: worker }]
|
|
393
|
+
];
|
|
394
|
+
for (const [key, descriptor] of privateProps) {
|
|
395
|
+
Object.defineProperty(result, key, descriptor);
|
|
396
|
+
}
|
|
397
|
+
return result;
|
|
398
|
+
}
|
|
399
|
+
async function spawn(worker, options) {
|
|
400
|
+
debugSpawn("Initializing new thread");
|
|
401
|
+
const timeout = options?.timeout ?? initMessageTimeout;
|
|
402
|
+
const initMessage = await withTimeout(
|
|
403
|
+
receiveInitMessage(worker),
|
|
404
|
+
timeout,
|
|
405
|
+
`Timeout: Did not receive an init message from worker after ${timeout}ms. Make sure the worker calls expose().`
|
|
406
|
+
);
|
|
407
|
+
const exposed = initMessage.exposed;
|
|
408
|
+
const { termination, terminate } = createTerminator(worker);
|
|
409
|
+
const events = createEventObservable(worker, termination);
|
|
410
|
+
if (exposed.type === "function") {
|
|
411
|
+
const proxy = createProxyFunction(worker);
|
|
412
|
+
return setPrivateThreadProps(proxy, worker, events, terminate);
|
|
413
|
+
}
|
|
414
|
+
if (exposed.type === "module") {
|
|
415
|
+
const proxy = createProxyModule(worker, exposed.methods);
|
|
416
|
+
return setPrivateThreadProps(proxy, worker, events, terminate);
|
|
417
|
+
}
|
|
418
|
+
const type = exposed.type;
|
|
419
|
+
throw new Error(`Worker init message states unexpected type of expose(): ${type}`);
|
|
420
|
+
}
|
|
421
|
+
export {
|
|
422
|
+
spawn
|
|
423
|
+
};
|
|
424
|
+
//# sourceMappingURL=spawn.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/master/spawn.ts", "../../../src/serializers.ts", "../../../src/common.ts", "../../../src/promise.ts", "../../../src/symbols.ts", "../../../src/master/invocation-proxy.ts", "../../../src/observable-promise.ts", "../../../src/transferable.ts"],
|
|
4
|
+
"sourcesContent": ["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport DebugLogger from 'debug'\nimport { Observable } from 'observable-fns'\n\nimport { deserialize } from '../common.ts'\nimport { createPromiseWithResolver } from '../promise.ts'\nimport {\n $errors, $events, $terminate, $worker,\n} from '../symbols.ts'\nimport type {\n FunctionThread,\n ModuleThread,\n PrivateThreadProps,\n StripAsync,\n Worker as WorkerType,\n WorkerEvent,\n WorkerInternalErrorEvent,\n WorkerMessageEvent,\n WorkerTerminationEvent,\n} from '../types/master.ts'\nimport { WorkerEventType } from '../types/master.ts'\nimport type { WorkerInitMessage, WorkerUncaughtErrorMessage } from '../types/messages.ts'\nimport type { WorkerFunction, WorkerModule } from '../types/worker.ts'\nimport { createProxyFunction, createProxyModule } from './invocation-proxy.ts'\n\ntype ArbitraryWorkerInterface = WorkerFunction & WorkerModule<string> & { somekeythatisneverusedinproductioncode123: 'magicmarker123' }\ntype ArbitraryThreadType = FunctionThread<any, any> & ModuleThread<any>\n\ninterface ProcessEnvGlobal {\n process?: {\n env?: {\n THREADS_WORKER_INIT_TIMEOUT?: string\n }\n }\n}\n\n/** Maps a worker's exposed API type to its corresponding thread type (`FunctionThread` or `ModuleThread`). */\nexport type ExposedToThreadType<Exposed extends WorkerFunction | WorkerModule<any>>\n = Exposed extends ArbitraryWorkerInterface ? ArbitraryThreadType\n : Exposed extends WorkerFunction ? FunctionThread<Parameters<Exposed>, StripAsync<ReturnType<Exposed>>>\n : Exposed extends WorkerModule<any> ? ModuleThread<Exposed>\n : never\n\nconst debugMessages = DebugLogger('threads:master:messages')\nconst debugSpawn = DebugLogger('threads:master:spawn')\nconst debugThreadUtils = DebugLogger('threads:master:thread-utils')\n\nconst isInitMessage = (data: any): data is WorkerInitMessage => data?.type === 'init' as const\nconst isUncaughtErrorMessage = (data: any): data is WorkerUncaughtErrorMessage => data?.type === 'uncaughtError' as const\nconst workerInitTimeout = (globalThis as ProcessEnvGlobal).process?.env?.THREADS_WORKER_INIT_TIMEOUT\n\nconst initMessageTimeout\n = workerInitTimeout !== undefined && workerInitTimeout !== ''\n ? Number(workerInitTimeout)\n : 10_000\n\nasync function withTimeout<T>(promise: Promise<T>, timeoutInMs: number, errorMessage: string): Promise<T> {\n let timeoutHandle: any\n\n const timeout = new Promise<never>((resolve, reject) => {\n timeoutHandle = setTimeout(() => reject(new Error(errorMessage)), timeoutInMs)\n })\n const result = await Promise.race([promise, timeout])\n\n clearTimeout(timeoutHandle)\n return result\n}\n\nfunction receiveInitMessage(worker: WorkerType): Promise<WorkerInitMessage> {\n return new Promise((resolve, reject) => {\n const messageHandler = ((event: MessageEvent) => {\n debugMessages('Message from worker before finishing initialization:', event.data)\n if (isInitMessage(event.data)) {\n worker.removeEventListener('message', messageHandler)\n resolve(event.data)\n } else if (isUncaughtErrorMessage(event.data)) {\n worker.removeEventListener('message', messageHandler)\n reject(deserialize(event.data.error))\n }\n }) as EventListener\n worker.addEventListener('message', messageHandler)\n })\n}\n\nfunction createEventObservable(worker: WorkerType, workerTermination: Promise<any>): Observable<WorkerEvent> {\n return new Observable<WorkerEvent>((observer) => {\n const messageHandler = ((messageEvent: MessageEvent) => {\n const workerEvent: WorkerMessageEvent<any> = {\n data: messageEvent.data,\n type: WorkerEventType.message,\n }\n observer.next(workerEvent)\n }) as EventListener\n const rejectionHandler = ((errorEvent: PromiseRejectionEvent) => {\n debugThreadUtils('Unhandled promise rejection event in thread:', errorEvent)\n const workerEvent: WorkerInternalErrorEvent = {\n error: new Error(errorEvent.reason),\n type: WorkerEventType.internalError,\n }\n observer.next(workerEvent)\n }) as EventListener\n worker.addEventListener('message', messageHandler)\n worker.addEventListener('unhandledrejection', rejectionHandler)\n\n void (async () => {\n await workerTermination\n const terminationEvent: WorkerTerminationEvent = { type: WorkerEventType.termination }\n worker.removeEventListener('message', messageHandler)\n worker.removeEventListener('unhandledrejection', rejectionHandler)\n observer.next(terminationEvent)\n observer.complete()\n })()\n })\n}\n\nfunction createTerminator(worker: WorkerType): { terminate: () => Promise<void>; termination: Promise<void> } {\n const [termination, resolver] = createPromiseWithResolver<void>()\n const terminate = async () => {\n debugThreadUtils('Terminating worker')\n // Newer versions of worker_threads workers return a promise\n await worker.terminate()\n resolver()\n }\n return { terminate, termination }\n}\n\nfunction setPrivateThreadProps<T>(\n raw: T,\n worker: WorkerType,\n workerEvents: Observable<WorkerEvent>,\n terminate: () => Promise<void>,\n): T & PrivateThreadProps {\n const workerErrors = workerEvents\n .filter(event => event.type === WorkerEventType.internalError)\n .map(errorEvent => (errorEvent as WorkerInternalErrorEvent).error)\n\n const result = raw as T & PrivateThreadProps\n const privateProps: [symbol, PropertyDescriptor][] = [\n [$errors, { enumerable: false, value: workerErrors }],\n [$events, { enumerable: false, value: workerEvents }],\n [$terminate, { enumerable: false, value: terminate }],\n [$worker, { enumerable: false, value: worker }],\n ]\n for (const [key, descriptor] of privateProps) {\n Object.defineProperty(result, key, descriptor)\n }\n return result\n}\n\n/**\n * Spawn a new thread. Takes a fresh worker instance, wraps it in a thin\n * abstraction layer to provide the transparent API and verifies that\n * the worker has initialized successfully.\n *\n * @param worker Instance of `Worker`. Either a web worker or `worker_threads` worker.\n * @param [options]\n * @param [options.timeout] Init message timeout. Default: 10000 or set by environment variable.\n */\nexport async function spawn<Exposed extends WorkerFunction | WorkerModule<any> = ArbitraryWorkerInterface>(\n worker: WorkerType,\n options?: { timeout?: number },\n): Promise<ExposedToThreadType<Exposed>> {\n debugSpawn('Initializing new thread')\n\n const timeout = options?.timeout ?? initMessageTimeout\n const initMessage = await withTimeout(\n receiveInitMessage(worker),\n timeout,\n `Timeout: Did not receive an init message from worker after ${timeout}ms. Make sure the worker calls expose().`,\n )\n const exposed = initMessage.exposed\n\n const { termination, terminate } = createTerminator(worker)\n const events = createEventObservable(worker, termination)\n\n if (exposed.type === 'function') {\n const proxy = createProxyFunction(worker)\n return setPrivateThreadProps(proxy, worker, events, terminate) as ExposedToThreadType<Exposed>\n }\n if (exposed.type === 'module') {\n const proxy = createProxyModule(worker, exposed.methods)\n return setPrivateThreadProps(proxy, worker, events, terminate) as ExposedToThreadType<Exposed>\n }\n const type = (exposed as WorkerInitMessage['exposed']).type\n throw new Error(`Worker init message states unexpected type of expose(): ${type}`)\n}\n", "/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type { SerializedError } from './types/messages.ts'\n\n/** A serializer that can convert between a message format and an input type. */\nexport interface Serializer<Msg = JsonSerializable, Input = any> {\n deserialize(message: Msg): Input\n serialize(input: Input): Msg\n}\n\n/** A serializer implementation that receives a fallback (default) serializer for chaining. */\nexport interface SerializerImplementation<Msg = JsonSerializable, Input = any> {\n deserialize(message: Msg, defaultDeserialize: (msg: Msg) => Input): Input\n serialize(input: Input, defaultSerialize: (inp: Input) => Msg): Msg\n}\n\n/**\n * Extend a base serializer with an additional serializer implementation, creating a chain.\n * @param extend - The base serializer to extend.\n * @param implementation - The new serializer implementation that wraps the base.\n * @returns A new serializer combining both behaviors.\n */\nexport function extendSerializer<MessageType, InputType = any>(\n extend: Serializer<MessageType, InputType>,\n implementation: SerializerImplementation<MessageType, InputType>,\n): Serializer<MessageType, InputType> {\n const fallbackDeserializer = extend.deserialize.bind(extend)\n const fallbackSerializer = extend.serialize.bind(extend)\n\n return {\n deserialize: (message: MessageType): InputType => implementation.deserialize(message, fallbackDeserializer),\n\n serialize: (input: InputType): MessageType => implementation.serialize(input, fallbackSerializer),\n }\n}\n\ntype JsonSerializablePrimitive = string | number | boolean | null\n\ntype JsonSerializableObject = {\n [key: string]: JsonSerializablePrimitive | JsonSerializablePrimitive[] | JsonSerializableObject | JsonSerializableObject[] | undefined\n}\n\n/** A JSON-compatible value that can be serialized for worker message passing. */\nexport type JsonSerializable = JsonSerializablePrimitive | JsonSerializablePrimitive[] | JsonSerializableObject | JsonSerializableObject[]\n\nconst DefaultErrorSerializer: Serializer<SerializedError, Error> = {\n deserialize: (message: SerializedError): Error => {\n const error = Object.create(Error.prototype) as Error\n error.message = message.message\n error.name = message.name\n error.stack = message.stack\n return error\n },\n serialize: (error: Error): SerializedError => ({\n __error_marker: '$$error',\n message: error.message,\n name: error.name,\n stack: error.stack,\n }),\n}\n\nconst isSerializedError = (thing: any): thing is SerializedError =>\n thing != null && typeof thing === 'object' && '__error_marker' in thing && thing.__error_marker === '$$error'\n\n/** Default serializer that handles Error instances and passes other values through. */\nexport const DefaultSerializer: Serializer<JsonSerializable> = {\n deserialize: (message: JsonSerializable): any => isSerializedError(message) ? DefaultErrorSerializer.deserialize(message) : message,\n serialize: (input: any): JsonSerializable => input instanceof Error ? (DefaultErrorSerializer.serialize(input) as any as JsonSerializable) : input,\n}\n", "/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type {\n JsonSerializable, Serializer, SerializerImplementation,\n} from './serializers.ts'\nimport { DefaultSerializer, extendSerializer } from './serializers.ts'\n\ndeclare global {\n var registeredSerializer: Serializer<JsonSerializable>\n}\n\nglobalThis.registeredSerializer = globalThis.registeredSerializer ?? DefaultSerializer\n\n/**\n * Register a custom serializer to extend the default serialization behavior for worker messages.\n * @param serializer - The serializer implementation to register.\n */\nexport function registerSerializer(serializer: SerializerImplementation<JsonSerializable>) {\n globalThis.registeredSerializer = extendSerializer(globalThis.registeredSerializer, serializer)\n}\n\n/**\n * Deserialize a message using the registered serializer.\n * @param message - The serialized message to deserialize.\n * @returns The deserialized value.\n */\nexport function deserialize(message: JsonSerializable): any {\n return globalThis.registeredSerializer.deserialize(message)\n}\n\n/**\n * Serialize an input value using the registered serializer.\n * @param input - The value to serialize.\n * @returns The serialized message.\n */\nexport function serialize(input: any): JsonSerializable {\n return globalThis.registeredSerializer.serialize(input)\n}\n", "// eslint-disable-next-line unicorn/no-useless-undefined\nconst doNothing = () => undefined\n\n/**\n * Creates a new promise and exposes its resolver function.\n * Use with care!\n */\nexport function createPromiseWithResolver<T>(): [Promise<T>, (result: T) => void] {\n let alreadyResolved = false\n let resolvedTo: T\n let resolver: (value: T | PromiseLike<T>) => void = doNothing\n\n const promise = new Promise<T>((resolve) => {\n if (alreadyResolved) {\n resolve(resolvedTo)\n } else {\n resolver = resolve\n }\n })\n const exposedResolver = (value: T) => {\n alreadyResolved = true\n resolvedTo = value\n resolver(resolvedTo)\n }\n return [promise, exposedResolver]\n}\n", "/** Symbol key for accessing a thread's error observable. */\nexport const $errors = Symbol('thread.errors')\n/** Symbol key for accessing a thread's event observable. */\nexport const $events = Symbol('thread.events')\n/** Symbol key for accessing a thread's terminate function. */\nexport const $terminate = Symbol('thread.terminate')\n/** Symbol key for marking an object as a transferable descriptor. */\nexport const $transferable = Symbol('thread.transferable')\n/** Symbol key for accessing the underlying worker instance of a thread. */\nexport const $worker = Symbol('thread.worker')\n", "/// <reference lib=\"webworker\" />\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/*\n * This source file contains the code for proxying calls in the master thread to calls in the workers\n * by `.postMessage()`-ing.\n *\n * Keep in mind that this code can make or break the program's performance! Need to optimize more\u2026\n */\n\nimport DebugLogger from 'debug'\nimport { multicast, Observable } from 'observable-fns'\n\nimport { deserialize, serialize } from '../common.ts'\nimport { ObservablePromise } from '../observable-promise.ts'\nimport { isTransferDescriptor } from '../transferable.ts'\nimport type {\n ModuleMethods, ModuleProxy, ProxyableFunction, Worker as WorkerType,\n} from '../types/master.ts'\nimport type {\n MasterJobCancelMessage,\n MasterJobRunMessage,\n WorkerJobErrorMessage,\n WorkerJobResultMessage,\n WorkerJobStartMessage,\n} from '../types/messages.ts'\nimport {\n MasterMessageType,\n WorkerMessageType,\n} from '../types/messages.ts'\n\nconst debugMessages = DebugLogger('threads:master:messages')\n\nlet nextJobUID = 1\n\nconst dedupe = <T>(array: T[]): T[] => [...new Set(array)]\n\nconst isJobErrorMessage = (data: any): data is WorkerJobErrorMessage => data?.type === WorkerMessageType.error\nconst isJobResultMessage = (data: any): data is WorkerJobResultMessage => data?.type === WorkerMessageType.result\nconst isJobStartMessage = (data: any): data is WorkerJobStartMessage => data?.type === WorkerMessageType.running\n\nfunction createObservableForJob<ResultType>(worker: WorkerType, jobUID: number): Observable<ResultType> {\n return new Observable((observer) => {\n let asyncType: 'observable' | 'promise' | undefined\n\n const messageHandler = ((event: MessageEvent) => {\n debugMessages('Message from worker:', event.data)\n if (event.data?.uid !== jobUID) return\n\n if (isJobStartMessage(event.data)) {\n asyncType = event.data.resultType\n } else if (isJobResultMessage(event.data)) {\n if (asyncType === 'promise') {\n if (event.data.payload !== undefined) {\n observer.next(deserialize(event.data.payload))\n }\n observer.complete()\n worker.removeEventListener('message', messageHandler)\n } else {\n if (event.data.payload !== undefined) {\n observer.next(deserialize(event.data.payload))\n }\n if (event.data.complete) {\n observer.complete()\n worker.removeEventListener('message', messageHandler)\n }\n }\n } else if (isJobErrorMessage(event.data)) {\n const error = deserialize(event.data.error as any)\n if (asyncType === 'promise' || asyncType === undefined) {\n observer.error(error)\n } else {\n observer.error(error)\n }\n worker.removeEventListener('message', messageHandler)\n }\n }) as EventListener\n\n worker.addEventListener('message', messageHandler)\n\n return () => {\n if (asyncType === 'observable' || asyncType === undefined) {\n const cancelMessage: MasterJobCancelMessage = {\n type: MasterMessageType.cancel,\n uid: jobUID,\n }\n worker.postMessage(cancelMessage)\n }\n worker.removeEventListener('message', messageHandler)\n }\n })\n}\n\nfunction prepareArguments(rawArgs: any[]): { args: any[]; transferables: Transferable[] } {\n if (rawArgs.length === 0) {\n // Exit early if possible\n return {\n args: [],\n transferables: [],\n }\n }\n\n const args: any[] = []\n const transferables: Transferable[] = []\n\n for (const arg of rawArgs) {\n if (isTransferDescriptor(arg)) {\n args.push(serialize(arg.send))\n transferables.push(...arg.transferables)\n } else {\n args.push(serialize(arg))\n }\n }\n\n return {\n args,\n transferables: transferables.length === 0 ? transferables : dedupe(transferables),\n }\n}\n\n/**\n * Create a proxy function that forwards calls to a worker thread via postMessage.\n * @param worker - The worker to send messages to.\n * @param method - Optional method name for module-style workers.\n * @returns A proxied function that returns an `ObservablePromise`.\n */\nexport function createProxyFunction<Args extends any[], ReturnType>(worker: WorkerType, method?: string) {\n return ((...rawArgs: Args) => {\n const uid = nextJobUID++\n const { args, transferables } = prepareArguments(rawArgs)\n const runMessage: MasterJobRunMessage = {\n args,\n method,\n type: MasterMessageType.run,\n uid,\n }\n\n debugMessages('Sending command to run function to worker:', runMessage)\n\n try {\n worker.postMessage(runMessage, transferables)\n } catch (error) {\n return ObservablePromise.from(Promise.reject(error))\n }\n\n return ObservablePromise.from(multicast(createObservableForJob<ReturnType>(worker, uid)))\n }) as any as ProxyableFunction<Args, ReturnType>\n}\n\n/**\n * Create a proxy module that maps method names to proxy functions forwarding calls to a worker.\n * @param worker - The worker to send messages to.\n * @param methodNames - The method names exposed by the worker module.\n * @returns A proxy object with methods matching the worker module's API.\n */\nexport function createProxyModule<Methods extends ModuleMethods>(worker: WorkerType, methodNames: string[]): ModuleProxy<Methods> {\n const proxy: any = {}\n\n for (const methodName of methodNames) {\n proxy[methodName] = createProxyFunction(worker, methodName)\n }\n\n return proxy\n}\n", "/* eslint-disable unicorn/no-thenable */\n/* eslint-disable @typescript-eslint/member-ordering */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-this-alias */\n/* eslint-disable unicorn/no-this-assignment */\nimport type { ObservableLike, SubscriptionObserver } from 'observable-fns'\nimport { Observable } from 'observable-fns'\n\ntype OnFulfilled<T, Result = void> = (value: T) => Result\ntype OnRejected<Result = void> = (error: Error) => Result\n\ntype Initializer<T> = (observer: SubscriptionObserver<T>) => UnsubscribeFn | void\n\ntype Thenable<T> = { then: (onFulfilled?: (value: T) => any, onRejected?: (error: any) => any) => any }\n\ntype UnsubscribeFn = () => void\n\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nconst doNothing = () => {}\nconst returnInput = <T>(input: T): T => input\nconst runDeferred = (fn: () => void) => {\n void (async () => {\n await Promise.resolve()\n fn()\n })()\n}\n\nfunction fail(error: Error): never {\n throw error\n}\n\nfunction isThenable(thing: any): thing is Thenable<any> {\n return thing != null && typeof thing.then === 'function'\n}\n\n/**\n * Creates a hybrid, combining the APIs of an Observable and a Promise.\n *\n * It is used to proxy async process states when we are initially not sure\n * if that async process will yield values once (-> Promise) or multiple\n * times (-> Observable).\n *\n * Note that the observable promise inherits some of the observable's characteristics:\n * The `init` function will be called *once for every time anyone subscribes to it*.\n *\n * If this is undesired, derive a hot observable from it using `makeHot()` and\n * subscribe to that.\n */\nexport class ObservablePromise<T> extends Observable<T> implements Promise<T> {\n readonly [Symbol.toStringTag] = '[object ObservablePromise]'\n private initHasRun = false\n private fulfillmentCallbacks: OnFulfilled<T>[] = []\n private rejectionCallbacks: OnRejected[] = []\n\n private firstValue: T | undefined\n private firstValueSet = false\n private rejection: Error | undefined\n private state: 'fulfilled' | 'pending' | 'rejected' = 'pending'\n\n constructor(init: Initializer<T>) {\n super((originalObserver: SubscriptionObserver<T>) => {\n const self = this\n const observer: SubscriptionObserver<T> = {\n ...originalObserver,\n complete() {\n originalObserver.complete()\n self.onCompletion()\n },\n error(error: Error) {\n originalObserver.error(error)\n self.onError(error)\n },\n next(value: T) {\n originalObserver.next(value)\n self.onNext(value)\n },\n }\n\n try {\n this.initHasRun = true\n return init(observer)\n } catch (error) {\n observer.error(error)\n }\n })\n }\n\n private onNext(value: T) {\n if (this.firstValueSet) {\n return\n }\n\n this.firstValue = value\n this.firstValueSet = true\n }\n\n private onError(error: Error) {\n this.state = 'rejected'\n this.rejection = error\n\n for (const onRejected of this.rejectionCallbacks) {\n // Promisifying the call to turn errors into unhandled promise rejections\n // instead of them failing sync and cancelling the iteration\n runDeferred(() => onRejected(error))\n }\n }\n\n private onCompletion() {\n this.state = 'fulfilled'\n\n for (const onFulfilled of this.fulfillmentCallbacks) {\n // Promisifying the call to turn errors into unhandled promise rejections\n // instead of them failing sync and cancelling the iteration\n runDeferred(() => onFulfilled(this.firstValue as T))\n }\n }\n\n private createPromise<TResult1 = T, TResult2 = never>(\n onFulfilledRaw?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,\n onRejectedRaw?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null,\n ): Promise<TResult1 | TResult2> {\n const onFulfilled: OnFulfilled<T, TResult1> = onFulfilledRaw || (returnInput as any)\n const onRejected = onRejectedRaw || fail\n let onRejectedCalled = false\n\n return new Promise<TResult1 | TResult2>((resolve, reject) => {\n const rejectionCallback = (error: Error) => {\n if (onRejectedCalled) return\n onRejectedCalled = true\n\n try {\n resolve(onRejected(error))\n } catch (anotherError) {\n reject(anotherError)\n }\n }\n const fulfillmentCallback = (value: T) => {\n try {\n resolve(onFulfilled(value))\n } catch (ex) {\n const error = ex as Error\n rejectionCallback(error)\n }\n }\n if (!this.initHasRun) {\n this.subscribe({ error: rejectionCallback })\n }\n if (this.state === 'fulfilled') {\n return resolve(onFulfilled(this.firstValue as T))\n }\n if (this.state === 'rejected') {\n onRejectedCalled = true\n return resolve(onRejected(this.rejection!))\n }\n this.fulfillmentCallbacks.push(fulfillmentCallback)\n this.rejectionCallbacks.push(rejectionCallback)\n })\n }\n\n then<TResult1 = T, TResult2 = never>(\n onFulfilledRaw?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,\n onRejectedRaw?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null,\n ): Promise<TResult1 | TResult2> {\n return this.createPromise(onFulfilledRaw, onRejectedRaw)\n }\n\n catch<Result = never>(onRejected: ((error: Error) => Promise<Result> | Result) | null | undefined) {\n return this.createPromise(undefined, onRejected)\n }\n\n finally(onCompleted?: (() => void) | null) {\n const handler = onCompleted || doNothing\n return this.createPromise(\n (value: T) => {\n handler()\n return value\n },\n () => handler(),\n ) as Promise<T>\n }\n\n static override from<T>(thing: Observable<T> | ObservableLike<T> | ArrayLike<T> | Thenable<T>): ObservablePromise<T> {\n return isThenable(thing)\n ? new ObservablePromise((observer) => {\n void (async () => {\n try {\n const value = await thing\n observer.next(value)\n observer.complete()\n } catch (error) {\n observer.error(error)\n }\n })()\n })\n : (super.from(thing) as ObservablePromise<T>)\n }\n}\n", "/// <reference lib=\"webworker\" />\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { $transferable } from './symbols.ts'\n\n/** Descriptor wrapping a value with its associated transferable objects for zero-copy messaging. */\nexport interface TransferDescriptor<T = any> {\n [$transferable]: true\n send: T\n transferables: Transferable[]\n}\n\nfunction isTransferable(thing: any): thing is Transferable {\n if (thing == null || typeof thing !== 'object') return false\n // Don't check too thoroughly, since the list of transferable things in JS might grow over time\n return true\n}\n\n/**\n * Check whether a value is a `TransferDescriptor` created by `Transfer()`.\n * @param thing - The value to check.\n * @returns True if the value is a transfer descriptor.\n */\nexport function isTransferDescriptor(thing: any): thing is TransferDescriptor {\n return thing != null && typeof thing === 'object' && Reflect.get(thing, $transferable) === true\n}\n\n/**\n * Mark a transferable object as such, so it will no be serialized and\n * deserialized on messaging with the main thread, but to transfer\n * ownership of it to the receiving thread.\n *\n * Only works with array buffers, message ports and few more special\n * types of objects, but it's much faster than serializing and\n * deserializing them.\n *\n * Note:\n * The transferable object cannot be accessed by this thread again\n * unless the receiving thread transfers it back again!\n *\n * @param transferable Array buffer, message port or similar.\n * @see <https://developers.google.com/web/updates/2011/12/Transferable-Objects-Lightning-Fast>\n */\nexport function Transfer(transferable: Transferable): TransferDescriptor\n\n/**\n * Mark transferable objects within an arbitrary object or array as\n * being a transferable object. They will then not be serialized\n * and deserialized on messaging with the main thread, but ownership\n * of them will be tranferred to the receiving thread.\n *\n * Only array buffers, message ports and few more special types of\n * objects can be transferred, but it's much faster than serializing and\n * deserializing them.\n *\n * Note:\n * The transferable object cannot be accessed by this thread again\n * unless the receiving thread transfers it back again!\n *\n * @param transferable Array buffer, message port or similar.\n * @see <https://developers.google.com/web/updates/2011/12/Transferable-Objects-Lightning-Fast>\n */\nexport function Transfer<T>(payload: T, transferables: Transferable[]): TransferDescriptor\n\nexport function Transfer<T>(payload: T, transferables?: Transferable[]): TransferDescriptor {\n console.log('Transfer')\n if (!transferables) {\n if (!isTransferable(payload)) throw new Error('Not transferable')\n transferables = [payload]\n }\n\n const descriptor = {\n send: payload,\n transferables,\n } as TransferDescriptor\n\n Object.defineProperty(descriptor, $transferable, { value: true })\n return descriptor\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["DebugLogger", "Observable", "Observable", "doNothing", "Observable", "debugMessages", "DebugLogger", "Observable"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Observable } from 'observable-fns';
|
|
2
|
+
import type { Thread as ThreadType, WorkerEvent } from '../types/master.ts';
|
|
3
|
+
/** Re-exported Thread type from the master types module. */
|
|
4
|
+
export type Thread = ThreadType;
|
|
5
|
+
/** Thread utility functions. Use them to manage or inspect a `spawn()`-ed thread. */
|
|
6
|
+
export declare const Thread: {
|
|
7
|
+
/** Return an observable that can be used to subscribe to all errors happening in the thread. */
|
|
8
|
+
errors: <ThreadT extends ThreadType>(thread: ThreadT) => Observable<Error>;
|
|
9
|
+
/** Return an observable that can be used to subscribe to internal events happening in the thread. Useful for debugging. */
|
|
10
|
+
events: <ThreadT extends ThreadType>(thread: ThreadT) => Observable<WorkerEvent>;
|
|
11
|
+
/** Terminate a thread. Remember to terminate every thread when you are done using it. */
|
|
12
|
+
terminate: <ThreadT extends ThreadType>(thread: ThreadT) => Promise<void>;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=thread.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thread.d.ts","sourceRoot":"","sources":["../../../src/master/thread.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAKhD,OAAO,KAAK,EACU,MAAM,IAAI,UAAU,EAAE,WAAW,EACtD,MAAM,oBAAoB,CAAA;AAa3B,4DAA4D;AAC5D,MAAM,MAAM,MAAM,GAAG,UAAU,CAAA;AAE/B,qFAAqF;AACrF,eAAO,MAAM,MAAM;IACjB,gGAAgG;aACvF,OAAO,SAAS,UAAU,UAAU,OAAO,KAAG,UAAU,CAAC,KAAK,CAAC;IAExE,2HAA2H;aAClH,OAAO,SAAS,UAAU,UAAU,OAAO,KAAG,UAAU,CAAC,WAAW,CAAC;IAE9E,yFAAyF;gBAC7E,OAAO,SAAS,UAAU,UAAU,OAAO;CAExD,CAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// src/symbols.ts
|
|
2
|
+
var $errors = /* @__PURE__ */ Symbol("thread.errors");
|
|
3
|
+
var $events = /* @__PURE__ */ Symbol("thread.events");
|
|
4
|
+
var $terminate = /* @__PURE__ */ Symbol("thread.terminate");
|
|
5
|
+
|
|
6
|
+
// src/master/thread.ts
|
|
7
|
+
function fail(message) {
|
|
8
|
+
throw new Error(message);
|
|
9
|
+
}
|
|
10
|
+
function readPrivateThreadProp(thread, key) {
|
|
11
|
+
return Reflect.get(thread, key);
|
|
12
|
+
}
|
|
13
|
+
var Thread = {
|
|
14
|
+
/** Return an observable that can be used to subscribe to all errors happening in the thread. */
|
|
15
|
+
errors: (thread) => readPrivateThreadProp(thread, $errors) ?? fail("Error observable not found. Make sure to pass a thread instance as returned by the spawn() promise."),
|
|
16
|
+
/** Return an observable that can be used to subscribe to internal events happening in the thread. Useful for debugging. */
|
|
17
|
+
events: (thread) => readPrivateThreadProp(thread, $events) ?? fail("Events observable not found. Make sure to pass a thread instance as returned by the spawn() promise."),
|
|
18
|
+
/** Terminate a thread. Remember to terminate every thread when you are done using it. */
|
|
19
|
+
terminate: (thread) => readPrivateThreadProp(thread, $terminate)?.() ?? fail("Terminate function not found. Make sure to pass a thread instance as returned by the spawn() promise.")
|
|
20
|
+
};
|
|
21
|
+
export {
|
|
22
|
+
Thread
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=thread.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/symbols.ts", "../../../src/master/thread.ts"],
|
|
4
|
+
"sourcesContent": ["/** Symbol key for accessing a thread's error observable. */\nexport const $errors = Symbol('thread.errors')\n/** Symbol key for accessing a thread's event observable. */\nexport const $events = Symbol('thread.events')\n/** Symbol key for accessing a thread's terminate function. */\nexport const $terminate = Symbol('thread.terminate')\n/** Symbol key for marking an object as a transferable descriptor. */\nexport const $transferable = Symbol('thread.transferable')\n/** Symbol key for accessing the underlying worker instance of a thread. */\nexport const $worker = Symbol('thread.worker')\n", "import type { Observable } from 'observable-fns'\n\nimport {\n $errors, $events, $terminate,\n} from '../symbols.ts'\nimport type {\n PrivateThreadProps, Thread as ThreadType, WorkerEvent,\n} from '../types/master.ts'\n\nfunction fail(message: string): never {\n throw new Error(message)\n}\n\nfunction readPrivateThreadProp<K extends keyof PrivateThreadProps>(\n thread: ThreadType,\n key: K,\n): PrivateThreadProps[K] | undefined {\n return Reflect.get(thread, key)\n}\n\n/** Re-exported Thread type from the master types module. */\nexport type Thread = ThreadType\n\n/** Thread utility functions. Use them to manage or inspect a `spawn()`-ed thread. */\nexport const Thread = {\n /** Return an observable that can be used to subscribe to all errors happening in the thread. */\n errors: <ThreadT extends ThreadType>(thread: ThreadT): Observable<Error> =>\n readPrivateThreadProp(thread, $errors) ?? fail('Error observable not found. Make sure to pass a thread instance as returned by the spawn() promise.'),\n /** Return an observable that can be used to subscribe to internal events happening in the thread. Useful for debugging. */\n events: <ThreadT extends ThreadType>(thread: ThreadT): Observable<WorkerEvent> =>\n readPrivateThreadProp(thread, $events) ?? fail('Events observable not found. Make sure to pass a thread instance as returned by the spawn() promise.'),\n /** Terminate a thread. Remember to terminate every thread when you are done using it. */\n terminate: <ThreadT extends ThreadType>(thread: ThreadT) =>\n readPrivateThreadProp(thread, $terminate)?.() ?? fail('Terminate function not found. Make sure to pass a thread instance as returned by the spawn() promise.'),\n}\n"],
|
|
5
|
+
"mappings": ";AACO,IAAM,UAAU,uBAAO,eAAe;AAEtC,IAAM,UAAU,uBAAO,eAAe;AAEtC,IAAM,aAAa,uBAAO,kBAAkB;;;ACInD,SAAS,KAAK,SAAwB;AACpC,QAAM,IAAI,MAAM,OAAO;AACzB;AAEA,SAAS,sBACP,QACA,KACmC;AACnC,SAAO,QAAQ,IAAI,QAAQ,GAAG;AAChC;AAMO,IAAM,SAAS;AAAA;AAAA,EAEpB,QAAQ,CAA6B,WACnC,sBAAsB,QAAQ,OAAO,KAAK,KAAK,qGAAqG;AAAA;AAAA,EAEtJ,QAAQ,CAA6B,WACnC,sBAAsB,QAAQ,OAAO,KAAK,KAAK,sGAAsG;AAAA;AAAA,EAEvJ,WAAW,CAA6B,WACtC,sBAAsB,QAAQ,UAAU,IAAI,KAAK,KAAK,uGAAuG;AACjK;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { ObservableLike, SubscriptionObserver } from 'observable-fns';
|
|
2
|
+
import { Observable } from 'observable-fns';
|
|
3
|
+
type Initializer<T> = (observer: SubscriptionObserver<T>) => UnsubscribeFn | void;
|
|
4
|
+
type Thenable<T> = {
|
|
5
|
+
then: (onFulfilled?: (value: T) => any, onRejected?: (error: any) => any) => any;
|
|
6
|
+
};
|
|
7
|
+
type UnsubscribeFn = () => void;
|
|
8
|
+
/**
|
|
9
|
+
* Creates a hybrid, combining the APIs of an Observable and a Promise.
|
|
10
|
+
*
|
|
11
|
+
* It is used to proxy async process states when we are initially not sure
|
|
12
|
+
* if that async process will yield values once (-> Promise) or multiple
|
|
13
|
+
* times (-> Observable).
|
|
14
|
+
*
|
|
15
|
+
* Note that the observable promise inherits some of the observable's characteristics:
|
|
16
|
+
* The `init` function will be called *once for every time anyone subscribes to it*.
|
|
17
|
+
*
|
|
18
|
+
* If this is undesired, derive a hot observable from it using `makeHot()` and
|
|
19
|
+
* subscribe to that.
|
|
20
|
+
*/
|
|
21
|
+
export declare class ObservablePromise<T> extends Observable<T> implements Promise<T> {
|
|
22
|
+
readonly [Symbol.toStringTag] = "[object ObservablePromise]";
|
|
23
|
+
private initHasRun;
|
|
24
|
+
private fulfillmentCallbacks;
|
|
25
|
+
private rejectionCallbacks;
|
|
26
|
+
private firstValue;
|
|
27
|
+
private firstValueSet;
|
|
28
|
+
private rejection;
|
|
29
|
+
private state;
|
|
30
|
+
constructor(init: Initializer<T>);
|
|
31
|
+
private onNext;
|
|
32
|
+
private onError;
|
|
33
|
+
private onCompletion;
|
|
34
|
+
private createPromise;
|
|
35
|
+
then<TResult1 = T, TResult2 = never>(onFulfilledRaw?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null, onRejectedRaw?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
|
|
36
|
+
catch<Result = never>(onRejected: ((error: Error) => Promise<Result> | Result) | null | undefined): Promise<T | Result>;
|
|
37
|
+
finally(onCompleted?: (() => void) | null): Promise<T>;
|
|
38
|
+
static from<T>(thing: Observable<T> | ObservableLike<T> | ArrayLike<T> | Thenable<T>): ObservablePromise<T>;
|
|
39
|
+
}
|
|
40
|
+
export {};
|
|
41
|
+
//# sourceMappingURL=observable-promise.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observable-promise.d.ts","sourceRoot":"","sources":["../../src/observable-promise.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAK3C,KAAK,WAAW,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,oBAAoB,CAAC,CAAC,CAAC,KAAK,aAAa,GAAG,IAAI,CAAA;AAEjF,KAAK,QAAQ,CAAC,CAAC,IAAI;IAAE,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,GAAG,EAAE,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,KAAK,GAAG,CAAA;CAAE,CAAA;AAEvG,KAAK,aAAa,GAAG,MAAM,IAAI,CAAA;AAoB/B;;;;;;;;;;;;GAYG;AACH,qBAAa,iBAAiB,CAAC,CAAC,CAAE,SAAQ,UAAU,CAAC,CAAC,CAAE,YAAW,OAAO,CAAC,CAAC,CAAC;IAC3E,QAAQ,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,gCAA+B;IAC5D,OAAO,CAAC,UAAU,CAAQ;IAC1B,OAAO,CAAC,oBAAoB,CAAuB;IACnD,OAAO,CAAC,kBAAkB,CAAmB;IAE7C,OAAO,CAAC,UAAU,CAAe;IACjC,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,KAAK,CAAkD;gBAEnD,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;IA4BhC,OAAO,CAAC,MAAM;IASd,OAAO,CAAC,OAAO;IAWf,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,aAAa;IA0CrB,IAAI,CAAC,QAAQ,GAAG,CAAC,EAAE,QAAQ,GAAG,KAAK,EACjC,cAAc,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,EACxE,aAAa,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,GAAG,KAAK,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,GACzE,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAI/B,KAAK,CAAC,MAAM,GAAG,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,IAAI,GAAG,SAAS;IAIjG,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,GAQlC,OAAO,CAAC,CAAC,CAAC;WAGD,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC;CAerH"}
|