/** * WASM Loader - Loads and manages WebAssembly modules * Provides a bridge between JavaScript/TypeScript and compiled WASM * * Optimizations: * - Singleton pattern with module caching * - Streaming compilation in browsers (WebAssembly.instantiateStreaming) * - Memory pooling for frequent allocations * - Compiled module caching for faster re-instantiation * - Configurable size thresholds for JS fallback * * Security: * - Optional SHA-384 integrity verification against a sibling * `wasm-manifest.json`. See `./integrity.ts`. When the manifest is * present any tampered .wasm payload is rejected before instantiation. */ import type { LoadingMetrics } from '@danielsimonjr/mathts-core/internal'; export type { LoadingMetrics }; /** Exports of the WebAssembly module that the loader uses: kernels and memory helpers. */ export interface WasmModule { multiplyDense: (aPtr: number, aRows: number, aCols: number, bPtr: number, bRows: number, bCols: number, resultPtr: number) => void; multiplyDenseSIMD: (aPtr: number, aRows: number, aCols: number, bPtr: number, bRows: number, bCols: number, resultPtr: number) => void; multiplyVector: (aPtr: number, aRows: number, aCols: number, xPtr: number, resultPtr: number) => void; transpose: (dataPtr: number, rows: number, cols: number, resultPtr: number) => void; add: (aPtr: number, bPtr: number, size: number, resultPtr: number) => void; subtract: (aPtr: number, bPtr: number, size: number, resultPtr: number) => void; scalarMultiply: (aPtr: number, scalar: number, size: number, resultPtr: number) => void; dotProduct: (aPtr: number, bPtr: number, size: number) => number; luDecomposition: (aPtr: number, n: number, permPtr: number) => number; qrDecomposition: (aPtr: number, m: number, n: number, qPtr: number) => void; choleskyDecomposition: (aPtr: number, n: number, lPtr: number) => number; schur: (aPtr: number, n: number, maxIter: number, tol: number, qPtr: number, tPtr: number, workPtr: number) => number; luSolve: (luPtr: number, n: number, permPtr: number, bPtr: number, xPtr: number) => void; luDeterminant: (luPtr: number, n: number, permPtr: number) => number; laDet: (aPtr: number, n: number, workPtr: number) => number; laInv: (aPtr: number, n: number, resultPtr: number, workPtr: number) => number; laInv2x2: (aPtr: number, resultPtr: number) => number; laInv3x3: (aPtr: number, resultPtr: number) => number; laCond1: (aPtr: number, n: number, workPtr: number) => number; laCondInf: (aPtr: number, n: number, workPtr: number) => number; laKron: (aPtr: number, aRows: number, aCols: number, bPtr: number, bRows: number, bCols: number) => number; laDot: (aPtr: number, bPtr: number, n: number) => number; laCross: (aPtr: number, bPtr: number) => number; laNorm2: (xPtr: number, n: number) => number; laSolve: (aPtr: number, bPtr: number, n: number, resultPtr: number, workPtr: number) => number; laLsolve: (lPtr: number, bPtr: number, n: number, resultPtr: number) => number; laUsolve: (uPtr: number, bPtr: number, n: number, resultPtr: number) => number; eigsSymmetric: (matrixPtr: number, n: number, precision: number, eigenvaluesPtr: number, eigenvectorsPtr: number, workPtr: number) => number; powerIteration: (matrixPtr: number, n: number, eigenvaluePtr: number, eigenvectorPtr: number, workPtr: number, maxIterations: number, tolerance: number) => number; spectralRadius: (matrixPtr: number, n: number, workPtr: number, maxIterations: number, tolerance: number) => number; inverseIteration: (matrixPtr: number, n: number, shift: number, eigenvectorPtr: number, workPtr: number, maxIterations: number, tolerance: number) => number; balanceMatrix: (matrixPtr: number, n: number, scalePtr: number, transformPtr: number) => void; reduceToHessenberg: (matrixPtr: number, n: number, transformPtr: number) => void; eigenvalues2x2: (a: number, b: number, c: number, d: number, realPtr: number, imagPtr: number) => void; qrIterationStep: (matrixPtr: number, n: number, workPtr: number, shift: number) => void; qrAlgorithm: (matrixPtr: number, n: number, eigenvaluesRealPtr: number, eigenvaluesImagPtr: number, workPtr: number, maxIterations: number, tolerance: number) => number; hessenbergQRStep: (matrixPtr: number, n: number, startRow: number, endRow: number, shift: number) => void; expm: (matrixPtr: number, n: number, resultPtr: number, workPtr: number) => number; expmSmall: (matrixPtr: number, n: number, resultPtr: number, workPtr: number, terms: number) => void; expmv: (matrixPtr: number, n: number, vectorPtr: number, resultPtr: number, workPtr: number, t: number) => void; sqrtm: (matrixPtr: number, n: number, resultPtr: number, tolerance: number, maxIterations: number, workPtr: number) => number; sqrtmNewtonSchulz: (matrixPtr: number, n: number, resultPtr: number, workPtr: number, maxIterations: number, tolerance: number) => number; sqrtmCholesky: (matrixPtr: number, n: number, resultPtr: number, workPtr: number) => number; sparseLu: (valuesPtr: number, rowIndPtr: number, colPtrPtr: number, n: number, nnz: number, lValuesPtr: number, lRowIndPtr: number, lColPtrPtr: number, uValuesPtr: number, uRowIndPtr: number, uColPtrPtr: number, permPtr: number, workPtr: number) => number; sparseForwardSolve: (lValuesPtr: number, lRowIndPtr: number, lColPtrPtr: number, n: number, bPtr: number, xPtr: number) => void; sparseBackwardSolve: (uValuesPtr: number, uRowIndPtr: number, uColPtrPtr: number, n: number, bPtr: number, xPtr: number) => void; sparseLuSolve: (lValuesPtr: number, lRowIndPtr: number, lColPtrPtr: number, uValuesPtr: number, uRowIndPtr: number, uColPtrPtr: number, n: number, permPtr: number, bPtr: number, xPtr: number, workPtr: number) => void; sparseChol: (valuesPtr: number, rowIndPtr: number, colPtrPtr: number, n: number, nnz: number, lValuesPtr: number, lRowIndPtr: number, lColPtrPtr: number, parentPtr: number, workPtr: number) => number; sparseCholSolve: (lValuesPtr: number, lRowIndPtr: number, lColPtrPtr: number, n: number, bPtr: number, xPtr: number, workPtr: number) => void; eliminationTree: (rowIndPtr: number, colPtrPtr: number, n: number, parentPtr: number) => void; columnCounts: (rowIndPtr: number, colPtrPtr: number, n: number, parentPtr: number, countsPtr: number, workPtr: number) => void; amd: (colPtrPtr: number, rowIdxPtr: number, n: number, permPtr: number, workPtr: number) => void; amdAggressive: (colPtrPtr: number, rowIdxPtr: number, n: number, permPtr: number, workPtr: number) => void; symbolicCholesky: (indexPtr: number, ptrPtr: number, n: number, parentPtr: number, postPtr: number, colCountPtr: number, workPtr: number) => void; simdDotF64: (aPtr: number, bPtr: number, length: number) => number; simdSumF64: (aPtr: number, length: number) => number; simdSumSquaresF64: (aPtr: number, length: number) => number; simdNormF64: (aPtr: number, length: number) => number; simdMinF64: (aPtr: number, length: number) => number; simdMaxF64: (aPtr: number, length: number) => number; simdMeanF64: (aPtr: number, length: number) => number; simdVarianceF64: (aPtr: number, length: number, ddof: number) => number; simdStdF64: (aPtr: number, length: number, ddof: number) => number; simdAddF64: (aPtr: number, bPtr: number, resultPtr: number, length: number) => void; simdSubF64: (aPtr: number, bPtr: number, resultPtr: number, length: number) => void; simdMulF64: (aPtr: number, bPtr: number, resultPtr: number, length: number) => void; simdScaleF64: (aPtr: number, scalar: number, resultPtr: number, length: number) => void; simdAbsF64: (aPtr: number, resultPtr: number, length: number) => void; simdMatMulF64: (aPtr: number, bPtr: number, cPtr: number, m: number, k: number, n: number) => void; gcdArray: (aPtr: number, n: number) => number; hypotArray: (aPtr: number, n: number) => number; norm1: (aPtr: number, n: number) => number; norm2: (aPtr: number, n: number) => number; normInf: (aPtr: number, n: number) => number; normP: (aPtr: number, n: number, p: number) => number; erfArray: (aPtr: number, n: number, resultPtr: number) => void; zetaArray: (aPtr: number, n: number, resultPtr: number) => void; gammaArray: (aPtr: number, n: number, resultPtr: number) => void; lgammaArray: (aPtr: number, n: number, resultPtr: number) => void; lgamma_f64: (xsPtr: number, n: number, outPtr: number) => number; partitionSelect: (dataPtr: number, n: number, k: number, workPtr: number) => number; distanceND: (p1Ptr: number, p2Ptr: number, n: number) => number; distance2D: (x1: number, y1: number, x2: number, y2: number) => number; distance3D: (x1: number, y1: number, z1: number, x2: number, y2: number, z2: number) => number; intersect2DLines: (x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number, resultPtr: number) => void; intersect2DInfiniteLines: (x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number, resultPtr: number) => void; distancePointToLine2D: (px: number, py: number, x1: number, y1: number, x2: number, y2: number) => number; statsMean: (aPtr: number, n: number) => number; statsMedian: (aPtr: number, n: number) => number; statsSum: (aPtr: number, n: number) => number; statsProd: (aPtr: number, n: number) => number; statsMin: (aPtr: number, n: number) => number; statsMax: (aPtr: number, n: number) => number; statsCumsum: (aPtr: number, n: number) => void; statsMad: (aPtr: number, n: number) => number; statsCorrelation: (aPtr: number, bPtr: number, n: number) => number; statsCovariance: (aPtr: number, bPtr: number, n: number, ddof: number) => number; dct_wasm: (inPtr: number, outPtr: number, n: number) => void; idct_wasm: (inPtr: number, outPtr: number, n: number) => void; dst_wasm: (inPtr: number, outPtr: number, n: number) => void; idst_wasm: (inPtr: number, outPtr: number, n: number) => void; dwt_wasm: (inPtr: number, approxPtr: number, detailPtr: number, n: number) => void; hilbert_wasm: (inRe: number, inIm: number, outRe: number, outIm: number, n: number) => void; spectrogram_wasm: (inPtr: number, outPtr: number, n: number, windowSize: number, hop: number) => number; periodogram_wasm: (inPtr: number, outPtr: number, n: number) => void; fir_filter_wasm: (inPtr: number, coeffsPtr: number, outPtr: number, n: number, numCoeffs: number) => void; freqz: (bPtr: number, bLen: number, aPtr: number, aLen: number, wPtr: number, wLen: number, hRealPtr: number, hImagPtr: number) => void; fft: (dataPtr: number, n: number, inverse: number) => void; fft2d: (dataPtr: number, rows: number, cols: number, inverse: number) => void; convolve: (signalPtr: number, n: number, kernelPtr: number, m: number, resultPtr: number) => void; rfft: (dataPtr: number, n: number, resultPtr: number) => void; irfft: (dataPtr: number, n: number, resultPtr: number) => void; isPowerOf2: (n: number) => number; vectorAdd: (aPtr: number, bPtr: number, n: number, resultPtr: number) => void; vectorScale: (aPtr: number, scalar: number, n: number, resultPtr: number) => void; vectorCopy: (srcPtr: number, n: number, dstPtr: number) => void; maxError: (errorPtr: number, n: number) => number; computeStepAdjustment: (maxErr: number, tol: number, order: number, minDelta: number, maxDelta: number) => number; rk45Step: (yPtr: number, t: number, h: number, n: number, kPtr: number, yNextPtr: number, yErrorPtr: number) => void; rk23Step: (yPtr: number, t: number, h: number, n: number, kPtr: number, yNextPtr: number, yErrorPtr: number) => void; minimize_quadratic_wasm: (hPtr: number, fPtr: number, n: number, xPtr: number) => number; least_squares_wasm: (aPtr: number, bPtr: number, m: number, n: number, xPtr: number) => number; levenberg_marquardt_wasm: (jPtr: number, rPtr: number, m: number, n: number, dpPtr: number, lambda: number) => void; condition_number_wasm: (aPtr: number, n: number) => number; matrix_rank_wasm: (aPtr: number, m: number, n: number, tol: number) => number; bezier_eval_wasm: (ctrlPtr: number, nPoints: number, dims: number, t: number, resultPtr: number) => void; bspline_eval_wasm: (ctrlPtr: number, nPoints: number, degree: number, t: number, resultPtr: number) => void; loess_wasm: (xsPtr: number, ysPtr: number, n: number, x: number, bandwidth: number) => number; rbf_interp_wasm: (pointsPtr: number, valuesPtr: number, n: number, dims: number, xiPtr: number, ni: number, resultPtr: number) => void; griddata_wasm: (pointsPtr: number, valuesPtr: number, n: number, xiPtr: number, yiPtr: number, ni: number, resultPtr: number) => void; implicit_euler_step_wasm: (yPtr: number, fPtr: number, jPtr: number, h: number, n: number, resultPtr: number) => void; ode_system_rk4_step_wasm: (yPtr: number, kPtrs: number, h: number, n: number, resultPtr: number) => void; delaunay_wasm: (ptsPtr: number, n: number, trisPtr: number) => number; voronoi_wasm: (ptsPtr: number, n: number, boundsPtr: number, vertsPtr: number, edgesPtr: number, maxVerts: number, maxEdges: number) => number; kdtree_build_wasm: (ptsPtr: number, n: number, dims: number, treePtr: number) => number; kdtree_nearest_wasm: (treePtr: number, queryPtr: number, dims: number, treeSize: number) => number; convex_hull_3d_wasm: (ptsPtr: number, nPts: number, facesPtr: number, maxFaces: number) => number; bitAndArray?: (aPtr: number, bPtr: number, resultPtr: number, length: number) => void; bitOrArray?: (aPtr: number, bPtr: number, resultPtr: number, length: number) => void; bitXorArray?: (aPtr: number, bPtr: number, resultPtr: number, length: number) => void; bitNotArray?: (inputPtr: number, resultPtr: number, length: number) => void; leftShiftArrayPerElement?: (aPtr: number, bPtr: number, resultPtr: number, length: number) => void; rightArithShiftArrayPerElement?: (aPtr: number, bPtr: number, resultPtr: number, length: number) => void; rightLogShiftArrayPerElement?: (aPtr: number, bPtr: number, resultPtr: number, length: number) => void; bitAnd_i32_array?: (a: Int32Array, b: Int32Array, result: Int32Array) => void; bitOr_i32_array?: (a: Int32Array, b: Int32Array, result: Int32Array) => void; bitXor_i32_array?: (a: Int32Array, b: Int32Array, result: Int32Array) => void; bitNot_i32_array?: (a: Int32Array, result: Int32Array) => void; leftShift_i32_array?: (a: Int32Array, b: Int32Array, result: Int32Array) => void; rightArithShift_i32_array?: (a: Int32Array, b: Int32Array, result: Int32Array) => void; rightLogShift_i32_array?: (a: Int32Array, b: Int32Array, result: Int32Array) => void; poly_mul_f64?: (aPtr: number, aLen: number, bPtr: number, bLen: number, outPtr: number) => number; poly_div_mod_f64?: (numPtr: number, numLen: number, denPtr: number, denLen: number, outPtr: number) => number; poly_resultant_f64?: (pPtr: number, pLen: number, qPtr: number, qLen: number) => number; poly_discriminant_f64?: (pPtr: number, pLen: number) => number; poly_fit_f64?: (xsPtr: number, ysPtr: number, n: number, degree: number, outPtr: number) => number; cheb_fit_f64?: (xsPtr: number, ysPtr: number, n: number, degree: number, outPtr: number) => number; legendre_fit_f64?: (xsPtr: number, ysPtr: number, n: number, degree: number, outPtr: number) => number; tridiag_solve_f64?: (diagPtr: number, lowerPtr: number, upperPtr: number, rhsPtr: number, n: number, outPtr: number) => number; divided_difference_f64?: (xsPtr: number, ysPtr: number, n: number, outPtr: number) => number; bessel_j0_f64?: (xsPtr: number, n: number, outPtr: number) => number; bessel_j1_f64?: (xsPtr: number, n: number, outPtr: number) => number; bessel_j_f64?: (order: number, xsPtr: number, nElems: number, outPtr: number) => number; bessel_y0_f64?: (xsPtr: number, n: number, outPtr: number) => number; bessel_y1_f64?: (xsPtr: number, n: number, outPtr: number) => number; bessel_y_f64?: (order: number, xsPtr: number, nElems: number, outPtr: number) => number; airy_ai_f64?: (xsPtr: number, n: number, outPtr: number) => number; airy_bi_f64?: (xsPtr: number, n: number, outPtr: number) => number; elliptic_k_f64?: (msPtr: number, n: number, outPtr: number) => number; elliptic_e_f64?: (msPtr: number, n: number, outPtr: number) => number; carlson_rc_f64?: (xsPtr: number, ysPtr: number, n: number, outPtr: number) => number; carlson_rf_f64?: (xsPtr: number, ysPtr: number, zsPtr: number, n: number, outPtr: number) => number; carlson_rd_f64?: (xsPtr: number, ysPtr: number, zsPtr: number, n: number, outPtr: number) => number; carlson_rj_f64?: (xsPtr: number, ysPtr: number, zsPtr: number, psPtr: number, n: number, outPtr: number) => number; elliptic_f_incomplete_f64?: (phisPtr: number, msPtr: number, n: number, outPtr: number) => number; elliptic_e_incomplete_f64?: (phisPtr: number, msPtr: number, n: number, outPtr: number) => number; elliptic_pi_incomplete_f64?: (nsPtr: number, phisPtr: number, msPtr: number, n: number, outPtr: number) => number; apply_window_f64?: (samplesPtr: number, n: number, windowType: number) => number; welch_psd_f64?: (samplesPtr: number, n: number, frameLength: number, overlap: number, windowType: number, outPtr: number) => number; bartlett_psd_f64?: (samplesPtr: number, n: number, frameLength: number, outPtr: number) => number; goertzel_f64?: (samplesPtr: number, n: number, targetFreq: number, sampleRate: number) => number; chirp_z_transform_f64?: (samplesPtr: number, n: number, m: number, phiStartRe: number, phiStartIm: number, phiStepRe: number, phiStepIm: number, outRePtr: number, outImPtr: number) => number; sort_f64?: (ptr: number, n: number) => number; argsort_f64?: (dataPtr: number, n: number, outPtr: number) => number; rank_f64?: (dataPtr: number, n: number, outPtr: number) => number; matrix_lu_decompose?: (aHdr: number, n: number, lOutHdr: number, uOutHdr: number, permOutHdr: number) => number; matrix_qr_decompose?: (aHdr: number, m: number, n: number, qOutHdr: number, rOutHdr: number) => number; matrix_cholesky?: (aHdr: number, n: number, lOutHdr: number) => number; matrix_inverse?: (aHdr: number, n: number, resultHdr: number, workHdr: number) => number; matrix_determinant?: (aHdr: number, n: number, workHdr: number) => number; __new: (size: number, id: number) => number; __pin: (ptr: number) => number; __unpin: (ptr: number) => void; __collect: () => void; memory: WebAssembly.Memory; } /** * Load the WebAssembly module and manage its memory. * * Use `getInstance` to get the one shared loader. */ export declare class WasmLoader { private static instance; private wasmModule; private compiledModule; private loading; private isNode; private lastMetrics; private float64Pool; private int32Pool; private readonly poolSizeThreshold; private constructor(); static getInstance(): WasmLoader; /** * Load the WASM module */ load(wasmPath?: string): Promise; /** * Precompile the WASM module without instantiation * Useful for build-time or startup optimization */ precompile(wasmPath?: string): Promise; private loadModule; /** * Get the WASM binary path. * * AssemblyScript is the sole WASM backend (`mathts-as.wasm`); the legacy * native WASM toolchain was removed (migration complete 2026-06-26). * * Returns an async result because the Node branch dynamically imports * `node:url` (fileURLToPath) so the path is resolved relative to this * source file's location rather than process.cwd(). The browser branch * probes candidate URLs with `fetch(..., { method: 'HEAD' })` for the same * reason Node walks the filesystem — see {@link resolveBrowserWasm}. */ private getDefaultWasmPath; private loadNodeWasm; private loadBrowserWasm; private getImports; /** * Get the loaded WASM module */ getModule(): WasmModule | null; /** * Get the compiled WASM module (for caching/serialization) */ getCompiledModule(): WebAssembly.Module | null; /** * Check if WASM is loaded */ isLoaded(): boolean; /** * Check if WASM is precompiled */ isPrecompiled(): boolean; /** * Get loading performance metrics */ getLoadingMetrics(): LoadingMetrics | null; /** * Allocate Float64Array in WASM memory * Uses memory pooling for frequently reused sizes */ allocateFloat64Array(data: number[] | Float64Array): { ptr: number; array: Float64Array; }; /** * Allocate Float64Array without copying data (for output buffers) */ allocateFloat64ArrayEmpty(length: number): { ptr: number; array: Float64Array; }; /** * Allocate Int32Array in WASM memory * Uses memory pooling for frequently reused sizes */ allocateInt32Array(data: number[] | Int32Array): { ptr: number; array: Int32Array; }; /** * Allocate Int32Array without copying data (for output buffers) */ allocateInt32ArrayEmpty(length: number): { ptr: number; array: Int32Array; }; /** * Get a suitable entry from the memory pool */ private getFromPool; /** * Return allocation to pool for reuse */ release(ptr: number, isFloat64?: boolean): void; /** * Free allocated memory (immediate, bypasses pool) */ free(ptr: number): void; /** * Clear the memory pool */ clearPool(): void; /** * Get pool statistics */ getPoolStats(): { float64: { total: number; inUse: number; totalBytes: number; }; int32: { total: number; inUse: number; totalBytes: number; }; }; /** * Run garbage collection */ collect(): void; /** * Reset the loader (for testing) */ reset(): void; } /** * Global WASM loader instance */ export declare const wasmLoader: WasmLoader; //# sourceMappingURL=WasmLoader.d.ts.map