@flaxia/node 0.3.3 → 0.3.5

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":"AAgBA,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,SAkChD,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":""}
@@ -5,7 +5,7 @@ interface ConsentConfig {
5
5
  }
6
6
  export declare class ConsentUI {
7
7
  private shadow;
8
- constructor(container: HTMLElement, config: ConsentConfig, onConsent: () => void);
8
+ constructor(container: HTMLElement, config: ConsentConfig, onConsent: () => void, onReject?: () => void);
9
9
  private render;
10
10
  }
11
11
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"ConsentUI.d.ts","sourceRoot":"","sources":["../../src/consent/ConsentUI.ts"],"names":[],"mappings":"AAAA,UAAU,aAAa;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,cAAc,GAAG,aAAa,GAAG,WAAW,GAAG,UAAU,CAAC;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAa;gBAEf,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,IAAI;IAKhF,OAAO,CAAC,MAAM;CA+Cf"}
1
+ {"version":3,"file":"ConsentUI.d.ts","sourceRoot":"","sources":["../../src/consent/ConsentUI.ts"],"names":[],"mappings":"AAAA,UAAU,aAAa;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,cAAc,GAAG,aAAa,GAAG,WAAW,GAAG,UAAU,CAAC;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAa;gBAGzB,SAAS,EAAE,WAAW,EACtB,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,MAAM,IAAI,EACrB,QAAQ,CAAC,EAAE,MAAM,IAAI;IAMvB,OAAO,CAAC,MAAM;CAyFf"}
@@ -3,6 +3,8 @@ declare function safeSet(key: string, value: string): void;
3
3
  declare function safeRemove(key: string): void;
4
4
  export declare const hasConsent: () => boolean;
5
5
  export declare const saveConsent: () => void;
6
+ export declare const hasDenial: () => boolean;
7
+ export declare const saveDenial: () => void;
6
8
  export declare const safeLocalStorageGet: typeof safeGet;
7
9
  export declare const safeLocalStorageSet: typeof safeSet;
8
10
  export declare const safeLocalStorageRemove: typeof safeRemove;
