-
Notifications
You must be signed in to change notification settings - Fork 0
/
sw.js
131 lines (115 loc) · 4.02 KB
/
sw.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
var cdn = {
unpkg: 'https://unpkg.com',
max: 'https://maxcdn.bootstrapcdn.com'
}
var vendor = {
bootstrap: 'https://unpkg.com/[email protected]',
fontAwesome: 'https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3',
raven: 'https://unpkg.com/[email protected]'
};
var URLS = {
app: [
'./',
'./css/style.css',
'./js/animationBody.js',
'./main.js',
'./index.html',
'./manifest.json',
'./iconos/icono16x16.png',
'./iconos/icono32x32.png',
'./iconos/icono64x64.png',
'./iconos/icono128x128.png',
'./iconos/icono192x192.png',
'./iconos/icono256x256.png',
'./iconos/icono384x384.png',
'./iconos/icono512x512.png'
],
vendor: [
`${vendor.bootstrap}/dist/css/bootstrap.min.css`,
`${vendor.fontAwesome}/css/font-awesome.min.css`,
`${vendor.fontAwesome}/fonts/fontawesome-webfont.woff2`, // browsers that support sw support woff2
`${vendor.raven}/dist/raven.min.js`
]
}
var CACHE_NAMES = {
app: 'app-cache-v5',
vendor: 'vendor-cache-v5'
};
function isVendor(url) {
return url.startsWith(cdn.unpkg) || url.startsWith(cdn.max);
}
function cacheAll(cacheName, urls) {
return caches.open(cacheName).then((cache) => cache.addAll(urls));
}
function addToCache(cacheName, request, response) {
if (response.ok) {
var clone = response.clone()
caches.open(cacheName).then((cache) => cache.put(request, clone));
}
return response;
}
function lookupCache(request) {
return caches.match(request).then(function (cachedResponse) {
if (!cachedResponse) {
throw Error(`${request.url} not found in cache`);
}
return cachedResponse;
});
}
function fetchThenCache(request, cacheName) {
var fetchRequest = fetch(request);
// add to cache, but don't block resolve of this promise on caching
fetchRequest.then((response) => addToCache(cacheName, request, response));
return fetchRequest;
}
function raceRequest(request, cacheName) {
var attempts = [
fetchThenCache(request, cacheName),
lookupCache(request)
];
return new Promise(function (resolve, reject) {
// resolve this promise once one resolves
attempts.forEach((attempt) => attempt.then(resolve));
// reject if all promises reject
attempts.reduce((verdict, attempt) => verdict.catch(() => attempt))
.catch(() => reject(Error('Unable to resolve request from network or cache.')));
})
}
function cleanupCache() {
var validKeys = Object.keys(CACHE_NAMES).map((key) => CACHE_NAMES[key]);
return caches.keys().then((localKeys) => Promise.all(
localKeys.map((key) => {
if (validKeys.indexOf(key) === -1) { // key no longer in our list
return caches.delete(key);
}
})
));
}
self.addEventListener('install', function (evt) {
var cachingCompleted = Promise.all([
cacheAll(CACHE_NAMES.app, URLS.app),
cacheAll(CACHE_NAMES.vendor, URLS.vendor)
]).then(() => self.skipWaiting())
evt.waitUntil(cachingCompleted);
});
self.addEventListener('activate', function (evt) {
evt.waitUntil(Promise.all([
cleanupCache(),
self.clients.claim() // claim immediately so the page can be controlled by the sw immediately
]));
});
self.addEventListener('fetch', function (evt) {
var request = evt.request;
var response;
// only handle GET requests
if (request.method !== 'GET') return;
if (isVendor(request.url)) {
// vendor requests: check cache first, fallback to fetch
response = lookupCache(request)
.catch(() => fetchThenCache(request, CACHE_NAMES.vendor));
} else {
// app request: race cache/fetch (bonus: update in background)
response = raceRequest(request, CACHE_NAMES.app);
}
evt.respondWith(response);
});