-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
sw.js
179 lines (164 loc) · 6 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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
const url_root_path= self.location.pathname.replace("/sw.js","");
const core_version = '5.1.3'; //has to be the same as the version in Emulator/config.h
const ui_version = '2024_12_14'+url_root_path.replace("/","_");
const needs_shared_array_buffer=false; //true when it runs in separat worker thread
const cache_name = `${core_version}@${ui_version}`;
const settings_cache = 'settings';
set_settings_cache_value = async function (key, value)
{
let settings = await caches.open(settings_cache);
await settings.put(key, new Response(value) );
}
get_settings_cache_value= async function (key)
{
let settings = await caches.open(settings_cache);
let response=await settings.match(key)
if(response==undefined)
return null;
return await response.text();
}
async function get_active_cache_name()
{
let v = await get_settings_cache_value('active_version');
return v!=null ? v:cache_name;
}
//get messages from the web app
self.addEventListener("message", async evt => {
const client = evt.source;
if(evt.data == "version")
{
//set the active_cache_name to the cache_name of this sw in case of no active version set yet!
await set_settings_cache_value("active_version", await get_active_cache_name());
client.postMessage({core: core_version, ui: ui_version, cache_name: cache_name});
}
});
// install event
self.addEventListener('install', evt => {
console.log('service worker installed');
self.skipWaiting();
});
// activate event
self.addEventListener('activate', evt => {
console.log('service worker activated');
let check_and_update=async () =>{
current_version=await get_settings_cache_value("active_version");
if(current_version == null)
{
console.log("current version of vc64web does not yet support update dialog, enforce install...");
let keys = await caches.keys();
for(c of keys)
{
if(c != settings_cache)
{
console.log('deleting cache files:'+c);
await caches.delete(c);
}
}
// and set active version
await set_settings_cache_value("active_version", cache_name);
// and reload app
const tabs = await self.clients.matchAll({type:'window'});
tabs.forEach((tab)=>{ tab.navigate(tab.url) });
}
}
evt.waitUntil( check_and_update());
/* evt.waitUntil(
caches.keys().then(keys => {
console.log('deleting cache files:'+keys);
return Promise.all(keys.map(key => caches.delete(key)));
})
);
*/
});
self.addEventListener('fetch', function(event){
event.respondWith(async function () {
//is this url one that should not be cached at all ?
if(
event.request.url.startsWith('https://csdb.dk/webservice/') &&
!event.request.url.endsWith('cache_me=true')
||
event.request.url.startsWith('https://mega65.github.io/')
||
event.request.url.startsWith('https://vc64web.github.io/doc')
||
event.request.url.endsWith('vc64web_player.js')
||
event.request.url.endsWith('run.html')
||
event.request.url.endsWith('cache_me=false')
)
{
console.log('sw: do not cache fetched resource: '+event.request.url);
return fetch(event.request);
}
else
{
//try to get it from the cache
active_cache_name = await get_active_cache_name();
var cache = await caches.open(active_cache_name);
var cachedResponsePromise = await cache.match(event.request);
if(cachedResponsePromise)
{
console.log('sw: get from '+active_cache_name+' cached resource: '+event.request.url);
const newHeaders = new Headers(cachedResponsePromise.headers);
if(needs_shared_array_buffer)
{
newHeaders.set("Cross-Origin-Embedder-Policy", "require-corp");
newHeaders.set("Cross-Origin-Opener-Policy", "same-origin");
}
const moddedResponse = new Response(cachedResponsePromise.body, {
status: cachedResponsePromise.status,
statusText: cachedResponsePromise.statusText,
headers: newHeaders,
});
return moddedResponse;
// return cachedResponsePromise;
}
//if not in cache try to fetch
//with no-cache because we dont want to cache a 304 response ...
//learn more here
//https://stackoverflow.com/questions/29246444/fetch-how-do-you-make-a-non-cached-request
//to cache vAmiga.html instead of the sw installer index.html
let sw_request=event.request;
/* if(event.request.url.endsWith(url_root_path+'/'))
{
sw_request = `${event.request.url}vAmiga.html`;
}
*/
var networkResponse = await fetch(sw_request, {cache: "no-cache"});
event.waitUntil(
async function ()
{
try {
if(networkResponse.status == 200)
{
console.log(`sw: status=200 into ${active_cache_name} putting fetched resource: ${event.request.url}`);
await cache.put(event.request, networkResponse.clone());
}
else
{
console.error(`sw: ${active_cache_name} received code ${networkResponse.code} for resource: ${event.request.url}`);
}
}
catch(e) { console.error(`exception during fetch ${e}`); }
}()
);
if(networkResponse.status < 200)
{
return networkResponse;
}
const newHeaders = new Headers(networkResponse.headers);
if(needs_shared_array_buffer)
{
newHeaders.set("Cross-Origin-Embedder-Policy", "require-corp");
newHeaders.set("Cross-Origin-Opener-Policy", "same-origin");
}
const moddedResponse = new Response(networkResponse.body, {
status: networkResponse.status,
statusText: networkResponse.statusText,
headers: newHeaders,
});
return moddedResponse;
}
}());
});