From 408d04ee982ecc68295da70820bb29e4089b38e1 Mon Sep 17 00:00:00 2001 From: Jono Wenger <jono@elixxir.io> Date: Fri, 10 Feb 2023 15:02:45 -0800 Subject: [PATCH] Fix bindings --- go.mod | 2 +- go.sum | 4 +-- main.go | 2 ++ wasm/channels.go | 80 +++++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 77 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index 36bb6b57..10df8563 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/spf13/cobra v1.5.0 github.com/spf13/jwalterweatherman v1.1.0 - gitlab.com/elixxir/client/v4 v4.3.12-0.20230130171647-cc3cced382ea + gitlab.com/elixxir/client/v4 v4.3.12-0.20230210230035-3659a70d7550 gitlab.com/elixxir/crypto v0.0.7-0.20230124220743-2a897bc01c59 gitlab.com/elixxir/primitives v0.0.3-0.20230109222259-f62b2a90b62c gitlab.com/xx_network/crypto v0.0.5-0.20230124215920-951bed503c49 diff --git a/go.sum b/go.sum index 256dd333..144015ee 100644 --- a/go.sum +++ b/go.sum @@ -401,8 +401,8 @@ github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= gitlab.com/elixxir/bloomfilter v0.0.0-20211222005329-7d931ceead6f h1:yXGvNBqzZwAhDYlSnxPRbgor6JWoOt1Z7s3z1O9JR40= gitlab.com/elixxir/bloomfilter v0.0.0-20211222005329-7d931ceead6f/go.mod h1:H6jztdm0k+wEV2QGK/KYA+MY9nj9Zzatux/qIvDDv3k= -gitlab.com/elixxir/client/v4 v4.3.12-0.20230130171647-cc3cced382ea h1:EeiPFLu/FLHN2XmbhLr8wAJrpoFx4JvWkYsn8FPiDLw= -gitlab.com/elixxir/client/v4 v4.3.12-0.20230130171647-cc3cced382ea/go.mod h1:OrNnBWm0nGiY/BK2ZNzjR6V0fS4+/aAYtVRE/d8uZ48= +gitlab.com/elixxir/client/v4 v4.3.12-0.20230210230035-3659a70d7550 h1:hxzb7o1otcwbnnM8l5Wbo1wrxjcwh8iOa32/iBVpRYE= +gitlab.com/elixxir/client/v4 v4.3.12-0.20230210230035-3659a70d7550/go.mod h1:OrNnBWm0nGiY/BK2ZNzjR6V0fS4+/aAYtVRE/d8uZ48= gitlab.com/elixxir/comms v0.0.4-0.20230116232020-39f76a2aeccc h1:sVcXrXylB4w4vMFTvPIssRNwz2FSTbyrtZTD921LRKo= gitlab.com/elixxir/comms v0.0.4-0.20230116232020-39f76a2aeccc/go.mod h1:Bb6XF9bC9TmuiklC4eWTeqSiZ0zMOTcMs5UFOp5DZlg= gitlab.com/elixxir/crypto v0.0.7-0.20230124220743-2a897bc01c59 h1:Imj5MSbTN+FtpRH+5Saf43YKU92J3cKvW9MpJ/QykcY= diff --git a/main.go b/main.go index 47552238..f170f646 100644 --- a/main.go +++ b/main.go @@ -89,6 +89,8 @@ func main() { js.Global().Set("GetShareUrlType", js.FuncOf(wasm.GetShareUrlType)) js.Global().Set("ValidForever", js.FuncOf(wasm.ValidForever)) js.Global().Set("IsNicknameValid", js.FuncOf(wasm.IsNicknameValid)) + js.Global().Set("GetNoMessageErr", js.FuncOf(wasm.GetNoMessageErr)) + js.Global().Set("CheckNoMessageErr", js.FuncOf(wasm.CheckNoMessageErr)) js.Global().Set("NewChannelsDatabaseCipher", js.FuncOf(wasm.NewChannelsDatabaseCipher)) diff --git a/wasm/channels.go b/wasm/channels.go index 43ae72bd..73655407 100644 --- a/wasm/channels.go +++ b/wasm/channels.go @@ -402,6 +402,7 @@ func NewChannelsManagerWithIndexedDb(_ js.Value, args []js.Value) any { // Returns a promise: // - Resolves to a Javascript representation of the [ChannelsManager] object. // - Rejected with an error if loading indexedDb or the manager fails. +// // FIXME: package names in comments for indexedDb func NewChannelsManagerWithIndexedDbUnsafe(_ js.Value, args []js.Value) any { cmixID := args[0].Int() @@ -437,7 +438,7 @@ func newChannelsManagerWithIndexedDb(cmixID int, wasmJsPath string, promiseFn := func(resolve, reject func(args ...any) js.Value) { cm, err := bindings.NewChannelsManagerGoEventModel( - cmixID, privateIdentity, model) + cmixID, privateIdentity, model, nil) if err != nil { reject(utils.JsTrace(err)) } else { @@ -574,7 +575,7 @@ func loadChannelsManagerWithIndexedDb(cmixID int, wasmJsPath, storageTag string, promiseFn := func(resolve, reject func(args ...any) js.Value) { cm, err := bindings.LoadChannelsManagerGoEventModel( - cmixID, storageTag, model) + cmixID, storageTag, model, nil) if err != nil { reject(utils.JsTrace(err)) } else { @@ -1673,6 +1674,30 @@ func (cm *ChannelsManager) RegisterReceiveHandler(_ js.Value, args []js.Value) a // Event Model Logic // //////////////////////////////////////////////////////////////////////////////// +// GetNoMessageErr returns the error channels.NoMessageErr, which must be +// returned by EventModel methods (such as EventModel.UpdateFromUUID, +// EventModel.UpdateFromMessageID, and EventModel.GetMessage) when the message +// cannot be found. +// +// Returns: +// - channels.NoMessageErr error message (string). +func GetNoMessageErr(js.Value, []js.Value) any { + return bindings.GetNoMessageErr() +} + +// CheckNoMessageErr determines if the error returned by an EventModel function +// indicates that the message or item does not exist. It returns true if the +// error contains channels.NoMessageErr. +// +// Parameters: +// - args[0] - Error to check (Error). +// +// Returns +// - True if the error contains channels.NoMessageErr (boolean). +func CheckNoMessageErr(_ js.Value, args []js.Value) any { + return bindings.CheckNoMessageErr(utils.JsErrorToJson(args[0])) +} + // eventModelBuilder adheres to the [bindings.EventModelBuilder] interface. type eventModelBuilder struct { build func(args ...any) js.Value @@ -1864,13 +1889,22 @@ func (em *eventModel) ReceiveReaction(channelID, messageID, reactionTo []byte, // - uuid - The unique identifier of the message in the database (int). // - messageUpdateInfoJSON - JSON of [bindings.MessageUpdateInfo] // (Uint8Array). -func (em *eventModel) UpdateFromUUID(uuid int64, messageUpdateInfoJSON []byte) { - em.updateFromUUID(uuid, utils.CopyBytesToJS(messageUpdateInfoJSON)) +// +// Returns: +// - Returns an error if the message cannot be updated. It must return the +// error from [GetNoMessageErr] if the message does not exist. +func (em *eventModel) UpdateFromUUID( + uuid int64, messageUpdateInfoJSON []byte) error { + err := em.updateFromUUID(uuid, utils.CopyBytesToJS(messageUpdateInfoJSON)) + return js.Error{Value: err} } // UpdateFromMessageID is called whenever a message with the message ID is // modified. // +// Note for developers: The internal Javascript function must return JSON of +// [UuidAndError], which includes the returned UUID or an error. +// // Parameters: // - messageID - The bytes of the [channel.MessageID] of the received message // (Uint8Array). @@ -1880,16 +1914,31 @@ func (em *eventModel) UpdateFromUUID(uuid int64, messageUpdateInfoJSON []byte) { // Returns: // - A non-negative unique uuid for the modified message by which it can be // referenced later with [EventModel.UpdateFromUUID] int). +// - Returns an error if the message cannot be updated. It must return the +// error from [GetNoMessageErr] if the message does not exist. func (em *eventModel) UpdateFromMessageID( - messageID []byte, messageUpdateInfoJSON []byte) int64 { - return int64(em.updateFromMessageID(utils.CopyBytesToJS(messageID), - utils.CopyBytesToJS(messageUpdateInfoJSON)).Int()) + messageID []byte, messageUpdateInfoJSON []byte) (int64, error) { + uuidAndErrorBytes := utils.CopyBytesToGo(em.updateFromMessageID( + utils.CopyBytesToJS(messageID), + utils.CopyBytesToJS(messageUpdateInfoJSON))) + + var uae UuidAndError + err := json.Unmarshal(uuidAndErrorBytes, &uae) + if err != nil { + return 0, err + } + + if uae.Error != "" { + return 0, errors.New(uae.Error) + } + + return uae.UUID, nil } // GetMessage returns the message with the given [channel.MessageID]. // // Note for developers: The internal Javascript function must return JSON of -// MessageAndError, which includes the returned [channels.ModelMessage] or any +// [MessageAndError], which includes the returned [channels.ModelMessage] or any // error that occurs during lookup. // // Parameters: @@ -1940,6 +1989,21 @@ func (em *eventModel) MuteUser(channelID, pubkey []byte, unmute bool) { utils.CopyBytesToJS(channelID), utils.CopyBytesToJS(pubkey), unmute) } +// UuidAndError contains a UUID returned by an eventModel method or any possible +// error that occurs. Only one field should be present at a time. +// +// Example JSON: +// +// { "uuid": 5, } +// +// Or: +// +// { "error": "An error occurred." } +type UuidAndError struct { + UUID int64 `json:"uuid,omitempty"` + Error string `json:"error,omitempty"` +} + // MessageAndError contains a message returned by eventModel.GetMessage or any // possible error that occurs during lookup. Only one field should be present at // a time; if an error occurs, ModelMessage should be empty. -- GitLab