sw_wasm.mx raw

   1  //:build wasm
   2  
   3  package sw
   4  
   5  import (
   6  	"git.smesh.lol/musiquay/web/common/jsbridge/callback"
   7  	"unsafe"
   8  )
   9  
  10  // --- Lifecycle ---
  11  
  12  //:wasmimport bridge sw_on_install
  13  func wasmOnInstall(cbID int32)
  14  
  15  //:wasmimport bridge sw_on_activate
  16  func wasmOnActivate(cbID int32)
  17  
  18  //:wasmimport bridge sw_on_fetch
  19  func wasmOnFetch(cbID int32)
  20  
  21  //:wasmimport bridge sw_on_message
  22  func wasmOnMessage(cbID int32)
  23  
  24  func OnInstall(fn func(Event))  { wasmOnInstall(callback.RegisterI(func(e int32) { fn(Event(e)) })) }
  25  func OnActivate(fn func(Event)) { wasmOnActivate(callback.RegisterI(func(e int32) { fn(Event(e)) })) }
  26  func OnFetch(fn func(Event))    { wasmOnFetch(callback.RegisterI(func(e int32) { fn(Event(e)) })) }
  27  func OnMessage(fn func(Event))  { wasmOnMessage(callback.RegisterI(func(e int32) { fn(Event(e)) })) }
  28  
  29  // --- Event methods ---
  30  
  31  //:wasmimport bridge sw_wait_until
  32  func wasmWaitUntil(event int32, cbID int32)
  33  
  34  //:wasmimport bridge sw_respond_with
  35  func wasmRespondWith(event int32, resp int32)
  36  
  37  //:wasmimport bridge sw_respond_with_network
  38  func wasmRespondWithNetwork(event int32)
  39  
  40  //:wasmimport bridge sw_respond_with_cache_first
  41  func wasmRespondWithCacheFirst(event int32)
  42  
  43  //:wasmimport bridge sw_respond_with_network_first
  44  func wasmRespondWithNetworkFirst(event int32)
  45  
  46  //:wasmimport bridge sw_respond_with_proxy_cache
  47  func wasmRespondWithProxyCache(event int32)
  48  
  49  //:wasmimport bridge sw_prune_proxy_cache
  50  func wasmPruneProxyCache(maxAgeMs int64, cbID int32)
  51  
  52  //:wasmimport bridge sw_get_request_url
  53  func wasmGetRequestURL(event int32, outPtr *int32, outLen *int32)
  54  
  55  //:wasmimport bridge sw_get_request_path
  56  func wasmGetRequestPath(event int32, outPtr *int32, outLen *int32)
  57  
  58  //:wasmimport bridge sw_get_message_data
  59  func wasmGetMessageData(event int32, outPtr *int32, outLen *int32)
  60  
  61  //:wasmimport bridge sw_get_message_client_id
  62  func wasmGetMessageClientID(event int32, outPtr *int32, outLen *int32)
  63  
  64  func WaitUntil(event Event, fn func(done func())) {
  65  	doneID := callback.Register0Once(func() {})
  66  	wasmWaitUntil(int32(event), doneID)
  67  	fn(func() {
  68  		callback.Release(doneID)
  69  	})
  70  }
  71  
  72  func RespondWith(event Event, resp Response)    { wasmRespondWith(int32(event), int32(resp)) }
  73  func RespondWithNetwork(event Event)            { wasmRespondWithNetwork(int32(event)) }
  74  func RespondWithCacheFirst(event Event)         { wasmRespondWithCacheFirst(int32(event)) }
  75  func RespondWithNetworkFirst(event Event)       { wasmRespondWithNetworkFirst(int32(event)) }
  76  func RespondWithProxyCache(event Event)         { wasmRespondWithProxyCache(int32(event)) }
  77  
  78  func PruneProxyCache(maxAgeMs int64, fn func()) {
  79  	wasmPruneProxyCache(maxAgeMs, callback.Register0Once(fn))
  80  }
  81  
  82  func GetRequestURL(event Event) (s string) {
  83  	var rPtr, rLen int32
  84  	wasmGetRequestURL(int32(event), &rPtr, &rLen)
  85  	return ptrToString(rPtr, rLen)
  86  }
  87  
  88  func GetRequestPath(event Event) (s string) {
  89  	var rPtr, rLen int32
  90  	wasmGetRequestPath(int32(event), &rPtr, &rLen)
  91  	return ptrToString(rPtr, rLen)
  92  }
  93  
  94  func GetMessageData(event Event) (s string) {
  95  	var rPtr, rLen int32
  96  	wasmGetMessageData(int32(event), &rPtr, &rLen)
  97  	return ptrToString(rPtr, rLen)
  98  }
  99  
 100  func GetMessageClientID(event Event) (s string) {
 101  	var rPtr, rLen int32
 102  	wasmGetMessageClientID(int32(event), &rPtr, &rLen)
 103  	return ptrToString(rPtr, rLen)
 104  }
 105  
 106  // --- SW globals ---
 107  
 108  //:wasmimport bridge sw_origin
 109  func wasmOrigin(outPtr *int32, outLen *int32)
 110  
 111  //:wasmimport bridge sw_skip_waiting
 112  func wasmSkipWaiting()
 113  
 114  //:wasmimport bridge sw_claim_clients
 115  func wasmClaimClients(cbID int32)
 116  
 117  //:wasmimport bridge sw_match_clients
 118  func wasmMatchClients(cbID int32)
 119  
 120  //:wasmimport bridge sw_post_message
 121  func wasmPostMessage(client int32, ptr *byte, length int32, capacity int32)
 122  
 123  //:wasmimport bridge sw_post_message_json
 124  func wasmPostMessageJSON(client int32, ptr *byte, length int32, capacity int32)
 125  
 126  //:wasmimport bridge sw_get_client_by_id
 127  func wasmGetClientByID(ptr *byte, length int32, capacity int32, cbID int32)
 128  
 129  //:wasmimport bridge sw_navigate
 130  func wasmNavigate(client int32, ptr *byte, length int32, capacity int32)
 131  
 132  func Origin() (s string) {
 133  	var rPtr, rLen int32
 134  	wasmOrigin(&rPtr, &rLen)
 135  	return ptrToString(rPtr, rLen)
 136  }
 137  
 138  func SkipWaiting() { wasmSkipWaiting() }
 139  
 140  func ClaimClients(done func()) {
 141  	wasmClaimClients(callback.Register0Once(done))
 142  }
 143  
 144  func MatchClients(fn func(Client)) {
 145  	wasmMatchClients(callback.RegisterI(func(c int32) { fn(Client(c)) }))
 146  }
 147  
 148  func PostMessage(client Client, msg string) {
 149  	wasmPostMessage(int32(client), unsafe.StringData(msg), int32(len(msg)), int32(len(msg)))
 150  }
 151  
 152  func PostMessageJSON(client Client, json string) {
 153  	wasmPostMessageJSON(int32(client), unsafe.StringData(json), int32(len(json)), int32(len(json)))
 154  }
 155  
 156  func GetClientByID(id string, fn func(Client, bool)) {
 157  	cbID := callback.RegisterIIOnce(func(c int32, found int32) {
 158  		fn(Client(c), found != 0)
 159  	})
 160  	wasmGetClientByID(unsafe.StringData(id), int32(len(id)), int32(len(id)), cbID)
 161  }
 162  
 163  func Navigate(client Client, url string) {
 164  	wasmNavigate(int32(client), unsafe.StringData(url), int32(len(url)), int32(len(url)))
 165  }
 166  
 167  // --- Cache ---
 168  
 169  //:wasmimport bridge sw_cache_open
 170  func wasmCacheOpen(ptr *byte, length int32, capacity int32, cbID int32)
 171  
 172  //:wasmimport bridge sw_cache_add_all
 173  func wasmCacheAddAll(cache int32, urlsPtr *byte, urlsLen int32, urlsCap int32, count int32, cbID int32)
 174  
 175  //:wasmimport bridge sw_cache_from_manifests
 176  func wasmCacheFromManifests(cache int32, filesPtr *byte, filesLen int32, filesCap int32, count int32, cbID int32)
 177  
 178  //:wasmimport bridge sw_cache_put
 179  func wasmCachePut(cache int32, urlPtr *byte, urlLen int32, urlCap int32, resp int32, cbID int32)
 180  
 181  //:wasmimport bridge sw_cache_match
 182  func wasmCacheMatch(ptr *byte, length int32, capacity int32, cbID int32)
 183  
 184  //:wasmimport bridge sw_cache_delete
 185  func wasmCacheDelete(ptr *byte, length int32, capacity int32, cbID int32)
 186  
 187  func CacheOpen(name string, fn func(Cache)) {
 188  	wasmCacheOpen(unsafe.StringData(name), int32(len(name)), int32(len(name)),
 189  		callback.RegisterIOnce(func(c int32) { fn(Cache(c)) }))
 190  }
 191  
 192  func CacheAddAll(cache Cache, urls []string, done func()) {
 193  	joined, count := joinNullSep(urls)
 194  	wasmCacheAddAll(int32(cache),
 195  		unsafe.StringData(joined), int32(len(joined)), int32(len(joined)),
 196  		count, callback.Register0Once(done))
 197  }
 198  
 199  func CacheFromManifests(cache Cache, staticFiles []string, done func()) {
 200  	joined, count := joinNullSep(staticFiles)
 201  	wasmCacheFromManifests(int32(cache),
 202  		unsafe.StringData(joined), int32(len(joined)), int32(len(joined)),
 203  		count, callback.Register0Once(done))
 204  }
 205  
 206  func CachePut(cache Cache, url string, resp Response, done func()) {
 207  	wasmCachePut(int32(cache), unsafe.StringData(url), int32(len(url)), int32(len(url)),
 208  		int32(resp), callback.Register0Once(done))
 209  }
 210  
 211  func CacheMatch(url string, fn func(Response)) {
 212  	wasmCacheMatch(unsafe.StringData(url), int32(len(url)), int32(len(url)),
 213  		callback.RegisterIOnce(func(r int32) { fn(Response(r)) }))
 214  }
 215  
 216  func CacheDelete(name string, done func()) {
 217  	wasmCacheDelete(unsafe.StringData(name), int32(len(name)), int32(len(name)),
 218  		callback.Register0Once(done))
 219  }
 220  
 221  // --- Fetch ---
 222  
 223  //:wasmimport bridge sw_fetch
 224  func wasmFetch(ptr *byte, length int32, capacity int32, cbID int32)
 225  
 226  //:wasmimport bridge sw_fetch_all
 227  func wasmFetchAll(urlsPtr *byte, urlsLen int32, urlsCap int32, count int32, onEachID int32, onDoneID int32)
 228  
 229  //:wasmimport bridge sw_response_ok
 230  func wasmResponseOK(resp int32) (n int32)
 231  
 232  func Fetch(url string, fn func(Response, bool)) {
 233  	cbID := callback.RegisterIIOnce(func(r int32, ok int32) {
 234  		fn(Response(r), ok != 0)
 235  	})
 236  	wasmFetch(unsafe.StringData(url), int32(len(url)), int32(len(url)), cbID)
 237  }
 238  
 239  func FetchAll(urls []string, onEach func(int32, Response, bool), onDone func()) {
 240  	eachID := callback.RegisterIII(func(idx, resp, ok int32) {
 241  		onEach(idx, Response(resp), ok != 0)
 242  	})
 243  	doneID := callback.Register0Once(func() {
 244  		callback.Release(eachID)
 245  		onDone()
 246  	})
 247  	joined, count := joinNullSep(urls)
 248  	wasmFetchAll(unsafe.StringData(joined), int32(len(joined)), int32(len(joined)),
 249  		count, eachID, doneID)
 250  }
 251  
 252  func ResponseOK(resp Response) (ok bool) {
 253  	return wasmResponseOK(int32(resp)) != 0
 254  }
 255  
 256  // --- SSE ---
 257  
 258  //:wasmimport bridge sw_sse_connect
 259  func wasmSSEConnect(ptr *byte, length int32, capacity int32, cbID int32) (n int32)
 260  
 261  //:wasmimport bridge sw_sse_close
 262  func wasmSSEClose(id int32)
 263  
 264  func SSEConnect(url string, onMessage func(string)) (s SSE) {
 265  	cbID := callback.RegisterS(onMessage)
 266  	return SSE(wasmSSEConnect(unsafe.StringData(url), int32(len(url)), int32(len(url)), cbID))
 267  }
 268  
 269  func SSEClose(id SSE) { wasmSSEClose(int32(id)) }
 270  
 271  // --- Timers ---
 272  
 273  //:wasmimport bridge sw_set_timeout
 274  func wasmSetTimeout(ms int32, cbID int32) (n int32)
 275  
 276  //:wasmimport bridge sw_clear_timeout
 277  func wasmClearTimeout(t int32)
 278  
 279  func SetTimeout(ms int32, fn func()) (t Timer) {
 280  	return Timer(wasmSetTimeout(ms, callback.Register0Once(fn)))
 281  }
 282  
 283  func ClearTimeout(t Timer) { wasmClearTimeout(int32(t)) }
 284  
 285  // --- Time ---
 286  
 287  //:wasmimport bridge sw_now_seconds
 288  func wasmNowSeconds() (n int64)
 289  
 290  //:wasmimport bridge sw_now_millis
 291  func wasmNowMillis() (n int64)
 292  
 293  func NowSeconds() (n int64) { return wasmNowSeconds() }
 294  func NowMillis() (n int64) { return wasmNowMillis() }
 295  
 296  // --- Logging ---
 297  
 298  //:wasmimport bridge sw_log
 299  func wasmLog(ptr *byte, length int32, capacity int32)
 300  
 301  func Log(msg string) {
 302  	wasmLog(unsafe.StringData(msg), int32(len(msg)), int32(len(msg)))
 303  }
 304  
 305  // joinNullSep joins strings with null byte separator for passing []string to JS.
 306  func joinNullSep(ss []string) (out []byte, n int32) {
 307  	if len(ss) == 0 {
 308  		return nil, 0
 309  	}
 310  	total := 0
 311  	for _, s := range ss {
 312  		total += len(s) + 1
 313  	}
 314  	buf := []byte{:0:total}
 315  	for i, s := range ss {
 316  		buf = buf | s
 317  		if i < len(ss)-1 {
 318  			buf = push(buf, 0)
 319  		}
 320  	}
 321  	return buf, int32(len(ss))
 322  }
 323  
 324  func ptrToString(ptr int32, length int32) (s string) {
 325  	if length <= 0 {
 326  		return ""
 327  	}
 328  	return unsafe.String((*byte)(unsafe.Pointer(uintptr(ptr))), length)
 329  }
 330