Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 11-22-implement-kv-interface-defined-in-collectiveversionedkvgo
  • @XX-4682/Files
  • Anne/CI-hash
  • Jakub/Emoji-CI-Test
  • NewHostPool
  • XX-4324/CleanWorkingTree
  • XX-4441
  • XX-4461/FileUpload
  • XX-4505/blockuser
  • XX-4602/SilentMessageType
  • XX-4688/DbEncoding
  • dev
  • fast-registration
  • fastReg
  • hotfix/XX-4655
  • hotfix/filetransfercallback
  • hotfix/leave_channel_delete
  • hotfix/update
  • jono/npmTest
  • master
  • project/HavenNotifications
  • release
  • testRSAVerify
  • testing/websockets
  • wasmTest2
  • xx-4287/encryption-helper
  • 06c73fe9e17a189ba0f81ff128120fc197c95e86fc0b45587b297d4ebac3beab
  • 15591a484b25c0f3181fdbbd76c1aaaf51c22ecffb027d8e58206d6b1f3a08f7
  • 1803273e8f7ee5c40abee417ed434f9f46bf3c4cdd16c6766382c27414fe6735
  • 22a695a0cead5f69122bd33d7ceae886844af81158a5146e899a20cfe12cf809
  • 291e9eb4ce787bf7af9c17896d2d89fafe197bee2b93b4fb622fc82392fc01d6
  • 2d58192c15c8d0b0c8d7fd452ccb4e8fb43da8336b1bdb1a996476585dcbe963
  • 3008b96ec6ea621869ab676586f39ee7592c8d42f7298d14d1b5f946f2825591
  • 31e4db3a893e1711ce6bfee845bbaa42b250dafd52a0761f97dde9fa620a88b9
  • 50eb5a589c7c1de0c2e8c83f804c63bf650310ce261bc42c0ab982a0013e0fbf
  • 575cb1e68e945ab74386885c347b60fc3e231367d708675ab010b06d30947bc0
  • 5d94c4042f39cd7284e8f7fb3e2c00900e22ae3b09b77fbb51da1f4f3de41ebc
  • 5fb6b664a40fbb4bb89e08622bb751a355f1f06ae1d1195bda6536808a12ff85
  • 68c89d4a78c1bc895d4ef4db81643a8441298af2175b67838f4a94ab8b753354
  • 75e66ec56f60c804e8f1b3b896697f406953ad7a1247e1e58095cf7c8e38f200
  • 76ba08e2dfa1798412a265404fa271840b52c035869111fce8e8cdb23a036a5a
  • 812b395df518ce096d01d5292596ca26f8fe92d9c4487ddfa515e190a51aa1a1
  • 8718f5b8341cccb99566fb91294d0af31bdbc9cc59cae5f766c32f32234f7c5b
  • 9048c22145ec8770e25c21afb4405368318261457b765a40f5ba5b3038fee353
  • a69a79e8517ae4196c5ddbbf71337460bf5b88464cfe81832152442b3f043937
  • a8bdea48f8fea1cc9e4b88cc20a19b8bb8914bf1d95c20150b6115d1572c1b70
  • bc0bb01e44383b4aae9af3cb4080a4629b39d4609d2105b6d07f6a6f12c5e902
  • d2e1a04c48dc2b4b878a2f72d15d93a21e640ae89b01d2e20c6520d27528e299
  • e73ddf4cf622d5b7747e50e6cb82966e83a0323ac49f214f30587c195ce9a69d
  • eff7aa8ca82523b901fec6a73d8dac9e995481623500fa421a8aa781320a13dd
  • f5069958dd13368620c00c8438d0d9583db34ebdd6224b876d50df6e43e5db45
  • v0.1.1
  • v0.1.10
  • v0.1.11
  • v0.1.12
  • v0.1.13
  • v0.1.2
  • v0.1.3
  • v0.1.5
  • v0.1.6
  • v0.1.8
  • v0.3.0
  • v0.3.10
  • v0.3.11
  • v0.3.12
  • v0.3.13
  • v0.3.14
  • v0.3.15
  • v0.3.16
  • v0.3.17
  • v0.3.18
  • v0.3.20
  • v0.3.21
  • v0.3.22
  • v0.3.3
  • v0.3.4
  • v0.3.5
  • v0.3.6
  • v0.3.7
  • v0.3.8
  • v0.3.9
81 results

Target

Select target project
  • elixxir/xxdk-wasm
