-
Notifications
You must be signed in to change notification settings - Fork 78
/
wer-middleware.raw.ts
139 lines (120 loc) · 4.65 KB
/
wer-middleware.raw.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
134
135
136
137
138
139
/* tslint:disable */
/* -------------------------------------------------- */
/* Start of Webpack Hot Extension Middleware */
/* ================================================== */
/* This will be converted into a lodash templ., any */
/* external argument must be provided using it */
/* -------------------------------------------------- */
(function(window) {
const injectionContext = {browser: null};
(function() {
`<%= polyfillSource %>`;
}).bind(injectionContext)();
const { browser }: any = injectionContext;
const signals: any = JSON.parse('<%= signals %>');
const config: any = JSON.parse('<%= config %>');
const reloadPage: boolean = ("<%= reloadPage %>" as "true" | "false") === "true";
const wsHost = "<%= WSHost %>";
const {
SIGN_CHANGE,
SIGN_RELOAD,
SIGN_RELOADED,
SIGN_LOG,
SIGN_CONNECT,
} = signals;
const { RECONNECT_INTERVAL, SOCKET_ERR_CODE_REF } = config;
const { extension, runtime, tabs } = browser;
const manifest = runtime.getManifest();
// =============================== Helper functions ======================================= //
const formatter = (msg: string) => `[ WER: ${msg} ]`;
const logger = (msg, level = "info") => console[level](formatter(msg));
const timeFormatter = (date: Date) =>
date.toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, "$1");
// ========================== Called only on content scripts ============================== //
function contentScriptWorker() {
runtime.sendMessage({ type: SIGN_CONNECT }).then(msg => console.info(msg));
runtime.onMessage.addListener(({ type, payload }: IAction) => {
switch (type) {
case SIGN_RELOAD:
logger("Detected Changes. Reloading ...");
reloadPage && window.location.reload();
break;
case SIGN_LOG:
console.info(payload);
break;
}
});
}
// ======================== Called only on background scripts ============================= //
function backgroundWorker(socket: WebSocket) {
runtime.onMessage.addListener((action: IAction, sender) => {
if (action.type === SIGN_CONNECT) {
return Promise.resolve(formatter("Connected to Extension Hot Reloader"));
}
return true;
});
socket.addEventListener("message", ({ data }: MessageEvent) => {
const { type, payload } = JSON.parse(data);
if (type === SIGN_CHANGE && (!payload || !payload.onlyPageChanged)) {
tabs.query({ status: "complete" }).then(loadedTabs => {
loadedTabs.forEach(
tab => tab.id && tabs.sendMessage(tab.id, { type: SIGN_RELOAD }),
);
socket.send(
JSON.stringify({
type: SIGN_RELOADED,
payload: formatter(
`${timeFormatter(new Date())} - ${
manifest.name
} successfully reloaded`,
),
}),
);
runtime.reload();
});
} else {
runtime.sendMessage({ type, payload });
}
});
socket.addEventListener("close", ({ code }: CloseEvent) => {
logger(
`Socket connection closed. Code ${code}. See more in ${
SOCKET_ERR_CODE_REF
}`,
"warn",
);
const intId = setInterval(() => {
logger("Attempting to reconnect (tip: Check if Webpack is running)");
const ws = new WebSocket(wsHost);
ws.onerror = () => logger(`Error trying to re-connect. Reattempting in ${RECONNECT_INTERVAL / 1000}s`, "warn");
ws.addEventListener("open", () => {
clearInterval(intId);
logger("Reconnected. Reloading plugin");
runtime.reload();
});
}, RECONNECT_INTERVAL);
});
}
// ======================== Called only on extension pages that are not the background ============================= //
function extensionPageWorker() {
runtime.sendMessage({ type: SIGN_CONNECT }).then(msg => console.info(msg));
runtime.onMessage.addListener(({ type, payload }: IAction) => {
switch (type) {
case SIGN_CHANGE:
logger("Detected Changes. Reloading ...");
reloadPage && window.location.reload();
break;
case SIGN_LOG:
console.info(payload);
break;
}
});
}
// ======================= Bootstraps the middleware =========================== //
runtime.reload
? extension.getBackgroundPage() === window ? backgroundWorker(new WebSocket(wsHost)) : extensionPageWorker()
: contentScriptWorker();
})(window);
/* ----------------------------------------------- */
/* End of Webpack Hot Extension Middleware */
/* ----------------------------------------------- */