spawn-term 3.0.1 → 3.0.3

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.
Files changed (51) hide show
  1. package/dist/cjs/components/App.js +25 -6
  2. package/dist/cjs/components/App.js.map +1 -1
  3. package/dist/cjs/components/ChildProcess.js +2 -17
  4. package/dist/cjs/components/ChildProcess.js.map +1 -1
  5. package/dist/cjs/components/CompactProcessLine.js +27 -36
  6. package/dist/cjs/components/CompactProcessLine.js.map +1 -1
  7. package/dist/cjs/components/StatusBar.js +4 -19
  8. package/dist/cjs/components/StatusBar.js.map +1 -1
  9. package/dist/cjs/constants.js +18 -0
  10. package/dist/cjs/constants.js.map +1 -1
  11. package/dist/cjs/createSessionWrapper.js +101 -0
  12. package/dist/cjs/createSessionWrapper.js.map +1 -0
  13. package/dist/cjs/index-esm.js +2 -2
  14. package/dist/cjs/index-esm.js.map +1 -1
  15. package/dist/cjs/lib/clipText.js +56 -0
  16. package/dist/cjs/lib/clipText.js.map +1 -0
  17. package/dist/cjs/session.js +26 -2
  18. package/dist/cjs/session.js.map +1 -1
  19. package/dist/cjs/src/constants.d.ts +4 -0
  20. package/dist/cjs/src/createSessionWrapper.d.ts +7 -0
  21. package/dist/cjs/src/index-esm.d.ts +2 -2
  22. package/dist/cjs/src/lib/clipText.d.ts +9 -0
  23. package/dist/cjs/src/state/processStore.d.ts +5 -2
  24. package/dist/cjs/state/processStore.js +20 -2
  25. package/dist/cjs/state/processStore.js.map +1 -1
  26. package/dist/esm/components/App.js +30 -9
  27. package/dist/esm/components/App.js.map +1 -1
  28. package/dist/esm/components/ChildProcess.js +1 -16
  29. package/dist/esm/components/ChildProcess.js.map +1 -1
  30. package/dist/esm/components/CompactProcessLine.js +26 -35
  31. package/dist/esm/components/CompactProcessLine.js.map +1 -1
  32. package/dist/esm/components/StatusBar.js +3 -18
  33. package/dist/esm/components/StatusBar.js.map +1 -1
  34. package/dist/esm/constants.js +16 -0
  35. package/dist/esm/constants.js.map +1 -1
  36. package/dist/esm/createSessionWrapper.js +43 -0
  37. package/dist/esm/createSessionWrapper.js.map +1 -0
  38. package/dist/esm/index-esm.js +1 -1
  39. package/dist/esm/index-esm.js.map +1 -1
  40. package/dist/esm/lib/clipText.js +37 -0
  41. package/dist/esm/lib/clipText.js.map +1 -0
  42. package/dist/esm/session.js +24 -2
  43. package/dist/esm/session.js.map +1 -1
  44. package/dist/esm/src/constants.d.ts +4 -0
  45. package/dist/esm/src/createSessionWrapper.d.ts +7 -0
  46. package/dist/esm/src/index-esm.d.ts +2 -2
  47. package/dist/esm/src/lib/clipText.d.ts +9 -0
  48. package/dist/esm/src/state/processStore.d.ts +5 -2
  49. package/dist/esm/state/processStore.js +18 -2
  50. package/dist/esm/state/processStore.js.map +1 -1
  51. package/package.json +1 -1