1 result
Select Git revision
  • 11-22-implement-kv-interface-defined-in-collectiveversionedkvgo
  • @XX-4682/Files
  • Anne/CI-hash
  • Jakub/Emoji-CI-Test
  • NewHostPool
  • XX-4324/CleanWorkingTree
  • XX-4441
  • XX-4461/FileUpload
  • XX-4505/blockuser
  • XX-4602/SilentMessageType
  • XX-4688/DbEncoding
  • dev
  • fast-registration
  • fastReg
  • hotfix/XX-4655
  • hotfix/filetransfercallback
  • hotfix/leave_channel_delete
  • hotfix/update
  • jono/npmTest
  • master
  • project/HavenNotifications
  • release
  • testRSAVerify
  • testing/websockets
  • wasmTest2
  • xx-4287/encryption-helper
  • 06c73fe9e17a189ba0f81ff128120fc197c95e86fc0b45587b297d4ebac3beab
  • 15591a484b25c0f3181fdbbd76c1aaaf51c22ecffb027d8e58206d6b1f3a08f7
  • 1803273e8f7ee5c40abee417ed434f9f46bf3c4cdd16c6766382c27414fe6735
  • 22a695a0cead5f69122bd33d7ceae886844af81158a5146e899a20cfe12cf809
  • 291e9eb4ce787bf7af9c17896d2d89fafe197bee2b93b4fb622fc82392fc01d6
  • 2d58192c15c8d0b0c8d7fd452ccb4e8fb43da8336b1bdb1a996476585dcbe963
  • 3008b96ec6ea621869ab676586f39ee7592c8d42f7298d14d1b5f946f2825591
  • 31e4db3a893e1711ce6bfee845bbaa42b250dafd52a0761f97dde9fa620a88b9
  • 50eb5a589c7c1de0c2e8c83f804c63bf650310ce261bc42c0ab982a0013e0fbf
  • 575cb1e68e945ab74386885c347b60fc3e231367d708675ab010b06d30947bc0
  • 5d94c4042f39cd7284e8f7fb3e2c00900e22ae3b09b77fbb51da1f4f3de41ebc
  • 5fb6b664a40fbb4bb89e08622bb751a355f1f06ae1d1195bda6536808a12ff85
  • 68c89d4a78c1bc895d4ef4db81643a8441298af2175b67838f4a94ab8b753354
  • 75e66ec56f60c804e8f1b3b896697f406953ad7a1247e1e58095cf7c8e38f200
  • 76ba08e2dfa1798412a265404fa271840b52c035869111fce8e8cdb23a036a5a
  • 812b395df518ce096d01d5292596ca26f8fe92d9c4487ddfa515e190a51aa1a1
  • 8718f5b8341cccb99566fb91294d0af31bdbc9cc59cae5f766c32f32234f7c5b
  • 9048c22145ec8770e25c21afb4405368318261457b765a40f5ba5b3038fee353
  • a69a79e8517ae4196c5ddbbf71337460bf5b88464cfe81832152442b3f043937
  • a8bdea48f8fea1cc9e4b88cc20a19b8bb8914bf1d95c20150b6115d1572c1b70
  • bc0bb01e44383b4aae9af3cb4080a4629b39d4609d2105b6d07f6a6f12c5e902
  • d2e1a04c48dc2b4b878a2f72d15d93a21e640ae89b01d2e20c6520d27528e299
  • e73ddf4cf622d5b7747e50e6cb82966e83a0323ac49f214f30587c195ce9a69d
  • eff7aa8ca82523b901fec6a73d8dac9e995481623500fa421a8aa781320a13dd
  • f5069958dd13368620c00c8438d0d9583db34ebdd6224b876d50df6e43e5db45
  • v0.1.1
  • v0.1.10
  • v0.1.11
  • v0.1.12
  • v0.1.13
  • v0.1.2
  • v0.1.3
  • v0.1.5
  • v0.1.6
  • v0.1.8
  • v0.3.0
  • v0.3.10
  • v0.3.11
  • v0.3.12
  • v0.3.13
  • v0.3.14
  • v0.3.15
  • v0.3.16
  • v0.3.17
  • v0.3.18
  • v0.3.20
  • v0.3.21
  • v0.3.22
  • v0.3.3
  • v0.3.4
  • v0.3.5
  • v0.3.6
  • v0.3.7
  • v0.3.8
  • v0.3.9
