|
| 1 | +/* global self */ |
| 2 | + |
| 3 | +const CACHE_NAME = 'next-prefetcher-v1' |
| 4 | + |
| 5 | +self.addEventListener('install', () => { |
| 6 | + console.log('Installing Next Prefetcher') |
| 7 | +}) |
| 8 | + |
| 9 | +self.addEventListener('activate', (e) => { |
| 10 | + console.log('Activated Next Prefetcher') |
| 11 | + e.waitUntil(Promise.all([ |
| 12 | + resetCache(), |
| 13 | + notifyClients() |
| 14 | + ])) |
| 15 | +}) |
| 16 | + |
| 17 | +self.addEventListener('fetch', (e) => { |
| 18 | + e.respondWith(getResponse(e.request)) |
| 19 | +}) |
| 20 | + |
| 21 | +self.addEventListener('message', (e) => { |
| 22 | + switch (e.data.action) { |
| 23 | + case 'ADD_URL': { |
| 24 | + console.log('CACHING ', e.data.url) |
| 25 | + sendReply(e, cacheUrl(e.data.url)) |
| 26 | + break |
| 27 | + } |
| 28 | + case 'RESET': { |
| 29 | + console.log('RESET') |
| 30 | + sendReply(e, resetCache()) |
| 31 | + break |
| 32 | + } |
| 33 | + default: |
| 34 | + console.error('Unknown action: ' + e.data.action) |
| 35 | + } |
| 36 | +}) |
| 37 | + |
| 38 | +function sendReply (e, result) { |
| 39 | + const payload = { action: 'REPLY', actionType: e.data.action, replyFor: e.data.id } |
| 40 | + result |
| 41 | + .then((result) => { |
| 42 | + payload.result = result |
| 43 | + e.source.postMessage(payload) |
| 44 | + }) |
| 45 | + .catch((error) => { |
| 46 | + payload.error = error.message |
| 47 | + e.source.postMessage(payload) |
| 48 | + }) |
| 49 | +} |
| 50 | + |
| 51 | +function cacheUrl (url) { |
| 52 | + const req = new self.Request(url, { |
| 53 | + mode: 'no-cors' |
| 54 | + }) |
| 55 | + |
| 56 | + return self.caches.open(CACHE_NAME) |
| 57 | + .then((cache) => { |
| 58 | + return self.fetch(req) |
| 59 | + .then((res) => cache.put(req, res)) |
| 60 | + }) |
| 61 | +} |
| 62 | + |
| 63 | +function getResponse (req) { |
| 64 | + return self.caches.open(CACHE_NAME) |
| 65 | + .then((cache) => cache.match(req)) |
| 66 | + .then((res) => { |
| 67 | + if (res) { |
| 68 | + console.log('CACHE HIT: ' + req.url) |
| 69 | + return res |
| 70 | + } else { |
| 71 | + console.log('CACHE MISS: ' + req.url) |
| 72 | + return self.fetch(req) |
| 73 | + } |
| 74 | + }) |
| 75 | +} |
| 76 | + |
| 77 | +function resetCache () { |
| 78 | + let cache |
| 79 | + |
| 80 | + return self.caches.open(CACHE_NAME) |
| 81 | + .then((c) => { |
| 82 | + cache = c |
| 83 | + return cache.keys() |
| 84 | + }) |
| 85 | + .then(function (items) { |
| 86 | + const deleteAll = items.map((item) => cache.delete(item)) |
| 87 | + return Promise.all(deleteAll) |
| 88 | + }) |
| 89 | +} |
| 90 | + |
| 91 | +function notifyClients () { |
| 92 | + return self.clients.claim() |
| 93 | + .then(() => self.clients.matchAll()) |
| 94 | + .then((clients) => { |
| 95 | + const notifyAll = clients.map((client) => { |
| 96 | + return client.postMessage({ action: 'NEXT_PREFETCHER_ACTIVATED' }) |
| 97 | + }) |
| 98 | + return Promise.all(notifyAll) |
| 99 | + }) |
| 100 | +} |
0 commit comments