@@ -29,6 +29,8 @@ function AppContent(param) {
29
29
  var store = param.store;
30
30
  var exit = (0, _ink.useApp)().exit;
31
31
  var isRawModeSupported = (0, _ink.useStdin)().isRawModeSupported;
32
+ var stdout = (0, _ink.useStdout)().stdout;
33
+ var terminalHeight = (stdout === null || stdout === void 0 ? void 0 : stdout.rows) || 24;
32
34
  // Subscribe to store state
33
35
  var processes = (0, _react.useSyncExternalStore)(store.subscribe, store.getSnapshot);
34
36
  var shouldExit = (0, _react.useSyncExternalStore)(store.subscribe, store.getShouldExit);
@@ -37,10 +39,14 @@ function AppContent(param) {
37
39
  var selectedErrorIndex = (0, _react.useSyncExternalStore)(store.subscribe, store.getSelectedErrorIndex);
38
40
  var expandedId = (0, _react.useSyncExternalStore)(store.subscribe, store.getExpandedId);
39
41
  var scrollOffset = (0, _react.useSyncExternalStore)(store.subscribe, store.getScrollOffset);
42
+ var listScrollOffset = (0, _react.useSyncExternalStore)(store.subscribe, store.getListScrollOffset);
40
43
  // Subscribed state that triggers re-renders
41
44
  var header = (0, _react.useSyncExternalStore)(store.subscribe, store.getHeader);
42
45
  var showStatusBar = (0, _react.useSyncExternalStore)(store.subscribe, store.getShowStatusBar);
43
46
  var isInteractive = (0, _react.useSyncExternalStore)(store.subscribe, store.getIsInteractive);
47
+ // Calculate visible process count (reserve lines for header, divider, status bar)
48
+ var reservedLines = (header ? 2 : 0) + (showStatusBar ? 2 : 0);
49
+ var visibleProcessCount = Math.max(1, terminalHeight - reservedLines);
44
50
  // Derived state (computed from processes which is already subscribed)
45
51
  var failedProcesses = store.getFailedProcesses();
46
52
  var runningCount = store.getRunningCount();
@@ -87,25 +93,25 @@ function AppContent(param) {
87
93
  if (expandedId) {
88
94
  store.scrollDown(_constantsts.EXPANDED_MAX_VISIBLE_LINES);
89
95
  } else {
90
- store.selectNext();
96
+ store.selectNext(visibleProcessCount);
91
97
  }
92
98
  } else if (key.upArrow) {
93
99
  if (expandedId) {
94
100
  store.scrollUp();
95
101
  } else {
96
- store.selectPrev();
102
+ store.selectPrev(visibleProcessCount);
97
103
  }
98
104
  } else if (input === 'j') {
99
105
  if (expandedId) {
100
106
  store.scrollDown(_constantsts.EXPANDED_MAX_VISIBLE_LINES);
101
107
  } else {
102
- store.selectNext();
108
+ store.selectNext(visibleProcessCount);
103
109
  }
104
110
  } else if (input === 'k') {
105
111
  if (expandedId) {
106
112
  store.scrollUp();
107
113
  } else {
108
- store.selectPrev();
114
+ store.selectPrev(visibleProcessCount);
109
115
  }
110
116
  } else if (input === 'e' && errorCount > 0) {
111
117
  store.setMode('errorList');
@@ -132,6 +138,18 @@ function AppContent(param) {
132
138
  }, {
133
139
  isActive: isRawModeSupported === true
134
140
  });
141
+ // Slice processes to visible viewport in interactive mode (must be before early returns)
142
+ var visibleProcesses = (0, _react.useMemo)(function() {
143
+ if (mode === 'interactive') {
144
+ return processes.slice(listScrollOffset, listScrollOffset + visibleProcessCount);
145
+ }
146
+ return processes;
147
+ }, [
148
+ processes,
149
+ mode,
150
+ listScrollOffset,
151
+ visibleProcessCount
152
+ ]);
135
153
  // Error list modal
136
154
  if (mode === 'errorList') {
137
155
  return /*#__PURE__*/ (0, _jsxruntime.jsx)(_ErrorListModalts.default, {
@@ -166,13 +184,14 @@ function AppContent(param) {
166
184
  /*#__PURE__*/ (0, _jsxruntime.jsx)(_Dividerts.default, {})
167
185
  ]
168
186
  }),
169
- processes.map(function(item, index) {
187
+ visibleProcesses.map(function(item) {
188
+ var originalIndex = processes.indexOf(item);
170
189
  return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_ink.Box, {
171
190
  flexDirection: "column",
172
191
  children: [
173
192
  /*#__PURE__*/ (0, _jsxruntime.jsx)(_CompactProcessLinets.default, {
174
193
  item: item,
175
- isSelected: showSelection && index === selectedIndex
194
+ isSelected: showSelection && originalIndex === selectedIndex
176
195
  }),
177
196
  expandedId === item.id && /*#__PURE__*/ (0, _jsxruntime.jsx)(_ExpandedOutputts.default, {
178
197
  lines: item.lines,
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/components/App.tsx"],"sourcesContent":["import { Box, Text, useApp, useInput, useStdin } from 'ink';\nimport { useEffect, useSyncExternalStore } from 'react';\nimport { EXPANDED_MAX_VISIBLE_LINES } from '../constants.ts';\nimport type { ProcessStore } from '../state/processStore.ts';\nimport { StoreContext } from '../state/StoreContext.ts';\nimport CompactProcessLine from './CompactProcessLine.ts';\nimport Divider from './Divider.ts';\nimport ErrorDetailModal from './ErrorDetailModal.ts';\nimport ErrorListModal from './ErrorListModal.ts';\nimport ExpandedOutput from './ExpandedOutput.ts';\nimport StatusBar from './StatusBar.ts';\n\ninterface AppProps {\n store: ProcessStore;\n}\n\nfunction AppContent({ store }: AppProps): React.JSX.Element {\n const { exit } = useApp();\n const { isRawModeSupported } = useStdin();\n\n // Subscribe to store state\n const processes = useSyncExternalStore(store.subscribe, store.getSnapshot);\n const shouldExit = useSyncExternalStore(store.subscribe, store.getShouldExit);\n const mode = useSyncExternalStore(store.subscribe, store.getMode);\n const selectedIndex = useSyncExternalStore(store.subscribe, store.getSelectedIndex);\n const selectedErrorIndex = useSyncExternalStore(store.subscribe, store.getSelectedErrorIndex);\n const expandedId = useSyncExternalStore(store.subscribe, store.getExpandedId);\n const scrollOffset = useSyncExternalStore(store.subscribe, store.getScrollOffset);\n\n // Subscribed state that triggers re-renders\n const header = useSyncExternalStore(store.subscribe, store.getHeader);\n const showStatusBar = useSyncExternalStore(store.subscribe, store.getShowStatusBar);\n const isInteractive = useSyncExternalStore(store.subscribe, store.getIsInteractive);\n\n // Derived state (computed from processes which is already subscribed)\n const failedProcesses = store.getFailedProcesses();\n const runningCount = store.getRunningCount();\n const doneCount = store.getDoneCount();\n const errorCount = store.getErrorCount();\n const errorLineCount = store.getErrorLineCount();\n const isAllComplete = store.isAllComplete();\n\n // Handle exit signal\n useEffect(() => {\n if (shouldExit) {\n exit();\n }\n }, [shouldExit, exit]);\n\n // Auto-enter interactive mode when all complete and interactive flag is set\n useEffect(() => {\n if (isAllComplete && isInteractive && mode === 'normal') {\n store.setMode('interactive');\n }\n }, [isAllComplete, isInteractive, mode, store]);\n\n // Keyboard handling (only active when raw mode is supported)\n useInput(\n (input, key) => {\n if (mode === 'normal') {\n if (input === 'e' && errorCount > 0) {\n store.setMode('errorList');\n }\n } else if (mode === 'interactive') {\n if (input === 'q' || key.escape) {\n if (expandedId) {\n store.collapse();\n } else {\n store.signalExit(() => {});\n }\n } else if (key.return) {\n store.toggleExpand();\n } else if (key.downArrow) {\n if (expandedId) {\n store.scrollDown(EXPANDED_MAX_VISIBLE_LINES);\n } else {\n store.selectNext();\n }\n } else if (key.upArrow) {\n if (expandedId) {\n store.scrollUp();\n } else {\n store.selectPrev();\n }\n } else if (input === 'j') {\n if (expandedId) {\n store.scrollDown(EXPANDED_MAX_VISIBLE_LINES);\n } else {\n store.selectNext();\n }\n } else if (input === 'k') {\n if (expandedId) {\n store.scrollUp();\n } else {\n store.selectPrev();\n }\n } else if (input === 'e' && errorCount > 0) {\n store.setMode('errorList');\n }\n } else if (mode === 'errorList') {\n if (key.escape) {\n store.setMode(isInteractive ? 'interactive' : 'normal');\n } else if (key.downArrow) {\n store.selectNextError();\n } else if (key.upArrow) {\n store.selectPrevError();\n } else if (key.return) {\n store.setMode('errorDetail');\n }\n } else if (mode === 'errorDetail') {\n if (key.escape) {\n store.setMode('errorList');\n } else if (key.downArrow) {\n store.selectNextError();\n } else if (key.upArrow) {\n store.selectPrevError();\n }\n }\n },\n { isActive: isRawModeSupported === true }\n );\n\n // Error list modal\n if (mode === 'errorList') {\n return <ErrorListModal errors={failedProcesses} selectedIndex={selectedErrorIndex} totalErrorLines={errorLineCount} />;\n }\n\n // Error detail modal\n if (mode === 'errorDetail') {\n const selectedError = store.getSelectedError();\n if (selectedError) {\n return <ErrorDetailModal error={selectedError} currentIndex={selectedErrorIndex} totalErrors={failedProcesses.length} />;\n }\n // Fallback if no error selected\n store.setMode('errorList');\n }\n\n // Normal/Interactive view - render in original registration order\n const showSelection = mode === 'interactive';\n return (\n <Box flexDirection=\"column\">\n {/* Header */}\n {header && (\n <>\n <Text>{header}</Text>\n <Divider />\n </>\n )}\n\n {/* All processes in registration order */}\n {processes.map((item, index) => (\n <Box key={item.id} flexDirection=\"column\">\n <CompactProcessLine item={item} isSelected={showSelection && index === selectedIndex} />\n {expandedId === item.id && <ExpandedOutput lines={item.lines} scrollOffset={scrollOffset} />}\n </Box>\n ))}\n\n {/* Status bar */}\n {showStatusBar && processes.length > 0 && (\n <>\n <Divider />\n <StatusBar running={runningCount} done={doneCount} errors={errorCount} errorLines={errorLineCount} />\n </>\n )}\n </Box>\n );\n}\n\n// Wrapper component that provides store context\nexport default function App({ store }: AppProps): React.JSX.Element {\n return (\n <StoreContext.Provider value={store}>\n <AppContent store={store} />\n </StoreContext.Provider>\n );\n}\n"],"names":["App","AppContent","store","exit","useApp","isRawModeSupported","useStdin","processes","useSyncExternalStore","subscribe","getSnapshot","shouldExit","getShouldExit","mode","getMode","selectedIndex","getSelectedIndex","selectedErrorIndex","getSelectedErrorIndex","expandedId","getExpandedId","scrollOffset","getScrollOffset","header","getHeader","showStatusBar","getShowStatusBar","isInteractive","getIsInteractive","failedProcesses","getFailedProcesses","runningCount","getRunningCount","doneCount","getDoneCount","errorCount","getErrorCount","errorLineCount","getErrorLineCount","isAllComplete","useEffect","setMode","useInput","input","key","escape","collapse","signalExit","return","toggleExpand","downArrow","scrollDown","EXPANDED_MAX_VISIBLE_LINES","selectNext","upArrow","scrollUp","selectPrev","selectNextError","selectPrevError","isActive","ErrorListModal","errors","totalErrorLines","selectedError","getSelectedError","ErrorDetailModal","error","currentIndex","totalErrors","length","showSelection","Box","flexDirection","Text","Divider","map","item","index","CompactProcessLine","isSelected","id","ExpandedOutput","lines","StatusBar","running","done","errorLines","StoreContext","Provider","value"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/components/App.tsx"],"sourcesContent":["import { Box, Text, useApp, useInput, useStdin, useStdout } from 'ink';\nimport { useEffect, useMemo, useSyncExternalStore } from 'react';\nimport { EXPANDED_MAX_VISIBLE_LINES } from '../constants.ts';\nimport type { ProcessStore } from '../state/processStore.ts';\nimport { StoreContext } from '../state/StoreContext.ts';\nimport CompactProcessLine from './CompactProcessLine.ts';\nimport Divider from './Divider.ts';\nimport ErrorDetailModal from './ErrorDetailModal.ts';\nimport ErrorListModal from './ErrorListModal.ts';\nimport ExpandedOutput from './ExpandedOutput.ts';\nimport StatusBar from './StatusBar.ts';\n\ninterface AppProps {\n store: ProcessStore;\n}\n\nfunction AppContent({ store }: AppProps): React.JSX.Element {\n const { exit } = useApp();\n const { isRawModeSupported } = useStdin();\n const { stdout } = useStdout();\n const terminalHeight = stdout?.rows || 24;\n\n // Subscribe to store state\n const processes = useSyncExternalStore(store.subscribe, store.getSnapshot);\n const shouldExit = useSyncExternalStore(store.subscribe, store.getShouldExit);\n const mode = useSyncExternalStore(store.subscribe, store.getMode);\n const selectedIndex = useSyncExternalStore(store.subscribe, store.getSelectedIndex);\n const selectedErrorIndex = useSyncExternalStore(store.subscribe, store.getSelectedErrorIndex);\n const expandedId = useSyncExternalStore(store.subscribe, store.getExpandedId);\n const scrollOffset = useSyncExternalStore(store.subscribe, store.getScrollOffset);\n const listScrollOffset = useSyncExternalStore(store.subscribe, store.getListScrollOffset);\n\n // Subscribed state that triggers re-renders\n const header = useSyncExternalStore(store.subscribe, store.getHeader);\n const showStatusBar = useSyncExternalStore(store.subscribe, store.getShowStatusBar);\n const isInteractive = useSyncExternalStore(store.subscribe, store.getIsInteractive);\n\n // Calculate visible process count (reserve lines for header, divider, status bar)\n const reservedLines = (header ? 2 : 0) + (showStatusBar ? 2 : 0);\n const visibleProcessCount = Math.max(1, terminalHeight - reservedLines);\n\n // Derived state (computed from processes which is already subscribed)\n const failedProcesses = store.getFailedProcesses();\n const runningCount = store.getRunningCount();\n const doneCount = store.getDoneCount();\n const errorCount = store.getErrorCount();\n const errorLineCount = store.getErrorLineCount();\n const isAllComplete = store.isAllComplete();\n\n // Handle exit signal\n useEffect(() => {\n if (shouldExit) {\n exit();\n }\n }, [shouldExit, exit]);\n\n // Auto-enter interactive mode when all complete and interactive flag is set\n useEffect(() => {\n if (isAllComplete && isInteractive && mode === 'normal') {\n store.setMode('interactive');\n }\n }, [isAllComplete, isInteractive, mode, store]);\n\n // Keyboard handling (only active when raw mode is supported)\n useInput(\n (input, key) => {\n if (mode === 'normal') {\n if (input === 'e' && errorCount > 0) {\n store.setMode('errorList');\n }\n } else if (mode === 'interactive') {\n if (input === 'q' || key.escape) {\n if (expandedId) {\n store.collapse();\n } else {\n store.signalExit(() => {});\n }\n } else if (key.return) {\n store.toggleExpand();\n } else if (key.downArrow) {\n if (expandedId) {\n store.scrollDown(EXPANDED_MAX_VISIBLE_LINES);\n } else {\n store.selectNext(visibleProcessCount);\n }\n } else if (key.upArrow) {\n if (expandedId) {\n store.scrollUp();\n } else {\n store.selectPrev(visibleProcessCount);\n }\n } else if (input === 'j') {\n if (expandedId) {\n store.scrollDown(EXPANDED_MAX_VISIBLE_LINES);\n } else {\n store.selectNext(visibleProcessCount);\n }\n } else if (input === 'k') {\n if (expandedId) {\n store.scrollUp();\n } else {\n store.selectPrev(visibleProcessCount);\n }\n } else if (input === 'e' && errorCount > 0) {\n store.setMode('errorList');\n }\n } else if (mode === 'errorList') {\n if (key.escape) {\n store.setMode(isInteractive ? 'interactive' : 'normal');\n } else if (key.downArrow) {\n store.selectNextError();\n } else if (key.upArrow) {\n store.selectPrevError();\n } else if (key.return) {\n store.setMode('errorDetail');\n }\n } else if (mode === 'errorDetail') {\n if (key.escape) {\n store.setMode('errorList');\n } else if (key.downArrow) {\n store.selectNextError();\n } else if (key.upArrow) {\n store.selectPrevError();\n }\n }\n },\n { isActive: isRawModeSupported === true }\n );\n\n // Slice processes to visible viewport in interactive mode (must be before early returns)\n const visibleProcesses = useMemo(() => {\n if (mode === 'interactive') {\n return processes.slice(listScrollOffset, listScrollOffset + visibleProcessCount);\n }\n return processes;\n }, [processes, mode, listScrollOffset, visibleProcessCount]);\n\n // Error list modal\n if (mode === 'errorList') {\n return <ErrorListModal errors={failedProcesses} selectedIndex={selectedErrorIndex} totalErrorLines={errorLineCount} />;\n }\n\n // Error detail modal\n if (mode === 'errorDetail') {\n const selectedError = store.getSelectedError();\n if (selectedError) {\n return <ErrorDetailModal error={selectedError} currentIndex={selectedErrorIndex} totalErrors={failedProcesses.length} />;\n }\n // Fallback if no error selected\n store.setMode('errorList');\n }\n\n // Normal/Interactive view - render in original registration order\n const showSelection = mode === 'interactive';\n\n return (\n <Box flexDirection=\"column\">\n {/* Header */}\n {header && (\n <>\n <Text>{header}</Text>\n <Divider />\n </>\n )}\n\n {/* Visible processes */}\n {visibleProcesses.map((item) => {\n const originalIndex = processes.indexOf(item);\n return (\n <Box key={item.id} flexDirection=\"column\">\n <CompactProcessLine item={item} isSelected={showSelection && originalIndex === selectedIndex} />\n {expandedId === item.id && <ExpandedOutput lines={item.lines} scrollOffset={scrollOffset} />}\n </Box>\n );\n })}\n\n {/* Status bar */}\n {showStatusBar && processes.length > 0 && (\n <>\n <Divider />\n <StatusBar running={runningCount} done={doneCount} errors={errorCount} errorLines={errorLineCount} />\n </>\n )}\n </Box>\n );\n}\n\n// Wrapper component that provides store context\nexport default function App({ store }: AppProps): React.JSX.Element {\n return (\n <StoreContext.Provider value={store}>\n <AppContent store={store} />\n </StoreContext.Provider>\n );\n}\n"],"names":["App","AppContent","store","exit","useApp","isRawModeSupported","useStdin","stdout","useStdout","terminalHeight","rows","processes","useSyncExternalStore","subscribe","getSnapshot","shouldExit","getShouldExit","mode","getMode","selectedIndex","getSelectedIndex","selectedErrorIndex","getSelectedErrorIndex","expandedId","getExpandedId","scrollOffset","getScrollOffset","listScrollOffset","getListScrollOffset","header","getHeader","showStatusBar","getShowStatusBar","isInteractive","getIsInteractive","reservedLines","visibleProcessCount","Math","max","failedProcesses","getFailedProcesses","runningCount","getRunningCount","doneCount","getDoneCount","errorCount","getErrorCount","errorLineCount","getErrorLineCount","isAllComplete","useEffect","setMode","useInput","input","key","escape","collapse","signalExit","return","toggleExpand","downArrow","scrollDown","EXPANDED_MAX_VISIBLE_LINES","selectNext","upArrow","scrollUp","selectPrev","selectNextError","selectPrevError","isActive","visibleProcesses","useMemo","slice","ErrorListModal","errors","totalErrorLines","selectedError","getSelectedError","ErrorDetailModal","error","currentIndex","totalErrors","length","showSelection","Box","flexDirection","Text","Divider","map","item","originalIndex","indexOf","CompactProcessLine","isSelected","id","ExpandedOutput","lines","StatusBar","running","done","errorLines","StoreContext","Provider","value"],"mappings":"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"}
@@ -11,6 +11,7 @@ Object.defineProperty(exports, "default", {
11
11
  var _jsxruntime = require("react/jsx-runtime");
12
12
  var _ink = require("ink");
13
13
  var _react = require("react");
14
+ var _constantsts = require("../constants.js");
14
15
  var _ansiRegexts = /*#__PURE__*/ _interop_require_default(require("../lib/ansiRegex.js"));
15
16
  var _figurests = /*#__PURE__*/ _interop_require_default(require("../lib/figures.js"));
16
17
  var _typests = require("../types.js");
@@ -53,22 +54,6 @@ var BLANK_LINE = {
53
54
  type: _typests.LineType.stdout,
54
55
  text: ''
55
56
  };
56
- // From: https://github.com/sindresorhus/cli-spinners/blob/00de8fbeee16fa49502fa4f687449f70f2c8ca2c/spinners.json#L2
57
- var SPINNER = {
58
- interval: 80,
59
- frames: [
60
- '⠋',
61
- '⠙',
62
- '⠹',
63
- '⠸',
64
- '⠼',
65
- '⠴',
66
- '⠦',
67
- '⠧',
68
- '⠇',
69
- '⠏'
70
- ]
71
- };
72
57
  var ICONS = {
73
58
  error: /*#__PURE__*/ (0, _jsxruntime.jsx)(_ink.Text, {
74
59
  color: "red",
@@ -78,7 +63,7 @@ var ICONS = {
78
63
  color: "green",
79
64
  children: _figurests.default.tick
80
65
  }),
81
- running: /*#__PURE__*/ (0, _jsxruntime.jsx)(_Spinnerts.default, _object_spread({}, SPINNER))
66
+ running: /*#__PURE__*/ (0, _jsxruntime.jsx)(_Spinnerts.default, _object_spread({}, _constantsts.SPINNER))
82
67
  };
83
68
  var Header = /*#__PURE__*/ (0, _react.memo)(function Header(param) {
84
69
  var group = param.group, title = param.title, state = param.state;
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/components/ChildProcess.tsx"],"sourcesContent":["import { Box, Text } from 'ink';\nimport { memo, useMemo } from 'react';\nimport ansiRegex from '../lib/ansiRegex.ts';\nimport figures from '../lib/figures.ts';\nimport type { ChildProcess as ChildProcessT, Line, State } from '../types.ts';\nimport { LineType } from '../types.ts';\nimport Spinner from './Spinner.ts';\n\nconst REGEX_ANSI = ansiRegex();\nconst BLANK_LINE = { type: LineType.stdout, text: '' };\n\n// From: https://github.com/sindresorhus/cli-spinners/blob/00de8fbeee16fa49502fa4f687449f70f2c8ca2c/spinners.json#L2\nconst SPINNER = {\n interval: 80,\n frames: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'],\n};\n\nconst ICONS = {\n error: <Text color=\"red\">{figures.cross}</Text>,\n success: <Text color=\"green\">{figures.tick}</Text>,\n running: <Spinner {...SPINNER} />,\n};\n\ntype ItemProps = {\n item: ChildProcessT;\n};\n\ntype HeaderProps = {\n group?: string;\n title: string;\n state: State;\n};\n\nconst Header = memo(\n function Header({ group, title, state }: HeaderProps) {\n const icon = ICONS[state];\n\n return (\n <Box>\n {icon}\n {group && <Text bold>{`${group}${figures.pointer} `}</Text>}\n <Text>{title}</Text>\n </Box>\n );\n },\n (a, b) => a.group === b.group && a.title === b.title && a.state === b.state\n);\n\ntype RunningSummaryProps = {\n line: Line;\n};\n\nconst RunningSummary = memo(function RunningSummary({ line }: RunningSummaryProps) {\n return (\n <Box marginLeft={2}>\n <Text color=\"gray\">{line.text.replace(REGEX_ANSI, '')}</Text>\n </Box>\n );\n});\n\ntype LinesProps = {\n lines: Line[];\n};\n\nconst renderLine = (line, index) => {\n return (\n <Box key={index} minHeight={1}>\n <Text>{line.text}</Text>\n </Box>\n );\n};\n\nconst Lines = memo(function Lines({ lines }: LinesProps) {\n return (\n <Box flexDirection=\"column\" marginLeft={2}>\n {lines.map(renderLine)}\n </Box>\n );\n});\n\nconst Expanded = memo(function Expanded({ item }: ItemProps) {\n const { lines } = item;\n\n return (\n <Box flexDirection=\"column\">\n <Header group={item.group} title={item.title} state={item.state} />\n <Lines lines={lines} />\n </Box>\n );\n});\n\nconst Contracted = memo(function Contracted({ item }: ItemProps) {\n const { state, lines } = item;\n\n // remove ansi codes when displaying single lines\n const errors = useMemo(() => lines.filter((line) => line.type === LineType.stderr), [lines]);\n const summary = useMemo(() => lines.filter((line) => line.text.length > 0 && errors.indexOf(line) < 0).pop(), [lines, errors]);\n\n return (\n <Box flexDirection=\"column\">\n <Header group={item.group} title={item.title} state={item.state} />\n {state === 'running' && <RunningSummary line={summary || BLANK_LINE} />}\n {errors.length > 0 && <Lines lines={errors} />}\n </Box>\n );\n});\n\nexport default memo(function ChildProcess({ item }: ItemProps) {\n const { expanded } = item;\n return expanded ? <Expanded item={item} /> : <Contracted item={item} />;\n});\n"],"names":["REGEX_ANSI","ansiRegex","BLANK_LINE","type","LineType","stdout","text","SPINNER","interval","frames","ICONS","error","Text","color","figures","cross","success","tick","running","Spinner","Header","memo","group","title","state","icon","Box","bold","pointer","a","b","RunningSummary","line","marginLeft","replace","renderLine","index","minHeight","Lines","lines","flexDirection","map","Expanded","item","Contracted","errors","useMemo","filter","stderr","summary","length","indexOf","pop","ChildProcess","expanded"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/components/ChildProcess.tsx"],"sourcesContent":["import { Box, Text } from 'ink';\nimport { memo, useMemo } from 'react';\nimport { SPINNER } from '../constants.ts';\nimport ansiRegex from '../lib/ansiRegex.ts';\nimport figures from '../lib/figures.ts';\nimport type { ChildProcess as ChildProcessT, Line, State } from '../types.ts';\nimport { LineType } from '../types.ts';\nimport Spinner from './Spinner.ts';\n\nconst REGEX_ANSI = ansiRegex();\nconst BLANK_LINE = { type: LineType.stdout, text: '' };\n\nconst ICONS = {\n error: <Text color=\"red\">{figures.cross}</Text>,\n success: <Text color=\"green\">{figures.tick}</Text>,\n running: <Spinner {...SPINNER} />,\n};\n\ntype ItemProps = {\n item: ChildProcessT;\n};\n\ntype HeaderProps = {\n group?: string;\n title: string;\n state: State;\n};\n\nconst Header = memo(\n function Header({ group, title, state }: HeaderProps) {\n const icon = ICONS[state];\n\n return (\n <Box>\n {icon}\n {group && <Text bold>{`${group}${figures.pointer} `}</Text>}\n <Text>{title}</Text>\n </Box>\n );\n },\n (a, b) => a.group === b.group && a.title === b.title && a.state === b.state\n);\n\ntype RunningSummaryProps = {\n line: Line;\n};\n\nconst RunningSummary = memo(function RunningSummary({ line }: RunningSummaryProps) {\n return (\n <Box marginLeft={2}>\n <Text color=\"gray\">{line.text.replace(REGEX_ANSI, '')}</Text>\n </Box>\n );\n});\n\ntype LinesProps = {\n lines: Line[];\n};\n\nconst renderLine = (line, index) => {\n return (\n <Box key={index} minHeight={1}>\n <Text>{line.text}</Text>\n </Box>\n );\n};\n\nconst Lines = memo(function Lines({ lines }: LinesProps) {\n return (\n <Box flexDirection=\"column\" marginLeft={2}>\n {lines.map(renderLine)}\n </Box>\n );\n});\n\nconst Expanded = memo(function Expanded({ item }: ItemProps) {\n const { lines } = item;\n\n return (\n <Box flexDirection=\"column\">\n <Header group={item.group} title={item.title} state={item.state} />\n <Lines lines={lines} />\n </Box>\n );\n});\n\nconst Contracted = memo(function Contracted({ item }: ItemProps) {\n const { state, lines } = item;\n\n // remove ansi codes when displaying single lines\n const errors = useMemo(() => lines.filter((line) => line.type === LineType.stderr), [lines]);\n const summary = useMemo(() => lines.filter((line) => line.text.length > 0 && errors.indexOf(line) < 0).pop(), [lines, errors]);\n\n return (\n <Box flexDirection=\"column\">\n <Header group={item.group} title={item.title} state={item.state} />\n {state === 'running' && <RunningSummary line={summary || BLANK_LINE} />}\n {errors.length > 0 && <Lines lines={errors} />}\n </Box>\n );\n});\n\nexport default memo(function ChildProcess({ item }: ItemProps) {\n const { expanded } = item;\n return expanded ? <Expanded item={item} /> : <Contracted item={item} />;\n});\n"],"names":["REGEX_ANSI","ansiRegex","BLANK_LINE","type","LineType","stdout","text","ICONS","error","Text","color","figures","cross","success","tick","running","Spinner","SPINNER","Header","memo","group","title","state","icon","Box","bold","pointer","a","b","RunningSummary","line","marginLeft","replace","renderLine","index","minHeight","Lines","lines","flexDirection","map","Expanded","item","Contracted","errors","useMemo","filter","stderr","summary","length","indexOf","pop","ChildProcess","expanded"],"mappings":"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"}
@@ -11,6 +11,8 @@ Object.defineProperty(exports, "default", {
11
11
  var _jsxruntime = require("react/jsx-runtime");
12
12
  var _ink = require("ink");
13
13
  var _react = require("react");
14
+ var _constantsts = require("../constants.js");
15
+ var _clipTextts = require("../lib/clipText.js");
14
16
  var _figurests = /*#__PURE__*/ _interop_require_default(require("../lib/figures.js"));
15
17
  var _formatts = require("../lib/format.js");
16
18
  var _StoreContextts = require("../state/StoreContext.js");
@@ -49,26 +51,6 @@ function _object_spread(target) {
49
51
  }
50
52
  return target;
51
53
  }
52
- // From: https://github.com/sindresorhus/cli-spinners/blob/00de8fbeee16fa49502fa4f687449f70f2c8ca2c/spinners.json#L2
53
- var SPINNER = {
54
- interval: 80,
55
- frames: [
56
- '⠋',
57
- '⠙',
58
- '⠹',
59
- '⠸',
60
- '⠼',
61
- '⠴',
62
- '⠦',
63
- '⠧',
64
- '⠇',
65
- '⠏'
66
- ]
67
- };
68
- function truncate(str, maxLength) {
69
- if (str.length <= maxLength) return str;
70
- return "".concat(str.slice(0, maxLength - 1), "…");
71
- }
72
54
  function getLastOutputLine(lines) {
73
55
  for(var i = lines.length - 1; i >= 0; i--){
74
56
  if (lines[i].text.length > 0) {
@@ -92,22 +74,24 @@ var _default = /*#__PURE__*/ (0, _react.memo)(function CompactProcessLine(param)
92
74
  // Display name: prefer group, fall back to title
93
75
  var displayName = group || title;
94
76
  // Calculate widths - use dynamic column width based on longest name
77
+ var selectionWidth = 1; // selection indicator
95
78
  var iconWidth = 2; // icon + space
96
79
  var maxGroupLength = store.getMaxGroupLength();
97
80
  var nameColumnWidth = (0, _formatts.calculateColumnWidth)('max', terminalWidth, maxGroupLength);
98
81
  var gap = 1; // space between name and status
99
- var statusWidth = terminalWidth - iconWidth - nameColumnWidth - gap;
100
- // Truncate name if needed and pad to column width
101
- var truncatedName = truncate(displayName, nameColumnWidth).padEnd(nameColumnWidth);
102
- // Status text based on state
82
+ var statusWidth = Math.max(0, terminalWidth - selectionWidth - iconWidth - nameColumnWidth - gap);
83
+ // Clip name to column width and pad
84
+ var clippedName = (0, _clipTextts.clipText)(displayName, nameColumnWidth).padEnd(nameColumnWidth);
85
+ // Status text based on state - clip to available width
103
86
  var statusText = (0, _react.useMemo)(function() {
104
87
  if (state === 'running') {
105
88
  var lastLine = getLastOutputLine(lines);
106
- return lastLine ? truncate(lastLine, statusWidth) : '';
89
+ return lastLine ? (0, _clipTextts.clipText)(lastLine, statusWidth) : '';
107
90
  }
108
91
  if (state === 'error') {
109
92
  var errorCount = getErrorCount(lines);
110
- return errorCount > 0 ? "".concat(errorCount, " error").concat(errorCount > 1 ? 's' : '') : 'failed';
93
+ var text = errorCount > 0 ? "".concat(errorCount, " error").concat(errorCount > 1 ? 's' : '') : 'failed';
94
+ return (0, _clipTextts.clipText)(text, statusWidth);
111
95
  }
112
96
  return ''; // success - no status text
113
97
  }, [
@@ -119,7 +103,7 @@ var _default = /*#__PURE__*/ (0, _react.memo)(function CompactProcessLine(param)
119
103
  var icon = (0, _react.useMemo)(function() {
120
104
  switch(state){
121
105
  case 'running':
122
- return /*#__PURE__*/ (0, _jsxruntime.jsx)(_Spinnerts.default, _object_spread({}, SPINNER));
106
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(_Spinnerts.default, _object_spread({}, _constantsts.SPINNER));
123
107
  case 'success':
124
108
  return /*#__PURE__*/ (0, _jsxruntime.jsx)(_ink.Text, {
125
109
  color: "green",
@@ -137,6 +121,7 @@ var _default = /*#__PURE__*/ (0, _react.memo)(function CompactProcessLine(param)
137
121
  // Status text color
138
122
  var statusColor = state === 'error' ? 'red' : 'gray';
139
123
  return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_ink.Box, {
124
+ width: terminalWidth,
140
125
  children: [
141
126
  /*#__PURE__*/ (0, _jsxruntime.jsx)(_ink.Text, {
142
127
  color: isSelected ? 'cyan' : undefined,
@@ -146,16 +131,22 @@ var _default = /*#__PURE__*/ (0, _react.memo)(function CompactProcessLine(param)
146
131
  width: iconWidth,
147
132
  children: icon
148
133
  }),
149
- /*#__PURE__*/ (0, _jsxruntime.jsx)(_ink.Text, {
150
- inverse: isSelected,
151
- children: truncatedName
134
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_ink.Box, {
135
+ width: nameColumnWidth,
136
+ children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_ink.Text, {
137
+ inverse: isSelected,
138
+ children: clippedName
139
+ })
152
140
  }),
153
- statusText && /*#__PURE__*/ (0, _jsxruntime.jsxs)(_ink.Text, {
154
- color: statusColor,
155
- children: [
156
- " ",
157
- statusText
158
- ]
141
+ statusWidth > 0 && statusText && /*#__PURE__*/ (0, _jsxruntime.jsx)(_ink.Box, {
142
+ width: statusWidth + gap,
143
+ children: /*#__PURE__*/ (0, _jsxruntime.jsxs)(_ink.Text, {
144
+ color: statusColor,
145
+ children: [
146
+ " ",
147
+ statusText
148
+ ]
149
+ })
159
150
  })
160
151
  ]
161
152
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/components/CompactProcessLine.tsx"],"sourcesContent":["import { Box, Text, useStdout } from 'ink';\nimport { memo, useMemo } from 'react';\nimport figures from '../lib/figures.ts';\nimport { calculateColumnWidth } from '../lib/format.ts';\nimport { useStore } from '../state/StoreContext.ts';\nimport type { ChildProcess, Line } from '../types.ts';\nimport { LineType } from '../types.ts';\nimport Spinner from './Spinner.ts';\n\n// From: https://github.com/sindresorhus/cli-spinners/blob/00de8fbeee16fa49502fa4f687449f70f2c8ca2c/spinners.json#L2\nconst SPINNER = {\n interval: 80,\n frames: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'],\n};\n\ntype Props = {\n item: ChildProcess;\n isSelected?: boolean;\n};\n\nfunction truncate(str: string, maxLength: number): string {\n if (str.length <= maxLength) return str;\n return `${str.slice(0, maxLength - 1)}…`;\n}\n\nfunction getLastOutputLine(lines: Line[]): string {\n for (let i = lines.length - 1; i >= 0; i--) {\n if (lines[i].text.length > 0) {\n return lines[i].text;\n }\n }\n return '';\n}\n\nfunction getErrorCount(lines: Line[]): number {\n return lines.filter((line) => line.type === LineType.stderr).length;\n}\n\nexport default memo(function CompactProcessLine({ item, isSelected = false }: Props) {\n const store = useStore();\n const { stdout } = useStdout();\n const terminalWidth = stdout?.columns || 80;\n\n const { group, title, state, lines } = item;\n const selectionIndicator = isSelected ? figures.pointer : ' ';\n\n // Display name: prefer group, fall back to title\n const displayName = group || title;\n\n // Calculate widths - use dynamic column width based on longest name\n const iconWidth = 2; // icon + space\n const maxGroupLength = store.getMaxGroupLength();\n const nameColumnWidth = calculateColumnWidth('max', terminalWidth, maxGroupLength);\n const gap = 1; // space between name and status\n const statusWidth = terminalWidth - iconWidth - nameColumnWidth - gap;\n\n // Truncate name if needed and pad to column width\n const truncatedName = truncate(displayName, nameColumnWidth).padEnd(nameColumnWidth);\n\n // Status text based on state\n const statusText = useMemo(() => {\n if (state === 'running') {\n const lastLine = getLastOutputLine(lines);\n return lastLine ? truncate(lastLine, statusWidth) : '';\n }\n if (state === 'error') {\n const errorCount = getErrorCount(lines);\n return errorCount > 0 ? `${errorCount} error${errorCount > 1 ? 's' : ''}` : 'failed';\n }\n return ''; // success - no status text\n }, [state, lines, statusWidth]);\n\n // Icon based on state\n const icon = useMemo(() => {\n switch (state) {\n case 'running':\n return <Spinner {...SPINNER} />;\n case 'success':\n return <Text color=\"green\">{figures.tick}</Text>;\n case 'error':\n return <Text color=\"red\">{figures.cross}</Text>;\n }\n }, [state]);\n\n // Status text color\n const statusColor = state === 'error' ? 'red' : 'gray';\n\n return (\n <Box>\n <Text color={isSelected ? 'cyan' : undefined}>{selectionIndicator}</Text>\n <Box width={iconWidth}>{icon}</Box>\n <Text inverse={isSelected}>{truncatedName}</Text>\n {statusText && <Text color={statusColor}> {statusText}</Text>}\n </Box>\n );\n});\n"],"names":["SPINNER","interval","frames","truncate","str","maxLength","length","slice","getLastOutputLine","lines","i","text","getErrorCount","filter","line","type","LineType","stderr","memo","CompactProcessLine","item","isSelected","store","useStore","stdout","useStdout","terminalWidth","columns","group","title","state","selectionIndicator","figures","pointer","displayName","iconWidth","maxGroupLength","getMaxGroupLength","nameColumnWidth","calculateColumnWidth","gap","statusWidth","truncatedName","padEnd","statusText","useMemo","lastLine","errorCount","icon","Spinner","Text","color","tick","cross","statusColor","Box","undefined","width","inverse"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/components/CompactProcessLine.tsx"],"sourcesContent":["import { Box, Text, useStdout } from 'ink';\nimport { memo, useMemo } from 'react';\nimport { SPINNER } from '../constants.ts';\nimport { clipText } from '../lib/clipText.ts';\nimport figures from '../lib/figures.ts';\nimport { calculateColumnWidth } from '../lib/format.ts';\nimport { useStore } from '../state/StoreContext.ts';\nimport type { ChildProcess, Line } from '../types.ts';\nimport { LineType } from '../types.ts';\nimport Spinner from './Spinner.ts';\n\ntype Props = {\n item: ChildProcess;\n isSelected?: boolean;\n};\n\nfunction getLastOutputLine(lines: Line[]): string {\n for (let i = lines.length - 1; i >= 0; i--) {\n if (lines[i].text.length > 0) {\n return lines[i].text;\n }\n }\n return '';\n}\n\nfunction getErrorCount(lines: Line[]): number {\n return lines.filter((line) => line.type === LineType.stderr).length;\n}\n\nexport default memo(function CompactProcessLine({ item, isSelected = false }: Props) {\n const store = useStore();\n const { stdout } = useStdout();\n const terminalWidth = stdout?.columns || 80;\n\n const { group, title, state, lines } = item;\n const selectionIndicator = isSelected ? figures.pointer : ' ';\n\n // Display name: prefer group, fall back to title\n const displayName = group || title;\n\n // Calculate widths - use dynamic column width based on longest name\n const selectionWidth = 1; // selection indicator\n const iconWidth = 2; // icon + space\n const maxGroupLength = store.getMaxGroupLength();\n const nameColumnWidth = calculateColumnWidth('max', terminalWidth, maxGroupLength);\n const gap = 1; // space between name and status\n const statusWidth = Math.max(0, terminalWidth - selectionWidth - iconWidth - nameColumnWidth - gap);\n\n // Clip name to column width and pad\n const clippedName = clipText(displayName, nameColumnWidth).padEnd(nameColumnWidth);\n\n // Status text based on state - clip to available width\n const statusText = useMemo(() => {\n if (state === 'running') {\n const lastLine = getLastOutputLine(lines);\n return lastLine ? clipText(lastLine, statusWidth) : '';\n }\n if (state === 'error') {\n const errorCount = getErrorCount(lines);\n const text = errorCount > 0 ? `${errorCount} error${errorCount > 1 ? 's' : ''}` : 'failed';\n return clipText(text, statusWidth);\n }\n return ''; // success - no status text\n }, [state, lines, statusWidth]);\n\n // Icon based on state\n const icon = useMemo(() => {\n switch (state) {\n case 'running':\n return <Spinner {...SPINNER} />;\n case 'success':\n return <Text color=\"green\">{figures.tick}</Text>;\n case 'error':\n return <Text color=\"red\">{figures.cross}</Text>;\n }\n }, [state]);\n\n // Status text color\n const statusColor = state === 'error' ? 'red' : 'gray';\n\n return (\n <Box width={terminalWidth}>\n <Text color={isSelected ? 'cyan' : undefined}>{selectionIndicator}</Text>\n <Box width={iconWidth}>{icon}</Box>\n <Box width={nameColumnWidth}>\n <Text inverse={isSelected}>{clippedName}</Text>\n </Box>\n {statusWidth > 0 && statusText && (\n <Box width={statusWidth + gap}>\n <Text color={statusColor}> {statusText}</Text>\n </Box>\n )}\n </Box>\n );\n});\n"],"names":["getLastOutputLine","lines","i","length","text","getErrorCount","filter","line","type","LineType","stderr","memo","CompactProcessLine","item","isSelected","store","useStore","stdout","useStdout","terminalWidth","columns","group","title","state","selectionIndicator","figures","pointer","displayName","selectionWidth","iconWidth","maxGroupLength","getMaxGroupLength","nameColumnWidth","calculateColumnWidth","gap","statusWidth","Math","max","clippedName","clipText","padEnd","statusText","useMemo","lastLine","errorCount","icon","Spinner","SPINNER","Text","color","tick","cross","statusColor","Box","width","undefined","inverse"],"mappings":"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"}
@@ -11,6 +11,7 @@ Object.defineProperty(exports, "default", {
11
11
  var _jsxruntime = require("react/jsx-runtime");
12
12
  var _ink = require("ink");
13
13
  var _react = require("react");
14
+ var _constantsts = require("../constants.js");
14
15
  var _figurests = /*#__PURE__*/ _interop_require_default(require("../lib/figures.js"));
15
16
  var _Spinnerts = /*#__PURE__*/ _interop_require_default(require("./Spinner.js"));
16
17
  function _define_property(obj, key, value) {
@@ -46,22 +47,6 @@ function _object_spread(target) {
46
47
  }
47
48
  return target;
48
49
  }
49
- // From: https://github.com/sindresorhus/cli-spinners/blob/00de8fbeee16fa49502fa4f687449f70f2c8ca2c/spinners.json#L2
50
- var SPINNER = {
51
- interval: 80,
52
- frames: [
53
- '⠋',
54
- '⠙',
55
- '⠹',
56
- '⠸',
57
- '⠼',
58
- '⠴',
59
- '⠦',
60
- '⠧',
61
- '⠇',
62
- '⠏'
63
- ]
64
- };
65
50
  var _default = /*#__PURE__*/ (0, _react.memo)(function StatusBar(param) {
66
51
  var running = param.running, done = param.done, errors = param.errors, errorLines = param.errorLines;
67
52
  return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_ink.Box, {
@@ -70,16 +55,16 @@ var _default = /*#__PURE__*/ (0, _react.memo)(function StatusBar(param) {
70
55
  /*#__PURE__*/ (0, _jsxruntime.jsx)(_ink.Box, {
71
56
  children: /*#__PURE__*/ (0, _jsxruntime.jsxs)(_ink.Text, {
72
57
  children: [
73
- running > 0 ? /*#__PURE__*/ (0, _jsxruntime.jsx)(_Spinnerts.default, _object_spread({}, SPINNER)) : /*#__PURE__*/ (0, _jsxruntime.jsx)(_ink.Text, {
58
+ running > 0 ? /*#__PURE__*/ (0, _jsxruntime.jsx)(_Spinnerts.default, _object_spread({}, _constantsts.SPINNER)) : /*#__PURE__*/ (0, _jsxruntime.jsx)(_ink.Text, {
74
59
  color: "green",
75
60
  children: _figurests.default.tick
76
61
  }),
77
- " Running: ".concat(running, " "),
62
+ " Running: ".concat(running, " | "),
78
63
  /*#__PURE__*/ (0, _jsxruntime.jsx)(_ink.Text, {
79
64
  color: "green",
80
65
  children: _figurests.default.tick
81
66
  }),
82
- " Done: ".concat(done, " "),
67
+ " Done: ".concat(done, " | "),
83
68
  /*#__PURE__*/ (0, _jsxruntime.jsx)(_ink.Text, {
84
69
  color: "red",
85
70
  children: _figurests.default.cross
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/components/StatusBar.tsx"],"sourcesContent":["import { Box, Text } from 'ink';\nimport { memo } from 'react';\nimport figures from '../lib/figures.ts';\nimport Spinner from './Spinner.ts';\n\n// From: https://github.com/sindresorhus/cli-spinners/blob/00de8fbeee16fa49502fa4f687449f70f2c8ca2c/spinners.json#L2\nconst SPINNER = {\n interval: 80,\n frames: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'],\n};\n\ntype Props = {\n running: number;\n done: number;\n errors: number;\n errorLines: number;\n};\n\nexport default memo(function StatusBar({ running, done, errors, errorLines }: Props) {\n return (\n <Box justifyContent=\"space-between\">\n <Box>\n <Text>\n {running > 0 ? <Spinner {...SPINNER} /> : <Text color=\"green\">{figures.tick}</Text>}\n {` Running: ${running} `}\n <Text color=\"green\">{figures.tick}</Text>\n {` Done: ${done} `}\n <Text color=\"red\">{figures.cross}</Text>\n {` Errors: ${errors}`}\n {errorLines > 0 && <Text dimColor>{` (${errorLines} lines)`}</Text>}\n </Text>\n </Box>\n {errors > 0 && (\n <Box>\n <Text dimColor>[e]rrors</Text>\n </Box>\n )}\n </Box>\n );\n});\n"],"names":["SPINNER","interval","frames","memo","StatusBar","running","done","errors","errorLines","Box","justifyContent","Text","Spinner","color","figures","tick","cross","dimColor"],"mappings":";;;;+BAkBA;;;eAAA;;;;mBAlB0B;qBACL;gEACD;gEACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEpB,oHAAoH;AACpH,IAAMA,UAAU;IACdC,UAAU;IACVC,QAAQ;QAAC;QAAK;QAAK;QAAK;QAAK;QAAK;QAAK;QAAK;QAAK;QAAK;KAAI;AAC5D;IASA,yBAAeC,IAAAA,WAAI,EAAC,SAASC,UAAU,KAA4C;QAA1CC,UAAF,MAAEA,SAASC,OAAX,MAAWA,MAAMC,SAAjB,MAAiBA,QAAQC,aAAzB,MAAyBA;IAC9D,qBACE,sBAACC,QAAG;QAACC,gBAAe;;0BAClB,qBAACD,QAAG;0BACF,cAAA,sBAACE,SAAI;;wBACFN,UAAU,kBAAI,qBAACO,kBAAO,qBAAKZ,0BAAc,qBAACW,SAAI;4BAACE,OAAM;sCAASC,kBAAO,CAACC,IAAI;;wBACzE,aAAoB,OAARV,SAAQ;sCACtB,qBAACM,SAAI;4BAACE,OAAM;sCAASC,kBAAO,CAACC,IAAI;;wBAC/B,UAAc,OAALT,MAAK;sCAChB,qBAACK,SAAI;4BAACE,OAAM;sCAAOC,kBAAO,CAACE,KAAK;;wBAC9B,YAAkB,OAAPT;wBACZC,aAAa,mBAAK,qBAACG,SAAI;4BAACM,QAAQ;sCAAE,AAAC,KAAe,OAAXT,YAAW;;;;;YAGtDD,SAAS,mBACR,qBAACE,QAAG;0BACF,cAAA,qBAACE,SAAI;oBAACM,QAAQ;8BAAC;;;;;AAKzB"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/components/StatusBar.tsx"],"sourcesContent":["import { Box, Text } from 'ink';\nimport { memo } from 'react';\nimport { SPINNER } from '../constants.ts';\nimport figures from '../lib/figures.ts';\nimport Spinner from './Spinner.ts';\n\ntype Props = {\n running: number;\n done: number;\n errors: number;\n errorLines: number;\n};\n\nexport default memo(function StatusBar({ running, done, errors, errorLines }: Props) {\n return (\n <Box justifyContent=\"space-between\">\n <Box>\n <Text>\n {running > 0 ? <Spinner {...SPINNER} /> : <Text color=\"green\">{figures.tick}</Text>}\n {` Running: ${running} | `}\n <Text color=\"green\">{figures.tick}</Text>\n {` Done: ${done} | `}\n <Text color=\"red\">{figures.cross}</Text>\n {` Errors: ${errors}`}\n {errorLines > 0 && <Text dimColor>{` (${errorLines} lines)`}</Text>}\n </Text>\n </Box>\n {errors > 0 && (\n <Box>\n <Text dimColor>[e]rrors</Text>\n </Box>\n )}\n </Box>\n );\n});\n"],"names":["memo","StatusBar","running","done","errors","errorLines","Box","justifyContent","Text","Spinner","SPINNER","color","figures","tick","cross","dimColor"],"mappings":";;;;+BAaA;;;eAAA;;;;mBAb0B;qBACL;2BACG;gEACJ;gEACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IASpB,yBAAeA,IAAAA,WAAI,EAAC,SAASC,UAAU,KAA4C;QAA1CC,UAAF,MAAEA,SAASC,OAAX,MAAWA,MAAMC,SAAjB,MAAiBA,QAAQC,aAAzB,MAAyBA;IAC9D,qBACE,sBAACC,QAAG;QAACC,gBAAe;;0BAClB,qBAACD,QAAG;0BACF,cAAA,sBAACE,SAAI;;wBACFN,UAAU,kBAAI,qBAACO,kBAAO,qBAAKC,oBAAO,mBAAO,qBAACF,SAAI;4BAACG,OAAM;sCAASC,kBAAO,CAACC,IAAI;;wBACzE,aAAoB,OAARX,SAAQ;sCACtB,qBAACM,SAAI;4BAACG,OAAM;sCAASC,kBAAO,CAACC,IAAI;;wBAC/B,UAAc,OAALV,MAAK;sCAChB,qBAACK,SAAI;4BAACG,OAAM;sCAAOC,kBAAO,CAACE,KAAK;;wBAC9B,YAAkB,OAAPV;wBACZC,aAAa,mBAAK,qBAACG,SAAI;4BAACO,QAAQ;sCAAE,AAAC,KAAe,OAAXV,YAAW;;;;;YAGtDD,SAAS,mBACR,qBAACE,QAAG;0BACF,cAAA,qBAACE,SAAI;oBAACO,QAAQ;8BAAC;;;;;AAKzB"}
@@ -30,6 +30,9 @@ _export(exports, {
30
30
  },
31
31
  get MAX_COLUMN_WIDTH_PERCENT () {
32
32
  return MAX_COLUMN_WIDTH_PERCENT;
33
+ },
34
+ get SPINNER () {
35
+ return SPINNER;
33
36
  }
34
37
  });
35
38
  var DEFAULT_COLUMN_WIDTH = 15;
@@ -39,4 +42,19 @@ var BATCH_MAX_LINES = 20;
39
42
  var BATCH_MAX_WAIT_MS = 50;
40
43
  var DEFAULT_MAX_FPS = 20;
41
44
  var EXPANDED_MAX_VISIBLE_LINES = 10;
45
+ var SPINNER = {
46
+ interval: 80,
47
+ frames: [
48
+ '⠋',
49
+ '⠙',
50
+ '⠹',
51
+ '⠸',
52
+ '⠼',
53
+ '⠴',
54
+ '⠦',
55
+ '⠧',
56
+ '⠇',
57
+ '⠏'
58
+ ]
59
+ };
42
60
  /* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/constants.ts"],"sourcesContent":["// Column width defaults\nexport const DEFAULT_COLUMN_WIDTH = 15;\nexport const MAX_COLUMN_WIDTH_PERCENT = 0.4; // 40% of terminal width\nexport const FALLBACK_COLUMN_WIDTH = 25;\n\n// Batching defaults\nexport const BATCH_MAX_LINES = 20;\nexport const BATCH_MAX_WAIT_MS = 50;\n\n// Rendering\nexport const DEFAULT_MAX_FPS = 20;\n\n// Expansion\nexport const EXPANDED_MAX_VISIBLE_LINES = 10;\n"],"names":["BATCH_MAX_LINES","BATCH_MAX_WAIT_MS","DEFAULT_COLUMN_WIDTH","DEFAULT_MAX_FPS","EXPANDED_MAX_VISIBLE_LINES","FALLBACK_COLUMN_WIDTH","MAX_COLUMN_WIDTH_PERCENT"],"mappings":"AAAA,wBAAwB;;;;;;;;;;;;QAMXA;eAAAA;;QACAC;eAAAA;;QANAC;eAAAA;;QASAC;eAAAA;;QAGAC;eAAAA;;QAVAC;eAAAA;;QADAC;eAAAA;;;AADN,IAAMJ,uBAAuB;AAC7B,IAAMI,2BAA2B,KAAK,wBAAwB;AAC9D,IAAMD,wBAAwB;AAG9B,IAAML,kBAAkB;AACxB,IAAMC,oBAAoB;AAG1B,IAAME,kBAAkB;AAGxB,IAAMC,6BAA6B"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/constants.ts"],"sourcesContent":["// Column width defaults\nexport const DEFAULT_COLUMN_WIDTH = 15;\nexport const MAX_COLUMN_WIDTH_PERCENT = 0.4; // 40% of terminal width\nexport const FALLBACK_COLUMN_WIDTH = 25;\n\n// Batching defaults\nexport const BATCH_MAX_LINES = 20;\nexport const BATCH_MAX_WAIT_MS = 50;\n\n// Rendering\nexport const DEFAULT_MAX_FPS = 20;\n\n// Expansion\nexport const EXPANDED_MAX_VISIBLE_LINES = 10;\n\n// From: https://github.com/sindresorhus/cli-spinners/blob/00de8fbeee16fa49502fa4f687449f70f2c8ca2c/spinners.json#L2\nexport const SPINNER = {\n interval: 80,\n frames: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'],\n};\n"],"names":["BATCH_MAX_LINES","BATCH_MAX_WAIT_MS","DEFAULT_COLUMN_WIDTH","DEFAULT_MAX_FPS","EXPANDED_MAX_VISIBLE_LINES","FALLBACK_COLUMN_WIDTH","MAX_COLUMN_WIDTH_PERCENT","SPINNER","interval","frames"],"mappings":"AAAA,wBAAwB;;;;;;;;;;;;QAMXA;eAAAA;;QACAC;eAAAA;;QANAC;eAAAA;;QASAC;eAAAA;;QAGAC;eAAAA;;QAVAC;eAAAA;;QADAC;eAAAA;;QAcAC;eAAAA;;;AAfN,IAAML,uBAAuB;AAC7B,IAAMI,2BAA2B,KAAK,wBAAwB;AAC9D,IAAMD,wBAAwB;AAG9B,IAAML,kBAAkB;AACxB,IAAMC,oBAAoB;AAG1B,IAAME,kBAAkB;AAGxB,IAAMC,6BAA6B;AAGnC,IAAMG,UAAU;IACrBC,UAAU;IACVC,QAAQ;QAAC;QAAK;QAAK;QAAK;QAAK;QAAK;QAAK;QAAK;QAAK;QAAK;KAAI;AAC5D"}
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "createSession", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return createSession;
9
+ }
10
+ });
11
+ function _getRequireWildcardCache(nodeInterop) {
12
+ if (typeof WeakMap !== "function") return null;
13
+ var cacheBabelInterop = new WeakMap();
14
+ var cacheNodeInterop = new WeakMap();
15
+ return (_getRequireWildcardCache = function(nodeInterop) {
16
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
17
+ })(nodeInterop);
18
+ }
19
+ function _interop_require_wildcard(obj, nodeInterop) {
20
+ if (!nodeInterop && obj && obj.__esModule) {
21
+ return obj;
22
+ }
23
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
24
+ return {
25
+ default: obj
26
+ };
27
+ }
28
+ var cache = _getRequireWildcardCache(nodeInterop);
29
+ if (cache && cache.has(obj)) {
30
+ return cache.get(obj);
31
+ }
32
+ var newObj = {
33
+ __proto__: null
34
+ };
35
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
36
+ for(var key in obj){
37
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
38
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
39
+ if (desc && (desc.get || desc.set)) {
40
+ Object.defineProperty(newObj, key, desc);
41
+ } else {
42
+ newObj[key] = obj[key];
43
+ }
44
+ }
45
+ }
46
+ newObj.default = obj;
47
+ if (cache) {
48
+ cache.set(obj, newObj);
49
+ }
50
+ return newObj;
51
+ }
52
+ function createSession(options) {
53
+ var realSession = null;
54
+ var loadError = null;
55
+ // Start loading immediately
56
+ Promise.resolve().then(function() {
57
+ return /*#__PURE__*/ _interop_require_wildcard(require("./session.js"));
58
+ }).then(function(mod) {
59
+ realSession = mod.createSession(options);
60
+ }).catch(function(err) {
61
+ loadError = err;
62
+ });
63
+ return {
64
+ spawn: function spawn(command, args, spawnOptions, processOptions, callback) {
65
+ if (loadError) {
66
+ callback(loadError);
67
+ return;
68
+ }
69
+ if (realSession) {
70
+ realSession.spawn(command, args, spawnOptions, processOptions, callback);
71
+ return;
72
+ }
73
+ // Still loading, wait for it
74
+ Promise.resolve().then(function() {
75
+ return /*#__PURE__*/ _interop_require_wildcard(require("./session.js"));
76
+ }).then(function(mod) {
77
+ if (!realSession) realSession = mod.createSession(options);
78
+ realSession.spawn(command, args, spawnOptions, processOptions, callback);
79
+ }).catch(callback);
80
+ },
81
+ close: function close() {
82
+ if (realSession) realSession.close();
83
+ },
84
+ waitAndClose: function waitAndClose(callback) {
85
+ if (realSession) {
86
+ realSession.waitAndClose(callback);
87
+ return;
88
+ }
89
+ // Still loading, wait for it
90
+ Promise.resolve().then(function() {
91
+ return /*#__PURE__*/ _interop_require_wildcard(require("./session.js"));
92
+ }).then(function(mod) {
93
+ if (!realSession) realSession = mod.createSession(options);
94
+ realSession.waitAndClose(callback);
95
+ }).catch(function() {
96
+ callback === null || callback === void 0 ? void 0 : callback();
97
+ });
98
+ }
99
+ };
100
+ }
101
+ /* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/createSessionWrapper.ts"],"sourcesContent":["import type { ProcessOptions, SessionOptions, SpawnError, SpawnOptions, TerminalCallback } from './types.ts';\n\nexport interface Session {\n spawn(command: string, args: string[], spawnOptions: SpawnOptions, options: ProcessOptions, callback: TerminalCallback): void;\n close(): void;\n waitAndClose(callback?: () => void): void;\n}\n\nexport function createSession(options?: SessionOptions): Session {\n let realSession: Session | null = null;\n let loadError: SpawnError | null = null;\n\n // Start loading immediately\n import('./session.ts')\n .then((mod) => {\n realSession = mod.createSession(options);\n })\n .catch((err) => {\n loadError = err;\n });\n\n return {\n spawn(command: string, args: string[], spawnOptions: SpawnOptions, processOptions: ProcessOptions, callback: TerminalCallback): void {\n if (loadError) {\n callback(loadError);\n return;\n }\n if (realSession) {\n realSession.spawn(command, args, spawnOptions, processOptions, callback);\n return;\n }\n // Still loading, wait for it\n import('./session.ts')\n .then((mod) => {\n if (!realSession) realSession = mod.createSession(options);\n realSession.spawn(command, args, spawnOptions, processOptions, callback);\n })\n .catch(callback);\n },\n close(): void {\n if (realSession) realSession.close();\n },\n waitAndClose(callback?: () => void): void {\n if (realSession) {\n realSession.waitAndClose(callback);\n return;\n }\n // Still loading, wait for it\n import('./session.ts')\n .then((mod) => {\n if (!realSession) realSession = mod.createSession(options);\n realSession.waitAndClose(callback);\n })\n .catch(() => {\n callback?.();\n });\n },\n };\n}\n"],"names":["createSession","options","realSession","loadError","then","mod","catch","err","spawn","command","args","spawnOptions","processOptions","callback","close","waitAndClose"],"mappings":";;;;+BAQgBA;;;eAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAT,SAASA,cAAcC,OAAwB;IACpD,IAAIC,cAA8B;IAClC,IAAIC,YAA+B;IAEnC,4BAA4B;IAC5B;uDAAA,QAAO;OACJC,IAAI,CAAC,SAACC;QACLH,cAAcG,IAAIL,aAAa,CAACC;IAClC,GACCK,KAAK,CAAC,SAACC;QACNJ,YAAYI;IACd;IAEF,OAAO;QACLC,OAAAA,SAAAA,MAAMC,OAAe,EAAEC,IAAc,EAAEC,YAA0B,EAAEC,cAA8B,EAAEC,QAA0B;YAC3H,IAAIV,WAAW;gBACbU,SAASV;gBACT;YACF;YACA,IAAID,aAAa;gBACfA,YAAYM,KAAK,CAACC,SAASC,MAAMC,cAAcC,gBAAgBC;gBAC/D;YACF;YACA,6BAA6B;YAC7B;+DAAA,QAAO;eACJT,IAAI,CAAC,SAACC;gBACL,IAAI,CAACH,aAAaA,cAAcG,IAAIL,aAAa,CAACC;gBAClDC,YAAYM,KAAK,CAACC,SAASC,MAAMC,cAAcC,gBAAgBC;YACjE,GACCP,KAAK,CAACO;QACX;QACAC,OAAAA,SAAAA;YACE,IAAIZ,aAAaA,YAAYY,KAAK;QACpC;QACAC,cAAAA,SAAAA,aAAaF,QAAqB;YAChC,IAAIX,aAAa;gBACfA,YAAYa,YAAY,CAACF;gBACzB;YACF;YACA,6BAA6B;YAC7B;+DAAA,QAAO;eACJT,IAAI,CAAC,SAACC;gBACL,IAAI,CAACH,aAAaA,cAAcG,IAAIL,aAAa,CAACC;gBAClDC,YAAYa,YAAY,CAACF;YAC3B,GACCP,KAAK,CAAC;gBACLO,qBAAAA,+BAAAA;YACF;QACJ;IACF;AACF"}
@@ -22,7 +22,7 @@ _export(exports, {
22
22
  var _figurests = /*#__PURE__*/ _interop_require_default(require("./lib/figures.js"));
23
23
  var _formatArgumentsts = /*#__PURE__*/ _interop_require_default(require("./lib/formatArguments.js"));
24
24
  _export_star(require("./types.js"), exports);
25
- var _sessionts = require("./session.js");
25
+ var _createSessionWrapperts = require("./createSessionWrapper.js");
26
26
  function _export_star(from, to) {
27
27
  Object.keys(from).forEach(function(k) {
28
28
  if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
@@ -42,5 +42,5 @@ function _interop_require_default(obj) {
42
42
  };
43
43
  }
44
44
  var major = +process.versions.node.split('.')[0];
45
- var createSession = major > 18 ? _sessionts.createSession : undefined;
45
+ var createSession = major > 18 ? _createSessionWrapperts.createSession : undefined;
46
46
  /* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }