2023-03-03 01:00:47 +03:00
|
|
|
/**
|
2023-03-15 06:42:14 +03:00
|
|
|
* @file This script is for watching the whole IDE and spawning the electron process.
|
2023-03-03 01:00:47 +03:00
|
|
|
*
|
|
|
|
* It sets up watchers for the client and content, and spawns the electron process with the IDE.
|
|
|
|
* The spawned electron process can then use its refresh capability to pull the latest changes
|
|
|
|
* from the watchers.
|
|
|
|
*
|
|
|
|
* If the electron is closed, the script will restart it, allowing to test the IDE setup.
|
|
|
|
* To stop, use Ctrl+C.
|
|
|
|
*/
|
|
|
|
|
2023-03-15 06:42:14 +03:00
|
|
|
import * as childProcess from 'node:child_process'
|
|
|
|
import * as fs from 'node:fs/promises'
|
|
|
|
import * as path from 'node:path'
|
2023-03-16 16:09:31 +03:00
|
|
|
import process from 'node:process'
|
2023-03-03 01:00:47 +03:00
|
|
|
|
2023-03-15 06:42:14 +03:00
|
|
|
import * as esbuild from 'esbuild'
|
2023-03-03 01:00:47 +03:00
|
|
|
|
|
|
|
import * as clientBundler from './esbuild-config.js'
|
|
|
|
import * as contentBundler from '../content/esbuild-config.js'
|
2023-03-15 06:42:14 +03:00
|
|
|
import * as paths from './paths.js'
|
2023-03-03 01:00:47 +03:00
|
|
|
|
|
|
|
/** Set of esbuild watches for the client and content. */
|
|
|
|
interface Watches {
|
|
|
|
client: esbuild.BuildResult
|
|
|
|
content: esbuild.BuildResult
|
|
|
|
}
|
|
|
|
|
2023-03-15 06:42:14 +03:00
|
|
|
const IDE_DIR_PATH = paths.getIdeDirectory()
|
|
|
|
const PROJECT_MANAGER_BUNDLE_PATH = paths.getProjectManagerBundlePath()
|
2023-03-03 01:00:47 +03:00
|
|
|
|
|
|
|
console.log('Cleaning IDE dist directory.')
|
2023-03-15 06:42:14 +03:00
|
|
|
await fs.rm(IDE_DIR_PATH, { recursive: true, force: true })
|
|
|
|
await fs.mkdir(IDE_DIR_PATH, { recursive: true })
|
2023-03-03 01:00:47 +03:00
|
|
|
|
2023-03-15 06:42:14 +03:00
|
|
|
const BOTH_BUNDLES_READY = new Promise<Watches>((resolve, reject) => {
|
|
|
|
void (async () => {
|
|
|
|
console.log('Bundling client.')
|
|
|
|
const clientBundlerOpts: esbuild.BuildOptions = {
|
|
|
|
...clientBundler.bundlerOptionsFromEnv(),
|
|
|
|
outdir: path.resolve(IDE_DIR_PATH),
|
|
|
|
watch: {
|
|
|
|
onRebuild(error) {
|
|
|
|
if (error) {
|
|
|
|
// We cannot carry on if the client failed to build, because electron executable
|
|
|
|
// would immediately exit with an error.
|
|
|
|
console.error('Client watch bundle failed:', error)
|
|
|
|
reject(error)
|
|
|
|
} else {
|
|
|
|
console.log('Client bundle updated.')
|
|
|
|
}
|
|
|
|
},
|
2023-03-03 01:00:47 +03:00
|
|
|
},
|
2023-03-15 06:42:14 +03:00
|
|
|
}
|
|
|
|
const client = await esbuild.build(clientBundlerOpts)
|
|
|
|
console.log('Result of client bundling: ', client)
|
2023-03-03 01:00:47 +03:00
|
|
|
|
2023-03-15 06:42:14 +03:00
|
|
|
console.log('Bundling content.')
|
|
|
|
const contentOpts = contentBundler.watchOptions(() => {
|
|
|
|
console.log('Content bundle updated.')
|
|
|
|
})
|
|
|
|
contentOpts.outdir = path.resolve(IDE_DIR_PATH, 'assets')
|
|
|
|
const content = await esbuild.build(contentOpts)
|
|
|
|
console.log('Result of content bundling: ', content)
|
|
|
|
resolve({ client, content })
|
|
|
|
})()
|
2023-03-03 01:00:47 +03:00
|
|
|
})
|
|
|
|
|
2023-03-15 06:42:14 +03:00
|
|
|
await BOTH_BUNDLES_READY
|
2023-03-03 01:00:47 +03:00
|
|
|
console.log('Exposing Project Manager bundle.')
|
2023-03-15 06:42:14 +03:00
|
|
|
await fs.symlink(
|
|
|
|
PROJECT_MANAGER_BUNDLE_PATH,
|
|
|
|
path.join(IDE_DIR_PATH, paths.PROJECT_MANAGER_BUNDLE),
|
|
|
|
'dir'
|
|
|
|
)
|
2023-03-03 01:00:47 +03:00
|
|
|
|
2023-03-15 06:42:14 +03:00
|
|
|
const ELECTRON_ARGS = [path.join(IDE_DIR_PATH, 'index.cjs'), '--', ...process.argv.slice(2)]
|
2023-03-03 01:00:47 +03:00
|
|
|
|
|
|
|
process.on('SIGINT', () => {
|
|
|
|
console.log('SIGINT received. Exiting.')
|
|
|
|
// The esbuild process seems to remain alive at this point and will keep our process from ending.
|
|
|
|
// Thus, we exit manually. It seems to terminate the child esbuild process as well.
|
|
|
|
process.exit(0)
|
|
|
|
})
|
|
|
|
|
2023-03-15 06:42:14 +03:00
|
|
|
for (;;) {
|
2023-03-03 01:00:47 +03:00
|
|
|
console.log('Spawning Electron process.')
|
2023-03-15 06:42:14 +03:00
|
|
|
const electronProcess = childProcess.spawn('electron', ELECTRON_ARGS, {
|
2023-03-03 01:00:47 +03:00
|
|
|
stdio: 'inherit',
|
|
|
|
shell: true,
|
|
|
|
})
|
|
|
|
console.log('Waiting for Electron process to finish.')
|
|
|
|
const result = await new Promise((resolve, reject) => {
|
|
|
|
electronProcess.on('close', resolve)
|
|
|
|
electronProcess.on('error', reject)
|
|
|
|
})
|
|
|
|
console.log('Electron process finished. Exit code: ', result)
|
|
|
|
}
|