numux 1.10.3 → 1.10.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/numux.js +73 -51
- package/package.json +1 -1
package/dist/numux.js
CHANGED
|
@@ -22,7 +22,7 @@ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports,
|
|
|
22
22
|
var require_package = __commonJS((exports, module) => {
|
|
23
23
|
module.exports = {
|
|
24
24
|
name: "numux",
|
|
25
|
-
version: "1.10.
|
|
25
|
+
version: "1.10.4",
|
|
26
26
|
description: "Terminal multiplexer with dependency orchestration",
|
|
27
27
|
type: "module",
|
|
28
28
|
license: "MIT",
|
|
@@ -2119,6 +2119,37 @@ var STATUS_ICON_HEX = {
|
|
|
2119
2119
|
skipped: "#888888"
|
|
2120
2120
|
};
|
|
2121
2121
|
var TERMINAL_STATUSES = new Set(["finished", "stopped", "failed", "skipped"]);
|
|
2122
|
+
function formatTab(name, status) {
|
|
2123
|
+
return `${STATUS_ICONS[status]} ${name}`;
|
|
2124
|
+
}
|
|
2125
|
+
function formatDescription(status, exitCode, restartCount) {
|
|
2126
|
+
let desc = status;
|
|
2127
|
+
if ((status === "failed" || status === "stopped") && exitCode != null && exitCode !== 0) {
|
|
2128
|
+
desc = `exit ${exitCode}`;
|
|
2129
|
+
}
|
|
2130
|
+
if (restartCount && restartCount > 0) {
|
|
2131
|
+
desc += ` \xD7${restartCount}`;
|
|
2132
|
+
}
|
|
2133
|
+
return desc;
|
|
2134
|
+
}
|
|
2135
|
+
function getDisplayOrder(originalNames, statuses) {
|
|
2136
|
+
const active = originalNames.filter((n) => !TERMINAL_STATUSES.has(statuses.get(n)));
|
|
2137
|
+
const terminal = originalNames.filter((n) => TERMINAL_STATUSES.has(statuses.get(n)));
|
|
2138
|
+
return [...active, ...terminal];
|
|
2139
|
+
}
|
|
2140
|
+
function resolveOptionColors(names, statuses, processColors, inputWaiting, erroredProcesses) {
|
|
2141
|
+
return names.map((name) => {
|
|
2142
|
+
const status = statuses.get(name);
|
|
2143
|
+
const waiting = inputWaiting.has(name);
|
|
2144
|
+
const errored = erroredProcesses.has(name);
|
|
2145
|
+
const statusHex = waiting ? "#ffaa00" : errored ? "#ff5555" : STATUS_ICON_HEX[status];
|
|
2146
|
+
const processHex = processColors.get(name);
|
|
2147
|
+
return {
|
|
2148
|
+
iconHex: statusHex ?? processHex ?? "#888888",
|
|
2149
|
+
nameHex: processHex ?? null
|
|
2150
|
+
};
|
|
2151
|
+
});
|
|
2152
|
+
}
|
|
2122
2153
|
|
|
2123
2154
|
class ColoredSelectRenderable extends SelectRenderable {
|
|
2124
2155
|
_optionColors = [];
|
|
@@ -2126,12 +2157,11 @@ class ColoredSelectRenderable extends SelectRenderable {
|
|
|
2126
2157
|
this._optionColors = colors;
|
|
2127
2158
|
this.requestRender();
|
|
2128
2159
|
}
|
|
2129
|
-
renderSelf(
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
if (
|
|
2133
|
-
this.
|
|
2134
|
-
}
|
|
2160
|
+
renderSelf(_buffer, _deltaTime) {
|
|
2161
|
+
if (!(this.visible && this.frameBuffer))
|
|
2162
|
+
return;
|
|
2163
|
+
if (this.isDirty)
|
|
2164
|
+
this.renderOptions();
|
|
2135
2165
|
}
|
|
2136
2166
|
onMouseEvent(event) {
|
|
2137
2167
|
if (event.type === "down") {
|
|
@@ -2144,28 +2174,45 @@ class ColoredSelectRenderable extends SelectRenderable {
|
|
|
2144
2174
|
}
|
|
2145
2175
|
}
|
|
2146
2176
|
}
|
|
2147
|
-
|
|
2177
|
+
renderOptions() {
|
|
2178
|
+
if (!this.frameBuffer || this.options.length === 0)
|
|
2179
|
+
return;
|
|
2148
2180
|
const fb = this.frameBuffer;
|
|
2181
|
+
const bgColor = this._focused ? this._focusedBackgroundColor : this._backgroundColor;
|
|
2182
|
+
fb.clear(bgColor);
|
|
2149
2183
|
const scrollOffset = this.scrollOffset;
|
|
2150
2184
|
const maxVisibleItems = this.maxVisibleItems;
|
|
2151
2185
|
const linesPerItem = this.linesPerItem;
|
|
2186
|
+
const fontHeight = this.fontHeight;
|
|
2152
2187
|
const selectedIndex = this.getSelectedIndex();
|
|
2153
|
-
const
|
|
2154
|
-
const visibleCount = Math.min(maxVisibleItems, options.length - scrollOffset);
|
|
2188
|
+
const showDescription = this._showDescription;
|
|
2155
2189
|
const baseTextColor = this._focused ? this._focusedTextColor : this._textColor;
|
|
2156
2190
|
const selectedTextColor = this._selectedTextColor;
|
|
2157
|
-
const
|
|
2191
|
+
const descColor = this._descriptionColor;
|
|
2192
|
+
const selectedDescColor = this._selectedDescriptionColor;
|
|
2193
|
+
const selectedBgColor = this._selectedBackgroundColor;
|
|
2194
|
+
const itemSpacing = this._itemSpacing;
|
|
2195
|
+
const visibleCount = Math.min(maxVisibleItems, this.options.length - scrollOffset);
|
|
2158
2196
|
for (let i = 0;i < visibleCount; i++) {
|
|
2159
2197
|
const actualIndex = scrollOffset + i;
|
|
2160
|
-
const
|
|
2161
|
-
const optName = options[actualIndex].name;
|
|
2198
|
+
const option = this.options[actualIndex];
|
|
2162
2199
|
const isSelected = actualIndex === selectedIndex;
|
|
2163
|
-
const
|
|
2200
|
+
const itemY = i * linesPerItem;
|
|
2201
|
+
if (itemY + linesPerItem - 1 >= this.height)
|
|
2202
|
+
break;
|
|
2203
|
+
if (isSelected) {
|
|
2204
|
+
fb.fillRect(0, itemY, this.width, linesPerItem - itemSpacing, selectedBgColor);
|
|
2205
|
+
}
|
|
2164
2206
|
const colors = this._optionColors[actualIndex];
|
|
2165
|
-
const
|
|
2166
|
-
|
|
2207
|
+
const defaultColor = isSelected ? selectedTextColor : baseTextColor;
|
|
2208
|
+
const nameColor = colors?.name ?? defaultColor;
|
|
2209
|
+
fb.drawText(option.name, 1, itemY, nameColor);
|
|
2167
2210
|
if (colors?.icon) {
|
|
2168
|
-
fb.drawText(
|
|
2211
|
+
fb.drawText(option.name.charAt(0), 1, itemY, colors.icon);
|
|
2212
|
+
}
|
|
2213
|
+
if (showDescription && itemY + fontHeight < this.height) {
|
|
2214
|
+
const dc = isSelected ? selectedDescColor : descColor;
|
|
2215
|
+
fb.drawText(option.description, 3, itemY + fontHeight, dc);
|
|
2169
2216
|
}
|
|
2170
2217
|
}
|
|
2171
2218
|
}
|
|
@@ -2191,7 +2238,7 @@ class TabBar {
|
|
|
2191
2238
|
width: "100%",
|
|
2192
2239
|
height: "100%",
|
|
2193
2240
|
options: names.map((n) => ({
|
|
2194
|
-
name:
|
|
2241
|
+
name: formatTab(n, "pending"),
|
|
2195
2242
|
description: "pending"
|
|
2196
2243
|
})),
|
|
2197
2244
|
selectedBackgroundColor: "#334455",
|
|
@@ -2214,7 +2261,7 @@ class TabBar {
|
|
|
2214
2261
|
}
|
|
2215
2262
|
updateStatus(name, status, exitCode, restartCount) {
|
|
2216
2263
|
this.statuses.set(name, status);
|
|
2217
|
-
this.baseDescriptions.set(name,
|
|
2264
|
+
this.baseDescriptions.set(name, formatDescription(status, exitCode, restartCount));
|
|
2218
2265
|
if (TERMINAL_STATUSES.has(status) || status === "stopping") {
|
|
2219
2266
|
this.inputWaiting.delete(name);
|
|
2220
2267
|
}
|
|
@@ -2246,9 +2293,9 @@ class TabBar {
|
|
|
2246
2293
|
refreshOptions() {
|
|
2247
2294
|
const currentIdx = this.renderable.getSelectedIndex();
|
|
2248
2295
|
const currentName = this.names[currentIdx];
|
|
2249
|
-
this.names = this.
|
|
2296
|
+
this.names = getDisplayOrder(this.originalNames, this.statuses);
|
|
2250
2297
|
this.renderable.options = this.names.map((n) => ({
|
|
2251
|
-
name:
|
|
2298
|
+
name: formatTab(n, this.statuses.get(n)),
|
|
2252
2299
|
description: this.getDescription(n)
|
|
2253
2300
|
}));
|
|
2254
2301
|
const newIdx = this.names.indexOf(currentName);
|
|
@@ -2257,11 +2304,6 @@ class TabBar {
|
|
|
2257
2304
|
}
|
|
2258
2305
|
this.updateOptionColors();
|
|
2259
2306
|
}
|
|
2260
|
-
getDisplayOrder() {
|
|
2261
|
-
const active = this.originalNames.filter((n) => !TERMINAL_STATUSES.has(this.statuses.get(n)));
|
|
2262
|
-
const terminal = this.originalNames.filter((n) => TERMINAL_STATUSES.has(this.statuses.get(n)));
|
|
2263
|
-
return [...active, ...terminal];
|
|
2264
|
-
}
|
|
2265
2307
|
getDescription(name) {
|
|
2266
2308
|
if (this.inputWaiting.has(name))
|
|
2267
2309
|
return "awaiting input";
|
|
@@ -2270,33 +2312,13 @@ class TabBar {
|
|
|
2270
2312
|
return this.baseDescriptions.get(name) ?? "pending";
|
|
2271
2313
|
}
|
|
2272
2314
|
updateOptionColors() {
|
|
2273
|
-
const
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
const processHex = this.processColors.get(name);
|
|
2279
|
-
return {
|
|
2280
|
-
icon: parseColor(statusHex ?? processHex ?? "#888888"),
|
|
2281
|
-
name: processHex ? parseColor(processHex) : null
|
|
2282
|
-
};
|
|
2283
|
-
});
|
|
2315
|
+
const resolved = resolveOptionColors(this.names, this.statuses, this.processColors, this.inputWaiting, this.erroredProcesses);
|
|
2316
|
+
const colors = resolved.map((c) => ({
|
|
2317
|
+
icon: parseColor(c.iconHex),
|
|
2318
|
+
name: c.nameHex ? parseColor(c.nameHex) : null
|
|
2319
|
+
}));
|
|
2284
2320
|
this.renderable.setOptionColors(colors);
|
|
2285
2321
|
}
|
|
2286
|
-
formatDescription(status, exitCode, restartCount) {
|
|
2287
|
-
let desc = status;
|
|
2288
|
-
if ((status === "failed" || status === "stopped") && exitCode != null && exitCode !== 0) {
|
|
2289
|
-
desc = `exit ${exitCode}`;
|
|
2290
|
-
}
|
|
2291
|
-
if (restartCount && restartCount > 0) {
|
|
2292
|
-
desc += ` \xD7${restartCount}`;
|
|
2293
|
-
}
|
|
2294
|
-
return desc;
|
|
2295
|
-
}
|
|
2296
|
-
formatTab(name, status) {
|
|
2297
|
-
const icon = STATUS_ICONS[status];
|
|
2298
|
-
return `${icon} ${name}`;
|
|
2299
|
-
}
|
|
2300
2322
|
getSelectedIndex() {
|
|
2301
2323
|
return this.renderable.getSelectedIndex();
|
|
2302
2324
|
}
|