@atolljs/core 0.1.6 → 0.1.8
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/README.md +1 -1
- package/dist/contract/memoryDevtools.d.ts +30 -0
- package/dist/contract/sharedMemory.d.ts +6 -2
- package/dist/contract/types.d.ts +13 -0
- package/dist/devtools.d.ts +346 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.js +19 -16
- package/dist/index10.js +28 -184
- package/dist/index11.js +18 -48
- package/dist/index12.js +29 -63
- package/dist/index13.js +49 -24
- package/dist/index14.js +57 -59
- package/dist/index15.js +335 -45
- package/dist/index16.js +242 -47
- package/dist/index17.js +57 -38
- package/dist/index18.js +9 -86
- package/dist/index19.js +58 -48
- package/dist/index20.js +24 -56
- package/dist/index21.js +61 -0
- package/dist/index22.js +48 -0
- package/dist/index23.js +68 -0
- package/dist/index24.js +41 -0
- package/dist/index25.js +46 -0
- package/dist/index26.js +113 -0
- package/dist/index27.js +60 -0
- package/dist/index28.js +57 -0
- package/dist/index5.js +227 -35
- package/dist/index6.js +143 -471
- package/dist/index7.js +51 -20
- package/dist/index8.js +507 -27
- package/dist/index9.js +19 -18
- package/dist/pool/dedicatedWorker.d.ts +63 -0
- package/dist/pool/devtoolsCommands.d.ts +54 -0
- package/dist/pool/subWorkerClient.d.ts +50 -0
- package/dist/pool/workerChannel.d.ts +44 -0
- package/dist/pool/workerClient.d.ts +38 -8
- package/dist/pool/workerPool.d.ts +13 -0
- package/dist/reactive.d.ts +15 -0
- package/dist/reactiveGraph.d.ts +9 -0
- package/dist/userTiming.d.ts +27 -0
- package/package.json +2 -1
- package/src/contract/memoryDevtools.ts +249 -0
- package/src/contract/sharedMemory.ts +39 -9
- package/src/contract/types.ts +13 -0
- package/src/devtools.ts +735 -0
- package/src/index.ts +27 -1
- package/src/log.ts +22 -0
- package/src/observable.ts +16 -3
- package/src/pool/dedicatedWorker.ts +332 -0
- package/src/pool/devtoolsCommands.ts +165 -0
- package/src/pool/subWorkerClient.ts +70 -0
- package/src/pool/workerChannel.ts +99 -0
- package/src/pool/workerClient.ts +64 -15
- package/src/pool/workerPool.ts +115 -36
- package/src/reactive.ts +87 -12
- package/src/reactiveGraph.ts +91 -0
- package/src/testing/inProcessWorker.ts +4 -3
- package/src/userTiming.ts +71 -0
- package/src/worker/workerBootstrap.ts +29 -3
package/dist/index10.js
CHANGED
|
@@ -1,191 +1,35 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
}), u = class {
|
|
13
|
-
slots = [];
|
|
14
|
-
pending = /* @__PURE__ */ new Map();
|
|
15
|
-
nextMessageId = 0;
|
|
16
|
-
queue = [];
|
|
17
|
-
memoryManager;
|
|
18
|
-
workerUrl;
|
|
19
|
-
spawn;
|
|
20
|
-
concurrency;
|
|
21
|
-
maxQueue;
|
|
22
|
-
respawn;
|
|
23
|
-
taskTimeout;
|
|
24
|
-
closed = !1;
|
|
25
|
-
drainWaiters = [];
|
|
26
|
-
statsAgg = {
|
|
27
|
-
completed: 0,
|
|
28
|
-
failed: 0,
|
|
29
|
-
aborted: 0,
|
|
30
|
-
waitMs: l(),
|
|
31
|
-
runMs: l()
|
|
32
|
-
};
|
|
33
|
-
sharedMemory;
|
|
34
|
-
persistence;
|
|
35
|
-
constructor(t) {
|
|
36
|
-
if (t.sharedMemory && (typeof SharedArrayBuffer > "u" || typeof crossOriginIsolated < "u" && !crossOriginIsolated)) throw Error("WorkerPool requires SharedArrayBuffer in a cross-origin isolated context — serve the page with COOP/COEP headers.");
|
|
37
|
-
if (!t.workerUrl && !t.createWorker) throw Error("WorkerPool requires either `workerUrl` or `createWorker` in its config.");
|
|
38
|
-
this.workerUrl = t.workerUrl, this.spawn = t.createWorker ?? (() => new Worker(this.workerUrl, { type: "module" })), this.concurrency = t.concurrency ?? 1, this.maxQueue = t.maxQueue ?? Infinity, this.respawn = t.respawn ?? !0, this.taskTimeout = t.taskTimeout, t.sharedMemory && (this.sharedMemory = t.sharedMemory, this.memoryManager = new n(t.memory), this.memoryManager.ensureCapacity(this.sharedMemory.totalBytes), this.sharedMemory.bind(this.memoryManager.getBuffer()), this.persistence = t.persistence?.(t.sharedMemory));
|
|
39
|
-
let r = t.poolSize ?? "auto", i = r === "auto" ? navigator.hardwareConcurrency ?? 4 : r;
|
|
40
|
-
s.info(this.sharedMemory ? `spawning ${i} worker(s) with ${e(this.sharedMemory.totalBytes)} shared buffer` : `spawning ${i} worker(s), message-only`, { workerUrl: t.workerUrl ? String(t.workerUrl) : "createWorker()" }), s.debug("tip: setLogLevel('trace') for per-task detail");
|
|
41
|
-
for (let e = 0; e < i; e++) this.addWorker(this.spawn());
|
|
42
|
-
let a = t.tasks ?? {};
|
|
43
|
-
for (let [e, t] of Object.entries(a)) {
|
|
44
|
-
if (e in this) {
|
|
45
|
-
s.warn(`task "${e}" collides with a WorkerPool member — not installed`);
|
|
46
|
-
continue;
|
|
47
|
-
}
|
|
48
|
-
this[e] = (...e) => this.runTask(t, ...e);
|
|
49
|
-
}
|
|
50
|
-
Object.keys(a).length > 0 && s.info(`task methods: ${Object.keys(a).join(", ")}`);
|
|
51
|
-
}
|
|
52
|
-
addWorker(e) {
|
|
53
|
-
let t = {
|
|
54
|
-
worker: e,
|
|
55
|
-
inFlight: 0
|
|
56
|
-
};
|
|
57
|
-
return e.addEventListener("message", (e) => {
|
|
58
|
-
this.handleReply(t, e.data);
|
|
59
|
-
}), e.addEventListener("error", (e) => {
|
|
60
|
-
this.handleWorkerError(t, e);
|
|
61
|
-
}), this.memoryManager ? e.postMessage({
|
|
62
|
-
type: "INIT_MEMORY",
|
|
63
|
-
memory: this.memoryManager.memory
|
|
64
|
-
}) : e.postMessage({ type: "INIT" }), this.slots.push(t), s.debug(`worker spawned, ${this.memoryManager ? "INIT_MEMORY" : "INIT"} sent`), t;
|
|
65
|
-
}
|
|
66
|
-
handleReply(e, t) {
|
|
67
|
-
let n = t.messageId === void 0 ? void 0 : this.pending.get(t.messageId);
|
|
68
|
-
n && (this.pending.delete(t.messageId), e.inFlight--, this.detach(n), n.done || (n.done = !0, this.statsAgg.runMs.add(performance.now() - (n.sentAt ?? n.enqueuedAt)), t.success ? (this.statsAgg.completed++, c.debug(`← ${n.contract.taskId} ok`), n.resolve(t.result)) : (this.statsAgg.failed++, c.warn(`← ${n.contract.taskId} failed: ${t.error}`), n.reject(Error(t.error)))), this.drainQueue(), this.checkDrained());
|
|
69
|
-
}
|
|
70
|
-
handleWorkerError(e, t) {
|
|
71
|
-
if (this.closed) return;
|
|
72
|
-
let n = t, r = n?.message ?? (n?.error ? String(n.error) : "worker error");
|
|
73
|
-
s.warn(`worker error: ${r}`);
|
|
74
|
-
for (let [t, n] of [...this.pending]) if (n.slot === e) {
|
|
75
|
-
if (this.pending.delete(t), this.detach(n), n.done) continue;
|
|
76
|
-
n.done = !0, this.statsAgg.failed++, n.reject(new o(r));
|
|
77
|
-
}
|
|
78
|
-
let i = this.slots.indexOf(e);
|
|
79
|
-
if (i >= 0 && this.slots.splice(i, 1), e.worker.terminate(), this.respawn) s.info("respawning crashed worker"), this.addWorker(this.spawn());
|
|
80
|
-
else if (this.slots.length === 0) for (let e of this.queue.splice(0)) e.done = !0, this.detach(e), this.statsAgg.failed++, e.reject(new o(r));
|
|
81
|
-
this.drainQueue(), this.checkDrained();
|
|
82
|
-
}
|
|
83
|
-
pickWorker() {
|
|
84
|
-
let e;
|
|
85
|
-
for (let t of this.slots) t.inFlight >= this.concurrency || (!e || t.inFlight < e.inFlight) && (e = t);
|
|
86
|
-
return e;
|
|
87
|
-
}
|
|
88
|
-
drainQueue() {
|
|
89
|
-
let e;
|
|
90
|
-
for (; this.queue.length > 0 && (e = this.pickWorker());) {
|
|
91
|
-
let t = this.queue.shift();
|
|
92
|
-
t.done || this.send(e, t);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
send(e, t) {
|
|
96
|
-
let n = this.nextMessageId++;
|
|
97
|
-
t.messageId = n, t.slot = e, t.sentAt = performance.now(), this.statsAgg.waitMs.add(performance.now() - t.enqueuedAt), e.inFlight++, this.pending.set(n, t), c.debug(`→ ${t.contract.taskId}`, {
|
|
98
|
-
worker: this.slots.indexOf(e),
|
|
99
|
-
args: t.args
|
|
100
|
-
}), e.worker.postMessage({
|
|
101
|
-
type: "EXECUTE_TASK",
|
|
102
|
-
messageId: n,
|
|
103
|
-
taskId: t.contract.taskId,
|
|
104
|
-
args: t.args
|
|
1
|
+
//#region src/pool/memory.ts
|
|
2
|
+
var e = class {
|
|
3
|
+
memory;
|
|
4
|
+
maxPages;
|
|
5
|
+
constructor(e = {}) {
|
|
6
|
+
let t = e.initialPages ?? 16;
|
|
7
|
+
this.maxPages = e.maximumPages ?? 16384, this.memory = new WebAssembly.Memory({
|
|
8
|
+
initial: t,
|
|
9
|
+
maximum: this.maxPages,
|
|
10
|
+
shared: !0
|
|
105
11
|
});
|
|
106
12
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
if (
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
13
|
+
ensureCapacity(e) {
|
|
14
|
+
let t = this.memory.buffer.byteLength;
|
|
15
|
+
if (t >= e) return;
|
|
16
|
+
let n = e - t, r = Math.ceil(n / 65536);
|
|
17
|
+
if (this.memory.buffer.byteLength / 65536 + r > this.maxPages) throw Error(`Cannot grow memory: exceeds maximum page limit of ${this.maxPages}`);
|
|
18
|
+
this.memory.grow(r);
|
|
19
|
+
}
|
|
20
|
+
getView(e, t = 0, n) {
|
|
21
|
+
let r = this.memory.buffer;
|
|
22
|
+
switch (e) {
|
|
23
|
+
case "Int32": return new Int32Array(r, t, n);
|
|
24
|
+
case "Float64": return new Float64Array(r, t, n);
|
|
25
|
+
case "BigInt64": return new BigInt64Array(r, t, n);
|
|
26
|
+
case "Uint8": return new Uint8Array(r, t, n);
|
|
27
|
+
default: throw Error(`Unsupported view type: ${e}`);
|
|
119
28
|
}
|
|
120
29
|
}
|
|
121
|
-
|
|
122
|
-
return this.
|
|
123
|
-
let c = {
|
|
124
|
-
contract: e,
|
|
125
|
-
args: t,
|
|
126
|
-
enqueuedAt: performance.now(),
|
|
127
|
-
resolve: o,
|
|
128
|
-
reject: s,
|
|
129
|
-
done: !1,
|
|
130
|
-
signal: n?.signal
|
|
131
|
-
};
|
|
132
|
-
n?.signal && (c.onSignalAbort = () => this.cancel(c, new i()), n.signal.addEventListener("abort", c.onSignalAbort, { once: !0 }));
|
|
133
|
-
let l = n?.timeout ?? this.taskTimeout;
|
|
134
|
-
l !== void 0 && (c.timer = setTimeout(() => this.cancel(c, new a()), l));
|
|
135
|
-
let u = this.pickWorker();
|
|
136
|
-
if (u) this.send(u, c);
|
|
137
|
-
else if (this.queue.length >= this.maxQueue) {
|
|
138
|
-
c.done = !0, this.detach(c), s(new r());
|
|
139
|
-
return;
|
|
140
|
-
} else this.queue.push(c);
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
runTask(e, ...t) {
|
|
144
|
-
return this.dispatch(e, t);
|
|
145
|
-
}
|
|
146
|
-
get sharedBuffer() {
|
|
147
|
-
return this.memoryManager?.getBuffer();
|
|
148
|
-
}
|
|
149
|
-
get workers() {
|
|
150
|
-
return this.slots.map((e) => e.worker);
|
|
151
|
-
}
|
|
152
|
-
stats() {
|
|
153
|
-
return {
|
|
154
|
-
workers: this.slots.length,
|
|
155
|
-
idle: this.slots.filter((e) => e.inFlight === 0).length,
|
|
156
|
-
inFlight: this.pending.size,
|
|
157
|
-
queued: this.queue.length,
|
|
158
|
-
completed: this.statsAgg.completed,
|
|
159
|
-
failed: this.statsAgg.failed,
|
|
160
|
-
aborted: this.statsAgg.aborted,
|
|
161
|
-
waitMs: {
|
|
162
|
-
count: this.statsAgg.waitMs.count,
|
|
163
|
-
mean: this.statsAgg.waitMs.mean,
|
|
164
|
-
max: this.statsAgg.waitMs.max
|
|
165
|
-
},
|
|
166
|
-
runMs: {
|
|
167
|
-
count: this.statsAgg.runMs.count,
|
|
168
|
-
mean: this.statsAgg.runMs.mean,
|
|
169
|
-
max: this.statsAgg.runMs.max
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
close() {
|
|
174
|
-
return this.queue.length === 0 && this.pending.size === 0 ? (this.terminate(), Promise.resolve()) : new Promise((e) => {
|
|
175
|
-
this.drainWaiters.push(() => {
|
|
176
|
-
this.terminate(), e();
|
|
177
|
-
});
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
terminate() {
|
|
181
|
-
this.closed = !0, this.persistence?.stop()?.catch?.((e) => s.warn("memory persistence stop failed", e)), s.info(`terminating ${this.slots.length} worker(s)`);
|
|
182
|
-
let e = new o("pool terminated");
|
|
183
|
-
for (let [, t] of this.pending) this.detach(t), !t.done && (t.done = !0, this.statsAgg.failed++, t.reject(e));
|
|
184
|
-
this.pending.clear();
|
|
185
|
-
for (let t of this.queue.splice(0)) t.done = !0, this.detach(t), this.statsAgg.failed++, t.reject(e);
|
|
186
|
-
for (let e of this.slots) e.worker.terminate();
|
|
187
|
-
this.slots = [], this.checkDrained();
|
|
30
|
+
getBuffer() {
|
|
31
|
+
return this.memory.buffer;
|
|
188
32
|
}
|
|
189
33
|
};
|
|
190
34
|
//#endregion
|
|
191
|
-
export {
|
|
35
|
+
export { e as MemoryManager };
|
package/dist/index11.js
CHANGED
|
@@ -1,50 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
1
|
+
//#region src/pool/errors.ts
|
|
2
|
+
var e = class extends Error {
|
|
3
|
+
constructor(e = "WorkerPool task queue is full") {
|
|
4
|
+
super(e), this.name = "PoolQueueFullError";
|
|
5
|
+
}
|
|
6
|
+
}, t = class extends Error {
|
|
7
|
+
constructor(e = "task aborted") {
|
|
8
|
+
super(e), this.name = "AbortError";
|
|
9
|
+
}
|
|
10
|
+
}, n = class extends Error {
|
|
11
|
+
constructor(e = "task timed out") {
|
|
12
|
+
super(e), this.name = "TaskTimeoutError";
|
|
13
|
+
}
|
|
14
|
+
}, r = class extends Error {
|
|
15
|
+
constructor(e = "worker crashed") {
|
|
16
|
+
super(e), this.name = "WorkerCrashedError";
|
|
17
|
+
}
|
|
18
18
|
};
|
|
19
|
-
function n(e) {
|
|
20
|
-
let n;
|
|
21
|
-
return t([], typeof e == "function" ? () => n ??= e() : () => e);
|
|
22
|
-
}
|
|
23
|
-
function r(n) {
|
|
24
|
-
let r = null, i = () => r ??= new e({
|
|
25
|
-
sharedMemory: n.sharedMemory,
|
|
26
|
-
createWorker: typeof n.worker == "function" ? n.worker : () => new Worker(n.worker, { type: "module" }),
|
|
27
|
-
poolSize: n.poolSize,
|
|
28
|
-
memory: n.memory,
|
|
29
|
-
concurrency: n.concurrency,
|
|
30
|
-
maxQueue: n.maxQueue,
|
|
31
|
-
respawn: n.respawn,
|
|
32
|
-
taskTimeout: n.taskTimeout
|
|
33
|
-
});
|
|
34
|
-
return n.lazy === !1 && i(), t([], i, {
|
|
35
|
-
start: () => {
|
|
36
|
-
i();
|
|
37
|
-
},
|
|
38
|
-
terminate: () => {
|
|
39
|
-
r?.terminate(), r = null;
|
|
40
|
-
},
|
|
41
|
-
get pool() {
|
|
42
|
-
return r;
|
|
43
|
-
},
|
|
44
|
-
get sharedMemory() {
|
|
45
|
-
return n.sharedMemory;
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
19
|
//#endregion
|
|
50
|
-
export {
|
|
20
|
+
export { e as PoolQueueFullError, t as TaskAbortedError, n as TaskTimeoutError, r as WorkerCrashedError };
|
package/dist/index12.js
CHANGED
|
@@ -1,64 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
this.port.addEventListener("message", s), this.port.postMessage({
|
|
32
|
-
type: "EXECUTE_TASK",
|
|
33
|
-
messageId: a,
|
|
34
|
-
taskId: e.taskId,
|
|
35
|
-
args: t
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
disconnect() {
|
|
40
|
-
try {
|
|
41
|
-
this.port.postMessage({ type: "SHARED_DISCONNECT" });
|
|
42
|
-
} finally {
|
|
43
|
-
this.port.close();
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
async function i(e) {
|
|
48
|
-
if (typeof SharedArrayBuffer > "u" || typeof crossOriginIsolated < "u" && !crossOriginIsolated) throw Error("connectSharedWorker requires SharedArrayBuffer in a cross-origin isolated context — serve the page with COOP/COEP headers.");
|
|
49
|
-
if (!e.port && !e.workerUrl && !e.createWorker) throw Error("connectSharedWorker requires `workerUrl`, `createWorker`, or `port` in its config.");
|
|
50
|
-
let n = e.port ?? (e.createWorker ? e.createWorker().port : new SharedWorker(e.workerUrl, { type: "module" }).port);
|
|
51
|
-
return n.start(), await new Promise((i, a) => {
|
|
52
|
-
let o = setTimeout(() => a(/* @__PURE__ */ Error("connectSharedWorker: timed out waiting for the shared worker — is the host module calling sharedWorkerHost()?")), e.connectTimeoutMs ?? 1e4), s = (a) => {
|
|
53
|
-
let c = a.data;
|
|
54
|
-
c?.type === "SHARED_MEMORY" && (n.removeEventListener("message", s), clearTimeout(o), e.sharedMemory.bind(c.buffer), t.info(`connected as client #${c.clientIndex}`, { bytes: c.buffer.byteLength }), i(new r(n, c.clientIndex, e)));
|
|
55
|
-
};
|
|
56
|
-
n.addEventListener("message", s), n.postMessage({
|
|
57
|
-
type: "SHARED_CONNECT",
|
|
58
|
-
memoryBytes: e.sharedMemory.totalBytes,
|
|
59
|
-
memory: e.memory
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
}
|
|
1
|
+
//#region src/userTiming.ts
|
|
2
|
+
var e = (e, t, n, r) => {
|
|
3
|
+
let i = globalThis.performance;
|
|
4
|
+
if (typeof i?.measure == "function") try {
|
|
5
|
+
i.measure(e, {
|
|
6
|
+
start: t,
|
|
7
|
+
end: Math.max(n, t),
|
|
8
|
+
detail: { devtools: {
|
|
9
|
+
dataType: "track-entry",
|
|
10
|
+
track: r.track,
|
|
11
|
+
trackGroup: "atoll",
|
|
12
|
+
color: r.color ?? "primary",
|
|
13
|
+
properties: r.properties,
|
|
14
|
+
tooltipText: r.tooltipText
|
|
15
|
+
} }
|
|
16
|
+
}), i.clearMeasures?.(e);
|
|
17
|
+
} catch {}
|
|
18
|
+
}, t = (t, n, r, i, a, o, s) => e(`atoll task ${n}`, a, o, {
|
|
19
|
+
track: t,
|
|
20
|
+
color: s ? "primary" : "error",
|
|
21
|
+
properties: [
|
|
22
|
+
["runner", t],
|
|
23
|
+
["slot", i],
|
|
24
|
+
["call", r],
|
|
25
|
+
["outcome", s ? "ok" : "error"]
|
|
26
|
+
],
|
|
27
|
+
tooltipText: `${n} on ${t}#${i}: ${(o - a).toFixed(1)}ms`
|
|
28
|
+
});
|
|
63
29
|
//#endregion
|
|
64
|
-
export {
|
|
30
|
+
export { e as measureAtoll, t as measureTaskCall };
|
package/dist/index13.js
CHANGED
|
@@ -1,25 +1,50 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
1
|
+
import { devtoolsEnabled as e, forwardDevtools as t } from "./index5.js";
|
|
2
|
+
import { MemoryManager as n } from "./index10.js";
|
|
3
|
+
//#region src/pool/workerChannel.ts
|
|
4
|
+
function r(e, t) {
|
|
5
|
+
if ((e.sharedMemory || e.sharedBuffer !== void 0) && (typeof SharedArrayBuffer > "u" || typeof crossOriginIsolated < "u" && !crossOriginIsolated)) throw Error(`${t} requires SharedArrayBuffer in a cross-origin isolated context — serve the page with COOP/COEP headers.`);
|
|
6
|
+
let r;
|
|
7
|
+
if (e.sharedBuffer !== void 0 && (r = typeof e.sharedBuffer == "function" ? e.sharedBuffer() : e.sharedBuffer, !r)) throw Error(`${t}: \`sharedBuffer\` resolved to an empty buffer — the producing pool or contract has no bound memory yet.`);
|
|
8
|
+
if (!e.sharedMemory) return {
|
|
9
|
+
sharedMemory: void 0,
|
|
10
|
+
injectedBuffer: r,
|
|
11
|
+
persistence: void 0
|
|
12
|
+
};
|
|
13
|
+
let i = e.sharedMemory, a;
|
|
14
|
+
return r ? i.bind(r) : (a = new n(e.memory), a.ensureCapacity(i.totalBytes), i.bind(a.getBuffer())), {
|
|
15
|
+
sharedMemory: i,
|
|
16
|
+
memoryManager: a,
|
|
17
|
+
injectedBuffer: r,
|
|
18
|
+
persistence: e.persistence?.(i)
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function i(t, n) {
|
|
22
|
+
return n.memoryManager ? (t.postMessage({
|
|
23
|
+
type: "INIT_MEMORY",
|
|
24
|
+
memory: n.memoryManager.memory,
|
|
25
|
+
devtools: e()
|
|
26
|
+
}), "INIT_MEMORY") : n.injectedBuffer ? (t.postMessage({
|
|
27
|
+
type: "INIT_MEMORY",
|
|
28
|
+
buffer: n.injectedBuffer,
|
|
29
|
+
devtools: e()
|
|
30
|
+
}), "INIT_MEMORY") : (t.postMessage({
|
|
31
|
+
type: "INIT",
|
|
32
|
+
devtools: e()
|
|
33
|
+
}), "INIT");
|
|
34
|
+
}
|
|
35
|
+
function a(e, n, r) {
|
|
36
|
+
let i = (t) => `${e}#${n}~${t}`;
|
|
37
|
+
t({
|
|
38
|
+
...r,
|
|
39
|
+
...r.poolId === void 0 ? {} : { poolId: i(r.poolId) },
|
|
40
|
+
worker: r.worker === void 0 ? {
|
|
41
|
+
poolId: e,
|
|
42
|
+
slot: n
|
|
43
|
+
} : {
|
|
44
|
+
poolId: i(r.worker.poolId),
|
|
45
|
+
slot: r.worker.slot
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
24
49
|
//#endregion
|
|
25
|
-
export {
|
|
50
|
+
export { a as forwardWorkerDevtools, i as sendInit, r as setupChannelMemory };
|
package/dist/index14.js
CHANGED
|
@@ -1,61 +1,59 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
1
|
+
import { registerDevtoolsCommand as e } from "./index5.js";
|
|
2
|
+
//#region src/pool/devtoolsCommands.ts
|
|
3
|
+
var t = "chaos: injected failure", n = "killed from devtools", r = /* @__PURE__ */ new Map(), i = null, a = (e) => {
|
|
4
|
+
let t = e.poolId;
|
|
5
|
+
if (typeof t != "string") throw Error("poolId (string) is required");
|
|
6
|
+
let n = r.get(t);
|
|
7
|
+
if (!n) throw Error(t.includes("~") ? `runner '${t}' lives inside a worker: nested pools are not controllable from the dashboard` : `no live runner '${t}' on this thread`);
|
|
8
|
+
return n;
|
|
9
|
+
}, o = (e, t) => {
|
|
10
|
+
if (e != null) {
|
|
11
|
+
if (typeof e != "number" || !Number.isFinite(e) || e < 0 || e > 1) throw Error(`${t} must be a number in 0..1`);
|
|
12
|
+
return e || void 0;
|
|
13
|
+
}
|
|
14
|
+
}, s = (e) => {
|
|
15
|
+
let { delayMs: t } = e;
|
|
16
|
+
if (t != null && (typeof t != "number" || !Number.isFinite(t) || t < 0)) throw Error("delayMs must be a non-negative number");
|
|
17
|
+
let n = o(e.failRate, "failRate"), r = o(e.timeoutRate, "timeoutRate");
|
|
18
|
+
if ((n ?? 0) + (r ?? 0) > 1) throw Error("failRate + timeoutRate must not exceed 1");
|
|
19
|
+
let i = {};
|
|
20
|
+
return t && (i.delayMs = t), n && (i.failRate = n), r && (i.timeoutRate = r), Object.keys(i).length ? i : null;
|
|
21
|
+
}, c = () => [...r.values()].map((e) => ({
|
|
22
|
+
poolId: e.poolId,
|
|
23
|
+
label: e.label ?? e.poolId,
|
|
24
|
+
size: e.size(),
|
|
25
|
+
dedicated: e.dedicated,
|
|
26
|
+
chaos: e.getChaos()
|
|
27
|
+
})), l = () => {
|
|
28
|
+
let t = [
|
|
29
|
+
e("pool.list", () => c()),
|
|
30
|
+
e("pool.stats", (e) => a(e).stats()),
|
|
31
|
+
e("worker.kill", (e) => {
|
|
32
|
+
let t = a(e), n = e.slot ?? 0;
|
|
33
|
+
if (typeof n != "number" || !Number.isInteger(n) || n < 0) throw Error("slot must be a non-negative integer");
|
|
34
|
+
return t.kill(n), {
|
|
35
|
+
poolId: t.poolId,
|
|
36
|
+
slot: n,
|
|
37
|
+
killed: !0
|
|
38
|
+
};
|
|
39
|
+
}),
|
|
40
|
+
e("pool.chaos", (e) => {
|
|
41
|
+
let t = a(e);
|
|
42
|
+
return t.setChaos(s(e)), t.getChaos();
|
|
43
|
+
})
|
|
44
|
+
];
|
|
45
|
+
return () => t.forEach((e) => e());
|
|
46
|
+
}, u = (e) => (r.set(e.poolId, e), i ??= l(), () => {
|
|
47
|
+
r.get(e.poolId) === e && (r.delete(e.poolId), r.size === 0 && i && (i(), i = null));
|
|
48
|
+
}), d = (e, t) => {
|
|
49
|
+
let n = Math.random(), r = n < (e.failRate ?? 0), i = !r && n < (e.failRate ?? 0) + (e.timeoutRate ?? 0);
|
|
50
|
+
if (!e.delayMs && !r && !i) return t.post();
|
|
51
|
+
setTimeout(() => {
|
|
52
|
+
if (t.live()) {
|
|
53
|
+
if (r) return t.fail();
|
|
54
|
+
i && t.timeout(), t.post();
|
|
24
55
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (!o) {
|
|
28
|
-
e.postMessage({
|
|
29
|
-
messageId: n,
|
|
30
|
-
success: !1,
|
|
31
|
-
error: "Shared memory not initialized in worker."
|
|
32
|
-
});
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
let l = performance.now();
|
|
36
|
-
try {
|
|
37
|
-
let r = await i.execute(s, ...c || []);
|
|
38
|
-
a.debug(`task ${s} → ${(performance.now() - l).toFixed(1)}ms (client #${t})`), e.postMessage({
|
|
39
|
-
messageId: n,
|
|
40
|
-
success: !0,
|
|
41
|
-
result: r
|
|
42
|
-
});
|
|
43
|
-
} catch (t) {
|
|
44
|
-
a.warn(`task ${s} failed: ${t.message || String(t)}`), e.postMessage({
|
|
45
|
-
messageId: n,
|
|
46
|
-
success: !1,
|
|
47
|
-
error: t.message || String(t)
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
r?.type === "SHARED_DISCONNECT" && (e.close(), a.info(`client #${t} disconnected`));
|
|
53
|
-
}, e.start();
|
|
54
|
-
}
|
|
55
|
-
function u() {
|
|
56
|
-
self.onconnect = (e) => {
|
|
57
|
-
l(e.ports[0]);
|
|
58
|
-
};
|
|
59
|
-
}
|
|
56
|
+
}, e.delayMs ?? 0);
|
|
57
|
+
};
|
|
60
58
|
//#endregion
|
|
61
|
-
export {
|
|
59
|
+
export { t as CHAOS_FAILURE, n as KILL_MESSAGE, d as applyChaos, s as parseChaos, u as registerDevtoolsRunner };
|