1- const CACHENAME = "assets" ;
1+ let VERSION = null ;
22
33/*
44 * This Service Worker is an optional optimisation to load the app faster.
@@ -41,7 +41,7 @@ self.addEventListener("fetch", async(event) => {
4141 if ( ! event . request . url . startsWith ( location . origin + "/assets/" ) ) return ;
4242
4343 event . respondWith ( ( async ( ) => {
44- const cache = await caches . open ( CACHENAME ) ;
44+ const cache = await caches . open ( VERSION ) ;
4545 const cachedResponse = await cache . match ( event . request ) ;
4646 if ( cachedResponse ) return cachedResponse ;
4747 return fetch ( event . request ) ;
@@ -51,19 +51,42 @@ self.addEventListener("fetch", async(event) => {
5151self . addEventListener ( "message" , ( event ) => {
5252 if ( event . data . type === "preload" ) handlePreloadMessage (
5353 event . data . payload ,
54+ event . data . clear ,
55+ event . data . version ,
5456 ( ) => event . source . postMessage ( { type : "preload" , status : "ok" } ) ,
5557 ( err ) => event . source . postMessage ( { type : "preload" , status : "error" , msg : err . message } ) ,
5658 ) ;
5759} ) ;
5860
59- async function handlePreloadMessage ( chunks , resolve , reject , id ) {
61+ async function handlePreloadMessage ( chunks , clear , version , resolve , reject ) {
62+ VERSION = version ;
6063 const cleanup = [ ] ;
6164 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+ }
6790 resolve ( ) ;
6891 } catch ( err ) {
6992 console . log ( "ERR" , err ) ;
@@ -88,7 +111,7 @@ async function preload({ urls, cache, cleanup }) {
88111 await cache . put (
89112 location . origin + url ,
90113 new Response (
91- decoder ( new Blob ( [ Uint8Array . from ( atob ( event . data ) , ( c ) => c . charCodeAt ( 0 ) ) ] ) . stream ( ) ) ,
114+ decoder ( new Blob ( [ base128Decode ( event . data ) ] ) . stream ( ) ) ,
92115 { headers : { "Content-Type" : mime } } ,
93116 ) ,
94117 ) ;
@@ -117,3 +140,22 @@ async function preload({ urls, cache, cleanup }) {
117140 } ;
118141 } ) ;
119142}
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