@sparkleideas/ruv-swarm 1.0.18-patch.1
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 +1565 -0
- package/bin/ruv-swarm-clean.js +1872 -0
- package/bin/ruv-swarm-memory.js +119 -0
- package/bin/ruv-swarm-secure-heartbeat.js +1549 -0
- package/bin/ruv-swarm-secure.js +1689 -0
- package/package.json +221 -0
- package/src/agent.ts +342 -0
- package/src/benchmark.js +267 -0
- package/src/claude-flow-enhanced.js +839 -0
- package/src/claude-integration/advanced-commands.js +561 -0
- package/src/claude-integration/core.js +112 -0
- package/src/claude-integration/docs.js +1548 -0
- package/src/claude-integration/env-template.js +39 -0
- package/src/claude-integration/index.js +209 -0
- package/src/claude-integration/remote.js +408 -0
- package/src/cli-diagnostics.js +364 -0
- package/src/cognitive-pattern-evolution.js +1317 -0
- package/src/daa-cognition.js +977 -0
- package/src/daa-service.d.ts +298 -0
- package/src/daa-service.js +1116 -0
- package/src/diagnostics.js +533 -0
- package/src/errors.js +528 -0
- package/src/github-coordinator/README.md +193 -0
- package/src/github-coordinator/claude-hooks.js +162 -0
- package/src/github-coordinator/gh-cli-coordinator.js +260 -0
- package/src/hooks/cli.js +82 -0
- package/src/hooks/index.js +1900 -0
- package/src/index-enhanced.d.ts +371 -0
- package/src/index-enhanced.js +734 -0
- package/src/index.d.ts +287 -0
- package/src/index.js +405 -0
- package/src/index.ts +457 -0
- package/src/logger.js +182 -0
- package/src/logging-config.js +179 -0
- package/src/mcp-daa-tools.js +735 -0
- package/src/mcp-tools-benchmarks.js +328 -0
- package/src/mcp-tools-enhanced.js +2863 -0
- package/src/memory-config.js +42 -0
- package/src/meta-learning-framework.js +1359 -0
- package/src/neural-agent.js +830 -0
- package/src/neural-coordination-protocol.js +1363 -0
- package/src/neural-models/README.md +118 -0
- package/src/neural-models/autoencoder.js +543 -0
- package/src/neural-models/base.js +269 -0
- package/src/neural-models/cnn.js +497 -0
- package/src/neural-models/gnn.js +447 -0
- package/src/neural-models/gru.js +536 -0
- package/src/neural-models/index.js +273 -0
- package/src/neural-models/lstm.js +551 -0
- package/src/neural-models/neural-presets-complete.js +1306 -0
- package/src/neural-models/presets/graph.js +392 -0
- package/src/neural-models/presets/index.js +279 -0
- package/src/neural-models/presets/nlp.js +328 -0
- package/src/neural-models/presets/timeseries.js +368 -0
- package/src/neural-models/presets/vision.js +387 -0
- package/src/neural-models/resnet.js +534 -0
- package/src/neural-models/transformer.js +515 -0
- package/src/neural-models/vae.js +489 -0
- package/src/neural-network-manager.js +1938 -0
- package/src/neural-network.ts +296 -0
- package/src/neural.js +574 -0
- package/src/performance-benchmarks.js +898 -0
- package/src/performance.js +458 -0
- package/src/persistence-pooled.js +695 -0
- package/src/persistence.js +480 -0
- package/src/schemas.js +864 -0
- package/src/security.js +218 -0
- package/src/singleton-container.js +183 -0
- package/src/sqlite-pool.js +587 -0
- package/src/sqlite-worker.js +141 -0
- package/src/types.ts +164 -0
- package/src/utils.ts +286 -0
- package/src/wasm-loader.js +601 -0
- package/src/wasm-loader2.js +404 -0
- package/src/wasm-memory-optimizer.js +783 -0
- package/src/wasm-types.d.ts +63 -0
- package/wasm/README.md +347 -0
- package/wasm/neuro-divergent.wasm +0 -0
- package/wasm/package.json +18 -0
- package/wasm/ruv-fann.wasm +0 -0
- package/wasm/ruv_swarm_simd.wasm +0 -0
- package/wasm/ruv_swarm_wasm.d.ts +391 -0
- package/wasm/ruv_swarm_wasm.js +2164 -0
- package/wasm/ruv_swarm_wasm_bg.wasm +0 -0
- package/wasm/ruv_swarm_wasm_bg.wasm.d.ts +123 -0
- package/wasm/wasm-bindings-loader.mjs +435 -0
- package/wasm/wasm-updates.md +684 -0
|
@@ -0,0 +1,601 @@
|
|
|
1
|
+
/* wasm-module-loader.js
|
|
2
|
+
* Universal (ESMย +ย CJS) progressive WASM loader.
|
|
3
|
+
* Author: Bron refactor 2025โ07โ01
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import { promises as fs } from 'node:fs';
|
|
8
|
+
import { existsSync, accessSync } from 'node:fs';
|
|
9
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
10
|
+
import { webcrypto as nodeCrypto } from 'node:crypto';
|
|
11
|
+
|
|
12
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
13
|
+
// helpers โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
14
|
+
const crypto = globalThis.crypto ?? nodeCrypto; // browser | Node
|
|
15
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
16
|
+
const __dirname = path.dirname(__filename);
|
|
17
|
+
|
|
18
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
19
|
+
class WasmModuleLoader {
|
|
20
|
+
constructor() {
|
|
21
|
+
this.modules = new Map();
|
|
22
|
+
this.loadingPromises = new Map();
|
|
23
|
+
this.loadingStrategy = 'on-demand'; // eager | on-demand | progressive
|
|
24
|
+
this.baseDir = __dirname; // one-liner dirname
|
|
25
|
+
this.wasmCache = new Map(); // Cache compiled WASM modules
|
|
26
|
+
this.cacheTimeout = 3600000; // 1 hour cache timeout
|
|
27
|
+
this.moduleManifest = {
|
|
28
|
+
/* The only compiled artefact today. Others are historical โ optional */
|
|
29
|
+
core: {
|
|
30
|
+
path: '../wasm/ruv_swarm_wasm_bg.wasm',
|
|
31
|
+
jsBindings: '../wasm/ruv_swarm_wasm.js',
|
|
32
|
+
size: 512 * 1024,
|
|
33
|
+
priority: 'high',
|
|
34
|
+
dependencies: [],
|
|
35
|
+
exists: true,
|
|
36
|
+
type: 'wasm-bindgen',
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
/* legacy / optional stubs */
|
|
40
|
+
neural: { path: '../wasm/ruv-fann.wasm', size: 1024 * 1024, priority: 'medium', dependencies: ['core'], exists: false, optional: true },
|
|
41
|
+
forecasting: { path: '../wasm/neuro-divergent.wasm', size: 1536 * 1024, priority: 'medium', dependencies: ['core'], exists: false, optional: true },
|
|
42
|
+
swarm: { path: '../wasm/ruv-swarm-orchestration.wasm', size: 768 * 1024, priority: 'high', dependencies: ['core'], exists: false, optional: true },
|
|
43
|
+
persistence: { path: '../wasm/ruv-swarm-persistence.wasm', size: 256 * 1024, priority: 'high', dependencies: ['core'], exists: false, optional: true },
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/* โโ public API โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ */
|
|
48
|
+
async initialize(strategy = 'progressive') {
|
|
49
|
+
this.loadingStrategy = strategy;
|
|
50
|
+
if (strategy === 'eager') {
|
|
51
|
+
return this.#loadAllModules();
|
|
52
|
+
}
|
|
53
|
+
if (strategy === 'progressive') {
|
|
54
|
+
return this.#loadCoreOnly();
|
|
55
|
+
}
|
|
56
|
+
if (strategy === 'on-demand') {
|
|
57
|
+
return this.#setupLazyProxies();
|
|
58
|
+
}
|
|
59
|
+
throw new Error(`Unknown loading strategy: ${strategy}`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async loadModule(name) {
|
|
63
|
+
if (this.modules.has(name)) {
|
|
64
|
+
return this.modules.get(name);
|
|
65
|
+
}
|
|
66
|
+
if (this.loadingPromises.has(name)) {
|
|
67
|
+
return this.loadingPromises.get(name);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const info = this.moduleManifest[name];
|
|
71
|
+
if (!info) {
|
|
72
|
+
throw new Error(`Unknown module: ${name}`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/* optional module not built โ silently alias to core when possible */
|
|
76
|
+
if (!info.exists && info.optional) {
|
|
77
|
+
await this.loadModule('core');
|
|
78
|
+
const coreMod = this.modules.get('core');
|
|
79
|
+
this.modules.set(name, coreMod);
|
|
80
|
+
return coreMod;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/* ensure deps first */
|
|
84
|
+
await Promise.all(info.dependencies.map(dep => this.loadModule(dep)));
|
|
85
|
+
|
|
86
|
+
const p = (name === 'core')
|
|
87
|
+
? this.#loadCoreBindings()
|
|
88
|
+
: this.#instantiateRaw(name, info);
|
|
89
|
+
|
|
90
|
+
this.loadingPromises.set(name, p);
|
|
91
|
+
try {
|
|
92
|
+
const m = await p;
|
|
93
|
+
this.modules.set(name, m);
|
|
94
|
+
console.log(`โ
Loaded WASM module: ${name} (${this.#fmt(info.size)})`);
|
|
95
|
+
return m;
|
|
96
|
+
} finally {
|
|
97
|
+
this.loadingPromises.delete(name);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
getModuleStatus() {
|
|
102
|
+
const s = {};
|
|
103
|
+
for (const [n, i] of Object.entries(this.moduleManifest)) {
|
|
104
|
+
s[n] = {
|
|
105
|
+
loaded: this.modules.has(n),
|
|
106
|
+
loading: this.loadingPromises.has(n),
|
|
107
|
+
placeholder: this.modules.get(n)?.isPlaceholder ?? false,
|
|
108
|
+
size: i.size,
|
|
109
|
+
priority: i.priority,
|
|
110
|
+
deps: i.dependencies,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
return s;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/* โโ internal โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ */
|
|
117
|
+
async #instantiateRaw(name, info) {
|
|
118
|
+
const wasmPath = path.join(this.baseDir, info.path);
|
|
119
|
+
const cacheKey = `${name}-${info.path}`;
|
|
120
|
+
|
|
121
|
+
// Check cache first
|
|
122
|
+
const cached = this.wasmCache.get(cacheKey);
|
|
123
|
+
if (cached && (Date.now() - cached.timestamp < this.cacheTimeout)) {
|
|
124
|
+
console.log(`โจ Using cached WASM module: ${name}`);
|
|
125
|
+
return cached.module;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
let buffer;
|
|
129
|
+
if (typeof window !== 'undefined') { // browser
|
|
130
|
+
const resp = await fetch(wasmPath);
|
|
131
|
+
if (!resp.ok) {
|
|
132
|
+
throw new Error(`fetch failed: ${resp.statusText}`);
|
|
133
|
+
}
|
|
134
|
+
buffer = await resp.arrayBuffer();
|
|
135
|
+
} else { // Node
|
|
136
|
+
buffer = await fs.readFile(wasmPath).catch(() => null);
|
|
137
|
+
if (!buffer) {
|
|
138
|
+
return this.#placeholder(name);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const imports = this.#importsFor(name);
|
|
143
|
+
const { instance, module } = await WebAssembly.instantiate(buffer, imports);
|
|
144
|
+
const result = { instance, module, exports: instance.exports, memory: instance.exports.memory };
|
|
145
|
+
|
|
146
|
+
// Cache the compiled module
|
|
147
|
+
this.wasmCache.set(cacheKey, {
|
|
148
|
+
module: result,
|
|
149
|
+
timestamp: Date.now(),
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
return result;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
async #loadCoreBindings() {
|
|
156
|
+
/* Enhanced WASM loader with context-aware path resolution */
|
|
157
|
+
try {
|
|
158
|
+
// Try multiple path resolution strategies
|
|
159
|
+
const pathCandidates = this.#getWasmPathCandidates();
|
|
160
|
+
|
|
161
|
+
for (const pathCandidate of pathCandidates) {
|
|
162
|
+
try {
|
|
163
|
+
const result = await this.#tryLoadFromPath(pathCandidate);
|
|
164
|
+
if (result && !result.isPlaceholder) {
|
|
165
|
+
console.log(`โ
Successfully loaded WASM from: ${pathCandidate.description}`);
|
|
166
|
+
return result;
|
|
167
|
+
}
|
|
168
|
+
} catch (pathError) {
|
|
169
|
+
console.debug(`โ Failed to load from ${pathCandidate.description}:`, pathError.message);
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
throw new Error('All WASM loading strategies failed');
|
|
175
|
+
} catch (error) {
|
|
176
|
+
console.error('Failed to load core module via bindings loader:', error);
|
|
177
|
+
console.warn('โ ๏ธ Falling back to placeholder WASM functionality');
|
|
178
|
+
|
|
179
|
+
// Log specific import errors for debugging
|
|
180
|
+
if (error.message && error.message.includes('import')) {
|
|
181
|
+
console.error('WASM import error details:', {
|
|
182
|
+
message: error.message,
|
|
183
|
+
stack: error.stack?.split('\n').slice(0, 5).join('\n'),
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return this.#placeholder('core');
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
#importsFor(name) {
|
|
192
|
+
const base = {
|
|
193
|
+
env: { memory: new WebAssembly.Memory({ initial: 256, maximum: 4096 }) },
|
|
194
|
+
wasi_snapshot_preview1: {
|
|
195
|
+
proc_exit: c => {
|
|
196
|
+
throw new Error(`WASI exit ${c}`);
|
|
197
|
+
},
|
|
198
|
+
fd_write: () => 0,
|
|
199
|
+
/* โฆminimal stubsโฆ */
|
|
200
|
+
random_get: (ptr, len) => {
|
|
201
|
+
const view = new Uint8Array(base.env.memory.buffer, ptr, len);
|
|
202
|
+
crypto.getRandomValues(view);
|
|
203
|
+
return 0;
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
if (name === 'neural') {
|
|
209
|
+
base.neural = { log_training_progress: (e, l) => console.log(`Epoch ${e} โ loss ${l}`) };
|
|
210
|
+
} else if (name === 'forecasting') {
|
|
211
|
+
base.forecasting = { log_forecast: (m, h) => console.log(`Forecast ${m}, horizon ${h}`) };
|
|
212
|
+
}
|
|
213
|
+
return base;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
#placeholder(name) {
|
|
217
|
+
console.warn(`โ ๏ธ Using placeholder for missing module '${name}'`);
|
|
218
|
+
const mem = new WebAssembly.Memory({ initial: 1, maximum: 10 });
|
|
219
|
+
return {
|
|
220
|
+
instance: { exports: { memory: mem } },
|
|
221
|
+
module: null,
|
|
222
|
+
exports: { memory: mem },
|
|
223
|
+
memory: mem,
|
|
224
|
+
isPlaceholder: true,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
async #loadCoreOnly() {
|
|
229
|
+
await this.loadModule('core');
|
|
230
|
+
}
|
|
231
|
+
async #loadAllModules() {
|
|
232
|
+
return Promise.all(Object.keys(this.moduleManifest).map(n => this.loadModule(n)));
|
|
233
|
+
}
|
|
234
|
+
#setupLazyProxies() {
|
|
235
|
+
const proxyBag = {};
|
|
236
|
+
for (const n of Object.keys(this.moduleManifest)) {
|
|
237
|
+
proxyBag[n] = new Proxy({}, {
|
|
238
|
+
get: (_, p) => {
|
|
239
|
+
if (!this.modules.has(n)) {
|
|
240
|
+
throw new Error(
|
|
241
|
+
`Module '${n}' not yet loaded; await loader.loadModule('${n}') first`,
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
return this.modules.get(n).exports[p];
|
|
245
|
+
},
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
return proxyBag;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
#resolvePackageWasmDir() {
|
|
252
|
+
try {
|
|
253
|
+
// Try different approaches to find the package root
|
|
254
|
+
const approaches = [
|
|
255
|
+
// Current working directory approach
|
|
256
|
+
() => {
|
|
257
|
+
const cwd = process.cwd();
|
|
258
|
+
const potentialPaths = [
|
|
259
|
+
path.join(cwd, 'node_modules', '@sparkleideas/ruv-swarm', 'wasm'),
|
|
260
|
+
path.join(cwd, '..', 'wasm'),
|
|
261
|
+
path.join(cwd, 'wasm'),
|
|
262
|
+
];
|
|
263
|
+
return potentialPaths.find(p => {
|
|
264
|
+
try {
|
|
265
|
+
accessSync(p);
|
|
266
|
+
return true;
|
|
267
|
+
} catch {
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
},
|
|
272
|
+
|
|
273
|
+
// Module resolution approach
|
|
274
|
+
() => {
|
|
275
|
+
try {
|
|
276
|
+
// For ES modules, use import.meta.resolve when available
|
|
277
|
+
const moduleDir = path.dirname(path.dirname(__filename));
|
|
278
|
+
return path.join(moduleDir, 'wasm');
|
|
279
|
+
} catch {
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
},
|
|
283
|
+
|
|
284
|
+
// Environment variable approach
|
|
285
|
+
() => process.env.RUV_SWARM_WASM_PATH,
|
|
286
|
+
];
|
|
287
|
+
|
|
288
|
+
for (const approach of approaches) {
|
|
289
|
+
try {
|
|
290
|
+
const result = approach();
|
|
291
|
+
if (result) {
|
|
292
|
+
return result;
|
|
293
|
+
}
|
|
294
|
+
} catch {
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
return null;
|
|
300
|
+
} catch {
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
#getWasmPathCandidates() {
|
|
306
|
+
return [
|
|
307
|
+
{
|
|
308
|
+
description: 'Local development (relative to src/)',
|
|
309
|
+
wasmDir: path.join(this.baseDir, '..', 'wasm'),
|
|
310
|
+
loaderPath: path.join(this.baseDir, '..', 'wasm', 'wasm-bindings-loader.mjs'),
|
|
311
|
+
wasmBinary: path.join(this.baseDir, '..', 'wasm', 'ruv_swarm_wasm_bg.wasm'),
|
|
312
|
+
jsBindings: path.join(this.baseDir, '..', 'wasm', 'ruv_swarm_wasm.js'),
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
description: 'NPM package installation (adjacent to src/)',
|
|
316
|
+
wasmDir: path.join(this.baseDir, '..', '..', 'wasm'),
|
|
317
|
+
loaderPath: path.join(this.baseDir, '..', '..', 'wasm', 'wasm-bindings-loader.mjs'),
|
|
318
|
+
wasmBinary: path.join(this.baseDir, '..', '..', 'wasm', 'ruv_swarm_wasm_bg.wasm'),
|
|
319
|
+
jsBindings: path.join(this.baseDir, '..', '..', 'wasm', 'ruv_swarm_wasm.js'),
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
description: 'Global npm installation',
|
|
323
|
+
wasmDir: this.#resolvePackageWasmDir(),
|
|
324
|
+
get loaderPath() {
|
|
325
|
+
return this.wasmDir ? path.join(this.wasmDir, 'wasm-bindings-loader.mjs') : null;
|
|
326
|
+
},
|
|
327
|
+
get wasmBinary() {
|
|
328
|
+
return this.wasmDir ? path.join(this.wasmDir, 'ruv_swarm_wasm_bg.wasm') : null;
|
|
329
|
+
},
|
|
330
|
+
get jsBindings() {
|
|
331
|
+
return this.wasmDir ? path.join(this.wasmDir, 'ruv_swarm_wasm.js') : null;
|
|
332
|
+
},
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
description: 'Bundled WASM (inline)',
|
|
336
|
+
wasmDir: null,
|
|
337
|
+
loaderPath: null,
|
|
338
|
+
wasmBinary: null,
|
|
339
|
+
jsBindings: null,
|
|
340
|
+
inline: true,
|
|
341
|
+
},
|
|
342
|
+
].filter(candidate => {
|
|
343
|
+
if (candidate.inline) {
|
|
344
|
+
return true;
|
|
345
|
+
}
|
|
346
|
+
try {
|
|
347
|
+
// Check if the wasm directory exists using sync fs access
|
|
348
|
+
accessSync(candidate.wasmDir);
|
|
349
|
+
return true;
|
|
350
|
+
} catch {
|
|
351
|
+
return false;
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
async #tryLoadFromPath(pathCandidate) {
|
|
357
|
+
if (pathCandidate.inline) {
|
|
358
|
+
// Use inline/bundled WASM approach
|
|
359
|
+
return this.#loadInlineWasm();
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Check if required files exist
|
|
363
|
+
await fs.access(pathCandidate.wasmBinary);
|
|
364
|
+
|
|
365
|
+
// Try to load the wasm-bindings-loader if it exists
|
|
366
|
+
if (pathCandidate.loaderPath) {
|
|
367
|
+
try {
|
|
368
|
+
await fs.access(pathCandidate.loaderPath);
|
|
369
|
+
|
|
370
|
+
const loaderURL = pathToFileURL(pathCandidate.loaderPath).href;
|
|
371
|
+
const loaderModule = await import(loaderURL);
|
|
372
|
+
const bindingsLoader = loaderModule.default;
|
|
373
|
+
const initialized = await bindingsLoader.initialize();
|
|
374
|
+
|
|
375
|
+
// Check if it's using placeholder
|
|
376
|
+
if (initialized.isPlaceholder) {
|
|
377
|
+
console.debug('Bindings loader returned placeholder');
|
|
378
|
+
throw new Error('Bindings loader using placeholder');
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
this.loadedBindings = initialized;
|
|
382
|
+
|
|
383
|
+
// Return a properly structured module object
|
|
384
|
+
return {
|
|
385
|
+
instance: { exports: initialized },
|
|
386
|
+
module: initialized,
|
|
387
|
+
exports: initialized,
|
|
388
|
+
memory: initialized.memory || new WebAssembly.Memory({ initial: 256, maximum: 4096 }),
|
|
389
|
+
getTotalMemoryUsage: initialized.getTotalMemoryUsage || (() => {
|
|
390
|
+
if (initialized.memory && initialized.memory.buffer) {
|
|
391
|
+
return initialized.memory.buffer.byteLength;
|
|
392
|
+
}
|
|
393
|
+
return 256 * 65536;
|
|
394
|
+
}),
|
|
395
|
+
isPlaceholder: false,
|
|
396
|
+
};
|
|
397
|
+
} catch (loaderError) {
|
|
398
|
+
console.debug('Loader error:', loaderError.message);
|
|
399
|
+
console.debug('Falling back to direct WASM loading');
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// Fallback to direct WASM loading
|
|
404
|
+
return this.#loadDirectWasm(pathCandidate.wasmBinary);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
async #loadInlineWasm() {
|
|
408
|
+
// Placeholder for inline WASM - could be base64 encoded or bundled
|
|
409
|
+
console.log('Using inline WASM placeholder');
|
|
410
|
+
throw new Error('Inline WASM not implemented yet');
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
async #loadDirectWasm(wasmPath) {
|
|
414
|
+
// For wasm-bindgen generated WASM, we need to use the JS bindings
|
|
415
|
+
const jsBindingsPath = wasmPath.replace('_bg.wasm', '.js');
|
|
416
|
+
|
|
417
|
+
try {
|
|
418
|
+
// Check if the JS bindings file exists
|
|
419
|
+
await fs.access(jsBindingsPath);
|
|
420
|
+
|
|
421
|
+
// Import the wasm-bindgen generated module
|
|
422
|
+
const bindingsURL = pathToFileURL(jsBindingsPath).href;
|
|
423
|
+
const wasmModule = await import(bindingsURL);
|
|
424
|
+
|
|
425
|
+
// Initialize the wasm module (wasm-bindgen handles the instantiation)
|
|
426
|
+
if (typeof wasmModule.default === 'function') {
|
|
427
|
+
// Call default export with the path to the WASM file
|
|
428
|
+
const wasmUrl = pathToFileURL(wasmPath).href;
|
|
429
|
+
await wasmModule.default(wasmUrl);
|
|
430
|
+
} else if (typeof wasmModule.init === 'function') {
|
|
431
|
+
// Some wasm-bindgen versions export an init function
|
|
432
|
+
const wasmUrl = pathToFileURL(wasmPath).href;
|
|
433
|
+
await wasmModule.init(wasmUrl);
|
|
434
|
+
} else if (typeof wasmModule.initSync === 'function') {
|
|
435
|
+
// Sync initialization variant
|
|
436
|
+
const wasmBuffer = await fs.readFile(wasmPath);
|
|
437
|
+
wasmModule.initSync(wasmBuffer);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// Store the loaded module
|
|
441
|
+
this.loadedWasm = wasmModule;
|
|
442
|
+
|
|
443
|
+
// Return a structure that matches our expected format
|
|
444
|
+
return {
|
|
445
|
+
instance: { exports: wasmModule },
|
|
446
|
+
module: wasmModule,
|
|
447
|
+
exports: wasmModule,
|
|
448
|
+
};
|
|
449
|
+
} catch (error) {
|
|
450
|
+
console.error('Failed to load wasm-bindgen module:', error);
|
|
451
|
+
// Fallback to direct WASM loading (won't work for wasm-bindgen but we try)
|
|
452
|
+
const wasmBuffer = await fs.readFile(wasmPath);
|
|
453
|
+
const imports = this.#importsFor('core');
|
|
454
|
+
const { instance, module } = await WebAssembly.instantiate(wasmBuffer, imports);
|
|
455
|
+
this.loadedWasm = { instance, module };
|
|
456
|
+
return { instance, module, exports: instance.exports };
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
#createBindingsApi() {
|
|
461
|
+
// If we have loaded bindings, return them directly
|
|
462
|
+
if (this.loadedBindings) {
|
|
463
|
+
return this.loadedBindings;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// If we have the actual wasm-bindgen module loaded, use it directly
|
|
467
|
+
if (this.loadedWasm && !this.loadedWasm.instance) {
|
|
468
|
+
// This is a wasm-bindgen module, return it directly
|
|
469
|
+
return this.loadedWasm;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// Create a minimal API that matches what the bindings would provide
|
|
473
|
+
const api = {
|
|
474
|
+
memory: new WebAssembly.Memory({ initial: 256, maximum: 4096 }),
|
|
475
|
+
|
|
476
|
+
// Neural network functions
|
|
477
|
+
create_neural_network: (layers, neurons_per_layer) => {
|
|
478
|
+
console.log(`Creating neural network with ${layers} layers and ${neurons_per_layer} neurons per layer`);
|
|
479
|
+
return 1;
|
|
480
|
+
},
|
|
481
|
+
|
|
482
|
+
train_network: (network_id, data, epochs) => {
|
|
483
|
+
console.log(`Training network ${network_id} for ${epochs} epochs`);
|
|
484
|
+
return true;
|
|
485
|
+
},
|
|
486
|
+
|
|
487
|
+
forward_pass: (network_id, input) => {
|
|
488
|
+
console.log(`Forward pass on network ${network_id}`);
|
|
489
|
+
return new Float32Array([0.5, 0.5, 0.5]);
|
|
490
|
+
},
|
|
491
|
+
|
|
492
|
+
// Forecasting functions
|
|
493
|
+
create_forecasting_model: (type) => {
|
|
494
|
+
console.log(`Creating forecasting model of type ${type}`);
|
|
495
|
+
return 1;
|
|
496
|
+
},
|
|
497
|
+
|
|
498
|
+
forecast: (model_id, data, horizon) => {
|
|
499
|
+
console.log(`Forecasting with model ${model_id} for horizon ${horizon}`);
|
|
500
|
+
return new Float32Array([0.1, 0.2, 0.3]);
|
|
501
|
+
},
|
|
502
|
+
|
|
503
|
+
// Swarm functions
|
|
504
|
+
create_swarm: (topology, max_agents) => {
|
|
505
|
+
console.log(`Creating swarm with ${topology} topology and ${max_agents} max agents`);
|
|
506
|
+
return 1;
|
|
507
|
+
},
|
|
508
|
+
|
|
509
|
+
spawn_agent: (swarm_id, agent_type) => {
|
|
510
|
+
console.log(`Spawning ${agent_type} agent in swarm ${swarm_id}`);
|
|
511
|
+
return 1;
|
|
512
|
+
},
|
|
513
|
+
|
|
514
|
+
// Memory management
|
|
515
|
+
getTotalMemoryUsage: () => {
|
|
516
|
+
return 256 * 65536; // 256 pages * 64KB
|
|
517
|
+
},
|
|
518
|
+
|
|
519
|
+
isPlaceholder: true,
|
|
520
|
+
};
|
|
521
|
+
|
|
522
|
+
// If we have actual WASM loaded, proxy to it
|
|
523
|
+
if (this.loadedWasm && this.loadedWasm.exports) {
|
|
524
|
+
const target = this.loadedWasm.exports;
|
|
525
|
+
return new Proxy(api, {
|
|
526
|
+
get(obj, prop) {
|
|
527
|
+
if (target && typeof target[prop] !== 'undefined') {
|
|
528
|
+
return target[prop];
|
|
529
|
+
}
|
|
530
|
+
return obj[prop];
|
|
531
|
+
},
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
return api;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
#fmt(b) {
|
|
539
|
+
if (!b) {
|
|
540
|
+
return '0 B';
|
|
541
|
+
}
|
|
542
|
+
const k = 1024, i = Math.floor(Math.log(b) / Math.log(k));
|
|
543
|
+
return `${(b / k ** i).toFixed(1)} ${['B', 'KB', 'MB', 'GB'][i]}`;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
getTotalMemoryUsage() {
|
|
547
|
+
let totalBytes = 0;
|
|
548
|
+
|
|
549
|
+
for (const [name, module] of this.modules.entries()) {
|
|
550
|
+
if (module && module.memory && module.memory.buffer) {
|
|
551
|
+
totalBytes += module.memory.buffer.byteLength;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
return totalBytes;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
clearCache() {
|
|
559
|
+
const cacheSize = this.wasmCache.size;
|
|
560
|
+
this.wasmCache.clear();
|
|
561
|
+
console.log(`๐งน Cleared WASM cache (${cacheSize} modules)`);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
optimizeMemory() {
|
|
565
|
+
// Clear expired cache entries
|
|
566
|
+
const now = Date.now();
|
|
567
|
+
let expired = 0;
|
|
568
|
+
|
|
569
|
+
for (const [key, cached] of this.wasmCache.entries()) {
|
|
570
|
+
if (now - cached.timestamp > this.cacheTimeout) {
|
|
571
|
+
this.wasmCache.delete(key);
|
|
572
|
+
expired++;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
if (expired > 0) {
|
|
577
|
+
console.log(`๐งน Removed ${expired} expired WASM cache entries`);
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
// Force garbage collection if available
|
|
581
|
+
if (global.gc) {
|
|
582
|
+
global.gc();
|
|
583
|
+
console.log('๐งน Triggered garbage collection');
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
return {
|
|
587
|
+
cacheSize: this.wasmCache.size,
|
|
588
|
+
memoryUsage: this.getTotalMemoryUsage(),
|
|
589
|
+
expiredEntries: expired,
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
595
|
+
export { WasmModuleLoader };
|
|
596
|
+
export default WasmModuleLoader; // ESM default
|
|
597
|
+
|
|
598
|
+
/* CJS interop --------------------------------------------------------------- */
|
|
599
|
+
if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
|
|
600
|
+
module.exports = WasmModuleLoader; // require('./wasm-module-loader')
|
|
601
|
+
}
|