miru/app/sw.js

122 lines
No EOL
3.3 KiB
JavaScript

'use strict';
const staticCacheName = 'v1.0.0';
const filesToCache = [
'index.html',
'js/settingsHandler.js',
'js/animeHandler.js',
'js/playerHandler.js',
'js/subtitleHandler.js',
'js/torrentHandler.js',
'js/rangeParser.js',
'js/util.js',
'css/misc.css',
'css/player.css',
'logo.png',
'https://cdn.jsdelivr.net/npm/matroska-subtitles@3.0.1/dist/matroska-subtitles.min.js',
'https://cdn.jsdelivr.net/npm/halfmoon@1.1.0/css/halfmoon-variables.min.css',
'https://cdn.jsdelivr.net/gh/halfmoonui/halfmoon@1.1.0/js/halfmoon.min.js',
'https://cdn.jsdelivr.net/npm/webtorrent@latest/webtorrent.min.js',
'https://fonts.googleapis.com/icon?family=Material+Icons'
];
self.addEventListener('install', event => {
event.waitUntil(
caches.open(staticCacheName)
.then(cache => {
return cache.addAll(filesToCache);
})
);
self.skipWaiting();
});
self.addEventListener('activate', event => {
const cacheWhitelist = [staticCacheName];
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if (cacheWhitelist.indexOf(cacheName) === -1) {
return caches.delete(cacheName);
}
})
);
})
);
return self.clients.claim();
});
self.addEventListener('fetch', evt => {
const { request } = evt
const { url, method, headers } = request
if (!url.includes(self.registration.scope + 'webtorrent/')) return null
function getConsumer(clients) {
return new Promise(rs => {
// Use race condition for whoever controls the response stream
for (const client of clients) {
const mc = new MessageChannel()
const { port1, port2 } = mc
port1.onmessage = evt => {
rs([evt.data, mc])
}
client.postMessage({
url,
method,
headers: [...headers],
scope: self.registration.scope
}, [port2])
}
})
}
evt.respondWith(
clients.matchAll({ type: 'window', includeUncontrolled: true })
.then(getConsumer)
.then(([data, mc]) => {
const body = data.body === 'stream' ? new ReadableStream({
pull(controller) {
return new Promise(rs => {
mc.port1.onmessage = evt => {
evt.data
? controller.enqueue(evt.data) // evt.data is Uint8Array
: controller.close() // evt.data is null, means the stream ended
rs()
}
mc.port1.postMessage(true) // send a pull request
})
},
cancel() {
// This event is never executed
mc.port1.postMessage(false) // send a cancel request
}
}) : data.body
return new Response(body, data)
})
.catch(console.error)
)
})
// self.addEventListener('fetch', event => {
// event.respondWith(
// caches.match(event.request)
// .then(response => {
// if (response) {
// return response;
// }
// return fetch(event.request)
// .then(response => {
// if (response.status === 404) {
// return;
// }
// return response;
// });
// }).catch(error => {
// return caches.match('index.html');
// })
// );
// });