-
Notifications
You must be signed in to change notification settings - Fork 0
/
pageHook.js
62 lines (56 loc) · 2.24 KB
/
pageHook.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
;(function hook(window) {
let counter = 0;
let messageCallback = {};
window.addEventListener('message', async event=>{
if (event.source !== window || event.data.source !== 'edge-lover-bridge') {
return;
}
console.log(`[edge][onEvent]${JSON.stringify(event.data)}`);
delete event.data.source;
let data = event.data;
if (data.type === 'request') {
let message = {type: 'response', destination: 'edge-lover-bridge', id: data.id};
try {
let response = await fetch(data.payload.api, data.payload.options);
let arrayBuffer = await response.arrayBuffer();
let body = btoa([].reduce.call(new Uint8Array(arrayBuffer), (p, c) => p + String.fromCharCode(c), ''));
let headers = {};
response.headers.forEach((value, key)=>headers[key]=value);
let options = {status: response.status, statusText: response.statusText, headers};
message.payload = {body, options};
} catch (error) {
message.payload = {error: error.message || error.stack || error.toString()};
}
window.postMessage(message);
}
if (data.type === 'response') {
if (data.payload.error) {
messageCallback[data.id][1](data.payload.error);
} else {
let body = atob(data.payload.body);
let bytes = new Uint8Array(body.length);
for (let idx = 0 ; idx < body.length; idx ++) {
bytes[idx] = body.charCodeAt(idx);
}
let response = new Response(bytes.buffer, data.payload.options);
messageCallback[data.id][0](response);
}
delete messageCallback[data.id];
}
});
window.edgeFetch = (api, options={}) => {
let id = ++ counter;
let origin;
if (options.edgeOrigin) {
origin = options.edgeOrigin;
delete options.edgeOrigin;
} else {
let url = new URL(api);
origin = url.origin;
}
let message = {id, destination: 'edge-lover-bridge', origin, type: 'request', payload: {api, options}};
console.log(`[edge][fetch]${JSON.stringify(message)}`);
window.postMessage(message);
return new Promise((resolve, reject) => messageCallback[id] = [resolve, reject]);
};
})(window);