-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsw.js
More file actions
66 lines (58 loc) · 1.96 KB
/
Copy pathsw.js
File metadata and controls
66 lines (58 loc) · 1.96 KB
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
const AUDIO_CACHE = 'meditation-audio-v1';
self.addEventListener('message', async (event) => {
if (event.data.type === 'cache-audio') {
const { url, blob } = event.data;
const cache = await caches.open(AUDIO_CACHE);
const response = new Response(blob, {
headers: {
'Content-Type': blob.type,
'Content-Length': blob.size,
'Accept-Ranges': 'bytes',
}
});
await cache.put(url, response);
event.source.postMessage({ type: 'audio-cached', url });
}
});
self.addEventListener('fetch', (event) => {
const url = new URL(event.request.url);
if (!url.pathname.startsWith('/generated-audio/')) return;
event.respondWith(handleAudioRequest(event.request));
});
async function handleAudioRequest(request) {
const cache = await caches.open(AUDIO_CACHE);
const cachedResponse = await cache.match(request.url);
if (!cachedResponse) {
return new Response('Not found', { status: 404 });
}
const blob = await cachedResponse.blob();
const totalSize = blob.size;
const rangeHeader = request.headers.get('Range');
// iOS Safari sends Range requests for <audio> — must respond with 206
if (rangeHeader) {
const matches = rangeHeader.match(/bytes=(\d+)-(\d*)/);
if (matches) {
const start = parseInt(matches[1], 10);
const end = matches[2] ? parseInt(matches[2], 10) : totalSize - 1;
const chunkSize = end - start + 1;
const slicedBlob = blob.slice(start, end + 1);
return new Response(slicedBlob, {
status: 206,
headers: {
'Content-Type': blob.type,
'Content-Length': chunkSize,
'Content-Range': `bytes ${start}-${end}/${totalSize}`,
'Accept-Ranges': 'bytes',
}
});
}
}
return new Response(blob, {
status: 200,
headers: {
'Content-Type': blob.type,
'Content-Length': totalSize,
'Accept-Ranges': 'bytes',
}
});
}