-
Notifications
You must be signed in to change notification settings - Fork 1
/
sw.js
165 lines (152 loc) · 5.95 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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
// PWA Service Worker
const CACHE_NAME = `${self.location.pathname}`;
// PWA Install Functionality
self.addEventListener('install', event => {
event.waitUntil((async () => {
try {
// Fetch the manifest file
const manifestResponse = await fetch('./manifest.webmanifest');
const manifest = await manifestResponse.json();
// Extract the resources you want to cache from the manifest
const resources = [manifest.start_url, ...manifest.icons.map(icon => icon.src)];
const cache = await caches.open(CACHE_NAME);
await cache.addAll([...resources,
'./js/content.js',
'https://img.shields.io/badge/SC--Open-gold?style=for-the-badge&link=https%3A%2F%2Fgithub.com%2FSC-Open',
'https://img.shields.io/badge/RSI--Waves2Epochs-blue?style=for-the-badge&logo=github&link=https%3A%2F%2Fgithub.com%2FSC-Open%2FRSI-Waves2Epochs',
'https://img.shields.io/github/license/sc-open/RSI-Waves2Epochs?style=for-the-badge',
'https://img.shields.io/github/sponsors/mistermatt1337?style=for-the-badge&logo=githubsponsors&link=https%3A%2F%2Fbit.ly%2F3TP4yKD',
'https://img.shields.io/badge/Patreon-Support_us!-orange?style=for-the-badge&logo=patreon&link=https%3A%2F%2Fbit.ly%2FSCOpenDevPatreon',
'https://img.shields.io/badge/RSI-Enlist_now!-blue?style=for-the-badge&logo=spaceship&link=https%3A%2F%2Fbit.ly%2FSCBonus5K',
'https://img.shields.io/discord/1113924866580684911?style=for-the-badge&logo=discord&logoColor=white&label=SC%20Open&color=gold&link=https%3A%2F%2Fbit.ly%2FSCOpen-Discord',
]);
} catch (err) {
console.error('Error during service worker installation:', err);
}
})());
});
async function evaluateAndCache(request, event) {
// Fetch and parse the manifest.json file
const manifestResponse = await fetch('./manifest.webmanifest');
const manifest = await manifestResponse.json();
// Use event if provided, otherwise use the global event
event = event || self;
// Try to get the response from the network
const fetchResponse = await fetch(event.request);
// Try to get the response from the cache
const cache = await caches.open(CACHE_NAME);
const cachedResponse = await cache.match(event.request);
if (cachedResponse) {
// Compare the network response with the cached response
const fetchResponseClone = fetchResponse.clone();
const fetchResponseText = await fetchResponseClone.text();
const cachedResponseClone = cachedResponse.clone();
const cachedResponseText = await cachedResponseClone.text();
if (fetchResponseText !== cachedResponseText) {
// If the network response is different from the cached response, update the cache
await cache.put(request, fetchResponse.clone());
}
} else {
// If the response is not in the cache, put it in the cache
await cache.put(request, fetchResponse.clone());
}
// Preserve the contentType
const url = new URL(request.url);
const extension = url.pathname.split('.').pop();
let contentType = '';
switch (extension) {
case 'html':
contentType = 'text/html';
break;
case 'css':
contentType = 'text/css';
break;
case 'js':
contentType = 'application/javascript';
break;
case 'png':
contentType = 'image/png';
break;
case 'json':
contentType = 'application/json';
break;
case 'webmanifest':
contentType = 'application/manifest+json';
break;
// Add more cases as needed
}
// This code seeks to solve some content header issues
const newResponse = new Response(fetchResponse.body, {
status: fetchResponse.status,
statusText: fetchResponse.statusText,
headers: {'Content-Type': contentType}
});
return newResponse;
}
// PWA Offline Functionality
self.addEventListener('fetch', event => {
event.respondWith((async () => {
try {
const fetchResponse = await evaluateAndCache(event.request, event);
return fetchResponse;
} catch (e) {
// The network request failed, try to get the result from the cache
const cache = await caches.open(CACHE_NAME);
const cachedResponse = await cache.match(event.request);
if (cachedResponse) {
// Return the cached response if available
return cachedResponse;
} else {
// If the requested resource is not in the cache, try to serve index.html
const cachedIndex = await cache.match('./index.html');
if (cachedIndex) {
return cachedIndex;
}
}
}
})());
});
// Use with Sync Functionality
async function fetchNewContent(event) {
// Fetch and parse the manifest.json file
const manifestResponse = await fetch('./manifest.webmanifest');
const manifest = await manifestResponse.json();
// Extract the resources you want to fetch from the manifest
const resources = [manifest.start_url, ...manifest.icons.map(icon => icon.src)];
const cache = await caches.open(CACHE_NAME);
// Fetch all resources in parallel
await Promise.all(resources.map(async resource => {
try {
const request = new Request(self.location.pathname + resource);
await evaluateAndCache(request, event);
} catch (e) {
console.error(`Failed to fetch ${resource}: ${e}`);
}
}));
}
// PWA Background Sync Functionality
self.addEventListener('sync', (event) => {
if (event.tag === 'fetch-new-content') {
event.waitUntil(fetchNewContent(event));
}
});
// PWA Periodic Sync Functionality
self.addEventListener('periodicsync', (event) => {
if (event.tag === 'fetch-new-content') {
event.waitUntil(fetchNewContent(event));
}
});
// Cleanup old caches
self.addEventListener('activate', event => {
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if (CACHE_NAME !== cacheName) {
return caches.delete(cacheName);
}
})
);
}).then(() => self.clients.claim()) // Claim the clients to make sure the active service worker is used
);
});