UNPKG

one

Version:

One is a new React Framework that makes Vite serve both native and web.

685 lines (684 loc) 23.9 kB
import { getAllServers, setRoute, clearRoute, getLastActiveServer } from "./registry.native.js"; import { getBootedSimulators } from "./picker.native.js"; import { setRouteMode, setPendingMapping, clearMappingsForSimulator, getSimulatorMappings, setSimulatorMapping } from "./server.native.js"; import colors from "picocolors"; var CABLE_COLORS = [colors.green, colors.cyan, colors.magenta, colors.blue, colors.yellow]; var ESC = "\x1B"; var CSI = `${ESC}[`; var ansi = { hideCursor: `${CSI}?25l`, showCursor: `${CSI}?25h`, clearScreen: `${CSI}2J`, home: `${CSI}H` }; var tuiState = null; var daemonState = null; var refreshInterval = null; var physicsInterval = null; var stdinListener = null; var resizeListener = null; function getRouteMode() { return (tuiState === null || tuiState === void 0 ? void 0 : tuiState.routeMode) || "ask"; } function calcLayout(width) { var simEndX = Math.floor(width * 0.25); var serverStartX = Math.floor(width * 0.65); return { simEndX, serverStartX }; } function showPopup(message) { var durationMs = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 2e3; if (!tuiState) return; if (tuiState.popup) { clearTimeout(tuiState.popup.timeout); } var timeout = setTimeout(function () { if (tuiState) { tuiState.popup = null; render(); } }, durationMs); tuiState.popup = { message, timeout }; render(); } function startTUI(state) { daemonState = state; var width = process.stdout.columns || 80; var height = process.stdout.rows || 24; var { simEndX, serverStartX } = calcLayout(width); tuiState = { simulators: [], servers: [], cables: /* @__PURE__ */new Map(), draggingSimIndex: null, modeBeforeDrag: null, selectedCol: 0, selectedRow: 0, routeMode: "most-recent", lastRender: "", width, height, simEndX, serverStartX, rowStartY: 5, popup: null }; process.stdout.write(ansi.clearScreen + ansi.home + ansi.hideCursor); if (process.stdin.isTTY) { process.stdin.setRawMode(true); } process.stdin.resume(); var resizePending = false; resizeListener = function () { if (!tuiState) return; tuiState.width = process.stdout.columns || 80; tuiState.height = process.stdout.rows || 24; var layout = calcLayout(tuiState.width); tuiState.simEndX = layout.simEndX; tuiState.serverStartX = layout.serverStartX; tuiState.lastRender = ""; if (!resizePending) { resizePending = true; setImmediate(function () { resizePending = false; process.stdout.write(ansi.clearScreen + ansi.home); render(); }); } }; process.stdout.on("resize", resizeListener); stdinListener = function (key) { var str = key.toString(); if (str === "" || str === "q") { stopTUI(); process.exit(0); } if (!tuiState || !daemonState) return; if (str === "\x1B[A") { tuiState.selectedRow = Math.max(0, tuiState.selectedRow - 1); } else if (str === "\x1B[B") { var max = tuiState.selectedCol === 0 ? Math.max(0, tuiState.simulators.length - 1) : Math.max(0, tuiState.servers.length - 1); tuiState.selectedRow = Math.min(max, tuiState.selectedRow + 1); } else if (str === "\x1B[C") { if (tuiState.selectedCol === 0) { tuiState.selectedCol = 1; tuiState.selectedRow = Math.min(tuiState.selectedRow, Math.max(0, tuiState.servers.length - 1)); } } else if (str === "\x1B[D") { if (tuiState.selectedCol === 1) { tuiState.selectedCol = 0; tuiState.selectedRow = Math.min(tuiState.selectedRow, Math.max(0, tuiState.simulators.length - 1)); } } else if (str === " " || str === "\r") { handleAction(); } else if (str === "d") { handleDisconnect(); } else if (str === "m") { tuiState.routeMode = tuiState.routeMode === "most-recent" ? "ask" : "most-recent"; setRouteMode(tuiState.routeMode); } else if (str === "b") { stopTUI(); console.log(colors.dim("\nDaemon running in background.")); return; } render(); }; process.stdin.on("data", stdinListener); var signalHandler = function () { stopTUI(); process.exit(0); }; process.on("SIGINT", signalHandler); process.on("SIGTERM", signalHandler); physicsInterval = setInterval(updatePhysics, 50); refreshInterval = setInterval(refreshData, 1e3); refreshData(); } function getRouteKey(sim) { return `sim:${sim.udid}`; } function handleAction() { if (!tuiState || !daemonState) return; var isDragging = tuiState.draggingSimIndex !== null; if (isDragging) { if (tuiState.selectedCol === 1 && tuiState.servers.length > 0) { var simIndex = tuiState.draggingSimIndex; var sim = tuiState.simulators[simIndex]; var serverIndex = tuiState.selectedRow; var server = tuiState.servers[serverIndex]; if (server && sim) { setSimulatorMapping(sim.udid, server.id); setPendingMapping(server.id, sim.udid); setRoute(daemonState, getRouteKey(sim), server.id); var cable = tuiState.cables.get(simIndex); if (cable) { cable.serverIndex = serverIndex; } tuiState.draggingSimIndex = null; if (tuiState.modeBeforeDrag === "most-recent") { tuiState.routeMode = "most-recent"; setRouteMode("most-recent"); } tuiState.modeBeforeDrag = null; } } return; } if (tuiState.selectedCol === 0 && tuiState.simulators.length > 0) { var simIndex1 = tuiState.selectedRow; var sim1 = tuiState.simulators[simIndex1]; if (!sim1) return; tuiState.modeBeforeDrag = tuiState.routeMode; if (tuiState.routeMode === "most-recent") { tuiState.routeMode = "ask"; setRouteMode("ask"); } clearRoute(daemonState, getRouteKey(sim1)); clearMappingsForSimulator(sim1.udid); var cable1 = tuiState.cables.get(simIndex1); if (!cable1) { cable1 = { serverIndex: null, controlPoint: { x: tuiState.simEndX + 5, y: tuiState.rowStartY + simIndex1 }, velocity: { x: 0, y: 0 } }; tuiState.cables.set(simIndex1, cable1); } cable1.serverIndex = null; cable1.velocity = { x: 3, y: -2 }; tuiState.draggingSimIndex = simIndex1; } else if (tuiState.selectedCol === 1 && tuiState.servers.length > 0) { var serverIndex1 = tuiState.selectedRow; var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0; try { for (var _iterator = tuiState.cables[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var [simIndex2, cable2] = _step.value; if (cable2.serverIndex === serverIndex1) { var sim2 = tuiState.simulators[simIndex2]; if (sim2) { tuiState.modeBeforeDrag = tuiState.routeMode; if (tuiState.routeMode === "most-recent") { tuiState.routeMode = "ask"; setRouteMode("ask"); } clearRoute(daemonState, getRouteKey(sim2)); cable2.serverIndex = null; cable2.velocity = { x: -3, y: 2 }; tuiState.draggingSimIndex = simIndex2; } break; } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return != null) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } } } function handleDisconnect() { if (!tuiState || !daemonState) return; if (tuiState.selectedCol === 0) { var simIndex = tuiState.selectedRow; var sim = tuiState.simulators[simIndex]; var cable = tuiState.cables.get(simIndex); if (!sim || !cable || cable.serverIndex === null) return; if (tuiState.routeMode === "most-recent") { tuiState.routeMode = "ask"; setRouteMode("ask"); showPopup("Switched to manual mode", 1500); } clearRoute(daemonState, getRouteKey(sim)); clearMappingsForSimulator(sim.udid); cable.serverIndex = null; cable.velocity = { x: -4, y: 3 }; } else { var serverIndex = tuiState.selectedRow; var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0; try { for (var _iterator = tuiState.cables[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var [simIndex1, cable1] = _step.value; if (cable1.serverIndex === serverIndex) { var sim1 = tuiState.simulators[simIndex1]; if (sim1) { if (tuiState.routeMode === "most-recent") { tuiState.routeMode = "ask"; setRouteMode("ask"); showPopup("Switched to manual mode", 1500); } clearRoute(daemonState, getRouteKey(sim1)); clearMappingsForSimulator(sim1.udid); cable1.serverIndex = null; cable1.velocity = { x: -4, y: 3 }; } break; } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return != null) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } } } function updatePhysics() { if (!tuiState) return; var gravity = 0.3; var damping = 0.85; var needsRender = false; var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0; try { for (var _iterator = tuiState.cables[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var [simIndex, cable] = _step.value; var simY = tuiState.rowStartY + simIndex; if (cable.serverIndex !== null) { var sagCurve = function (i) { if (i <= 4) return 6 - i; return 2 + (i - 4) * 0.8; }; var sag = sagCurve(simIndex); var serverY = tuiState.rowStartY + cable.serverIndex; var targetX = (tuiState.simEndX + tuiState.serverStartX) / 2; var targetY = (simY + serverY) / 2 + sag; var dx = targetX - cable.controlPoint.x; var dy = targetY - cable.controlPoint.y; cable.velocity.x += dx * 0.15; cable.velocity.y += dy * 0.15; cable.velocity.x *= damping; cable.velocity.y *= damping; cable.controlPoint.x += cable.velocity.x; cable.controlPoint.y += cable.velocity.y; if (Math.abs(cable.velocity.x) > 0.05 || Math.abs(cable.velocity.y) > 0.05) { needsRender = true; } } else { cable.velocity.y += gravity; cable.velocity.x *= damping; cable.velocity.y *= damping; cable.controlPoint.x += cable.velocity.x; cable.controlPoint.y += cable.velocity.y; var anchorX = tuiState.simEndX; var anchorY = simY; if (cable.controlPoint.x < anchorX) { cable.controlPoint.x = anchorX; cable.velocity.x = Math.abs(cable.velocity.x) * 0.5; } if (cable.controlPoint.x > tuiState.serverStartX) { cable.controlPoint.x = tuiState.serverStartX; cable.velocity.x = -Math.abs(cable.velocity.x) * 0.5; } if (cable.controlPoint.y < anchorY) { cable.controlPoint.y = anchorY; cable.velocity.y = Math.abs(cable.velocity.y) * 0.3; } if (cable.controlPoint.y > tuiState.height - 5) { cable.controlPoint.y = tuiState.height - 5; cable.velocity.y = -Math.abs(cable.velocity.y) * 0.5; } needsRender = true; } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return != null) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } if (needsRender) render(); } async function refreshData() { var _loop = function (simIndex2) { var sim = newSims[simIndex2]; var mappedServerId = simMappings.get(sim.udid); var routedServerIndex = null; if (mappedServerId) { routedServerIndex = newServers.findIndex(function (s) { return s.id === mappedServerId; }); if (routedServerIndex === -1) routedServerIndex = null; } var cable = tuiState.cables.get(simIndex2); if (!cable) { cable = { serverIndex: routedServerIndex, controlPoint: { x: tuiState.simEndX + 5, y: tuiState.rowStartY + simIndex2 }, velocity: { x: 0, y: 0 } }; tuiState.cables.set(simIndex2, cable); } if (tuiState.draggingSimIndex !== simIndex2) { if (routedServerIndex !== cable.serverIndex) { cable.serverIndex = routedServerIndex; if (routedServerIndex !== null) { cable.velocity = { x: 0, y: -2 }; } } } }; if (!tuiState || !daemonState) return; var newSims = await getBootedSimulators(); var newServers = getAllServers(daemonState); tuiState.simulators = newSims; tuiState.servers = newServers; var simMappings = getSimulatorMappings(); for (var simIndex = 0; simIndex < newSims.length; simIndex++) _loop(simIndex); var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0; try { for (var _iterator = tuiState.cables.keys()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var simIndex1 = _step.value; if (simIndex1 >= newSims.length) { tuiState.cables.delete(simIndex1); } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return != null) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } if (tuiState.selectedCol === 0) { tuiState.selectedRow = Math.min(tuiState.selectedRow, Math.max(0, newSims.length - 1)); } else { tuiState.selectedRow = Math.min(tuiState.selectedRow, Math.max(0, newServers.length - 1)); } render(); } function render() { if (!tuiState) return; var { width, height, simEndX, serverStartX } = tuiState; var lines = []; var title = " one daemon "; var headerPad = Math.max(0, width - title.length - 10); lines.push(colors.cyan(`\u250C\u2500${title}${"\u2500".repeat(headerPad)}\u2500:8081\u2500\u2510`)); var isAuto = tuiState.routeMode === "most-recent"; var toggleLeft = isAuto ? colors.green("\u25B6") : colors.dim("\u25B7"); var toggleRight = isAuto ? colors.dim("\u25C1") : colors.yellow("\u25C0"); var autoLabel = isAuto ? colors.green("AUTO") : colors.dim("auto"); var askLabel = isAuto ? colors.dim("ask") : colors.yellow("ASK"); var toggle = ` ${autoLabel} ${toggleLeft}\u2550\u2550\u2550${toggleRight} ${askLabel} [m] toggle`; var togglePad = Math.max(0, width - stripAnsi(toggle).length - 2); lines.push(colors.cyan("\u2502") + toggle + " ".repeat(togglePad) + colors.cyan("\u2502")); var simHeader = " SIMULATORS"; var srvHeader = "SERVERS "; var gap = " ".repeat(Math.max(0, serverStartX - simEndX)); lines.push(colors.cyan("\u2502") + colors.bold(simHeader.padEnd(simEndX - 1)) + gap + colors.bold(srvHeader.padStart(width - serverStartX - 1)) + colors.cyan("\u2502")); lines.push(colors.cyan("\u2502") + colors.dim("\u2500".repeat(width - 2)) + colors.cyan("\u2502")); var contentRows = height - 7; for (var row = 0; row < contentRows; row++) { var y = tuiState.rowStartY + row; var line = ""; line += colors.cyan("\u2502"); var sim = tuiState.simulators[row]; var simText = ""; if (sim) { var isSelected = tuiState.selectedCol === 0 && tuiState.selectedRow === row; var cable = tuiState.cables.get(row); var hasConnection = (cable === null || cable === void 0 ? void 0 : cable.serverIndex) !== null; var cableColor = CABLE_COLORS[row % CABLE_COLORS.length]; var plug = hasConnection ? cableColor("\u25CF") : colors.dim("\u25CB"); var name = truncate(sim.name, simEndX - 5); simText = `${name} ${plug}`; if (isSelected) simText = colors.inverse(simText); } var simTextLen = stripAnsi(simText).length; var simPad = Math.max(0, simEndX - 1 - simTextLen); line += " ".repeat(simPad) + simText; var cableZone = ""; for (var x = simEndX; x < serverStartX; x++) { var char = getCableCharAt(x, y); cableZone += char || " "; } line += cableZone; var server = tuiState.servers[row]; var srvLeft = ""; var srvRight = ""; if (server) { var isSelected1 = tuiState.selectedCol === 1 && tuiState.selectedRow === row; var connectedColor = null; var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0; try { for (var _iterator = tuiState.cables[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var [simIndex, cable1] = _step.value; if (cable1.serverIndex === row) { connectedColor = CABLE_COLORS[simIndex % CABLE_COLORS.length]; break; } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return != null) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } var lastActive = daemonState ? getLastActiveServer(daemonState) : null; var isLastActive = (lastActive === null || lastActive === void 0 ? void 0 : lastActive.id) === server.id; var plug1 = connectedColor ? connectedColor("\u25CF") : colors.dim("\u25CB"); var star = isLastActive ? colors.yellow("\u2605") : " "; var shortRoot = truncate(server.root.replace(process.env.HOME || "", "~"), width - serverStartX - 14); srvLeft = `${plug1} ${star}${shortRoot}`; srvRight = colors.bold(colors.yellow(`:${server.port}`)); if (isSelected1) { srvLeft = colors.inverse(srvLeft); srvRight = colors.inverse(srvRight); } } var srvLeftLen = stripAnsi(srvLeft).length; var srvRightLen = stripAnsi(srvRight).length; var srvColWidth = width - serverStartX - 2; var srvGap = Math.max(1, srvColWidth - srvLeftLen - srvRightLen); line += srvLeft + " ".repeat(srvGap) + srvRight; line += colors.cyan("\u2502"); lines.push(line); } if (tuiState.popup) { var msg = tuiState.popup.message; var padLeft = Math.floor((width - msg.length - 4) / 2); var padRight = width - msg.length - padLeft - 4; lines.push(colors.cyan("\u2502") + " ".repeat(Math.max(0, padLeft)) + colors.bgYellow(colors.black(` ${msg} `)) + " ".repeat(Math.max(0, padRight)) + colors.cyan("\u2502")); } else { lines.push(colors.cyan("\u2502") + colors.dim(" \u2191\u2193 select \u2190\u2192 move space grab/plug d disconnect b bg q quit").padEnd(width - 2) + colors.cyan("\u2502")); } lines.push(colors.cyan(`\u2514${"\u2500".repeat(width - 2)}\u2518`)); var output = lines.join("\n"); if (output !== tuiState.lastRender) { tuiState.lastRender = output; process.stdout.write(ansi.home + output); } } function getCableCharAt(x, y) { if (!tuiState) return null; if (tuiState.simulators.length === 0) return null; var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0; try { for (var _iterator = tuiState.cables[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var [simIndex, cable] = _step.value; var startX = tuiState.simEndX; var startY = tuiState.rowStartY + simIndex; var endX = void 0, endY = void 0; if (cable.serverIndex !== null) { endX = tuiState.serverStartX; endY = tuiState.rowStartY + cable.serverIndex; } else { endX = Math.round(cable.controlPoint.x); endY = Math.round(cable.controlPoint.y); } var ctrlX = Math.round(cable.controlPoint.x); var ctrlY = Math.round(cable.controlPoint.y); var steps = 30; for (var i = 0; i <= steps; i++) { var t = i / steps; var invT = 1 - t; var px = Math.round(invT * invT * startX + 2 * invT * t * ctrlX + t * t * endX); var py = Math.round(invT * invT * startY + 2 * invT * t * ctrlY + t * t * endY); if (px === x && py === y) { var connected = cable.serverIndex !== null; var baseColor = CABLE_COLORS[simIndex % CABLE_COLORS.length]; var color = connected ? baseColor : colors.dim; var tPrev = Math.max(0, (i - 1) / steps); var tNext = Math.min(1, (i + 1) / steps); var prevX = Math.round((1 - tPrev) * (1 - tPrev) * startX + 2 * (1 - tPrev) * tPrev * ctrlX + tPrev * tPrev * endX); var prevY = Math.round((1 - tPrev) * (1 - tPrev) * startY + 2 * (1 - tPrev) * tPrev * ctrlY + tPrev * tPrev * endY); var nextX = Math.round((1 - tNext) * (1 - tNext) * startX + 2 * (1 - tNext) * tNext * ctrlX + tNext * tNext * endX); var nextY = Math.round((1 - tNext) * (1 - tNext) * startY + 2 * (1 - tNext) * tNext * ctrlY + tNext * tNext * endY); var dx = nextX - prevX; var dy = nextY - prevY; var char = void 0; if (Math.abs(dx) > Math.abs(dy) * 2) { char = "\u2500"; } else if (Math.abs(dy) > Math.abs(dx) * 2) { char = "\u2502"; } else if (dx > 0 && dy > 0 || dx < 0 && dy < 0) { char = "\u2572"; } else { char = "\u2571"; } return color(char); } } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return != null) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } return null; } function truncate(str, maxLen) { if (maxLen <= 0) return ""; if (str.length <= maxLen) return str; return str.slice(0, maxLen - 1) + "\u2026"; } function stripAnsi(str) { return str.replace(/\x1b\[[0-9;]*m/g, ""); } function stopTUI() { if (refreshInterval) { clearInterval(refreshInterval); refreshInterval = null; } if (physicsInterval) { clearInterval(physicsInterval); physicsInterval = null; } if (stdinListener) { process.stdin.removeListener("data", stdinListener); stdinListener = null; } if (resizeListener) { process.stdout.removeListener("resize", resizeListener); resizeListener = null; } process.stdout.write(ansi.clearScreen + ansi.home + ansi.showCursor); if (process.stdin.isTTY) { process.stdin.setRawMode(false); } tuiState = null; daemonState = null; } function triggerPulse(_serverId, _direction) {} export { getRouteMode, startTUI, stopTUI, triggerPulse }; //# sourceMappingURL=tui.native.js.map