Skip to content

Commit 2dac7cb

Browse files
committed
feat(devtools): make the devtools web client work standalone and fix some issues
1 parent 790d304 commit 2dac7cb

File tree

14 files changed

+592
-176
lines changed

14 files changed

+592
-176
lines changed

package-lock.json

Lines changed: 83 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
"@typescript-eslint/parser": "7.18.0",
7070
"babel-loader": "9.2.1",
7171
"commitizen": "4.3.1",
72+
"concurrently": "^9.1.2",
7273
"cz-customizable": "7.4.0",
7374
"cz-customizable-ghooks": "2.0.0",
7475
"eslint": "8.57.0",

packages/overmind-devtools-client/DevtoolBackend.js

Lines changed: 75 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,55 @@ class DevtoolBackend {
1414

1515
connect(port) {
1616
if (this.devtoolServer) {
17-
this.devtoolServer.close()
18-
}
17+
const oldServer = this.devtoolServer
18+
this.devtoolServer = null
1919

20-
return new Promise((resolve, reject) => {
21-
this.devtoolServer = new WebSocket.Server({
22-
port,
23-
})
20+
return new Promise((resolve, reject) => {
21+
try {
22+
this.devtoolServer = new WebSocket.Server({ port })
23+
this.currentPort = port
24+
25+
this.devtoolServer.on('connection', this.onConnection)
26+
this.devtoolServer.on('error', reject)
27+
this.devtoolServer.on('close', () =>
28+
console.log('WebSocket server closed')
29+
)
2430

25-
this.devtoolServer.on('connection', this.onConnection)
26-
this.devtoolServer.on('error', reject)
27-
this.devtoolServer.on('close', (reason) => {
28-
console.log('Devtools backend closed', reason)
31+
this.devtoolServer.on('listening', () => {
32+
console.log(`DevTools WebSocket server listening on port ${port}`)
33+
34+
if (oldServer) {
35+
try {
36+
oldServer.close()
37+
} catch (err) {
38+
console.log('Error closing old server:', err.message)
39+
}
40+
}
41+
42+
resolve()
43+
})
44+
} catch (err) {
45+
console.error(`Error creating WebSocket server on port ${port}:`, err)
46+
reject(err)
47+
}
2948
})
30-
this.devtoolServer.on('listening', resolve)
31-
})
49+
} else {
50+
return new Promise((resolve, reject) => {
51+
this.devtoolServer = new WebSocket.Server({ port })
52+
this.devtoolServer.on('connection', this.onConnection)
53+
this.devtoolServer.on('error', reject)
54+
this.devtoolServer.on('close', () =>
55+
console.log('WebSocket server closed')
56+
)
57+
this.devtoolServer.on('listening', resolve)
58+
})
59+
}
3260
}
3361

3462
close() {
35-
this.devtoolServer.close()
63+
if (this.devtoolServer) {
64+
this.devtoolServer.close()
65+
}
3666
}
3767

3868
getQuery(url) {
@@ -41,7 +71,6 @@ class DevtoolBackend {
4171
.split(',')
4272
.reduce((aggr, part) => {
4373
const parts = part.split('=')
44-
4574
return Object.assign(aggr, {
4675
[parts[0]]: decodeURIComponent(parts[1]),
4776
})
@@ -50,8 +79,6 @@ class DevtoolBackend {
5079

5180
onConnection(ws, req) {
5281
const query = this.getQuery(req.url)
53-
54-
// devtools connects with ?devtools=1 in url
5582
if (query.devtools) {
5683
this.onDevtoolConnection(ws, req)
5784
} else {
@@ -69,11 +96,7 @@ class DevtoolBackend {
6996

7097
switch (parsedMessage.type) {
7198
case 'ping':
72-
this.devtoolSocket.send(
73-
JSON.stringify({
74-
type: 'pong',
75-
})
76-
)
99+
this.devtoolSocket.send(JSON.stringify({ type: 'pong' }))
77100
break
78101
case 'storage:get':
79102
this.evaluateDevtoolMessage(parsedMessage, () =>
@@ -100,7 +123,6 @@ class DevtoolBackend {
100123
this.options.openChromeDevtools()
101124
break
102125
default:
103-
console.log('DEVTOOL MESSAGE', message)
104126
this.clientSockets[parsedMessage.data.appName].send(
105127
JSON.stringify(parsedMessage.data)
106128
)
@@ -113,25 +135,34 @@ class DevtoolBackend {
113135
}
114136

115137
this.clientSockets[name] = ws
116-
117138
ws.on('message', this.onClientMessage)
118139

119140
const self = this
120141
ws.on('close', function onClose() {
121142
ws.removeEventListener('message', self.onClientMessage)
122143
ws.removeEventListener('close', onClose)
123144

124-
self.devtoolSocket.send(
125-
JSON.stringify({
126-
type: 'disconnect',
127-
data: name,
128-
})
129-
)
145+
if (
146+
self.devtoolSocket &&
147+
self.devtoolSocket.readyState === WebSocket.OPEN
148+
) {
149+
self.devtoolSocket.send(
150+
JSON.stringify({
151+
type: 'disconnect',
152+
data: name,
153+
})
154+
)
155+
}
130156
})
131157
}
132158

133159
onClientMessage(message) {
134-
this.devtoolSocket.send(`{"type":"message","data":${message}}`)
160+
if (
161+
this.devtoolSocket &&
162+
this.devtoolSocket.readyState === WebSocket.OPEN
163+
) {
164+
this.devtoolSocket.send(`{"type":"message","data":${message}}`)
165+
}
135166
}
136167

137168
async evaluateDevtoolMessage(message, cb) {
@@ -150,27 +181,20 @@ class DevtoolBackend {
150181
}
151182
}
152183

184+
// Templates for error pages
153185
getChangePortMarkup(port, onPortSubmit, onRestart) {
154186
return `<!DOCTYPE html>
155187
<html lang="en">
156188
<head>
157189
<meta charset="UTF-8" />
158190
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
159191
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
160-
<title>Document</title>
161-
<link
162-
href="https://fonts.googleapis.com/css?family=Source+Code+Pro"
163-
rel="stylesheet"
164-
/>
165-
<link
166-
href="https://fonts.googleapis.com/css?family=Nunito:400,700"
167-
rel="stylesheet"
168-
/>
192+
<title>Port Error</title>
193+
<link href="https://fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" />
194+
<link href="https://fonts.googleapis.com/css?family=Nunito:400,700" rel="stylesheet" />
169195
<script type="text/javascript">
170196
${onPortSubmit.toString()}
171-
172197
${onRestart.toString()}
173-
174198
function handleFormSubmit(event) {
175199
event.preventDefault()
176200
var input = document.querySelector('#port-input')
@@ -179,45 +203,13 @@ class DevtoolBackend {
179203
}
180204
</script>
181205
<style>
182-
html, body {
183-
margin: 0;
184-
padding: 0;
185-
height: 100vh;
186-
background-color: hsl(206, 57%, 13%);
187-
}
188-
.wrapper {
189-
display: flex;
190-
align-items: center;
191-
justify-content: center;
192-
height: 100%;
193-
}
194-
.inner-wrapper {
195-
display: flex;
196-
flex-direction: column;
197-
align-items: center;
198-
}
199-
h1 {
200-
color: white;
201-
}
202-
input {
203-
border: 0;
204-
border-radius: 3px;
205-
width: 200px;
206-
padding: 1rem;
207-
font-size: 18px;
208-
outline: none;
209-
}
210-
button {
211-
padding: 1rem;
212-
border: 0;
213-
outline: 0;
214-
color: white;
215-
background-color: #fac863;
216-
margin: 1rem;
217-
font-size: 18px;
218-
border-radius: 3px;
219-
cursor: pointer;
220-
}
206+
html, body { margin: 0; padding: 0; height: 100vh; background-color: hsl(206, 57%, 13%); }
207+
.wrapper { display: flex; align-items: center; justify-content: center; height: 100%; }
208+
.inner-wrapper { display: flex; flex-direction: column; align-items: center; }
209+
h1 { color: white; }
210+
input { border: 0; border-radius: 3px; width: 200px; padding: 1rem; font-size: 18px; outline: none; }
211+
button { padding: 1rem; border: 0; color: white; background-color: #fac863;
212+
margin: 1rem; font-size: 18px; border-radius: 3px; cursor: pointer; }
221213
</style>
222214
</head>
223215
<body>
@@ -242,23 +234,15 @@ class DevtoolBackend {
242234
<meta charset="UTF-8" />
243235
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
244236
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
245-
<title>Document</title>
246-
<link
247-
href="https://fonts.googleapis.com/css?family=Source+Code+Pro"
248-
rel="stylesheet"
249-
/>
250-
<link
251-
href="https://fonts.googleapis.com/css?family=Nunito:400,700"
252-
rel="stylesheet"
253-
/>
237+
<title>Overmind DevTools</title>
238+
<link href="https://fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" />
239+
<link href="https://fonts.googleapis.com/css?family=Nunito:400,700" rel="stylesheet" />
254240
<script type="text/javascript">
255241
window['__OVERMIND_DEVTOOLS_BACKEND_PORT__'] = "${port}";
256242
</script>
257243
<script type="text/javascript">
258244
${onPortSubmit.toString()}
259-
260245
${onRestart.toString()}
261-
262246
function handleFormSubmit(event) {
263247
event.preventDefault()
264248
var input = document.querySelector('#port-input')

0 commit comments

Comments
 (0)