enso/app/ydoc-server-nodejs/build.mjs
Paweł Grabarz 4d2cc04e17
More robust ydoc server watch (#10817)
Fixed occasional issues with ydoc server starting in dev mode, which were caused by missing dist file, then nodemon failing to trigger a file watch event after esbuild completion. Now esbuild is directly responsible for managing a child process, without needing an additional layer of file watchers.
2024-08-14 13:17:53 +00:00

51 lines
1.4 KiB
JavaScript

import esbuild from 'esbuild'
import { wasmLoader } from 'esbuild-plugin-wasm'
import { fork } from 'node:child_process'
const watchMode = process.argv[2] === 'watch'
const ctx = await esbuild.context({
outfile: 'dist/main.mjs',
sourcemap: 'linked',
entryPoints: ['src/main.ts'],
bundle: true,
platform: 'node',
target: ['node20'],
conditions: watchMode ? ['source'] : [],
format: 'esm',
plugins: [wasmLoader(), ...(watchMode ? [runServerProcess()] : [])],
})
if (watchMode) await ctx.watch()
else {
await ctx.rebuild()
await ctx.dispose()
}
function runServerProcess() {
return {
name: 'run-server-process',
setup: async function (build) {
let abortCtl
build.onEnd(async function (result) {
if (result.errors.length > 0) return
if (abortCtl) abortCtl.abort()
let scriptPath = build.initialOptions.outfile
console.info(`Restarting "${scriptPath}".`)
abortCtl = forkChildProcess(scriptPath)
})
},
}
}
function forkChildProcess(scriptPath) {
const controller = new AbortController()
fork(scriptPath, { stdio: 'inherit', signal: controller.signal })
.on('error', error => {
if (error.constructor.name != 'AbortError') console.error(error)
})
.on('close', function (code) {
if (code) console.info(`Completed '${scriptPath}' with exit code ${code}.`)
})
return controller
}