Failed to use wasm function on vue

Viewed 63

When I want to use wasm in vue, the first thing is that I have an unsolvable problem, the startQuorum function in my wasm file can't be found.

import { Go } from './wasm_exec'
import quorumWasmUrl from './lib.wasm'

export const startQuorum = async (bootstraps: Array<string>) => {
  const go = new Go()
  WebAssembly.instantiateStreaming(fetch(quorumWasmUrl), go.importObject).then(
    async (result) => {
      go.run(result.instance)
      const StartQuorum = result.instance.exports.StartQuorum as CallableFunction
      // StartQuorum is a function. but ts can not find it.
      await StartQuorum('password', bootstraps.join(','))
    }
  )
  console.log('startQuorum over')
}

And the wasm files written in Go.The original function is like this

js.Global().Set("StartQuorum", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
        if qChan == nil {
            qChan = make(chan struct{}, 0)
        }
        if len(args) < 2 {
            return nil
        }
        password := args[0].String()
        bootAddrsStr := args[1].String()
        bootAddrs := strings.Split(bootAddrsStr, ",")

        handler := func() (map[string]interface{}, error) {
            ret := make(map[string]interface{})
            ok, err := StartQuorum(qChan, password, bootAddrs)
            ret["ok"] = ok
            if err != nil {
                return ret, err
            }
            return ret, nil
        }
        return Promisefy(handler)
    }))

That means the StartQuorum function in wasm is existed, but typescript can't find it, browser return this.

Uncaught (in promise) TypeError: StartQuorum is not a function
at eval (load-quorum.ts?b7b7:139:1)

The wasm file is loaded well, my initial diagnosis is that ts does not recognize the functions in wasm.

How can I solve it?

1 Answers

That happens because it's not an exported function. Currently, Golang Compiler doesn't support export function (only importing, by magic CALLIMPORT assembly instruction). I'm saying "Golang Compiler" because that is not true if you are using TinyGo or other compiler.


Anyway, using js.Global().Set will set the function into the js.Global(), which is window/globalThis or equivalent:

js.Global().Set("StartQuorum", ....)

That is creating the StartQuorum function at the window/globalThis level. So, the function must be called using: window.StartQuorum().


So, this line:

const StartQuorum = result.instance.exports.StartQuorum as CallableFunction
// StartQuorum is a function. but ts can not find it.

await StartQuorum('password', bootstraps.join(','))

Doesn't seems to make sense, since result.instance.exports.StartQuorum is always null. Your function lives on window.StartQuorum or globalThis.StartQuorum (...).

That is not one exported function from WebAssembly (which will live at result.instance.exports.

Related