@atolljs/core 0.1.7 → 0.1.9
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 +4 -2
- package/dist/contract/types.d.ts +11 -0
- package/dist/devtools.d.ts +127 -4
- package/dist/index.d.ts +8 -4
- package/dist/index.js +19 -17
- package/dist/index10.js +29 -14
- package/dist/index11.js +14 -307
- package/dist/index12.js +29 -50
- package/dist/index13.js +46 -60
- package/dist/index14.js +56 -22
- package/dist/index15.js +332 -55
- package/dist/index16.js +246 -45
- package/dist/index17.js +56 -51
- package/dist/index18.js +9 -39
- package/dist/index19.js +56 -80
- package/dist/index20.js +24 -53
- package/dist/index21.js +56 -52
- 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 +135 -64
- package/dist/index6.js +160 -35
- package/dist/index7.js +45 -503
- package/dist/index8.js +513 -19
- package/dist/index9.js +19 -33
- 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 +36 -8
- package/dist/pool/workerPool.d.ts +10 -1
- package/dist/reactive.d.ts +15 -0
- package/dist/reactiveGraph.d.ts +9 -0
- package/dist/userTiming.d.ts +27 -0
- package/package.json +4 -3
- package/src/contract/memoryDevtools.ts +249 -0
- package/src/contract/sharedMemory.ts +20 -6
- package/src/contract/types.ts +11 -0
- package/src/devtools.ts +251 -6
- package/src/index.ts +13 -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 +61 -15
- package/src/pool/workerPool.ts +75 -45
- 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 +33 -5
package/dist/index17.js
CHANGED
|
@@ -1,55 +1,60 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
import { WorkerPool as e } from "./index15.js";
|
|
2
|
+
import { DedicatedWorker as t } from "./index16.js";
|
|
3
|
+
//#region src/pool/workerClient.ts
|
|
4
|
+
var n = (e, t, r, i) => {
|
|
5
|
+
let a = /* @__PURE__ */ new Map();
|
|
6
|
+
return new Proxy(() => {}, {
|
|
7
|
+
get(o, s) {
|
|
8
|
+
if (s === "then" || typeof s == "symbol") return;
|
|
9
|
+
if (s === "with") return (i) => n(e, t, r, i);
|
|
10
|
+
if (e.length === 0 && r && s in r) return Reflect.get(r, s);
|
|
11
|
+
let c = a.get(s);
|
|
12
|
+
return c || (c = n([...e, s], t, r, i), a.set(s, c)), c;
|
|
13
|
+
},
|
|
14
|
+
apply(n, r, a) {
|
|
15
|
+
let o = t(), s = { taskId: e.join(".") };
|
|
16
|
+
return o.dispatch ? o.dispatch(s, a, i) : o.runTask(s, ...a);
|
|
12
17
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
});
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
let r = performance.now();
|
|
35
|
-
try {
|
|
36
|
-
let i = await a.execute(t, ...n || []);
|
|
37
|
-
o.debug(`task ${t} → ${(performance.now() - r).toFixed(1)}ms`), self.postMessage({
|
|
38
|
-
messageId: e,
|
|
39
|
-
success: !0,
|
|
40
|
-
result: i
|
|
41
|
-
});
|
|
42
|
-
} catch (n) {
|
|
43
|
-
o.warn(`task ${t} failed: ${n.message || String(n)}`), self.postMessage({
|
|
44
|
-
messageId: e,
|
|
45
|
-
success: !1,
|
|
46
|
-
error: n.message || String(n)
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
}
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
function r(e) {
|
|
21
|
+
let t;
|
|
22
|
+
return n([], typeof e == "function" ? () => t ??= e() : () => e);
|
|
23
|
+
}
|
|
24
|
+
var i = (e) => e === "auto" ? typeof navigator < "u" ? navigator.hardwareConcurrency ?? 4 : 4 : Math.max(1, Math.floor(e ?? 1));
|
|
25
|
+
function a(r) {
|
|
26
|
+
let a = null, o = () => {
|
|
27
|
+
if (a) return a;
|
|
28
|
+
let n = i(r.workers ?? r.poolSize), o = {
|
|
29
|
+
sharedMemory: r.sharedMemory,
|
|
30
|
+
sharedBuffer: r.sharedBuffer,
|
|
31
|
+
createWorker: typeof r.worker == "function" ? r.worker : () => new Worker(r.worker, { type: "module" }),
|
|
32
|
+
name: r.name,
|
|
33
|
+
memory: r.memory,
|
|
34
|
+
respawn: r.respawn,
|
|
35
|
+
taskTimeout: r.taskTimeout
|
|
50
36
|
};
|
|
51
|
-
|
|
37
|
+
return a = n === 1 ? new t(o) : new e({
|
|
38
|
+
...o,
|
|
39
|
+
poolSize: n,
|
|
40
|
+
concurrency: r.concurrency,
|
|
41
|
+
maxQueue: r.maxQueue
|
|
42
|
+
}), a;
|
|
43
|
+
};
|
|
44
|
+
return r.lazy === !1 && o(), n([], o, {
|
|
45
|
+
start: () => {
|
|
46
|
+
o();
|
|
47
|
+
},
|
|
48
|
+
terminate: () => {
|
|
49
|
+
a?.terminate(), a = null;
|
|
50
|
+
},
|
|
51
|
+
get pool() {
|
|
52
|
+
return a;
|
|
53
|
+
},
|
|
54
|
+
get sharedMemory() {
|
|
55
|
+
return r.sharedMemory;
|
|
56
|
+
}
|
|
57
|
+
});
|
|
52
58
|
}
|
|
53
|
-
l();
|
|
54
59
|
//#endregion
|
|
55
|
-
export {
|
|
60
|
+
export { a as connectWorker, i as resolveWorkerCount, r as workerClient };
|
package/dist/index18.js
CHANGED
|
@@ -1,41 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
"sharedMemory",
|
|
10
|
-
"then",
|
|
11
|
-
"with"
|
|
12
|
-
], a = (e) => typeof e == "object" && !!e && "run" in e, o = new Set(i);
|
|
13
|
-
function s(e) {
|
|
14
|
-
n();
|
|
15
|
-
let i = e.methods ?? {}, s = e.services ?? {}, c = 0, l = (e, n, r, i) => {
|
|
16
|
-
if (o.has(n)) throw Error(`defineWorker: "${n}" is reserved for the client API — rename the method`);
|
|
17
|
-
if (a(r)) {
|
|
18
|
-
let { def: n } = r;
|
|
19
|
-
t.register({
|
|
20
|
-
taskId: n.taskId ?? e,
|
|
21
|
-
...n.dataType ? { dataType: n.dataType } : {},
|
|
22
|
-
...n.argsSchema ? { argsSchema: n.argsSchema } : {},
|
|
23
|
-
...n.resultSchema ? { resultSchema: n.resultSchema } : {}
|
|
24
|
-
}, r.run.bind(r));
|
|
25
|
-
} else t.register({ taskId: e }, r.bind(i));
|
|
26
|
-
c++;
|
|
27
|
-
};
|
|
28
|
-
for (let [e, t] of Object.entries(i)) l(e, e, t, i);
|
|
29
|
-
for (let [e, t] of Object.entries(s)) {
|
|
30
|
-
if (o.has(e)) throw Error(`defineWorker: service name "${e}" is reserved for the client API — rename it`);
|
|
31
|
-
for (let [n, r] of Object.entries(t)) l(`${e}.${n}`, n, r, t);
|
|
32
|
-
}
|
|
33
|
-
r.info(`worker defined — ${c} method(s)`);
|
|
34
|
-
let u = {
|
|
35
|
-
methods: i,
|
|
36
|
-
services: s
|
|
37
|
-
};
|
|
38
|
-
return e.sharedMemory && (u.sharedMemory = e.sharedMemory), u;
|
|
1
|
+
import { connectWorker as e } from "./index17.js";
|
|
2
|
+
//#region src/pool/subWorkerClient.ts
|
|
3
|
+
function t(t) {
|
|
4
|
+
let n = { ...t };
|
|
5
|
+
return typeof t.worker != "function" && (n.worker = () => {
|
|
6
|
+
if (typeof Worker > "u") throw Error("connectSubWorker: no `Worker` global in this context — nested dedicated workers are unsupported here (e.g. Safari). Feature-detect and fall back to a main-thread pool.");
|
|
7
|
+
return new Worker(t.worker, { type: "module" });
|
|
8
|
+
}), e(n);
|
|
39
9
|
}
|
|
40
10
|
//#endregion
|
|
41
|
-
export {
|
|
11
|
+
export { t as connectSubWorker };
|
package/dist/index19.js
CHANGED
|
@@ -1,88 +1,64 @@
|
|
|
1
|
-
import { scoped as e } from "./
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
for (; !r;) {
|
|
17
|
-
let a = Atomics.waitAsync(n.view, n.index, i);
|
|
18
|
-
a.async && await a.value, i = Atomics.load(n.view, n.index), r || (o.trace(`remote write observed (offset ${e.byteOffset})`), t());
|
|
1
|
+
import { scoped as e } from "./index7.js";
|
|
2
|
+
//#region src/shared/sharedWorkerClient.ts
|
|
3
|
+
var t = e("shared-client"), n = e("task"), r = class {
|
|
4
|
+
clientIndex;
|
|
5
|
+
sharedMemory;
|
|
6
|
+
port;
|
|
7
|
+
constructor(e, n, r) {
|
|
8
|
+
this.clientIndex = n, this.port = e, this.sharedMemory = r.sharedMemory;
|
|
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);
|
|
19
16
|
}
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
n(), e++;
|
|
17
|
+
Object.keys(i).length > 0 && t.info(`task methods: ${Object.keys(i).join(", ")}`);
|
|
18
|
+
}
|
|
19
|
+
runTask(e, ...t) {
|
|
20
|
+
return new Promise((r, i) => {
|
|
21
|
+
let a = Math.random().toString(36).substring(2), o = performance.now();
|
|
22
|
+
n.debug(`→ ${e.taskId}`, { args: t });
|
|
23
|
+
let s = (t) => {
|
|
24
|
+
let c = t.data;
|
|
25
|
+
if (c.messageId === a) {
|
|
26
|
+
this.port.removeEventListener("message", s);
|
|
27
|
+
let t = (performance.now() - o).toFixed(1);
|
|
28
|
+
c.success ? (n.debug(`← ${e.taskId} ok`, { ms: +t }), r(c.result)) : (n.warn(`← ${e.taskId} failed: ${c.error}`, { ms: +t }), i(Error(c.error)));
|
|
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
|
|
40
36
|
});
|
|
41
|
-
})
|
|
42
|
-
}
|
|
43
|
-
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
disconnect() {
|
|
40
|
+
try {
|
|
41
|
+
this.port.postMessage({ type: "SHARED_DISCONNECT" });
|
|
42
|
+
} finally {
|
|
43
|
+
this.port.close();
|
|
44
|
+
}
|
|
44
45
|
}
|
|
45
|
-
return l || o.warn("solid-js resolved to the SSR build — watch() falls back to direct version watching"), l;
|
|
46
46
|
};
|
|
47
|
-
function
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
observeRemote: () => c(e, r)
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
function f(e, r, a, s) {
|
|
59
|
-
let l = a ? r : ((e) => e), f = a ?? r;
|
|
60
|
-
if (!u()) {
|
|
61
|
-
let t = (e, t) => e === void 0 || t === void 0 ? e === t : (s?.equals ?? Object.is)(e, t), n, r = () => {
|
|
62
|
-
let r = e.read(), i = r == null ? void 0 : l(r);
|
|
63
|
-
if (i === void 0 || t(n, i)) return;
|
|
64
|
-
let a = n;
|
|
65
|
-
n = i, f(i, a);
|
|
66
|
-
};
|
|
67
|
-
r();
|
|
68
|
-
let i = c(e, r);
|
|
69
|
-
return o.debug(`watching connector at offset ${e.byteOffset} (direct)`), () => {
|
|
70
|
-
o.debug(`watch stopped (offset ${e.byteOffset})`), i();
|
|
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)));
|
|
71
55
|
};
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}, void 0, s?.equals ? { equals: (e, t) => e === void 0 || t === void 0 ? e === t : s.equals(e, t) } : void 0);
|
|
78
|
-
return t((e) => {
|
|
79
|
-
let t = r();
|
|
80
|
-
return t !== void 0 && f(t, e), t;
|
|
81
|
-
}), e;
|
|
56
|
+
n.addEventListener("message", s), n.postMessage({
|
|
57
|
+
type: "SHARED_CONNECT",
|
|
58
|
+
memoryBytes: e.sharedMemory.totalBytes,
|
|
59
|
+
memory: e.memory
|
|
60
|
+
});
|
|
82
61
|
});
|
|
83
|
-
return o.debug(`watching connector at offset ${e.byteOffset}`), () => {
|
|
84
|
-
o.debug(`watch stopped (offset ${e.byteOffset})`), m(), h();
|
|
85
|
-
};
|
|
86
62
|
}
|
|
87
63
|
//#endregion
|
|
88
|
-
export {
|
|
64
|
+
export { i as connectSharedWorker };
|
package/dist/index20.js
CHANGED
|
@@ -1,54 +1,25 @@
|
|
|
1
|
-
import { scoped as e } from "./
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
try {
|
|
25
|
-
t = e.connector(String(r));
|
|
26
|
-
} catch {
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
t !== p && (u?.(), u = null, p = null, h());
|
|
30
|
-
}), n.debug(`observing "${String(r)}" (offset ${i.byteOffset})`);
|
|
31
|
-
}, g = () => {
|
|
32
|
-
u?.(), u = null, p = null, d?.(), d = null, f?.(), f = null;
|
|
33
|
-
};
|
|
34
|
-
return {
|
|
35
|
-
get() {
|
|
36
|
-
if (u || e.bound) try {
|
|
37
|
-
let t = e.connector(String(r)), n = t._version ? Atomics.load(t._version.view, t._version.index) : 0;
|
|
38
|
-
if (n !== l) {
|
|
39
|
-
l = n;
|
|
40
|
-
let e = o(t.read());
|
|
41
|
-
(c === void 0 || !s(c, e)) && (c = e);
|
|
42
|
-
}
|
|
43
|
-
} catch {}
|
|
44
|
-
return c;
|
|
45
|
-
},
|
|
46
|
-
subscribe(e) {
|
|
47
|
-
return m.add(e), h(), () => {
|
|
48
|
-
m.delete(e), m.size === 0 && g();
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
}
|
|
1
|
+
import { scoped as e } from "./index7.js";
|
|
2
|
+
//#region src/worker/registry.ts
|
|
3
|
+
var t = e("registry"), n = class {
|
|
4
|
+
static tasks = /* @__PURE__ */ new Map();
|
|
5
|
+
static register(e, n) {
|
|
6
|
+
this.tasks.set(e.taskId, {
|
|
7
|
+
contract: e,
|
|
8
|
+
handler: n
|
|
9
|
+
}), t.debug(`registered "${e.taskId}"`, {
|
|
10
|
+
args: e.argsSchema ? "validated" : "unvalidated",
|
|
11
|
+
result: e.resultSchema ? "validated" : "unvalidated"
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
static getContract(e) {
|
|
15
|
+
return this.tasks.get(e)?.contract;
|
|
16
|
+
}
|
|
17
|
+
static async execute(e, ...t) {
|
|
18
|
+
let n = this.tasks.get(e);
|
|
19
|
+
if (!n) throw Error(`Task handler not found for id: ${e}`);
|
|
20
|
+
let { contract: r, handler: i } = n, a = await i(...r.argsSchema ? r.argsSchema.parse(t) : t);
|
|
21
|
+
return r.resultSchema ? r.resultSchema.parse(a) : a;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
53
24
|
//#endregion
|
|
54
|
-
export {
|
|
25
|
+
export { n as TaskRegistry };
|
package/dist/index21.js
CHANGED
|
@@ -1,57 +1,61 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
},
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
let o = ++n, s = performance.now();
|
|
23
|
-
a({
|
|
24
|
-
...r,
|
|
25
|
-
pending: !0,
|
|
26
|
-
error: null
|
|
27
|
-
}), e(i).then((e) => {
|
|
28
|
-
o === n && a({
|
|
29
|
-
data: e,
|
|
30
|
-
pending: !1,
|
|
31
|
-
settled: !0,
|
|
32
|
-
elapsedMs: performance.now() - s,
|
|
33
|
-
error: null
|
|
34
|
-
});
|
|
35
|
-
}, (e) => {
|
|
36
|
-
o === n && a({
|
|
37
|
-
...r,
|
|
38
|
-
pending: !1,
|
|
39
|
-
settled: !0,
|
|
40
|
-
error: e
|
|
41
|
-
}), t.error("task run failed", e);
|
|
1
|
+
import { fmtBytes as e, scoped as t } from "./index7.js";
|
|
2
|
+
import { bindSharedMemories as n } from "./index8.js";
|
|
3
|
+
import { MemoryManager as r } from "./index10.js";
|
|
4
|
+
import { TaskRegistry as i } from "./index20.js";
|
|
5
|
+
//#region src/shared/sharedWorkerHost.ts
|
|
6
|
+
var a = t("shared-worker"), o = null, s = 0;
|
|
7
|
+
function c(t, i) {
|
|
8
|
+
if (o) return o.buffer.byteLength < t && a.warn(`client requested ${e(t)} but buffer is ${e(o.buffer.byteLength)} — first client's capacity wins`), o;
|
|
9
|
+
let s = new r(i);
|
|
10
|
+
return s.ensureCapacity(t), o = s.memory, n(s.getBuffer()), a.info(`shared buffer allocated (${e(o.buffer.byteLength)})`), o;
|
|
11
|
+
}
|
|
12
|
+
function l(e) {
|
|
13
|
+
let t = ++s;
|
|
14
|
+
a.info(`client #${t} connected`), e.onmessage = async (n) => {
|
|
15
|
+
let r = n.data;
|
|
16
|
+
if (r?.type === "SHARED_CONNECT") {
|
|
17
|
+
let n = c(r.memoryBytes ?? 0, r.memory);
|
|
18
|
+
e.postMessage({
|
|
19
|
+
type: "SHARED_MEMORY",
|
|
20
|
+
buffer: n.buffer,
|
|
21
|
+
clientIndex: t
|
|
42
22
|
});
|
|
43
|
-
|
|
44
|
-
runOnce(e) {
|
|
45
|
-
r.pending || r.settled || o.run(e);
|
|
23
|
+
return;
|
|
46
24
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
25
|
+
if (r?.type === "EXECUTE_TASK") {
|
|
26
|
+
let { messageId: n, taskId: s, args: c } = r;
|
|
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();
|
|
52
54
|
}
|
|
53
|
-
function
|
|
54
|
-
|
|
55
|
+
function u() {
|
|
56
|
+
self.onconnect = (e) => {
|
|
57
|
+
l(e.ports[0]);
|
|
58
|
+
};
|
|
55
59
|
}
|
|
56
60
|
//#endregion
|
|
57
|
-
export {
|
|
61
|
+
export { l as attachSharedPort, u as sharedWorkerHost };
|
package/dist/index22.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { scoped as e } from "./index7.js";
|
|
2
|
+
import { TaskRegistry as t } from "./index20.js";
|
|
3
|
+
//#region src/service.ts
|
|
4
|
+
var n = e("service");
|
|
5
|
+
function r(e = {}) {
|
|
6
|
+
return e;
|
|
7
|
+
}
|
|
8
|
+
function i(e) {
|
|
9
|
+
return e;
|
|
10
|
+
}
|
|
11
|
+
function a(e, t) {
|
|
12
|
+
let n = {};
|
|
13
|
+
for (let [r, i] of Object.entries(t)) {
|
|
14
|
+
let t = "def" in i ? i.def : i;
|
|
15
|
+
n[r] = {
|
|
16
|
+
taskId: t.taskId ?? `${e}.${r}`,
|
|
17
|
+
...t.dataType ? { dataType: t.dataType } : {},
|
|
18
|
+
...t.argsSchema ? { argsSchema: t.argsSchema } : {},
|
|
19
|
+
...t.resultSchema ? { resultSchema: t.resultSchema } : {}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
name: e,
|
|
24
|
+
tasks: n
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function o(e, r) {
|
|
28
|
+
let i = Object.keys(e.tasks).filter((e) => {
|
|
29
|
+
let t = r[e];
|
|
30
|
+
return typeof t != "function" && typeof t?.run != "function";
|
|
31
|
+
});
|
|
32
|
+
if (i.length > 0) throw Error(`implementService("${e.name}"): missing handlers for ${i.join(", ")}`);
|
|
33
|
+
for (let [n, i] of Object.entries(e.tasks)) {
|
|
34
|
+
let e = r[n];
|
|
35
|
+
t.register(i, typeof e == "function" ? e.bind(r) : e.run.bind(e));
|
|
36
|
+
}
|
|
37
|
+
return n.info(`service "${e.name}" implemented — ${Object.keys(e.tasks).join(", ")}`), {
|
|
38
|
+
service: e,
|
|
39
|
+
handlers: r
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function s(e, t) {
|
|
43
|
+
let n = {};
|
|
44
|
+
for (let [r, i] of Object.entries(e.tasks)) n[r] = (...e) => t.runTask(i, ...e);
|
|
45
|
+
return n;
|
|
46
|
+
}
|
|
47
|
+
//#endregion
|
|
48
|
+
export { s as createClient, a as defineService, o as implementService, r as rpc, i as serviceMethod };
|
package/dist/index23.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { devtoolsEnabled as e, enableWorkerDevtoolsForwarding as t } from "./index5.js";
|
|
2
|
+
import { fmtBytes as n, scoped as r } from "./index7.js";
|
|
3
|
+
import { bindSharedMemories as i, getDefinedSharedMemoryCount as a } from "./index8.js";
|
|
4
|
+
import { measureAtoll as o } from "./index12.js";
|
|
5
|
+
import { TaskRegistry as s } from "./index20.js";
|
|
6
|
+
//#region src/worker/workerBootstrap.ts
|
|
7
|
+
var c = r("worker"), l = (e, t, n, r) => {
|
|
8
|
+
let i = performance.now();
|
|
9
|
+
o(`atoll run ${e}`, n, i, {
|
|
10
|
+
track: "tasks",
|
|
11
|
+
color: r ? "secondary" : "error",
|
|
12
|
+
properties: [["message", t], ["outcome", r ? "ok" : "error"]],
|
|
13
|
+
tooltipText: `${e}: ${(i - n).toFixed(1)}ms in worker`
|
|
14
|
+
});
|
|
15
|
+
}, u = !1, d = !1;
|
|
16
|
+
function f() {
|
|
17
|
+
if (!d) {
|
|
18
|
+
if (typeof self > "u") {
|
|
19
|
+
c.warn("workerBootstrap: no worker global found — skipping message wiring");
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
d = !0, self.onmessage = async (r) => {
|
|
23
|
+
let o = r.data;
|
|
24
|
+
if (o.type === "INIT") {
|
|
25
|
+
u = !0, o.devtools && t(), a() > 0 && c.warn("pool sent INIT without memory, but shared-memory contracts are defined — field access will throw until bound"), c.info("initialized (message-only pool — no shared memory)");
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (o.type === "INIT_MEMORY") {
|
|
29
|
+
let e = o.memory?.buffer ?? o.buffer;
|
|
30
|
+
if (!e) {
|
|
31
|
+
c.warn("INIT_MEMORY arrived without a buffer — contracts stay unbound");
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
i(e), u = !0, o.devtools && t(), c.info(`shared memory initialized (${n(e.byteLength)})`);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (o.type === "EXECUTE_TASK") {
|
|
38
|
+
let { messageId: t, taskId: n, args: r } = o;
|
|
39
|
+
if (!u) {
|
|
40
|
+
c.warn(`rejected ${n} — shared memory not initialized`), self.postMessage({
|
|
41
|
+
messageId: t,
|
|
42
|
+
success: !1,
|
|
43
|
+
error: "Shared memory not initialized in worker."
|
|
44
|
+
});
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
let i = performance.now();
|
|
48
|
+
try {
|
|
49
|
+
let a = await s.execute(n, ...r || []);
|
|
50
|
+
e() && l(n, t, i, !0), c.debug(`task ${n} → ${(performance.now() - i).toFixed(1)}ms`), self.postMessage({
|
|
51
|
+
messageId: t,
|
|
52
|
+
success: !0,
|
|
53
|
+
result: a
|
|
54
|
+
});
|
|
55
|
+
} catch (r) {
|
|
56
|
+
e() && l(n, t, i, !1), c.warn(`task ${n} failed: ${r.message || String(r)}`), self.postMessage({
|
|
57
|
+
messageId: t,
|
|
58
|
+
success: !1,
|
|
59
|
+
error: r.message || String(r)
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
queueMicrotask(f);
|
|
67
|
+
//#endregion
|
|
68
|
+
export { f as installWorkerListener };
|
package/dist/index24.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { scoped as e } from "./index7.js";
|
|
2
|
+
import { TaskRegistry as t } from "./index20.js";
|
|
3
|
+
import { installWorkerListener as n } from "./index23.js";
|
|
4
|
+
//#region src/worker/defineWorker.ts
|
|
5
|
+
var r = e("worker"), i = [
|
|
6
|
+
"start",
|
|
7
|
+
"terminate",
|
|
8
|
+
"pool",
|
|
9
|
+
"sharedMemory",
|
|
10
|
+
"then",
|
|
11
|
+
"with"
|
|
12
|
+
], a = (e) => typeof e == "object" && !!e && "run" in e, o = new Set(i);
|
|
13
|
+
function s(e) {
|
|
14
|
+
n();
|
|
15
|
+
let i = e.methods ?? {}, s = e.services ?? {}, c = 0, l = (e, n, r, i) => {
|
|
16
|
+
if (o.has(n)) throw Error(`defineWorker: "${n}" is reserved for the client API — rename the method`);
|
|
17
|
+
if (a(r)) {
|
|
18
|
+
let { def: n } = r;
|
|
19
|
+
t.register({
|
|
20
|
+
taskId: n.taskId ?? e,
|
|
21
|
+
...n.dataType ? { dataType: n.dataType } : {},
|
|
22
|
+
...n.argsSchema ? { argsSchema: n.argsSchema } : {},
|
|
23
|
+
...n.resultSchema ? { resultSchema: n.resultSchema } : {}
|
|
24
|
+
}, r.run.bind(r));
|
|
25
|
+
} else t.register({ taskId: e }, r.bind(i));
|
|
26
|
+
c++;
|
|
27
|
+
};
|
|
28
|
+
for (let [e, t] of Object.entries(i)) l(e, e, t, i);
|
|
29
|
+
for (let [e, t] of Object.entries(s)) {
|
|
30
|
+
if (o.has(e)) throw Error(`defineWorker: service name "${e}" is reserved for the client API — rename it`);
|
|
31
|
+
for (let [n, r] of Object.entries(t)) l(`${e}.${n}`, n, r, t);
|
|
32
|
+
}
|
|
33
|
+
r.info(`worker defined — ${c} method(s)`);
|
|
34
|
+
let u = {
|
|
35
|
+
methods: i,
|
|
36
|
+
services: s
|
|
37
|
+
};
|
|
38
|
+
return e.sharedMemory && (u.sharedMemory = e.sharedMemory), u;
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
export { i as RESERVED_CLIENT_KEYS, s as defineWorker };
|