Skip to content

Commit 28f1847

Browse files
Include WASM file for StackBlitz
1 parent bafb432 commit 28f1847

7 files changed

Lines changed: 333 additions & 12 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ build/
88
*.wasm
99
*.wasm.map
1010

11+
# But include the demo WASM file for StackBlitz
12+
!examples/react-demo/public/compute.wasm
13+
1114
# IDE
1215
.idea/
1316
.vscode/
9.48 KB
Binary file not shown.
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/** Exported memory */
2+
export declare const memory: WebAssembly.Memory;
3+
/**
4+
* compute/sum/sum
5+
* @param arr `~lib/typedarray/Int32Array`
6+
* @returns `i32`
7+
*/
8+
export declare function sum(arr: Int32Array): number;
9+
/**
10+
* compute/sum/sumFloat
11+
* @param arr `~lib/typedarray/Float64Array`
12+
* @returns `f64`
13+
*/
14+
export declare function sumFloat(arr: Float64Array): number;
15+
/**
16+
* compute/sum/average
17+
* @param arr `~lib/typedarray/Int32Array`
18+
* @returns `f64`
19+
*/
20+
export declare function average(arr: Int32Array): number;
21+
/**
22+
* compute/fibonacci/fibonacci
23+
* @param n `i32`
24+
* @returns `i64`
25+
*/
26+
export declare function fibonacci(n: number): bigint;
27+
/**
28+
* compute/fibonacci/fibonacciSequence
29+
* @param n `i32`
30+
* @returns `~lib/typedarray/Int64Array`
31+
*/
32+
export declare function fibonacciSequence(n: number): BigInt64Array;
33+
/**
34+
* compute/fibonacci/isFibonacci
35+
* @param num `i64`
36+
* @returns `bool`
37+
*/
38+
export declare function isFibonacci(num: bigint): boolean;
39+
/**
40+
* compute/mandelbrot/mandelbrot
41+
* @param width `i32`
42+
* @param height `i32`
43+
* @param zoom `f64`
44+
* @param panX `f64`
45+
* @param panY `f64`
46+
* @param maxIter `i32`
47+
* @returns `~lib/typedarray/Uint32Array`
48+
*/
49+
export declare function mandelbrot(width: number, height: number, zoom: number, panX: number, panY: number, maxIter: number): Uint32Array;
50+
/**
51+
* compute/mandelbrot/julia
52+
* @param width `i32`
53+
* @param height `i32`
54+
* @param cRe `f64`
55+
* @param cIm `f64`
56+
* @param zoom `f64`
57+
* @param maxIter `i32`
58+
* @returns `~lib/typedarray/Uint32Array`
59+
*/
60+
export declare function julia(width: number, height: number, cRe: number, cIm: number, zoom: number, maxIter: number): Uint32Array;
61+
/**
62+
* compute/matrix/matrixMultiply
63+
* @param a `~lib/typedarray/Float64Array`
64+
* @param b `~lib/typedarray/Float64Array`
65+
* @param aRows `i32`
66+
* @param aCols `i32`
67+
* @param bCols `i32`
68+
* @returns `~lib/typedarray/Float64Array`
69+
*/
70+
export declare function matrixMultiply(a: Float64Array, b: Float64Array, aRows: number, aCols: number, bCols: number): Float64Array;
71+
/**
72+
* compute/matrix/matrixTranspose
73+
* @param matrix `~lib/typedarray/Float64Array`
74+
* @param rows `i32`
75+
* @param cols `i32`
76+
* @returns `~lib/typedarray/Float64Array`
77+
*/
78+
export declare function matrixTranspose(matrix: Float64Array, rows: number, cols: number): Float64Array;
79+
/**
80+
* compute/matrix/matrixAdd
81+
* @param a `~lib/typedarray/Float64Array`
82+
* @param b `~lib/typedarray/Float64Array`
83+
* @returns `~lib/typedarray/Float64Array`
84+
*/
85+
export declare function matrixAdd(a: Float64Array, b: Float64Array): Float64Array;
86+
/**
87+
* compute/matrix/matrixScale
88+
* @param matrix `~lib/typedarray/Float64Array`
89+
* @param scalar `f64`
90+
* @returns `~lib/typedarray/Float64Array`
91+
*/
92+
export declare function matrixScale(matrix: Float64Array, scalar: number): Float64Array;
93+
/**
94+
* compute/matrix/dotProduct
95+
* @param a `~lib/typedarray/Float64Array`
96+
* @param b `~lib/typedarray/Float64Array`
97+
* @returns `f64`
98+
*/
99+
export declare function dotProduct(a: Float64Array, b: Float64Array): number;
100+
/**
101+
* compute/matrix/vectorMagnitude
102+
* @param v `~lib/typedarray/Float64Array`
103+
* @returns `f64`
104+
*/
105+
export declare function vectorMagnitude(v: Float64Array): number;
106+
/**
107+
* compute/matrix/vectorNormalize
108+
* @param v `~lib/typedarray/Float64Array`
109+
* @returns `~lib/typedarray/Float64Array`
110+
*/
111+
export declare function vectorNormalize(v: Float64Array): Float64Array;
112+
/**
113+
* compute/blur/getBufferPtr
114+
* @returns `usize`
115+
*/
116+
export declare function getBufferPtr(): number;
117+
/**
118+
* compute/blur/blurImage
119+
* @param width `i32`
120+
* @param height `i32`
121+
* @param passes `i32`
122+
*/
123+
export declare function blurImage(width: number, height: number, passes: number): void;

