-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsw.ts
133 lines (114 loc) · 3.91 KB
/
sw.ts
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
// @ts-nocheck
// Default type of `self` is `WorkerGlobalScope & typeof globalThis`
// https://github.com/microsoft/TypeScript/issues/14877
declare var self: ServiceWorkerGlobalScope;
const SW_VERSION = '1.0.0';
let CURRENT_PEER_HOST_CLIENT_ID = null;
class ResponseEvent extends EventTarget {
reactResponse(eventId, data) {
this.dispatchEvent(
new CustomEvent(`RESPONSE-${eventId}`, { detail: data })
);
}
}
const responseBridge = new ResponseEvent();
// // // Choose a cache name
// const cacheName = 'cache-v1';
// // // List the files to precache
// const precacheResources = ['/', '/index.html'];
// When the service worker is installing, open the cache and add the precache resources to it
self.addEventListener('install', (event) => {
console.log('sw install');
// event.waitUntil(
// caches.open(cacheName).then((cache) => cache.addAll(precacheResources))
// );
});
self.addEventListener('activate', (event) => {
console.log('sw activate');
});
// When there's an incoming fetch request, try and respond with a precached resource, otherwise fall back to the network
self.addEventListener('fetch', (event: FetchEvent) => {
const log = console.log.bind(this, 'sw.on(fetch)');
log(
'Fetch intercepted for:',
event.request.url,
'event.clientId',
event.clientId,
'event.resultingClientId',
event.resultingClientId
);
/// this is a new page
if (event.resultingClientId) {
(async () => {
const client = await self.clients.get(event.resultingClientId);
log('new window', event.request.url, client);
})();
}
if (!CURRENT_PEER_HOST_CLIENT_ID) {
event.respondWith(fetch(event.request));
} else {
event.respondWith(
(async () => {
log('getting data...');
// ------------ GET DATA ------------
const peerHostClient: Client = await self.clients.get(
CURRENT_PEER_HOST_CLIENT_ID
);
if (!peerHostClient) {
log('peerHostClient is gone... opening a new one');
return fetch(event.request);
}
log('getting demo data from peer host client', peerHostClient.id);
const eventId = `${Date.now()}-${Math.floor(Math.random() * 10000000)}`;
peerHostClient.postMessage({ type: 'GET_DEMO_DATA', eventId });
const data = await new Promise((resolve, reject) => {
responseBridge.addEventListener(
`RESPONSE-${eventId}`,
(e: CustomEvent) => {
log(`RESPONSE-${eventId} received data`, e.detail);
resolve(e.detail);
}
);
});
const { status, statusText, headers, body } = data;
return new Response(body, { status, statusText, headers });
})()
);
}
});
/// Main message router
self.addEventListener('message', (event: MessageEvent) => {
const log = console.log.bind(this, 'sw.on(message)');
const sourceClientId = event.source.id;
log(event.data);
if (event.data.type === 'GET_VERSION') {
// event.ports[0].postMessage(SW_VERSION);
event.source?.postMessage({ version: SW_VERSION });
}
if (event.data.type === 'SET_PEER_HOST') {
if (CURRENT_PEER_HOST_CLIENT_ID === null) {
log('setting new CURRENT_PEER_HOST_CLIENT_ID', sourceClientId);
} else {
log('updating CURRENT_PEER_HOST_CLIENT_ID to', sourceClientId);
}
CURRENT_PEER_HOST_CLIENT_ID = sourceClientId;
event.source?.postMessage({
type: 'RESPONSE',
originalType: event.data.type,
statusText: 'OK',
});
}
if (event.data.type === 'CLEAR_PEER_HOST') {
CURRENT_PEER_HOST_CLIENT_ID = null;
event.source?.postMessage({
type: 'RESPONSE',
originalType: event.data.type,
statusText: 'OK',
});
}
if (event.data.type === 'RESPONSE') {
const eventId = event.data.eventId;
responseBridge.reactResponse(eventId, event.data);
// self.dispatchEvent(new Event(`${event.data.type}-${eventId}`, event.data));
}
});