github.com/vicanso/pike@v1.0.1-0.20210630235453-9099e041f6ec/web/flutter_service_worker.js (about) 1 'use strict'; 2 const MANIFEST = 'flutter-app-manifest'; 3 const TEMP = 'flutter-temp-cache'; 4 const CACHE_NAME = 'flutter-app-cache'; 5 const RESOURCES = { 6 "version.json": "1f308f6516a18ecd7674c9a450a742cd", 7 "index.html": "9bf34098aa05b0f5daa3672d1d389d66", 8 "/": "9bf34098aa05b0f5daa3672d1d389d66", 9 "main.dart.js": "1b2d0e9a1e65bbc2080d47783b5ce740", 10 "favicon.png": "884a1524c6ce95ff3b2c4d9f28bb3d6d", 11 "icons/Icon-192.png": "2170366816d46ad1215c42f6c1aaa16a", 12 "icons/Icon-512.png": "02722d7162edf88b761e758a44e7d1a9", 13 "manifest.json": "1f566b509698542d126fbd8f162102f7", 14 "assets/images/logo.png": "884a1524c6ce95ff3b2c4d9f28bb3d6d", 15 "assets/AssetManifest.json": "852da4d3c401b4c84bb94225217e82f4", 16 "assets/NOTICES": "dd53e653312f96c2d1fdd9b2925f9f67", 17 "assets/FontManifest.json": "dc3d03800ccca4601324923c0b1d6d57", 18 "assets/packages/cupertino_icons/assets/CupertinoIcons.ttf": "b14fcf3ee94e3ace300b192e9e7c8c5d", 19 "assets/packages/fluttertoast/assets/toastify.js": "8f5ac78dd0b9b5c9959ea1ade77f68ae", 20 "assets/packages/fluttertoast/assets/toastify.css": "8beb4c67569fb90146861e66d94163d7", 21 "assets/fonts/MaterialIcons-Regular.otf": "4e6447691c9509f7acdbf8a931a85ca1" 22 }; 23 24 // The application shell files that are downloaded before a service worker can 25 // start. 26 const CORE = [ 27 "/", 28 "main.dart.js", 29 "index.html", 30 "assets/NOTICES", 31 "assets/AssetManifest.json", 32 "assets/FontManifest.json"]; 33 // During install, the TEMP cache is populated with the application shell files. 34 self.addEventListener("install", (event) => { 35 self.skipWaiting(); 36 return event.waitUntil( 37 caches.open(TEMP).then((cache) => { 38 return cache.addAll( 39 CORE.map((value) => new Request(value, {'cache': 'reload'}))); 40 }) 41 ); 42 }); 43 44 // During activate, the cache is populated with the temp files downloaded in 45 // install. If this service worker is upgrading from one with a saved 46 // MANIFEST, then use this to retain unchanged resource files. 47 self.addEventListener("activate", function(event) { 48 return event.waitUntil(async function() { 49 try { 50 var contentCache = await caches.open(CACHE_NAME); 51 var tempCache = await caches.open(TEMP); 52 var manifestCache = await caches.open(MANIFEST); 53 var manifest = await manifestCache.match('manifest'); 54 // When there is no prior manifest, clear the entire cache. 55 if (!manifest) { 56 await caches.delete(CACHE_NAME); 57 contentCache = await caches.open(CACHE_NAME); 58 for (var request of await tempCache.keys()) { 59 var response = await tempCache.match(request); 60 await contentCache.put(request, response); 61 } 62 await caches.delete(TEMP); 63 // Save the manifest to make future upgrades efficient. 64 await manifestCache.put('manifest', new Response(JSON.stringify(RESOURCES))); 65 return; 66 } 67 var oldManifest = await manifest.json(); 68 var origin = self.location.origin; 69 for (var request of await contentCache.keys()) { 70 var key = request.url.substring(origin.length + 1); 71 if (key == "") { 72 key = "/"; 73 } 74 // If a resource from the old manifest is not in the new cache, or if 75 // the MD5 sum has changed, delete it. Otherwise the resource is left 76 // in the cache and can be reused by the new service worker. 77 if (!RESOURCES[key] || RESOURCES[key] != oldManifest[key]) { 78 await contentCache.delete(request); 79 } 80 } 81 // Populate the cache with the app shell TEMP files, potentially overwriting 82 // cache files preserved above. 83 for (var request of await tempCache.keys()) { 84 var response = await tempCache.match(request); 85 await contentCache.put(request, response); 86 } 87 await caches.delete(TEMP); 88 // Save the manifest to make future upgrades efficient. 89 await manifestCache.put('manifest', new Response(JSON.stringify(RESOURCES))); 90 return; 91 } catch (err) { 92 // On an unhandled exception the state of the cache cannot be guaranteed. 93 console.error('Failed to upgrade service worker: ' + err); 94 await caches.delete(CACHE_NAME); 95 await caches.delete(TEMP); 96 await caches.delete(MANIFEST); 97 } 98 }()); 99 }); 100 101 // The fetch handler redirects requests for RESOURCE files to the service 102 // worker cache. 103 self.addEventListener("fetch", (event) => { 104 if (event.request.method !== 'GET') { 105 return; 106 } 107 var origin = self.location.origin; 108 var key = event.request.url.substring(origin.length + 1); 109 // Redirect URLs to the index.html 110 if (key.indexOf('?v=') != -1) { 111 key = key.split('?v=')[0]; 112 } 113 if (event.request.url == origin || event.request.url.startsWith(origin + '/#') || key == '') { 114 key = '/'; 115 } 116 // If the URL is not the RESOURCE list then return to signal that the 117 // browser should take over. 118 if (!RESOURCES[key]) { 119 return; 120 } 121 // If the URL is the index.html, perform an online-first request. 122 if (key == '/') { 123 return onlineFirst(event); 124 } 125 event.respondWith(caches.open(CACHE_NAME) 126 .then((cache) => { 127 return cache.match(event.request).then((response) => { 128 // Either respond with the cached resource, or perform a fetch and 129 // lazily populate the cache. 130 return response || fetch(event.request).then((response) => { 131 cache.put(event.request, response.clone()); 132 return response; 133 }); 134 }) 135 }) 136 ); 137 }); 138 139 self.addEventListener('message', (event) => { 140 // SkipWaiting can be used to immediately activate a waiting service worker. 141 // This will also require a page refresh triggered by the main worker. 142 if (event.data === 'skipWaiting') { 143 self.skipWaiting(); 144 return; 145 } 146 if (event.data === 'downloadOffline') { 147 downloadOffline(); 148 return; 149 } 150 }); 151 152 // Download offline will check the RESOURCES for all files not in the cache 153 // and populate them. 154 async function downloadOffline() { 155 var resources = []; 156 var contentCache = await caches.open(CACHE_NAME); 157 var currentContent = {}; 158 for (var request of await contentCache.keys()) { 159 var key = request.url.substring(origin.length + 1); 160 if (key == "") { 161 key = "/"; 162 } 163 currentContent[key] = true; 164 } 165 for (var resourceKey of Object.keys(RESOURCES)) { 166 if (!currentContent[resourceKey]) { 167 resources.push(resourceKey); 168 } 169 } 170 return contentCache.addAll(resources); 171 } 172 173 // Attempt to download the resource online before falling back to 174 // the offline cache. 175 function onlineFirst(event) { 176 return event.respondWith( 177 fetch(event.request).then((response) => { 178 return caches.open(CACHE_NAME).then((cache) => { 179 cache.put(event.request, response.clone()); 180 return response; 181 }); 182 }).catch((error) => { 183 return caches.open(CACHE_NAME).then((cache) => { 184 return cache.match(event.request).then((response) => { 185 if (response != null) { 186 return response; 187 } 188 throw error; 189 }); 190 }); 191 }) 192 ); 193 }