Skip to content

Commit bafb432

Browse files
fix: update WASM loading logic to use Vite-resolved URL and improve error handling
1 parent d0a43d4 commit bafb432

3 files changed

Lines changed: 29 additions & 41 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/// <reference types="vite/client" />
2+
3+
declare module '*.wasm?url' {
4+
const url: string;
5+
export default url;
6+
}

examples/react-demo/src/wasmLoader.ts

Lines changed: 22 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
/* eslint-disable @typescript-eslint/no-explicit-any */
22

3+
// Import WASM as URL - Vite handles asset resolution across all environments
4+
import wasmUrl from './compute.wasm?url';
5+
36
interface WasmImports {
47
env?: Record<string, unknown>;
58
}
@@ -77,50 +80,29 @@ export async function loadWasm(): Promise<WasmExports> {
7780
}
7881

7982
loadingPromise = (async () => {
80-
// Try multiple paths to handle different environments (local dev, StackBlitz, production)
81-
const possiblePaths = [
82-
'/compute.wasm',
83-
'./compute.wasm',
84-
new URL('/compute.wasm', import.meta.url).href,
85-
];
86-
87-
let arrayBuffer: ArrayBuffer | null = null;
88-
let lastError: string = '';
89-
90-
for (const wasmUrl of possiblePaths) {
91-
try {
92-
const res = await fetch(wasmUrl);
93-
if (!res.ok) {
94-
lastError = `${wasmUrl}: ${res.status} ${res.statusText}`;
95-
continue;
96-
}
97-
98-
const buffer = await res.arrayBuffer();
99-
// Check for WASM magic number (0x00 0x61 0x73 0x6D = "\0asm")
100-
const magic = new Uint8Array(buffer.slice(0, 4));
101-
if (
102-
magic[0] === 0x00 &&
103-
magic[1] === 0x61 &&
104-
magic[2] === 0x73 &&
105-
magic[3] === 0x6d
106-
) {
107-
arrayBuffer = buffer;
108-
break;
109-
} else {
110-
lastError = `${wasmUrl}: Invalid WASM (got ${Array.from(magic)
111-
.map((b) => b.toString(16))
112-
.join(' ')})`;
113-
}
114-
} catch (e) {
115-
lastError = `${wasmUrl}: ${(e as Error).message}`;
116-
}
83+
// Use the Vite-resolved WASM URL (works in StackBlitz and local dev)
84+
const res = await fetch(wasmUrl);
85+
if (!res.ok) {
86+
throw new Error(`Failed to fetch WASM: ${res.status} ${res.statusText}`);
11787
}
11888

119-
if (!arrayBuffer) {
120-
throw new Error(`Failed to fetch WASM from any path. Last error: ${lastError}`);
89+
const buffer = await res.arrayBuffer();
90+
// Verify WASM magic number (0x00 0x61 0x73 0x6D = "\0asm")
91+
const magic = new Uint8Array(buffer.slice(0, 4));
92+
if (
93+
magic[0] !== 0x00 ||
94+
magic[1] !== 0x61 ||
95+
magic[2] !== 0x73 ||
96+
magic[3] !== 0x6d
97+
) {
98+
throw new Error(
99+
`Invalid WASM file (got ${Array.from(magic)
100+
.map((b) => b.toString(16).padStart(2, '0'))
101+
.join(' ')})`
102+
);
121103
}
122104

123-
const module = await WebAssembly.compile(arrayBuffer);
105+
const module = await WebAssembly.compile(buffer);
124106
cachedExports = await instantiate(module, {});
125107
return cachedExports;
126108
})();

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
],
1111
"scripts": {
1212
"build": "npm run build:wasm && npm run build:core && npm run build:react && npm run build:react-query && npm run build:examples",
13-
"build:wasm": "asc compute/index.ts --outFile examples/react-demo/public/compute.wasm --bindings esm --optimize",
13+
"build:wasm": "asc compute/index.ts --outFile examples/react-demo/src/compute.wasm --bindings esm --optimize",
1414
"build:core": "npm run build -w @computekit/core",
1515
"build:react": "npm run build -w @computekit/react",
1616
"build:react-query": "npm run build -w @computekit/react-query",

0 commit comments

Comments
 (0)