@@ -1 +1 @@
1
- {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/consent/storage.ts"],"names":[],"mappings":"AAWA,iBAAS,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM3C;AAED,iBAAS,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAMjD;AAED,iBAAS,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAMrC;AAED,eAAO,MAAM,UAAU,QAAO,OAgB7B,CAAC;AAEF,eAAO,MAAM,WAAW,QAAO,IAG9B,CAAC;AAEF,eAAO,MAAM,mBAAmB,gBAAU,CAAC;AAC3C,eAAO,MAAM,mBAAmB,gBAAU,CAAC;AAC3C,eAAO,MAAM,sBAAsB,mBAAa,CAAC;AAEjD;;;;GAIG;AACH,eAAO,MAAM,cAAc,QAAO,MAajC,CAAC"}
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/consent/storage.ts"],"names":[],"mappings":"AAYA,iBAAS,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM3C;AAED,iBAAS,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAMjD;AAED,iBAAS,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAMrC;AAED,eAAO,MAAM,UAAU,QAAO,OAgB7B,CAAC;AAEF,eAAO,MAAM,WAAW,QAAO,IAG9B,CAAC;AAEF,eAAO,MAAM,SAAS,QAAO,OAE5B,CAAC;AAEF,eAAO,MAAM,UAAU,QAAO,IAE7B,CAAC;AAEF,eAAO,MAAM,mBAAmB,gBAAU,CAAC;AAC3C,eAAO,MAAM,mBAAmB,gBAAU,CAAC;AAC3C,eAAO,MAAM,sBAAsB,mBAAa,CAAC;AAEjD;;;;GAIG;AACH,eAAO,MAAM,cAAc,QAAO,MAajC,CAAC"}
@@ -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,17 +1,19 @@
1
+ import { r as e, t } from "./assets/memoryProbe.js";
1
2
  //#region src/consent/ConsentUI.ts
2
- var e = class {
3
- constructor(e, t, n) {
4
- this.shadow = e.attachShadow({ mode: "open" }), this.render(t, n);
3
+ var n = class {
4
+ constructor(e, t, n, r) {
5
+ this.shadow = e.attachShadow({ mode: "open" }), this.render(t, n, r);
5
6
  }
6
- render(e, t) {
7
- let { brandName: n, position: r, accentColor: i = "#6366f1" } = e, [a, o] = r.split("-"), s = document.createElement("style");
8
- s.textContent = `
7
+ render(e, t, n) {
8
+ let { brandName: r, position: i, accentColor: a = "#6366f1" } = e, [o, s] = i.split("-"), c = document.createElement("style");
9
+ c.textContent = `
9
10
  .overlay {
10
11
  position: fixed;
11
- ${a}: 20px;
12
12
  ${o}: 20px;
13
+ ${s}: 20px;
13
14
  padding: 20px;
14
15
  background: #fff;
16
+ color: #1f2937;
15
17
  border: 1px solid #ccc;
16
18
  box-shadow: 0 4px 6px rgba(0,0,0,0.1);
17
19
  z-index: 9999;
@@ -19,8 +21,19 @@ var e = class {
19
21
  max-width: 300px;
20
22
  font-family: sans-serif;
21
23
  }
24
+ .overlay h3 {
25
+ margin: 0 0 8px;
26
+ color: #111827;
27
+ font-size: 16px;
28
+ }
29
+ .overlay p {
30
+ margin: 0 0 12px;
31
+ color: #4b5563;
32
+ font-size: 14px;
33
+ line-height: 1.4;
34
+ }
22
35
  button {
23
- background: ${i};
36
+ background: ${a};
24
37
  color: white;
25
38
  border: none;
26
39
  padding: 10px 15px;
@@ -28,50 +41,79 @@ var e = class {
28
41
  cursor: pointer;
29
42
  margin-top: 10px;
30
43
  width: 100%;
44
+ font-size: 14px;
45
+ }
46
+ button.reject {
47
+ background: transparent;
48
+ color: #4b5563;
49
+ border: 1px solid #ccc;
50
+ }
51
+ @media (prefers-color-scheme: dark) {
52
+ .overlay {
53
+ background: #1f2937;
54
+ color: #f9fafb;
55
+ border-color: #374151;
56
+ box-shadow: 0 4px 6px rgba(0,0,0,0.4);
57
+ }
58
+ .overlay h3 {
59
+ color: #f9fafb;
60
+ }
61
+ .overlay p {
62
+ color: #d1d5db;
63
+ }
64
+ button.reject {
65
+ color: #d1d5db;
66
+ border-color: #4b5563;
67
+ }
31
68
  }
32
69
  `;
33
- let c = document.createElement("div");
34
- c.className = "overlay", c.innerHTML = `
35
- <h3>${n}</h3>
70
+ let l = document.createElement("div");
71
+ l.className = "overlay", l.innerHTML = `
72
+ <h3>${r}</h3>
36
73
  <p>サイトのパフォーマンス向上にご協力ください。</p>
37
74
  <button id="consent-btn">同意して開始</button>
38
- `, c.querySelector("#consent-btn")?.addEventListener("click", () => {
39
- c.remove(), t();
40
- }), this.shadow.appendChild(s), this.shadow.appendChild(c);
75
+ <button id="reject-btn" class="reject">拒否</button>
76
+ `, l.querySelector("#consent-btn")?.addEventListener("click", () => {
77
+ l.remove(), t();
78
+ }), l.querySelector("#reject-btn")?.addEventListener("click", () => {
79
+ l.remove(), n?.();
80
+ }), this.shadow.appendChild(c), this.shadow.appendChild(l);
41
81
  }
42
- }, t = "flaxia_consent_granted", n = "flaxia_consent_expiry", r = 720 * 60 * 60 * 1e3, i = /* @__PURE__ */ new Map();
43
- function a(e) {
82
+ }, r = "flaxia_consent_granted", i = "flaxia_consent_expiry", a = "flaxia_consent_denied", o = 720 * 60 * 60 * 1e3, s = /* @__PURE__ */ new Map();
83
+ function c(e) {
44
84
  try {
45
85
  return localStorage.getItem(e);
46
86
  } catch {
47
- return i.get(e) ?? null;
87
+ return s.get(e) ?? null;
48
88
  }
49
89
  }
50
- function o(e, t) {
90
+ function l(e, t) {
51
91
  try {
52
92
  localStorage.setItem(e, t);
53
93
  } catch {
54
- i.set(e, t);
94
+ s.set(e, t);
55
95
  }
56
96
  }
57
- function s(e) {
97
+ function u(e) {
58
98
  try {
59
99
  localStorage.removeItem(e);
60
100
  } catch {
61
- i.delete(e);
101
+ s.delete(e);
62
102
  }
63
103
  }
64
- var c = () => {
65
- if (a(t) !== "true") return !1;
66
- let e = a(n);
104
+ var d = () => {
105
+ if (c(r) !== "true") return !1;
106
+ let e = c(i);
67
107
  if (e) {
68
- let r = parseInt(e, 10);
69
- if (!Number.isFinite(r) || Date.now() > r) return s(t), s(n), !1;
108
+ let t = parseInt(e, 10);
109
+ if (!Number.isFinite(t) || Date.now() > t) return u(r), u(i), !1;
70
110
  }
71
111
  return !0;
72
- }, l = () => {
73
- o(t, "true"), o(n, String(Date.now() + r));
74
- }, u = a, d = o, f = () => {
112
+ }, f = () => {
113
+ l(r, "true"), l(i, String(Date.now() + o));
114
+ }, p = () => c(a) === "true", m = () => {
115
+ l(a, "true");
116
+ }, h = c, g = l, _ = () => {
75
117
  try {
76
118
  if (typeof crypto < "u" && typeof crypto.randomUUID == "function") return crypto.randomUUID();
77
119
  } catch {}
@@ -79,7 +121,7 @@ var c = () => {
79
121
  let t = Math.random() * 16 | 0;
80
122
  return (e === "x" ? t : t & 3 | 8).toString(16);
81
123
  });
82
- }, p = (...e) => console.log("[flaxia-node]", ...e), m = class {
124
+ }, v = (...e) => console.log("[flaxia-node]", ...e), y = class {
83
125
  constructor(e, t = 3e5) {
84
126
  this.worker = null, this.queue = [], this.active = null, this._lastCpuLoad = 0, this.workerUrl = e || "/worker.js", this.defaultTimeoutMs = t, this.initWorker();
85
127
  }
@@ -99,7 +141,7 @@ var c = () => {
99
141
  return;
100
142
  }
101
143
  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();
144
+ this.active ? (v(`task queued id=${e} workload=${t} (active task running)`), this.queue.push(c)) : c();
103
145
  });
104
146
  }
105
147
  execute(e, t, n, r, i, a, o, s) {
@@ -109,36 +151,36 @@ var c = () => {
109
151
  return;
110
152
  }
111
153
  let l = r ?? this.defaultTimeoutMs, u = !1, d = performance.now();
112
- p(`task start id=${e} workload=${t} timeoutMs=${l}`);
154
+ v(`task start id=${e} workload=${t} timeoutMs=${l}`);
113
155
  let f = (e) => {
114
156
  if (u) return;
115
157
  u = !0;
116
158
  let t = this.active;
117
159
  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;
160
+ }, p = (n) => {
161
+ let { id: r, type: a, result: c, error: l, token: u, cpuLoad: p } = n.data;
120
162
  if (r === e) {
121
163
  if (a === "token") {
122
164
  i?.(u);
123
165
  return;
124
166
  }
125
167
  if (a === "heartbeat") {
126
- typeof m == "number" && Number.isFinite(m) && (this._lastCpuLoad = Math.min(1, Math.max(0, m)));
168
+ typeof p == "number" && Number.isFinite(p) && (this._lastCpuLoad = Math.min(1, Math.max(0, p)));
127
169
  return;
128
170
  }
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)}`))));
171
+ a === "done" ? (v(`task done id=${e} workload=${t} durationMs=${Math.round(performance.now() - d)}`), f(() => o(c))) : a === "error" ? (v(`task failed id=${e} workload=${t} error=${l}`), f(() => s(Error(l)))) : (v(`task unknown-message id=${e} type=${String(a)}`), f(() => s(/* @__PURE__ */ Error(`Unknown message type: ${String(a)}`))));
130
172
  }
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")));
173
+ }, m = () => c.removeEventListener("message", p), h = setTimeout(() => {
174
+ v(`task timeout id=${e} workload=${t} (worker terminated after ${l}ms)`), this.cleanupWorker(), f(() => s(/* @__PURE__ */ Error("TIMEOUT")));
133
175
  }, l);
134
176
  this.active = {
135
177
  id: e,
136
178
  resolve: o,
137
179
  reject: s,
138
- timer: g,
180
+ timer: h,
139
181
  worker: c,
140
- removeListener: h
141
- }, c.addEventListener("message", m);
182
+ removeListener: m
183
+ }, c.addEventListener("message", p);
142
184
  try {
143
185
  c.postMessage({
144
186
  id: e,
@@ -152,7 +194,7 @@ var c = () => {
152
194
  }
153
195
  }
154
196
  handleWorkerError(e) {
155
- p(`worker error error=${e.message}`);
197
+ v(`worker error error=${e.message}`);
156
198
  let t = this.active;
157
199
  this.cleanupWorker(), t && (clearTimeout(t.timer), this.active = null, t.reject(e), this.dequeue());
158
200
  }
@@ -172,13 +214,13 @@ var c = () => {
172
214
  get lastCpuLoad() {
173
215
  return this._lastCpuLoad;
174
216
  }
175
- }, h = (...e) => console.log("[flaxia-node]", ...e), g = (...e) => console.error("[flaxia-node]", ...e), _ = "flaxia_node_id", v = "flaxia_node_token", y = class {
217
+ }, b = (...e) => console.log("[flaxia-node]", ...e), x = (...e) => console.error("[flaxia-node]", ...e), S = "flaxia_node_id", C = "flaxia_node_token", w = class {
176
218
  constructor(e, t, n) {
177
219
  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
220
  }
179
221
  async connect() {
180
222
  if (this.destroyed) return;
181
- if (h(`connect nodeId=${this.nodeId}`), this.ws) {
223
+ if (b(`connect nodeId=${this.nodeId}`), this.ws) {
182
224
  let e = this.ws;
183
225
  e.onclose = null;
184
226
  try {
@@ -189,14 +231,14 @@ var c = () => {
189
231
  this.setupVisibilityHandler();
190
232
  let e = await this.obtainToken();
191
233
  if (!e) {
192
- g("token acquisition failed; scheduling reconnect"), this.scheduleReconnect();
234
+ x("token acquisition failed; scheduling reconnect"), this.scheduleReconnect();
193
235
  return;
194
236
  }
195
237
  let t = this.config.orchestratorUrl.replace(/\/+$/, "").replace(/^http/, "ws"), n = new URL(`${t}/crowd/signal`);
196
238
  n.searchParams.set("token", e.token);
197
239
  let r = new WebSocket(n.toString());
198
240
  this.ws = r, r.onopen = () => {
199
- this.reconnectAttempts = 0, h(`signal connected ${n.toString()}`);
241
+ this.reconnectAttempts = 0, b(`signal connected ${n.toString()}`);
200
242
  }, r.onmessage = async (e) => {
201
243
  let t;
202
244
  try {
@@ -213,12 +255,12 @@ var c = () => {
213
255
  }
214
256
  if (t.type === "task") {
215
257
  let e = t;
216
- h(`task received taskId=${e.taskId} workload=${e.workload} timeoutMs=${e.timeoutMs ?? "default"}`);
258
+ b(`task received taskId=${e.taskId} workload=${e.workload} timeoutMs=${e.timeoutMs ?? "default"}`);
217
259
  try {
218
260
  await this.handleTask(e);
219
261
  } catch (n) {
220
262
  let r = n instanceof Error ? n.message : String(n);
221
- g(`task failed taskId=${e.taskId} workload=${e.workload} error=${r}`), this.send({
263
+ x(`task failed taskId=${e.taskId} workload=${e.workload} error=${r}`), this.send({
222
264
  type: "error",
223
265
  taskId: String(t.taskId ?? ""),
224
266
  error: r
@@ -226,7 +268,7 @@ var c = () => {
226
268
  }
227
269
  }
228
270
  }, 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()));
271
+ r.onclose = null, this.ws === r && (this.ws = null, !this.destroyed && (b(`signal disconnected; scheduling reconnect attempt=${this.reconnectAttempts + 1}`), this.scheduleReconnect()));
230
272
  };
231
273
  }
232
274
  scheduleReconnect() {
@@ -236,13 +278,13 @@ var c = () => {
236
278
  }, e);
237
279
  }
238
280
  disconnect() {
239
- h(`disconnect nodeId=${this.nodeId}`), this.destroyed = !0, this.suspended = !1, this.removeVisibilityHandler();
281
+ b(`disconnect nodeId=${this.nodeId}`), this.destroyed = !0, this.suspended = !1, this.removeVisibilityHandler();
240
282
  try {
241
283
  this.ws?.close();
242
284
  } catch {}
243
285
  this.ws = null;
244
286
  try {
245
- delete window[x];
287
+ delete window[E];
246
288
  } catch {}
247
289
  try {
248
290
  this.workerPool.terminate();
@@ -250,7 +292,7 @@ var c = () => {
250
292
  }
251
293
  suspend() {
252
294
  if (!(this.suspended || this.destroyed)) {
253
- if (h("suspended (visibility or manual)"), this.suspended = !0, this.ws) {
295
+ if (b("suspended (visibility or manual)"), this.suspended = !0, this.ws) {
254
296
  let e = this.ws;
255
297
  e.onclose = null;
256
298
  try {
@@ -262,35 +304,38 @@ var c = () => {
262
304
  }
263
305
  }
264
306
  resume() {
265
- !this.suspended || this.destroyed || (h("resumed"), this.suspended = !1, this.workerPool.resume(), this.connect());
307
+ !this.suspended || this.destroyed || (b("resumed"), this.suspended = !1, this.workerPool.resume(), this.connect());
266
308
  }
267
309
  async obtainToken() {
268
310
  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;
311
+ let n = h(C);
312
+ if (n) try {
313
+ let e = JSON.parse(n);
314
+ if (e.token && e.nodeId && e.expiresAt > Date.now() + 6e4) return b(`token cached nodeId=${e.nodeId} expiresIn=${Math.round((e.expiresAt - Date.now()) / 1e3)}s`), e;
273
315
  } catch {}
274
- let t = this.config.orchestratorUrl.replace(/\/+$/, ""), n = await fetch(`${t}/crowd/nodes/register`, {
316
+ let r = e(), i = r >= t, a = i ? this.config.capabilities ?? ["ai-inference", "image-process"] : [];
317
+ b(`register capability probe capable=${i} wasmMemoryBytes=${r} capabilities=${JSON.stringify(a)}`);
318
+ let o = this.config.orchestratorUrl.replace(/\/+$/, ""), s = await fetch(`${o}/crowd/nodes/register`, {
275
319
  method: "POST",
276
320
  headers: { "Content-Type": "application/json" },
277
321
  body: JSON.stringify({
278
322
  siteId: this.config.siteId,
279
323
  nodeId: this.nodeId,
280
- capabilities: this.config.capabilities ?? ["ai-inference", "image-process"],
324
+ capabilities: a,
325
+ wasmMemoryBytes: e(),
281
326
  deviceMemory: typeof navigator.deviceMemory == "number" ? navigator.deviceMemory : null
282
327
  })
283
328
  });
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`);
329
+ if (!s.ok) return x(`node register failed HTTP ${s.status} (${o}/crowd/nodes/register)`), null;
330
+ let c = await s.json();
331
+ if (!c.token) return x("node register returned no token"), null;
332
+ b(`node registered nodeId=${this.nodeId} expiresIn=${Math.round((c.expiresAt - Date.now()) / 1e3)}s`);
288
333
  try {
289
- d(v, JSON.stringify(r));
334
+ g(C, JSON.stringify(c));
290
335
  } catch {}
291
- return r;
336
+ return c;
292
337
  } catch (e) {
293
- return g("node register threw", e instanceof Error ? e.message : e), null;
338
+ return x("node register threw", e instanceof Error ? e.message : e), null;
294
339
  }
295
340
  }
296
341
  send(e) {
@@ -312,7 +357,7 @@ var c = () => {
312
357
  type: "result",
313
358
  taskId: e.taskId,
314
359
  payload: r
315
- }), h(`task result sent taskId=${e.taskId} workload=${e.workload} durationMs=${Math.round(performance.now() - t)}`);
360
+ }), b(`task result sent taskId=${e.taskId} workload=${e.workload} durationMs=${Math.round(performance.now() - t)}`);
316
361
  } finally {
317
362
  this.inflightTasks.delete(e.taskId);
318
363
  }
@@ -325,23 +370,26 @@ var c = () => {
325
370
  removeVisibilityHandler() {
326
371
  this.visibilityHandler &&= (document.removeEventListener("visibilitychange", this.visibilityHandler), null);
327
372
  }
328
- }, b = "__flaxia_node_signal_client", x = "__flaxia_node_init_started", S = (e) => {
329
- let t = window[b];
373
+ }, T = "__flaxia_node_signal_client", E = "__flaxia_node_init_started", D = (e) => {
374
+ let t = window[T];
330
375
  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);
376
+ let n = new URL("./worker.js", "" + import.meta.url).href, r = new y(n), i = h(S);
377
+ i || (i = _(), g(S, i));
378
+ let a = new w(e, r, i);
379
+ window[T] = a, a.connect();
380
+ }, O = (e) => {
381
+ if (window[E]) return;
382
+ if (window[E] = !0, d()) {
383
+ D(e);
339
384
  return;
340
385
  }
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);
386
+ if (p()) return;
387
+ let t = document.createElement("div");
388
+ t.id = "flaxia-consent-container", document.body.appendChild(t), new n(t, e.consent, () => {
389
+ f(), t.remove(), D(e);
390
+ }, () => {
391
+ m(), t.remove();
344
392
  });
345
393
  };
346
394
  //#endregion
347
- export { C as initFlaxiaNode };
395
+ export { O 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.5",
4
4
  "private": false,
5
5
  "main": "dist/index.js",
6
6
  "types": "./dist/index.d.ts",