@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,404 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Progressive WASM Module Loader
|
|
3
|
+
* Implements on-demand, eager, and progressive loading strategies
|
|
4
|
+
* for optimal performance and memory usage
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import path from 'path';
|
|
8
|
+
import { promises as fs } from 'fs';
|
|
9
|
+
|
|
10
|
+
class WasmModuleLoader {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.modules = new Map();
|
|
13
|
+
this.loadingPromises = new Map();
|
|
14
|
+
this.loadingStrategy = 'on-demand'; // 'eager', 'on-demand', 'progressive'
|
|
15
|
+
this.moduleManifest = {
|
|
16
|
+
core: {
|
|
17
|
+
path: './wasm/ruv_swarm_wasm_bg.wasm',
|
|
18
|
+
jsBindings: './wasm/ruv_swarm_wasm.js',
|
|
19
|
+
size: 512 * 1024, // 512KB
|
|
20
|
+
priority: 'high',
|
|
21
|
+
dependencies: [],
|
|
22
|
+
exists: true, // This module definitely exists
|
|
23
|
+
type: 'wasm-bindgen', // Uses wasm-bindgen generated bindings
|
|
24
|
+
},
|
|
25
|
+
// Legacy modules - keep for compatibility but mark as optional
|
|
26
|
+
neural: {
|
|
27
|
+
path: './wasm/ruv-fann.wasm',
|
|
28
|
+
size: 1024 * 1024, // 1MB
|
|
29
|
+
priority: 'medium',
|
|
30
|
+
dependencies: ['core'],
|
|
31
|
+
exists: false, // This is a standalone module, not currently built
|
|
32
|
+
optional: true,
|
|
33
|
+
},
|
|
34
|
+
forecasting: {
|
|
35
|
+
path: './wasm/neuro-divergent.wasm',
|
|
36
|
+
size: 1536 * 1024, // 1.5MB
|
|
37
|
+
priority: 'medium',
|
|
38
|
+
dependencies: ['core'],
|
|
39
|
+
exists: false, // This is a standalone module, not currently built
|
|
40
|
+
optional: true,
|
|
41
|
+
},
|
|
42
|
+
swarm: {
|
|
43
|
+
path: './wasm/ruv-swarm-orchestration.wasm',
|
|
44
|
+
size: 768 * 1024, // 768KB
|
|
45
|
+
priority: 'high',
|
|
46
|
+
dependencies: ['core'],
|
|
47
|
+
exists: false, // This functionality is in core module
|
|
48
|
+
optional: true,
|
|
49
|
+
},
|
|
50
|
+
persistence: {
|
|
51
|
+
path: './wasm/ruv-swarm-persistence.wasm',
|
|
52
|
+
size: 256 * 1024, // 256KB
|
|
53
|
+
priority: 'high',
|
|
54
|
+
dependencies: ['core'],
|
|
55
|
+
exists: false, // This functionality is handled by Node.js layer
|
|
56
|
+
optional: true,
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
this.baseDir = path.join(new URL('.', import.meta.url).pathname, '..');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async initialize(strategy = 'progressive') {
|
|
63
|
+
this.loadingStrategy = strategy;
|
|
64
|
+
|
|
65
|
+
switch (strategy) {
|
|
66
|
+
case 'eager':
|
|
67
|
+
return this.loadAllModules();
|
|
68
|
+
case 'progressive':
|
|
69
|
+
return this.loadCoreModules();
|
|
70
|
+
case 'on-demand':
|
|
71
|
+
return this.setupLazyLoading();
|
|
72
|
+
default:
|
|
73
|
+
throw new Error(`Unknown loading strategy: ${strategy}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async loadModule(moduleName) {
|
|
78
|
+
if (this.modules.has(moduleName)) {
|
|
79
|
+
return this.modules.get(moduleName);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (this.loadingPromises.has(moduleName)) {
|
|
83
|
+
return this.loadingPromises.get(moduleName);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const moduleInfo = this.moduleManifest[moduleName];
|
|
87
|
+
if (!moduleInfo) {
|
|
88
|
+
throw new Error(`Unknown module: ${moduleName}`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Check if module is marked as non-existent and optional
|
|
92
|
+
if (!moduleInfo.exists && moduleInfo.optional) {
|
|
93
|
+
// Silently use core module for neural and forecasting features
|
|
94
|
+
// These are integrated into the core module, not separate files
|
|
95
|
+
if (moduleName === 'neural' || moduleName === 'forecasting') {
|
|
96
|
+
if (this.modules.has('core')) {
|
|
97
|
+
const coreModule = this.modules.get('core');
|
|
98
|
+
this.modules.set(moduleName, coreModule); // Alias to core module
|
|
99
|
+
return coreModule;
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
// Only warn for other optional modules
|
|
103
|
+
console.warn(`⚠️ Optional module ${moduleName} is not available, functionality will be provided by core module`);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Return a reference to the core module instead of a placeholder
|
|
107
|
+
if (moduleName !== 'core' && this.modules.has('core')) {
|
|
108
|
+
const coreModule = this.modules.get('core');
|
|
109
|
+
this.modules.set(moduleName, coreModule); // Alias to core module
|
|
110
|
+
return coreModule;
|
|
111
|
+
}
|
|
112
|
+
throw new Error(`Optional module ${moduleName} not available and core module not loaded`);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Load dependencies first
|
|
116
|
+
for (const dep of moduleInfo.dependencies) {
|
|
117
|
+
await this.loadModule(dep);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const loadingPromise = this.loadWasmModule(moduleName, moduleInfo);
|
|
121
|
+
this.loadingPromises.set(moduleName, loadingPromise);
|
|
122
|
+
|
|
123
|
+
try {
|
|
124
|
+
const module = await loadingPromise;
|
|
125
|
+
this.modules.set(moduleName, module);
|
|
126
|
+
this.loadingPromises.delete(moduleName);
|
|
127
|
+
|
|
128
|
+
console.log(`✅ Loaded WASM module: ${moduleName} (${this.formatBytes(moduleInfo.size)})`);
|
|
129
|
+
return module;
|
|
130
|
+
} catch (error) {
|
|
131
|
+
this.loadingPromises.delete(moduleName);
|
|
132
|
+
|
|
133
|
+
// If it's an optional module, provide fallback to core functionality
|
|
134
|
+
if (moduleInfo.optional && this.modules.has('core')) {
|
|
135
|
+
console.warn(`⚠️ Optional module ${moduleName} failed to load, using core module functionality`);
|
|
136
|
+
const coreModule = this.modules.get('core');
|
|
137
|
+
this.modules.set(moduleName, coreModule);
|
|
138
|
+
return coreModule;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
console.error(`❌ Failed to load WASM module: ${moduleName}`, error);
|
|
142
|
+
throw error;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async loadWasmModule(moduleName, moduleInfo) {
|
|
147
|
+
// Special handling for the core module which uses ES module bindings
|
|
148
|
+
if (moduleName === 'core') {
|
|
149
|
+
return this.loadCoreModule();
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// For other modules, load the WASM file directly
|
|
153
|
+
const wasmPath = path.join(this.baseDir, moduleInfo.path);
|
|
154
|
+
|
|
155
|
+
try {
|
|
156
|
+
let wasmBuffer;
|
|
157
|
+
|
|
158
|
+
if (typeof window !== 'undefined') {
|
|
159
|
+
// Browser environment
|
|
160
|
+
const response = await fetch(wasmPath);
|
|
161
|
+
if (!response.ok) {
|
|
162
|
+
throw new Error(`Failed to fetch WASM module: ${response.statusText}`);
|
|
163
|
+
}
|
|
164
|
+
wasmBuffer = await response.arrayBuffer();
|
|
165
|
+
} else {
|
|
166
|
+
// Node.js environment
|
|
167
|
+
try {
|
|
168
|
+
wasmBuffer = await fs.readFile(wasmPath);
|
|
169
|
+
} catch (error) {
|
|
170
|
+
// Fallback: module might not exist yet, return a placeholder
|
|
171
|
+
console.warn(`Module ${moduleName} not found at ${wasmPath}, using placeholder`);
|
|
172
|
+
return this.createPlaceholderModule(moduleName);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const imports = this.getModuleImports(moduleName);
|
|
177
|
+
const wasmModule = await WebAssembly.instantiate(wasmBuffer, imports);
|
|
178
|
+
|
|
179
|
+
return {
|
|
180
|
+
instance: wasmModule.instance,
|
|
181
|
+
module: wasmModule.module,
|
|
182
|
+
exports: wasmModule.instance.exports,
|
|
183
|
+
memory: wasmModule.instance.exports.memory,
|
|
184
|
+
};
|
|
185
|
+
} catch (error) {
|
|
186
|
+
console.warn(`Failed to load ${moduleName}, using placeholder:`, error.message);
|
|
187
|
+
return this.createPlaceholderModule(moduleName);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
async loadCoreModule() {
|
|
192
|
+
// Load the core module using ES module bindings
|
|
193
|
+
try {
|
|
194
|
+
// Ensure we're using URL-based import for ES modules
|
|
195
|
+
const wasmJsUrl = new URL('../wasm/ruv_swarm_wasm.js', import.meta.url).href;
|
|
196
|
+
|
|
197
|
+
// Use dynamic import with URL protocol for ES modules
|
|
198
|
+
const bindings = await import(wasmJsUrl);
|
|
199
|
+
|
|
200
|
+
// Initialize WASM module with file buffer for Node.js
|
|
201
|
+
if (bindings.default && typeof window === 'undefined') {
|
|
202
|
+
const wasmPath = path.join(this.baseDir, 'wasm', 'ruv_swarm_wasm_bg.wasm');
|
|
203
|
+
try {
|
|
204
|
+
const wasmBuffer = await fs.readFile(wasmPath);
|
|
205
|
+
await bindings.default(wasmBuffer);
|
|
206
|
+
} catch (error) {
|
|
207
|
+
console.warn('Failed to load WASM file, using bindings defaults:', error);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return {
|
|
212
|
+
instance: { exports: bindings },
|
|
213
|
+
module: null,
|
|
214
|
+
exports: bindings,
|
|
215
|
+
memory: bindings.memory,
|
|
216
|
+
};
|
|
217
|
+
} catch (error) {
|
|
218
|
+
console.warn('Failed to load core module bindings:', error);
|
|
219
|
+
return this.createPlaceholderModule('core');
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
getModuleImports(moduleName) {
|
|
224
|
+
const baseImports = {
|
|
225
|
+
env: {
|
|
226
|
+
memory: new WebAssembly.Memory({ initial: 256, maximum: 4096 }),
|
|
227
|
+
},
|
|
228
|
+
wasi_snapshot_preview1: {
|
|
229
|
+
// Basic WASI imports for compatibility
|
|
230
|
+
proc_exit: (code) => {
|
|
231
|
+
throw new Error(`Process exited with code ${code}`);
|
|
232
|
+
},
|
|
233
|
+
fd_write: () => 0,
|
|
234
|
+
fd_prestat_get: () => 1,
|
|
235
|
+
fd_prestat_dir_name: () => 1,
|
|
236
|
+
environ_sizes_get: () => 0,
|
|
237
|
+
environ_get: () => 0,
|
|
238
|
+
args_sizes_get: () => 0,
|
|
239
|
+
args_get: () => 0,
|
|
240
|
+
clock_time_get: () => Date.now() * 1000000,
|
|
241
|
+
path_open: () => 1,
|
|
242
|
+
fd_close: () => 0,
|
|
243
|
+
fd_read: () => 0,
|
|
244
|
+
fd_seek: () => 0,
|
|
245
|
+
random_get: (ptr, len) => {
|
|
246
|
+
const bytes = new Uint8Array(this.memory.buffer, ptr, len);
|
|
247
|
+
crypto.getRandomValues(bytes);
|
|
248
|
+
return 0;
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
// Module-specific imports
|
|
254
|
+
switch (moduleName) {
|
|
255
|
+
case 'neural':
|
|
256
|
+
return {
|
|
257
|
+
...baseImports,
|
|
258
|
+
neural: {
|
|
259
|
+
log_training_progress: (epoch, loss) => {
|
|
260
|
+
console.log(`Training progress - Epoch: ${epoch}, Loss: ${loss}`);
|
|
261
|
+
},
|
|
262
|
+
},
|
|
263
|
+
};
|
|
264
|
+
case 'forecasting':
|
|
265
|
+
return {
|
|
266
|
+
...baseImports,
|
|
267
|
+
forecasting: {
|
|
268
|
+
log_forecast: (model, horizon) => {
|
|
269
|
+
console.log(`Forecasting with model: ${model}, horizon: ${horizon}`);
|
|
270
|
+
},
|
|
271
|
+
},
|
|
272
|
+
};
|
|
273
|
+
default:
|
|
274
|
+
return baseImports;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
createPlaceholderModule(moduleName) {
|
|
279
|
+
// Create a placeholder module with basic functionality
|
|
280
|
+
console.warn(`Creating placeholder for module: ${moduleName}`);
|
|
281
|
+
|
|
282
|
+
const placeholderExports = {
|
|
283
|
+
memory: new WebAssembly.Memory({ initial: 1, maximum: 10 }),
|
|
284
|
+
__wbindgen_malloc: (size) => 0,
|
|
285
|
+
__wbindgen_realloc: (ptr, oldSize, newSize) => ptr,
|
|
286
|
+
__wbindgen_free: (ptr, size) => {},
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
// Add module-specific placeholder functions
|
|
290
|
+
switch (moduleName) {
|
|
291
|
+
case 'neural':
|
|
292
|
+
placeholderExports.create_neural_network = () => {
|
|
293
|
+
console.warn('Neural network module not loaded, using placeholder');
|
|
294
|
+
return 0;
|
|
295
|
+
};
|
|
296
|
+
placeholderExports.train_network = () => 0;
|
|
297
|
+
placeholderExports.forward_pass = () => new Float32Array([0.5]);
|
|
298
|
+
break;
|
|
299
|
+
case 'forecasting':
|
|
300
|
+
placeholderExports.create_forecasting_model = () => {
|
|
301
|
+
console.warn('Forecasting module not loaded, using placeholder');
|
|
302
|
+
return 0;
|
|
303
|
+
};
|
|
304
|
+
placeholderExports.forecast = () => new Float32Array([0.0]);
|
|
305
|
+
break;
|
|
306
|
+
case 'swarm':
|
|
307
|
+
placeholderExports.create_swarm_orchestrator = () => {
|
|
308
|
+
console.warn('Swarm orchestration module not loaded, using placeholder');
|
|
309
|
+
return 0;
|
|
310
|
+
};
|
|
311
|
+
break;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
return {
|
|
315
|
+
instance: { exports: placeholderExports },
|
|
316
|
+
module: null,
|
|
317
|
+
exports: placeholderExports,
|
|
318
|
+
memory: placeholderExports.memory,
|
|
319
|
+
isPlaceholder: true,
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
async loadCoreModules() {
|
|
324
|
+
// Load only the core module - other functionality is included in it
|
|
325
|
+
await this.loadModule('core');
|
|
326
|
+
|
|
327
|
+
console.log('🚀 Core WASM module loaded successfully');
|
|
328
|
+
return true;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
async loadAllModules() {
|
|
332
|
+
// Only load modules that actually exist
|
|
333
|
+
const existingModules = Object.keys(this.moduleManifest)
|
|
334
|
+
.filter(name => this.moduleManifest[name].exists);
|
|
335
|
+
|
|
336
|
+
await Promise.all(existingModules.map(name => this.loadModule(name)));
|
|
337
|
+
|
|
338
|
+
console.log(`🎯 All available WASM modules loaded successfully (${existingModules.length} modules)`);
|
|
339
|
+
return true;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
setupLazyLoading() {
|
|
343
|
+
// Create proxy objects that load modules on first access
|
|
344
|
+
const moduleProxies = {};
|
|
345
|
+
|
|
346
|
+
for (const moduleName of Object.keys(this.moduleManifest)) {
|
|
347
|
+
moduleProxies[moduleName] = new Proxy({}, {
|
|
348
|
+
get: (target, prop) => {
|
|
349
|
+
if (!this.modules.has(moduleName)) {
|
|
350
|
+
// Trigger module loading
|
|
351
|
+
this.loadModule(moduleName);
|
|
352
|
+
throw new Error(`Module ${moduleName} is loading. Please await loadModule('${moduleName}') first.`);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
const module = this.modules.get(moduleName);
|
|
356
|
+
return module.exports[prop];
|
|
357
|
+
},
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
return moduleProxies;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
getModuleStatus() {
|
|
365
|
+
const status = {};
|
|
366
|
+
|
|
367
|
+
for (const [name, info] of Object.entries(this.moduleManifest)) {
|
|
368
|
+
status[name] = {
|
|
369
|
+
loaded: this.modules.has(name),
|
|
370
|
+
loading: this.loadingPromises.has(name),
|
|
371
|
+
size: info.size,
|
|
372
|
+
priority: info.priority,
|
|
373
|
+
dependencies: info.dependencies,
|
|
374
|
+
isPlaceholder: this.modules.has(name) && this.modules.get(name).isPlaceholder,
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
return status;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
getTotalMemoryUsage() {
|
|
382
|
+
let totalBytes = 0;
|
|
383
|
+
|
|
384
|
+
for (const module of this.modules.values()) {
|
|
385
|
+
if (module.memory && module.memory.buffer) {
|
|
386
|
+
totalBytes += module.memory.buffer.byteLength;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
return totalBytes;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
formatBytes(bytes) {
|
|
394
|
+
if (bytes === 0) {
|
|
395
|
+
return '0 Bytes';
|
|
396
|
+
}
|
|
397
|
+
const k = 1024;
|
|
398
|
+
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
399
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
400
|
+
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2)) } ${ sizes[i]}`;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
export { WasmModuleLoader };
|