//:build wasm package ext import ( "git.smesh.lol/musiquay/web/common/jsbridge/callback" "unsafe" ) //:wasmimport bridge ext_storage_get func wasmStorageGet(kPtr *byte, kLen int32, kCap int32, cbID int32) //:wasmimport bridge ext_storage_set func wasmStorageSet(kPtr *byte, kLen int32, kCap int32, vPtr *byte, vLen int32, vCap int32) //:wasmimport bridge ext_storage_remove func wasmStorageRemove(kPtr *byte, kLen int32, kCap int32) //:wasmimport bridge ext_on_message func wasmOnMessage(cbID int32) //:wasmimport bridge ext_send_message_to_tab func wasmSendMessageToTab(tabID int32, msgPtr *byte, msgLen int32, msgCap int32) //:wasmimport bridge ext_get_active_tab func wasmGetActiveTab(cbID int32) //:wasmimport bridge ext_console_log func wasmConsoleLog(ptr *byte, length int32, capacity int32) //:wasmimport bridge ext_session_get func wasmSessionGet(kPtr *byte, kLen int32, kCap int32, cbID int32) //:wasmimport bridge ext_session_set func wasmSessionSet(kPtr *byte, kLen int32, kCap int32, vPtr *byte, vLen int32, vCap int32) //:wasmimport bridge ext_is_in_page func wasmIsInPage() (n int32) //:wasmimport bridge ext_on_message_respond func wasmOnMessageRespond(reqID int32, ptr *byte, length int32, capacity int32) //:wasmimport bridge signer_signal_ready func wasmSignalReady() // SignalReady tells the host that asynchronous boot work (e.g. vault load) // has completed and the signer is safe to receive method calls. The host // queues all method calls before this signal arrives. func SignalReady() { wasmSignalReady() } func StorageGet(key string, fn func(string)) { wasmStorageGet(unsafe.StringData(key), int32(len(key)), int32(len(key)), callback.RegisterSOnce(fn)) } func StorageSet(key, value string) { wasmStorageSet( unsafe.StringData(key), int32(len(key)), int32(len(key)), unsafe.StringData(value), int32(len(value)), int32(len(value)), ) } func StorageRemove(key string) { wasmStorageRemove(unsafe.StringData(key), int32(len(key)), int32(len(key))) } // extState holds the bridge's mutable state. Package globals are immutable // outside init, so the handler and the in-flight request id live in a // self-mutating type and are written through its methods. type extState struct { onMessage func(string, string, int32, func(string)) reqID int32 } var st *extState func (s *extState) SetHandler(fn func(string, string, int32, func(string))) { s.onMessage = fn } func (s *extState) Handler() (fn func(string, string, int32, func(string))) { return s.onMessage } func (s *extState) SetReqID(id int32) { s.reqID = id } func (s *extState) ReqID() (id int32) { return s.reqID } func OnMessage(fn func(string, string, int32, func(string))) { st.SetHandler(fn) wasmOnMessage(0) } //:wasmexport __hook_ext_on_message func hookExtOnMessage(reqID int32, methodPtr *byte, methodLen int32, paramsPtr *byte, paramsLen int32, tabID int32) { fn := st.Handler() if fn == nil { return } st.SetReqID(reqID) method := ptrToString(methodPtr, methodLen) params := ptrToString(paramsPtr, paramsLen) fn(method, params, tabID, respondPending) } func respondPending(resp string) { wasmOnMessageRespond(st.ReqID(), unsafe.StringData(resp), int32(len(resp)), int32(len(resp))) } func SendMessageToTab(tabID int32, msg string) { wasmSendMessageToTab(tabID, unsafe.StringData(msg), int32(len(msg)), int32(len(msg))) } func GetActiveTab(fn func(int32, string)) { wasmGetActiveTab(callback.RegisterISOnce(fn)) } func ConsoleLog(msg string) { wasmConsoleLog(unsafe.StringData(msg), int32(len(msg)), int32(len(msg))) } func SessionGet(key string, fn func(string)) { wasmSessionGet(unsafe.StringData(key), int32(len(key)), int32(len(key)), callback.RegisterSOnce(fn)) } func SessionSet(key, value string) { wasmSessionSet( unsafe.StringData(key), int32(len(key)), int32(len(key)), unsafe.StringData(value), int32(len(value)), int32(len(value)), ) } func IsInPage() (ok bool) { return wasmIsInPage() != 0 } func ptrToString(ptr *byte, length int32) (s string) { if ptr == nil || length <= 0 { return "" } return unsafe.String(ptr, length) } func init() { st = &extState{} }