@flaxia/node 0.3.3 → 0.3.4

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.
@@ -0,0 +1,28 @@
1
+ //#region src/executor/memoryProbe.ts
2
+ var e = 2 * 1024 ** 3, t = 65536, n = 16 * 1024 * 1024;
3
+ function r(r = e, i = n) {
4
+ let a;
5
+ try {
6
+ a = new WebAssembly.Memory({ initial: 0 });
7
+ } catch {
8
+ return 0;
9
+ }
10
+ let o = 0;
11
+ for (; o < r;) {
12
+ let e = r - o, n = Math.ceil(Math.min(i, e) / t);
13
+ try {
14
+ a.grow(n);
15
+ } catch {
16
+ break;
17
+ }
18
+ let s = new Uint8Array(a.buffer);
19
+ for (let e = 0; e < n; e++) s[o + e * t] = 0;
20
+ o += n * t;
21
+ }
22
+ return o;
23
+ }
24
+ function i() {
25
+ return r() >= e;
26
+ }
27
+ //#endregion
28
+ export { i as n, r, e as t };
@@ -1 +1 @@
1
- {"version":3,"file":"SignalingClient.d.ts","sourceRoot":"","sources":["../../src/client/SignalingClient.ts"],"names":[],"mappings":"AAUA,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;AA2QD,eAAO,MAAM,cAAc,GAAI,QAAQ,UAAU,SAsBhD,CAAC"}
1
+ {"version":3,"file":"SignalingClient.d.ts","sourceRoot":"","sources":["../../src/client/SignalingClient.ts"],"names":[],"mappings":"AAcA,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;AA2RD,eAAO,MAAM,cAAc,GAAI,QAAQ,UAAU,SAsBhD,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=SignalingClient.incapable.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SignalingClient.incapable.test.d.ts","sourceRoot":"","sources":["../../../src/client/__tests__/SignalingClient.incapable.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=memoryProbe.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memoryProbe.test.d.ts","sourceRoot":"","sources":["../../../src/executor/__tests__/memoryProbe.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ export declare const HEAVY_WORKLOAD_WASM_MEMORY_BYTES: number;
2
+ export declare function probeMaxWasmMemoryBytes(targetBytes?: number, chunkBytes?: number): number;
3
+ export declare function hasEnoughWasmMemoryForHeavy(): boolean;
4
+ //# sourceMappingURL=memoryProbe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memoryProbe.d.ts","sourceRoot":"","sources":["../../src/executor/memoryProbe.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,gCAAgC,QAAgB,CAAC;AAI9D,wBAAgB,uBAAuB,CACrC,WAAW,GAAE,MAAyC,EACtD,UAAU,GAAE,MAA0B,GACrC,MAAM,CA4BR;AAED,wBAAgB,2BAA2B,IAAI,OAAO,CAErD"}
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
+ import { r as e, t } from "./assets/memoryProbe.js";
1
2
  //#region src/consent/ConsentUI.ts
2
- var e = class {
3
+ var n = class {
3
4
  constructor(e, t, n) {
4
5
  this.shadow = e.attachShadow({ mode: "open" }), this.render(t, n);
5
6
  }
@@ -39,39 +40,39 @@ var e = class {
39
40
  c.remove(), t();
40
41
  }), this.shadow.appendChild(s), this.shadow.appendChild(c);
41
42
  }
42
- }, t = "flaxia_consent_granted", n = "flaxia_consent_expiry", r = 720 * 60 * 60 * 1e3, i = /* @__PURE__ */ new Map();
43
- function a(e) {
43
+ }, r = "flaxia_consent_granted", i = "flaxia_consent_expiry", a = 720 * 60 * 60 * 1e3, o = /* @__PURE__ */ new Map();
44
+ function s(e) {
44
45
  try {
45
46
  return localStorage.getItem(e);
46
47
  } catch {
47
- return i.get(e) ?? null;
48
+ return o.get(e) ?? null;
48
49
  }
49
50
  }
50
- function o(e, t) {
51
+ function c(e, t) {
51
52
  try {
52
53
  localStorage.setItem(e, t);
53
54
  } catch {
54
- i.set(e, t);
55
+ o.set(e, t);
55
56
  }
56
57
  }
57
- function s(e) {
58
+ function l(e) {
58
59
  try {
59
60
  localStorage.removeItem(e);
60
61
  } catch {
61
- i.delete(e);
62
+ o.delete(e);
62
63
  }
63
64
  }
64
- var c = () => {
65
- if (a(t) !== "true") return !1;
66
- let e = a(n);
65
+ var u = () => {
66
+ if (s(r) !== "true") return !1;
67
+ let e = s(i);
67
68
  if (e) {
68
- let r = parseInt(e, 10);
69
- if (!Number.isFinite(r) || Date.now() > r) return s(t), s(n), !1;
69
+ let t = parseInt(e, 10);
70
+ if (!Number.isFinite(t) || Date.now() > t) return l(r), l(i), !1;
70
71
  }
71
72
  return !0;
72
- }, l = () => {
73
- o(t, "true"), o(n, String(Date.now() + r));
74
- }, u = a, d = o, f = () => {
73
+ }, d = () => {
74
+ c(r, "true"), c(i, String(Date.now() + a));
75
+ }, f = s, p = c, m = () => {
75
76
  try {
76
77
  if (typeof crypto < "u" && typeof crypto.randomUUID == "function") return crypto.randomUUID();
77
78
  } catch {}
@@ -79,7 +80,7 @@ var c = () => {
79
80
  let t = Math.random() * 16 | 0;
80
81
  return (e === "x" ? t : t & 3 | 8).toString(16);
81
82
  });
82
- }, p = (...e) => console.log("[flaxia-node]", ...e), m = class {
83
+ }, h = (...e) => console.log("[flaxia-node]", ...e), g = class {
83
84
  constructor(e, t = 3e5) {
84
85
  this.worker = null, this.queue = [], this.active = null, this._lastCpuLoad = 0, this.workerUrl = e || "/worker.js", this.defaultTimeoutMs = t, this.initWorker();
85
86
  }
@@ -99,7 +100,7 @@ var c = () => {
99
100
  return;
100
101
  }
101
102
  let c = () => this.execute(e, t, n, r, i, a, o, s);
102
- this.active ? (p(`task queued id=${e} workload=${t} (active task running)`), this.queue.push(c)) : c();
103
+ this.active ? (h(`task queued id=${e} workload=${t} (active task running)`), this.queue.push(c)) : c();
103
104
  });
104
105
  }
105
106
  execute(e, t, n, r, i, a, o, s) {
@@ -109,27 +110,27 @@ var c = () => {
109
110
  return;
110
111
  }
111
112
  let l = r ?? this.defaultTimeoutMs, u = !1, d = performance.now();
112
- p(`task start id=${e} workload=${t} timeoutMs=${l}`);
113
+ h(`task start id=${e} workload=${t} timeoutMs=${l}`);
113
114
  let f = (e) => {
114
115
  if (u) return;
115
116
  u = !0;
116
117
  let t = this.active;
117
118
  t && (clearTimeout(t.timer), t.removeListener()), this.active = null, e(), this.dequeue();
118
- }, m = (n) => {
119
- let { id: r, type: a, result: c, error: l, token: u, cpuLoad: m } = n.data;
119
+ }, p = (n) => {
120
+ let { id: r, type: a, result: c, error: l, token: u, cpuLoad: p } = n.data;
120
121
  if (r === e) {
121
122
  if (a === "token") {
122
123
  i?.(u);
123
124
  return;
124
125
  }
125
126
  if (a === "heartbeat") {
126
- typeof m == "number" && Number.isFinite(m) && (this._lastCpuLoad = Math.min(1, Math.max(0, m)));
127
+ typeof p == "number" && Number.isFinite(p) && (this._lastCpuLoad = Math.min(1, Math.max(0, p)));
127
128
  return;
128
129
  }
129
- a === "done" ? (p(`task done id=${e} workload=${t} durationMs=${Math.round(performance.now() - d)}`), f(() => o(c))) : a === "error" ? (p(`task failed id=${e} workload=${t} error=${l}`), f(() => s(Error(l)))) : (p(`task unknown-message id=${e} type=${String(a)}`), f(() => s(/* @__PURE__ */ Error(`Unknown message type: ${String(a)}`))));
130
+ a === "done" ? (h(`task done id=${e} workload=${t} durationMs=${Math.round(performance.now() - d)}`), f(() => o(c))) : a === "error" ? (h(`task failed id=${e} workload=${t} error=${l}`), f(() => s(Error(l)))) : (h(`task unknown-message id=${e} type=${String(a)}`), f(() => s(/* @__PURE__ */ Error(`Unknown message type: ${String(a)}`))));
130
131
  }
131
- }, h = () => c.removeEventListener("message", m), g = setTimeout(() => {
132
- p(`task timeout id=${e} workload=${t} (worker terminated after ${l}ms)`), this.cleanupWorker(), f(() => s(/* @__PURE__ */ Error("TIMEOUT")));
132
+ }, m = () => c.removeEventListener("message", p), g = setTimeout(() => {
133
+ h(`task timeout id=${e} workload=${t} (worker terminated after ${l}ms)`), this.cleanupWorker(), f(() => s(/* @__PURE__ */ Error("TIMEOUT")));
133
134
  }, l);
134
135
  this.active = {
135
136
  id: e,
@@ -137,8 +138,8 @@ var c = () => {
137
138
  reject: s,
138
139
  timer: g,
139
140
  worker: c,
140
- removeListener: h
141
- }, c.addEventListener("message", m);
141
+ removeListener: m
142
+ }, c.addEventListener("message", p);
142
143
  try {
143
144
  c.postMessage({
144
145
  id: e,
@@ -152,7 +153,7 @@ var c = () => {
152
153
  }
153
154
  }
154
155
  handleWorkerError(e) {
155
- p(`worker error error=${e.message}`);
156
+ h(`worker error error=${e.message}`);
156
157
  let t = this.active;
157
158
  this.cleanupWorker(), t && (clearTimeout(t.timer), this.active = null, t.reject(e), this.dequeue());
158
159
  }
@@ -172,13 +173,13 @@ var c = () => {
172
173
  get lastCpuLoad() {
173
174
  return this._lastCpuLoad;
174
175
  }
175
- }, h = (...e) => console.log("[flaxia-node]", ...e), g = (...e) => console.error("[flaxia-node]", ...e), _ = "flaxia_node_id", v = "flaxia_node_token", y = class {
176
+ }, _ = (...e) => console.log("[flaxia-node]", ...e), v = (...e) => console.error("[flaxia-node]", ...e), y = "flaxia_node_id", b = "flaxia_node_token", x = class {
176
177
  constructor(e, t, n) {
177
178
  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();
178
179
  }
179
180
  async connect() {
180
181
  if (this.destroyed) return;
181
- if (h(`connect nodeId=${this.nodeId}`), this.ws) {
182
+ if (_(`connect nodeId=${this.nodeId}`), this.ws) {
182
183
  let e = this.ws;
183
184
  e.onclose = null;
184
185
  try {
@@ -189,14 +190,14 @@ var c = () => {
189
190
  this.setupVisibilityHandler();
190
191
  let e = await this.obtainToken();
191
192
  if (!e) {
192
- g("token acquisition failed; scheduling reconnect"), this.scheduleReconnect();
193
+ v("token acquisition failed; scheduling reconnect"), this.scheduleReconnect();
193
194
  return;
194
195
  }
195
196
  let t = this.config.orchestratorUrl.replace(/\/+$/, "").replace(/^http/, "ws"), n = new URL(`${t}/crowd/signal`);
196
197
  n.searchParams.set("token", e.token);
197
198
  let r = new WebSocket(n.toString());
198
199
  this.ws = r, r.onopen = () => {
199
- this.reconnectAttempts = 0, h(`signal connected ${n.toString()}`);
200
+ this.reconnectAttempts = 0, _(`signal connected ${n.toString()}`);
200
201
  }, r.onmessage = async (e) => {
201
202
  let t;
202
203
  try {
@@ -213,12 +214,12 @@ var c = () => {
213
214
  }
214
215
  if (t.type === "task") {
215
216
  let e = t;
216
- h(`task received taskId=${e.taskId} workload=${e.workload} timeoutMs=${e.timeoutMs ?? "default"}`);
217
+ _(`task received taskId=${e.taskId} workload=${e.workload} timeoutMs=${e.timeoutMs ?? "default"}`);
217
218
  try {
218
219
  await this.handleTask(e);
219
220
  } catch (n) {
220
221
  let r = n instanceof Error ? n.message : String(n);
221
- g(`task failed taskId=${e.taskId} workload=${e.workload} error=${r}`), this.send({
222
+ v(`task failed taskId=${e.taskId} workload=${e.workload} error=${r}`), this.send({
222
223
  type: "error",
223
224
  taskId: String(t.taskId ?? ""),
224
225
  error: r
@@ -226,7 +227,7 @@ var c = () => {
226
227
  }
227
228
  }
228
229
  }, r.onclose = () => {
229
- r.onclose = null, this.ws === r && (this.ws = null, !this.destroyed && (h(`signal disconnected; scheduling reconnect attempt=${this.reconnectAttempts + 1}`), this.scheduleReconnect()));
230
+ r.onclose = null, this.ws === r && (this.ws = null, !this.destroyed && (_(`signal disconnected; scheduling reconnect attempt=${this.reconnectAttempts + 1}`), this.scheduleReconnect()));
230
231
  };
231
232
  }
232
233
  scheduleReconnect() {
@@ -236,13 +237,13 @@ var c = () => {
236
237
  }, e);
237
238
  }
238
239
  disconnect() {
239
- h(`disconnect nodeId=${this.nodeId}`), this.destroyed = !0, this.suspended = !1, this.removeVisibilityHandler();
240
+ _(`disconnect nodeId=${this.nodeId}`), this.destroyed = !0, this.suspended = !1, this.removeVisibilityHandler();
240
241
  try {
241
242
  this.ws?.close();
242
243
  } catch {}
243
244
  this.ws = null;
244
245
  try {
245
- delete window[x];
246
+ delete window[C];
246
247
  } catch {}
247
248
  try {
248
249
  this.workerPool.terminate();
@@ -250,7 +251,7 @@ var c = () => {
250
251
  }
251
252
  suspend() {
252
253
  if (!(this.suspended || this.destroyed)) {
253
- if (h("suspended (visibility or manual)"), this.suspended = !0, this.ws) {
254
+ if (_("suspended (visibility or manual)"), this.suspended = !0, this.ws) {
254
255
  let e = this.ws;
255
256
  e.onclose = null;
256
257
  try {
@@ -262,35 +263,38 @@ var c = () => {
262
263
  }
263
264
  }
264
265
  resume() {
265
- !this.suspended || this.destroyed || (h("resumed"), this.suspended = !1, this.workerPool.resume(), this.connect());
266
+ !this.suspended || this.destroyed || (_("resumed"), this.suspended = !1, this.workerPool.resume(), this.connect());
266
267
  }
267
268
  async obtainToken() {
268
269
  try {
269
- let e = u(v);
270
- if (e) try {
271
- let t = JSON.parse(e);
272
- if (t.token && t.nodeId && t.expiresAt > Date.now() + 6e4) return h(`token cached nodeId=${t.nodeId} expiresIn=${Math.round((t.expiresAt - Date.now()) / 1e3)}s`), t;
270
+ let n = f(b);
271
+ if (n) try {
272
+ let e = JSON.parse(n);
273
+ if (e.token && e.nodeId && e.expiresAt > Date.now() + 6e4) return _(`token cached nodeId=${e.nodeId} expiresIn=${Math.round((e.expiresAt - Date.now()) / 1e3)}s`), e;
273
274
  } catch {}
274
- let t = this.config.orchestratorUrl.replace(/\/+$/, ""), n = await fetch(`${t}/crowd/nodes/register`, {
275
+ let r = e(), i = r >= t, a = i ? this.config.capabilities ?? ["ai-inference", "image-process"] : [];
276
+ _(`register capability probe capable=${i} wasmMemoryBytes=${r} capabilities=${JSON.stringify(a)}`);
277
+ let o = this.config.orchestratorUrl.replace(/\/+$/, ""), s = await fetch(`${o}/crowd/nodes/register`, {
275
278
  method: "POST",
276
279
  headers: { "Content-Type": "application/json" },
277
280
  body: JSON.stringify({
278
281
  siteId: this.config.siteId,
279
282
  nodeId: this.nodeId,
280
- capabilities: this.config.capabilities ?? ["ai-inference", "image-process"],
283
+ capabilities: a,
284
+ wasmMemoryBytes: e(),
281
285
  deviceMemory: typeof navigator.deviceMemory == "number" ? navigator.deviceMemory : null
282
286
  })
283
287
  });
284
- if (!n.ok) return g(`node register failed HTTP ${n.status} (${t}/crowd/nodes/register)`), null;
285
- let r = await n.json();
286
- if (!r.token) return g("node register returned no token"), null;
287
- h(`node registered nodeId=${this.nodeId} expiresIn=${Math.round((r.expiresAt - Date.now()) / 1e3)}s`);
288
+ if (!s.ok) return v(`node register failed HTTP ${s.status} (${o}/crowd/nodes/register)`), null;
289
+ let c = await s.json();
290
+ if (!c.token) return v("node register returned no token"), null;
291
+ _(`node registered nodeId=${this.nodeId} expiresIn=${Math.round((c.expiresAt - Date.now()) / 1e3)}s`);
288
292
  try {
289
- d(v, JSON.stringify(r));
293
+ p(b, JSON.stringify(c));
290
294
  } catch {}
291
- return r;
295
+ return c;
292
296
  } catch (e) {
293
- return g("node register threw", e instanceof Error ? e.message : e), null;
297
+ return v("node register threw", e instanceof Error ? e.message : e), null;
294
298
  }
295
299
  }
296
300
  send(e) {
@@ -312,7 +316,7 @@ var c = () => {
312
316
  type: "result",
313
317
  taskId: e.taskId,
314
318
  payload: r
315
- }), h(`task result sent taskId=${e.taskId} workload=${e.workload} durationMs=${Math.round(performance.now() - t)}`);
319
+ }), _(`task result sent taskId=${e.taskId} workload=${e.workload} durationMs=${Math.round(performance.now() - t)}`);
316
320
  } finally {
317
321
  this.inflightTasks.delete(e.taskId);
318
322
  }
@@ -325,23 +329,23 @@ var c = () => {
325
329
  removeVisibilityHandler() {
326
330
  this.visibilityHandler &&= (document.removeEventListener("visibilitychange", this.visibilityHandler), null);
327
331
  }
328
- }, b = "__flaxia_node_signal_client", x = "__flaxia_node_init_started", S = (e) => {
329
- let t = window[b];
332
+ }, S = "__flaxia_node_signal_client", C = "__flaxia_node_init_started", w = (e) => {
333
+ let t = window[S];
330
334
  t && t.disconnect();
331
- let n = new URL("./worker.js", "" + import.meta.url).href, r = new m(n), i = u(_);
332
- i || (i = f(), d(_, i));
333
- let a = new y(e, r, i);
334
- window[b] = a, a.connect();
335
- }, C = (t) => {
336
- if (window[x]) return;
337
- if (window[x] = !0, c()) {
338
- S(t);
335
+ let n = new URL("./worker.js", "" + import.meta.url).href, r = new g(n), i = f(y);
336
+ i || (i = m(), p(y, i));
337
+ let a = new x(e, r, i);
338
+ window[S] = a, a.connect();
339
+ }, T = (e) => {
340
+ if (window[C]) return;
341
+ if (window[C] = !0, u()) {
342
+ w(e);
339
343
  return;
340
344
  }
341
- let n = document.createElement("div");
342
- n.id = "flaxia-consent-container", document.body.appendChild(n), new e(n, t.consent, () => {
343
- l(), n.remove(), S(t);
345
+ let t = document.createElement("div");
346
+ t.id = "flaxia-consent-container", document.body.appendChild(t), new n(t, e.consent, () => {
347
+ d(), t.remove(), w(e);
344
348
  });
345
349
  };
346
350
  //#endregion
347
- export { C as initFlaxiaNode };
351
+ export { T as initFlaxiaNode };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=main.worker.capable.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.worker.capable.test.d.ts","sourceRoot":"","sources":["../../../src/worker/__tests__/main.worker.capable.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=main.worker.incapable.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.worker.incapable.test.d.ts","sourceRoot":"","sources":["../../../src/worker/__tests__/main.worker.incapable.test.ts"],"names":[],"mappings":""}
package/dist/worker.js CHANGED
@@ -1,14 +1,15 @@
1
+ import { n as e, r as t, t as n } from "./assets/memoryProbe.js";
1
2
  //#region src/executor/throttle.ts
2
- function e(e) {
3
+ function r(e) {
3
4
  return new Promise((t) => setTimeout(t, e));
4
5
  }
5
- var t = 3e4, n = 3e4, r = class {
6
+ var i = 3e4, a = 3e4, o = class {
6
7
  constructor(e = .15) {
7
8
  this.windowStart = performance.now(), this.windowBusyMs = 0, this.lastLoad = 0, this.maxLoad = Math.max(.05, Math.min(.3, e));
8
9
  }
9
10
  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();
11
+ let t = performance.now();
12
+ t - this.windowStart > i && (this.windowStart = t, this.windowBusyMs = 0), this.windowBusyMs += Math.max(0, e), this.lastLoad = this.estimate();
12
13
  }
13
14
  estimate() {
14
15
  let e = performance.now() - this.windowStart;
@@ -17,9 +18,9 @@ var t = 3e4, n = 3e4, r = class {
17
18
  async shouldPause() {
18
19
  return this.estimate() > this.maxLoad;
19
20
  }
20
- async waitForSlot(t = n) {
21
- let r = performance.now();
22
- for (; await this.shouldPause() && !(performance.now() - r > t);) await e(500);
21
+ async waitForSlot(e = a) {
22
+ let t = performance.now();
23
+ for (; await this.shouldPause() && !(performance.now() - t > e);) await r(500);
23
24
  }
24
25
  get lastMeasuredLoad() {
25
26
  return this.lastLoad;
@@ -27,69 +28,67 @@ var t = 3e4, n = 3e4, r = class {
27
28
  get maxLoadValue() {
28
29
  return this.maxLoad;
29
30
  }
30
- }, i = null, a = new Set([
31
+ }, s = null, c = new Set([
31
32
  "ai-inference",
32
33
  "vector-embed",
33
34
  "vector-query",
34
35
  "nudenet",
35
36
  "image-process",
36
37
  "container"
37
- ]), o = 6e4;
38
- function s() {
39
- let e = navigator.deviceMemory;
40
- return typeof e == "number" && e >= 4;
38
+ ]), l = 6e4, u = t(), d = u >= n;
39
+ console.log(`[flaxia-node:worker] startup memory probe wasmMemoryBytes=${u} capable=${d}`);
40
+ function f() {
41
+ return e();
41
42
  }
42
- var c = /* @__PURE__ */ new Map(), l = null;
43
- function u() {
44
- for (let e of c.values()) try {
43
+ var p = /* @__PURE__ */ new Map(), m = null;
44
+ function h() {
45
+ for (let e of p.values()) try {
45
46
  e();
46
47
  } catch {}
47
- c.clear();
48
+ p.clear();
48
49
  }
49
- function d() {
50
- l && clearTimeout(l), l = setTimeout(() => {
51
- l = null, u();
52
- }, o);
50
+ function g() {
51
+ m && clearTimeout(m), m = setTimeout(() => {
52
+ m = null, h();
53
+ }, l);
53
54
  }
54
- async function f(e, t, n) {
55
+ async function _(e, t, n) {
55
56
  switch (e) {
56
57
  case "ai-inference":
57
58
  let r = await import("./assets/ai-inference.js");
58
- return c.set(e, r.releaseCache), await r.handleAiInference(t, n);
59
+ return p.set(e, r.releaseCache), await r.handleAiInference(t, n);
59
60
  case "image-process": return await (await import("./assets/image-process.js")).handleImageProcess(t);
60
61
  case "container": return await (await import("./assets/container.js")).handleContainer(t);
61
62
  case "vector-embed":
62
63
  let i = await import("./assets/vector-embed.js");
63
- return c.set(e, i.releaseCache), await i.handleVectorEmbed(t);
64
+ return p.set(e, i.releaseCache), await i.handleVectorEmbed(t);
64
65
  case "vector-store":
65
66
  let a = await import("./assets/vector-store.js");
66
- return c.set(e, a.releaseCache), await a.handleVectorStore(t);
67
+ return p.set(e, a.releaseCache), await a.handleVectorStore(t);
67
68
  case "vector-query":
68
69
  let o = await import("./assets/vector-query.js");
69
- return c.set(e, o.releaseCache), await o.handleVectorQuery(t);
70
+ return p.set(e, o.releaseCache), await o.handleVectorQuery(t);
70
71
  case "nudenet":
71
72
  let s = await import("./assets/nudenet.js");
72
- return c.set(e, s.releaseCache), await s.handleNudeNet(t);
73
+ return p.set(e, s.releaseCache), await s.handleNudeNet(t);
73
74
  default: throw Error(`Unknown workload type: ${e}`);
74
75
  }
75
76
  }
76
77
  self.onmessage = async (e) => {
77
- let { id: t, workload: n, payload: o, config: c } = e.data, l = performance.now();
78
+ let { id: t, workload: r, payload: i, config: a } = e.data, l = performance.now();
78
79
  try {
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();
80
+ if (s ||= new o(a?.maxCpuLoad), console.log(`[flaxia-node:worker] task start id=${t} workload=${r}`), !d) throw Error(`node incapable: insufficient WASM memory (${u} bytes < ${n}); rejecting all tasks`);
81
+ if (c.has(r) && !f()) throw Error(`${r}: insufficient WASM memory (${u} bytes < ${n})`);
82
+ await s.waitForSlot();
84
83
  let e = setInterval(() => {
85
84
  self.postMessage({
86
85
  id: t,
87
86
  type: "heartbeat",
88
- cpuLoad: i?.lastMeasuredLoad ?? 0
87
+ cpuLoad: s?.lastMeasuredLoad ?? 0
89
88
  });
90
- }, 1e4), u = performance.now();
89
+ }, 1e4), p = performance.now();
91
90
  try {
92
- let e = await f(n, o, (e) => {
91
+ let e = await _(r, i, (e) => {
93
92
  self.postMessage({
94
93
  id: t,
95
94
  type: "token",
@@ -100,16 +99,16 @@ self.onmessage = async (e) => {
100
99
  id: t,
101
100
  type: "done",
102
101
  result: e
103
- }), console.log(`[flaxia-node:worker] task done id=${t} workload=${n} durationMs=${Math.round(performance.now() - l)}`);
102
+ }), console.log(`[flaxia-node:worker] task done id=${t} workload=${r} durationMs=${Math.round(performance.now() - l)}`);
104
103
  } finally {
105
- clearInterval(e), i.markTaskComplete(performance.now() - u), d();
104
+ clearInterval(e), s.markTaskComplete(performance.now() - p), g();
106
105
  }
107
106
  } catch (e) {
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({
107
+ let n = e instanceof Error ? e.message : String(e);
108
+ console.error(`[flaxia-node:worker] task error id=${t} workload=${r} error=${n}`), self.postMessage({
110
109
  id: t,
111
110
  type: "error",
112
- error: r
111
+ error: n
113
112
  });
114
113
  }
115
114
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flaxia/node",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "private": false,
5
5
  "main": "dist/index.js",
6
6
  "types": "./dist/index.d.ts",