forked from zuixjs/zuix-web-flix
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sw.js
135 lines (129 loc) · 4.47 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
132
133
134
135
// TODO: increase `version` number to force cache update when publishing a new release
const version = 'v2';
const config = {
cacheRemote: true,
version: version+'::',
preCachingItems: [
'app.bundle.js',
'index.html',
'index.js',
'offline.html',
'404.html',
'sw.js'
],
blacklistCacheItems: [
'index.html',
'service-worker.js'
],
offlineImage: '<svg role="img" aria-labelledby="offline-title"' + ' viewBox="0 0 400 300" xmlns="http://www.w3.org/2000/svg">' + '<title id="offline-title">Offline</title>' + '<g fill="none" fill-rule="evenodd"><path fill="#121212" d="M0 0h400v300H0z"/>' + '<text fill="#aaa" font-family="monospace" font-size="32" font-weight="bold">' + '<tspan x="136" y="156">offline</tspan></text></g></svg>',
offlinePage: 'offline.html',
notFoundPage: '404.html',
offlineTmdbResults: {
page: 1,
results: [{
"title": "Offline",
"poster_path": "https://tmdb.org/offline.jpg",
"backdrop_path": "https://tmdb.org/offline.jpg",
"overview": ""
}],
total_pages: 1,
total_results: 1
}
};
function cacheName(key, opts) {
return `${opts.version}${key}`;
}
function addToCache(cacheKey, request, response) {
if (response.ok) {
const copy = response.clone();
caches.open(cacheKey).then(cache => {
cache.put(request, copy);
});
}
return response;
}
function fetchFromCache(event) {
return caches.match(event.request).then(response => {
if (!response) {
throw Error(`${event.request.url} not found in cache`);
} else if (response.status === 404) {
return caches.match(config.notFoundPage);
}
return response;
});
}
function offlineResponse(resourceType, opts) {
if (resourceType === 'content') {
return caches.match(opts.offlinePage);
}
if (resourceType === 'image') {
return new Response(opts.offlineImage, {
headers: { 'Content-Type': 'image/svg+xml' }
});
}
if (resourceType === 'tmdb') {
return new Response(JSON.stringify(opts.offlineTmdbResults), {
headers: { 'Content-Type': 'application/json' }
});
}
return undefined;
}
self.addEventListener('install', event => {
event.waitUntil(caches.open(
cacheName('static', config)
)
.then(cache => cache.addAll(config.preCachingItems))
.then(() => self.skipWaiting())
);
});
self.addEventListener('activate', event => {
function clearCacheIfDifferent(event, opts) {
return caches.keys().then(cacheKeys => {
const oldCacheKeys = cacheKeys.filter(key => key.indexOf(opts.version) !== 0);
const deletePromises = oldCacheKeys.map(oldKey => caches.delete(oldKey));
return Promise.all(deletePromises);
});
}
event.waitUntil(
clearCacheIfDifferent(event, config)
.then(() => self.clients.claim())
);
});
self.addEventListener('fetch', event => {
const request = event.request;
const url = new URL(request.url);
if (request.method !== 'GET'
|| (config.cacheRemote !== true && url.origin !== self.location.origin)
|| (config.blacklistCacheItems.length > 0 && config.blacklistCacheItems.indexOf(url.pathname) !== -1)) {
// default browser behavior
return;
}
let cacheKey;
let resourceType = 'content';
if (/(.jpg|.jpeg|.webp|.png|.svg|.gif)$/.test(url.pathname)) {
resourceType = 'image';
} else if (/.\/fonts.(?:googleapis|gstatic).com/.test(url.origin)) {
resourceType = 'font';
} else if (url.origin === 'https://api.themoviedb.org') {
// The Movie DB json API
resourceType = 'tmdb';
}
cacheKey = cacheName(resourceType, config);
if (resourceType === 'content') {
// Network First Strategy
event.respondWith(
fetch(request)
.then(response => addToCache(cacheKey, request, response))
.catch(() => fetchFromCache(event))
.catch(() => offlineResponse(resourceType, config))
);
} else {
// Cache First Strategy
event.respondWith(
fetchFromCache(event)
.catch(() => fetch(request))
.then(response => addToCache(cacheKey, request, response))
.catch(() => offlineResponse(resourceType, config))
);
}
});