@nmakarov/cli-toolkit 0.80.0 → 0.81.0
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/cli-runner.cjs +59 -26
- package/dist/cli-runner.cjs.map +1 -1
- package/dist/cli-runner.js +59 -26
- package/dist/cli-runner.js.map +1 -1
- package/dist/index.cjs +63 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +59 -26
- package/dist/index.js.map +1 -1
- package/dist/init.cjs +59 -26
- package/dist/init.cjs.map +1 -1
- package/dist/init.js +59 -26
- package/dist/init.js.map +1 -1
- package/dist/screen.cjs +59 -26
- package/dist/screen.cjs.map +1 -1
- package/dist/screen.js +55 -26
- package/dist/screen.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -996,6 +996,30 @@ var init_ui_elements = __esm({
|
|
|
996
996
|
}
|
|
997
997
|
});
|
|
998
998
|
|
|
999
|
+
// src/screen/follow-scroll.js
|
|
1000
|
+
function clampScroll(scrollTop, maxScroll) {
|
|
1001
|
+
const max = Math.max(0, Number(maxScroll) || 0);
|
|
1002
|
+
const top = Number(scrollTop) || 0;
|
|
1003
|
+
return Math.min(Math.max(0, top), max);
|
|
1004
|
+
}
|
|
1005
|
+
function isScrolledToBottom(scrollTop, maxScroll) {
|
|
1006
|
+
return clampScroll(scrollTop, maxScroll) >= Math.max(0, Number(maxScroll) || 0);
|
|
1007
|
+
}
|
|
1008
|
+
function nextScrollAfterUserMove(scrollTop, maxScroll, delta) {
|
|
1009
|
+
const next = clampScroll((Number(scrollTop) || 0) + (Number(delta) || 0), maxScroll);
|
|
1010
|
+
return { scrollTop: next, following: isScrolledToBottom(next, maxScroll) };
|
|
1011
|
+
}
|
|
1012
|
+
function nextScrollAfterContentChange({ following, scrollTop, maxScroll }) {
|
|
1013
|
+
const max = Math.max(0, Number(maxScroll) || 0);
|
|
1014
|
+
if (following) return { scrollTop: max, following: true };
|
|
1015
|
+
const next = clampScroll(scrollTop, max);
|
|
1016
|
+
return { scrollTop: next, following: isScrolledToBottom(next, max) };
|
|
1017
|
+
}
|
|
1018
|
+
var init_follow_scroll = __esm({
|
|
1019
|
+
"src/screen/follow-scroll.js"() {
|
|
1020
|
+
}
|
|
1021
|
+
});
|
|
1022
|
+
|
|
999
1023
|
// src/screen/scrollable-text.js
|
|
1000
1024
|
import { useState as useState3, useEffect as useEffect2, useMemo, useRef as useRef2, createElement as createElement2 } from "react";
|
|
1001
1025
|
import { Box as Box4, Text as Text5 } from "ink";
|
|
@@ -1030,9 +1054,11 @@ function ScrollableText({
|
|
|
1030
1054
|
showScrollbar = true,
|
|
1031
1055
|
showStatus = true,
|
|
1032
1056
|
bindKeys = true,
|
|
1033
|
-
header = null
|
|
1057
|
+
header = null,
|
|
1058
|
+
followBottom = false
|
|
1034
1059
|
}) {
|
|
1035
1060
|
const [scrollTop, setScrollTop] = useState3(0);
|
|
1061
|
+
const [following, setFollowing] = useState3(() => !!followBottom);
|
|
1036
1062
|
const [, bump] = useState3(0);
|
|
1037
1063
|
const termRows = process.stdout.rows || 24;
|
|
1038
1064
|
const viewportRows = Math.max(
|
|
@@ -1051,39 +1077,40 @@ function ScrollableText({
|
|
|
1051
1077
|
const clamped = Math.min(Math.max(0, scrollTop), maxScroll);
|
|
1052
1078
|
const visible = allLines.slice(clamped, clamped + viewportRows);
|
|
1053
1079
|
const bar = needsBar ? scrollbarGlyphs(viewportRows, allLines.length, clamped) : null;
|
|
1054
|
-
useEffect2(() => {
|
|
1055
|
-
setScrollTop((s) => Math.min(s, maxScroll));
|
|
1056
|
-
}, [maxScroll]);
|
|
1057
1080
|
const maxScrollRef = useRef2(maxScroll);
|
|
1058
1081
|
const pageSizeRef = useRef2(viewportRows);
|
|
1082
|
+
const scrollTopRef = useRef2(scrollTop);
|
|
1083
|
+
const followingRef = useRef2(following);
|
|
1059
1084
|
maxScrollRef.current = maxScroll;
|
|
1060
1085
|
pageSizeRef.current = viewportRows;
|
|
1086
|
+
scrollTopRef.current = scrollTop;
|
|
1087
|
+
followingRef.current = following;
|
|
1088
|
+
useEffect2(() => {
|
|
1089
|
+
const next = nextScrollAfterContentChange({
|
|
1090
|
+
following: followBottom && followingRef.current,
|
|
1091
|
+
scrollTop: scrollTopRef.current,
|
|
1092
|
+
maxScroll
|
|
1093
|
+
});
|
|
1094
|
+
if (next.scrollTop !== scrollTopRef.current) setScrollTop(next.scrollTop);
|
|
1095
|
+
if (followBottom && next.following !== followingRef.current) setFollowing(next.following);
|
|
1096
|
+
}, [maxScroll, followBottom]);
|
|
1097
|
+
const applyUserScroll = (delta) => {
|
|
1098
|
+
const next = nextScrollAfterUserMove(scrollTopRef.current, maxScrollRef.current, delta);
|
|
1099
|
+
setScrollTop(next.scrollTop);
|
|
1100
|
+
if (followBottom) setFollowing(next.following);
|
|
1101
|
+
bump((n) => n + 1);
|
|
1102
|
+
ctx?.update?.();
|
|
1103
|
+
};
|
|
1061
1104
|
useEffect2(() => {
|
|
1062
1105
|
if (!ctx || !bindKeys) return void 0;
|
|
1063
1106
|
ctx.setKeyBinding(SCROLL_KEYS);
|
|
1064
|
-
ctx.setAction("scrollUp", () =>
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
});
|
|
1069
|
-
ctx.setAction("scrollDown", () => {
|
|
1070
|
-
setScrollTop((s) => Math.min(maxScrollRef.current, s + 1));
|
|
1071
|
-
bump((n) => n + 1);
|
|
1072
|
-
ctx.update?.();
|
|
1073
|
-
});
|
|
1074
|
-
ctx.setAction("pageUp", () => {
|
|
1075
|
-
setScrollTop((s) => Math.max(0, s - pageSizeRef.current));
|
|
1076
|
-
bump((n) => n + 1);
|
|
1077
|
-
ctx.update?.();
|
|
1078
|
-
});
|
|
1079
|
-
ctx.setAction("pageDown", () => {
|
|
1080
|
-
setScrollTop((s) => Math.min(maxScrollRef.current, s + pageSizeRef.current));
|
|
1081
|
-
bump((n) => n + 1);
|
|
1082
|
-
ctx.update?.();
|
|
1083
|
-
});
|
|
1107
|
+
ctx.setAction("scrollUp", () => applyUserScroll(-1));
|
|
1108
|
+
ctx.setAction("scrollDown", () => applyUserScroll(1));
|
|
1109
|
+
ctx.setAction("pageUp", () => applyUserScroll(-pageSizeRef.current));
|
|
1110
|
+
ctx.setAction("pageDown", () => applyUserScroll(pageSizeRef.current));
|
|
1084
1111
|
return void 0;
|
|
1085
|
-
}, [ctx, bindKeys]);
|
|
1086
|
-
const status = allLines.length === 0 ? "empty" : `lines ${clamped + 1}-${Math.min(clamped + visible.length, allLines.length)} of ${allLines.length}` + (needsBar ? " \xB7 \u2325\u2191/\u2193 or PgUp/Dn page" : "");
|
|
1112
|
+
}, [ctx, bindKeys, followBottom]);
|
|
1113
|
+
const status = allLines.length === 0 ? "empty" : `lines ${clamped + 1}-${Math.min(clamped + visible.length, allLines.length)} of ${allLines.length}` + (needsBar ? " \xB7 \u2325\u2191/\u2193 or PgUp/Dn page" : "") + (followBottom && following ? " \xB7 follow" : followBottom ? " \xB7 follow off" : "");
|
|
1087
1114
|
const rowNodes = visible.map((line, i) => {
|
|
1088
1115
|
const body = padEndVisible(line, textWidth);
|
|
1089
1116
|
const glyph = bar ? bar[i] ?? BAR_TRACK : showScrollbar ? " " : "";
|
|
@@ -1121,6 +1148,7 @@ var init_scrollable_text = __esm({
|
|
|
1121
1148
|
"src/screen/scrollable-text.js"() {
|
|
1122
1149
|
init_components();
|
|
1123
1150
|
init_scrollbar();
|
|
1151
|
+
init_follow_scroll();
|
|
1124
1152
|
init_scrollbar();
|
|
1125
1153
|
h5 = createElement2;
|
|
1126
1154
|
SCROLL_KEYS = [
|
|
@@ -1279,6 +1307,7 @@ var init_screen = __esm({
|
|
|
1279
1307
|
init_components();
|
|
1280
1308
|
init_ui_elements();
|
|
1281
1309
|
init_scrollable_text();
|
|
1310
|
+
init_follow_scroll();
|
|
1282
1311
|
init_scrollbar();
|
|
1283
1312
|
init_key_bindings();
|
|
1284
1313
|
init_utils();
|
|
@@ -10164,6 +10193,7 @@ export {
|
|
|
10164
10193
|
buildDetailBreadcrumb,
|
|
10165
10194
|
buildFooter,
|
|
10166
10195
|
bumpPatchVersion,
|
|
10196
|
+
clampScroll,
|
|
10167
10197
|
cloneRepo,
|
|
10168
10198
|
coerceRuntimeValue,
|
|
10169
10199
|
controlLaneTaskNames,
|
|
@@ -10201,6 +10231,7 @@ export {
|
|
|
10201
10231
|
ipcFileLogsTableNameForSourceResource,
|
|
10202
10232
|
isFreshOnline,
|
|
10203
10233
|
isPidAlive,
|
|
10234
|
+
isScrolledToBottom,
|
|
10204
10235
|
joiEdateType,
|
|
10205
10236
|
joiStringArrayType,
|
|
10206
10237
|
listServicesRegistry as listAliveRunnerHeartbeats,
|
|
@@ -10214,6 +10245,8 @@ export {
|
|
|
10214
10245
|
memo,
|
|
10215
10246
|
mergeAllowedTasksWithServiceTasks,
|
|
10216
10247
|
mergeRuntimeParamSpecs,
|
|
10248
|
+
nextScrollAfterContentChange,
|
|
10249
|
+
nextScrollAfterUserMove,
|
|
10217
10250
|
nextTimeMatch,
|
|
10218
10251
|
normalizeAllowedTasks,
|
|
10219
10252
|
npmEnv,
|