spawn-term 3.0.3 → 3.0.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.
|
@@ -184,22 +184,25 @@ function AppContent(param) {
|
|
|
184
184
|
/*#__PURE__*/ (0, _jsxruntime.jsx)(_Dividerts.default, {})
|
|
185
185
|
]
|
|
186
186
|
}),
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
187
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(_ink.Box, {
|
|
188
|
+
flexDirection: "column",
|
|
189
|
+
children: visibleProcesses.map(function(item) {
|
|
190
|
+
var originalIndex = processes.indexOf(item);
|
|
191
|
+
return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_ink.Box, {
|
|
192
|
+
flexDirection: "column",
|
|
193
|
+
children: [
|
|
194
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(_CompactProcessLinets.default, {
|
|
195
|
+
item: item,
|
|
196
|
+
isSelected: showSelection && originalIndex === selectedIndex
|
|
197
|
+
}),
|
|
198
|
+
expandedId === item.id && /*#__PURE__*/ (0, _jsxruntime.jsx)(_ExpandedOutputts.default, {
|
|
199
|
+
lines: item.lines,
|
|
200
|
+
scrollOffset: scrollOffset
|
|
201
|
+
})
|
|
202
|
+
]
|
|
203
|
+
}, item.id);
|
|
204
|
+
})
|
|
205
|
+
}, "processes-".concat(listScrollOffset)),
|
|
203
206
|
showStatusBar && processes.length > 0 && /*#__PURE__*/ (0, _jsxruntime.jsxs)(_jsxruntime.Fragment, {
|
|
204
207
|
children: [
|
|
205
208
|
/*#__PURE__*/ (0, _jsxruntime.jsx)(_Dividerts.default, {}),
|
|
@@ -1 +1 @@
|
|
|
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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"}
|
|
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 - key forces clean re-render on scroll */}\n <Box key={`processes-${listScrollOffset}`} flexDirection=\"column\">\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 </Box>\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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"}
|
|
@@ -167,22 +167,25 @@ function AppContent({ store }) {
|
|
|
167
167
|
/*#__PURE__*/ _jsx(Divider, {})
|
|
168
168
|
]
|
|
169
169
|
}),
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
170
|
+
/*#__PURE__*/ _jsx(Box, {
|
|
171
|
+
flexDirection: "column",
|
|
172
|
+
children: visibleProcesses.map((item)=>{
|
|
173
|
+
const originalIndex = processes.indexOf(item);
|
|
174
|
+
return /*#__PURE__*/ _jsxs(Box, {
|
|
175
|
+
flexDirection: "column",
|
|
176
|
+
children: [
|
|
177
|
+
/*#__PURE__*/ _jsx(CompactProcessLine, {
|
|
178
|
+
item: item,
|
|
179
|
+
isSelected: showSelection && originalIndex === selectedIndex
|
|
180
|
+
}),
|
|
181
|
+
expandedId === item.id && /*#__PURE__*/ _jsx(ExpandedOutput, {
|
|
182
|
+
lines: item.lines,
|
|
183
|
+
scrollOffset: scrollOffset
|
|
184
|
+
})
|
|
185
|
+
]
|
|
186
|
+
}, item.id);
|
|
187
|
+
})
|
|
188
|
+
}, `processes-${listScrollOffset}`),
|
|
186
189
|
showStatusBar && processes.length > 0 && /*#__PURE__*/ _jsxs(_Fragment, {
|
|
187
190
|
children: [
|
|
188
191
|
/*#__PURE__*/ _jsx(Divider, {}),
|
|
@@ -1 +1 @@
|
|
|
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":["Box","Text","useApp","useInput","useStdin","useStdout","useEffect","useMemo","useSyncExternalStore","EXPANDED_MAX_VISIBLE_LINES","StoreContext","CompactProcessLine","Divider","ErrorDetailModal","ErrorListModal","ExpandedOutput","StatusBar","AppContent","store","exit","isRawModeSupported","stdout","terminalHeight","rows","processes","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","setMode","input","key","escape","collapse","signalExit","return","toggleExpand","downArrow","scrollDown","selectNext","upArrow","scrollUp","selectPrev","selectNextError","selectPrevError","isActive","visibleProcesses","slice","errors","totalErrorLines","selectedError","getSelectedError","error","currentIndex","totalErrors","length","showSelection","flexDirection","map","item","originalIndex","indexOf","isSelected","id","lines","running","done","errorLines","App","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 - key forces clean re-render on scroll */}\n <Box key={`processes-${listScrollOffset}`} flexDirection=\"column\">\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 </Box>\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":["Box","Text","useApp","useInput","useStdin","useStdout","useEffect","useMemo","useSyncExternalStore","EXPANDED_MAX_VISIBLE_LINES","StoreContext","CompactProcessLine","Divider","ErrorDetailModal","ErrorListModal","ExpandedOutput","StatusBar","AppContent","store","exit","isRawModeSupported","stdout","terminalHeight","rows","processes","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","setMode","input","key","escape","collapse","signalExit","return","toggleExpand","downArrow","scrollDown","selectNext","upArrow","scrollUp","selectPrev","selectNextError","selectPrevError","isActive","visibleProcesses","slice","errors","totalErrorLines","selectedError","getSelectedError","error","currentIndex","totalErrors","length","showSelection","flexDirection","map","item","originalIndex","indexOf","isSelected","id","lines","running","done","errorLines","App","Provider","value"],"mappings":"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"}
|