@flaxia/node 0.3.1 → 0.3.2
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/assets/ai-inference.js +28 -22
- package/dist/assets/nudenet.js +4 -1
- package/dist/assets/vector-embed.js +5 -3
- package/dist/assets/vector-query.js +9 -7
- package/dist/assets/vector-store.js +9 -7
- package/dist/client/SignalingClient.d.ts.map +1 -1
- package/dist/executor/throttle.d.ts +13 -24
- package/dist/executor/throttle.d.ts.map +1 -1
- package/dist/index.js +20 -12
- package/dist/worker.js +78 -72
- package/dist/workloads/ai-inference.d.ts +6 -0
- package/dist/workloads/ai-inference.d.ts.map +1 -1
- package/dist/workloads/nudenet.d.ts +1 -0
- package/dist/workloads/nudenet.d.ts.map +1 -1
- package/dist/workloads/vector-embed.d.ts +1 -0
- package/dist/workloads/vector-embed.d.ts.map +1 -1
- package/dist/workloads/vector-query.d.ts +1 -0
- package/dist/workloads/vector-query.d.ts.map +1 -1
- package/dist/workloads/vector-store.d.ts +1 -0
- package/dist/workloads/vector-store.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -26,7 +26,9 @@ var r = [
|
|
|
26
26
|
"depth-estimation",
|
|
27
27
|
"feature-extraction",
|
|
28
28
|
"image-feature-extraction"
|
|
29
|
-
], i = /* @__PURE__ */ new Map(), a =
|
|
29
|
+
], i = /* @__PURE__ */ new Map(), a = 2, o = () => {
|
|
30
|
+
i.clear();
|
|
31
|
+
}, s = (e, t) => {
|
|
30
32
|
if (!t.tokenBuffer) return e;
|
|
31
33
|
let n = "", r = null, i = t.tokenBufferIntervalMs ?? 50, a = () => {
|
|
32
34
|
n &&= (e(n), ""), r = null;
|
|
@@ -34,39 +36,43 @@ var r = [
|
|
|
34
36
|
return (e) => {
|
|
35
37
|
n += e, r ||= setTimeout(a, i);
|
|
36
38
|
};
|
|
37
|
-
},
|
|
38
|
-
let { task:
|
|
39
|
-
if (!r.includes(
|
|
39
|
+
}, c = async (o, c) => {
|
|
40
|
+
let { task: l, model: u, input: d, options: f = {} } = o;
|
|
41
|
+
if (!r.includes(l)) throw Error(`Invalid or unsupported task: ${l}. Supported tasks are: ${r.join(", ")}`);
|
|
40
42
|
if (self.crossOriginIsolated) {
|
|
41
|
-
let e =
|
|
43
|
+
let e = f.numThreads ?? navigator.hardwareConcurrency;
|
|
42
44
|
t.backends.onnx?.wasm && (t.backends.onnx.wasm.numThreads = Math.max(1, Math.min(e, navigator.hardwareConcurrency || 4)));
|
|
43
45
|
}
|
|
44
|
-
let
|
|
45
|
-
if (!
|
|
46
|
+
let p = `${l}:${u}`, m = i.get(p);
|
|
47
|
+
if (!m) {
|
|
48
|
+
if (i.size >= a) {
|
|
49
|
+
let e = i.keys().next().value;
|
|
50
|
+
i.delete(e);
|
|
51
|
+
}
|
|
46
52
|
let e = {
|
|
47
|
-
dtype:
|
|
48
|
-
device:
|
|
53
|
+
dtype: f.dtype ?? "q4f16",
|
|
54
|
+
device: f.device
|
|
49
55
|
}, t = performance.now();
|
|
50
|
-
console.log(`[flaxia-node] ai-inference: loading pipeline task=${
|
|
56
|
+
console.log(`[flaxia-node] ai-inference: loading pipeline task=${l} model=${u} dtype=${e.dtype} device=${e.device ?? "wasm"}`);
|
|
51
57
|
try {
|
|
52
|
-
|
|
58
|
+
m = await n(l, u, e);
|
|
53
59
|
} catch (t) {
|
|
54
|
-
if (
|
|
55
|
-
else throw console.error(`[flaxia-node] ai-inference: pipeline load FAILED task=${
|
|
60
|
+
if (f.device && f.device !== "wasm") console.warn(`[AiInference] ${f.device} failed, falling back to wasm:`, t), e.device = "wasm", m = await n(l, u, e);
|
|
61
|
+
else throw console.error(`[flaxia-node] ai-inference: pipeline load FAILED task=${l} model=${u} error=${t instanceof Error ? t.message : String(t)}`), t;
|
|
56
62
|
}
|
|
57
|
-
console.log(`[flaxia-node] ai-inference: pipeline ready task=${
|
|
63
|
+
console.log(`[flaxia-node] ai-inference: pipeline ready task=${l} model=${u} loadMs=${Math.round(performance.now() - t)}`), i.set(p, m);
|
|
58
64
|
}
|
|
59
|
-
let
|
|
60
|
-
max_new_tokens:
|
|
61
|
-
do_sample:
|
|
65
|
+
let h = {
|
|
66
|
+
max_new_tokens: f.max_new_tokens ?? 128,
|
|
67
|
+
do_sample: f.do_sample ?? !1
|
|
62
68
|
};
|
|
63
|
-
|
|
69
|
+
f.temperature != null && (h.temperature = f.temperature), f.top_p != null && (h.top_p = f.top_p), f.top_k != null && (h.top_k = f.top_k), f.repetition_penalty != null && (h.repetition_penalty = f.repetition_penalty), f.src_lang != null && (h.src_lang = f.src_lang), f.tgt_lang != null && (h.tgt_lang = f.tgt_lang), c && m.tokenizer && (h.streamer = new e(m.tokenizer, {
|
|
64
70
|
skip_prompt: !0,
|
|
65
71
|
skip_special_tokens: !0,
|
|
66
|
-
callback_function:
|
|
72
|
+
callback_function: s(c, f)
|
|
67
73
|
}));
|
|
68
|
-
let
|
|
69
|
-
return console.log(`[flaxia-node] ai-inference: done task=${
|
|
74
|
+
let g = performance.now(), _ = await m(d, h);
|
|
75
|
+
return console.log(`[flaxia-node] ai-inference: done task=${l} model=${u} execMs=${Math.round(performance.now() - g)} inputLen=${String(d).length}`), { output: _ };
|
|
70
76
|
};
|
|
71
77
|
//#endregion
|
|
72
|
-
export {
|
|
78
|
+
export { c as handleAiInference, o as releaseCache };
|
package/dist/assets/nudenet.js
CHANGED
|
@@ -14047,5 +14047,8 @@ var jd = async (e) => {
|
|
|
14047
14047
|
a.close();
|
|
14048
14048
|
}
|
|
14049
14049
|
};
|
|
14050
|
+
function Md() {
|
|
14051
|
+
Ed.clear();
|
|
14052
|
+
}
|
|
14050
14053
|
//#endregion
|
|
14051
|
-
export { jd as handleNudeNet };
|
|
14054
|
+
export { jd as handleNudeNet, Md as releaseCache };
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
//#region src/workloads/vector-embed.ts
|
|
2
|
-
var e = null
|
|
3
|
-
|
|
2
|
+
var e = null, t = () => {
|
|
3
|
+
e = null;
|
|
4
|
+
};
|
|
5
|
+
async function n(t) {
|
|
4
6
|
let n = performance.now();
|
|
5
7
|
if (!e) {
|
|
6
8
|
let t = performance.now();
|
|
@@ -25,4 +27,4 @@ async function t(t) {
|
|
|
25
27
|
};
|
|
26
28
|
}
|
|
27
29
|
//#endregion
|
|
28
|
-
export {
|
|
30
|
+
export { n as handleVectorEmbed, t as releaseCache };
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import { t as e } from "./VectorStoreEngine.js";
|
|
2
2
|
//#region src/workloads/vector-query.ts
|
|
3
|
-
var t = null
|
|
4
|
-
|
|
3
|
+
var t = null, n = () => {
|
|
4
|
+
t = null;
|
|
5
|
+
};
|
|
6
|
+
async function r() {
|
|
5
7
|
return t || (t = new e(), await t.initialize()), t;
|
|
6
8
|
}
|
|
7
|
-
async function
|
|
8
|
-
let t = await
|
|
9
|
+
async function i(e) {
|
|
10
|
+
let t = await r(), n = performance.now();
|
|
9
11
|
try {
|
|
10
|
-
let
|
|
11
|
-
return console.log(`[flaxia-node] vector-query: done durationMs=${Math.round(performance.now() -
|
|
12
|
+
let r = await t.query(e);
|
|
13
|
+
return console.log(`[flaxia-node] vector-query: done durationMs=${Math.round(performance.now() - n)}`), r;
|
|
12
14
|
} catch (e) {
|
|
13
15
|
throw console.error(`[flaxia-node] vector-query: failed error=${e instanceof Error ? e.message : String(e)}`), e;
|
|
14
16
|
}
|
|
15
17
|
}
|
|
16
18
|
//#endregion
|
|
17
|
-
export {
|
|
19
|
+
export { i as handleVectorQuery, n as releaseCache };
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import { t as e } from "./VectorStoreEngine.js";
|
|
2
2
|
//#region src/workloads/vector-store.ts
|
|
3
|
-
var t = null
|
|
4
|
-
|
|
3
|
+
var t = null, n = () => {
|
|
4
|
+
t = null;
|
|
5
|
+
};
|
|
6
|
+
async function r() {
|
|
5
7
|
return t || (t = new e(), await t.initialize()), t;
|
|
6
8
|
}
|
|
7
|
-
async function
|
|
8
|
-
let t = await
|
|
9
|
+
async function i(e) {
|
|
10
|
+
let t = await r(), n = performance.now();
|
|
9
11
|
try {
|
|
10
|
-
let
|
|
11
|
-
return console.log(`[flaxia-node] vector-store: done durationMs=${Math.round(performance.now() -
|
|
12
|
+
let r = await t.store(e);
|
|
13
|
+
return console.log(`[flaxia-node] vector-store: done durationMs=${Math.round(performance.now() - n)}`), r;
|
|
12
14
|
} catch (e) {
|
|
13
15
|
throw console.error(`[flaxia-node] vector-store: failed error=${e instanceof Error ? e.message : String(e)}`), e;
|
|
14
16
|
}
|
|
15
17
|
}
|
|
16
18
|
//#endregion
|
|
17
|
-
export {
|
|
19
|
+
export { i as handleVectorStore, n as releaseCache };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SignalingClient.d.ts","sourceRoot":"","sources":["../../src/client/SignalingClient.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAK5D,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,YAAY,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"SignalingClient.d.ts","sourceRoot":"","sources":["../../src/client/SignalingClient.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAK5D,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,YAAY,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAqQD,eAAO,MAAM,cAAc,GAAI,QAAQ,UAAU,SAehD,CAAC"}
|
|
@@ -1,31 +1,20 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Estimates current CPU contention and throttles work accordingly.
|
|
3
|
-
*
|
|
4
|
-
* Runs inside the compute Worker (where the actual workload executes) rather
|
|
5
|
-
* than on the main thread, so the measurement reflects the thread that does
|
|
6
|
-
* the work. Load is estimated with a calibrated busy-loop: a fixed-iteration
|
|
7
|
-
* loop takes longer to finish when the system is busy, and the ratio to the
|
|
8
|
-
* idle baseline is the estimated load.
|
|
9
|
-
*
|
|
10
|
-
* There is no direct API for CPU usage in the browser, so this is a heuristic
|
|
11
|
-
* used to (a) avoid starting work while the machine is already loaded and
|
|
12
|
-
* (b) space out task starts so average CPU stays near `maxLoad`.
|
|
13
|
-
*/
|
|
14
1
|
export declare class CpuThrottle {
|
|
15
|
-
private baselineMs;
|
|
16
|
-
private lastLoad;
|
|
17
2
|
private readonly maxLoad;
|
|
18
|
-
private
|
|
19
|
-
|
|
20
|
-
private
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
3
|
+
private windowStart;
|
|
4
|
+
private windowBusyMs;
|
|
5
|
+
private lastLoad;
|
|
6
|
+
constructor(maxLoad?: number);
|
|
7
|
+
/**
|
|
8
|
+
* Charge a completed task's wall-clock duration (in ms) against the CPU budget.
|
|
9
|
+
* Call this from the worker once a workload has finished (incl. errors/timeouts).
|
|
10
|
+
*/
|
|
11
|
+
markTaskComplete(durationMs: number): void;
|
|
12
|
+
private estimate;
|
|
24
13
|
shouldPause(): Promise<boolean>;
|
|
25
14
|
/**
|
|
26
|
-
* Waits until the
|
|
27
|
-
* Bounded by `maxWaitMs` so a
|
|
28
|
-
*
|
|
15
|
+
* Waits until the rolling busy ratio is back under `maxLoad`.
|
|
16
|
+
* Bounded by `maxWaitMs` so a sustained heavy device cannot stall the queue
|
|
17
|
+
* forever.
|
|
29
18
|
*/
|
|
30
19
|
waitForSlot(maxWaitMs?: number): Promise<void>;
|
|
31
20
|
get lastMeasuredLoad(): number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"throttle.d.ts","sourceRoot":"","sources":["../../src/executor/throttle.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"throttle.d.ts","sourceRoot":"","sources":["../../src/executor/throttle.ts"],"names":[],"mappings":"AAmBA,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,QAAQ,CAAK;gBAET,OAAO,SAAO;IAI1B;;;OAGG;IACH,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAU1C,OAAO,CAAC,QAAQ;IAMV,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAIrC;;;;OAIG;IACG,WAAW,CAAC,SAAS,SAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ9D,IAAI,gBAAgB,IAAI,MAAM,CAE7B;IAED,IAAI,YAAY,IAAI,MAAM,CAEzB;CACF"}
|
package/dist/index.js
CHANGED
|
@@ -144,7 +144,7 @@ var e = class {
|
|
|
144
144
|
}
|
|
145
145
|
}, c = (...e) => console.log("[flaxia-node]", ...e), l = (...e) => console.error("[flaxia-node]", ...e), u = "flaxia_node_id", d = "flaxia_node_token", f = class {
|
|
146
146
|
constructor(e, t, n) {
|
|
147
|
-
this.config = e, this.workerPool = t, this.nodeId = n, this.ws = null, this.reconnectAttempts = 0, this.MAX_RECONNECT_DELAY = 3e4, this.destroyed = !1, this.suspended = !1, this.visibilityHandler = null;
|
|
147
|
+
this.config = e, this.workerPool = t, this.nodeId = n, this.ws = null, this.reconnectAttempts = 0, this.MAX_RECONNECT_DELAY = 3e4, this.destroyed = !1, this.suspended = !1, this.visibilityHandler = null, this.inflightTasks = /* @__PURE__ */ new Set();
|
|
148
148
|
}
|
|
149
149
|
async connect() {
|
|
150
150
|
if (this.destroyed) return;
|
|
@@ -241,7 +241,8 @@ var e = class {
|
|
|
241
241
|
body: JSON.stringify({
|
|
242
242
|
siteId: this.config.siteId,
|
|
243
243
|
nodeId: this.nodeId,
|
|
244
|
-
capabilities: this.config.capabilities ?? ["ai-inference", "image-process"]
|
|
244
|
+
capabilities: this.config.capabilities ?? ["ai-inference", "image-process"],
|
|
245
|
+
deviceMemory: typeof navigator.deviceMemory == "number" ? navigator.deviceMemory : null
|
|
245
246
|
})
|
|
246
247
|
});
|
|
247
248
|
if (!n.ok) return l(`node register failed HTTP ${n.status} (${t}/crowd/nodes/register)`), null;
|
|
@@ -260,18 +261,25 @@ var e = class {
|
|
|
260
261
|
this.ws && this.ws.readyState === WebSocket.OPEN && this.ws.send(JSON.stringify(e));
|
|
261
262
|
}
|
|
262
263
|
async handleTask(e) {
|
|
263
|
-
|
|
264
|
+
if (this.inflightTasks.has(e.taskId)) return;
|
|
265
|
+
this.inflightTasks.add(e.taskId);
|
|
266
|
+
let t = performance.now();
|
|
267
|
+
try {
|
|
268
|
+
let n = e.timeoutMs ? e.timeoutMs + 3e4 : void 0, r = await this.workerPool.run(e.taskId, e.workload, e.payload, n, (t) => {
|
|
269
|
+
this.send({
|
|
270
|
+
type: "progress",
|
|
271
|
+
taskId: e.taskId,
|
|
272
|
+
token: t
|
|
273
|
+
});
|
|
274
|
+
}, { maxCpuLoad: this.config.maxCpuLoad });
|
|
264
275
|
this.send({
|
|
265
|
-
type: "
|
|
276
|
+
type: "result",
|
|
266
277
|
taskId: e.taskId,
|
|
267
|
-
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
taskId: e.taskId,
|
|
273
|
-
payload: r
|
|
274
|
-
}), c(`task result sent taskId=${e.taskId} workload=${e.workload} durationMs=${Math.round(performance.now() - n)}`);
|
|
278
|
+
payload: r
|
|
279
|
+
}), c(`task result sent taskId=${e.taskId} workload=${e.workload} durationMs=${Math.round(performance.now() - t)}`);
|
|
280
|
+
} finally {
|
|
281
|
+
this.inflightTasks.delete(e.taskId);
|
|
282
|
+
}
|
|
275
283
|
}
|
|
276
284
|
setupVisibilityHandler() {
|
|
277
285
|
this.removeVisibilityHandler(), this.visibilityHandler = () => {
|
package/dist/worker.js
CHANGED
|
@@ -2,36 +2,24 @@
|
|
|
2
2
|
function e(e) {
|
|
3
3
|
return new Promise((t) => setTimeout(t, e));
|
|
4
4
|
}
|
|
5
|
-
var t = class {
|
|
6
|
-
constructor(e = .15
|
|
7
|
-
this.
|
|
5
|
+
var t = 3e4, n = 3e4, r = class {
|
|
6
|
+
constructor(e = .15) {
|
|
7
|
+
this.windowStart = performance.now(), this.windowBusyMs = 0, this.lastLoad = 0, this.maxLoad = Math.max(.05, Math.min(.3, e));
|
|
8
8
|
}
|
|
9
|
-
|
|
10
|
-
let
|
|
11
|
-
|
|
12
|
-
return performance.now() - t;
|
|
13
|
-
}
|
|
14
|
-
sample() {
|
|
15
|
-
return [
|
|
16
|
-
this.busyLoop(),
|
|
17
|
-
this.busyLoop(),
|
|
18
|
-
this.busyLoop()
|
|
19
|
-
].sort((e, t) => e - t)[1];
|
|
20
|
-
}
|
|
21
|
-
async calibrate() {
|
|
22
|
-
this.busyLoop(), this.baselineMs = this.sample(), this.lastLoad = 0;
|
|
9
|
+
markTaskComplete(e) {
|
|
10
|
+
let n = performance.now();
|
|
11
|
+
n - this.windowStart > t && (this.windowStart = n, this.windowBusyMs = 0), this.windowBusyMs += Math.max(0, e), this.lastLoad = this.estimate();
|
|
23
12
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return this.lastLoad = t, t;
|
|
13
|
+
estimate() {
|
|
14
|
+
let e = performance.now() - this.windowStart;
|
|
15
|
+
return e <= 0 ? 0 : Math.min(1, Math.max(0, this.windowBusyMs / e));
|
|
28
16
|
}
|
|
29
17
|
async shouldPause() {
|
|
30
|
-
return
|
|
18
|
+
return this.estimate() > this.maxLoad;
|
|
31
19
|
}
|
|
32
|
-
async waitForSlot(t =
|
|
33
|
-
let
|
|
34
|
-
for (; await this.shouldPause() && !(performance.now() -
|
|
20
|
+
async waitForSlot(t = n) {
|
|
21
|
+
let r = performance.now();
|
|
22
|
+
for (; await this.shouldPause() && !(performance.now() - r > t);) await e(500);
|
|
35
23
|
}
|
|
36
24
|
get lastMeasuredLoad() {
|
|
37
25
|
return this.lastLoad;
|
|
@@ -39,71 +27,89 @@ var t = class {
|
|
|
39
27
|
get maxLoadValue() {
|
|
40
28
|
return this.maxLoad;
|
|
41
29
|
}
|
|
42
|
-
},
|
|
30
|
+
}, i = null, a = new Set([
|
|
31
|
+
"ai-inference",
|
|
32
|
+
"vector-embed",
|
|
33
|
+
"vector-query",
|
|
34
|
+
"nudenet",
|
|
35
|
+
"image-process",
|
|
36
|
+
"container"
|
|
37
|
+
]), o = 6e4;
|
|
38
|
+
function s() {
|
|
39
|
+
let e = navigator.deviceMemory;
|
|
40
|
+
return typeof e == "number" && e >= 4;
|
|
41
|
+
}
|
|
42
|
+
var c = /* @__PURE__ */ new Map(), l = null;
|
|
43
|
+
function u() {
|
|
44
|
+
for (let e of c.values()) try {
|
|
45
|
+
e();
|
|
46
|
+
} catch {}
|
|
47
|
+
c.clear();
|
|
48
|
+
}
|
|
49
|
+
function d() {
|
|
50
|
+
l && clearTimeout(l), l = setTimeout(() => {
|
|
51
|
+
l = null, u();
|
|
52
|
+
}, o);
|
|
53
|
+
}
|
|
54
|
+
async function f(e, t, n) {
|
|
55
|
+
switch (e) {
|
|
56
|
+
case "ai-inference":
|
|
57
|
+
let r = await import("./assets/ai-inference.js");
|
|
58
|
+
return c.set(e, r.releaseCache), await r.handleAiInference(t, n);
|
|
59
|
+
case "image-process": return await (await import("./assets/image-process.js")).handleImageProcess(t);
|
|
60
|
+
case "container": return await (await import("./assets/container.js")).handleContainer(t);
|
|
61
|
+
case "vector-embed":
|
|
62
|
+
let i = await import("./assets/vector-embed.js");
|
|
63
|
+
return c.set(e, i.releaseCache), await i.handleVectorEmbed(t);
|
|
64
|
+
case "vector-store":
|
|
65
|
+
let a = await import("./assets/vector-store.js");
|
|
66
|
+
return c.set(e, a.releaseCache), await a.handleVectorStore(t);
|
|
67
|
+
case "vector-query":
|
|
68
|
+
let o = await import("./assets/vector-query.js");
|
|
69
|
+
return c.set(e, o.releaseCache), await o.handleVectorQuery(t);
|
|
70
|
+
case "nudenet":
|
|
71
|
+
let s = await import("./assets/nudenet.js");
|
|
72
|
+
return c.set(e, s.releaseCache), await s.handleNudeNet(t);
|
|
73
|
+
default: throw Error(`Unknown workload type: ${e}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
43
76
|
self.onmessage = async (e) => {
|
|
44
|
-
let { id:
|
|
77
|
+
let { id: t, workload: n, payload: o, config: c } = e.data, l = performance.now();
|
|
45
78
|
try {
|
|
46
|
-
|
|
79
|
+
if (i ||= new r(c?.maxCpuLoad), console.log(`[flaxia-node:worker] task start id=${t} workload=${n}`), a.has(n) && !s()) {
|
|
80
|
+
let e = navigator.deviceMemory;
|
|
81
|
+
throw Error(`${n}: insufficient device memory (deviceMemory=${e ?? "unknown"})`);
|
|
82
|
+
}
|
|
83
|
+
await i.waitForSlot();
|
|
47
84
|
let e = setInterval(() => {
|
|
48
85
|
self.postMessage({
|
|
49
|
-
id:
|
|
86
|
+
id: t,
|
|
50
87
|
type: "heartbeat",
|
|
51
|
-
cpuLoad:
|
|
88
|
+
cpuLoad: i?.lastMeasuredLoad ?? 0
|
|
52
89
|
});
|
|
53
|
-
}, 1e4);
|
|
90
|
+
}, 1e4), u = performance.now();
|
|
54
91
|
try {
|
|
55
|
-
let e
|
|
92
|
+
let e = await f(n, o, (e) => {
|
|
56
93
|
self.postMessage({
|
|
57
|
-
id:
|
|
94
|
+
id: t,
|
|
58
95
|
type: "token",
|
|
59
96
|
token: e
|
|
60
97
|
});
|
|
61
|
-
};
|
|
62
|
-
switch (i) {
|
|
63
|
-
case "ai-inference":
|
|
64
|
-
let { handleAiInference: n } = await import("./assets/ai-inference.js");
|
|
65
|
-
e = await n(a, t);
|
|
66
|
-
break;
|
|
67
|
-
case "image-process":
|
|
68
|
-
let { handleImageProcess: r } = await import("./assets/image-process.js");
|
|
69
|
-
e = await r(a);
|
|
70
|
-
break;
|
|
71
|
-
case "container":
|
|
72
|
-
let { handleContainer: o } = await import("./assets/container.js");
|
|
73
|
-
e = await o(a);
|
|
74
|
-
break;
|
|
75
|
-
case "vector-embed":
|
|
76
|
-
let { handleVectorEmbed: s } = await import("./assets/vector-embed.js");
|
|
77
|
-
e = await s(a);
|
|
78
|
-
break;
|
|
79
|
-
case "vector-store":
|
|
80
|
-
let { handleVectorStore: c } = await import("./assets/vector-store.js");
|
|
81
|
-
e = await c(a);
|
|
82
|
-
break;
|
|
83
|
-
case "vector-query":
|
|
84
|
-
let { handleVectorQuery: l } = await import("./assets/vector-query.js");
|
|
85
|
-
e = await l(a);
|
|
86
|
-
break;
|
|
87
|
-
case "nudenet":
|
|
88
|
-
let { handleNudeNet: u } = await import("./assets/nudenet.js");
|
|
89
|
-
e = await u(a);
|
|
90
|
-
break;
|
|
91
|
-
default: throw Error(`Unknown workload type: ${i}`);
|
|
92
|
-
}
|
|
98
|
+
});
|
|
93
99
|
self.postMessage({
|
|
94
|
-
id:
|
|
100
|
+
id: t,
|
|
95
101
|
type: "done",
|
|
96
102
|
result: e
|
|
97
|
-
}), console.log(`[flaxia-node:worker] task done id=${
|
|
103
|
+
}), console.log(`[flaxia-node:worker] task done id=${t} workload=${n} durationMs=${Math.round(performance.now() - l)}`);
|
|
98
104
|
} finally {
|
|
99
|
-
clearInterval(e);
|
|
105
|
+
clearInterval(e), i.markTaskComplete(performance.now() - u), d();
|
|
100
106
|
}
|
|
101
107
|
} catch (e) {
|
|
102
|
-
let
|
|
103
|
-
console.error(`[flaxia-node:worker] task error id=${
|
|
104
|
-
id:
|
|
108
|
+
let r = e instanceof Error ? e.message : String(e);
|
|
109
|
+
console.error(`[flaxia-node:worker] task error id=${t} workload=${n} error=${r}`), self.postMessage({
|
|
110
|
+
id: t,
|
|
105
111
|
type: "error",
|
|
106
|
-
error:
|
|
112
|
+
error: r
|
|
107
113
|
});
|
|
108
114
|
}
|
|
109
115
|
};
|
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
import type { AiInferencePayload, AiInferenceResult } from '@flaxia/sdk';
|
|
2
|
+
/**
|
|
3
|
+
* Drops all cached model pipelines so the (potentially hundreds of MB of)
|
|
4
|
+
* transformers/onnxruntime memory can be garbage-collected. Called by the
|
|
5
|
+
* worker after an idle period so a node does not pin every model it ever saw.
|
|
6
|
+
*/
|
|
7
|
+
export declare const releaseCache: () => void;
|
|
2
8
|
export declare const handleAiInference: (payload: AiInferencePayload, onToken?: (token: string) => void) => Promise<AiInferenceResult>;
|
|
3
9
|
//# sourceMappingURL=ai-inference.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-inference.d.ts","sourceRoot":"","sources":["../../src/workloads/ai-inference.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAsB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"ai-inference.d.ts","sourceRoot":"","sources":["../../src/workloads/ai-inference.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAsB,MAAM,aAAa,CAAC;AAe7F;;;;GAIG;AACH,eAAO,MAAM,YAAY,QAAO,IAE/B,CAAC;AA4BF,eAAO,MAAM,iBAAiB,GAC5B,SAAS,kBAAkB,EAC3B,UAAU,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,KAChC,OAAO,CAAC,iBAAiB,CA2E3B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nudenet.d.ts","sourceRoot":"","sources":["../../src/workloads/nudenet.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoB,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA+KnF,eAAO,MAAM,aAAa,GAAU,SAAS,cAAc,KAAG,OAAO,CAAC,aAAa,CA6BlF,CAAC"}
|
|
1
|
+
{"version":3,"file":"nudenet.d.ts","sourceRoot":"","sources":["../../src/workloads/nudenet.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoB,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA+KnF,eAAO,MAAM,aAAa,GAAU,SAAS,cAAc,KAAG,OAAO,CAAC,aAAa,CA6BlF,CAAC;AAEF,wBAAgB,YAAY,IAAI,IAAI,CAEnC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vector-embed.d.ts","sourceRoot":"","sources":["../../src/workloads/vector-embed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAIzE,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA2C/F"}
|
|
1
|
+
{"version":3,"file":"vector-embed.d.ts","sourceRoot":"","sources":["../../src/workloads/vector-embed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAIzE,eAAO,MAAM,YAAY,QAAO,IAE/B,CAAC;AAEF,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA2C/F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vector-query.d.ts","sourceRoot":"","sources":["../../src/workloads/vector-query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"vector-query.d.ts","sourceRoot":"","sources":["../../src/workloads/vector-query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAKzE,eAAO,MAAM,YAAY,QAAO,IAE/B,CAAC;AAUF,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAW/F"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { VectorStorePayload, VectorStoreResult } from '@flaxia/sdk';
|
|
2
|
+
export declare const releaseCache: () => void;
|
|
2
3
|
export declare function handleVectorStore(payload: VectorStorePayload): Promise<VectorStoreResult>;
|
|
3
4
|
export declare function handleVectorStoreAssignShard(rangeStart: number, rangeEnd: number): Promise<void>;
|
|
4
5
|
//# sourceMappingURL=vector-store.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vector-store.d.ts","sourceRoot":"","sources":["../../src/workloads/vector-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"vector-store.d.ts","sourceRoot":"","sources":["../../src/workloads/vector-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAKzE,eAAO,MAAM,YAAY,QAAO,IAE/B,CAAC;AAUF,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAW/F;AAED,wBAAsB,4BAA4B,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGtG"}
|