81 results
Show changes
......@@ -11,7 +11,8 @@ package wasm
import (
"gitlab.com/elixxir/client/v4/bindings"
"gitlab.com/elixxir/xxdk-wasm/utils"
"gitlab.com/elixxir/wasm-utils/exception"
"gitlab.com/elixxir/wasm-utils/utils"
"syscall/js"
)
......@@ -34,7 +35,7 @@ func DownloadAndVerifySignedNdfWithUrl(_ js.Value, args []js.Value) any {
promiseFn := func(resolve, reject func(args ...any) js.Value) {
ndf, err := bindings.DownloadAndVerifySignedNdfWithUrl(url, cert)
if err != nil {
reject(utils.JsTrace(err))
reject(exception.NewTrace(err))
} else {
resolve(utils.CopyBytesToJS(ndf))
}
......
////////////////////////////////////////////////////////////////////////////////
// Copyright © 2022 xx foundation //
// //
// Use of this source code is governed by a license that can be found in the //
// LICENSE file. //
////////////////////////////////////////////////////////////////////////////////
//go:build js && wasm
package wasm
import (
"syscall/js"
"gitlab.com/elixxir/client/v4/bindings"
"gitlab.com/elixxir/client/v4/notifications"
"gitlab.com/elixxir/wasm-utils/exception"
)
type Notifications struct {
api bindings.Notifications
}
// newNotificationsJS wrapts the bindings Noticiation object and implements
// wrappers in JS for all it's functionality.
func newNotificationsJS(api bindings.Notifications) map[string]any {
n := Notifications{api}
notificationsImplJS := map[string]any{
"AddToken": js.FuncOf(n.AddToken),
"RemoveToken": js.FuncOf(n.RemoveToken),
"SetMaxState": js.FuncOf(n.SetMaxState),
"GetMaxState": js.FuncOf(n.GetMaxState),
"GetID": js.FuncOf(n.GetID),
}
return notificationsImplJS
}
// LoadNotifications returns a JS wrapped implementation of
// [bindings.Notifications].
//
// Parameters:
// - args[0] - the cMixID integer
//
// Returns a notifications object or throws an error
func LoadNotifications(_ js.Value, args []js.Value) any {
cMixID := args[0].Int()
api, err := bindings.LoadNotifications(cMixID)
if err != nil {
exception.ThrowTrace(err)
return nil
}
return newNotificationsJS(api)
}
// LoadNotificationsDummy returns a JS wrapped implementation of
// [bindings.Notifications] with a dummy notifications implementation.
//
// Parameters:
// - args[0] - the cMixID integer
//
// Returns a notifications object or throws an error
func LoadNotificationsDummy(_ js.Value, args []js.Value) any {
cMixID := args[0].Int()
api, err := bindings.LoadNotificationsDummy(cMixID)
if err != nil {
exception.ThrowTrace(err)
return nil
}
return newNotificationsJS(api)
}
// GetID returns the bindings ID for the [bindings.Notifications] object
func (n *Notifications) GetID(js.Value, []js.Value) any {
return n.api.GetID()
}
// AddToken implements [bindings.Notifications.AddToken].
//
// Parameters:
// - args[0] - newToken string
// - args[1] - app string
//
// Returns nothing or an error (throwable)
func (n *Notifications) AddToken(_ js.Value, args []js.Value) any {
newToken := args[0].String()
app := args[1].String()
err := n.api.AddToken(newToken, app)
if err != nil {
exception.ThrowTrace(err)
}
return nil
}
// RemoveToken implements [bindings.Notifications.RemoveToken].
//
// Returns nothing or throws an error.
func (n *Notifications) RemoveToken(_ js.Value, args []js.Value) any {
err := n.api.RemoveToken()
if err != nil {
exception.ThrowTrace(err)
}
return nil
}
// SetMaxState implements [bindings.Notifications.SetMaxState]
//
// Parameters:
// - args[0] - maxState integer
//
// Returns nothing or throws an error
func (n *Notifications) SetMaxState(_ js.Value, args []js.Value) any {
maxState := int64(args[0].Int())
err := n.api.SetMaxState(notifications.NotificationState(maxState))
if err != nil {
exception.ThrowTrace(err)
}
return nil
}
// GetMaxState implements [bindings.Notifications.GetMaxState]
//
// Returns the current maxState integer
func (n *Notifications) GetMaxState(_ js.Value, args []js.Value) any {
return int64(n.api.GetMaxState())
}
......@@ -11,7 +11,7 @@ package wasm
import (
"gitlab.com/elixxir/client/v4/bindings"
"gitlab.com/elixxir/xxdk-wasm/utils"
"gitlab.com/elixxir/wasm-utils/utils"
"syscall/js"
)
......
......@@ -11,7 +11,8 @@ package wasm
import (
"gitlab.com/elixxir/client/v4/bindings"
"gitlab.com/elixxir/xxdk-wasm/utils"
"gitlab.com/elixxir/wasm-utils/exception"
"gitlab.com/elixxir/wasm-utils/utils"
"syscall/js"
)
......@@ -39,7 +40,7 @@ func RestlikeRequest(_ js.Value, args []js.Value) any {
msg, err := bindings.RestlikeRequest(
cmixId, connectionID, request, e2eParamsJSON)
if err != nil {
reject(utils.JsTrace(err))
reject(exception.NewTrace(err))
} else {
resolve(utils.CopyBytesToJS(msg))
}
......@@ -72,7 +73,7 @@ func RestlikeRequestAuth(_ js.Value, args []js.Value) any {
msg, err := bindings.RestlikeRequestAuth(
cmixId, authConnectionID, request, e2eParamsJSON)
if err != nil {
reject(utils.JsTrace(err))
reject(exception.NewTrace(err))
} else {
resolve(utils.CopyBytesToJS(msg))
}
......
......@@ -11,7 +11,8 @@ package wasm
import (
"gitlab.com/elixxir/client/v4/bindings"
"gitlab.com/elixxir/xxdk-wasm/utils"
"gitlab.com/elixxir/wasm-utils/exception"
"gitlab.com/elixxir/wasm-utils/utils"
"syscall/js"
)
......@@ -27,7 +28,7 @@ type restlikeCallback struct {
// - payload - JSON of [restlike.Message] (Uint8Array).
// - err - Returns an error on failure (Error).
func (rlc *restlikeCallback) Callback(payload []byte, err error) {
rlc.callback(utils.CopyBytesToJS(payload), utils.JsTrace(err))
rlc.callback(utils.CopyBytesToJS(payload), exception.NewTrace(err))
}
// RequestRestLike sends a restlike request to a given contact.
......@@ -54,7 +55,7 @@ func RequestRestLike(_ js.Value, args []js.Value) any {
msg, err := bindings.RequestRestLike(
e2eID, recipient, request, paramsJSON)
if err != nil {
reject(utils.JsTrace(err))
reject(exception.NewTrace(err))
} else {
resolve(utils.CopyBytesToJS(msg))
}
......@@ -79,7 +80,7 @@ func RequestRestLike(_ js.Value, args []js.Value) any {
// [bindings.RestlikeCallback] interface.
//
// Returns:
// - Throws a TypeError if parsing the parameters or making the request fails.
// - Throws an error if parsing the parameters or making the request fails.
func AsyncRequestRestLike(_ js.Value, args []js.Value) any {
e2eID := args[0].Int()
recipient := utils.CopyBytesToGo(args[1])
......@@ -91,7 +92,7 @@ func AsyncRequestRestLike(_ js.Value, args []js.Value) any {
err := bindings.AsyncRequestRestLike(
e2eID, recipient, request, paramsJSON, cb)
if err != nil {
utils.Throw(utils.TypeError, err)
exception.ThrowTrace(err)
}
}()
......
......@@ -11,7 +11,7 @@ package wasm
import (
"gitlab.com/elixxir/client/v4/bindings"
"gitlab.com/elixxir/xxdk-wasm/utils"
"gitlab.com/elixxir/wasm-utils/utils"
"syscall/js"
)
......
......@@ -11,7 +11,8 @@ package wasm
import (
"gitlab.com/elixxir/client/v4/bindings"
"gitlab.com/elixxir/xxdk-wasm/utils"
"gitlab.com/elixxir/wasm-utils/exception"
"gitlab.com/elixxir/wasm-utils/utils"
"syscall/js"
)
......@@ -49,7 +50,7 @@ func TransmitSingleUse(_ js.Value, args []js.Value) any {
sendReport, err := bindings.TransmitSingleUse(
e2eID, recipient, tag, payload, paramsJSON, responseCB)
if err != nil {
reject(utils.JsTrace(err))
reject(exception.NewTrace(err))
} else {
resolve(utils.CopyBytesToJS(sendReport))
}
......@@ -71,12 +72,12 @@ func TransmitSingleUse(_ js.Value, args []js.Value) any {
// Returns:
// - Javascript representation of the [Stopper] object, an interface
// containing a function used to stop the listener.
// - Throws a TypeError if listening fails.
// - Throws an error if listening fails.
func Listen(_ js.Value, args []js.Value) any {
cb := &singleUseCallback{utils.WrapCB(args[2], "Callback")}
api, err := bindings.Listen(args[0].Int(), args[1].String(), cb)
if err != nil {
utils.Throw(utils.TypeError, err)
exception.ThrowTrace(err)
return nil
}
......@@ -128,7 +129,7 @@ type singleUseCallback struct {
// (Uint8Array).
// - err - Returns an error on failure (Error).
func (suc *singleUseCallback) Callback(callbackReport []byte, err error) {
suc.callback(utils.CopyBytesToJS(callbackReport), utils.JsTrace(err))
suc.callback(utils.CopyBytesToJS(callbackReport), exception.NewTrace(err))
}
// singleUseResponse wraps Javascript callbacks to adhere to the
......@@ -145,5 +146,5 @@ type singleUseResponse struct {
// (Uint8Array).
// - err - Returns an error on failure (Error).
func (sur *singleUseResponse) Callback(responseReport []byte, err error) {
sur.callback(utils.CopyBytesToJS(responseReport), utils.JsTrace(err))
sur.callback(utils.CopyBytesToJS(responseReport), exception.NewTrace(err))
}
......@@ -11,7 +11,7 @@ package wasm
import (
"gitlab.com/elixxir/client/v4/bindings"
"gitlab.com/elixxir/xxdk-wasm/utils"
"gitlab.com/elixxir/wasm-utils/utils"
"syscall/js"
)
......
......@@ -11,7 +11,8 @@ package wasm
import (
"gitlab.com/elixxir/client/v4/bindings"
"gitlab.com/elixxir/xxdk-wasm/utils"
"gitlab.com/elixxir/wasm-utils/exception"
"gitlab.com/elixxir/wasm-utils/utils"
"syscall/js"
)
......@@ -99,7 +100,7 @@ func (uns *udNetworkStatus) UdNetworkStatus() int {
// Returns:
// - Javascript representation of the [UserDiscovery] object that is
// registered to the specified UD service.
// - Throws a TypeError if creating or loading fails.
// - Throws an error if creating or loading fails.
func NewOrLoadUd(_ js.Value, args []js.Value) any {
e2eID := args[0].Int()
follower := &udNetworkStatus{utils.WrapCB(args[1], "UdNetworkStatus")}
......@@ -112,7 +113,7 @@ func NewOrLoadUd(_ js.Value, args []js.Value) any {
api, err := bindings.NewOrLoadUd(e2eID, follower, username,
registrationValidationSignature, cert, contactFile, address)
if err != nil {
utils.Throw(utils.TypeError, err)
exception.ThrowTrace(err)
return nil
}
......@@ -145,7 +146,7 @@ func NewOrLoadUd(_ js.Value, args []js.Value) any {
// Returns:
// - Javascript representation of the [UserDiscovery] object that is loaded
// from backup.
// - Throws a TypeError if getting UD from backup fails.
// - Throws an error if getting UD from backup fails.
func NewUdManagerFromBackup(_ js.Value, args []js.Value) any {
e2eID := args[0].Int()
follower := &udNetworkStatus{utils.WrapCB(args[1], "UdNetworkStatus")}
......@@ -157,7 +158,7 @@ func NewUdManagerFromBackup(_ js.Value, args []js.Value) any {
e2eID, follower, cert,
contactFile, address)
if err != nil {
utils.Throw(utils.TypeError, err)
exception.ThrowTrace(err)
return nil
}
......@@ -182,7 +183,7 @@ func (ud *UserDiscovery) GetFacts(js.Value, []js.Value) any {
func (ud *UserDiscovery) GetContact(js.Value, []js.Value) any {
c, err := ud.api.GetContact()
if err != nil {
utils.Throw(utils.TypeError, err)
exception.ThrowTrace(err)
return nil
}
......@@ -203,7 +204,7 @@ func (ud *UserDiscovery) GetContact(js.Value, []js.Value) any {
func (ud *UserDiscovery) ConfirmFact(_ js.Value, args []js.Value) any {
err := ud.api.ConfirmFact(args[0].String(), args[1].String())
if err != nil {
utils.Throw(utils.TypeError, err)
exception.ThrowTrace(err)
return nil
}
......@@ -228,7 +229,7 @@ func (ud *UserDiscovery) ConfirmFact(_ js.Value, args []js.Value) any {
func (ud *UserDiscovery) SendRegisterFact(_ js.Value, args []js.Value) any {
confirmationID, err := ud.api.SendRegisterFact(utils.CopyBytesToGo(args[0]))
if err != nil {
utils.Throw(utils.TypeError, err)
exception.ThrowTrace(err)
return nil
}
......@@ -247,7 +248,7 @@ func (ud *UserDiscovery) SendRegisterFact(_ js.Value, args []js.Value) any {
func (ud *UserDiscovery) PermanentDeleteAccount(_ js.Value, args []js.Value) any {
err := ud.api.PermanentDeleteAccount(utils.CopyBytesToGo(args[0]))
if err != nil {
utils.Throw(utils.TypeError, err)
exception.ThrowTrace(err)
return nil
}
......@@ -265,7 +266,7 @@ func (ud *UserDiscovery) PermanentDeleteAccount(_ js.Value, args []js.Value) any
func (ud *UserDiscovery) RemoveFact(_ js.Value, args []js.Value) any {
err := ud.api.RemoveFact(utils.CopyBytesToGo(args[0]))
if err != nil {
utils.Throw(utils.TypeError, err)
exception.ThrowTrace(err)
return nil
}
......@@ -290,7 +291,7 @@ type udLookupCallback struct {
// the lookup, or nil if an error occurs (Uint8Array).
// - err - Returns an error on failure (Error).
func (ulc *udLookupCallback) Callback(contactBytes []byte, err error) {
ulc.callback(utils.CopyBytesToJS(contactBytes), utils.JsTrace(err))
ulc.callback(utils.CopyBytesToJS(contactBytes), exception.NewTrace(err))
}
// LookupUD returns the public key of the passed ID as known by the user
......@@ -322,7 +323,7 @@ func LookupUD(_ js.Value, args []js.Value) any {
sendReport, err := bindings.LookupUD(
e2eID, udContact, cb, lookupId, singleRequestParamsJSON)
if err != nil {
reject(utils.JsTrace(err))
reject(exception.NewTrace(err))
} else {
resolve(utils.CopyBytesToJS(sendReport))
}
......@@ -357,7 +358,7 @@ type udSearchCallback struct {
// "<xxc(2)d7RJTu61Vy1lDThDMn8rYIiKSe1uXA/RCvvcIhq5Yg4DEgB7Ugdw/BAr6RsCABkWAFV1c2VybmFtZTI7N3XWrxIUpR29atpFMkcR6A==xxc>"
// }
func (usc *udSearchCallback) Callback(contactListJSON []byte, err error) {
usc.callback(utils.CopyBytesToJS(contactListJSON), utils.JsTrace(err))
usc.callback(utils.CopyBytesToJS(contactListJSON), exception.NewTrace(err))
}
// SearchUD searches user discovery for the passed Facts. The searchCallback
......@@ -389,7 +390,7 @@ func SearchUD(_ js.Value, args []js.Value) any {
sendReport, err := bindings.SearchUD(
e2eID, udContact, cb, factListJSON, singleRequestParamsJSON)
if err != nil {
reject(utils.JsTrace(err))
reject(exception.NewTrace(err))
} else {
resolve(utils.CopyBytesToJS(sendReport))
}
......
......@@ -14,8 +14,9 @@ import (
"syscall/js"
"gitlab.com/elixxir/client/v4/bindings"
"gitlab.com/elixxir/wasm-utils/exception"
"gitlab.com/elixxir/wasm-utils/utils"
"gitlab.com/elixxir/xxdk-wasm/storage"
"gitlab.com/elixxir/xxdk-wasm/utils"
)
// GetVersion returns the current xxDK WASM semantic version.
......@@ -66,7 +67,7 @@ type VersionInfo struct {
//
// Returns:
// - JSON of [VersionInfo] (Uint8Array).
// - Throws a TypeError if getting the version failed.
// - Throws an error if getting the version failed.
func GetWasmSemanticVersion(js.Value, []js.Value) any {
vi := VersionInfo{
Current: storage.SEMVER,
......@@ -80,7 +81,7 @@ func GetWasmSemanticVersion(js.Value, []js.Value) any {
data, err := json.Marshal(vi)
if err != nil {
utils.Throw(utils.TypeError, err)
exception.ThrowTrace(err)
}
return utils.CopyBytesToJS(data)
......@@ -91,7 +92,7 @@ func GetWasmSemanticVersion(js.Value, []js.Value) any {
//
// Returns:
// - JSON of [VersionInfo] (Uint8Array).
// - Throws a TypeError if getting the version failed.
// - Throws an error if getting the version failed.
func GetXXDKSemanticVersion(js.Value, []js.Value) any {
vi := VersionInfo{
Current: bindings.GetVersion(),
......@@ -104,7 +105,7 @@ func GetXXDKSemanticVersion(js.Value, []js.Value) any {
data, err := json.Marshal(vi)
if err != nil {
utils.Throw(utils.TypeError, err)
exception.ThrowTrace(err)
}
return utils.CopyBytesToJS(data)
......
......@@ -453,7 +453,7 @@
},
// func Throw(exception string, message string)
'gitlab.com/elixxir/xxdk-wasm/utils.throw': (sp) => {
'gitlab.com/elixxir/wasm-utils/exception.throw': (sp) => {
const exception = loadString(sp + 8)
const message = loadString(sp + 24)
throw globalThis[exception](message)
......
......@@ -63,6 +63,12 @@ func TestPublicFunctions(t *testing.T) {
// C-Library specific bindings not needed by the browser
"GetDMInstance": {},
"GetCMixInstance": {},
// Logging has been moved to startup flags
"LogLevel": {},
// NewFilesystemRemoteStorage is internal for bindings.
"NewFileSystemRemoteStorage": {},
}
wasmFuncs := getPublicFunctions("wasm", t)
bindingsFuncs := getPublicFunctions(
......
......@@ -18,7 +18,7 @@ package main
import (
"fmt"
"gitlab.com/elixxir/xxdk-wasm/utils/worker"
"gitlab.com/elixxir/wasm-utils/utils/worker"
)
func main() {
......
......@@ -18,7 +18,7 @@ import (
"github.com/pkg/errors"
jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/xxdk-wasm/utils"
"gitlab.com/elixxir/wasm-utils/utils"
)
// initID is the ID for the first item in the callback list. If the list only
......@@ -41,7 +41,7 @@ const (
// put on.
const receiveQueueChanSize = 100
// ReceptionCallback is the function that handles incoming data from the worker.
// ReceptionCallback is called with a message received from the worker.
type ReceptionCallback func(data []byte)
// Manager manages the handling of messages received from the worker.
......@@ -64,7 +64,7 @@ type Manager struct {
// receiveQueue is the channel that all received messages are queued on
// while they wait to be processed.
receiveQueue chan []byte
receiveQueue chan js.Value
// quit, when triggered, stops the thread that processes received messages.
quit chan struct{}
......@@ -89,7 +89,7 @@ func NewManager(aURL, name string, messageLogging bool) (*Manager, error) {
worker: js.Global().Get("Worker").New(aURL, opts),
callbacks: make(map[Tag]map[uint64]ReceptionCallback),
responseIDs: make(map[Tag]uint64),
receiveQueue: make(chan []byte, receiveQueueChanSize),
receiveQueue: make(chan js.Value, receiveQueueChanSize),
quit: make(chan struct{}),
name: name,
messageLogging: messageLogging,
......@@ -138,12 +138,25 @@ func (m *Manager) processThread() {
case <-m.quit:
jww.INFO.Printf("[WW] [%s] Quitting process thread.", m.name)
return
case message := <-m.receiveQueue:
err := m.processReceivedMessage(message)
case msgData := <-m.receiveQueue:
switch msgData.Type() {
case js.TypeObject:
if msgData.Get("constructor").Equal(utils.Uint8Array) {
err := m.processReceivedMessage(utils.CopyBytesToGo(msgData))
if err != nil {
jww.ERROR.Printf("[WW] [%s] Failed to process received "+
"message from worker: %+v", m.name, err)
}
break
}
fallthrough
default:
jww.ERROR.Printf("[WW] [%s] Cannot handle data of type %s "+
"from worker: %s", m.name, msgData.Type(),
utils.JsToJson(msgData))
}
}
}
}
......@@ -174,12 +187,12 @@ func (m *Manager) SendMessage(
"ID %d going to worker: %+v", m.name, msg, tag, id, err)
}
go m.postMessage(string(payload))
go m.postMessage(payload)
}
// receiveMessage is registered with the Javascript event listener and is called
// every time a new message from the worker is received.
func (m *Manager) receiveMessage(data []byte) {
func (m *Manager) receiveMessage(data js.Value) {
m.receiveQueue <- data
}
......@@ -303,7 +316,7 @@ func (m *Manager) addEventListeners() {
// occurs when a message is received from the worker.
// Doc: https://developer.mozilla.org/en-US/docs/Web/API/Worker/message_event
messageEvent := js.FuncOf(func(_ js.Value, args []js.Value) any {
m.receiveMessage([]byte(args[0].Get("data").String()))
m.receiveMessage(args[0].Get("data"))
return nil
})
......@@ -312,8 +325,8 @@ func (m *Manager) addEventListeners() {
// Doc: https://developer.mozilla.org/en-US/docs/Web/API/Worker/error_event
errorEvent := js.FuncOf(func(_ js.Value, args []js.Value) any {
event := args[0]
jww.ERROR.Printf("[WW] [%s] Main received error event: %s",
m.name, utils.JsErrorToJson(event))
jww.FATAL.Panicf("[WW] [%s] Main received error event: %+v",
m.name, js.Error{Value: event})
return nil
})
......@@ -322,8 +335,8 @@ func (m *Manager) addEventListeners() {
// Doc: https://developer.mozilla.org/en-US/docs/Web/API/Worker/messageerror_event
messageerrorEvent := js.FuncOf(func(_ js.Value, args []js.Value) any {
event := args[0]
jww.ERROR.Printf("[WW] [%s] Main received message error event: %s",
m.name, utils.JsErrorToJson(event))
jww.ERROR.Printf("[WW] [%s] Main received message error event: %+v",
m.name, js.Error{Value: event})
return nil
})
......@@ -336,20 +349,19 @@ func (m *Manager) addEventListeners() {
// postMessage sends a message to the worker.
//
// message is the object to deliver to the worker; this will be in the data
// field in the event delivered to the worker. It must be a js.Value or a
// primitive type that can be converted via js.ValueOf. The Javascript object
// must be "any value or JavaScript object handled by the structured clone
// algorithm, which includes cyclical references.". See the doc for more
// information.
// msg is the object to deliver to the worker; this will be in the data
// field in the event delivered to the worker. It must be a transferable object
// because this function transfers ownership of the message instead of copying
// it for better performance. See the doc for more information.
//
// If the message parameter is not provided, a SyntaxError will be thrown by the
// parser. If the data to be passed to the worker is unimportant, js.Null or
// js.Undefined can be passed explicitly.
//
// Doc: https://developer.mozilla.org/en-US/docs/Web/API/Worker/postMessage
func (m *Manager) postMessage(msg any) {
m.worker.Call("postMessage", msg)
func (m *Manager) postMessage(msg []byte) {
buffer := utils.CopyBytesToJS(msg)
m.worker.Call("postMessage", buffer, []any{buffer.Get("buffer")})
}
// terminate immediately terminates the Worker. This does not offer the worker
......
......@@ -21,7 +21,7 @@ func TestManager_processReceivedMessage(t *testing.T) {
m := &Manager{callbacks: make(map[Tag]map[uint64]ReceptionCallback)}
msg := Message{Tag: readyTag, ID: 5}
cbChan := make(chan struct{})
cbChan := make(chan struct{}, 1)
cb := func([]byte) { cbChan <- struct{}{} }
m.callbacks[msg.Tag] = map[uint64]ReceptionCallback{msg.ID: cb}
......@@ -31,17 +31,17 @@ func TestManager_processReceivedMessage(t *testing.T) {
}
go func() {
err = m.processReceivedMessage(data)
if err != nil {
t.Errorf("Failed to receive message: %+v", err)
}
}()
select {
case <-cbChan:
case <-time.After(10 * time.Millisecond):
t.Error("Timed out waiting for callback to be called.")
}
}()
err = m.processReceivedMessage(data)
if err != nil {
t.Errorf("Failed to receive message: %+v", err)
}
}
// Tests Manager.getCallback returns the expected callback and deletes only the
......@@ -97,7 +97,7 @@ func TestManager_RegisterCallback(t *testing.T) {
m := &Manager{callbacks: make(map[Tag]map[uint64]ReceptionCallback)}
msg := Message{Tag: readyTag, ID: initID}
cbChan := make(chan struct{})
cbChan := make(chan struct{}, 1)
cb := func([]byte) { cbChan <- struct{}{} }
m.RegisterCallback(msg.Tag, cb)
......@@ -107,17 +107,17 @@ func TestManager_RegisterCallback(t *testing.T) {
}
go func() {
err = m.processReceivedMessage(data)
if err != nil {
t.Errorf("Failed to receive message: %+v", err)
}
}()
select {
case <-cbChan:
case <-time.After(10 * time.Millisecond):
t.Error("Timed out waiting for callback to be called.")
}
}()
err = m.processReceivedMessage(data)
if err != nil {
t.Errorf("Failed to receive message: %+v", err)
}
}
// Tests that Manager.registerReplyCallback registers a callback that is then
......@@ -129,7 +129,7 @@ func TestManager_registerReplyCallback(t *testing.T) {
}
msg := Message{Tag: readyTag, ID: 5}
cbChan := make(chan struct{})
cbChan := make(chan struct{}, 1)
cb := func([]byte) { cbChan <- struct{}{} }
m.registerReplyCallback(msg.Tag, cb)
m.callbacks[msg.Tag] = map[uint64]ReceptionCallback{msg.ID: cb}
......@@ -140,17 +140,17 @@ func TestManager_registerReplyCallback(t *testing.T) {
}
go func() {
err = m.processReceivedMessage(data)
if err != nil {
t.Errorf("Failed to receive message: %+v", err)
}
}()
select {
case <-cbChan:
case <-time.After(10 * time.Millisecond):
t.Error("Timed out waiting for callback to be called.")
}
}()
err = m.processReceivedMessage(data)
if err != nil {
t.Errorf("Failed to receive message: %+v", err)
}
}
// Tests that Manager.getNextID returns the expected ID for various Tags.
......
......@@ -17,11 +17,12 @@ import (
"github.com/pkg/errors"
jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/xxdk-wasm/utils"
"gitlab.com/elixxir/wasm-utils/utils"
)
// ThreadReceptionCallback is the function that handles incoming data from the
// main thread.
// ThreadReceptionCallback is called with a message received from the main
// thread. Any bytes returned are sent as a response back to the main thread.
// Any returned errors are printed to the log.
type ThreadReceptionCallback func(data []byte) ([]byte, error)
// ThreadManager queues incoming messages from the main thread and handles them
......@@ -34,9 +35,9 @@ type ThreadManager struct {
// main thread keyed on the callback tag.
callbacks map[Tag]ThreadReceptionCallback
// receiveQueue is the channel that all received messages are queued on
// while they wait to be processed.
receiveQueue chan []byte
// receiveQueue is the channel that all received MessageEvent.data are
// queued on while they wait to be processed.
receiveQueue chan js.Value
// quit, when triggered, stops the thread that processes received messages.
quit chan struct{}
......@@ -56,7 +57,7 @@ func NewThreadManager(name string, messageLogging bool) *ThreadManager {
tm := &ThreadManager{
messages: make(chan js.Value, 100),
callbacks: make(map[Tag]ThreadReceptionCallback),
receiveQueue: make(chan []byte, receiveQueueChanSize),
receiveQueue: make(chan js.Value, receiveQueueChanSize),
quit: make(chan struct{}),
name: name,
messageLogging: messageLogging,
......@@ -88,14 +89,24 @@ func (tm *ThreadManager) processThread() {
case <-tm.quit:
jww.INFO.Printf("[WW] [%s] Quitting worker process thread.", tm.name)
return
case message := <-tm.receiveQueue:
if tm.messageLogging {
jww.INFO.Printf("[WW] Worker processors received message: %q", message)
}
err := tm.processReceivedMessage(message)
case msgData := <-tm.receiveQueue:
switch msgData.Type() {
case js.TypeObject:
if msgData.Get("constructor").Equal(utils.Uint8Array) {
err := tm.processReceivedMessage(utils.CopyBytesToGo(msgData))
if err != nil {
jww.ERROR.Printf("[WW] [%s] Failed to receive message from "+
"main thread: %+v", tm.name, err)
jww.ERROR.Printf("[WW] [%s] Failed to process message "+
"received from main thread: %+v", tm.name, err)
}
break
}
fallthrough
default:
jww.ERROR.Printf("[WW] [%s] Cannot handle data of type %s "+
"from main thread: %s",
tm.name, msgData.Type(), utils.JsToJson(msgData))
}
}
}
......@@ -128,7 +139,7 @@ func (tm *ThreadManager) SendMessage(tag Tag, data []byte) {
"to main: %+v", tm.name, msg, tag, err)
}
go tm.postMessage(string(payload))
go tm.postMessage(payload)
}
// sendResponse sends a reply to the main thread with the given tag and ID.
......@@ -151,14 +162,14 @@ func (tm *ThreadManager) sendResponse(tag Tag, id uint64, data []byte) error {
"%d going to main: %+v", msg, tag, id, err)
}
go tm.postMessage(string(payload))
go tm.postMessage(payload)
return nil
}
// receiveMessage is registered with the Javascript event listener and is called
// every time a new message from the main thread is received.
func (tm *ThreadManager) receiveMessage(data []byte) {
func (tm *ThreadManager) receiveMessage(data js.Value) {
tm.receiveQueue <- data
}
......@@ -224,7 +235,7 @@ func (tm *ThreadManager) addEventListeners() {
// occurs when a message is received from the main thread.
// Doc: https://developer.mozilla.org/en-US/docs/Web/API/Worker/message_event
messageEvent := js.FuncOf(func(_ js.Value, args []js.Value) any {
tm.receiveMessage([]byte(args[0].Get("data").String()))
tm.receiveMessage(args[0].Get("data"))
return nil
})
......@@ -233,8 +244,8 @@ func (tm *ThreadManager) addEventListeners() {
// Doc: https://developer.mozilla.org/en-US/docs/Web/API/Worker/error_event
errorEvent := js.FuncOf(func(_ js.Value, args []js.Value) any {
event := args[0]
jww.ERROR.Printf("[WW] [%s] Worker received error event: %s",
tm.name, utils.JsErrorToJson(event))
jww.ERROR.Printf("[WW] [%s] Worker received error event: %+v",
tm.name, js.Error{Value: event})
return nil
})
......@@ -243,8 +254,8 @@ func (tm *ThreadManager) addEventListeners() {
// Doc: https://developer.mozilla.org/en-US/docs/Web/API/Worker/messageerror_event
messageerrorEvent := js.FuncOf(func(_ js.Value, args []js.Value) any {
event := args[0]
jww.ERROR.Printf("[WW] [%s] Worker received message error event: %s",
tm.name, utils.JsErrorToJson(event))
jww.ERROR.Printf("[WW] [%s] Worker received message error event: %+v",
tm.name, js.Error{Value: event})
return nil
})
......@@ -260,10 +271,16 @@ func (tm *ThreadManager) addEventListeners() {
// aMessage must be a js.Value or a primitive type that can be converted via
// js.ValueOf. The Javascript object must be "any value or JavaScript object
// handled by the structured clone algorithm". See the doc for more information.
// aMessage is the object to deliver to the main thread; this will be in the
// data field in the event delivered to the thread. It must be a transferable
// object because this function transfers ownership of the message instead of
// copying it for better performance. See the doc for more information.
//
// Doc: https://developer.mozilla.org/docs/Web/API/DedicatedWorkerGlobalScope/postMessage
func (tm *ThreadManager) postMessage(aMessage any) {
js.Global().Call("postMessage", aMessage)
func (tm *ThreadManager) postMessage(aMessage []byte) {
buffer := utils.CopyBytesToJS(aMessage)
js.Global().Call("postMessage", buffer, []any{buffer.Get("buffer")})
}
// close discards any tasks queued in the worker's event loop, effectively
......
......@@ -20,7 +20,7 @@ func TestThreadManager_processReceivedMessage(t *testing.T) {
tm := &ThreadManager{callbacks: make(map[Tag]ThreadReceptionCallback)}
msg := Message{Tag: readyTag, ID: 5}
cbChan := make(chan struct{})
cbChan := make(chan struct{}, 1)
cb := func([]byte) ([]byte, error) { cbChan <- struct{}{}; return nil, nil }
tm.callbacks[msg.Tag] = cb
......@@ -30,17 +30,17 @@ func TestThreadManager_processReceivedMessage(t *testing.T) {
}
go func() {
err = tm.processReceivedMessage(data)
if err != nil {
t.Errorf("Failed to receive message: %+v", err)
}
}()
select {
case <-cbChan:
case <-time.After(10 * time.Millisecond):
t.Error("Timed out waiting for callback to be called.")
}
}()
err = tm.processReceivedMessage(data)
if err != nil {
t.Errorf("Failed to receive message: %+v", err)
}
}
// Tests that ThreadManager.RegisterCallback registers a callback that is then
......@@ -49,7 +49,7 @@ func TestThreadManager_RegisterCallback(t *testing.T) {
tm := &ThreadManager{callbacks: make(map[Tag]ThreadReceptionCallback)}
msg := Message{Tag: readyTag, ID: 5}
cbChan := make(chan struct{})
cbChan := make(chan struct{}, 1)
cb := func([]byte) ([]byte, error) { cbChan <- struct{}{}; return nil, nil }
tm.RegisterCallback(msg.Tag, cb)
......@@ -59,15 +59,15 @@ func TestThreadManager_RegisterCallback(t *testing.T) {
}
go func() {
err = tm.processReceivedMessage(data)
if err != nil {
t.Errorf("Failed to receive message: %+v", err)
}
}()
select {
case <-cbChan:
case <-time.After(10 * time.Millisecond):
t.Error("Timed out waiting for callback to be called.")
}
}()
err = tm.processReceivedMessage(data)
if err != nil {
t.Errorf("Failed to receive message: %+v", err)
}
}