diff --git a/packages/komodo_defi_framework/web/res/kdflib_bootstrapper.js b/packages/komodo_defi_framework/web/res/kdflib_bootstrapper.js index 9c92413cf..d39e70ef7 100644 --- a/packages/komodo_defi_framework/web/res/kdflib_bootstrapper.js +++ b/packages/komodo_defi_framework/web/res/kdflib_bootstrapper.js @@ -1,6 +1,7 @@ // @ts-check import init, { LogLevel } from "../kdf/bin/kdflib.js"; import * as kdflib from "../kdf/bin/kdflib.js"; +import { loadCompressedWasm } from "./wasm_loader.js"; const LOG_LEVEL = LogLevel.Info; @@ -42,7 +43,11 @@ kdf.init_wasm = async function () { } kdf._isInitializing = true; - kdf._initPromise = init() + const gzipWasmBinPath = "../kdf/bin/kdflib_bg.wasm.gz" + const gzipKdfBinUrl = new URL(gzipWasmBinPath, import.meta.url); + const kdfBinBuffer = await loadCompressedWasm(gzipKdfBinUrl); + + kdf._initPromise = init(kdfBinBuffer) .then(() => { kdf._isInitializing = false; kdf._initPromise = null; diff --git a/packages/komodo_defi_framework/web/res/wasm_loader.js b/packages/komodo_defi_framework/web/res/wasm_loader.js new file mode 100644 index 000000000..bbeb76b7e --- /dev/null +++ b/packages/komodo_defi_framework/web/res/wasm_loader.js @@ -0,0 +1,66 @@ +export async function loadCompressedWasm(url) { + try { + // Fetch the compressed WASM file + const response = await fetch(url.toString(), { + method: 'GET', + cache: 'force-cache', // Use cache if available + }); + + if (!response.ok) { + throw new Error( + `Failed to fetch compressed WASM: ${response.status} ${response.statusText}` + ); + } + + // Check if browser supports DecompressionStream + if (!('DecompressionStream' in globalThis)) { + throw new Error( + 'Browser does not support DecompressionStream API. Please use a modern browser.' + ); + } + + // Ensure response.body is available + if (!response.body) { + throw new Error( + 'Response body is not available. Streaming not supported or body already consumed.' + ); + } + + // Create a decompression stream for gzip + const decompressionStream = new DecompressionStream('gzip'); + + // Pipe the response through the decompression stream + const decompressedStream = response.body.pipeThrough(decompressionStream); + + // Read the decompressed stream into an ArrayBuffer + const reader = decompressedStream.getReader(); + const chunks = []; + + while (true) { + const { done, value } = await reader.read(); + if (done) break; + chunks.push(value); + } + + // Combine all chunks into a single ArrayBuffer + const totalLength = chunks.reduce((acc, chunk) => acc + chunk.length, 0); + const result = new Uint8Array(totalLength); + let offset = 0; + + for (const chunk of chunks) { + result.set(chunk, offset); + offset += chunk.length; + } + + //console.log(`WASM decompressed: ${(totalLength / 1024 / 1024).toFixed(2)} MB`); + + return result.buffer; + } catch (error) { + console.error('Failed to load compressed WASM:', error); + throw error; + } +} + +export function supportsGzipDecompression() { + return 'DecompressionStream' in globalThis; +} \ No newline at end of file diff --git a/packages/komodo_wallet_build_transformer/lib/src/steps/copy_platform_assets_build_step.dart b/packages/komodo_wallet_build_transformer/lib/src/steps/copy_platform_assets_build_step.dart index a215f309c..5518fc3de 100644 --- a/packages/komodo_wallet_build_transformer/lib/src/steps/copy_platform_assets_build_step.dart +++ b/packages/komodo_wallet_build_transformer/lib/src/steps/copy_platform_assets_build_step.dart @@ -140,7 +140,6 @@ class CopyPlatformAssetsBuildStep extends BuildStep { await for (final entity in sourceDir.list(recursive: true)) { if (entity is File) { final relativePath = path.relative(entity.path, from: sourceDir.path); - final destFile = File(path.join(destDir.path, relativePath)); if (skipDir != null && path.isWithin( @@ -151,13 +150,44 @@ class CopyPlatformAssetsBuildStep extends BuildStep { continue; } - if (!destFile.parent.existsSync()) { - destFile.parent.createSync(recursive: true); + // Check if this is a WASM file that needs compression + if (path.basename(entity.path) == 'kdflib_bg.wasm') { + // Compress and save as .wasm.gz + final destFile = File(path.join(destDir.path, relativePath + '.gz')); + + if (!destFile.parent.existsSync()) { + destFile.parent.createSync(recursive: true); + } + if (destFile.existsSync()) { + destFile.deleteSync(); + } + + // Read, compress, and write + final wasmBytes = await entity.readAsBytes(); + final originalSize = wasmBytes.length; + final compressedBytes = gzip.encode(wasmBytes); + final compressedSize = compressedBytes.length; + await destFile.writeAsBytes(compressedBytes); + + final compressionRatio = + ((originalSize - compressedSize) / originalSize * 100).toStringAsFixed(1); + _log.info( + 'Compressed kdflib_bg.wasm during copy: ' + '${originalSize} bytes -> ${compressedSize} bytes ' + '($compressionRatio% reduction)', + ); + } else { + // Normal file copy + final destFile = File(path.join(destDir.path, relativePath)); + + if (!destFile.parent.existsSync()) { + destFile.parent.createSync(recursive: true); + } + if (destFile.existsSync()) { + destFile.deleteSync(); + } + entity.copySync(destFile.path); } - if (destFile.existsSync()) { - destFile.deleteSync(); - } - entity.copySync(destFile.path); } } _log.info(