one
Version:
One is a new React Framework that makes Vite serve both native and web.
453 lines (452 loc) • 22.3 kB
JavaScript
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 ESC = "\x1B",
CSI = `${ESC}[`,
ansi = {
hideCursor: `${CSI}?25l`,
showCursor: `${CSI}?25h`,
clearScreen: `${CSI}2J`,
home: `${CSI}H`
},
tuiState = null,
daemonState = null,
refreshInterval = null,
physicsInterval = null,
stdinListener = null,
resizeListener = null;
function getRouteMode() {
return tuiState?.routeMode || "ask";
}
function calcLayout(width) {
var simEndX = Math.floor(width * 0.25),
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) {
tuiState.popup && clearTimeout(tuiState.popup.timeout);
var timeout = setTimeout(function () {
tuiState && (tuiState.popup = null, render());
}, durationMs);
tuiState.popup = {
message,
timeout
}, render();
}
}
function startTUI(state) {
daemonState = state;
var 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();
var resizePending = !1;
resizeListener = function () {
if (tuiState) {
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 = "", resizePending || (resizePending = !0, setImmediate(function () {
resizePending = !1, 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)), !(!tuiState || !daemonState)) {
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") 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", setRouteMode(tuiState.routeMode);else if (str === "b") {
stopTUI(), console.log(colors.dim(`
Daemon 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)) {
var isDragging = tuiState.draggingSimIndex !== null;
if (isDragging) {
if (tuiState.selectedCol === 1 && tuiState.servers.length > 0) {
var simIndex = tuiState.draggingSimIndex,
sim = tuiState.simulators[simIndex],
serverIndex = tuiState.selectedRow,
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);
cable && (cable.serverIndex = serverIndex), tuiState.draggingSimIndex = null, 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,
sim1 = tuiState.simulators[simIndex1];
if (!sim1) return;
tuiState.modeBeforeDrag = tuiState.routeMode, tuiState.routeMode === "most-recent" && (tuiState.routeMode = "ask", setRouteMode("ask")), clearRoute(daemonState, getRouteKey(sim1)), clearMappingsForSimulator(sim1.udid);
var cable1 = tuiState.cables.get(simIndex1);
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,
_iteratorNormalCompletion = !0,
_didIteratorError = !1,
_iteratorError = void 0;
try {
for (var _iterator = tuiState.cables[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = !0) {
var [simIndex2, cable2] = _step.value;
if (cable2.serverIndex === serverIndex1) {
var sim2 = tuiState.simulators[simIndex2];
sim2 && (tuiState.modeBeforeDrag = tuiState.routeMode, 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 = !0, _iteratorError = err;
} finally {
try {
!_iteratorNormalCompletion && _iterator.return != null && _iterator.return();
} finally {
if (_didIteratorError) throw _iteratorError;
}
}
}
}
}
function handleDisconnect() {
if (!(!tuiState || !daemonState)) if (tuiState.selectedCol === 0) {
var 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", 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,
_iteratorNormalCompletion = !0,
_didIteratorError = !1,
_iteratorError = void 0;
try {
for (var _iterator = tuiState.cables[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = !0) {
var [simIndex1, cable1] = _step.value;
if (cable1.serverIndex === serverIndex) {
var sim1 = tuiState.simulators[simIndex1];
sim1 && (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 = !0, _iteratorError = err;
} finally {
try {
!_iteratorNormalCompletion && _iterator.return != null && _iterator.return();
} finally {
if (_didIteratorError) throw _iteratorError;
}
}
}
}
function updatePhysics() {
if (tuiState) {
var gravity = 0.3,
damping = 0.85,
needsRender = !1,
_iteratorNormalCompletion = !0,
_didIteratorError = !1,
_iteratorError = void 0;
try {
for (var _iterator = tuiState.cables[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = !0) {
var [simIndex, cable] = _step.value,
simY = tuiState.rowStartY + simIndex;
if (cable.serverIndex !== null) {
var sagCurve = function (i) {
return i <= 4 ? 6 - i : 2 + (i - 4) * 0.8;
},
sag = sagCurve(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;
var 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;
}
}
} catch (err) {
_didIteratorError = !0, _iteratorError = err;
} finally {
try {
!_iteratorNormalCompletion && _iterator.return != null && _iterator.return();
} finally {
if (_didIteratorError) throw _iteratorError;
}
}
needsRender && render();
}
}
async function refreshData() {
var _loop = function (simIndex2) {
var sim = newSims[simIndex2],
mappedServerId = simMappings.get(sim.udid),
routedServerIndex = null;
mappedServerId && (routedServerIndex = newServers.findIndex(function (s) {
return s.id === mappedServerId;
}), routedServerIndex === -1 && (routedServerIndex = null));
var cable = tuiState.cables.get(simIndex2);
cable || (cable = {
serverIndex: routedServerIndex,
controlPoint: {
x: tuiState.simEndX + 5,
y: tuiState.rowStartY + simIndex2
},
velocity: {
x: 0,
y: 0
}
}, tuiState.cables.set(simIndex2, cable)), tuiState.draggingSimIndex !== simIndex2 && routedServerIndex !== cable.serverIndex && (cable.serverIndex = routedServerIndex, routedServerIndex !== null && (cable.velocity = {
x: 0,
y: -2
}));
};
if (!(!tuiState || !daemonState)) {
var newSims = await getBootedSimulators(),
newServers = getAllServers(daemonState);
tuiState.simulators = newSims, tuiState.servers = newServers;
for (var isDragging = tuiState.draggingSimIndex !== null, simMappings = getSimulatorMappings(), simIndex = 0; simIndex < newSims.length; simIndex++) _loop(simIndex);
var _iteratorNormalCompletion = !0,
_didIteratorError = !1,
_iteratorError = void 0;
try {
for (var _iterator = tuiState.cables.keys()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = !0) {
var simIndex1 = _step.value;
simIndex1 >= newSims.length && tuiState.cables.delete(simIndex1);
}
} catch (err) {
_didIteratorError = !0, _iteratorError = err;
} finally {
try {
!_iteratorNormalCompletion && _iterator.return != null && _iterator.return();
} finally {
if (_didIteratorError) throw _iteratorError;
}
}
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) {
var {
width,
height,
simEndX,
serverStartX
} = tuiState,
lines = [],
title = " one daemon ",
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",
toggleLeft = isAuto ? colors.green("\u25B6") : colors.dim("\u25B7"),
toggleRight = isAuto ? colors.dim("\u25C1") : colors.yellow("\u25C0"),
autoLabel = isAuto ? colors.green("AUTO") : colors.dim("auto"),
askLabel = isAuto ? colors.dim("ask") : colors.yellow("ASK"),
toggle = ` ${autoLabel} ${toggleLeft}\u2550\u2550\u2550${toggleRight} ${askLabel} [m] toggle`,
togglePad = Math.max(0, width - stripAnsi(toggle).length - 2);
lines.push(colors.cyan("\u2502") + toggle + " ".repeat(togglePad) + colors.cyan("\u2502"));
var simHeader = " SIMULATORS",
srvHeader = "SERVERS ",
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"));
for (var contentRows = height - 7, row = 0; row < contentRows; row++) {
var y = tuiState.rowStartY + row,
line = "";
line += colors.cyan("\u2502");
var sim = tuiState.simulators[row],
simText = "";
if (sim) {
var isSelected = tuiState.selectedCol === 0 && tuiState.selectedRow === row,
cable = tuiState.cables.get(row),
hasConnection = cable?.serverIndex !== null,
cableColors = [colors.green, colors.cyan, colors.magenta, colors.blue, colors.yellow],
cableColor = cableColors[row % cableColors.length],
plug = hasConnection ? cableColor("\u25CF") : colors.dim("\u25CB"),
name = truncate(sim.name, simEndX - 5);
simText = `${name} ${plug}`, isSelected && (simText = colors.inverse(simText));
}
var simTextLen = stripAnsi(simText).length,
simPad = Math.max(0, simEndX - 1 - simTextLen);
line += " ".repeat(simPad) + simText;
for (var cableZone = "", x = simEndX; x < serverStartX; x++) {
var char = getCableCharAt(x, y);
cableZone += char || " ";
}
line += cableZone;
var server = tuiState.servers[row],
srvLeft = "",
srvRight = "";
if (server) {
var isSelected1 = tuiState.selectedCol === 1 && tuiState.selectedRow === row,
cableColors1 = [colors.green, colors.cyan, colors.magenta, colors.blue, colors.yellow],
connectedColor = null,
_iteratorNormalCompletion = !0,
_didIteratorError = !1,
_iteratorError = void 0;
try {
for (var _iterator = tuiState.cables[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = !0) {
var [simIndex, cable1] = _step.value;
if (cable1.serverIndex === row) {
connectedColor = cableColors1[simIndex % cableColors1.length];
break;
}
}
} catch (err) {
_didIteratorError = !0, _iteratorError = err;
} finally {
try {
!_iteratorNormalCompletion && _iterator.return != null && _iterator.return();
} finally {
if (_didIteratorError) throw _iteratorError;
}
}
var lastActive = daemonState ? getLastActiveServer(daemonState) : null,
isLastActive = lastActive?.id === server.id,
plug1 = connectedColor ? connectedColor("\u25CF") : colors.dim("\u25CB"),
star = isLastActive ? colors.yellow("\u2605") : " ",
shortRoot = truncate(server.root.replace(process.env.HOME || "", "~"), width - serverStartX - 14);
srvLeft = `${plug1} ${star}${shortRoot}`, srvRight = colors.bold(colors.yellow(`:${server.port}`)), isSelected1 && (srvLeft = colors.inverse(srvLeft), srvRight = colors.inverse(srvRight));
}
var 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 += colors.cyan("\u2502"), lines.push(line);
}
if (tuiState.popup) {
var msg = tuiState.popup.message,
padLeft = Math.floor((width - msg.length - 4) / 2),
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(`
`);
output !== tuiState.lastRender && (tuiState.lastRender = output, process.stdout.write(ansi.home + output));
}
}
function getCableCharAt(x, y) {
if (!tuiState || tuiState.simulators.length === 0) return null;
var _iteratorNormalCompletion = !0,
_didIteratorError = !1,
_iteratorError = void 0;
try {
for (var _iterator = tuiState.cables[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = !0) {
var [simIndex, cable] = _step.value,
startX = tuiState.simEndX,
startY = tuiState.rowStartY + simIndex,
endX = void 0,
endY = void 0;
cable.serverIndex !== null ? (endX = tuiState.serverStartX, endY = tuiState.rowStartY + cable.serverIndex) : (endX = Math.round(cable.controlPoint.x), endY = Math.round(cable.controlPoint.y));
for (var ctrlX = Math.round(cable.controlPoint.x), ctrlY = Math.round(cable.controlPoint.y), steps = 30, i = 0; i <= steps; i++) {
var 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) {
var connected = cable.serverIndex !== null,
cableColors = [colors.green, colors.cyan, colors.magenta, colors.blue, colors.yellow],
baseColor = cableColors[simIndex % cableColors.length],
color = connected ? baseColor : colors.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,
char = void 0;
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);
}
}
}
} catch (err) {
_didIteratorError = !0, _iteratorError = err;
} finally {
try {
!_iteratorNormalCompletion && _iterator.return != null && _iterator.return();
} finally {
if (_didIteratorError) throw _iteratorError;
}
}
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) {}
export { getRouteMode, startTUI, stopTUI, triggerPulse };
//# sourceMappingURL=tui.native.js.map