1
- const CACHENAME = "assets" ;
1
+ let VERSION = null ;
2
2
3
3
/*
4
4
* This Service Worker is an optional optimisation to load the app faster.
@@ -41,7 +41,7 @@ self.addEventListener("fetch", async(event) => {
41
41
if ( ! event . request . url . startsWith ( location . origin + "/assets/" ) ) return ;
42
42
43
43
event . respondWith ( ( async ( ) => {
44
- const cache = await caches . open ( CACHENAME ) ;
44
+ const cache = await caches . open ( VERSION ) ;
45
45
const cachedResponse = await cache . match ( event . request ) ;
46
46
if ( cachedResponse ) return cachedResponse ;
47
47
return fetch ( event . request ) ;
@@ -51,19 +51,42 @@ self.addEventListener("fetch", async(event) => {
51
51
self . addEventListener ( "message" , ( event ) => {
52
52
if ( event . data . type === "preload" ) handlePreloadMessage (
53
53
event . data . payload ,
54
+ event . data . clear ,
55
+ event . data . version ,
54
56
( ) => event . source . postMessage ( { type : "preload" , status : "ok" } ) ,
55
57
( err ) => event . source . postMessage ( { type : "preload" , status : "error" , msg : err . message } ) ,
56
58
) ;
57
59
} ) ;
58
60
59
- async function handlePreloadMessage ( chunks , resolve , reject , id ) {
61
+ async function handlePreloadMessage ( chunks , clear , version , resolve , reject ) {
62
+ VERSION = version ;
60
63
const cleanup = [ ] ;
61
64
try {
62
- await caches . delete ( CACHENAME ) ;
63
- const cache = await caches . open ( CACHENAME ) ;
64
- await Promise . all ( chunks . map ( ( urls ) => {
65
- return preload ( { urls, cache, cleanup } ) ;
66
- } ) ) ;
65
+ let execHTTP = true ;
66
+ await caches . keys ( ) . then ( async ( names ) => {
67
+ for ( let i = 0 ; i < names . length ; i ++ ) {
68
+ if ( names [ i ] === VERSION && ! clear ) {
69
+ execHTTP = false ;
70
+ return ;
71
+ }
72
+ await caches . delete ( names [ i ] ) ;
73
+ }
74
+ } ) ;
75
+ if ( execHTTP ) {
76
+ const cache = await caches . open ( VERSION ) ;
77
+ chunks = await Promise . all ( chunks . map ( async ( urls ) => {
78
+ const missing = [ ] ;
79
+ await Promise . all ( urls . map ( async ( url ) => {
80
+ if ( ! await cache . match ( location . origin + url ) ) missing . push ( url ) ;
81
+ } ) ) ;
82
+ return missing ;
83
+ } ) ) ;
84
+ if ( chunks . filter ( ( urls ) => urls . length > 0 ) . length > 0 ) {
85
+ await Promise . all ( chunks . map ( ( urls ) => {
86
+ return preload ( { urls, cache, cleanup } ) ;
87
+ } ) ) ;
88
+ }
89
+ }
67
90
resolve ( ) ;
68
91
} catch ( err ) {
69
92
console . log ( "ERR" , err ) ;
@@ -88,7 +111,7 @@ async function preload({ urls, cache, cleanup }) {
88
111
await cache . put (
89
112
location . origin + url ,
90
113
new Response (
91
- decoder ( new Blob ( [ Uint8Array . from ( atob ( event . data ) , ( c ) => c . charCodeAt ( 0 ) ) ] ) . stream ( ) ) ,
114
+ decoder ( new Blob ( [ base128Decode ( event . data ) ] ) . stream ( ) ) ,
92
115
{ headers : { "Content-Type" : mime } } ,
93
116
) ,
94
117
) ;
@@ -117,3 +140,22 @@ async function preload({ urls, cache, cleanup }) {
117
140
} ;
118
141
} ) ;
119
142
}
143
+
144
+ function base128Decode ( s ) { // encoder is in server/ctrl/static.go -> encodeB128
145
+ const out = new Uint8Array ( Math . floor ( ( s . length * 7 ) / 8 ) + 1 ) ;
146
+ let acc = 0 ;
147
+ let bits = 0 ;
148
+ let oi = 0 ;
149
+ for ( let i = 0 ; i < s . length ; i ++ ) {
150
+ const ch = s . charCodeAt ( i ) ;
151
+ const digit = ch & 0x7F ; // undo 0x80 masking for NUL/LF/CR
152
+ acc = ( acc << 7 ) | digit ;
153
+ bits += 7 ;
154
+ while ( bits >= 8 ) {
155
+ bits -= 8 ;
156
+ out [ oi ++ ] = ( acc >> bits ) & 0xFF ;
157
+ acc &= ( 1 << bits ) - 1 ;
158
+ }
159
+ }
160
+ return out . subarray ( 0 , oi ) ;
161
+ }
0 commit comments