one
Version:
One is a new React Framework that makes Vite serve both native and web.
386 lines • 20.9 kB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf,
__hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all) __defProp(target, name, {
get: all[name],
enumerable: !0
});
},
__copyProps = (to, from, except, desc) => {
if (from && typeof from == "object" || typeof from == "function") for (let key of __getOwnPropNames(from)) !__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: !0
}) : target, mod)),
__toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
value: !0
}), 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"),
import_picker = require("./picker.cjs"),
import_server = require("./server.cjs"),
import_picocolors = __toESM(require("picocolors"), 1);
const ESC = "\x1B",
CSI = `${ESC}[`,
ansi = {
hideCursor: `${CSI}?25l`,
showCursor: `${CSI}?25h`,
clearScreen: `${CSI}2J`,
home: `${CSI}H`
};
let tuiState = null,
daemonState = null,
refreshInterval = null,
physicsInterval = null,
stdinListener = null,
resizeListener = null;
function getRouteMode() {
return tuiState?.routeMode || "ask";
}
function calcLayout(width) {
const simEndX = Math.floor(width * 0.25),
serverStartX = Math.floor(width * 0.65);
return {
simEndX,
serverStartX
};
}
function showPopup(message, durationMs = 2e3) {
if (!tuiState) return;
tuiState.popup && clearTimeout(tuiState.popup.timeout);
const timeout = setTimeout(() => {
tuiState && (tuiState.popup = null, render());
}, durationMs);
tuiState.popup = {
message,
timeout
}, render();
}
function startTUI(state) {
daemonState = state;
const width = process.stdout.columns || 80,
height = process.stdout.rows || 24,
{
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), process.stdin.isTTY && process.stdin.setRawMode(!0), process.stdin.resume();
let resizePending = !1;
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 = "", resizePending || (resizePending = !0, setImmediate(() => {
resizePending = !1, 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)), !(!tuiState || !daemonState)) {
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") tuiState.selectedCol === 0 && (tuiState.selectedCol = 1, tuiState.selectedRow = Math.min(tuiState.selectedRow, Math.max(0, tuiState.servers.length - 1)));else if (str === "\x1B[D") 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(`
Daemon 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;
if (tuiState.draggingSimIndex !== null) {
if (tuiState.selectedCol === 1 && tuiState.servers.length > 0) {
const simIndex = tuiState.draggingSimIndex,
sim = tuiState.simulators[simIndex],
serverIndex = tuiState.selectedRow,
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);
cable && (cable.serverIndex = serverIndex), tuiState.draggingSimIndex = null, 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,
sim = tuiState.simulators[simIndex];
if (!sim) return;
tuiState.modeBeforeDrag = tuiState.routeMode, 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);
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];
sim && (tuiState.modeBeforeDrag = tuiState.routeMode, 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)) if (tuiState.selectedCol === 0) {
const simIndex = tuiState.selectedRow,
sim = tuiState.simulators[simIndex],
cable = tuiState.cables.get(simIndex);
if (!sim || !cable || cable.serverIndex === null) return;
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];
sim && (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,
damping = 0.85;
let needsRender = !1;
for (const [simIndex, cable] of tuiState.cables) {
const simY = tuiState.rowStartY + simIndex;
if (cable.serverIndex !== null) {
const sag = (i => i <= 4 ? 6 - i : 2 + (i - 4) * 0.8)(simIndex),
serverY = tuiState.rowStartY + cable.serverIndex,
targetX = (tuiState.simEndX + tuiState.serverStartX) / 2,
targetY = (simY + serverY) / 2 + sag,
dx = targetX - cable.controlPoint.x,
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, (Math.abs(cable.velocity.x) > 0.05 || Math.abs(cable.velocity.y) > 0.05) && (needsRender = !0);
} 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,
anchorY = simY;
cable.controlPoint.x < anchorX && (cable.controlPoint.x = anchorX, cable.velocity.x = Math.abs(cable.velocity.x) * 0.5), cable.controlPoint.x > tuiState.serverStartX && (cable.controlPoint.x = tuiState.serverStartX, cable.velocity.x = -Math.abs(cable.velocity.x) * 0.5), cable.controlPoint.y < anchorY && (cable.controlPoint.y = anchorY, cable.velocity.y = Math.abs(cable.velocity.y) * 0.3), cable.controlPoint.y > tuiState.height - 5 && (cable.controlPoint.y = tuiState.height - 5, cable.velocity.y = -Math.abs(cable.velocity.y) * 0.5), needsRender = !0;
}
}
needsRender && render();
}
async function refreshData() {
if (!tuiState || !daemonState) return;
const newSims = await (0, import_picker.getBootedSimulators)(),
newServers = (0, import_registry.getAllServers)(daemonState);
tuiState.simulators = newSims, tuiState.servers = newServers;
const isDragging = tuiState.draggingSimIndex !== null,
simMappings = (0, import_server.getSimulatorMappings)();
for (let simIndex = 0; simIndex < newSims.length; simIndex++) {
const sim = newSims[simIndex],
mappedServerId = simMappings.get(sim.udid);
let routedServerIndex = null;
mappedServerId && (routedServerIndex = newServers.findIndex(s => s.id === mappedServerId), routedServerIndex === -1 && (routedServerIndex = null));
let cable = tuiState.cables.get(simIndex);
cable || (cable = {
serverIndex: routedServerIndex,
controlPoint: {
x: tuiState.simEndX + 5,
y: tuiState.rowStartY + simIndex
},
velocity: {
x: 0,
y: 0
}
}, tuiState.cables.set(simIndex, cable)), tuiState.draggingSimIndex !== simIndex && routedServerIndex !== cable.serverIndex && (cable.serverIndex = routedServerIndex, routedServerIndex !== null && (cable.velocity = {
x: 0,
y: -2
}));
}
for (const simIndex of tuiState.cables.keys()) simIndex >= newSims.length && tuiState.cables.delete(simIndex);
tuiState.selectedCol === 0 ? tuiState.selectedRow = Math.min(tuiState.selectedRow, Math.max(0, newSims.length - 1)) : tuiState.selectedRow = Math.min(tuiState.selectedRow, Math.max(0, newServers.length - 1)), render();
}
function render() {
if (!tuiState) return;
const {
width,
height,
simEndX,
serverStartX
} = tuiState,
lines = [],
title = " one daemon ",
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",
toggleLeft = isAuto ? import_picocolors.default.green("\u25B6") : import_picocolors.default.dim("\u25B7"),
toggleRight = isAuto ? import_picocolors.default.dim("\u25C1") : import_picocolors.default.yellow("\u25C0"),
autoLabel = isAuto ? import_picocolors.default.green("AUTO") : import_picocolors.default.dim("auto"),
askLabel = isAuto ? import_picocolors.default.dim("ask") : import_picocolors.default.yellow("ASK"),
toggle = ` ${autoLabel} ${toggleLeft}\u2550\u2550\u2550${toggleRight} ${askLabel} [m] toggle`,
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",
srvHeader = "SERVERS ",
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,
hasConnection = tuiState.cables.get(row)?.serverIndex !== null,
cableColors = [import_picocolors.default.green, import_picocolors.default.cyan, import_picocolors.default.magenta, import_picocolors.default.blue, import_picocolors.default.yellow],
cableColor = cableColors[row % cableColors.length],
plug = hasConnection ? cableColor("\u25CF") : import_picocolors.default.dim("\u25CB");
simText = `${truncate(sim.name, simEndX - 5)} ${plug}`, isSelected && (simText = import_picocolors.default.inverse(simText));
}
const simTextLen = stripAnsi(simText).length,
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 = "",
srvRight = "";
if (server) {
const isSelected = tuiState.selectedCol === 1 && tuiState.selectedRow === row,
cableColors = [import_picocolors.default.green, import_picocolors.default.cyan, import_picocolors.default.magenta, import_picocolors.default.blue, import_picocolors.default.yellow];
let connectedColor = null;
for (const [simIndex, cable] of tuiState.cables) if (cable.serverIndex === row) {
connectedColor = cableColors[simIndex % cableColors.length];
break;
}
const isLastActive = (daemonState ? (0, import_registry.getLastActiveServer)(daemonState) : null)?.id === server.id,
plug = connectedColor ? connectedColor("\u25CF") : import_picocolors.default.dim("\u25CB"),
star = isLastActive ? import_picocolors.default.yellow("\u2605") : " ",
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}`)), isSelected && (srvLeft = import_picocolors.default.inverse(srvLeft), srvRight = import_picocolors.default.inverse(srvRight));
}
const srvLeftLen = stripAnsi(srvLeft).length,
srvRightLen = stripAnsi(srvRight).length,
srvColWidth = width - serverStartX - 2,
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,
padLeft = Math.floor((width - msg.length - 4) / 2),
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(`
`);
output !== tuiState.lastRender && (tuiState.lastRender = output, process.stdout.write(ansi.home + output));
}
function getCableCharAt(x, y) {
if (!tuiState || tuiState.simulators.length === 0) return null;
for (const [simIndex, cable] of tuiState.cables) {
const startX = tuiState.simEndX,
startY = tuiState.rowStartY + simIndex;
let endX, endY;
cable.serverIndex !== null ? (endX = tuiState.serverStartX, endY = tuiState.rowStartY + cable.serverIndex) : (endX = Math.round(cable.controlPoint.x), endY = Math.round(cable.controlPoint.y));
const ctrlX = Math.round(cable.controlPoint.x),
ctrlY = Math.round(cable.controlPoint.y),
steps = 30;
for (let i = 0; i <= steps; i++) {
const t = i / steps,
invT = 1 - t,
px = Math.round(invT * invT * startX + 2 * invT * t * ctrlX + t * t * endX),
py = Math.round(invT * invT * startY + 2 * invT * t * ctrlY + t * t * endY);
if (px === x && py === y) {
const connected = cable.serverIndex !== null,
cableColors = [import_picocolors.default.green, import_picocolors.default.cyan, import_picocolors.default.magenta, import_picocolors.default.blue, import_picocolors.default.yellow],
baseColor = cableColors[simIndex % cableColors.length],
color = connected ? baseColor : import_picocolors.default.dim,
tPrev = Math.max(0, (i - 1) / steps),
tNext = Math.min(1, (i + 1) / steps),
prevX = Math.round((1 - tPrev) * (1 - tPrev) * startX + 2 * (1 - tPrev) * tPrev * ctrlX + tPrev * tPrev * endX),
prevY = Math.round((1 - tPrev) * (1 - tPrev) * startY + 2 * (1 - tPrev) * tPrev * ctrlY + tPrev * tPrev * endY),
nextX = Math.round((1 - tNext) * (1 - tNext) * startX + 2 * (1 - tNext) * tNext * ctrlX + tNext * tNext * endX),
nextY = Math.round((1 - tNext) * (1 - tNext) * startY + 2 * (1 - tNext) * tNext * ctrlY + tNext * tNext * endY),
dx = nextX - prevX,
dy = nextY - prevY;
let char;
return Math.abs(dx) > Math.abs(dy) * 2 ? char = "\u2500" : Math.abs(dy) > Math.abs(dx) * 2 ? char = "\u2502" : dx > 0 && dy > 0 || dx < 0 && dy < 0 ? char = "\u2572" : char = "\u2571", color(char);
}
}
}
return null;
}
function truncate(str, maxLen) {
return maxLen <= 0 ? "" : str.length <= maxLen ? str : str.slice(0, maxLen - 1) + "\u2026";
}
function stripAnsi(str) {
return str.replace(/\x1b\[[0-9;]*m/g, "");
}
function stopTUI() {
refreshInterval && (clearInterval(refreshInterval), refreshInterval = null), physicsInterval && (clearInterval(physicsInterval), physicsInterval = null), stdinListener && (process.stdin.removeListener("data", stdinListener), stdinListener = null), resizeListener && (process.stdout.removeListener("resize", resizeListener), resizeListener = null), process.stdout.write(ansi.clearScreen + ansi.home + ansi.showCursor), process.stdin.isTTY && process.stdin.setRawMode(!1), tuiState = null, daemonState = null;
}
function triggerPulse(_serverId, _direction) {}