@lvce-editor/server 0.53.5 → 0.53.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@ This project incorporates components from the projects listed below, that may ha
2
2
  differing from this project:
3
3
 
4
4
 
5
- 1) License Notice for static/bef774c/icons (from https://github.com/microsoft/vscode-icons)
5
+ 1) License Notice for static/92d11f3/icons (from https://github.com/microsoft/vscode-icons)
6
6
  ---------------------------------------
7
7
 
8
8
  Attribution 4.0 International
@@ -402,7 +402,7 @@ public licenses.
402
402
  Creative Commons may be contacted at creativecommons.org.
403
403
 
404
404
 
405
- 2) License Notice for static/bef774c/fonts/FiraCode-VariableFont.ttf (from https://github.com/tonsky/FiraCode)
405
+ 2) License Notice for static/92d11f3/fonts/FiraCode-VariableFont.ttf (from https://github.com/tonsky/FiraCode)
406
406
  ---------------------------------------
407
407
 
408
408
  Copyright (c) 2014, The Fira Code Project Authors (https://github.com/tonsky/FiraCode)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/server",
3
- "version": "0.53.5",
3
+ "version": "0.53.7",
4
4
  "description": "Run LVCE Editor as a server.",
5
5
  "main": "index.js",
6
6
  "bin": "bin/server.js",
@@ -20,7 +20,7 @@
20
20
  "node": ">=18"
21
21
  },
22
22
  "dependencies": {
23
- "@lvce-editor/shared-process": "0.53.5",
24
- "@lvce-editor/static-server": "0.53.5"
23
+ "@lvce-editor/shared-process": "0.53.7",
24
+ "@lvce-editor/static-server": "0.53.7"
25
25
  }
26
26
  }
package/src/server.js CHANGED
@@ -4,6 +4,7 @@ import { ChildProcess, fork } from 'node:child_process'
4
4
  import { createServer } from 'node:http'
5
5
  import { dirname, join, resolve } from 'node:path'
6
6
  import { fileURLToPath } from 'node:url'
7
+ import { Worker } from 'node:worker_threads'
7
8
 
8
9
  const __dirname = dirname(fileURLToPath(import.meta.url))
9
10
  const ROOT = resolve(__dirname, '../')
