@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,783 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WASM Memory Optimizer
|
|
3
|
+
*
|
|
4
|
+
* Advanced memory management and allocation optimization for WASM modules
|
|
5
|
+
* with progressive loading, memory pooling, and garbage collection strategies.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
class WasmMemoryPool {
|
|
9
|
+
constructor(initialSize = 16 * 1024 * 1024) { // 16MB initial
|
|
10
|
+
this.pools = new Map();
|
|
11
|
+
this.allocations = new Map();
|
|
12
|
+
this.totalAllocated = 0;
|
|
13
|
+
this.maxMemory = 512 * 1024 * 1024; // 512MB max
|
|
14
|
+
this.initialSize = initialSize;
|
|
15
|
+
this.allocationCounter = 0;
|
|
16
|
+
this.gcThreshold = 0.8; // GC when 80% full
|
|
17
|
+
this.compressionEnabled = true;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Get or create memory pool for specific module
|
|
22
|
+
*/
|
|
23
|
+
getPool(moduleId, requiredSize = this.initialSize) {
|
|
24
|
+
if (!this.pools.has(moduleId)) {
|
|
25
|
+
const poolSize = Math.max(requiredSize, this.initialSize);
|
|
26
|
+
const memory = new WebAssembly.Memory({
|
|
27
|
+
initial: Math.ceil(poolSize / (64 * 1024)), // Pages are 64KB
|
|
28
|
+
maximum: Math.ceil(this.maxMemory / (64 * 1024)),
|
|
29
|
+
shared: false,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
this.pools.set(moduleId, {
|
|
33
|
+
memory,
|
|
34
|
+
allocated: 0,
|
|
35
|
+
maxSize: poolSize,
|
|
36
|
+
freeBlocks: [],
|
|
37
|
+
allocations: new Map(),
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
console.log(`🧠 Created memory pool for ${moduleId}: ${poolSize / 1024 / 1024}MB`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return this.pools.get(moduleId);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Allocate memory with alignment and tracking
|
|
48
|
+
*/
|
|
49
|
+
allocate(moduleId, size, alignment = 16) {
|
|
50
|
+
const pool = this.getPool(moduleId, size * 2);
|
|
51
|
+
const alignedSize = Math.ceil(size / alignment) * alignment;
|
|
52
|
+
|
|
53
|
+
// Try to reuse free blocks first
|
|
54
|
+
const freeBlock = this.findFreeBlock(pool, alignedSize);
|
|
55
|
+
if (freeBlock) {
|
|
56
|
+
this.allocationCounter++;
|
|
57
|
+
const allocation = {
|
|
58
|
+
id: this.allocationCounter,
|
|
59
|
+
moduleId,
|
|
60
|
+
offset: freeBlock.offset,
|
|
61
|
+
size: alignedSize,
|
|
62
|
+
timestamp: Date.now(),
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
pool.allocations.set(allocation.id, allocation);
|
|
66
|
+
this.allocations.set(allocation.id, allocation);
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
id: allocation.id,
|
|
70
|
+
offset: freeBlock.offset,
|
|
71
|
+
ptr: pool.memory.buffer.slice(freeBlock.offset, freeBlock.offset + alignedSize),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Allocate new memory
|
|
76
|
+
const currentSize = pool.memory.buffer.byteLength;
|
|
77
|
+
const newOffset = pool.allocated;
|
|
78
|
+
|
|
79
|
+
if (newOffset + alignedSize > currentSize) {
|
|
80
|
+
// Need to grow memory
|
|
81
|
+
const requiredPages = Math.ceil((newOffset + alignedSize - currentSize) / (64 * 1024));
|
|
82
|
+
try {
|
|
83
|
+
pool.memory.grow(requiredPages);
|
|
84
|
+
console.log(`📈 Grew memory for ${moduleId} by ${requiredPages} pages`);
|
|
85
|
+
} catch (error) {
|
|
86
|
+
console.error(`❌ Failed to grow memory for ${moduleId}:`, error);
|
|
87
|
+
// Try garbage collection
|
|
88
|
+
this.garbageCollect(moduleId);
|
|
89
|
+
return this.allocate(moduleId, size, alignment); // Retry after GC
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
this.allocationCounter++;
|
|
94
|
+
const allocation = {
|
|
95
|
+
id: this.allocationCounter,
|
|
96
|
+
moduleId,
|
|
97
|
+
offset: newOffset,
|
|
98
|
+
size: alignedSize,
|
|
99
|
+
timestamp: Date.now(),
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
pool.allocated = newOffset + alignedSize;
|
|
103
|
+
pool.allocations.set(allocation.id, allocation);
|
|
104
|
+
this.allocations.set(allocation.id, allocation);
|
|
105
|
+
this.totalAllocated += alignedSize;
|
|
106
|
+
|
|
107
|
+
// Check if GC is needed
|
|
108
|
+
if (this.getMemoryUtilization() > this.gcThreshold) {
|
|
109
|
+
setTimeout(() => this.garbageCollectAll(), 100);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return {
|
|
113
|
+
id: allocation.id,
|
|
114
|
+
offset: newOffset,
|
|
115
|
+
ptr: pool.memory.buffer.slice(newOffset, newOffset + alignedSize),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Find suitable free block
|
|
121
|
+
*/
|
|
122
|
+
findFreeBlock(pool, size) {
|
|
123
|
+
for (let i = 0; i < pool.freeBlocks.length; i++) {
|
|
124
|
+
const block = pool.freeBlocks[i];
|
|
125
|
+
if (block.size >= size) {
|
|
126
|
+
// Remove from free blocks or split if larger
|
|
127
|
+
if (block.size > size + 64) { // Worth splitting
|
|
128
|
+
const remaining = {
|
|
129
|
+
offset: block.offset + size,
|
|
130
|
+
size: block.size - size,
|
|
131
|
+
};
|
|
132
|
+
pool.freeBlocks[i] = remaining;
|
|
133
|
+
} else {
|
|
134
|
+
pool.freeBlocks.splice(i, 1);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return {
|
|
138
|
+
offset: block.offset,
|
|
139
|
+
size: block.size,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Deallocate memory and add to free blocks
|
|
148
|
+
*/
|
|
149
|
+
deallocate(allocationId) {
|
|
150
|
+
const allocation = this.allocations.get(allocationId);
|
|
151
|
+
if (!allocation) {
|
|
152
|
+
console.warn(`⚠️ Allocation ${allocationId} not found`);
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const pool = this.pools.get(allocation.moduleId);
|
|
157
|
+
if (!pool) {
|
|
158
|
+
console.warn(`⚠️ Pool for ${allocation.moduleId} not found`);
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Add to free blocks
|
|
163
|
+
pool.freeBlocks.push({
|
|
164
|
+
offset: allocation.offset,
|
|
165
|
+
size: allocation.size,
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
// Merge adjacent free blocks
|
|
169
|
+
this.mergeFreeBlocks(pool);
|
|
170
|
+
|
|
171
|
+
// Remove from allocations
|
|
172
|
+
pool.allocations.delete(allocationId);
|
|
173
|
+
this.allocations.delete(allocationId);
|
|
174
|
+
this.totalAllocated -= allocation.size;
|
|
175
|
+
|
|
176
|
+
console.log(`🗑️ Deallocated ${allocation.size} bytes for ${allocation.moduleId}`);
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Merge adjacent free blocks to reduce fragmentation
|
|
182
|
+
*/
|
|
183
|
+
mergeFreeBlocks(pool) {
|
|
184
|
+
pool.freeBlocks.sort((a, b) => a.offset - b.offset);
|
|
185
|
+
|
|
186
|
+
for (let i = 0; i < pool.freeBlocks.length - 1; i++) {
|
|
187
|
+
const current = pool.freeBlocks[i];
|
|
188
|
+
const next = pool.freeBlocks[i + 1];
|
|
189
|
+
|
|
190
|
+
if (current.offset + current.size === next.offset) {
|
|
191
|
+
// Merge blocks
|
|
192
|
+
current.size += next.size;
|
|
193
|
+
pool.freeBlocks.splice(i + 1, 1);
|
|
194
|
+
i--; // Check again with merged block
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Garbage collect unused allocations
|
|
201
|
+
*/
|
|
202
|
+
garbageCollect(moduleId) {
|
|
203
|
+
const pool = this.pools.get(moduleId);
|
|
204
|
+
if (!pool) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const now = Date.now();
|
|
209
|
+
const maxAge = 300000; // 5 minutes
|
|
210
|
+
const freedAllocations = [];
|
|
211
|
+
|
|
212
|
+
for (const [id, allocation] of pool.allocations) {
|
|
213
|
+
if (now - allocation.timestamp > maxAge) {
|
|
214
|
+
freedAllocations.push(id);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
for (const id of freedAllocations) {
|
|
219
|
+
this.deallocate(id);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
console.log(`🧹 GC for ${moduleId}: freed ${freedAllocations.length} allocations`);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Garbage collect all pools
|
|
227
|
+
*/
|
|
228
|
+
garbageCollectAll() {
|
|
229
|
+
for (const moduleId of this.pools.keys()) {
|
|
230
|
+
this.garbageCollect(moduleId);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Get memory utilization ratio
|
|
236
|
+
*/
|
|
237
|
+
getMemoryUtilization() {
|
|
238
|
+
return this.totalAllocated / this.maxMemory;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Get detailed memory statistics
|
|
243
|
+
*/
|
|
244
|
+
getMemoryStats() {
|
|
245
|
+
const poolStats = {};
|
|
246
|
+
|
|
247
|
+
for (const [moduleId, pool] of this.pools) {
|
|
248
|
+
poolStats[moduleId] = {
|
|
249
|
+
allocated: pool.allocated,
|
|
250
|
+
bufferSize: pool.memory.buffer.byteLength,
|
|
251
|
+
freeBlocks: pool.freeBlocks.length,
|
|
252
|
+
activeAllocations: pool.allocations.size,
|
|
253
|
+
utilization: pool.allocated / pool.memory.buffer.byteLength,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return {
|
|
258
|
+
totalAllocated: this.totalAllocated,
|
|
259
|
+
maxMemory: this.maxMemory,
|
|
260
|
+
globalUtilization: this.getMemoryUtilization(),
|
|
261
|
+
pools: poolStats,
|
|
262
|
+
allocationCount: this.allocationCounter,
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Optimize memory layout by compacting allocations
|
|
268
|
+
*/
|
|
269
|
+
compactMemory(moduleId) {
|
|
270
|
+
const pool = this.pools.get(moduleId);
|
|
271
|
+
if (!pool) {
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Sort allocations by offset
|
|
276
|
+
const allocations = Array.from(pool.allocations.values())
|
|
277
|
+
.sort((a, b) => a.offset - b.offset);
|
|
278
|
+
|
|
279
|
+
let newOffset = 0;
|
|
280
|
+
const moves = [];
|
|
281
|
+
|
|
282
|
+
for (const allocation of allocations) {
|
|
283
|
+
if (allocation.offset !== newOffset) {
|
|
284
|
+
moves.push({
|
|
285
|
+
from: allocation.offset,
|
|
286
|
+
to: newOffset,
|
|
287
|
+
size: allocation.size,
|
|
288
|
+
});
|
|
289
|
+
allocation.offset = newOffset;
|
|
290
|
+
}
|
|
291
|
+
newOffset += allocation.size;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// Perform memory moves
|
|
295
|
+
const buffer = new Uint8Array(pool.memory.buffer);
|
|
296
|
+
for (const move of moves) {
|
|
297
|
+
const src = buffer.subarray(move.from, move.from + move.size);
|
|
298
|
+
buffer.set(src, move.to);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Update pool state
|
|
302
|
+
pool.allocated = newOffset;
|
|
303
|
+
pool.freeBlocks = newOffset < pool.memory.buffer.byteLength ?
|
|
304
|
+
[{ offset: newOffset, size: pool.memory.buffer.byteLength - newOffset }] : [];
|
|
305
|
+
|
|
306
|
+
console.log(`🗜️ Compacted ${moduleId}: ${moves.length} moves, freed ${pool.memory.buffer.byteLength - newOffset} bytes`);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Progressive WASM Module Loader with Memory Optimization
|
|
312
|
+
*/
|
|
313
|
+
class ProgressiveWasmLoader {
|
|
314
|
+
constructor() {
|
|
315
|
+
this.memoryPool = new WasmMemoryPool();
|
|
316
|
+
this.loadedModules = new Map();
|
|
317
|
+
this.loadingQueues = new Map();
|
|
318
|
+
this.priorityLevels = {
|
|
319
|
+
'critical': 1,
|
|
320
|
+
'high': 2,
|
|
321
|
+
'medium': 3,
|
|
322
|
+
'low': 4,
|
|
323
|
+
};
|
|
324
|
+
this.loadingStrategies = {
|
|
325
|
+
'eager': this.loadAllModules.bind(this),
|
|
326
|
+
'lazy': this.loadOnDemand.bind(this),
|
|
327
|
+
'progressive': this.loadProgressively.bind(this),
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Register module for progressive loading
|
|
333
|
+
*/
|
|
334
|
+
registerModule(config) {
|
|
335
|
+
const {
|
|
336
|
+
id,
|
|
337
|
+
url,
|
|
338
|
+
size,
|
|
339
|
+
priority = 'medium',
|
|
340
|
+
dependencies = [],
|
|
341
|
+
features = [],
|
|
342
|
+
preload = false,
|
|
343
|
+
} = config;
|
|
344
|
+
|
|
345
|
+
const module = {
|
|
346
|
+
id,
|
|
347
|
+
url,
|
|
348
|
+
size,
|
|
349
|
+
priority,
|
|
350
|
+
dependencies,
|
|
351
|
+
features,
|
|
352
|
+
preload,
|
|
353
|
+
loaded: false,
|
|
354
|
+
loading: false,
|
|
355
|
+
instance: null,
|
|
356
|
+
memoryAllocations: new Set(),
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
this.loadedModules.set(id, module);
|
|
360
|
+
|
|
361
|
+
if (preload) {
|
|
362
|
+
this.queueLoad(id, 'critical');
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
console.log(`📋 Registered WASM module: ${id} (${size / 1024}KB, ${priority} priority)`);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Queue module for loading with priority
|
|
370
|
+
*/
|
|
371
|
+
queueLoad(moduleId, priority = 'medium') {
|
|
372
|
+
if (!this.loadingQueues.has(priority)) {
|
|
373
|
+
this.loadingQueues.set(priority, []);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
const queue = this.loadingQueues.get(priority);
|
|
377
|
+
if (!queue.includes(moduleId)) {
|
|
378
|
+
queue.push(moduleId);
|
|
379
|
+
this.processLoadingQueue();
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Process loading queue by priority
|
|
385
|
+
*/
|
|
386
|
+
async processLoadingQueue() {
|
|
387
|
+
for (const priority of Object.keys(this.priorityLevels).sort((a, b) =>
|
|
388
|
+
this.priorityLevels[a] - this.priorityLevels[b])) {
|
|
389
|
+
|
|
390
|
+
const queue = this.loadingQueues.get(priority);
|
|
391
|
+
if (!queue || queue.length === 0) {
|
|
392
|
+
continue;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
const moduleId = queue.shift();
|
|
396
|
+
await this.loadModule(moduleId);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Load individual module with memory optimization
|
|
402
|
+
*/
|
|
403
|
+
async loadModule(moduleId) {
|
|
404
|
+
const module = this.loadedModules.get(moduleId);
|
|
405
|
+
if (!module) {
|
|
406
|
+
throw new Error(`Module ${moduleId} not registered`);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
if (module.loaded) {
|
|
410
|
+
return module.instance;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
if (module.loading) {
|
|
414
|
+
// Wait for existing load
|
|
415
|
+
while (module.loading) {
|
|
416
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
417
|
+
}
|
|
418
|
+
return module.instance;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
module.loading = true;
|
|
422
|
+
|
|
423
|
+
try {
|
|
424
|
+
console.log(`📦 Loading WASM module: ${moduleId}`);
|
|
425
|
+
|
|
426
|
+
// Load dependencies first
|
|
427
|
+
for (const depId of module.dependencies) {
|
|
428
|
+
await this.loadModule(depId);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// Fetch WASM bytes
|
|
432
|
+
const response = await fetch(module.url);
|
|
433
|
+
if (!response.ok) {
|
|
434
|
+
throw new Error(`Failed to fetch ${module.url}: ${response.status}`);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
const wasmBytes = await response.arrayBuffer();
|
|
438
|
+
|
|
439
|
+
// Allocate memory for module
|
|
440
|
+
const memoryAllocation = this.memoryPool.allocate(
|
|
441
|
+
moduleId,
|
|
442
|
+
module.size || wasmBytes.byteLength * 2,
|
|
443
|
+
);
|
|
444
|
+
|
|
445
|
+
module.memoryAllocations.add(memoryAllocation.id);
|
|
446
|
+
|
|
447
|
+
// Create imports with optimized memory
|
|
448
|
+
const imports = this.createModuleImports(moduleId, memoryAllocation);
|
|
449
|
+
|
|
450
|
+
// Compile and instantiate
|
|
451
|
+
const startTime = performance.now();
|
|
452
|
+
const wasmModule = await WebAssembly.compile(wasmBytes);
|
|
453
|
+
const instance = await WebAssembly.instantiate(wasmModule, imports);
|
|
454
|
+
const loadTime = performance.now() - startTime;
|
|
455
|
+
|
|
456
|
+
module.instance = {
|
|
457
|
+
module: wasmModule,
|
|
458
|
+
instance,
|
|
459
|
+
exports: instance.exports,
|
|
460
|
+
memory: memoryAllocation,
|
|
461
|
+
loadTime,
|
|
462
|
+
};
|
|
463
|
+
|
|
464
|
+
module.loaded = true;
|
|
465
|
+
module.loading = false;
|
|
466
|
+
|
|
467
|
+
console.log(`✅ Loaded ${moduleId} in ${loadTime.toFixed(2)}ms`);
|
|
468
|
+
|
|
469
|
+
// Optimize memory after loading
|
|
470
|
+
this.optimizeModuleMemory(moduleId);
|
|
471
|
+
|
|
472
|
+
return module.instance;
|
|
473
|
+
|
|
474
|
+
} catch (error) {
|
|
475
|
+
module.loading = false;
|
|
476
|
+
console.error(`❌ Failed to load ${moduleId}:`, error);
|
|
477
|
+
throw error;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* Create optimized imports for module
|
|
483
|
+
*/
|
|
484
|
+
createModuleImports(moduleId, memoryAllocation) {
|
|
485
|
+
const pool = this.memoryPool.getPool(moduleId);
|
|
486
|
+
|
|
487
|
+
return {
|
|
488
|
+
env: {
|
|
489
|
+
memory: pool.memory,
|
|
490
|
+
|
|
491
|
+
// Optimized memory allocation functions
|
|
492
|
+
malloc: (size) => {
|
|
493
|
+
const allocation = this.memoryPool.allocate(moduleId, size);
|
|
494
|
+
return allocation.offset;
|
|
495
|
+
},
|
|
496
|
+
|
|
497
|
+
free: (ptr) => {
|
|
498
|
+
// Find allocation by offset and free it
|
|
499
|
+
for (const allocation of this.memoryPool.allocations.values()) {
|
|
500
|
+
if (allocation.moduleId === moduleId && allocation.offset === ptr) {
|
|
501
|
+
this.memoryPool.deallocate(allocation.id);
|
|
502
|
+
break;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
},
|
|
506
|
+
|
|
507
|
+
// SIMD-optimized math functions
|
|
508
|
+
simd_add_f32x4: (a, b, result) => {
|
|
509
|
+
// This would call the SIMD implementation
|
|
510
|
+
console.log('SIMD add called');
|
|
511
|
+
},
|
|
512
|
+
|
|
513
|
+
// Performance monitoring
|
|
514
|
+
performance_mark: (name) => {
|
|
515
|
+
performance.mark(`${moduleId}_${name}`);
|
|
516
|
+
},
|
|
517
|
+
},
|
|
518
|
+
|
|
519
|
+
// WASI support for file operations
|
|
520
|
+
wasi_snapshot_preview1: {
|
|
521
|
+
proc_exit: (code) => {
|
|
522
|
+
console.log(`Module ${moduleId} exited with code ${code}`);
|
|
523
|
+
},
|
|
524
|
+
fd_write: () => 0,
|
|
525
|
+
},
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
/**
|
|
530
|
+
* Optimize module memory after loading
|
|
531
|
+
*/
|
|
532
|
+
optimizeModuleMemory(moduleId) {
|
|
533
|
+
setTimeout(() => {
|
|
534
|
+
this.memoryPool.compactMemory(moduleId);
|
|
535
|
+
}, 1000); // Delay to allow initial operations
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* Progressive loading strategy
|
|
540
|
+
*/
|
|
541
|
+
async loadProgressively() {
|
|
542
|
+
// Load critical modules first
|
|
543
|
+
const criticalModules = Array.from(this.loadedModules.values())
|
|
544
|
+
.filter(m => m.priority === 'critical' || m.preload)
|
|
545
|
+
.sort((a, b) => this.priorityLevels[a.priority] - this.priorityLevels[b.priority]);
|
|
546
|
+
|
|
547
|
+
for (const module of criticalModules) {
|
|
548
|
+
await this.loadModule(module.id);
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
// Load remaining modules in background
|
|
552
|
+
const remainingModules = Array.from(this.loadedModules.values())
|
|
553
|
+
.filter(m => !m.loaded && !m.loading)
|
|
554
|
+
.sort((a, b) => this.priorityLevels[a.priority] - this.priorityLevels[b.priority]);
|
|
555
|
+
|
|
556
|
+
// Load with delay to prevent blocking
|
|
557
|
+
let delay = 0;
|
|
558
|
+
for (const module of remainingModules) {
|
|
559
|
+
setTimeout(() => this.loadModule(module.id), delay);
|
|
560
|
+
delay += 100; // 100ms between loads
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Eager loading strategy
|
|
566
|
+
*/
|
|
567
|
+
async loadAllModules() {
|
|
568
|
+
const modules = Array.from(this.loadedModules.values())
|
|
569
|
+
.sort((a, b) => this.priorityLevels[a.priority] - this.priorityLevels[b.priority]);
|
|
570
|
+
|
|
571
|
+
await Promise.all(modules.map(m => this.loadModule(m.id)));
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* Lazy loading strategy
|
|
576
|
+
*/
|
|
577
|
+
async loadOnDemand(moduleId) {
|
|
578
|
+
return this.loadModule(moduleId);
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
/**
|
|
582
|
+
* Get module by ID
|
|
583
|
+
*/
|
|
584
|
+
getModule(moduleId) {
|
|
585
|
+
const module = this.loadedModules.get(moduleId);
|
|
586
|
+
return module?.instance || null;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
/**
|
|
590
|
+
* Unload module and free memory
|
|
591
|
+
*/
|
|
592
|
+
unloadModule(moduleId) {
|
|
593
|
+
const module = this.loadedModules.get(moduleId);
|
|
594
|
+
if (!module || !module.loaded) {
|
|
595
|
+
return false;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
// Free all memory allocations
|
|
599
|
+
for (const allocationId of module.memoryAllocations) {
|
|
600
|
+
this.memoryPool.deallocate(allocationId);
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
module.memoryAllocations.clear();
|
|
604
|
+
module.instance = null;
|
|
605
|
+
module.loaded = false;
|
|
606
|
+
|
|
607
|
+
console.log(`🗑️ Unloaded module: ${moduleId}`);
|
|
608
|
+
return true;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* Get comprehensive loader statistics
|
|
613
|
+
*/
|
|
614
|
+
getLoaderStats() {
|
|
615
|
+
const modules = Array.from(this.loadedModules.values());
|
|
616
|
+
const loaded = modules.filter(m => m.loaded);
|
|
617
|
+
const loading = modules.filter(m => m.loading);
|
|
618
|
+
|
|
619
|
+
return {
|
|
620
|
+
totalModules: modules.length,
|
|
621
|
+
loadedModules: loaded.length,
|
|
622
|
+
loadingModules: loading.length,
|
|
623
|
+
memoryStats: this.memoryPool.getMemoryStats(),
|
|
624
|
+
loadTimes: loaded.map(m => ({
|
|
625
|
+
id: m.id,
|
|
626
|
+
loadTime: m.instance?.loadTime || 0,
|
|
627
|
+
})),
|
|
628
|
+
averageLoadTime: loaded.reduce((acc, m) => acc + (m.instance?.loadTime || 0), 0) / loaded.length,
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
/**
|
|
633
|
+
* Optimize all memory pools
|
|
634
|
+
*/
|
|
635
|
+
optimizeMemory() {
|
|
636
|
+
this.memoryPool.garbageCollectAll();
|
|
637
|
+
|
|
638
|
+
for (const moduleId of this.loadedModules.keys()) {
|
|
639
|
+
if (this.loadedModules.get(moduleId).loaded) {
|
|
640
|
+
this.memoryPool.compactMemory(moduleId);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
console.log('🧹 Memory optimization completed');
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
/**
|
|
649
|
+
* WASM Browser Compatibility Manager
|
|
650
|
+
*/
|
|
651
|
+
class WasmCompatibilityManager {
|
|
652
|
+
constructor() {
|
|
653
|
+
this.capabilities = null;
|
|
654
|
+
this.fallbacks = new Map();
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
/**
|
|
658
|
+
* Detect browser WASM capabilities
|
|
659
|
+
*/
|
|
660
|
+
async detectCapabilities() {
|
|
661
|
+
const capabilities = {
|
|
662
|
+
webassembly: typeof WebAssembly !== 'undefined',
|
|
663
|
+
simd: false,
|
|
664
|
+
threads: false,
|
|
665
|
+
exceptions: false,
|
|
666
|
+
memory64: false,
|
|
667
|
+
streaming: false,
|
|
668
|
+
};
|
|
669
|
+
|
|
670
|
+
if (!capabilities.webassembly) {
|
|
671
|
+
this.capabilities = capabilities;
|
|
672
|
+
return capabilities;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
// Test SIMD support
|
|
676
|
+
try {
|
|
677
|
+
const simdTest = new Uint8Array([
|
|
678
|
+
0x00, 0x61, 0x73, 0x6d, // WASM magic
|
|
679
|
+
0x01, 0x00, 0x00, 0x00, // version
|
|
680
|
+
0x01, 0x05, 0x01, 0x60, 0x00, 0x01, 0x7b, // type section
|
|
681
|
+
0x03, 0x02, 0x01, 0x00, // function section
|
|
682
|
+
0x0a, 0x09, 0x01, 0x07, 0x00, 0xfd, 0x0c, 0x00, 0x0b, // code section with SIMD
|
|
683
|
+
]);
|
|
684
|
+
|
|
685
|
+
await WebAssembly.compile(simdTest);
|
|
686
|
+
capabilities.simd = true;
|
|
687
|
+
} catch (e) {
|
|
688
|
+
capabilities.simd = false;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
// Test streaming compilation
|
|
692
|
+
capabilities.streaming = typeof WebAssembly.compileStreaming === 'function';
|
|
693
|
+
|
|
694
|
+
// Test SharedArrayBuffer for threads
|
|
695
|
+
capabilities.threads = typeof SharedArrayBuffer !== 'undefined';
|
|
696
|
+
|
|
697
|
+
this.capabilities = capabilities;
|
|
698
|
+
console.log('🔍 WASM capabilities detected:', capabilities);
|
|
699
|
+
|
|
700
|
+
return capabilities;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
/**
|
|
704
|
+
* Get capabilities (detect if not already done)
|
|
705
|
+
*/
|
|
706
|
+
async getCapabilities() {
|
|
707
|
+
if (!this.capabilities) {
|
|
708
|
+
await this.detectCapabilities();
|
|
709
|
+
}
|
|
710
|
+
return this.capabilities;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
/**
|
|
714
|
+
* Register fallback for feature
|
|
715
|
+
*/
|
|
716
|
+
registerFallback(feature, fallbackFn) {
|
|
717
|
+
this.fallbacks.set(feature, fallbackFn);
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
/**
|
|
721
|
+
* Check if feature is supported with fallback
|
|
722
|
+
*/
|
|
723
|
+
async isSupported(feature) {
|
|
724
|
+
const capabilities = await this.getCapabilities();
|
|
725
|
+
|
|
726
|
+
if (capabilities[feature]) {
|
|
727
|
+
return true;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
if (this.fallbacks.has(feature)) {
|
|
731
|
+
console.log(`⚠️ Using fallback for ${feature}`);
|
|
732
|
+
return 'fallback';
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
return false;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
/**
|
|
739
|
+
* Load module with compatibility checks
|
|
740
|
+
*/
|
|
741
|
+
async loadCompatibleModule(url, features = []) {
|
|
742
|
+
const capabilities = await this.getCapabilities();
|
|
743
|
+
|
|
744
|
+
if (!capabilities.webassembly) {
|
|
745
|
+
throw new Error('WebAssembly not supported in this browser');
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
// Check required features
|
|
749
|
+
const unsupported = [];
|
|
750
|
+
for (const feature of features) {
|
|
751
|
+
const support = await this.isSupported(feature);
|
|
752
|
+
if (!support) {
|
|
753
|
+
unsupported.push(feature);
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
if (unsupported.length > 0) {
|
|
758
|
+
console.warn(`⚠️ Unsupported features: ${unsupported.join(', ')}`);
|
|
759
|
+
// Could load alternative module or disable features
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
// Load with appropriate method
|
|
763
|
+
if (capabilities.streaming) {
|
|
764
|
+
return WebAssembly.compileStreaming(fetch(url));
|
|
765
|
+
}
|
|
766
|
+
const response = await fetch(url);
|
|
767
|
+
const bytes = await response.arrayBuffer();
|
|
768
|
+
return WebAssembly.compile(bytes);
|
|
769
|
+
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
export {
|
|
774
|
+
WasmMemoryPool,
|
|
775
|
+
ProgressiveWasmLoader,
|
|
776
|
+
WasmCompatibilityManager,
|
|
777
|
+
};
|
|
778
|
+
|
|
779
|
+
export default {
|
|
780
|
+
WasmMemoryPool,
|
|
781
|
+
ProgressiveWasmLoader,
|
|
782
|
+
WasmCompatibilityManager,
|
|
783
|
+
};
|