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