@@ -45,7 +46,7 @@ const isStatic = (url) => {
45
46
  if(url === '/'){
46
47
  return true
47
48
  }
48
- if (url.startsWith('/bef774c')) {
49
+ if (url.startsWith('/92d11f3')) {
49
50
  return true
50
51
  }
51
52
  if (url.startsWith('/favicon.ico')) {
@@ -59,7 +60,7 @@ const isStatic = (url) => {
59
60
 
60
61
  const handleRequest = (req, res) => {
61
62
  if (isStatic(req.url)) {
62
- return sendHandleStaticServerProcess(req, res.socket, 'HandleRequest.handleRequest')
63
+ return sendHandleStaticServerProcess(req, res, 'StaticServer.getResponse')
63
64
  }
64
65
  return sendHandleSharedProcess(req, res.socket, 'HandleRequest.handleRequest')
65
66
  }
@@ -107,24 +108,55 @@ const handleSharedProcessDisconnect = () => {
107
108
  console.info('[server] shared process disconnected')
108
109
  }
109
110
 
111
+ const waitForProcessToBeReady = async (childProcess) => {
112
+ const { resolve, promise } = Promise.withResolvers()
113
+ childProcess.once('message', resolve)
114
+ const message = await promise
115
+ if (message !== 'ready') {
116
+ throw new Error('unexpected message')
117
+ }
118
+ }
119
+
110
120
  /**
111
121
  *
112
- * @returns {Promise<ChildProcess>}
122
+ * @returns {Promise<any>}
113
123
  */
114
124
  const launchProcess = async (processPath, execArgv) => {
115
- const childProcess = fork(processPath, execArgv, {
116
- stdio: 'inherit',
117
- env: {
118
- ...process.env,
119
- },
120
- execArgv: [],
121
- })
122
- childProcess.on('exit', handleExit)
123
- childProcess.on('disconnect', handleSharedProcessDisconnect)
124
- const { resolve, promise } = Promise.withResolvers()
125
- childProcess.once('message', resolve)
126
- await promise
127
- return childProcess
125
+ const isWorker = execArgv.includes('--ipc-type=node-worker')
126
+ if (isWorker) {
127
+ const childProcess = new Worker(processPath, {
128
+ argv: execArgv,
129
+ env: {
130
+ ...process.env,
131
+ },
132
+ })
133
+ childProcess.on('exit', handleExit)
134
+ childProcess.on('disconnect', handleSharedProcessDisconnect)
135
+ await waitForProcessToBeReady(childProcess)
136
+ return {
137
+ send(message) {
138
+ childProcess.postMessage(message)
139
+ },
140
+ on(event, listener) {
141
+ childProcess.on(event, listener)
142
+ },
143
+ off(event, listener) {
144
+ childProcess.off(event, listener)
145
+ },
146
+ }
147
+ } else {
148
+ const childProcess = fork(processPath, execArgv, {
149
+ stdio: 'inherit',
150
+ env: {
151
+ ...process.env,
152
+ },
153
+ execArgv: [],
154
+ })
155
+ childProcess.on('exit', handleExit)
156
+ childProcess.on('disconnect', handleSharedProcessDisconnect)
157
+ await waitForProcessToBeReady(childProcess)
158
+ return childProcess
159
+ }
128
160
  }
129
161
 
130
162
  /**
@@ -153,7 +185,8 @@ const getOrCreateSharedProcess = () => {
153
185
  */
154
186
  const launchStaticServerProcess = async () => {
155
187
  const staticServerPath = fileURLToPath(import.meta.resolve('@lvce-editor/static-server'))
156
- return launchProcess(staticServerPath, [])
188
+ const ipc = await launchProcess(staticServerPath, ['--ipc-type=node-worker'])
189
+ return ipc
157
190
  }
158
191
 
159
192
  /**
@@ -189,14 +222,22 @@ const handleRequestError = (error) => {
189
222
  console.info('[info]: request upgrade error', error)
190
223
  }
191
224
 
192
- const handleSocketError = (error) => {
225
+ const handleSocketUpgradeError = (error) => {
193
226
  // @ts-ignore
194
227
  console.info('[info] request socket upgrade error', error)
195
228
  }
196
229
 
230
+ const handleSocketError = (error) => {
231
+ if (error && error.code === 'ECONNRESET') {
232
+ return
233
+ }
234
+ // @ts-ignore
235
+ console.info('[info] request socket error', error)
236
+ }
237
+
197
238
  const sendHandleSharedProcess = async (request, socket, method, ...params) => {
198
239
  request.on('error', handleRequestError)
199
- socket.on('error', handleSocketError)
240
+ socket.on('error', handleSocketUpgradeError)
200
241
  const sharedProcess = await getOrCreateSharedProcess()
201
242
  sharedProcess.send(
202
243
  {
@@ -211,21 +252,47 @@ const sendHandleSharedProcess = async (request, socket, method, ...params) => {
211
252
  )
212
253
  }
213
254
 
214
- const sendHandleStaticServerProcess = async (request, socket, method, ...params) => {
255
+ let id = 1
256
+
257
+ const createId = () => {
258
+ return ++id
259
+ }
260
+
261
+ const setHeaders = (response, headers) => {
262
+ for (const [key, value] of Object.entries(headers)) {
263
+ response.setHeader(key, value)
264
+ }
265
+ }
266
+
267
+ const sendHandleStaticServerProcess = async (request, res, method, ...params) => {
215
268
  request.on('error', handleRequestError)
216
- socket.on('error', handleSocketError)
269
+ res.socket.on('error', handleSocketError)
217
270
  const staticServerProcess = await getOrCreateStaticServerPathProcess()
218
- staticServerProcess.send(
219
- {
220
- jsonrpc: '2.0',
221
- method,
222
- params: [getHandleMessage(request), ...params],
223
- },
224
- socket,
225
- {
226
- keepOpen: false,
227
- },
228
- )
271
+ const { resolve, promise } = Promise.withResolvers()
272
+ const id = createId()
273
+ const handleMessage = (message) => {
274
+ if (message.id && message.id === id) {
275
+ resolve(message)
276
+ staticServerProcess.off('message', handleMessage)
277
+ }
278
+ }
279
+ staticServerProcess.on('message', handleMessage)
280
+ staticServerProcess.send({
281
+ jsonrpc: '2.0',
282
+ id,
283
+ method,
284
+ params: [getHandleMessage(request), ...params],
285
+ })
286
+ const response = await promise
287
+ const { result } = response
288
+ const { status, headers, body } = result
289
+ if (!status) {
290
+ throw new Error('invalid status')
291
+ }
292
+ res.statusCode = status
293
+ setHeaders(res, headers)
294
+ res.end(body)
295
+ // TODO use invoke
229
296
  }
230
297
 
231
298
  /**