UNPKG

one

Version:

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

604 lines 22.5 kB
var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod)); var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var tui_exports = {}; __export(tui_exports, { getRouteMode: () => getRouteMode, startTUI: () => startTUI, stopTUI: () => stopTUI, triggerPulse: () => triggerPulse }); module.exports = __toCommonJS(tui_exports); var import_registry = require("./registry.cjs"); var import_picker = require("./picker.cjs"); var import_server = require("./server.cjs"); var import_picocolors = __toESM(require("picocolors"), 1); const CABLE_COLORS = [import_picocolors.default.green, import_picocolors.default.cyan, import_picocolors.default.magenta, import_picocolors.default.blue, import_picocolors.default.yellow]; const ESC = "\x1B"; const CSI = `${ESC}[`; const ansi = { hideCursor: `${CSI}?25l`, showCursor: `${CSI}?25h`, clearScreen: `${CSI}2J`, home: `${CSI}H` }; let tuiState = null; let daemonState = null; let refreshInterval = null; let physicsInterval = null; let stdinListener = null; let resizeListener = null; function getRouteMode() { return tuiState?.routeMode || "ask"; } function calcLayout(width) { const simEndX = Math.floor(width * 0.25); const serverStartX = Math.floor(width * 0.65); return { simEndX, serverStartX }; } function showPopup(message, durationMs = 2e3) { if (!tuiState) return; if (tuiState.popup) { clearTimeout(tuiState.popup.timeout); } const timeout = setTimeout(() => { if (tuiState) { tuiState.popup = null; render(); } }, durationMs); tuiState.popup = { message, timeout }; render(); } function startTUI(state) { daemonState = state; const width = process.stdout.columns || 80; const height = process.stdout.rows || 24; const { 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(); let resizePending = false; resizeListener = () => { if (!tuiState) return; tuiState.width = process.stdout.columns || 80; tuiState.height = process.stdout.rows || 24; const layout = calcLayout(tuiState.width); tuiState.simEndX = layout.simEndX; tuiState.serverStartX = layout.serverStartX; tuiState.lastRender = ""; if (!resizePending) { resizePending = true; setImmediate(() => { resizePending = false; process.stdout.write(ansi.clearScreen + ansi.home); render(); }); } }; process.stdout.on("resize", resizeListener); stdinListener = key => { const 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") { const 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"; (0, import_server.setRouteMode)(tuiState.routeMode); } else if (str === "b") { stopTUI(); console.log(import_picocolors.default.dim("\nDaemon running in background.")); return; } render(); }; process.stdin.on("data", stdinListener); const signalHandler = () => { 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; const isDragging = tuiState.draggingSimIndex !== null; if (isDragging) { if (tuiState.selectedCol === 1 && tuiState.servers.length > 0) { const simIndex = tuiState.draggingSimIndex; const sim = tuiState.simulators[simIndex]; const serverIndex = tuiState.selectedRow; const server = tuiState.servers[serverIndex]; if (server && sim) { (0, import_server.setSimulatorMapping)(sim.udid, server.id); (0, import_server.setPendingMapping)(server.id, sim.udid); (0, import_registry.setRoute)(daemonState, getRouteKey(sim), server.id); const cable = tuiState.cables.get(simIndex); if (cable) { cable.serverIndex = serverIndex; } tuiState.draggingSimIndex = null; if (tuiState.modeBeforeDrag === "most-recent") { tuiState.routeMode = "most-recent"; (0, import_server.setRouteMode)("most-recent"); } tuiState.modeBeforeDrag = null; } } return; } if (tuiState.selectedCol === 0 && tuiState.simulators.length > 0) { const simIndex = tuiState.selectedRow; const sim = tuiState.simulators[simIndex]; if (!sim) return; tuiState.modeBeforeDrag = tuiState.routeMode; if (tuiState.routeMode === "most-recent") { tuiState.routeMode = "ask"; (0, import_server.setRouteMode)("ask"); } (0, import_registry.clearRoute)(daemonState, getRouteKey(sim)); (0, import_server.clearMappingsForSimulator)(sim.udid); let cable = tuiState.cables.get(simIndex); if (!cable) { cable = { serverIndex: null, controlPoint: { x: tuiState.simEndX + 5, y: tuiState.rowStartY + simIndex }, velocity: { x: 0, y: 0 } }; tuiState.cables.set(simIndex, cable); } cable.serverIndex = null; cable.velocity = { x: 3, y: -2 }; tuiState.draggingSimIndex = simIndex; } else if (tuiState.selectedCol === 1 && tuiState.servers.length > 0) { const serverIndex = tuiState.selectedRow; for (const [simIndex, cable] of tuiState.cables) { if (cable.serverIndex === serverIndex) { const sim = tuiState.simulators[simIndex]; if (sim) { tuiState.modeBeforeDrag = tuiState.routeMode; if (tuiState.routeMode === "most-recent") { tuiState.routeMode = "ask"; (0, import_server.setRouteMode)("ask"); } (0, import_registry.clearRoute)(daemonState, getRouteKey(sim)); cable.serverIndex = null; cable.velocity = { x: -3, y: 2 }; tuiState.draggingSimIndex = simIndex; } break; } } } } function handleDisconnect() { if (!tuiState || !daemonState) return; if (tuiState.selectedCol === 0) { const simIndex = tuiState.selectedRow; const sim = tuiState.simulators[simIndex]; const cable = tuiState.cables.get(simIndex); if (!sim || !cable || cable.serverIndex === null) return; if (tuiState.routeMode === "most-recent") { tuiState.routeMode = "ask"; (0, import_server.setRouteMode)("ask"); showPopup("Switched to manual mode", 1500); } (0, import_registry.clearRoute)(daemonState, getRouteKey(sim)); (0, import_server.clearMappingsForSimulator)(sim.udid); cable.serverIndex = null; cable.velocity = { x: -4, y: 3 }; } else { const serverIndex = tuiState.selectedRow; for (const [simIndex, cable] of tuiState.cables) { if (cable.serverIndex === serverIndex) { const sim = tuiState.simulators[simIndex]; if (sim) { if (tuiState.routeMode === "most-recent") { tuiState.routeMode = "ask"; (0, import_server.setRouteMode)("ask"); showPopup("Switched to manual mode", 1500); } (0, import_registry.clearRoute)(daemonState, getRouteKey(sim)); (0, import_server.clearMappingsForSimulator)(sim.udid); cable.serverIndex = null; cable.velocity = { x: -4, y: 3 }; } break; } } } } function updatePhysics() { if (!tuiState) return; const gravity = 0.3; const damping = 0.85; let needsRender = false; for (const [simIndex, cable] of tuiState.cables) { const simY = tuiState.rowStartY + simIndex; if (cable.serverIndex !== null) { const sagCurve = i => { if (i <= 4) return 6 - i; return 2 + (i - 4) * 0.8; }; const sag = sagCurve(simIndex); const serverY = tuiState.rowStartY + cable.serverIndex; const targetX = (tuiState.simEndX + tuiState.serverStartX) / 2; const targetY = (simY + serverY) / 2 + sag; const dx = targetX - cable.controlPoint.x; const 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; const anchorX = tuiState.simEndX; const 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; } } if (needsRender) render(); } async function refreshData() { if (!tuiState || !daemonState) return; const newSims = await (0, import_picker.getBootedSimulators)(); const newServers = (0, import_registry.getAllServers)(daemonState); tuiState.simulators = newSims; tuiState.servers = newServers; const simMappings = (0, import_server.getSimulatorMappings)(); for (let simIndex = 0; simIndex < newSims.length; simIndex++) { const sim = newSims[simIndex]; const mappedServerId = simMappings.get(sim.udid); let routedServerIndex = null; if (mappedServerId) { routedServerIndex = newServers.findIndex(s => s.id === mappedServerId); if (routedServerIndex === -1) routedServerIndex = null; } let cable = tuiState.cables.get(simIndex); if (!cable) { cable = { serverIndex: routedServerIndex, controlPoint: { x: tuiState.simEndX + 5, y: tuiState.rowStartY + simIndex }, velocity: { x: 0, y: 0 } }; tuiState.cables.set(simIndex, cable); } if (tuiState.draggingSimIndex !== simIndex) { if (routedServerIndex !== cable.serverIndex) { cable.serverIndex = routedServerIndex; if (routedServerIndex !== null) { cable.velocity = { x: 0, y: -2 }; } } } } for (const simIndex of tuiState.cables.keys()) { if (simIndex >= newSims.length) { tuiState.cables.delete(simIndex); } } 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; const { width, height, simEndX, serverStartX } = tuiState; const lines = []; const title = " one daemon "; const headerPad = Math.max(0, width - title.length - 10); lines.push(import_picocolors.default.cyan(`\u250C\u2500${title}${"\u2500".repeat(headerPad)}\u2500:8081\u2500\u2510`)); const isAuto = tuiState.routeMode === "most-recent"; const toggleLeft = isAuto ? import_picocolors.default.green("\u25B6") : import_picocolors.default.dim("\u25B7"); const toggleRight = isAuto ? import_picocolors.default.dim("\u25C1") : import_picocolors.default.yellow("\u25C0"); const autoLabel = isAuto ? import_picocolors.default.green("AUTO") : import_picocolors.default.dim("auto"); const askLabel = isAuto ? import_picocolors.default.dim("ask") : import_picocolors.default.yellow("ASK"); const toggle = ` ${autoLabel} ${toggleLeft}\u2550\u2550\u2550${toggleRight} ${askLabel} [m] toggle`; const togglePad = Math.max(0, width - stripAnsi(toggle).length - 2); lines.push(import_picocolors.default.cyan("\u2502") + toggle + " ".repeat(togglePad) + import_picocolors.default.cyan("\u2502")); const simHeader = " SIMULATORS"; const srvHeader = "SERVERS "; const gap = " ".repeat(Math.max(0, serverStartX - simEndX)); lines.push(import_picocolors.default.cyan("\u2502") + import_picocolors.default.bold(simHeader.padEnd(simEndX - 1)) + gap + import_picocolors.default.bold(srvHeader.padStart(width - serverStartX - 1)) + import_picocolors.default.cyan("\u2502")); lines.push(import_picocolors.default.cyan("\u2502") + import_picocolors.default.dim("\u2500".repeat(width - 2)) + import_picocolors.default.cyan("\u2502")); const contentRows = height - 7; for (let row = 0; row < contentRows; row++) { const y = tuiState.rowStartY + row; let line = ""; line += import_picocolors.default.cyan("\u2502"); const sim = tuiState.simulators[row]; let simText = ""; if (sim) { const isSelected = tuiState.selectedCol === 0 && tuiState.selectedRow === row; const cable = tuiState.cables.get(row); const hasConnection = cable?.serverIndex !== null; const cableColor = CABLE_COLORS[row % CABLE_COLORS.length]; const plug = hasConnection ? cableColor("\u25CF") : import_picocolors.default.dim("\u25CB"); const name = truncate(sim.name, simEndX - 5); simText = `${name} ${plug}`; if (isSelected) simText = import_picocolors.default.inverse(simText); } const simTextLen = stripAnsi(simText).length; const simPad = Math.max(0, simEndX - 1 - simTextLen); line += " ".repeat(simPad) + simText; let cableZone = ""; for (let x = simEndX; x < serverStartX; x++) { const char = getCableCharAt(x, y); cableZone += char || " "; } line += cableZone; const server = tuiState.servers[row]; let srvLeft = ""; let srvRight = ""; if (server) { const isSelected = tuiState.selectedCol === 1 && tuiState.selectedRow === row; let connectedColor = null; for (const [simIndex, cable] of tuiState.cables) { if (cable.serverIndex === row) { connectedColor = CABLE_COLORS[simIndex % CABLE_COLORS.length]; break; } } const lastActive = daemonState ? (0, import_registry.getLastActiveServer)(daemonState) : null; const isLastActive = lastActive?.id === server.id; const plug = connectedColor ? connectedColor("\u25CF") : import_picocolors.default.dim("\u25CB"); const star = isLastActive ? import_picocolors.default.yellow("\u2605") : " "; const shortRoot = truncate(server.root.replace(process.env.HOME || "", "~"), width - serverStartX - 14); srvLeft = `${plug} ${star}${shortRoot}`; srvRight = import_picocolors.default.bold(import_picocolors.default.yellow(`:${server.port}`)); if (isSelected) { srvLeft = import_picocolors.default.inverse(srvLeft); srvRight = import_picocolors.default.inverse(srvRight); } } const srvLeftLen = stripAnsi(srvLeft).length; const srvRightLen = stripAnsi(srvRight).length; const srvColWidth = width - serverStartX - 2; const srvGap = Math.max(1, srvColWidth - srvLeftLen - srvRightLen); line += srvLeft + " ".repeat(srvGap) + srvRight; line += import_picocolors.default.cyan("\u2502"); lines.push(line); } if (tuiState.popup) { const msg = tuiState.popup.message; const padLeft = Math.floor((width - msg.length - 4) / 2); const padRight = width - msg.length - padLeft - 4; lines.push(import_picocolors.default.cyan("\u2502") + " ".repeat(Math.max(0, padLeft)) + import_picocolors.default.bgYellow(import_picocolors.default.black(` ${msg} `)) + " ".repeat(Math.max(0, padRight)) + import_picocolors.default.cyan("\u2502")); } else { lines.push(import_picocolors.default.cyan("\u2502") + import_picocolors.default.dim(" \u2191\u2193 select \u2190\u2192 move space grab/plug d disconnect b bg q quit").padEnd(width - 2) + import_picocolors.default.cyan("\u2502")); } lines.push(import_picocolors.default.cyan(`\u2514${"\u2500".repeat(width - 2)}\u2518`)); const 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; for (const [simIndex, cable] of tuiState.cables) { const startX = tuiState.simEndX; const startY = tuiState.rowStartY + simIndex; let endX, endY; 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); } const ctrlX = Math.round(cable.controlPoint.x); const ctrlY = Math.round(cable.controlPoint.y); const steps = 30; for (let i = 0; i <= steps; i++) { const t = i / steps; const invT = 1 - t; const px = Math.round(invT * invT * startX + 2 * invT * t * ctrlX + t * t * endX); const py = Math.round(invT * invT * startY + 2 * invT * t * ctrlY + t * t * endY); if (px === x && py === y) { const connected = cable.serverIndex !== null; const baseColor = CABLE_COLORS[simIndex % CABLE_COLORS.length]; const color = connected ? baseColor : import_picocolors.default.dim; const tPrev = Math.max(0, (i - 1) / steps); const tNext = Math.min(1, (i + 1) / steps); const prevX = Math.round((1 - tPrev) * (1 - tPrev) * startX + 2 * (1 - tPrev) * tPrev * ctrlX + tPrev * tPrev * endX); const prevY = Math.round((1 - tPrev) * (1 - tPrev) * startY + 2 * (1 - tPrev) * tPrev * ctrlY + tPrev * tPrev * endY); const nextX = Math.round((1 - tNext) * (1 - tNext) * startX + 2 * (1 - tNext) * tNext * ctrlX + tNext * tNext * endX); const nextY = Math.round((1 - tNext) * (1 - tNext) * startY + 2 * (1 - tNext) * tNext * ctrlY + tNext * tNext * endY); const dx = nextX - prevX; const dy = nextY - prevY; let char; 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); } } } 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) {}