Files
wifi-densepose/examples/edge-net/pkg/models/wasm-core.js
ruv d803bfe2b1 Squashed 'vendor/ruvector/' content from commit b64c2172
git-subtree-dir: vendor/ruvector
git-subtree-split: b64c21726f2bb37286d9ee36a7869fef60cc6900
2026-02-28 14:39:40 -05:00

1026 lines
31 KiB
JavaScript

/**
* @ruvector/edge-net WASM Core
*
* Pure WASM implementation for cross-platform edge support:
* - Browsers (Chrome, Firefox, Safari, Edge)
* - Node.js 16+
* - Deno
* - Cloudflare Workers
* - Vercel Edge
* - Bun
*
* Uses ruvector_edge_net WASM module for:
* - Ed25519 signing/verification
* - SHA256/SHA512 hashing
* - Merkle tree operations
* - Canonical JSON encoding
*
* @module @ruvector/edge-net/models/wasm-core
*/
// ============================================================================
// PLATFORM DETECTION
// ============================================================================
/**
* Detect current runtime environment
*/
export function detectPlatform() {
// Cloudflare Workers
if (typeof caches !== 'undefined' && typeof HTMLRewriter !== 'undefined') {
return 'cloudflare-workers';
}
// Deno
if (typeof Deno !== 'undefined') {
return 'deno';
}
// Bun
if (typeof Bun !== 'undefined') {
return 'bun';
}
// Node.js
if (typeof process !== 'undefined' && process.versions?.node) {
return 'node';
}
// Browser with WebAssembly
if (typeof window !== 'undefined' && typeof WebAssembly !== 'undefined') {
return 'browser';
}
// Generic WebAssembly environment
if (typeof WebAssembly !== 'undefined') {
return 'wasm';
}
return 'unknown';
}
/**
* Platform capabilities
*/
export function getPlatformCapabilities() {
const platform = detectPlatform();
return {
platform,
hasWebAssembly: typeof WebAssembly !== 'undefined',
hasSIMD: checkSIMDSupport(),
hasThreads: checkThreadsSupport(),
hasStreaming: typeof WebAssembly?.compileStreaming === 'function',
hasIndexedDB: typeof indexedDB !== 'undefined',
hasWebCrypto: typeof crypto?.subtle !== 'undefined',
hasP2P: typeof RTCPeerConnection !== 'undefined',
maxMemory: getMaxMemory(),
};
}
function checkSIMDSupport() {
try {
return WebAssembly.validate(new Uint8Array([
0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00,
0x01, 0x05, 0x01, 0x60, 0x00, 0x01, 0x7b, 0x03,
0x02, 0x01, 0x00, 0x0a, 0x0a, 0x01, 0x08, 0x00,
0xfd, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x0b
]));
} catch {
return false;
}
}
function checkThreadsSupport() {
try {
return typeof SharedArrayBuffer !== 'undefined' &&
typeof Atomics !== 'undefined';
} catch {
return false;
}
}
function getMaxMemory() {
// Browser
if (typeof navigator !== 'undefined' && navigator.deviceMemory) {
return navigator.deviceMemory * 1024 * 1024 * 1024;
}
// Node.js
if (typeof process !== 'undefined') {
try {
const os = require('os');
return os.totalmem?.() || 4 * 1024 * 1024 * 1024;
} catch {
return 4 * 1024 * 1024 * 1024;
}
}
// Default 4GB
return 4 * 1024 * 1024 * 1024;
}
// ============================================================================
// WASM MODULE LOADING
// ============================================================================
let wasmModule = null;
let wasmInstance = null;
let wasmReady = false;
/**
* Initialize WASM module with platform-specific loading
*/
export async function initWasm(options = {}) {
if (wasmReady && wasmInstance) {
return wasmInstance;
}
const platform = detectPlatform();
const capabilities = getPlatformCapabilities();
console.log(`[WASM Core] Initializing on ${platform}`);
try {
// Try to import the main WASM module
const wasmPath = options.wasmPath || findWasmPath();
if (capabilities.hasStreaming && platform !== 'cloudflare-workers') {
// Streaming compilation (faster)
const response = await fetch(wasmPath);
wasmModule = await WebAssembly.compileStreaming(response);
} else {
// Buffer-based compilation (Workers, fallback)
const wasmBytes = await loadWasmBytes(wasmPath);
wasmModule = await WebAssembly.compile(wasmBytes);
}
// Instantiate with imports
wasmInstance = await WebAssembly.instantiate(wasmModule, getWasmImports());
wasmReady = true;
console.log(`[WASM Core] Ready with ${capabilities.hasSIMD ? 'SIMD' : 'no SIMD'}`);
return wasmInstance;
} catch (error) {
console.warn(`[WASM Core] Native WASM failed, using JS fallback:`, error.message);
// Use JavaScript fallback
wasmInstance = createJSFallback();
wasmReady = true;
return wasmInstance;
}
}
/**
* Find WASM file path based on environment
*/
function findWasmPath() {
const platform = detectPlatform();
switch (platform) {
case 'node':
case 'bun':
return new URL('../ruvector_edge_net_bg.wasm', import.meta.url).href;
case 'deno':
return new URL('../ruvector_edge_net_bg.wasm', import.meta.url).href;
case 'browser':
// Try multiple paths
return './ruvector_edge_net_bg.wasm';
case 'cloudflare-workers':
// Workers use bundled WASM
return '__WASM_MODULE__';
default:
return './ruvector_edge_net_bg.wasm';
}
}
/**
* Load WASM bytes based on platform
*/
async function loadWasmBytes(path) {
const platform = detectPlatform();
switch (platform) {
case 'node': {
// Node 18+ has native fetch, use it for URLs
if (path.startsWith('http://') || path.startsWith('https://')) {
const response = await fetch(path);
return response.arrayBuffer();
}
// For file:// URLs or local paths
const fs = await import('fs/promises');
const { fileURLToPath } = await import('url');
// Convert file:// URL to path if needed
const filePath = path.startsWith('file://')
? fileURLToPath(path)
: path;
return fs.readFile(filePath);
}
case 'deno': {
return Deno.readFile(path);
}
case 'bun': {
return Bun.file(path).arrayBuffer();
}
default: {
const response = await fetch(path);
return response.arrayBuffer();
}
}
}
/**
* Shared WASM memory - created once before instantiation
*/
let sharedMemory = null;
function getSharedMemory() {
if (!sharedMemory) {
// Reasonable memory limits for edge platforms:
// initial: 256 pages (16MB), max: 1024 pages (64MB)
sharedMemory = new WebAssembly.Memory({ initial: 256, maximum: 1024 });
}
return sharedMemory;
}
/**
* WASM imports for the module
* CRITICAL: Does NOT reference wasmInstance - uses shared memory instead
*/
function getWasmImports() {
const memory = getSharedMemory();
return {
env: {
// Memory - use shared instance created BEFORE wasm instantiation
memory,
// Console - uses shared memory buffer (safe, memory exists)
console_log: (ptr, len) => {
const bytes = new Uint8Array(memory.buffer, ptr, len);
console.log(new TextDecoder().decode(bytes));
},
console_error: (ptr, len) => {
const bytes = new Uint8Array(memory.buffer, ptr, len);
console.error(new TextDecoder().decode(bytes));
},
// Time
now_ms: () => Date.now(),
// Random - uses shared memory buffer (safe)
get_random_bytes: (ptr, len) => {
const bytes = new Uint8Array(memory.buffer, ptr, len);
crypto.getRandomValues(bytes);
},
},
wasi_snapshot_preview1: {
// Minimal WASI stubs for compatibility
fd_write: () => 0,
fd_read: () => 0,
fd_close: () => 0,
environ_get: () => 0,
environ_sizes_get: () => 0,
proc_exit: () => {},
},
};
}
// ============================================================================
// JAVASCRIPT FALLBACK
// ============================================================================
/**
* Pure JavaScript fallback when WASM is unavailable
*/
function createJSFallback() {
return {
exports: {
// SHA256
sha256: async (data) => {
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
return new Uint8Array(hashBuffer);
},
// SHA512
sha512: async (data) => {
const hashBuffer = await crypto.subtle.digest('SHA-512', data);
return new Uint8Array(hashBuffer);
},
// Ed25519 (using SubtleCrypto if available)
// SECURITY: Fail closed - never return mock signatures
ed25519_sign: async (message, privateKey) => {
// SubtleCrypto Ed25519 support varies by platform
try {
const key = await crypto.subtle.importKey(
'raw',
privateKey,
{ name: 'Ed25519' },
false,
['sign']
);
const signature = await crypto.subtle.sign('Ed25519', key, message);
return new Uint8Array(signature);
} catch (error) {
// FAIL CLOSED: Do not return mock signatures - throw error
throw new Error(`[SECURITY] Ed25519 signing unavailable: ${error.message}. Install tweetnacl for platforms without native Ed25519.`);
}
},
ed25519_verify: async (message, signature, publicKey) => {
try {
const key = await crypto.subtle.importKey(
'raw',
publicKey,
{ name: 'Ed25519' },
false,
['verify']
);
return await crypto.subtle.verify('Ed25519', key, signature, message);
} catch (error) {
// FAIL CLOSED: If verification unavailable, reject
console.error('[SECURITY] Ed25519 verify unavailable:', error.message);
return false; // Reject signature when verification unavailable
}
},
// Merkle operations (pure JS)
merkle_root: (hashes) => {
return computeMerkleRootJS(hashes);
},
// Canonical JSON
canonical_json: (obj) => {
return canonicalizeJS(obj);
},
},
};
}
/**
* Pure JS Merkle root computation
*/
function computeMerkleRootJS(hashes) {
if (hashes.length === 0) return new Uint8Array(32);
if (hashes.length === 1) return hashes[0];
let level = [...hashes];
while (level.length > 1) {
const nextLevel = [];
for (let i = 0; i < level.length; i += 2) {
const left = level[i];
const right = level[i + 1] || left;
// Concatenate and hash
const combined = new Uint8Array(left.length + right.length);
combined.set(left, 0);
combined.set(right, left.length);
// Use sync hash for fallback
nextLevel.push(hashSync(combined));
}
level = nextLevel;
}
return level[0];
}
/**
* Synchronous hash for fallback (uses simple hash if crypto.subtle unavailable)
*/
function hashSync(data) {
// Simple FNV-1a hash for fallback (NOT cryptographically secure)
// In production, use a proper sync hash library
const FNV_PRIME = 0x01000193;
const FNV_OFFSET = 0x811c9dc5;
let hash = FNV_OFFSET;
for (let i = 0; i < data.length; i++) {
hash ^= data[i];
hash = Math.imul(hash, FNV_PRIME);
}
// Expand to 32 bytes (not secure, just for structure)
const result = new Uint8Array(32);
for (let i = 0; i < 32; i++) {
result[i] = (hash >> (i % 4) * 8) & 0xff;
hash = Math.imul(hash, FNV_PRIME);
}
return result;
}
/**
* Canonical JSON for JS fallback
*/
function canonicalizeJS(obj) {
if (obj === null || obj === undefined) return 'null';
if (typeof obj === 'boolean') return obj ? 'true' : 'false';
if (typeof obj === 'number') {
if (!Number.isFinite(obj)) throw new Error('Cannot canonicalize Infinity/NaN');
return JSON.stringify(obj);
}
if (typeof obj === 'string') {
return JSON.stringify(obj).replace(/[\u007f-\uffff]/g, (c) =>
'\\u' + ('0000' + c.charCodeAt(0).toString(16)).slice(-4)
);
}
if (Array.isArray(obj)) {
return '[' + obj.map(canonicalizeJS).join(',') + ']';
}
if (typeof obj === 'object') {
const keys = Object.keys(obj).sort();
const pairs = keys
.filter(k => obj[k] !== undefined)
.map(k => canonicalizeJS(k) + ':' + canonicalizeJS(obj[k]));
return '{' + pairs.join(',') + '}';
}
throw new Error(`Cannot canonicalize: ${typeof obj}`);
}
// ============================================================================
// WASM CRYPTO API
// ============================================================================
/**
* WASM-accelerated cryptographic operations
*/
export class WasmCrypto {
constructor() {
this.ready = false;
this.instance = null;
}
async init() {
this.instance = await initWasm();
this.ready = true;
return this;
}
/**
* SHA256 hash
*/
async sha256(data) {
if (!this.ready) await this.init();
const input = typeof data === 'string'
? new TextEncoder().encode(data)
: new Uint8Array(data);
if (this.instance.exports.sha256) {
return this.instance.exports.sha256(input);
}
// Fallback to SubtleCrypto
const hash = await crypto.subtle.digest('SHA-256', input);
return new Uint8Array(hash);
}
/**
* SHA256 as hex string
*/
async sha256Hex(data) {
const hash = await this.sha256(data);
return Array.from(hash).map(b => b.toString(16).padStart(2, '0')).join('');
}
/**
* Ed25519 sign
*/
async sign(message, privateKey) {
if (!this.ready) await this.init();
const msgBytes = typeof message === 'string'
? new TextEncoder().encode(message)
: new Uint8Array(message);
return this.instance.exports.ed25519_sign(msgBytes, privateKey);
}
/**
* Ed25519 verify
*/
async verify(message, signature, publicKey) {
if (!this.ready) await this.init();
const msgBytes = typeof message === 'string'
? new TextEncoder().encode(message)
: new Uint8Array(message);
return this.instance.exports.ed25519_verify(msgBytes, signature, publicKey);
}
/**
* Compute Merkle root from chunk hashes
*/
async merkleRoot(chunkHashes) {
if (!this.ready) await this.init();
if (this.instance.exports.merkle_root) {
return this.instance.exports.merkle_root(chunkHashes);
}
// JS fallback
return computeMerkleRootJS(chunkHashes);
}
/**
* Canonical JSON encoding
*/
canonicalize(obj) {
return canonicalizeJS(obj);
}
/**
* Hash canonical JSON
*/
async hashCanonical(obj) {
const canonical = this.canonicalize(obj);
return this.sha256Hex(canonical);
}
}
// ============================================================================
// WASM MODEL INFERENCE
// ============================================================================
/**
* WASM-accelerated model inference
*/
export class WasmInference {
constructor(options = {}) {
this.ready = false;
this.model = null;
this.crypto = new WasmCrypto();
this.useSIMD = options.useSIMD ?? true;
this.useThreads = options.useThreads ?? false;
}
async init() {
await this.crypto.init();
this.ready = true;
const caps = getPlatformCapabilities();
console.log(`[WASM Inference] Ready: SIMD=${caps.hasSIMD}, Threads=${caps.hasThreads}`);
return this;
}
/**
* Load ONNX model into WASM runtime
*/
async loadModel(modelData, manifest) {
if (!this.ready) await this.init();
// Verify model integrity first
const hash = await this.crypto.sha256Hex(modelData);
// Support both manifest formats: artifacts.model.sha256 and artifacts[0].sha256
const expected = manifest.artifacts?.model?.sha256 ||
manifest.artifacts?.[0]?.sha256 ||
manifest.model?.sha256;
if (expected && hash !== expected) {
throw new Error(`Model hash mismatch: ${hash} !== ${expected}`);
}
// In production, this would initialize ONNX runtime in WASM
// For now, we store the model data
this.model = {
data: modelData,
manifest,
loadedAt: Date.now(),
};
return this;
}
/**
* Run inference (placeholder for ONNX WASM runtime)
*/
async infer(input, options = {}) {
if (!this.model) {
throw new Error('No model loaded');
}
// In production, this would call ONNX WASM runtime
// For now, return placeholder
console.log('[WASM Inference] Would run inference on:', typeof input);
return {
output: null,
timeMs: 0,
platform: detectPlatform(),
};
}
/**
* Generate embeddings
*/
async embed(texts) {
if (!this.model) {
throw new Error('No model loaded');
}
const inputTexts = Array.isArray(texts) ? texts : [texts];
// Placeholder - in production, run through ONNX
const embeddings = inputTexts.map(text => {
// Generate deterministic pseudo-embedding from text hash
const hash = this.crypto.canonicalize(text);
const embedding = new Float32Array(384);
for (let i = 0; i < 384; i++) {
embedding[i] = (hash.charCodeAt(i % hash.length) - 64) / 64;
}
return embedding;
});
return {
embeddings,
model: this.model.manifest?.model?.id || 'unknown',
platform: detectPlatform(),
};
}
/**
* Unload model and free memory
*/
unload() {
this.model = null;
}
}
// ============================================================================
// GENESIS BIRTHING SYSTEM (WASM)
// ============================================================================
/**
* WASM-native network genesis/birthing system
*
* Creates new network instances with:
* - Cryptographic identity (Ed25519 keypair)
* - Lineage tracking (Merkle DAG)
* - Cross-platform compatibility
* - Cryptographic signing of genesis blocks
*/
export class WasmGenesis {
constructor(options = {}) {
this.crypto = new WasmCrypto();
this.ready = false;
// Genesis configuration
this.config = {
networkName: options.networkName || 'edge-net',
version: options.version || '1.0.0',
parentId: options.parentId || null,
traits: options.traits || {},
};
// Network keypair (generated during birth)
this.keypair = null;
}
async init() {
await this.crypto.init();
this.ready = true;
return this;
}
/**
* Generate Ed25519 keypair for network identity
* SECURITY: Uses WebCrypto for key generation
*/
async _generateKeypair() {
try {
const keyPair = await crypto.subtle.generateKey(
{ name: 'Ed25519' },
true, // extractable for export
['sign', 'verify']
);
// Export public key
const publicKeyRaw = await crypto.subtle.exportKey('raw', keyPair.publicKey);
return {
privateKey: keyPair.privateKey,
publicKey: keyPair.publicKey,
publicKeyBytes: new Uint8Array(publicKeyRaw),
publicKeyHex: Array.from(new Uint8Array(publicKeyRaw))
.map(b => b.toString(16).padStart(2, '0'))
.join(''),
};
} catch (error) {
throw new Error(`[SECURITY] Cannot generate Ed25519 keypair: ${error.message}. Native Ed25519 required for genesis.`);
}
}
/**
* Sign data with network private key
*/
async _signWithKeypair(data, keypair) {
const dataBytes = typeof data === 'string'
? new TextEncoder().encode(data)
: new Uint8Array(data);
try {
const signature = await crypto.subtle.sign(
{ name: 'Ed25519' },
keypair.privateKey,
dataBytes
);
return {
signature: new Uint8Array(signature),
signatureHex: Array.from(new Uint8Array(signature))
.map(b => b.toString(16).padStart(2, '0'))
.join(''),
};
} catch (error) {
throw new Error(`[SECURITY] Signing failed: ${error.message}`);
}
}
/**
* Birth a new network instance with cryptographic signing
*/
async birthNetwork(options = {}) {
if (!this.ready) await this.init();
const timestamp = Date.now();
// Generate network keypair
this.keypair = await this._generateKeypair();
// Generate network identity
const networkId = await this._generateNetworkId(timestamp);
// Create genesis block (unsigned payload)
const genesisBlock = {
networkId,
version: this.config.version,
birthTimestamp: timestamp,
parentId: this.config.parentId,
traits: {
...this.config.traits,
...options.traits,
},
capabilities: options.capabilities || ['embed', 'generate'],
platform: detectPlatform(),
platformCapabilities: getPlatformCapabilities(),
// Include public key for verification
publicKey: this.keypair.publicKeyHex,
keyAlgorithm: 'Ed25519',
};
// Compute canonical hash of genesis block
const genesisCanonical = this.crypto.canonicalize(genesisBlock);
const genesisHash = await this.crypto.sha256Hex(genesisCanonical);
// SECURITY: Sign the genesis hash with network keypair
const { signature, signatureHex } = await this._signWithKeypair(genesisHash, this.keypair);
// Create network manifest with signature
const manifest = {
schemaVersion: '2.0.0',
genesis: genesisBlock,
integrity: {
genesisHash,
signatureAlgorithm: 'Ed25519',
signature: signatureHex,
signedPayload: 'genesis',
merkleRoot: await this.crypto.merkleRoot([
await this.crypto.sha256(genesisCanonical),
]),
},
lineage: this.config.parentId ? {
parentId: this.config.parentId,
generation: options.generation || 1,
inheritedTraits: options.inheritedTraits || [],
} : null,
};
return {
networkId,
manifest,
genesisHash,
signature: signatureHex,
publicKey: this.keypair.publicKeyHex,
platform: detectPlatform(),
};
}
/**
* Generate unique network ID using cryptographic randomness
* SECURITY: Uses crypto.getRandomValues instead of Math.random()
*/
async _generateNetworkId(timestamp) {
// Generate 16 bytes of cryptographic randomness
const randomBytes = new Uint8Array(16);
crypto.getRandomValues(randomBytes);
const randomHex = Array.from(randomBytes)
.map(b => b.toString(16).padStart(2, '0'))
.join('');
const seed = `${this.config.networkName}:${timestamp}:${randomHex}`;
const hash = await this.crypto.sha256Hex(seed);
return `net_${hash.slice(0, 16)}`;
}
/**
* Verify a network's genesis signature
* SECURITY: Validates cryptographic signature of genesis block
*/
async verifyGenesis(manifest) {
const genesis = manifest.genesis;
const integrity = manifest.integrity;
if (!genesis.publicKey || !integrity.signature) {
return { valid: false, error: 'Missing public key or signature' };
}
try {
// Reconstruct the canonical hash
const genesisCanonical = this.crypto.canonicalize(genesis);
const genesisHash = await this.crypto.sha256Hex(genesisCanonical);
// Verify hash matches
if (genesisHash !== integrity.genesisHash) {
return { valid: false, error: 'Genesis hash mismatch' };
}
// Convert hex strings back to bytes
const publicKeyBytes = new Uint8Array(
genesis.publicKey.match(/.{2}/g).map(b => parseInt(b, 16))
);
const signatureBytes = new Uint8Array(
integrity.signature.match(/.{2}/g).map(b => parseInt(b, 16))
);
const hashBytes = new TextEncoder().encode(genesisHash);
// Import public key and verify
const publicKey = await crypto.subtle.importKey(
'raw',
publicKeyBytes,
{ name: 'Ed25519' },
false,
['verify']
);
const valid = await crypto.subtle.verify(
{ name: 'Ed25519' },
publicKey,
signatureBytes,
hashBytes
);
return { valid, genesisHash };
} catch (error) {
return { valid: false, error: `Verification failed: ${error.message}` };
}
}
/**
* Verify a network's lineage with cryptographic validation
*/
async verifyLineage(manifest, parentManifest = null) {
// First verify genesis signature
const genesisResult = await this.verifyGenesis(manifest);
if (!genesisResult.valid) {
return { valid: false, error: `Genesis invalid: ${genesisResult.error}` };
}
if (!manifest.lineage) {
return { valid: true, isRoot: true, genesisVerified: true };
}
if (!parentManifest) {
return { valid: false, error: 'Parent manifest required for lineage verification' };
}
// Verify parent genesis signature
const parentGenesisResult = await this.verifyGenesis(parentManifest);
if (!parentGenesisResult.valid) {
return { valid: false, error: `Parent genesis invalid: ${parentGenesisResult.error}` };
}
// Verify parent ID matches
if (manifest.lineage.parentId !== parentManifest.genesis.networkId) {
return { valid: false, error: 'Parent ID mismatch' };
}
// Verify generation is sequential
const parentGen = parentManifest.lineage?.generation || 0;
if (manifest.lineage.generation !== parentGen + 1) {
return { valid: false, error: 'Generation sequence broken' };
}
return {
valid: true,
parentId: manifest.lineage.parentId,
generation: manifest.lineage.generation,
genesisVerified: true,
parentVerified: true,
};
}
/**
* Create a child network (reproduction)
*/
async reproduce(parentManifest, options = {}) {
if (!this.ready) await this.init();
// Mutate traits from parent
const mutatedTraits = this._mutateTraits(
parentManifest.genesis.traits,
options.mutationRate || 0.1
);
// Birth child network
const child = await this.birthNetwork({
traits: mutatedTraits,
capabilities: options.capabilities || parentManifest.genesis.capabilities,
generation: (parentManifest.lineage?.generation || 0) + 1,
inheritedTraits: Object.keys(parentManifest.genesis.traits),
});
// Update config for lineage
child.manifest.lineage = {
parentId: parentManifest.genesis.networkId,
generation: (parentManifest.lineage?.generation || 0) + 1,
inheritedTraits: Object.keys(parentManifest.genesis.traits),
mutatedTraits: Object.keys(mutatedTraits).filter(
k => mutatedTraits[k] !== parentManifest.genesis.traits[k]
),
};
return child;
}
/**
* Mutate traits for evolution using cryptographic randomness
* SECURITY: Uses crypto.getRandomValues for unpredictable mutations
*/
_mutateTraits(parentTraits, mutationRate) {
const mutated = { ...parentTraits };
// Generate random bytes for mutation decisions
const randomBytes = new Uint8Array(Object.keys(mutated).length * 2);
crypto.getRandomValues(randomBytes);
let idx = 0;
for (const [key, value] of Object.entries(mutated)) {
// Use crypto random for mutation probability check
const shouldMutate = (randomBytes[idx++] / 255) < mutationRate;
if (typeof value === 'number' && shouldMutate) {
// Use crypto random for mutation amount (+/- 10%)
const mutationFactor = ((randomBytes[idx++] / 255) - 0.5) * 0.2;
mutated[key] = value * (1 + mutationFactor);
} else {
idx++; // Skip unused random byte
}
}
return mutated;
}
}
// ============================================================================
// SINGLETON INSTANCES
// ============================================================================
let cryptoInstance = null;
let genesisInstance = null;
export async function getCrypto() {
if (!cryptoInstance) {
cryptoInstance = new WasmCrypto();
await cryptoInstance.init();
}
return cryptoInstance;
}
export async function getGenesis(options = {}) {
if (!genesisInstance) {
genesisInstance = new WasmGenesis(options);
await genesisInstance.init();
}
return genesisInstance;
}
// ============================================================================
// EXPORTS
// ============================================================================
export default {
detectPlatform,
getPlatformCapabilities,
initWasm,
WasmCrypto,
WasmInference,
WasmGenesis,
getCrypto,
getGenesis,
};