@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.
- package/dist/assets/memoryProbe.js +28 -0
- package/dist/client/SignalingClient.d.ts.map +1 -1
- package/dist/client/__tests__/SignalingClient.incapable.test.d.ts +2 -0
- package/dist/client/__tests__/SignalingClient.incapable.test.d.ts.map +1 -0
- package/dist/consent/ConsentUI.d.ts +1 -1
- package/dist/consent/ConsentUI.d.ts.map +1 -1
- package/dist/consent/storage.d.ts +2 -0
- package/dist/consent/storage.d.ts.map +1 -1
- package/dist/executor/__tests__/memoryProbe.test.d.ts +2 -0
- package/dist/executor/__tests__/memoryProbe.test.d.ts.map +1 -0
- package/dist/executor/memoryProbe.d.ts +4 -0
- package/dist/executor/memoryProbe.d.ts.map +1 -0
- package/dist/index.js +129 -81
- package/dist/worker/__tests__/main.worker.capable.test.d.ts +2 -0
- package/dist/worker/__tests__/main.worker.capable.test.d.ts.map +1 -0
- package/dist/worker/__tests__/main.worker.incapable.test.d.ts +2 -0
- package/dist/worker/__tests__/main.worker.incapable.test.d.ts.map +1 -0
- package/dist/worker.js +39 -40
- package/package.json +1 -1
|
@@ -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":"
|
|
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 @@
|
|
|
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;
|
|
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":"
|
|
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 @@
|
|
|
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
|
|
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:
|
|
8
|
-
|
|
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: ${
|
|
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
|
|
34
|
-
|
|
35
|
-
<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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
},
|
|
43
|
-
function
|
|
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
|
|
87
|
+
return s.get(e) ?? null;
|
|
48
88
|
}
|
|
49
89
|
}
|
|
50
|
-
function
|
|
90
|
+
function l(e, t) {
|
|
51
91
|
try {
|
|
52
92
|
localStorage.setItem(e, t);
|
|
53
93
|
} catch {
|
|
54
|
-
|
|
94
|
+
s.set(e, t);
|
|
55
95
|
}
|
|
56
96
|
}
|
|
57
|
-
function
|
|
97
|
+
function u(e) {
|
|
58
98
|
try {
|
|
59
99
|
localStorage.removeItem(e);
|
|
60
100
|
} catch {
|
|
61
|
-
|
|
101
|
+
s.delete(e);
|
|
62
102
|
}
|
|
63
103
|
}
|
|
64
|
-
var
|
|
65
|
-
if (
|
|
66
|
-
let e =
|
|
104
|
+
var d = () => {
|
|
105
|
+
if (c(r) !== "true") return !1;
|
|
106
|
+
let e = c(i);
|
|
67
107
|
if (e) {
|
|
68
|
-
let
|
|
69
|
-
if (!Number.isFinite(
|
|
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
|
-
},
|
|
73
|
-
|
|
74
|
-
},
|
|
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
|
-
},
|
|
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 ? (
|
|
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
|
-
|
|
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
|
-
},
|
|
119
|
-
let { id: r, type: a, result: c, error: l, token: u, cpuLoad:
|
|
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
|
|
168
|
+
typeof p == "number" && Number.isFinite(p) && (this._lastCpuLoad = Math.min(1, Math.max(0, p)));
|
|
127
169
|
return;
|
|
128
170
|
}
|
|
129
|
-
a === "done" ? (
|
|
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
|
-
},
|
|
132
|
-
|
|
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:
|
|
180
|
+
timer: h,
|
|
139
181
|
worker: c,
|
|
140
|
-
removeListener:
|
|
141
|
-
}, c.addEventListener("message",
|
|
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
|
-
|
|
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
|
-
},
|
|
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 (
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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 && (
|
|
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
|
-
|
|
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[
|
|
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 (
|
|
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 || (
|
|
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
|
|
270
|
-
if (
|
|
271
|
-
let
|
|
272
|
-
if (
|
|
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.
|
|
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:
|
|
324
|
+
capabilities: a,
|
|
325
|
+
wasmMemoryBytes: e(),
|
|
281
326
|
deviceMemory: typeof navigator.deviceMemory == "number" ? navigator.deviceMemory : null
|
|
282
327
|
})
|
|
283
328
|
});
|
|
284
|
-
if (!
|
|
285
|
-
let
|
|
286
|
-
if (!
|
|
287
|
-
|
|
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
|
-
|
|
334
|
+
g(C, JSON.stringify(c));
|
|
290
335
|
} catch {}
|
|
291
|
-
return
|
|
336
|
+
return c;
|
|
292
337
|
} catch (e) {
|
|
293
|
-
return
|
|
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
|
-
}),
|
|
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
|
-
},
|
|
329
|
-
let t = window[
|
|
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
|
|
332
|
-
i || (i =
|
|
333
|
-
let a = new
|
|
334
|
-
window[
|
|
335
|
-
},
|
|
336
|
-
if (window[
|
|
337
|
-
if (window[
|
|
338
|
-
|
|
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
|
-
|
|
342
|
-
|
|
343
|
-
|
|
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 {
|
|
395
|
+
export { O as initFlaxiaNode };
|
|
@@ -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 @@
|
|
|
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
|
|
3
|
+
function r(e) {
|
|
3
4
|
return new Promise((t) => setTimeout(t, e));
|
|
4
5
|
}
|
|
5
|
-
var
|
|
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
|
|
11
|
-
|
|
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(
|
|
21
|
-
let
|
|
22
|
-
for (; await this.shouldPause() && !(performance.now() -
|
|
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
|
-
},
|
|
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
|
-
]),
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return
|
|
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
|
|
43
|
-
function
|
|
44
|
-
for (let e of
|
|
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
|
-
|
|
48
|
+
p.clear();
|
|
48
49
|
}
|
|
49
|
-
function
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
},
|
|
50
|
+
function g() {
|
|
51
|
+
m && clearTimeout(m), m = setTimeout(() => {
|
|
52
|
+
m = null, h();
|
|
53
|
+
}, l);
|
|
53
54
|
}
|
|
54
|
-
async function
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
78
|
+
let { id: t, workload: r, payload: i, config: a } = e.data, l = performance.now();
|
|
78
79
|
try {
|
|
79
|
-
if (
|
|
80
|
-
|
|
81
|
-
|
|
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:
|
|
87
|
+
cpuLoad: s?.lastMeasuredLoad ?? 0
|
|
89
88
|
});
|
|
90
|
-
}, 1e4),
|
|
89
|
+
}, 1e4), p = performance.now();
|
|
91
90
|
try {
|
|
92
|
-
let e = await
|
|
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=${
|
|
102
|
+
}), console.log(`[flaxia-node:worker] task done id=${t} workload=${r} durationMs=${Math.round(performance.now() - l)}`);
|
|
104
103
|
} finally {
|
|
105
|
-
clearInterval(e),
|
|
104
|
+
clearInterval(e), s.markTaskComplete(performance.now() - p), g();
|
|
106
105
|
}
|
|
107
106
|
} catch (e) {
|
|
108
|
-
let
|
|
109
|
-
console.error(`[flaxia-node:worker] task error id=${t} workload=${
|
|
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:
|
|
111
|
+
error: n
|
|
113
112
|
});
|
|
114
113
|
}
|
|
115
114
|
};
|