@jxrstudios/jxr 1.2.27 → 1.2.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/package.json +1 -1
- package/zzz_react_template/const.ts +2 -2
- package/dist/deployer.js +0 -278
- package/dist/deployer.js.map +0 -1
- package/dist/enhanced-transpiler.js +0 -272
- package/dist/enhanced-transpiler.js.map +0 -1
- package/dist/entry-point-detection.js +0 -415
- package/dist/entry-point-detection.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/jxr-server-manager.js +0 -453
- package/dist/jxr-server-manager.js.map +0 -1
- package/dist/module-resolver.js +0 -430
- package/dist/module-resolver.js.map +0 -1
- package/dist/moq-transport.js +0 -188
- package/dist/moq-transport.js.map +0 -1
- package/dist/runtime.js +0 -150
- package/dist/runtime.js.map +0 -1
- package/dist/web-crypto.js +0 -186
- package/dist/web-crypto.js.map +0 -1
- package/dist/worker-pool.js +0 -238
- package/dist/worker-pool.js.map +0 -1
package/dist/runtime.js
DELETED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* JXR.js — Runtime Orchestrator
|
|
3
|
-
* ─────────────────────────────────────────────────────────────────────────────
|
|
4
|
-
* Design: LavaFlow OS — Thermal Precision + Edge Command
|
|
5
|
-
* Layer: Core Runtime / Orchestration
|
|
6
|
-
*
|
|
7
|
-
* The JXR Runtime ties together all subsystems:
|
|
8
|
-
* - WorkerPool: Parallel task execution
|
|
9
|
-
* - MoQTransport: Edge data streaming
|
|
10
|
-
* - JXRCrypto: Module integrity & encryption
|
|
11
|
-
* - VirtualFS: In-memory file system
|
|
12
|
-
* - JSXTransformer: Zero-build JSX transform
|
|
13
|
-
* - ModuleCache: LRU module cache
|
|
14
|
-
* - ImportMapBuilder: Browser import maps
|
|
15
|
-
* ─────────────────────────────────────────────────────────────────────────────
|
|
16
|
-
*/
|
|
17
|
-
import { MoQTransport } from './moq-transport.ts';
|
|
18
|
-
import { JXRCrypto } from './web-crypto.ts';
|
|
19
|
-
import { VirtualFS, JSXTransformer, ModuleCache, ImportMapBuilder, DEFAULT_PROJECT_FILES } from './module-resolver.ts';
|
|
20
|
-
/**
|
|
21
|
-
* JXRRuntime — The central edge OS runtime instance
|
|
22
|
-
*/
|
|
23
|
-
export class JXRRuntime {
|
|
24
|
-
version = '1.0.0-edge';
|
|
25
|
-
vfs;
|
|
26
|
-
transformer;
|
|
27
|
-
cache;
|
|
28
|
-
crypto;
|
|
29
|
-
moq;
|
|
30
|
-
importMap;
|
|
31
|
-
workerPool = null;
|
|
32
|
-
startTime = Date.now();
|
|
33
|
-
config;
|
|
34
|
-
metricsListeners = new Set();
|
|
35
|
-
metricsInterval = null;
|
|
36
|
-
constructor(config = {}) {
|
|
37
|
-
this.config = config;
|
|
38
|
-
this.vfs = new VirtualFS(DEFAULT_PROJECT_FILES);
|
|
39
|
-
this.transformer = new JSXTransformer();
|
|
40
|
-
this.cache = new ModuleCache(200);
|
|
41
|
-
this.crypto = new JXRCrypto();
|
|
42
|
-
this.moq = new MoQTransport();
|
|
43
|
-
this.importMap = new ImportMapBuilder().addReactDefaults('18');
|
|
44
|
-
}
|
|
45
|
-
/** Initialize the runtime — connects MoQ, warms worker pool */
|
|
46
|
-
async init() {
|
|
47
|
-
// Initialize worker pool (deferred — no worker script needed for demo)
|
|
48
|
-
// In production: this.workerPool = new WorkerPool('/jxr-worker.js');
|
|
49
|
-
// Connect MoQ transport
|
|
50
|
-
await this.moq.connect(this.config.moqEndpoint ?? 'local://jxr-edge');
|
|
51
|
-
// Start metrics broadcasting
|
|
52
|
-
this.startMetricsBroadcast();
|
|
53
|
-
}
|
|
54
|
-
/** Resolve and transform a module from the VirtualFS */
|
|
55
|
-
async resolveModule(path) {
|
|
56
|
-
const cached = this.cache.get(path);
|
|
57
|
-
if (cached)
|
|
58
|
-
return cached.transformed;
|
|
59
|
-
const file = this.vfs.read(path);
|
|
60
|
-
if (!file)
|
|
61
|
-
throw new Error(`Module not found: ${path}`);
|
|
62
|
-
const startTime = performance.now();
|
|
63
|
-
const transformed = this.transformer.transform(file.content, path);
|
|
64
|
-
const transformMs = performance.now() - startTime;
|
|
65
|
-
const objectUrl = this.transformer.createObjectUrl(transformed);
|
|
66
|
-
this.cache.set(path, {
|
|
67
|
-
path,
|
|
68
|
-
source: file.content,
|
|
69
|
-
transformed,
|
|
70
|
-
objectUrl,
|
|
71
|
-
dependencies: this.extractDependencies(file.content),
|
|
72
|
-
resolvedAt: Date.now(),
|
|
73
|
-
transformMs,
|
|
74
|
-
});
|
|
75
|
-
return transformed;
|
|
76
|
-
}
|
|
77
|
-
/** Build a preview HTML document for the current project */
|
|
78
|
-
buildPreviewDocument() {
|
|
79
|
-
const importMapScript = this.importMap.toScriptTag();
|
|
80
|
-
const entryFile = this.vfs.read('/src/index.tsx') ?? this.vfs.read('/src/App.tsx');
|
|
81
|
-
if (!entryFile)
|
|
82
|
-
return '<html><body><p>No entry file found</p></body></html>';
|
|
83
|
-
const transformed = this.transformer.transform(entryFile.content, entryFile.path);
|
|
84
|
-
const entryUrl = this.transformer.createObjectUrl(transformed);
|
|
85
|
-
return `<!DOCTYPE html>
|
|
86
|
-
<html lang="en">
|
|
87
|
-
<head>
|
|
88
|
-
<meta charset="UTF-8" />
|
|
89
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
90
|
-
<title>JXR Preview</title>
|
|
91
|
-
${importMapScript}
|
|
92
|
-
<style>
|
|
93
|
-
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
94
|
-
body { font-family: system-ui, sans-serif; }
|
|
95
|
-
</style>
|
|
96
|
-
</head>
|
|
97
|
-
<body>
|
|
98
|
-
<div id="root"></div>
|
|
99
|
-
<script type="module" src="${entryUrl}"></script>
|
|
100
|
-
</body>
|
|
101
|
-
</html>`;
|
|
102
|
-
}
|
|
103
|
-
extractDependencies(source) {
|
|
104
|
-
const deps = [];
|
|
105
|
-
const regex = /^import\s+.*?\s+from\s+['"]([^'"]+)['"]/gm;
|
|
106
|
-
let match;
|
|
107
|
-
while ((match = regex.exec(source)) !== null) {
|
|
108
|
-
deps.push(match[1]);
|
|
109
|
-
}
|
|
110
|
-
return deps;
|
|
111
|
-
}
|
|
112
|
-
startMetricsBroadcast() {
|
|
113
|
-
this.metricsInterval = setInterval(() => {
|
|
114
|
-
this.emitMetrics();
|
|
115
|
-
}, 500);
|
|
116
|
-
}
|
|
117
|
-
emitMetrics() {
|
|
118
|
-
const metrics = {
|
|
119
|
-
workerPool: this.workerPool?.getMetrics() ?? {
|
|
120
|
-
totalWorkers: navigator.hardwareConcurrency ?? 4,
|
|
121
|
-
idleWorkers: Math.floor((navigator.hardwareConcurrency ?? 4) * 0.6),
|
|
122
|
-
busyWorkers: Math.floor((navigator.hardwareConcurrency ?? 4) * 0.4),
|
|
123
|
-
queueDepth: 0,
|
|
124
|
-
throughputPerSec: Math.floor(Math.random() * 50 + 80),
|
|
125
|
-
avgLatencyMs: Math.random() * 2 + 0.5,
|
|
126
|
-
totalTasksCompleted: Math.floor(Date.now() / 1000 - this.startTime / 1000) * 12,
|
|
127
|
-
},
|
|
128
|
-
moq: this.moq.getMetrics(),
|
|
129
|
-
moduleCache: { size: this.cache.size },
|
|
130
|
-
uptime: Date.now() - this.startTime,
|
|
131
|
-
version: this.version,
|
|
132
|
-
};
|
|
133
|
-
this.metricsListeners.forEach((cb) => cb(metrics));
|
|
134
|
-
}
|
|
135
|
-
onMetrics(cb) {
|
|
136
|
-
this.metricsListeners.add(cb);
|
|
137
|
-
return () => this.metricsListeners.delete(cb);
|
|
138
|
-
}
|
|
139
|
-
dispose() {
|
|
140
|
-
if (this.metricsInterval)
|
|
141
|
-
clearInterval(this.metricsInterval);
|
|
142
|
-
this.workerPool?.terminate();
|
|
143
|
-
this.moq.disconnect();
|
|
144
|
-
this.transformer.cleanup();
|
|
145
|
-
this.cache.clear();
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
/** Global JXR Runtime singleton */
|
|
149
|
-
export const jxrRuntime = new JXRRuntime();
|
|
150
|
-
//# sourceMappingURL=runtime.js.map
|
package/dist/runtime.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
|
package/dist/web-crypto.js
DELETED
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* JXR.js — Web Crypto Engine
|
|
3
|
-
* ─────────────────────────────────────────────────────────────────────────────
|
|
4
|
-
* Design: LavaFlow OS — Thermal Precision + Edge Command
|
|
5
|
-
* Layer: Core Runtime / Security
|
|
6
|
-
*
|
|
7
|
-
* Architecture:
|
|
8
|
-
* Universal Web Crypto API wrapper providing:
|
|
9
|
-
* - Module integrity verification (SHA-256/SHA-384 hashing)
|
|
10
|
-
* - Signed module manifests (ECDSA P-256)
|
|
11
|
-
* - Encrypted module caching (AES-GCM 256)
|
|
12
|
-
* - Key derivation for per-project isolation (HKDF)
|
|
13
|
-
* - Random nonce generation for replay protection
|
|
14
|
-
*
|
|
15
|
-
* All operations use the native SubtleCrypto API — no dependencies,
|
|
16
|
-
* runs in any modern browser, Cloudflare Worker, or Deno runtime.
|
|
17
|
-
* ─────────────────────────────────────────────────────────────────────────────
|
|
18
|
-
*/
|
|
19
|
-
const subtle = globalThis.crypto.subtle;
|
|
20
|
-
/**
|
|
21
|
-
* JXRCrypto — Universal Web Crypto API abstraction
|
|
22
|
-
*/
|
|
23
|
-
export class JXRCrypto {
|
|
24
|
-
signingKeyPair = null;
|
|
25
|
-
encryptionKeys = new Map();
|
|
26
|
-
hashCache = new Map();
|
|
27
|
-
/** Generate an ECDSA P-256 signing key pair for module manifests */
|
|
28
|
-
async generateSigningKeyPair() {
|
|
29
|
-
const keyPair = await subtle.generateKey({ name: 'ECDSA', namedCurve: 'P-256' }, true, ['sign', 'verify']);
|
|
30
|
-
const spki = await subtle.exportKey('spki', keyPair.publicKey);
|
|
31
|
-
const publicKeyExported = this.toBase64Url(spki);
|
|
32
|
-
this.signingKeyPair = {
|
|
33
|
-
publicKey: keyPair.publicKey,
|
|
34
|
-
privateKey: keyPair.privateKey,
|
|
35
|
-
publicKeyExported,
|
|
36
|
-
};
|
|
37
|
-
return this.signingKeyPair;
|
|
38
|
-
}
|
|
39
|
-
/** Hash a module's source code for integrity verification */
|
|
40
|
-
async hashModule(source, algorithm = 'SHA-256') {
|
|
41
|
-
const cacheKey = `${algorithm}:${source.length}:${source.slice(0, 64)}`;
|
|
42
|
-
const cached = this.hashCache.get(cacheKey);
|
|
43
|
-
if (cached)
|
|
44
|
-
return cached;
|
|
45
|
-
const encoded = new TextEncoder().encode(source);
|
|
46
|
-
const hashBuffer = await subtle.digest(algorithm, encoded);
|
|
47
|
-
const digest = this.toHex(hashBuffer);
|
|
48
|
-
const result = {
|
|
49
|
-
algorithm,
|
|
50
|
-
digest,
|
|
51
|
-
size: encoded.byteLength,
|
|
52
|
-
timestamp: Date.now(),
|
|
53
|
-
};
|
|
54
|
-
this.hashCache.set(cacheKey, result);
|
|
55
|
-
return result;
|
|
56
|
-
}
|
|
57
|
-
/** Verify a module's integrity against a known hash */
|
|
58
|
-
async verifyModule(source, expected) {
|
|
59
|
-
const actual = await this.hashModule(source, expected.algorithm);
|
|
60
|
-
return actual.digest === expected.digest;
|
|
61
|
-
}
|
|
62
|
-
/** Sign a module manifest with ECDSA P-256 */
|
|
63
|
-
async signManifest(modules, projectId, version) {
|
|
64
|
-
if (!this.signingKeyPair) {
|
|
65
|
-
await this.generateSigningKeyPair();
|
|
66
|
-
}
|
|
67
|
-
const manifest = {
|
|
68
|
-
modules,
|
|
69
|
-
projectId,
|
|
70
|
-
version,
|
|
71
|
-
signedAt: Date.now(),
|
|
72
|
-
};
|
|
73
|
-
const data = new TextEncoder().encode(JSON.stringify(manifest));
|
|
74
|
-
const signatureBuffer = await subtle.sign({ name: 'ECDSA', hash: 'SHA-256' }, this.signingKeyPair.privateKey, data);
|
|
75
|
-
return {
|
|
76
|
-
...manifest,
|
|
77
|
-
signature: this.toBase64Url(signatureBuffer),
|
|
78
|
-
publicKey: this.signingKeyPair.publicKeyExported,
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
/** Verify a signed manifest */
|
|
82
|
-
async verifyManifest(manifest) {
|
|
83
|
-
try {
|
|
84
|
-
const spki = this.fromBase64Url(manifest.publicKey);
|
|
85
|
-
const publicKey = await subtle.importKey('spki', spki, { name: 'ECDSA', namedCurve: 'P-256' }, false, ['verify']);
|
|
86
|
-
const { signature, publicKey: _pk, ...rest } = manifest;
|
|
87
|
-
const data = new TextEncoder().encode(JSON.stringify(rest));
|
|
88
|
-
const sigBuffer = this.fromBase64Url(signature);
|
|
89
|
-
return await subtle.verify({ name: 'ECDSA', hash: 'SHA-256' }, publicKey, sigBuffer, data);
|
|
90
|
-
}
|
|
91
|
-
catch {
|
|
92
|
-
return false;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
/** Generate or retrieve an AES-GCM-256 encryption key for a project */
|
|
96
|
-
async getEncryptionKey(keyId, projectSeed) {
|
|
97
|
-
const existing = this.encryptionKeys.get(keyId);
|
|
98
|
-
if (existing)
|
|
99
|
-
return existing;
|
|
100
|
-
let key;
|
|
101
|
-
if (projectSeed) {
|
|
102
|
-
// Derive key from project seed using HKDF
|
|
103
|
-
const seedBytes = new TextEncoder().encode(projectSeed);
|
|
104
|
-
const baseKey = await subtle.importKey('raw', seedBytes, 'HKDF', false, ['deriveKey']);
|
|
105
|
-
const salt = new TextEncoder().encode(`jxr-project-${keyId}`);
|
|
106
|
-
const info = new TextEncoder().encode('JXR.js Module Cache v1');
|
|
107
|
-
key = await subtle.deriveKey({ name: 'HKDF', hash: 'SHA-256', salt, info }, baseKey, { name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt']);
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
key = await subtle.generateKey({ name: 'AES-GCM', length: 256 }, false, [
|
|
111
|
-
'encrypt',
|
|
112
|
-
'decrypt',
|
|
113
|
-
]);
|
|
114
|
-
}
|
|
115
|
-
this.encryptionKeys.set(keyId, key);
|
|
116
|
-
return key;
|
|
117
|
-
}
|
|
118
|
-
/** Encrypt a module for secure caching */
|
|
119
|
-
async encryptModule(source, keyId) {
|
|
120
|
-
const key = await this.getEncryptionKey(keyId);
|
|
121
|
-
const iv = globalThis.crypto.getRandomValues(new Uint8Array(12));
|
|
122
|
-
const encoded = new TextEncoder().encode(source);
|
|
123
|
-
const cipherBuffer = await subtle.encrypt({ name: 'AES-GCM', iv }, key, encoded);
|
|
124
|
-
// AES-GCM appends 16-byte auth tag to ciphertext
|
|
125
|
-
const ciphertext = cipherBuffer.slice(0, cipherBuffer.byteLength - 16);
|
|
126
|
-
const tag = cipherBuffer.slice(cipherBuffer.byteLength - 16);
|
|
127
|
-
return {
|
|
128
|
-
ciphertext: this.toBase64Url(ciphertext),
|
|
129
|
-
iv: this.toBase64Url(iv.buffer),
|
|
130
|
-
tag: this.toBase64Url(tag),
|
|
131
|
-
keyId,
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
/** Decrypt a cached module */
|
|
135
|
-
async decryptModule(encrypted) {
|
|
136
|
-
const key = await this.getEncryptionKey(encrypted.keyId);
|
|
137
|
-
const iv = this.fromBase64Url(encrypted.iv);
|
|
138
|
-
const ciphertext = this.fromBase64Url(encrypted.ciphertext);
|
|
139
|
-
const tag = this.fromBase64Url(encrypted.tag);
|
|
140
|
-
// Reassemble ciphertext + tag for AES-GCM
|
|
141
|
-
const combined = new Uint8Array(ciphertext.byteLength + tag.byteLength);
|
|
142
|
-
combined.set(new Uint8Array(ciphertext));
|
|
143
|
-
combined.set(new Uint8Array(tag), ciphertext.byteLength);
|
|
144
|
-
const plainBuffer = await subtle.decrypt({ name: 'AES-GCM', iv }, key, combined);
|
|
145
|
-
return new TextDecoder().decode(plainBuffer);
|
|
146
|
-
}
|
|
147
|
-
/** Generate a cryptographically secure random nonce */
|
|
148
|
-
generateNonce(bytes = 16) {
|
|
149
|
-
const nonce = globalThis.crypto.getRandomValues(new Uint8Array(bytes));
|
|
150
|
-
return this.toBase64Url(nonce.buffer);
|
|
151
|
-
}
|
|
152
|
-
/** Generate a project-unique ID using Web Crypto */
|
|
153
|
-
async generateProjectId(name, timestamp) {
|
|
154
|
-
const data = new TextEncoder().encode(`${name}:${timestamp}`);
|
|
155
|
-
const hash = await subtle.digest('SHA-256', data);
|
|
156
|
-
return this.toHex(hash).slice(0, 16);
|
|
157
|
-
}
|
|
158
|
-
// ─── Encoding utilities ───────────────────────────────────────────────────
|
|
159
|
-
toHex(buffer) {
|
|
160
|
-
return Array.from(new Uint8Array(buffer))
|
|
161
|
-
.map((b) => b.toString(16).padStart(2, '0'))
|
|
162
|
-
.join('');
|
|
163
|
-
}
|
|
164
|
-
toBase64Url(buffer) {
|
|
165
|
-
const bytes = new Uint8Array(buffer);
|
|
166
|
-
let binary = '';
|
|
167
|
-
for (let i = 0; i < bytes.byteLength; i++) {
|
|
168
|
-
binary += String.fromCharCode(bytes[i]);
|
|
169
|
-
}
|
|
170
|
-
return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
|
|
171
|
-
}
|
|
172
|
-
fromBase64Url(str) {
|
|
173
|
-
const padded = str.replace(/-/g, '+').replace(/_/g, '/');
|
|
174
|
-
const padLength = (4 - (padded.length % 4)) % 4;
|
|
175
|
-
const base64 = padded + '='.repeat(padLength);
|
|
176
|
-
const binary = atob(base64);
|
|
177
|
-
const bytes = new Uint8Array(binary.length);
|
|
178
|
-
for (let i = 0; i < binary.length; i++) {
|
|
179
|
-
bytes[i] = binary.charCodeAt(i);
|
|
180
|
-
}
|
|
181
|
-
return bytes.buffer;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
/** Singleton instance */
|
|
185
|
-
export const jxrCrypto = new JXRCrypto();
|
|
186
|
-
//# sourceMappingURL=web-crypto.js.map
|
package/dist/web-crypto.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"web-crypto.js","sourceRoot":"","sources":["../src/web-crypto.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC;AA+BxC;;GAEG;AACH,MAAM,OAAO,SAAS;IACZ,cAAc,GAAyB,IAAI,CAAC;IAC5C,cAAc,GAA2B,IAAI,GAAG,EAAE,CAAC;IACnD,SAAS,GAA4B,IAAI,GAAG,EAAE,CAAC;IAEvD,oEAAoE;IACpE,KAAK,CAAC,sBAAsB;QAC1B,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,WAAW,CACtC,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,EACtC,IAAI,EACJ,CAAC,MAAM,EAAE,QAAQ,CAAC,CACnB,CAAC;QAEF,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QAC/D,MAAM,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAEjD,IAAI,CAAC,cAAc,GAAG;YACpB,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,iBAAiB;SAClB,CAAC;QAEF,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED,6DAA6D;IAC7D,KAAK,CAAC,UAAU,CACd,MAAc,EACd,YAA+C,SAAS;QAExD,MAAM,QAAQ,GAAG,GAAG,SAAS,IAAI,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QACxE,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC5C,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;QAE1B,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACjD,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC3D,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAEtC,MAAM,MAAM,GAAe;YACzB,SAAS;YACT,MAAM;YACN,IAAI,EAAE,OAAO,CAAC,UAAU;YACxB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC;QAEF,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACrC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,uDAAuD;IACvD,KAAK,CAAC,YAAY,CAAC,MAAc,EAAE,QAAoB;QACrD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;QACjE,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,CAAC;IAC3C,CAAC;IAED,8CAA8C;IAC9C,KAAK,CAAC,YAAY,CAChB,OAAmC,EACnC,SAAiB,EACjB,OAAe;QAEf,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACzB,MAAM,IAAI,CAAC,sBAAsB,EAAE,CAAC;QACtC,CAAC;QAED,MAAM,QAAQ,GAAG;YACf,OAAO;YACP,SAAS;YACT,OAAO;YACP,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE;SACrB,CAAC;QAEF,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;QAChE,MAAM,eAAe,GAAG,MAAM,MAAM,CAAC,IAAI,CACvC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAClC,IAAI,CAAC,cAAe,CAAC,UAAU,EAC/B,IAAI,CACL,CAAC;QAEF,OAAO;YACL,GAAG,QAAQ;YACX,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC;YAC5C,SAAS,EAAE,IAAI,CAAC,cAAe,CAAC,iBAAiB;SAClD,CAAC;IACJ,CAAC;IAED,+BAA+B;IAC/B,KAAK,CAAC,cAAc,CAAC,QAAwB;QAC3C,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YACpD,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,SAAS,CACtC,MAAM,EACN,IAAI,EACJ,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,EACtC,KAAK,EACL,CAAC,QAAQ,CAAC,CACX,CAAC;YAEF,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,QAAQ,CAAC;YACxD,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;YAC5D,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;YAEhD,OAAO,MAAM,MAAM,CAAC,MAAM,CACxB,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAClC,SAAS,EACT,SAAS,EACT,IAAI,CACL,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,uEAAuE;IACvE,KAAK,CAAC,gBAAgB,CAAC,KAAa,EAAE,WAAoB;QACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAChD,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAC;QAE9B,IAAI,GAAc,CAAC;QAEnB,IAAI,WAAW,EAAE,CAAC;YAChB,0CAA0C;YAC1C,MAAM,SAAS,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YACxD,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;YACvF,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,eAAe,KAAK,EAAE,CAAC,CAAC;YAC9D,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC;YAEhE,GAAG,GAAG,MAAM,MAAM,CAAC,SAAS,CAC1B,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,EAC7C,OAAO,EACP,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,EAChC,KAAK,EACL,CAAC,SAAS,EAAE,SAAS,CAAC,CACvB,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,GAAG,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE;gBACtE,SAAS;gBACT,SAAS;aACV,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACpC,OAAO,GAAG,CAAC;IACb,CAAC;IAED,0CAA0C;IAC1C,KAAK,CAAC,aAAa,CAAC,MAAc,EAAE,KAAa;QAC/C,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;QAC/C,MAAM,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;QACjE,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAEjD,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;QAEjF,iDAAiD;QACjD,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC;QACvE,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC;QAE7D,OAAO;YACL,UAAU,EAAE,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC;YACxC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,MAAM,CAAC;YAC/B,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC;YAC1B,KAAK;SACN,CAAC;IACJ,CAAC;IAED,8BAA8B;IAC9B,KAAK,CAAC,aAAa,CAAC,SAA0B;QAC5C,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACzD,MAAM,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAC5C,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAC5D,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAE9C,0CAA0C;QAC1C,MAAM,QAAQ,GAAG,IAAI,UAAU,CAAC,UAAU,CAAC,UAAU,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC;QACxE,QAAQ,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;QACzC,QAAQ,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;QAEzD,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;QACjF,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC/C,CAAC;IAED,uDAAuD;IACvD,aAAa,CAAC,KAAK,GAAG,EAAE;QACtB,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;QACvE,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACxC,CAAC;IAED,oDAAoD;IACpD,KAAK,CAAC,iBAAiB,CAAC,IAAY,EAAE,SAAiB;QACrD,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,IAAI,IAAI,SAAS,EAAE,CAAC,CAAC;QAC9D,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,6EAA6E;IAErE,KAAK,CAAC,MAAmB;QAC/B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;aACtC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;aAC3C,IAAI,CAAC,EAAE,CAAC,CAAC;IACd,CAAC;IAEO,WAAW,CAAC,MAAmB;QACrC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;YAC1C,MAAM,IAAI,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1C,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAChF,CAAC;IAEO,aAAa,CAAC,GAAW;QAC/B,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACzD,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5B,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAClC,CAAC;QACD,OAAO,KAAK,CAAC,MAAM,CAAC;IACtB,CAAC;CACF;AAED,yBAAyB;AACzB,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,SAAS,EAAE,CAAC"}
|
package/dist/worker-pool.js
DELETED
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* JXR.js — Worker Pool Engine
|
|
3
|
-
* ─────────────────────────────────────────────────────────────────────────────
|
|
4
|
-
* Design: LavaFlow OS — Thermal Precision + Edge Command
|
|
5
|
-
* Layer: Core Runtime / Worker Orchestration
|
|
6
|
-
*
|
|
7
|
-
* Architecture:
|
|
8
|
-
* WorkerPool manages a fleet of Web Workers for parallel task execution.
|
|
9
|
-
* Tasks are dispatched via a priority queue and results streamed back
|
|
10
|
-
* through a structured message protocol. Each worker is isolated with
|
|
11
|
-
* its own module scope, enabling true parallelism without shared state.
|
|
12
|
-
*
|
|
13
|
-
* Performance targets:
|
|
14
|
-
* - Task dispatch latency: <1ms
|
|
15
|
-
* - Worker spawn time: <5ms (pre-warmed pool)
|
|
16
|
-
* - Throughput: saturate all available CPU cores
|
|
17
|
-
* ─────────────────────────────────────────────────────────────────────────────
|
|
18
|
-
*/
|
|
19
|
-
const PRIORITY_WEIGHTS = {
|
|
20
|
-
critical: 4,
|
|
21
|
-
high: 3,
|
|
22
|
-
normal: 2,
|
|
23
|
-
low: 1,
|
|
24
|
-
};
|
|
25
|
-
/**
|
|
26
|
-
* WorkerPool — Pre-warmed, priority-aware Web Worker fleet
|
|
27
|
-
*/
|
|
28
|
-
export class WorkerPool {
|
|
29
|
-
workers = new Map();
|
|
30
|
-
taskQueue = [];
|
|
31
|
-
pendingTasks = new Map();
|
|
32
|
-
metricsHistory = [];
|
|
33
|
-
throughputWindow = [];
|
|
34
|
-
maxWorkers;
|
|
35
|
-
workerScript;
|
|
36
|
-
taskCounter = 0;
|
|
37
|
-
listeners = new Map();
|
|
38
|
-
constructor(workerScript, maxWorkers) {
|
|
39
|
-
this.workerScript = workerScript;
|
|
40
|
-
this.maxWorkers = maxWorkers ?? Math.max(2, (navigator.hardwareConcurrency ?? 4) - 1);
|
|
41
|
-
this.prewarm();
|
|
42
|
-
}
|
|
43
|
-
/** Pre-warm the pool to eliminate cold-start latency */
|
|
44
|
-
prewarm() {
|
|
45
|
-
const initialCount = Math.min(2, this.maxWorkers);
|
|
46
|
-
for (let i = 0; i < initialCount; i++) {
|
|
47
|
-
this.spawnWorker();
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
spawnWorker() {
|
|
51
|
-
const workerId = `worker-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
52
|
-
const worker = new Worker(this.workerScript, { type: 'module' });
|
|
53
|
-
const entry = {
|
|
54
|
-
worker,
|
|
55
|
-
status: 'idle',
|
|
56
|
-
currentTaskId: null,
|
|
57
|
-
latencyHistory: [],
|
|
58
|
-
metrics: {
|
|
59
|
-
workerId,
|
|
60
|
-
status: 'idle',
|
|
61
|
-
tasksCompleted: 0,
|
|
62
|
-
tasksFailed: 0,
|
|
63
|
-
avgLatencyMs: 0,
|
|
64
|
-
lastActiveAt: Date.now(),
|
|
65
|
-
cpuLoad: 0,
|
|
66
|
-
},
|
|
67
|
-
};
|
|
68
|
-
worker.onmessage = (event) => this.handleWorkerMessage(workerId, event);
|
|
69
|
-
worker.onerror = (error) => this.handleWorkerError(workerId, error);
|
|
70
|
-
this.workers.set(workerId, entry);
|
|
71
|
-
return workerId;
|
|
72
|
-
}
|
|
73
|
-
handleWorkerMessage(workerId, event) {
|
|
74
|
-
const { taskId, result, error, type } = event.data;
|
|
75
|
-
const entry = this.workers.get(workerId);
|
|
76
|
-
if (!entry)
|
|
77
|
-
return;
|
|
78
|
-
if (type === 'metrics') {
|
|
79
|
-
entry.metrics.cpuLoad = event.data.cpuLoad ?? 0;
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
const task = this.pendingTasks.get(taskId);
|
|
83
|
-
if (!task)
|
|
84
|
-
return;
|
|
85
|
-
const latency = Date.now() - task.timestamp;
|
|
86
|
-
entry.latencyHistory.push(latency);
|
|
87
|
-
if (entry.latencyHistory.length > 50)
|
|
88
|
-
entry.latencyHistory.shift();
|
|
89
|
-
entry.metrics.avgLatencyMs =
|
|
90
|
-
entry.latencyHistory.reduce((a, b) => a + b, 0) / entry.latencyHistory.length;
|
|
91
|
-
entry.metrics.lastActiveAt = Date.now();
|
|
92
|
-
if (error) {
|
|
93
|
-
entry.metrics.tasksFailed++;
|
|
94
|
-
task.reject(new Error(error));
|
|
95
|
-
}
|
|
96
|
-
else {
|
|
97
|
-
entry.metrics.tasksCompleted++;
|
|
98
|
-
this.throughputWindow.push(Date.now());
|
|
99
|
-
task.resolve(result);
|
|
100
|
-
}
|
|
101
|
-
this.pendingTasks.delete(taskId);
|
|
102
|
-
entry.status = 'idle';
|
|
103
|
-
entry.metrics.status = 'idle';
|
|
104
|
-
entry.currentTaskId = null;
|
|
105
|
-
this.emitMetrics();
|
|
106
|
-
this.drainQueue();
|
|
107
|
-
}
|
|
108
|
-
handleWorkerError(workerId, error) {
|
|
109
|
-
const entry = this.workers.get(workerId);
|
|
110
|
-
if (!entry)
|
|
111
|
-
return;
|
|
112
|
-
entry.status = 'error';
|
|
113
|
-
entry.metrics.status = 'error';
|
|
114
|
-
if (entry.currentTaskId) {
|
|
115
|
-
const task = this.pendingTasks.get(entry.currentTaskId);
|
|
116
|
-
if (task) {
|
|
117
|
-
task.reject(new Error(error.message));
|
|
118
|
-
this.pendingTasks.delete(entry.currentTaskId);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
// Respawn worker
|
|
122
|
-
entry.worker.terminate();
|
|
123
|
-
this.workers.delete(workerId);
|
|
124
|
-
this.spawnWorker();
|
|
125
|
-
this.drainQueue();
|
|
126
|
-
}
|
|
127
|
-
getIdleWorker() {
|
|
128
|
-
for (const [, entry] of Array.from(this.workers.entries())) {
|
|
129
|
-
if (entry.status === 'idle')
|
|
130
|
-
return entry;
|
|
131
|
-
}
|
|
132
|
-
return null;
|
|
133
|
-
}
|
|
134
|
-
drainQueue() {
|
|
135
|
-
if (this.taskQueue.length === 0)
|
|
136
|
-
return;
|
|
137
|
-
// Sort by priority weight descending
|
|
138
|
-
this.taskQueue.sort((a, b) => PRIORITY_WEIGHTS[b.priority] - PRIORITY_WEIGHTS[a.priority]);
|
|
139
|
-
let idleWorker = this.getIdleWorker();
|
|
140
|
-
// Scale up if needed and under cap
|
|
141
|
-
if (!idleWorker && this.workers.size < this.maxWorkers) {
|
|
142
|
-
const newId = this.spawnWorker();
|
|
143
|
-
idleWorker = this.workers.get(newId) ?? null;
|
|
144
|
-
}
|
|
145
|
-
if (!idleWorker)
|
|
146
|
-
return;
|
|
147
|
-
const task = this.taskQueue.shift();
|
|
148
|
-
this.dispatchToWorker(idleWorker, task);
|
|
149
|
-
}
|
|
150
|
-
dispatchToWorker(entry, task) {
|
|
151
|
-
entry.status = 'busy';
|
|
152
|
-
entry.metrics.status = 'busy';
|
|
153
|
-
entry.currentTaskId = task.id;
|
|
154
|
-
this.pendingTasks.set(task.id, task);
|
|
155
|
-
entry.worker.postMessage({
|
|
156
|
-
taskId: task.id,
|
|
157
|
-
type: task.type,
|
|
158
|
-
payload: task.payload,
|
|
159
|
-
});
|
|
160
|
-
if (task.timeoutMs) {
|
|
161
|
-
setTimeout(() => {
|
|
162
|
-
if (this.pendingTasks.has(task.id)) {
|
|
163
|
-
task.reject(new Error(`Task ${task.id} timed out after ${task.timeoutMs}ms`));
|
|
164
|
-
this.pendingTasks.delete(task.id);
|
|
165
|
-
}
|
|
166
|
-
}, task.timeoutMs);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
/** Submit a task to the pool, returns a Promise */
|
|
170
|
-
submit(type, payload, options = {}) {
|
|
171
|
-
return new Promise((resolve, reject) => {
|
|
172
|
-
const task = {
|
|
173
|
-
id: `task-${++this.taskCounter}-${Date.now()}`,
|
|
174
|
-
type,
|
|
175
|
-
payload,
|
|
176
|
-
priority: options.priority ?? 'normal',
|
|
177
|
-
timestamp: Date.now(),
|
|
178
|
-
timeoutMs: options.timeoutMs,
|
|
179
|
-
resolve,
|
|
180
|
-
reject,
|
|
181
|
-
};
|
|
182
|
-
const idleWorker = this.getIdleWorker();
|
|
183
|
-
if (idleWorker) {
|
|
184
|
-
this.dispatchToWorker(idleWorker, task);
|
|
185
|
-
}
|
|
186
|
-
else {
|
|
187
|
-
this.taskQueue.push(task);
|
|
188
|
-
// Scale up if under cap
|
|
189
|
-
if (this.workers.size < this.maxWorkers) {
|
|
190
|
-
this.spawnWorker();
|
|
191
|
-
this.drainQueue();
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
/** Get current pool metrics */
|
|
197
|
-
getMetrics() {
|
|
198
|
-
const now = Date.now();
|
|
199
|
-
// Clean throughput window to last 1 second
|
|
200
|
-
this.throughputWindow = this.throughputWindow.filter((t) => now - t < 1000);
|
|
201
|
-
const allLatencies = Array.from(this.workers.values()).flatMap((e) => e.latencyHistory);
|
|
202
|
-
const avgLatency = allLatencies.length > 0
|
|
203
|
-
? allLatencies.reduce((a, b) => a + b, 0) / allLatencies.length
|
|
204
|
-
: 0;
|
|
205
|
-
const totalCompleted = Array.from(this.workers.values()).reduce((sum, e) => sum + e.metrics.tasksCompleted, 0);
|
|
206
|
-
return {
|
|
207
|
-
totalWorkers: this.workers.size,
|
|
208
|
-
idleWorkers: Array.from(this.workers.values()).filter((e) => e.status === 'idle').length,
|
|
209
|
-
busyWorkers: Array.from(this.workers.values()).filter((e) => e.status === 'busy').length,
|
|
210
|
-
queueDepth: this.taskQueue.length,
|
|
211
|
-
throughputPerSec: this.throughputWindow.length,
|
|
212
|
-
avgLatencyMs: Math.round(avgLatency * 10) / 10,
|
|
213
|
-
totalTasksCompleted: totalCompleted,
|
|
214
|
-
};
|
|
215
|
-
}
|
|
216
|
-
getWorkerMetrics() {
|
|
217
|
-
return Array.from(this.workers.values()).map((e) => ({ ...e.metrics }));
|
|
218
|
-
}
|
|
219
|
-
onMetrics(event, cb) {
|
|
220
|
-
if (!this.listeners.has(event))
|
|
221
|
-
this.listeners.set(event, new Set());
|
|
222
|
-
this.listeners.get(event).add(cb);
|
|
223
|
-
return () => this.listeners.get(event)?.delete(cb);
|
|
224
|
-
}
|
|
225
|
-
emitMetrics() {
|
|
226
|
-
const metrics = this.getMetrics();
|
|
227
|
-
this.listeners.get('metrics')?.forEach((cb) => cb(metrics));
|
|
228
|
-
}
|
|
229
|
-
terminate() {
|
|
230
|
-
for (const [, entry] of Array.from(this.workers.entries())) {
|
|
231
|
-
entry.worker.terminate();
|
|
232
|
-
}
|
|
233
|
-
this.workers.clear();
|
|
234
|
-
this.taskQueue.length = 0;
|
|
235
|
-
this.pendingTasks.clear();
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
//# sourceMappingURL=worker-pool.js.map
|
package/dist/worker-pool.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"worker-pool.js","sourceRoot":"","sources":["../src/worker-pool.ts"],"names":[],"mappings":"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"}
|