UNPKG

monex

Version:

Execute one or multiple scripts, interactively or in daemon mode, and restart them whenever they crash or a watched file changes.

95 lines (94 loc) 2.73 kB
/* IMPORT */ import findUp from 'find-up-json'; import { spawn } from 'node:child_process'; import fs from 'node:fs'; import path from 'node:path'; import process from 'node:process'; import { color } from 'specialist'; import dirname from 'tiny-dirname'; import JSONC from 'tiny-jsonc'; import client from './client.js'; /* MAIN */ const Daemon = { /* API */ idle: async () => { if (await Daemon.ping()) return; return Daemon.idle(); }, log: async (linesNr = 100) => { const stats = await Daemon.stat(); const lines = []; for (const stat of stats) { const stdoutLines = stat.stdout.split(/\r?\n|\r/g).splice(-linesNr); const stderrLines = stat.stderr.split(/\r?\n|\r/g).splice(-linesNr); lines.push(`[${color.cyan.bold(stat.name)}:${color.bold('stdout')}]`); lines.push(...stdoutLines); lines.push(`[${color.cyan.bold(stat.name)}:${color.bold('stderr')}]`); lines.push(...stderrLines); } return lines.join('\n'); }, ping: async () => { try { await client.ping(); return true; } catch { return false; } }, spawn: async () => { await Daemon.stop(); const folderPath = dirname(import.meta.url); const serverPath = path.join(folderPath, 'server.js'); const proc = spawn(process.execPath, [serverPath], { stdio: 'ignore', env: process.env, cwd: process.cwd(), detached: true }); proc.unref(); await Daemon.idle(); }, start: async (config) => { if (typeof config === 'string') { config = JSONC.parse(fs.readFileSync(config, 'utf8')); } if (typeof config === 'undefined') { config = findUp('monex.json')?.content; } if (!Array.isArray(config)) { throw new Error('You need to provide a configuration, either via the "--config" option or by having a "monex.json" file higher up'); } await Daemon.spawn(); try { const result = await client.start(config); return !!result; } catch { return false; } }, stat: async () => { try { const result = await client.stat(); return result; } catch { return []; } }, stop: async () => { if (!await Daemon.ping()) return; try { await client.stop(); } catch { return Daemon.stop(); } } }; /* EXPORT */ export default Daemon;