diff --git a/go.mod b/go.mod index 7ad5bd5a28679e5085b85792726e4bc68b0ce78c..1ebdbb75cce58076455135b58c8c2ca213531ee9 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/hack-pad/go-indexeddb v0.2.0 github.com/pkg/errors v0.9.1 github.com/spf13/jwalterweatherman v1.1.0 - gitlab.com/elixxir/client v1.5.1-0.20220924203712-7d4b1dce86b8 + gitlab.com/elixxir/client v1.5.1-0.20220925005456-24eb354b1d6f gitlab.com/elixxir/crypto v0.0.7-0.20220923233816-0364f1b203c6 gitlab.com/elixxir/primitives v0.0.3-0.20220901220638-1acc75fabdc6 gitlab.com/xx_network/primitives v0.0.4-0.20220809193445-9fc0a5209548 diff --git a/go.sum b/go.sum index a6b844fe56cad8ffc710ab66934718a32b34ef1e..ec84476e30dedc0b420fb13ca4d05799d1b55434 100644 --- a/go.sum +++ b/go.sum @@ -630,6 +630,10 @@ gitlab.com/elixxir/bloomfilter v0.0.0-20211222005329-7d931ceead6f h1:yXGvNBqzZwA gitlab.com/elixxir/bloomfilter v0.0.0-20211222005329-7d931ceead6f/go.mod h1:H6jztdm0k+wEV2QGK/KYA+MY9nj9Zzatux/qIvDDv3k= gitlab.com/elixxir/client v1.5.1-0.20220924203712-7d4b1dce86b8 h1:A1x9EJOWm6YiaAJG5SPHXiwsDvik2XGSjeSylJbDBBk= gitlab.com/elixxir/client v1.5.1-0.20220924203712-7d4b1dce86b8/go.mod h1:z1Bdlja75CF3UrzifMC0LQwjlEdOcJCfXEX5k9AKQTQ= +gitlab.com/elixxir/client v1.5.1-0.20220925004736-f9acd4f64d77 h1:wjyV+vXxAAapD8BzHNoYV8ROoaVyQi//h+TKjGjOIWw= +gitlab.com/elixxir/client v1.5.1-0.20220925004736-f9acd4f64d77/go.mod h1:z1Bdlja75CF3UrzifMC0LQwjlEdOcJCfXEX5k9AKQTQ= +gitlab.com/elixxir/client v1.5.1-0.20220925005456-24eb354b1d6f h1:m0jwFnBatQH/3uIhSwO0le06ky80LLuzqKD+Xd4nwXk= +gitlab.com/elixxir/client v1.5.1-0.20220925005456-24eb354b1d6f/go.mod h1:z1Bdlja75CF3UrzifMC0LQwjlEdOcJCfXEX5k9AKQTQ= gitlab.com/elixxir/comms v0.0.4-0.20220916185715-f1e9a5eda939 h1:+VRx2ULHKs040bBhDAOKNCZnbcXxUk3jD9JoKQzQpLk= gitlab.com/elixxir/comms v0.0.4-0.20220916185715-f1e9a5eda939/go.mod h1:AO6XkMhaHJW8eXlgL5m3UUcJqsSP8F5Wm1GX+wyq/rw= gitlab.com/elixxir/crypto v0.0.0-20200804182833-984246dea2c4/go.mod h1:ucm9SFKJo+K0N2GwRRpaNr+tKXMIOVWzmyUD0SbOu2c= diff --git a/main.go b/main.go index 072ea2537c4f595b85dd1d923187239026735f9e..a7042228bd1a49304f7bccaae7c4c973755a359c 100644 --- a/main.go +++ b/main.go @@ -49,9 +49,11 @@ func main() { js.Global().Set("GetPublicChannelIdentityFromPrivate", js.FuncOf(wasm.GetPublicChannelIdentityFromPrivate)) js.Global().Set("NewChannelsManager", js.FuncOf(wasm.NewChannelsManager)) + js.Global().Set("LoadChannelsManager", js.FuncOf(wasm.LoadChannelsManager)) js.Global().Set("NewChannelsManagerWithIndexedDb", js.FuncOf(wasm.NewChannelsManagerWithIndexedDb)) - js.Global().Set("LoadChannelsManager", js.FuncOf(wasm.LoadChannelsManager)) + js.Global().Set("LoadChannelsManagerWithIndexedDb", + js.FuncOf(wasm.LoadChannelsManagerWithIndexedDb)) js.Global().Set("GenerateChannel", js.FuncOf(wasm.GenerateChannel)) js.Global().Set("GetChannelInfo", js.FuncOf(wasm.GetChannelInfo)) js.Global().Set("IsNicknameValid", js.FuncOf(wasm.IsNicknameValid)) diff --git a/wasm/channels.go b/wasm/channels.go index 550ba506f4e0e08bbff1b1bf9beb49434195eab8..61e2012a4a2f875895ee2333d2c0202fd9b43c51 100644 --- a/wasm/channels.go +++ b/wasm/channels.go @@ -10,8 +10,7 @@ package wasm import ( - "encoding/base64" - "gitlab.com/elixxir/crypto/channel" + "gitlab.com/elixxir/client/channels" "syscall/js" "gitlab.com/elixxir/client/bindings" @@ -131,6 +130,24 @@ func GetPublicChannelIdentityFromPrivate(_ js.Value, args []js.Value) interface{ return utils.CopyBytesToJS(identity) } +// eventModelBuilder adheres to the [bindings.EventModelBuilder] interface. +type eventModelBuilder struct { + build func(args ...interface{}) js.Value +} + +// Build initializes and returns the event model. +func (emb *eventModelBuilder) Build(path string) bindings.EventModel { + emJs := emb.build(path) + return &eventModel{ + joinChannel: utils.WrapCB(emJs, "JoinChannel"), + leaveChannel: utils.WrapCB(emJs, "LeaveChannel"), + receiveMessage: utils.WrapCB(emJs, "ReceiveMessage"), + receiveReply: utils.WrapCB(emJs, "ReceiveReply"), + receiveReaction: utils.WrapCB(emJs, "ReceiveReaction"), + updateSentStatus: utils.WrapCB(emJs, "UpdateSentStatus"), + } +} + // NewChannelsManager creates a new [ChannelsManager] from a new private // identity ([channel.PrivateIdentity]). // @@ -144,22 +161,17 @@ func GetPublicChannelIdentityFromPrivate(_ js.Value, args []js.Value) interface{ // using [Cmix.GetID]. // - args[1] - Bytes of a private identity ([channel.PrivateIdentity]) that is // generated by [GenerateChannelIdentity] (Uint8Array). -// - args[2] - Javascript object that matches the [bindings.EventModel] -// interface. +// - args[2] - A function that initialises and returns a Javascript object that +// matches the [bindings.EventModel] interface. The function must match the +// Build function in [bindings.EventModelBuilder]. // // Returns: // - Javascript representation of the [ChannelsManager] object. // - Throws a TypeError if creating the manager fails. func NewChannelsManager(_ js.Value, args []js.Value) interface{} { privateIdentity := utils.CopyBytesToGo(args[1]) - em := &eventModel{ - joinChannel: utils.WrapCB(args[2], "JoinChannel"), - leaveChannel: utils.WrapCB(args[2], "LeaveChannel"), - receiveMessage: utils.WrapCB(args[2], "ReceiveMessage"), - receiveReply: utils.WrapCB(args[2], "ReceiveReply"), - receiveReaction: utils.WrapCB(args[2], "ReceiveReaction"), - updateSentStatus: utils.WrapCB(args[2], "UpdateSentStatus"), - } + + em := &eventModelBuilder{args[2].Invoke} cm, err := bindings.NewChannelsManager(args[0].Int(), privateIdentity, em) if err != nil { @@ -170,13 +182,43 @@ func NewChannelsManager(_ js.Value, args []js.Value) interface{} { return newChannelsManagerJS(cm) } +// LoadChannelsManager loads an existing [ChannelsManager]. +// +// This is for loading a manager for an identity that has already been created. +// The channel manager should have previously been created with +// [NewChannelsManager] and the storage is retrievable with +// [ChannelsManager.GetStorageTag]. +// +// Parameters: +// - args[0] - ID of [Cmix] object in tracker (int). This can be retrieved +// using [Cmix.GetID]. +// - args[1] - The storage tag associated with the previously created channel +// manager and retrieved with [ChannelsManager.GetStorageTag] (string). +// - args[2] - A function that initialises and returns a Javascript object that +// matches the [bindings.EventModel] interface. The function must match the +// Build function in [bindings.EventModelBuilder]. +// +// Returns: +// - Javascript representation of the [ChannelsManager] object. +// - Throws a TypeError if loading the manager fails. +func LoadChannelsManager(_ js.Value, args []js.Value) interface{} { + em := &eventModelBuilder{args[2].Invoke} + cm, err := bindings.LoadChannelsManager(args[0].Int(), args[1].String(), em) + if err != nil { + utils.Throw(utils.TypeError, err) + return nil + } + + return newChannelsManagerJS(cm) +} + // NewChannelsManagerWithIndexedDb creates a new [ChannelsManager] from a new // private identity ([channel.PrivateIdentity]) and using indexedDb as a backend // to manage the event model. // // This is for creating a manager for an identity for the first time. For // generating a new one channel identity, use [GenerateChannelIdentity]. To -// reload this channel manager, use [LoadChannelsManagerGoEventModel], passing +// reload this channel manager, use [LoadChannelsManagerWithIndexedDb], passing // in the storage tag retrieved by [ChannelsManager.GetStorageTag]. // // This function initialises an indexedDb database. @@ -194,22 +236,18 @@ func NewChannelsManager(_ js.Value, args []js.Value) interface{} { func NewChannelsManagerWithIndexedDb(_ js.Value, args []js.Value) interface{} { privateIdentity := utils.CopyBytesToGo(args[1]) - // Get the public key to use as a key for indexedDb - pi, err := channel.UnmarshalPrivateIdentity(privateIdentity) - if err != nil { - utils.Throw(utils.TypeError, err) - return nil - } + emBuilder := func(path string) channels.EventModel { + em, err := indexedDb.NewWasmEventModel(path) + if err != nil { + utils.Throw(utils.TypeError, err) + return nil + } - key := base64.StdEncoding.EncodeToString(pi.Identity.PubKey) - em, err := indexedDb.NewWasmEventModel(key) - if err != nil { - utils.Throw(utils.TypeError, err) - return nil + return em } cm, err := bindings.NewChannelsManagerGoEventModel( - args[0].Int(), privateIdentity, em) + args[0].Int(), privateIdentity, emBuilder) if err != nil { utils.Throw(utils.TypeError, err) return nil @@ -218,11 +256,12 @@ func NewChannelsManagerWithIndexedDb(_ js.Value, args []js.Value) interface{} { return newChannelsManagerJS(cm) } -// LoadChannelsManager loads an existing [ChannelsManager]. +// LoadChannelsManagerWithIndexedDb loads an existing [ChannelsManager] using +// an existing indexedDb database as a backend to manage the event model. // // This is for loading a manager for an identity that has already been created. // The channel manager should have previously been created with -// [NewChannelsManager] and the storage is retrievable with +// [NewChannelsManagerWithIndexedDb] and the storage is retrievable with // [ChannelsManager.GetStorageTag]. // // Parameters: @@ -230,23 +269,23 @@ func NewChannelsManagerWithIndexedDb(_ js.Value, args []js.Value) interface{} { // using [Cmix.GetID]. // - args[1] - The storage tag associated with the previously created channel // manager and retrieved with [ChannelsManager.GetStorageTag] (string). -// - args[2] - Javascript object that matches the [bindings.EventModel] -// interface. // // Returns: // - Javascript representation of the [ChannelsManager] object. // - Throws a TypeError if loading the manager fails. -func LoadChannelsManager(_ js.Value, args []js.Value) interface{} { - em := &eventModel{ - joinChannel: utils.WrapCB(args[2], "JoinChannel"), - leaveChannel: utils.WrapCB(args[2], "LeaveChannel"), - receiveMessage: utils.WrapCB(args[2], "ReceiveMessage"), - receiveReply: utils.WrapCB(args[2], "ReceiveReply"), - receiveReaction: utils.WrapCB(args[2], "ReceiveReaction"), - updateSentStatus: utils.WrapCB(args[2], "UpdateSentStatus"), +func LoadChannelsManagerWithIndexedDb(_ js.Value, args []js.Value) interface{} { + emBuilder := func(path string) channels.EventModel { + em, err := indexedDb.NewWasmEventModel(path) + if err != nil { + utils.Throw(utils.TypeError, err) + return nil + } + + return em } - cm, err := bindings.LoadChannelsManager(args[0].Int(), args[1].String(), em) + cm, err := bindings.LoadChannelsManagerGoEventModel( + args[0].Int(), args[1].String(), emBuilder) if err != nil { utils.Throw(utils.TypeError, err) return nil