message: feat: bring up replacement workers for lost ones
diff: @@ -15,40 +15,41 @@ const OPTS = { stdio: ["pipe", "pipe", "pipe", "ipc"] };
  module.exports = createCompiler;
  async function createCompiler({ cwd, target = "" }) {
  - const workerPath = path.join(__dirname, "compiler-worker.js");
  - debug(`starting compiler worker at ${workerPath}`);
  + let worker;
  - const worker = fork(workerPath, dargs({cwd, target}), OPTS);
  - const send = typeof worker.send === "function"
  - ? payload => {
  - if (worker.connected) {
  - worker.send(ARSON.stringify(payload));
  + const send = payload => {
  + if (!worker || !worker.send || !worker.connected) {
  + return;
  }
  + worker.send(ARSON.stringify(payload));
  }
  - : () => {};
  let watching = false;
  const queue = [];
  let listeners = [];
  +
  const next = (message) => listeners.forEach(listener => listener.next(message));
  - setInterval(() => send({type: "heartbeat"}), 500);
  + const start = () => {
  + const workerPath = path.join(__dirname, "compiler-worker.js");
  + debug(`starting compiler worker at ${workerPath}`);
  + const cp = fork(workerPath, dargs({cwd, target}), OPTS);
  let stderr = ``;
  let stdout = ``;
  - worker.stdout.on("data", data => {
  + cp.stdout.on("data", data => {
  stdout += String(data);
  debug(`stdout ${workerPath}: ${data}`);
  });
  - worker.stderr.on("data", data => {
  + cp.stderr.on("data", data => {
  stderr += String(data);
  debug(`stderr ${workerPath}: ${data}`);
  });
  - worker.once("close", (code) => {
  + cp.once("close", (code) => {
  if (code !== 0) {
  queue.unshift({type: "exception", payload: {
  code,
  @@ -59,7 +60,14 @@ async function createCompiler({ cwd, target = "" }) {
  }
  });
  - worker.on("message", envelope => {
  + return cp;
  + };
  +
  + worker = start();
  +
  + setInterval(() => send({type: "heartbeat"}), 500);
  +
  + const onMessage = envelope => {
  const {type, target, payload} = ARSON.parse(envelope);
  switch (type) {
  @@ -84,11 +92,21 @@ async function createCompiler({ cwd, target = "" }) {
  return console.error(payload.message);
  }
  case "shutdown": {
  - console.warn(`compiler-worker for ${target} at ${workerPath} shut down.`);
  - return send({type: "stop"});
  + debug({type, target});
  + send({type: "stop"});
  +
  + worker = start();
  +
  + worker.on("message", onMessage);
  +
  + if (watching) {
  + send({type: "watch"});
  }
  }
  - });
  + }
  + };
  +
  + worker.on("message", onMessage);
  const observable = new Observable(observer => {
  if (!watching) {
  