examples/react-demo/src/compute.js

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
async function instantiate(module, imports = {}) {
2+
const adaptedImports = {
3+
env: Object.assign(Object.create(globalThis), imports.env || {}, {
4+
abort(message, fileName, lineNumber, columnNumber) {
5+
// ~lib/builtins/abort(~lib/string/String | null?, ~lib/string/String | null?, u32?, u32?) => void
6+
message = __liftString(message >>> 0);
7+
fileName = __liftString(fileName >>> 0);
8+
lineNumber = lineNumber >>> 0;
9+
columnNumber = columnNumber >>> 0;
10+
(() => {
11+
// @external.js
12+
throw Error(`${message} in ${fileName}:${lineNumber}:${columnNumber}`);
13+
})();
14+
},
15+
}),
16+
};
17+
const { exports } = await WebAssembly.instantiate(module, adaptedImports);
18+
const memory = exports.memory || imports.env.memory;
19+
const adaptedExports = Object.setPrototypeOf({
20+
sum(arr) {
21+
// compute/sum/sum(~lib/typedarray/Int32Array) => i32
22+
arr = __lowerTypedArray(Int32Array, 4, 2, arr) || __notnull();
23+
return exports.sum(arr);
24+
},
25+
sumFloat(arr) {
26+
// compute/sum/sumFloat(~lib/typedarray/Float64Array) => f64
27+
arr = __lowerTypedArray(Float64Array, 5, 3, arr) || __notnull();
28+
return exports.sumFloat(arr);
29+
},
30+
average(arr) {
31+
// compute/sum/average(~lib/typedarray/Int32Array) => f64
32+
arr = __lowerTypedArray(Int32Array, 4, 2, arr) || __notnull();
33+
return exports.average(arr);
34+
},
35+
fibonacciSequence(n) {
36+
// compute/fibonacci/fibonacciSequence(i32) => ~lib/typedarray/Int64Array
37+
return __liftTypedArray(BigInt64Array, exports.fibonacciSequence(n) >>> 0);
38+
},
39+
isFibonacci(num) {
40+
// compute/fibonacci/isFibonacci(i64) => bool
41+
num = num || 0n;
42+
return exports.isFibonacci(num) != 0;
43+
},
44+
mandelbrot(width, height, zoom, panX, panY, maxIter) {
45+
// compute/mandelbrot/mandelbrot(i32, i32, f64, f64, f64, i32) => ~lib/typedarray/Uint32Array
46+
return __liftTypedArray(Uint32Array, exports.mandelbrot(width, height, zoom, panX, panY, maxIter) >>> 0);
47+
},
48+
julia(width, height, cRe, cIm, zoom, maxIter) {
49+
// compute/mandelbrot/julia(i32, i32, f64, f64, f64, i32) => ~lib/typedarray/Uint32Array
50+
return __liftTypedArray(Uint32Array, exports.julia(width, height, cRe, cIm, zoom, maxIter) >>> 0);
51+
},
52+
matrixMultiply(a, b, aRows, aCols, bCols) {
53+
// compute/matrix/matrixMultiply(~lib/typedarray/Float64Array, ~lib/typedarray/Float64Array, i32, i32, i32) => ~lib/typedarray/Float64Array
54+
a = __retain(__lowerTypedArray(Float64Array, 5, 3, a) || __notnull());
55+
b = __lowerTypedArray(Float64Array, 5, 3, b) || __notnull();
56+
try {
57+
return __liftTypedArray(Float64Array, exports.matrixMultiply(a, b, aRows, aCols, bCols) >>> 0);
58+
} finally {
59+
__release(a);
60+
}
61+
},
62+
matrixTranspose(matrix, rows, cols) {
63+
// compute/matrix/matrixTranspose(~lib/typedarray/Float64Array, i32, i32) => ~lib/typedarray/Float64Array
64+
matrix = __lowerTypedArray(Float64Array, 5, 3, matrix) || __notnull();
65+
return __liftTypedArray(Float64Array, exports.matrixTranspose(matrix, rows, cols) >>> 0);
66+
},
67+
matrixAdd(a, b) {
68+
// compute/matrix/matrixAdd(~lib/typedarray/Float64Array, ~lib/typedarray/Float64Array) => ~lib/typedarray/Float64Array
69+
a = __retain(__lowerTypedArray(Float64Array, 5, 3, a) || __notnull());
70+
b = __lowerTypedArray(Float64Array, 5, 3, b) || __notnull();
71+
try {
72+
return __liftTypedArray(Float64Array, exports.matrixAdd(a, b) >>> 0);
73+
} finally {
74+
__release(a);
75+
}
76+
},
77+
matrixScale(matrix, scalar) {
78+
// compute/matrix/matrixScale(~lib/typedarray/Float64Array, f64) => ~lib/typedarray/Float64Array
79+
matrix = __lowerTypedArray(Float64Array, 5, 3, matrix) || __notnull();
80+
return __liftTypedArray(Float64Array, exports.matrixScale(matrix, scalar) >>> 0);
81+
},
82+
dotProduct(a, b) {
83+
// compute/matrix/dotProduct(~lib/typedarray/Float64Array, ~lib/typedarray/Float64Array) => f64
84+
a = __retain(__lowerTypedArray(Float64Array, 5, 3, a) || __notnull());
85+
b = __lowerTypedArray(Float64Array, 5, 3, b) || __notnull();
86+
try {
87+
return exports.dotProduct(a, b);
88+
} finally {
89+
__release(a);
90+
}
91+
},
92+
vectorMagnitude(v) {
93+
// compute/matrix/vectorMagnitude(~lib/typedarray/Float64Array) => f64
94+
v = __lowerTypedArray(Float64Array, 5, 3, v) || __notnull();
95+
return exports.vectorMagnitude(v);
96+
},
97+
vectorNormalize(v) {
98+
// compute/matrix/vectorNormalize(~lib/typedarray/Float64Array) => ~lib/typedarray/Float64Array
99+
v = __lowerTypedArray(Float64Array, 5, 3, v) || __notnull();
100+
return __liftTypedArray(Float64Array, exports.vectorNormalize(v) >>> 0);
101+
},
102+
getBufferPtr() {
103+
// compute/blur/getBufferPtr() => usize
104+
return exports.getBufferPtr() >>> 0;
105+
},
106+
}, exports);
107+
function __liftString(pointer) {
108+
if (!pointer) return null;
109+
const
110+
end = pointer + new Uint32Array(memory.buffer)[pointer - 4 >>> 2] >>> 1,
111+
memoryU16 = new Uint16Array(memory.buffer);
112+
let
113+
start = pointer >>> 1,
114+
string = "";
115+
while (end - start > 1024) string += String.fromCharCode(...memoryU16.subarray(start, start += 1024));
116+
return string + String.fromCharCode(...memoryU16.subarray(start, end));
117+
}
118+
function __liftTypedArray(constructor, pointer) {
119+
if (!pointer) return null;
120+
return new constructor(
121+
memory.buffer,
122+
__getU32(pointer + 4),
123+
__dataview.getUint32(pointer + 8, true) / constructor.BYTES_PER_ELEMENT
124+
).slice();
125+
}
126+
function __lowerTypedArray(constructor, id, align, values) {
127+
if (values == null) return 0;
128+
const
129+
length = values.length,
130+
buffer = exports.__pin(exports.__new(length << align, 1)) >>> 0,
131+
header = exports.__new(12, id) >>> 0;
132+
__setU32(header + 0, buffer);
133+
__dataview.setUint32(header + 4, buffer, true);
134+
__dataview.setUint32(header + 8, length << align, true);
135+
new constructor(memory.buffer, buffer, length).set(values);
136+
exports.__unpin(buffer);
137+
return header;
138+
}
139+
const refcounts = new Map();
140+
function __retain(pointer) {
141+
if (pointer) {
142+
const refcount = refcounts.get(pointer);
143+
if (refcount) refcounts.set(pointer, refcount + 1);
144+
else refcounts.set(exports.__pin(pointer), 1);
145+
}
146+
return pointer;
147+
}
148+
function __release(pointer) {
149+
if (pointer) {
150+
const refcount = refcounts.get(pointer);
151+
if (refcount === 1) exports.__unpin(pointer), refcounts.delete(pointer);
152+
else if (refcount) refcounts.set(pointer, refcount - 1);
153+
else throw Error(`invalid refcount '${refcount}' for reference '${pointer}'`);
154+
}
155+
}
156+
function __notnull() {
157+
throw TypeError("value must not be null");
158+
}
159+
let __dataview = new DataView(memory.buffer);
160+
function __setU32(pointer, value) {
161+
try {
162+
__dataview.setUint32(pointer, value, true);
163+
} catch {
164+
__dataview = new DataView(memory.buffer);
165+
__dataview.setUint32(pointer, value, true);
166+
}
167+
}
168+
function __getU32(pointer) {
169+
try {
170+
return __dataview.getUint32(pointer, true);
171+
} catch {
172+
__dataview = new DataView(memory.buffer);
173+
return __dataview.getUint32(pointer, true);
174+
}
175+
}
176+
return adaptedExports;
177+
}
178+
export const {
179+
memory,
180+
sum,
181+
sumFloat,
182+
average,
183+
fibonacci,
184+
fibonacciSequence,
185+
isFibonacci,
186+
mandelbrot,
187+
julia,
188+
matrixMultiply,
189+
matrixTranspose,
190+
matrixAdd,
191+
matrixScale,
192+
dotProduct,
193+
vectorMagnitude,
194+
vectorNormalize,
195+
getBufferPtr,
196+
blurImage,
197+
} = await (async url => instantiate(
198+
await (async () => {
199+
const isNodeOrBun = typeof process != "undefined" && process.versions != null && (process.versions.node != null || process.versions.bun != null);
200+
if (isNodeOrBun) { return globalThis.WebAssembly.compile(await (await import("node:fs/promises")).readFile(url)); }
201+
else { return await globalThis.WebAssembly.compileStreaming(globalThis.fetch(url)); }
202+
})(), {
203+
}
204+
))(new URL("compute.wasm", import.meta.url));

examples/react-demo/src/vite-env.d.ts

Lines changed: 0 additions & 6 deletions
This file was deleted.

examples/react-demo/src/wasmLoader.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
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-
63
interface WasmImports {
74
env?: Record<string, unknown>;
85
}
@@ -80,8 +77,8 @@ export async function loadWasm(): Promise<WasmExports> {
8077
}
8178

8279
loadingPromise = (async () => {
83-
// Use the Vite-resolved WASM URL (works in StackBlitz and local dev)
84-
const res = await fetch(wasmUrl);
80+
// Fetch from public folder - works in local dev, production, and StackBlitz
81+
const res = await fetch('/compute.wasm');
8582
if (!res.ok) {
8683
throw new Error(`Failed to fetch WASM: ${res.status} ${res.statusText}`);
8784
}

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/src/compute.wasm --bindings esm --optimize",
13+
"build:wasm": "asc compute/index.ts --outFile examples/react-demo/public/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)