type ModuleFactory = ( opts: EmscriptenWasm.ModuleOpts, ) => M; export function initEmscriptenModule( moduleFactory: ModuleFactory, wasmUrl: string, ): Promise { return new Promise((resolve) => { const module = moduleFactory({ // Just to be safe, don't automatically invoke any wasm functions noInitialRun: true, locateFile(url: string): string { // Redirect the request for the wasm binary to whatever webpack gave us. if (url.endsWith('.wasm')) return wasmUrl; return url; }, onRuntimeInitialized() { // An Emscripten is a then-able that resolves with itself, causing an infite loop when you // wrap it in a real promise. Delete the `then` prop solves this for now. // https://github.com/kripken/emscripten/issues/5820 delete (module as any).then; resolve(module); }, }); }); } interface ClampOpts { min?: number; max?: number; } export function clamp(x: number, opts: ClampOpts): number { return Math.min(Math.max(x, opts.min || Number.MIN_VALUE), opts.max || Number.MAX_VALUE); }