@atolljs/core 0.1.13 → 0.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/contract/listSchema.js +1 -2
- package/dist/contract/memoryDevtools.js +2 -3
- package/dist/contract/msgpackrCodec.js +1 -2
- package/dist/contract/reef.js +1 -2
- package/dist/contract/sharedMemory.js +61 -62
- package/dist/contract/types.d.ts +24 -0
- package/dist/contract/zod.js +1 -2
- package/dist/devtools.js +32 -39
- package/dist/index.d.ts +1 -1
- package/dist/index.js +22 -22
- package/dist/log.js +1 -2
- package/dist/observable.js +18 -19
- package/dist/pool/dedicatedWorker.d.ts +3 -0
- package/dist/pool/dedicatedWorker.js +72 -68
- package/dist/pool/devtoolsCommands.js +1 -2
- package/dist/pool/errors.js +1 -2
- package/dist/pool/memory.js +1 -2
- package/dist/pool/subWorkerClient.js +1 -2
- package/dist/pool/workerChannel.js +21 -22
- package/dist/pool/workerClient.d.ts +15 -1
- package/dist/pool/workerClient.js +14 -10
- package/dist/pool/workerPool.d.ts +3 -0
- package/dist/pool/workerPool.js +119 -121
- package/dist/reactive.js +1 -2
- package/dist/reactiveGraph.js +1 -2
- package/dist/service.js +1 -2
- package/dist/shared/sharedWorkerClient.js +2 -9
- package/dist/shared/sharedWorkerHost.js +22 -27
- package/dist/task.js +1 -2
- package/dist/testing/inProcessWorker.js +3 -8
- package/dist/userTiming.js +1 -2
- package/dist/worker/defineWorker.js +8 -9
- package/dist/worker/registry.js +1 -2
- package/dist/worker/workerBootstrap.js +40 -52
- package/package.json +11 -7
- package/src/contract/types.ts +26 -0
- package/src/index.ts +2 -0
- package/src/pool/dedicatedWorker.ts +19 -1
- package/src/pool/workerClient.ts +30 -1
- package/src/pool/workerPool.ts +11 -1
package/dist/pool/workerPool.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import { PoolQueueFullError as e, TaskAbortedError as t, TaskTimeoutError as n, WorkerCrashedError as r } from "./errors.js";
|
|
2
|
+
import { devtoolsEnabled as i, emitDevtools as a, estimateCloneBytes as o, nextDevtoolsId as s } from "../devtools.js";
|
|
3
|
+
import { measureTaskCall as c } from "../userTiming.js";
|
|
4
|
+
import { forwardWorkerDevtools as l, sendInit as u, setupChannelMemory as d } from "./workerChannel.js";
|
|
5
|
+
import { fmtBytes as f, scoped as p } from "../log.js";
|
|
6
6
|
import { CHAOS_FAILURE as m, KILL_MESSAGE as h, applyChaos as g, registerDevtoolsRunner as _ } from "./devtoolsCommands.js";
|
|
7
|
-
|
|
8
|
-
var v =
|
|
7
|
+
// src/pool/workerPool.ts
|
|
8
|
+
var v = p("pool"), y = p("task"), b = () => ({
|
|
9
9
|
count: 0,
|
|
10
10
|
mean: 0,
|
|
11
11
|
max: 0,
|
|
@@ -25,6 +25,7 @@ var v = a("pool"), y = a("task"), b = () => ({
|
|
|
25
25
|
concurrency;
|
|
26
26
|
maxQueue;
|
|
27
27
|
respawn;
|
|
28
|
+
onLifecycle;
|
|
28
29
|
taskTimeout;
|
|
29
30
|
closed = !1;
|
|
30
31
|
chaos = null;
|
|
@@ -42,21 +43,21 @@ var v = a("pool"), y = a("task"), b = () => ({
|
|
|
42
43
|
nextCallId = 0;
|
|
43
44
|
sharedMemory;
|
|
44
45
|
persistence;
|
|
45
|
-
constructor(
|
|
46
|
-
let
|
|
47
|
-
if (!
|
|
48
|
-
this.workerUrl =
|
|
49
|
-
let
|
|
50
|
-
v.info(this.sharedMemory ? `spawning ${
|
|
46
|
+
constructor(e) {
|
|
47
|
+
let t = d(e, "WorkerPool");
|
|
48
|
+
if (!e.workerUrl && !e.createWorker) throw Error("WorkerPool requires either `workerUrl` or `createWorker` in its config.");
|
|
49
|
+
this.workerUrl = e.workerUrl, this.spawn = e.createWorker ?? (() => new Worker(this.workerUrl, { type: "module" })), this.concurrency = e.concurrency ?? 1, this.maxQueue = e.maxQueue ?? Infinity, this.respawn = e.respawn ?? !0, this.onLifecycle = e.onLifecycle, this.taskTimeout = e.taskTimeout, this.label = e.name, this.poolId = s("pool", e.name), this.mem = t, this.sharedMemory = t.sharedMemory, this.memoryManager = t.memoryManager, this.injectedBuffer = t.injectedBuffer, this.persistence = t.persistence;
|
|
50
|
+
let n = e.poolSize ?? "auto", r = n === "auto" ? typeof navigator < "u" ? navigator.hardwareConcurrency ?? 4 : 4 : n;
|
|
51
|
+
v.info(this.sharedMemory ? `spawning ${r} worker(s) with ${f(this.sharedMemory.totalBytes)} shared buffer` : this.injectedBuffer ? `spawning ${r} worker(s) with ${f(this.injectedBuffer.byteLength)} inherited buffer` : `spawning ${r} worker(s), message-only`, { workerUrl: e.workerUrl ? String(e.workerUrl) : "createWorker()" }), v.debug("tip: setLogLevel('trace') for per-task detail"), a({
|
|
51
52
|
type: "pool:init",
|
|
52
53
|
poolId: this.poolId,
|
|
53
54
|
label: this.label,
|
|
54
|
-
poolSize:
|
|
55
|
+
poolSize: r,
|
|
55
56
|
concurrency: this.concurrency,
|
|
56
57
|
memoryBytes: this.sharedMemory?.totalBytes ?? this.injectedBuffer?.byteLength
|
|
57
58
|
});
|
|
58
|
-
for (let e = 0; e <
|
|
59
|
-
|
|
59
|
+
for (let e = 0; e < r; e++) this.addWorker(this.spawn());
|
|
60
|
+
i() && (this.devtoolsOff = _({
|
|
60
61
|
poolId: this.poolId,
|
|
61
62
|
label: this.label,
|
|
62
63
|
dedicated: !1,
|
|
@@ -72,100 +73,98 @@ var v = a("pool"), y = a("task"), b = () => ({
|
|
|
72
73
|
this.chaos = e;
|
|
73
74
|
}
|
|
74
75
|
}));
|
|
75
|
-
let
|
|
76
|
-
for (let [e, t] of Object.entries(
|
|
77
|
-
|
|
78
|
-
v.warn(`task "${e}" collides with a WorkerPool member — not installed`);
|
|
79
|
-
continue;
|
|
80
|
-
}
|
|
81
|
-
this[e] = (...e) => this.runTask(t, ...e);
|
|
82
|
-
}
|
|
83
|
-
Object.keys(c).length > 0 && v.info(`task methods: ${Object.keys(c).join(", ")}`);
|
|
76
|
+
let o = e.tasks ?? {};
|
|
77
|
+
for (let [e, t] of Object.entries(o)) e in this ? v.warn(`task "${e}" collides with a WorkerPool member — not installed`) : this[e] = (...e) => this.runTask(t, ...e);
|
|
78
|
+
Object.keys(o).length > 0 && v.info(`task methods: ${Object.keys(o).join(", ")}`);
|
|
84
79
|
}
|
|
85
80
|
addWorker(e) {
|
|
86
|
-
let
|
|
81
|
+
let t = {
|
|
87
82
|
worker: e,
|
|
88
83
|
inFlight: 0
|
|
89
84
|
};
|
|
90
85
|
e.addEventListener("message", (e) => {
|
|
91
|
-
let
|
|
92
|
-
|
|
93
|
-
d(this.poolId, this.slots.indexOf(n), t.event);
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
this.handleReply(n, t);
|
|
86
|
+
let n = e.data;
|
|
87
|
+
n.type === "ATOLL_DEVTOOLS" && n.event ? l(this.poolId, this.slots.indexOf(t), n.event) : this.handleReply(t, n);
|
|
97
88
|
}), e.addEventListener("error", (e) => {
|
|
98
|
-
this.handleWorkerError(
|
|
89
|
+
this.handleWorkerError(t, e);
|
|
99
90
|
});
|
|
100
|
-
let
|
|
101
|
-
return this.slots.push(
|
|
91
|
+
let n = u(e, this.mem);
|
|
92
|
+
return this.slots.push(t), v.debug(`worker spawned, ${n} sent`), a({
|
|
102
93
|
type: "worker:spawn",
|
|
103
94
|
poolId: this.poolId,
|
|
104
|
-
slot: this.slots.indexOf(
|
|
105
|
-
}),
|
|
95
|
+
slot: this.slots.indexOf(t)
|
|
96
|
+
}), t;
|
|
106
97
|
}
|
|
107
|
-
handleReply(
|
|
108
|
-
let
|
|
109
|
-
if (
|
|
110
|
-
if (this.pending.delete(
|
|
111
|
-
|
|
112
|
-
let
|
|
113
|
-
this.statsAgg.runMs.add(s),
|
|
98
|
+
handleReply(e, t) {
|
|
99
|
+
let n = t.messageId === void 0 ? void 0 : this.pending.get(t.messageId);
|
|
100
|
+
if (n) {
|
|
101
|
+
if (this.pending.delete(t.messageId), e.inFlight--, this.detach(n), !n.done) {
|
|
102
|
+
n.done = !0;
|
|
103
|
+
let r = n.sentAt ?? n.enqueuedAt, s = performance.now() - r;
|
|
104
|
+
this.statsAgg.runMs.add(s), t.success ? (this.statsAgg.completed++, y.debug(`← ${n.contract.taskId} ok`), i() && (a({
|
|
114
105
|
type: "task:settle",
|
|
115
106
|
poolId: this.poolId,
|
|
116
|
-
callId:
|
|
117
|
-
taskId:
|
|
107
|
+
callId: n.callId,
|
|
108
|
+
taskId: n.contract.taskId,
|
|
118
109
|
outcome: "ok",
|
|
119
110
|
runMs: s,
|
|
120
|
-
resultBytes:
|
|
121
|
-
}),
|
|
111
|
+
resultBytes: o(t.result)
|
|
112
|
+
}), c(this.poolId, n.contract.taskId, n.callId, this.slots.indexOf(e), r, r + s, !0)), n.resolve(t.result)) : (this.statsAgg.failed++, y.warn(`← ${n.contract.taskId} failed: ${t.error}`), i() && (a({
|
|
122
113
|
type: "task:settle",
|
|
123
114
|
poolId: this.poolId,
|
|
124
|
-
callId:
|
|
125
|
-
taskId:
|
|
115
|
+
callId: n.callId,
|
|
116
|
+
taskId: n.contract.taskId,
|
|
126
117
|
outcome: "error",
|
|
127
118
|
runMs: s,
|
|
128
|
-
error:
|
|
129
|
-
}),
|
|
119
|
+
error: t.error
|
|
120
|
+
}), c(this.poolId, n.contract.taskId, n.callId, this.slots.indexOf(e), r, r + s, !1)), n.reject(Error(t.error)));
|
|
130
121
|
}
|
|
131
122
|
this.drainQueue(), this.checkDrained();
|
|
132
123
|
}
|
|
133
124
|
}
|
|
134
|
-
|
|
125
|
+
lifecycle(e, t, n) {
|
|
126
|
+
this.onLifecycle?.({
|
|
127
|
+
type: e,
|
|
128
|
+
poolId: this.poolId,
|
|
129
|
+
slot: t,
|
|
130
|
+
message: n
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
handleWorkerError(e, t) {
|
|
135
134
|
if (this.closed) return;
|
|
136
|
-
let
|
|
135
|
+
let n = t, i = n?.message ?? (n?.error ? String(n.error) : "worker error");
|
|
137
136
|
v.warn(`worker error: ${i}`);
|
|
138
|
-
let
|
|
139
|
-
|
|
137
|
+
let o = this.slots.indexOf(e);
|
|
138
|
+
a({
|
|
140
139
|
type: "worker:error",
|
|
141
140
|
poolId: this.poolId,
|
|
142
|
-
slot:
|
|
141
|
+
slot: o,
|
|
143
142
|
message: i
|
|
144
|
-
});
|
|
145
|
-
for (let [
|
|
146
|
-
if (this.pending.delete(
|
|
147
|
-
|
|
143
|
+
}), this.lifecycle("error", o >= 0 ? o : void 0, i);
|
|
144
|
+
for (let [t, n] of [...this.pending]) if (n.slot === e) {
|
|
145
|
+
if (this.pending.delete(t), this.detach(n), n.done) continue;
|
|
146
|
+
n.done = !0, this.statsAgg.failed++, a({
|
|
148
147
|
type: "task:settle",
|
|
149
148
|
poolId: this.poolId,
|
|
150
|
-
callId:
|
|
151
|
-
taskId:
|
|
149
|
+
callId: n.callId,
|
|
150
|
+
taskId: n.contract.taskId,
|
|
152
151
|
outcome: "crashed",
|
|
153
152
|
error: i
|
|
154
|
-
}),
|
|
153
|
+
}), n.reject(new r(i));
|
|
155
154
|
}
|
|
156
|
-
if (
|
|
155
|
+
if (o >= 0 && this.slots.splice(o, 1), e.worker.terminate(), this.respawn) v.info("respawning crashed worker"), this.addWorker(this.spawn()), a({
|
|
157
156
|
type: "worker:respawn",
|
|
158
157
|
poolId: this.poolId,
|
|
159
158
|
slot: this.slots.length - 1
|
|
160
|
-
});
|
|
161
|
-
else if (this.slots.length === 0) for (let e of this.queue.splice(0)) e.done = !0, this.detach(e), this.statsAgg.failed++,
|
|
159
|
+
}), this.lifecycle("respawn", this.slots.length - 1);
|
|
160
|
+
else if (this.slots.length === 0) for (let e of this.queue.splice(0)) e.done = !0, this.detach(e), this.statsAgg.failed++, a({
|
|
162
161
|
type: "task:settle",
|
|
163
162
|
poolId: this.poolId,
|
|
164
163
|
callId: e.callId,
|
|
165
164
|
taskId: e.contract.taskId,
|
|
166
165
|
outcome: "crashed",
|
|
167
166
|
error: i
|
|
168
|
-
}), e.reject(new
|
|
167
|
+
}), e.reject(new r(i));
|
|
169
168
|
this.drainQueue(), this.checkDrained();
|
|
170
169
|
}
|
|
171
170
|
pickWorker() {
|
|
@@ -180,55 +179,55 @@ var v = a("pool"), y = a("task"), b = () => ({
|
|
|
180
179
|
t.done || this.send(e, t);
|
|
181
180
|
}
|
|
182
181
|
}
|
|
183
|
-
send(
|
|
184
|
-
let
|
|
185
|
-
|
|
186
|
-
let
|
|
187
|
-
this.statsAgg.waitMs.add(
|
|
188
|
-
let
|
|
189
|
-
y.debug(`→ ${
|
|
190
|
-
worker:
|
|
191
|
-
args:
|
|
192
|
-
}),
|
|
182
|
+
send(e, t) {
|
|
183
|
+
let r = this.nextMessageId++;
|
|
184
|
+
t.messageId = r, t.slot = e, t.sentAt = performance.now();
|
|
185
|
+
let s = t.sentAt - t.enqueuedAt;
|
|
186
|
+
this.statsAgg.waitMs.add(s), e.inFlight++, this.pending.set(r, t);
|
|
187
|
+
let c = this.slots.indexOf(e);
|
|
188
|
+
y.debug(`→ ${t.contract.taskId}`, {
|
|
189
|
+
worker: c,
|
|
190
|
+
args: t.args
|
|
191
|
+
}), i() && a({
|
|
193
192
|
type: "task:dispatch",
|
|
194
193
|
poolId: this.poolId,
|
|
195
|
-
callId:
|
|
196
|
-
taskId:
|
|
197
|
-
slot:
|
|
198
|
-
waitMs:
|
|
199
|
-
argBytes:
|
|
194
|
+
callId: t.callId,
|
|
195
|
+
taskId: t.contract.taskId,
|
|
196
|
+
slot: c,
|
|
197
|
+
waitMs: s,
|
|
198
|
+
argBytes: o(t.args)
|
|
200
199
|
});
|
|
201
200
|
let l = {
|
|
202
201
|
type: "EXECUTE_TASK",
|
|
203
|
-
messageId:
|
|
204
|
-
taskId:
|
|
205
|
-
args:
|
|
202
|
+
messageId: r,
|
|
203
|
+
taskId: t.contract.taskId,
|
|
204
|
+
args: t.args
|
|
206
205
|
};
|
|
207
206
|
this.chaos ? g(this.chaos, {
|
|
208
|
-
live: () => this.pending.get(
|
|
209
|
-
fail: () => this.handleReply(
|
|
210
|
-
messageId:
|
|
207
|
+
live: () => this.pending.get(r) === t,
|
|
208
|
+
fail: () => this.handleReply(e, {
|
|
209
|
+
messageId: r,
|
|
211
210
|
taskId: l.taskId,
|
|
212
211
|
success: !1,
|
|
213
212
|
error: m
|
|
214
213
|
}),
|
|
215
|
-
timeout: () => this.cancel(
|
|
216
|
-
post: () =>
|
|
217
|
-
}) :
|
|
214
|
+
timeout: () => this.cancel(t, new n()),
|
|
215
|
+
post: () => e.worker.postMessage(l)
|
|
216
|
+
}) : e.worker.postMessage(l);
|
|
218
217
|
}
|
|
219
218
|
detach(e) {
|
|
220
219
|
e.timer && clearTimeout(e.timer), e.signal && e.onSignalAbort && e.signal.removeEventListener("abort", e.onSignalAbort);
|
|
221
220
|
}
|
|
222
|
-
cancel(e,
|
|
221
|
+
cancel(e, t) {
|
|
223
222
|
if (e.done) return;
|
|
224
223
|
let r = this.queue.indexOf(e);
|
|
225
|
-
r >= 0 && this.queue.splice(r, 1), e.done = !0, this.detach(e), this.statsAgg.aborted++,
|
|
224
|
+
r >= 0 && this.queue.splice(r, 1), e.done = !0, this.detach(e), this.statsAgg.aborted++, a({
|
|
226
225
|
type: "task:settle",
|
|
227
226
|
poolId: this.poolId,
|
|
228
227
|
callId: e.callId,
|
|
229
228
|
taskId: e.contract.taskId,
|
|
230
|
-
outcome:
|
|
231
|
-
}), e.reject(
|
|
229
|
+
outcome: t instanceof n ? "timeout" : "aborted"
|
|
230
|
+
}), e.reject(t), this.drainQueue(), this.checkDrained();
|
|
232
231
|
}
|
|
233
232
|
checkDrained() {
|
|
234
233
|
if (this.queue.length === 0 && this.pending.size === 0) {
|
|
@@ -236,36 +235,36 @@ var v = a("pool"), y = a("task"), b = () => ({
|
|
|
236
235
|
for (let t of e) t();
|
|
237
236
|
}
|
|
238
237
|
}
|
|
239
|
-
dispatch(
|
|
240
|
-
return this.closed || this.slots.length === 0 ? Promise.reject(new
|
|
238
|
+
dispatch(i, o, s) {
|
|
239
|
+
return this.closed || this.slots.length === 0 ? Promise.reject(new r("WorkerPool has been terminated — no workers available.")) : s?.signal?.aborted ? Promise.reject(new t()) : new Promise((r, c) => {
|
|
241
240
|
let l = {
|
|
242
|
-
contract:
|
|
243
|
-
args:
|
|
241
|
+
contract: i,
|
|
242
|
+
args: o,
|
|
244
243
|
callId: ++this.nextCallId,
|
|
245
244
|
enqueuedAt: performance.now(),
|
|
246
|
-
resolve:
|
|
247
|
-
reject:
|
|
245
|
+
resolve: r,
|
|
246
|
+
reject: c,
|
|
248
247
|
done: !1,
|
|
249
|
-
signal:
|
|
248
|
+
signal: s?.signal
|
|
250
249
|
};
|
|
251
|
-
|
|
252
|
-
let u =
|
|
253
|
-
u !== void 0 && (l.timer = setTimeout(() => this.cancel(l, new
|
|
250
|
+
s?.signal && (l.onSignalAbort = () => this.cancel(l, new t()), s.signal.addEventListener("abort", l.onSignalAbort, { once: !0 }));
|
|
251
|
+
let u = s?.timeout ?? this.taskTimeout;
|
|
252
|
+
u !== void 0 && (l.timer = setTimeout(() => this.cancel(l, new n()), u)), a({
|
|
254
253
|
type: "task:enqueue",
|
|
255
254
|
poolId: this.poolId,
|
|
256
255
|
callId: l.callId,
|
|
257
|
-
taskId:
|
|
256
|
+
taskId: i.taskId
|
|
258
257
|
});
|
|
259
258
|
let d = this.pickWorker();
|
|
260
259
|
if (d) this.send(d, l);
|
|
261
260
|
else if (this.queue.length >= this.maxQueue) {
|
|
262
|
-
l.done = !0, this.detach(l),
|
|
261
|
+
l.done = !0, this.detach(l), a({
|
|
263
262
|
type: "task:settle",
|
|
264
263
|
poolId: this.poolId,
|
|
265
264
|
callId: l.callId,
|
|
266
|
-
taskId:
|
|
265
|
+
taskId: i.taskId,
|
|
267
266
|
outcome: "queue-full"
|
|
268
|
-
}),
|
|
267
|
+
}), c(new e());
|
|
269
268
|
return;
|
|
270
269
|
} else this.queue.push(l);
|
|
271
270
|
});
|
|
@@ -308,31 +307,30 @@ var v = a("pool"), y = a("task"), b = () => ({
|
|
|
308
307
|
});
|
|
309
308
|
}
|
|
310
309
|
terminate() {
|
|
311
|
-
this.closed = !0, this.devtoolsOff?.(), this.persistence?.stop()?.catch?.((e) => v.warn("memory persistence stop failed", e)), v.info(`terminating ${this.slots.length} worker(s)`),
|
|
310
|
+
this.closed = !0, this.lifecycle("terminate"), this.devtoolsOff?.(), this.persistence?.stop()?.catch?.((e) => v.warn("memory persistence stop failed", e)), v.info(`terminating ${this.slots.length} worker(s)`), a({
|
|
312
311
|
type: "pool:terminate",
|
|
313
312
|
poolId: this.poolId
|
|
314
313
|
});
|
|
315
|
-
let e = new
|
|
316
|
-
for (let [,
|
|
314
|
+
let e = new r("pool terminated");
|
|
315
|
+
for (let [, t] of this.pending) this.detach(t), t.done || (t.done = !0, this.statsAgg.failed++, a({
|
|
317
316
|
type: "task:settle",
|
|
318
317
|
poolId: this.poolId,
|
|
319
|
-
callId:
|
|
320
|
-
taskId:
|
|
318
|
+
callId: t.callId,
|
|
319
|
+
taskId: t.contract.taskId,
|
|
321
320
|
outcome: "crashed",
|
|
322
321
|
error: "pool terminated"
|
|
323
|
-
}),
|
|
322
|
+
}), t.reject(e));
|
|
324
323
|
this.pending.clear();
|
|
325
|
-
for (let
|
|
324
|
+
for (let t of this.queue.splice(0)) t.done = !0, this.detach(t), this.statsAgg.failed++, a({
|
|
326
325
|
type: "task:settle",
|
|
327
326
|
poolId: this.poolId,
|
|
328
|
-
callId:
|
|
329
|
-
taskId:
|
|
327
|
+
callId: t.callId,
|
|
328
|
+
taskId: t.contract.taskId,
|
|
330
329
|
outcome: "crashed",
|
|
331
330
|
error: "pool terminated"
|
|
332
|
-
}),
|
|
331
|
+
}), t.reject(e);
|
|
333
332
|
for (let e of this.slots) e.worker.terminate();
|
|
334
333
|
this.slots = [], this.checkDrained();
|
|
335
334
|
}
|
|
336
335
|
};
|
|
337
|
-
//#endregion
|
|
338
336
|
export { x as WorkerPool };
|
package/dist/reactive.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { scoped as e } from "./log.js";
|
|
2
2
|
import { disposeNodes as t, graphNode as n, graphSource as r } from "./reactiveGraph.js";
|
|
3
3
|
import { createEffect as i, createMemo as a, createRenderEffect as o, createRoot as s, createSignal as c } from "solid-js";
|
|
4
|
-
|
|
4
|
+
// src/reactive.ts
|
|
5
5
|
var l = e("reactive");
|
|
6
6
|
function u(e, t) {
|
|
7
7
|
if (e === t) return !0;
|
|
@@ -109,5 +109,4 @@ function v(e, r, o, u, f) {
|
|
|
109
109
|
}
|
|
110
110
|
};
|
|
111
111
|
}
|
|
112
|
-
//#endregion
|
|
113
112
|
export { g as reactive, u as shallowEqual, _ as watch, v as watchNodes };
|
package/dist/reactiveGraph.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { devtoolsEnabled as e, emitDevtools as t, registerDevtoolsCommand as n } from "./devtools.js";
|
|
2
|
-
|
|
2
|
+
// src/reactiveGraph.ts
|
|
3
3
|
var r = typeof WorkerGlobalScope < "u" && self instanceof WorkerGlobalScope ? "worker" : "main", i = 0, a = /* @__PURE__ */ new Map(), o = !1, s = (e, n) => {
|
|
4
4
|
t({
|
|
5
5
|
type: "reactive:node",
|
|
@@ -42,5 +42,4 @@ var r = typeof WorkerGlobalScope < "u" && self instanceof WorkerGlobalScope ? "w
|
|
|
42
42
|
t && (a.delete(n), e() && s(t, !0));
|
|
43
43
|
}
|
|
44
44
|
};
|
|
45
|
-
//#endregion
|
|
46
45
|
export { f as disposeNodes, u as graphNode, l as graphSource, d as relabelNode };
|
package/dist/service.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { scoped as e } from "./log.js";
|
|
2
2
|
import { TaskRegistry as t } from "./worker/registry.js";
|
|
3
|
-
|
|
3
|
+
// src/service.ts
|
|
4
4
|
var n = e("service");
|
|
5
5
|
function r(e = {}) {
|
|
6
6
|
return e;
|
|
@@ -44,5 +44,4 @@ function s(e, t) {
|
|
|
44
44
|
for (let [r, i] of Object.entries(e.tasks)) n[r] = (...e) => t.runTask(i, ...e);
|
|
45
45
|
return n;
|
|
46
46
|
}
|
|
47
|
-
//#endregion
|
|
48
47
|
export { s as createClient, a as defineService, o as implementService, r as rpc, i as serviceMethod };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { scoped as e } from "../log.js";
|
|
2
|
-
|
|
2
|
+
// src/shared/sharedWorkerClient.ts
|
|
3
3
|
var t = e("shared-client"), n = e("task"), r = class {
|
|
4
4
|
clientIndex;
|
|
5
5
|
sharedMemory;
|
|
@@ -7,13 +7,7 @@ var t = e("shared-client"), n = e("task"), r = class {
|
|
|
7
7
|
constructor(e, n, r) {
|
|
8
8
|
this.clientIndex = n, this.port = e, this.sharedMemory = r.sharedMemory;
|
|
9
9
|
let i = r.tasks ?? {};
|
|
10
|
-
for (let [e, n] of Object.entries(i)) {
|
|
11
|
-
if (e in this) {
|
|
12
|
-
t.warn(`task "${e}" collides with a SharedWorkerClient member — not installed`);
|
|
13
|
-
continue;
|
|
14
|
-
}
|
|
15
|
-
this[e] = (...e) => this.runTask(n, ...e);
|
|
16
|
-
}
|
|
10
|
+
for (let [e, n] of Object.entries(i)) e in this ? t.warn(`task "${e}" collides with a SharedWorkerClient member — not installed`) : this[e] = (...e) => this.runTask(n, ...e);
|
|
17
11
|
Object.keys(i).length > 0 && t.info(`task methods: ${Object.keys(i).join(", ")}`);
|
|
18
12
|
}
|
|
19
13
|
runTask(e, ...t) {
|
|
@@ -60,5 +54,4 @@ async function i(e) {
|
|
|
60
54
|
});
|
|
61
55
|
});
|
|
62
56
|
}
|
|
63
|
-
//#endregion
|
|
64
57
|
export { i as connectSharedWorker };
|
|
@@ -1,32 +1,30 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
var a =
|
|
7
|
-
function c(
|
|
8
|
-
if (o) return o.buffer.byteLength <
|
|
9
|
-
let s = new
|
|
10
|
-
return s.ensureCapacity(
|
|
1
|
+
import { bindSharedMemories as e } from "../contract/sharedMemory.js";
|
|
2
|
+
import { MemoryManager as t } from "../pool/memory.js";
|
|
3
|
+
import { TaskRegistry as n } from "../worker/registry.js";
|
|
4
|
+
import { fmtBytes as r, scoped as i } from "../log.js";
|
|
5
|
+
// src/shared/sharedWorkerHost.ts
|
|
6
|
+
var a = i("shared-worker"), o = null, s = 0;
|
|
7
|
+
function c(n, i) {
|
|
8
|
+
if (o) return o.buffer.byteLength < n && a.warn(`client requested ${r(n)} but buffer is ${r(o.buffer.byteLength)} — first client's capacity wins`), o;
|
|
9
|
+
let s = new t(i);
|
|
10
|
+
return s.ensureCapacity(n), o = s.memory, e(s.getBuffer()), a.info(`shared buffer allocated (${r(o.buffer.byteLength)})`), o;
|
|
11
11
|
}
|
|
12
12
|
function l(e) {
|
|
13
13
|
let t = ++s;
|
|
14
|
-
a.info(`client #${t} connected`), e.onmessage = async (
|
|
15
|
-
let
|
|
16
|
-
if (
|
|
17
|
-
let n = c(
|
|
14
|
+
a.info(`client #${t} connected`), e.onmessage = async (r) => {
|
|
15
|
+
let i = r.data;
|
|
16
|
+
if (i?.type === "SHARED_CONNECT") {
|
|
17
|
+
let n = c(i.memoryBytes ?? 0, i.memory);
|
|
18
18
|
e.postMessage({
|
|
19
19
|
type: "SHARED_MEMORY",
|
|
20
20
|
buffer: n.buffer,
|
|
21
21
|
clientIndex: t
|
|
22
22
|
});
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (r?.type === "EXECUTE_TASK") {
|
|
26
|
-
let { messageId: n, taskId: s, args: c } = r;
|
|
23
|
+
} else if (i?.type === "EXECUTE_TASK") {
|
|
24
|
+
let { messageId: r, taskId: s, args: c } = i;
|
|
27
25
|
if (!o) {
|
|
28
26
|
e.postMessage({
|
|
29
|
-
messageId:
|
|
27
|
+
messageId: r,
|
|
30
28
|
success: !1,
|
|
31
29
|
error: "Shared memory not initialized in worker."
|
|
32
30
|
});
|
|
@@ -34,22 +32,20 @@ function l(e) {
|
|
|
34
32
|
}
|
|
35
33
|
let l = performance.now();
|
|
36
34
|
try {
|
|
37
|
-
let
|
|
35
|
+
let i = await n.execute(s, ...c || []);
|
|
38
36
|
a.debug(`task ${s} → ${(performance.now() - l).toFixed(1)}ms (client #${t})`), e.postMessage({
|
|
39
|
-
messageId:
|
|
37
|
+
messageId: r,
|
|
40
38
|
success: !0,
|
|
41
|
-
result:
|
|
39
|
+
result: i
|
|
42
40
|
});
|
|
43
41
|
} catch (t) {
|
|
44
42
|
a.warn(`task ${s} failed: ${t.message || String(t)}`), e.postMessage({
|
|
45
|
-
messageId:
|
|
43
|
+
messageId: r,
|
|
46
44
|
success: !1,
|
|
47
45
|
error: t.message || String(t)
|
|
48
46
|
});
|
|
49
47
|
}
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
r?.type === "SHARED_DISCONNECT" && (e.close(), a.info(`client #${t} disconnected`));
|
|
48
|
+
} else i?.type === "SHARED_DISCONNECT" && (e.close(), a.info(`client #${t} disconnected`));
|
|
53
49
|
}, e.start();
|
|
54
50
|
}
|
|
55
51
|
function u() {
|
|
@@ -57,5 +53,4 @@ function u() {
|
|
|
57
53
|
l(e.ports[0]);
|
|
58
54
|
};
|
|
59
55
|
}
|
|
60
|
-
//#endregion
|
|
61
56
|
export { l as attachSharedPort, u as sharedWorkerHost };
|
package/dist/task.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { scoped as e } from "./log.js";
|
|
2
|
-
|
|
2
|
+
// src/task.ts
|
|
3
3
|
var t = e("task");
|
|
4
4
|
function n(e) {
|
|
5
5
|
let n = 0, r = {
|
|
@@ -53,5 +53,4 @@ function r(e) {
|
|
|
53
53
|
function i(e) {
|
|
54
54
|
return r(e) ? e : n(e);
|
|
55
55
|
}
|
|
56
|
-
//#endregion
|
|
57
56
|
export { n as defineTask, r as isAsyncTask, i as toTask };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { bindSharedMemories as e } from "../contract/sharedMemory.js";
|
|
2
2
|
import { TaskRegistry as t } from "../worker/registry.js";
|
|
3
|
-
|
|
3
|
+
// src/testing/inProcessWorker.ts
|
|
4
4
|
var n = class n {
|
|
5
5
|
url;
|
|
6
6
|
options;
|
|
@@ -46,9 +46,7 @@ var n = class n {
|
|
|
46
46
|
} catch (e) {
|
|
47
47
|
this.crashOnBoot(e);
|
|
48
48
|
}
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
if (n.type === "INIT_MEMORY") {
|
|
49
|
+
} else if (n.type === "INIT_MEMORY") {
|
|
52
50
|
let t = n.memory?.buffer ?? n.buffer;
|
|
53
51
|
this.ready ??= this.boot().then(() => {
|
|
54
52
|
t && e(t);
|
|
@@ -58,9 +56,7 @@ var n = class n {
|
|
|
58
56
|
} catch (e) {
|
|
59
57
|
this.crashOnBoot(e);
|
|
60
58
|
}
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
if (n.type === "EXECUTE_TASK") {
|
|
59
|
+
} else if (n.type === "EXECUTE_TASK") {
|
|
64
60
|
if (this.dead) return;
|
|
65
61
|
try {
|
|
66
62
|
await this.ready;
|
|
@@ -106,5 +102,4 @@ var n = class n {
|
|
|
106
102
|
this.terminated = !0;
|
|
107
103
|
}
|
|
108
104
|
}, r = () => new Promise((e) => setTimeout(e, 5));
|
|
109
|
-
//#endregion
|
|
110
105
|
export { n as InProcessWorker, r as flushObservers };
|
package/dist/userTiming.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// src/userTiming.ts
|
|
2
2
|
var e = (e, t, n, r) => {
|
|
3
3
|
let i = globalThis.performance;
|
|
4
4
|
if (typeof i?.measure == "function") try {
|
|
@@ -26,5 +26,4 @@ var e = (e, t, n, r) => {
|
|
|
26
26
|
],
|
|
27
27
|
tooltipText: `${n} on ${t}#${i}: ${(o - a).toFixed(1)}ms`
|
|
28
28
|
});
|
|
29
|
-
//#endregion
|
|
30
29
|
export { e as measureAtoll, t as measureTaskCall };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { installWorkerListener as e } from "./workerBootstrap.js";
|
|
2
2
|
import { TaskRegistry as t } from "./registry.js";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
var r =
|
|
3
|
+
import { scoped as n } from "../log.js";
|
|
4
|
+
// src/worker/defineWorker.ts
|
|
5
|
+
var r = n("worker"), i = [
|
|
6
6
|
"start",
|
|
7
7
|
"terminate",
|
|
8
8
|
"pool",
|
|
@@ -10,9 +10,9 @@ var r = e("worker"), i = [
|
|
|
10
10
|
"then",
|
|
11
11
|
"with"
|
|
12
12
|
], a = (e) => typeof e == "object" && !!e && "run" in e, o = new Set(i);
|
|
13
|
-
function s(
|
|
14
|
-
|
|
15
|
-
let i =
|
|
13
|
+
function s(n) {
|
|
14
|
+
e();
|
|
15
|
+
let i = n.methods ?? {}, s = n.services ?? {}, c = 0, l = (e, n, r, i) => {
|
|
16
16
|
if (o.has(n)) throw Error(`defineWorker: "${n}" is reserved for the client API — rename the method`);
|
|
17
17
|
if (a(r)) {
|
|
18
18
|
let { def: n } = r;
|
|
@@ -35,7 +35,6 @@ function s(e) {
|
|
|
35
35
|
methods: i,
|
|
36
36
|
services: s
|
|
37
37
|
};
|
|
38
|
-
return
|
|
38
|
+
return n.sharedMemory && (u.sharedMemory = n.sharedMemory), u;
|
|
39
39
|
}
|
|
40
|
-
//#endregion
|
|
41
40
|
export { i as RESERVED_CLIENT_KEYS, s as defineWorker };
|
package/dist/worker/registry.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { scoped as e } from "../log.js";
|
|
2
|
-
|
|
2
|
+
// src/worker/registry.ts
|
|
3
3
|
var t = e("registry"), n = class {
|
|
4
4
|
static tasks = /* @__PURE__ */ new Map();
|
|
5
5
|
static register(e, n) {
|
|
@@ -21,5 +21,4 @@ var t = e("registry"), n = class {
|
|
|
21
21
|
return r.resultSchema ? r.resultSchema.parse(a) : a;
|
|
22
22
|
}
|
|
23
23
|
};
|
|
24
|
-
//#endregion
|
|
25
24
|
export { n as TaskRegistry };
|