dop251 / goja

ECMAScript/JavaScript engine in pure Go

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Create typed arrays from Go

s1na opened this issue · comments

Hello! I was wondering if it's possible to create a Uint8Array in Go and pass it to the JS code. I see there are functions like Runtime.newUint8Array but they are not exposed publicly. The workaround I came up for now is a JS function which takes in an array and returns a buffer and invoke that in Go, and pass the returned value again to JS which has unnecessary overhead.

Hi. You can do rt.New(rt.Get("Uint8Array")) (possibly cache rt.Get("Uint8Array") if you plan to do it many times and you don't override Uint8Array in your runtime).

Ok I managed to get it working with your suggestion, thanks. Closing this issue but please consider exposing those methods publicly.

Hey, just posting this for people who need to do the same thing:

func toBuf(vm *goja.Runtime, bufType goja.Value, val []byte) (goja.Value, error) {
      // bufType is cached `vm.Get("Uint8Array")`
     return vm.New(bufType, vm.ToValue(vm.NewArrayBuffer(val)))
}

Note by first casting to ArrayBuffer you'll avoid copying and get a significant speed-up.

And to get a buffer from JS:

func fromBuf(vm *goja.Runtime, bufType goja.Value, buf goja.Value) ([]byte, error) {
    obj := buf.ToObject(vm)
    if !obj.Get("constructor").SameAs(bufType) {
        return nil, errors.New("invalid buffer")
    }
    b := obj.Get("buffer").Export().(goja.ArrayBuffer).Bytes()
    return b, nil
}