5

I have an existing project written in TypeScript and I'm trying to import a WebAssembly Module to replace some functionality.

I have managed to successfully import the WebAssembly module by extracting the logic for loading the .wasm to a .js file. This is it's own TypeScript module and is imported into the .ts file where I want to use the WebAssembly functions.

For demonstration purposes I have made a simple add function in wasm.

In the .ts that is compiled to .wasm with AssemblyScript:

export function add(a: i32, b: i32): i32 {
  return a + b;
}

In the .js file:

export async function loadWasm() {
  const imports = {}; // Omitted the contents since it's most likely irrelevant
  const module = await 
  WebAssembly.instantiateStreaming(fetch('path/to/file.wasm'),imports);
  return module;
}

And in the .ts file where I want to use the WebAssembly:

loadWasm().then((module: any) => {
  let addFunc: ((a: number, b: number) => any) = module.add;
  console.log('Adding 2 and 5 in Wasm: ' + addFunc(2, 5));
});

But when running this it gives me the following error:

Uncaught (in promise) TypeError: addFunc is not a function at eval

Does anyone know what causes this?

2 Answers 2

5

Try this snippet:

loadWasm().then(module => {
  const { add: addFunc } = module.instance.exports;
  console.log(addFunc(2, 5));
});
Sign up to request clarification or add additional context in comments.

Comments

3

Here's a method using AssemblyScript Loader that you can use directly in the TypeScript:

It requires "regenerator-runtime": "^0.13.2" which you can import together with the loader in the .ts file where you want to use the Wasm module, as such:

import { instantiateStreaming, ASUtil } from 'assemblyscript/lib/loader';
import { regeneratorRuntime } from 'regenerator-runtime';

I've instantiated it like so:

interface MyApi {
    add(a: number, b: number): number;
}

async function getWasm(): Promise<ASUtil & MyApi> {
    const imports: any = {};
    let module: ASUtil & MyApi = await instantiateStreaming<MyApi>(fetch('path/to/file.wasm'), imports);
    return module;
}

After which you can simply:

getWasm().then((module) => {
    console.log('The result is: ', module.add(3, 4));
});

As well as use any of the additional functionality that the Loader provides:

let str = "Hello World!";
let ref = module.__retain(module.__allocString(str));
console.log(module.__getString(ref));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.