#!/usr/bin/env node const fs = require("fs"); var electronPath = require("electron"); const net = require("net"); var buffer = []; var electronWindowOpened = false; var socket; net.createServer((s) => { socket = s; const pythonLineStream = byline.createStream(socket); pythonLineStream.on("data", line => { line = line.toString(); if (!line.length) return; if (electronWindowOpened) { electronProcess.send(line); } else { buffer.push(line); } }); }).listen(4387) const { spawn } = require("child_process"); const byline = require("byline") var args = process.argv.slice(2) if (!args.length) { console.log("Usage: livepython [program] [..args]") process.exit() } args.unshift(__dirname + "/../tracer.py") const electronProcess = spawn(electronPath, [__dirname + "/../"], { stdio: ["pipe", "pipe", "pipe", "ipc"] }) const pythonProcess = spawn("python", args); pythonProcess.stdout.on("data", data => { process.stdout.write(data.toString()); }); pythonProcess.stderr.on("data", data => { process.stdout.write(data.toString()) }) pythonProcess.on("exit", (code) => { electronProcess.kill('SIGINT') process.exit(); }) electronProcess.on("message", msg => { if (msg.type === 'connected') { electronWindowOpened = true; buffer.forEach(msg => { electronProcess.send(msg); }); } else if (msg.type === "toggle_running_state") { if (msg.value) { pythonProcess.kill("SIGSTOP") } else { pythonProcess.kill("SIGCONT"); } } else { socket.write(JSON.stringify(msg)) } }) function killSubprocesses (e) { electronProcess.kill("SIGINT"); pythonProcess.kill("SIGINT"); process.exit(); } process.on('exit', killSubprocesses) process.on('SIGINT', killSubprocesses) process.on("SIGUSR1", killSubprocesses) process.on("SIGUSR2", killSubprocesses) process.on("uncaughtException", killSubprocesses)