spawn-term 1.1.8 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/App.js +159 -9
- package/dist/cjs/components/App.js.map +1 -1
- package/dist/cjs/components/CompactProcessLine.js +162 -0
- package/dist/cjs/components/CompactProcessLine.js.map +1 -0
- package/dist/cjs/components/Divider.js +24 -0
- package/dist/cjs/components/Divider.js.map +1 -0
- package/dist/cjs/components/ErrorDetailModal.js +115 -0
- package/dist/cjs/components/ErrorDetailModal.js.map +1 -0
- package/dist/cjs/components/ErrorListModal.js +135 -0
- package/dist/cjs/components/ErrorListModal.js.map +1 -0
- package/dist/cjs/components/ExpandedOutput.js +55 -0
- package/dist/cjs/components/ExpandedOutput.js.map +1 -0
- package/dist/cjs/components/StatusBar.js +104 -0
- package/dist/cjs/components/StatusBar.js.map +1 -0
- package/dist/cjs/constants.js +42 -0
- package/dist/cjs/constants.js.map +1 -0
- package/dist/cjs/createApp.js +7 -2
- package/dist/cjs/createApp.js.map +1 -1
- package/dist/cjs/lib/addLines.js +58 -4
- package/dist/cjs/lib/addLines.js.map +1 -1
- package/dist/cjs/lib/format.js +21 -0
- package/dist/cjs/lib/format.js.map +1 -0
- package/dist/cjs/src/components/CompactProcessLine.d.ts +7 -0
- package/dist/cjs/src/components/Divider.d.ts +2 -0
- package/dist/cjs/src/components/ErrorDetailModal.d.ts +8 -0
- package/dist/cjs/src/components/ErrorListModal.d.ts +8 -0
- package/dist/cjs/src/components/ExpandedOutput.d.ts +8 -0
- package/dist/cjs/src/components/StatusBar.d.ts +8 -0
- package/dist/cjs/src/constants.d.ts +7 -0
- package/dist/cjs/src/lib/addLines.d.ts +6 -1
- package/dist/cjs/src/lib/format.d.ts +2 -0
- package/dist/cjs/src/state/processStore.d.ts +36 -0
- package/dist/cjs/src/types.d.ts +6 -0
- package/dist/cjs/state/processStore.js +202 -0
- package/dist/cjs/state/processStore.js.map +1 -1
- package/dist/cjs/types.js.map +1 -1
- package/dist/esm/components/App.js +159 -9
- package/dist/esm/components/App.js.map +1 -1
- package/dist/esm/components/CompactProcessLine.js +143 -0
- package/dist/esm/components/CompactProcessLine.js.map +1 -0
- package/dist/esm/components/Divider.js +13 -0
- package/dist/esm/components/Divider.js.map +1 -0
- package/dist/esm/components/ErrorDetailModal.js +99 -0
- package/dist/esm/components/ErrorDetailModal.js.map +1 -0
- package/dist/esm/components/ErrorListModal.js +116 -0
- package/dist/esm/components/ErrorListModal.js.map +1 -0
- package/dist/esm/components/ExpandedOutput.js +41 -0
- package/dist/esm/components/ExpandedOutput.js.map +1 -0
- package/dist/esm/components/StatusBar.js +87 -0
- package/dist/esm/components/StatusBar.js.map +1 -0
- package/dist/esm/constants.js +11 -0
- package/dist/esm/constants.js.map +1 -0
- package/dist/esm/createApp.js +7 -2
- package/dist/esm/createApp.js.map +1 -1
- package/dist/esm/lib/addLines.js +32 -5
- package/dist/esm/lib/addLines.js.map +1 -1
- package/dist/esm/lib/format.js +10 -0
- package/dist/esm/lib/format.js.map +1 -0
- package/dist/esm/src/components/CompactProcessLine.d.ts +7 -0
- package/dist/esm/src/components/Divider.d.ts +2 -0
- package/dist/esm/src/components/ErrorDetailModal.d.ts +8 -0
- package/dist/esm/src/components/ErrorListModal.d.ts +8 -0
- package/dist/esm/src/components/ExpandedOutput.d.ts +8 -0
- package/dist/esm/src/components/StatusBar.d.ts +8 -0
- package/dist/esm/src/constants.d.ts +7 -0
- package/dist/esm/src/lib/addLines.d.ts +6 -1
- package/dist/esm/src/lib/format.d.ts +2 -0
- package/dist/esm/src/state/processStore.d.ts +36 -0
- package/dist/esm/src/types.d.ts +6 -0
- package/dist/esm/state/processStore.js +146 -0
- package/dist/esm/state/processStore.js.map +1 -1
- package/dist/esm/types.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,16 +1,52 @@
|
|
|
1
1
|
import type { ChildProcess, Line } from '../types.js';
|
|
2
2
|
type Listener = () => void;
|
|
3
|
+
type Mode = 'normal' | 'interactive' | 'errorList' | 'errorDetail';
|
|
3
4
|
declare class ProcessStore {
|
|
4
5
|
private processes;
|
|
6
|
+
private completedIds;
|
|
5
7
|
private listeners;
|
|
6
8
|
private shouldExit;
|
|
7
9
|
private exitCallback;
|
|
10
|
+
private mode;
|
|
11
|
+
private selectedIndex;
|
|
12
|
+
private selectedErrorIndex;
|
|
13
|
+
private expandedId;
|
|
14
|
+
private scrollOffset;
|
|
15
|
+
private header;
|
|
8
16
|
subscribe: (listener: Listener) => (() => void);
|
|
9
17
|
getSnapshot: () => ChildProcess[];
|
|
18
|
+
getRunningProcesses: () => ChildProcess[];
|
|
19
|
+
getCompletedProcesses: () => ChildProcess[];
|
|
20
|
+
getFailedProcesses: () => ChildProcess[];
|
|
21
|
+
getRunningCount: () => number;
|
|
22
|
+
getMaxGroupLength: () => number;
|
|
23
|
+
getDoneCount: () => number;
|
|
24
|
+
getErrorCount: () => number;
|
|
25
|
+
getErrorLineCount: () => number;
|
|
26
|
+
getMode: () => Mode;
|
|
27
|
+
getSelectedIndex: () => number;
|
|
28
|
+
getSelectedErrorIndex: () => number;
|
|
29
|
+
getExpandedId: () => string | null;
|
|
30
|
+
getScrollOffset: () => number;
|
|
31
|
+
getHeader: () => string | undefined;
|
|
32
|
+
getShowStatusBar: () => boolean;
|
|
33
|
+
getIsInteractive: () => boolean;
|
|
34
|
+
isAllComplete: () => boolean;
|
|
10
35
|
addProcess(process: ChildProcess): void;
|
|
11
36
|
updateProcess(id: string, update: Partial<ChildProcess>): void;
|
|
12
37
|
appendLines(id: string, newLines: Line[]): void;
|
|
13
38
|
getProcess(id: string): ChildProcess | undefined;
|
|
39
|
+
setMode(mode: Mode): void;
|
|
40
|
+
selectNext(): void;
|
|
41
|
+
selectPrev(): void;
|
|
42
|
+
getSelectedProcess(): ChildProcess | undefined;
|
|
43
|
+
selectNextError(): void;
|
|
44
|
+
selectPrevError(): void;
|
|
45
|
+
getSelectedError(): ChildProcess | undefined;
|
|
46
|
+
toggleExpand(): void;
|
|
47
|
+
collapse(): void;
|
|
48
|
+
scrollDown(maxVisible: number): void;
|
|
49
|
+
scrollUp(): void;
|
|
14
50
|
signalExit(callback: () => void): void;
|
|
15
51
|
getShouldExit: () => boolean;
|
|
16
52
|
getExitCallback: () => (() => void) | null;
|
package/dist/cjs/src/types.d.ts
CHANGED
|
@@ -3,6 +3,9 @@ import type { SpawnError, SpawnResult } from 'cross-spawn-cb';
|
|
|
3
3
|
export type TerminalOptions = {
|
|
4
4
|
group?: string;
|
|
5
5
|
expanded?: boolean;
|
|
6
|
+
header?: string;
|
|
7
|
+
showStatusBar?: boolean;
|
|
8
|
+
interactive?: boolean;
|
|
6
9
|
};
|
|
7
10
|
export type TerminalCallback = (error?: SpawnError, result?: SpawnResult) => undefined;
|
|
8
11
|
export declare const LineType: {
|
|
@@ -21,4 +24,7 @@ export type ChildProcess = {
|
|
|
21
24
|
state: State;
|
|
22
25
|
lines: Line[];
|
|
23
26
|
expanded?: boolean;
|
|
27
|
+
header?: string;
|
|
28
|
+
showStatusBar?: boolean;
|
|
29
|
+
interactive?: boolean;
|
|
24
30
|
};
|
|
@@ -8,6 +8,8 @@ Object.defineProperty(exports, "processStore", {
|
|
|
8
8
|
return processStore;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
+
var _constantsts = require("../constants.js");
|
|
12
|
+
var _typests = require("../types.js");
|
|
11
13
|
function _array_like_to_array(arr, len) {
|
|
12
14
|
if (len == null || len > arr.length) len = arr.length;
|
|
13
15
|
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
@@ -72,9 +74,16 @@ var ProcessStore = /*#__PURE__*/ function() {
|
|
|
72
74
|
var _this = this;
|
|
73
75
|
_class_call_check(this, ProcessStore);
|
|
74
76
|
this.processes = [];
|
|
77
|
+
this.completedIds = []; // Track completion order
|
|
75
78
|
this.listeners = new Set();
|
|
76
79
|
this.shouldExit = false;
|
|
77
80
|
this.exitCallback = null;
|
|
81
|
+
// UI state
|
|
82
|
+
this.mode = 'normal';
|
|
83
|
+
this.selectedIndex = 0;
|
|
84
|
+
this.selectedErrorIndex = 0;
|
|
85
|
+
this.expandedId = null;
|
|
86
|
+
this.scrollOffset = 0;
|
|
78
87
|
// useSyncExternalStore API
|
|
79
88
|
this.subscribe = function(listener) {
|
|
80
89
|
_this.listeners.add(listener);
|
|
@@ -85,6 +94,96 @@ var ProcessStore = /*#__PURE__*/ function() {
|
|
|
85
94
|
this.getSnapshot = function() {
|
|
86
95
|
return _this.processes;
|
|
87
96
|
};
|
|
97
|
+
// Filtered getters
|
|
98
|
+
this.getRunningProcesses = function() {
|
|
99
|
+
return _this.processes.filter(function(p) {
|
|
100
|
+
return p.state === 'running';
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
this.getCompletedProcesses = function() {
|
|
104
|
+
// Return in completion order
|
|
105
|
+
return _this.completedIds.map(function(id) {
|
|
106
|
+
return _this.processes.find(function(p) {
|
|
107
|
+
return p.id === id;
|
|
108
|
+
});
|
|
109
|
+
}).filter(function(p) {
|
|
110
|
+
return p !== undefined;
|
|
111
|
+
});
|
|
112
|
+
};
|
|
113
|
+
this.getFailedProcesses = function() {
|
|
114
|
+
return _this.processes.filter(function(p) {
|
|
115
|
+
return p.state === 'error';
|
|
116
|
+
});
|
|
117
|
+
};
|
|
118
|
+
// Counts
|
|
119
|
+
this.getRunningCount = function() {
|
|
120
|
+
return _this.processes.filter(function(p) {
|
|
121
|
+
return p.state === 'running';
|
|
122
|
+
}).length;
|
|
123
|
+
};
|
|
124
|
+
this.getMaxGroupLength = function() {
|
|
125
|
+
var _Math;
|
|
126
|
+
if (_this.processes.length === 0) return _constantsts.DEFAULT_COLUMN_WIDTH;
|
|
127
|
+
return (_Math = Math).max.apply(_Math, _to_consumable_array(_this.processes.map(function(p) {
|
|
128
|
+
return (p.group || p.title).length;
|
|
129
|
+
})));
|
|
130
|
+
};
|
|
131
|
+
this.getDoneCount = function() {
|
|
132
|
+
return _this.processes.filter(function(p) {
|
|
133
|
+
return p.state !== 'running';
|
|
134
|
+
}).length;
|
|
135
|
+
};
|
|
136
|
+
this.getErrorCount = function() {
|
|
137
|
+
return _this.processes.filter(function(p) {
|
|
138
|
+
return p.state === 'error';
|
|
139
|
+
}).length;
|
|
140
|
+
};
|
|
141
|
+
this.getErrorLineCount = function() {
|
|
142
|
+
return _this.processes.filter(function(p) {
|
|
143
|
+
return p.state === 'error';
|
|
144
|
+
}).reduce(function(total, p) {
|
|
145
|
+
return total + p.lines.filter(function(l) {
|
|
146
|
+
return l.type === _typests.LineType.stderr;
|
|
147
|
+
}).length;
|
|
148
|
+
}, 0);
|
|
149
|
+
};
|
|
150
|
+
// UI state getters
|
|
151
|
+
this.getMode = function() {
|
|
152
|
+
return _this.mode;
|
|
153
|
+
};
|
|
154
|
+
this.getSelectedIndex = function() {
|
|
155
|
+
return _this.selectedIndex;
|
|
156
|
+
};
|
|
157
|
+
this.getSelectedErrorIndex = function() {
|
|
158
|
+
return _this.selectedErrorIndex;
|
|
159
|
+
};
|
|
160
|
+
this.getExpandedId = function() {
|
|
161
|
+
return _this.expandedId;
|
|
162
|
+
};
|
|
163
|
+
this.getScrollOffset = function() {
|
|
164
|
+
return _this.scrollOffset;
|
|
165
|
+
};
|
|
166
|
+
// Get header
|
|
167
|
+
this.getHeader = function() {
|
|
168
|
+
return _this.header;
|
|
169
|
+
};
|
|
170
|
+
// Show status bar only if any process sets showStatusBar: true (default: false)
|
|
171
|
+
this.getShowStatusBar = function() {
|
|
172
|
+
return _this.processes.some(function(p) {
|
|
173
|
+
return p.showStatusBar === true;
|
|
174
|
+
});
|
|
175
|
+
};
|
|
176
|
+
// Interactive mode if any process has interactive: true
|
|
177
|
+
this.getIsInteractive = function() {
|
|
178
|
+
return _this.processes.some(function(p) {
|
|
179
|
+
return p.interactive === true;
|
|
180
|
+
});
|
|
181
|
+
};
|
|
182
|
+
this.isAllComplete = function() {
|
|
183
|
+
return _this.processes.length > 0 && _this.processes.every(function(p) {
|
|
184
|
+
return p.state !== 'running';
|
|
185
|
+
});
|
|
186
|
+
};
|
|
88
187
|
this.getShouldExit = function() {
|
|
89
188
|
return _this.shouldExit;
|
|
90
189
|
};
|
|
@@ -95,15 +194,30 @@ var ProcessStore = /*#__PURE__*/ function() {
|
|
|
95
194
|
var _proto = ProcessStore.prototype;
|
|
96
195
|
// Mutations - Ink handles render throttling at 30 FPS
|
|
97
196
|
_proto.addProcess = function addProcess(process) {
|
|
197
|
+
// Set header on first process that provides one
|
|
198
|
+
if (this.header === undefined && process.header !== undefined) {
|
|
199
|
+
this.header = process.header;
|
|
200
|
+
}
|
|
98
201
|
this.processes = _to_consumable_array(this.processes).concat([
|
|
99
202
|
process
|
|
100
203
|
]);
|
|
101
204
|
this.notify();
|
|
102
205
|
};
|
|
103
206
|
_proto.updateProcess = function updateProcess(id, update) {
|
|
207
|
+
var oldProcess = this.processes.find(function(p) {
|
|
208
|
+
return p.id === id;
|
|
209
|
+
});
|
|
210
|
+
var wasRunning = (oldProcess === null || oldProcess === void 0 ? void 0 : oldProcess.state) === 'running';
|
|
211
|
+
var isNowComplete = update.state && update.state !== 'running';
|
|
104
212
|
this.processes = this.processes.map(function(p) {
|
|
105
213
|
return p.id === id ? _object_spread({}, p, update) : p;
|
|
106
214
|
});
|
|
215
|
+
// Track completion order
|
|
216
|
+
if (wasRunning && isNowComplete && !this.completedIds.includes(id)) {
|
|
217
|
+
this.completedIds = _to_consumable_array(this.completedIds).concat([
|
|
218
|
+
id
|
|
219
|
+
]);
|
|
220
|
+
}
|
|
107
221
|
this.notify();
|
|
108
222
|
};
|
|
109
223
|
_proto.appendLines = function appendLines(id, newLines) {
|
|
@@ -121,6 +235,87 @@ var ProcessStore = /*#__PURE__*/ function() {
|
|
|
121
235
|
return p.id === id;
|
|
122
236
|
});
|
|
123
237
|
};
|
|
238
|
+
// UI state mutations
|
|
239
|
+
_proto.setMode = function setMode(mode) {
|
|
240
|
+
this.mode = mode;
|
|
241
|
+
if (mode === 'interactive') {
|
|
242
|
+
this.selectedIndex = 0;
|
|
243
|
+
} else if (mode === 'errorList') {
|
|
244
|
+
this.selectedErrorIndex = 0;
|
|
245
|
+
}
|
|
246
|
+
this.notify();
|
|
247
|
+
};
|
|
248
|
+
// Interactive mode navigation
|
|
249
|
+
_proto.selectNext = function selectNext() {
|
|
250
|
+
if (this.processes.length > 0) {
|
|
251
|
+
this.selectedIndex = (this.selectedIndex + 1) % this.processes.length;
|
|
252
|
+
this.notify();
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
_proto.selectPrev = function selectPrev() {
|
|
256
|
+
if (this.processes.length > 0) {
|
|
257
|
+
this.selectedIndex = (this.selectedIndex - 1 + this.processes.length) % this.processes.length;
|
|
258
|
+
this.notify();
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
_proto.getSelectedProcess = function getSelectedProcess() {
|
|
262
|
+
return this.processes[this.selectedIndex];
|
|
263
|
+
};
|
|
264
|
+
_proto.selectNextError = function selectNextError() {
|
|
265
|
+
var failed = this.getFailedProcesses();
|
|
266
|
+
if (failed.length > 0) {
|
|
267
|
+
this.selectedErrorIndex = (this.selectedErrorIndex + 1) % failed.length;
|
|
268
|
+
this.notify();
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
_proto.selectPrevError = function selectPrevError() {
|
|
272
|
+
var failed = this.getFailedProcesses();
|
|
273
|
+
if (failed.length > 0) {
|
|
274
|
+
this.selectedErrorIndex = (this.selectedErrorIndex - 1 + failed.length) % failed.length;
|
|
275
|
+
this.notify();
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
_proto.getSelectedError = function getSelectedError() {
|
|
279
|
+
var failed = this.getFailedProcesses();
|
|
280
|
+
return failed[this.selectedErrorIndex];
|
|
281
|
+
};
|
|
282
|
+
// Expansion methods
|
|
283
|
+
_proto.toggleExpand = function toggleExpand() {
|
|
284
|
+
var selected = this.getSelectedProcess();
|
|
285
|
+
if (!selected) return;
|
|
286
|
+
if (this.expandedId === selected.id) {
|
|
287
|
+
// Collapse
|
|
288
|
+
this.expandedId = null;
|
|
289
|
+
this.scrollOffset = 0;
|
|
290
|
+
} else {
|
|
291
|
+
// Expand
|
|
292
|
+
this.expandedId = selected.id;
|
|
293
|
+
this.scrollOffset = 0;
|
|
294
|
+
}
|
|
295
|
+
this.notify();
|
|
296
|
+
};
|
|
297
|
+
_proto.collapse = function collapse() {
|
|
298
|
+
this.expandedId = null;
|
|
299
|
+
this.scrollOffset = 0;
|
|
300
|
+
this.notify();
|
|
301
|
+
};
|
|
302
|
+
_proto.scrollDown = function scrollDown(maxVisible) {
|
|
303
|
+
if (!this.expandedId) return;
|
|
304
|
+
var process = this.getProcess(this.expandedId);
|
|
305
|
+
if (!process) return;
|
|
306
|
+
var maxOffset = Math.max(0, process.lines.length - maxVisible);
|
|
307
|
+
if (this.scrollOffset < maxOffset) {
|
|
308
|
+
this.scrollOffset++;
|
|
309
|
+
this.notify();
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
_proto.scrollUp = function scrollUp() {
|
|
313
|
+
if (!this.expandedId) return;
|
|
314
|
+
if (this.scrollOffset > 0) {
|
|
315
|
+
this.scrollOffset--;
|
|
316
|
+
this.notify();
|
|
317
|
+
}
|
|
318
|
+
};
|
|
124
319
|
// Exit signaling
|
|
125
320
|
_proto.signalExit = function signalExit(callback) {
|
|
126
321
|
this.shouldExit = true;
|
|
@@ -129,8 +324,15 @@ var ProcessStore = /*#__PURE__*/ function() {
|
|
|
129
324
|
};
|
|
130
325
|
_proto.reset = function reset() {
|
|
131
326
|
this.processes = [];
|
|
327
|
+
this.completedIds = [];
|
|
132
328
|
this.shouldExit = false;
|
|
133
329
|
this.exitCallback = null;
|
|
330
|
+
this.mode = 'normal';
|
|
331
|
+
this.selectedIndex = 0;
|
|
332
|
+
this.selectedErrorIndex = 0;
|
|
333
|
+
this.expandedId = null;
|
|
334
|
+
this.scrollOffset = 0;
|
|
335
|
+
this.header = undefined;
|
|
134
336
|
};
|
|
135
337
|
_proto.notify = function notify() {
|
|
136
338
|
this.listeners.forEach(function(l) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/state/processStore.ts"],"sourcesContent":["import type { ChildProcess, Line } from '../types.ts';\n\ntype Listener = () => void;\n\nclass ProcessStore {\n private processes: ChildProcess[] = [];\n private listeners = new Set<Listener>();\n private shouldExit = false;\n private exitCallback: (() => void) | null = null;\n\n // useSyncExternalStore API\n subscribe = (listener: Listener): (() => void) => {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n };\n\n getSnapshot = (): ChildProcess[] => this.processes;\n\n // Mutations - Ink handles render throttling at 30 FPS\n addProcess(process: ChildProcess): void {\n this.processes = [...this.processes, process];\n this.notify();\n }\n\n updateProcess(id: string, update: Partial<ChildProcess>): void {\n this.processes = this.processes.map((p) => (p.id === id ? { ...p, ...update } : p));\n this.notify();\n }\n\n appendLines(id: string, newLines: Line[]): void {\n const process = this.processes.find((p) => p.id === id);\n if (process) {\n this.updateProcess(id, { lines: process.lines.concat(newLines) });\n }\n }\n\n getProcess(id: string): ChildProcess | undefined {\n return this.processes.find((p) => p.id === id);\n }\n\n // Exit signaling\n signalExit(callback: () => void): void {\n this.shouldExit = true;\n this.exitCallback = callback;\n this.notify();\n }\n\n getShouldExit = (): boolean => this.shouldExit;\n getExitCallback = (): (() => void) | null => this.exitCallback;\n\n reset(): void {\n this.processes = [];\n this.shouldExit = false;\n this.exitCallback = null;\n }\n\n private notify(): void {\n this.listeners.forEach((l) => {\n l();\n });\n }\n}\n\nexport const processStore = new ProcessStore();\nexport type { ProcessStore };\n"],"names":["processStore","ProcessStore","processes","listeners","Set","shouldExit","exitCallback","subscribe","listener","add","delete","getSnapshot","getShouldExit","getExitCallback","addProcess","process","notify","updateProcess","id","update","map","p","appendLines","newLines","find","lines","concat","getProcess","signalExit","callback","reset","forEach","l"],"mappings":";;;;+BA+DaA;;;eAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA3Db,IAAA,AAAMC,6BAAN;;aAAMA;;gCAAAA;aACIC,YAA4B,EAAE;aAC9BC,YAAY,IAAIC;aAChBC,aAAa;aACbC,eAAoC;QAE5C,2BAA2B;aAC3BC,YAAY,SAACC;YACX,MAAKL,SAAS,CAACM,GAAG,CAACD;YACnB,OAAO;uBAAM,MAAKL,SAAS,CAACO,MAAM,CAACF;;QACrC;aAEAG,cAAc;mBAAsB,MAAKT,SAAS;;aA+BlDU,gBAAgB;mBAAe,MAAKP,UAAU;;aAC9CQ,kBAAkB;mBAA2B,MAAKP,YAAY;;;iBA5C1DL;IAcJ,sDAAsD;IACtDa,OAAAA,UAGC,GAHDA,SAAAA,WAAWC,OAAqB;QAC9B,IAAI,CAACb,SAAS,GAAG,AAAC,qBAAG,IAAI,CAACA,SAAS,SAAlB;YAAoBa;SAAQ;QAC7C,IAAI,CAACC,MAAM;IACb;IAEAC,OAAAA,aAGC,GAHDA,SAAAA,cAAcC,EAAU,EAAEC,MAA6B;QACrD,IAAI,CAACjB,SAAS,GAAG,IAAI,CAACA,SAAS,CAACkB,GAAG,CAAC,SAACC;mBAAOA,EAAEH,EAAE,KAAKA,KAAK,mBAAKG,GAAMF,UAAWE;;QAChF,IAAI,CAACL,MAAM;IACb;IAEAM,OAAAA,WAKC,GALDA,SAAAA,YAAYJ,EAAU,EAAEK,QAAgB;QACtC,IAAMR,UAAU,IAAI,CAACb,SAAS,CAACsB,IAAI,CAAC,SAACH;mBAAMA,EAAEH,EAAE,KAAKA;;QACpD,IAAIH,SAAS;YACX,IAAI,CAACE,aAAa,CAACC,IAAI;gBAAEO,OAAOV,QAAQU,KAAK,CAACC,MAAM,CAACH;YAAU;QACjE;IACF;IAEAI,OAAAA,UAEC,GAFDA,SAAAA,WAAWT,EAAU;QACnB,OAAO,IAAI,CAAChB,SAAS,CAACsB,IAAI,CAAC,SAACH;mBAAMA,EAAEH,EAAE,KAAKA;;IAC7C;IAEA,iBAAiB;IACjBU,OAAAA,UAIC,GAJDA,SAAAA,WAAWC,QAAoB;QAC7B,IAAI,CAACxB,UAAU,GAAG;QAClB,IAAI,CAACC,YAAY,GAAGuB;QACpB,IAAI,CAACb,MAAM;IACb;IAKAc,OAAAA,KAIC,GAJDA,SAAAA;QACE,IAAI,CAAC5B,SAAS,GAAG,EAAE;QACnB,IAAI,CAACG,UAAU,GAAG;QAClB,IAAI,CAACC,YAAY,GAAG;IACtB;IAEA,OAAQU,MAIP,GAJD,SAAQA;QACN,IAAI,CAACb,SAAS,CAAC4B,OAAO,CAAC,SAACC;YACtBA;QACF;IACF;WAxDI/B;;AA2DC,IAAMD,eAAe,IAAIC"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/state/processStore.ts"],"sourcesContent":["import { DEFAULT_COLUMN_WIDTH } from '../constants.ts';\nimport type { ChildProcess, Line } from '../types.ts';\nimport { LineType } from '../types.ts';\n\ntype Listener = () => void;\ntype Mode = 'normal' | 'interactive' | 'errorList' | 'errorDetail';\n\nclass ProcessStore {\n private processes: ChildProcess[] = [];\n private completedIds: string[] = []; // Track completion order\n private listeners = new Set<Listener>();\n private shouldExit = false;\n private exitCallback: (() => void) | null = null;\n\n // UI state\n private mode: Mode = 'normal';\n private selectedIndex = 0;\n private selectedErrorIndex = 0;\n private expandedId: string | null = null;\n private scrollOffset = 0;\n\n // App-level display settings\n private header: string | undefined;\n\n // useSyncExternalStore API\n subscribe = (listener: Listener): (() => void) => {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n };\n\n getSnapshot = (): ChildProcess[] => this.processes;\n\n // Filtered getters\n getRunningProcesses = (): ChildProcess[] => {\n return this.processes.filter((p) => p.state === 'running');\n };\n\n getCompletedProcesses = (): ChildProcess[] => {\n // Return in completion order\n return this.completedIds.map((id) => this.processes.find((p) => p.id === id)).filter((p): p is ChildProcess => p !== undefined);\n };\n\n getFailedProcesses = (): ChildProcess[] => {\n return this.processes.filter((p) => p.state === 'error');\n };\n\n // Counts\n getRunningCount = (): number => this.processes.filter((p) => p.state === 'running').length;\n getMaxGroupLength = (): number => {\n if (this.processes.length === 0) return DEFAULT_COLUMN_WIDTH;\n return Math.max(...this.processes.map((p) => (p.group || p.title).length));\n };\n getDoneCount = (): number => this.processes.filter((p) => p.state !== 'running').length;\n getErrorCount = (): number => this.processes.filter((p) => p.state === 'error').length;\n getErrorLineCount = (): number => {\n return this.processes.filter((p) => p.state === 'error').reduce((total, p) => total + p.lines.filter((l) => l.type === LineType.stderr).length, 0);\n };\n\n // UI state getters\n getMode = (): Mode => this.mode;\n getSelectedIndex = (): number => this.selectedIndex;\n getSelectedErrorIndex = (): number => this.selectedErrorIndex;\n getExpandedId = (): string | null => this.expandedId;\n getScrollOffset = (): number => this.scrollOffset;\n // Get header\n getHeader = (): string | undefined => this.header;\n // Show status bar only if any process sets showStatusBar: true (default: false)\n getShowStatusBar = (): boolean => this.processes.some((p) => p.showStatusBar === true);\n // Interactive mode if any process has interactive: true\n getIsInteractive = (): boolean => this.processes.some((p) => p.interactive === true);\n isAllComplete = (): boolean => this.processes.length > 0 && this.processes.every((p) => p.state !== 'running');\n\n // Mutations - Ink handles render throttling at 30 FPS\n addProcess(process: ChildProcess): void {\n // Set header on first process that provides one\n if (this.header === undefined && process.header !== undefined) {\n this.header = process.header;\n }\n this.processes = [...this.processes, process];\n this.notify();\n }\n\n updateProcess(id: string, update: Partial<ChildProcess>): void {\n const oldProcess = this.processes.find((p) => p.id === id);\n const wasRunning = oldProcess?.state === 'running';\n const isNowComplete = update.state && update.state !== 'running';\n\n this.processes = this.processes.map((p) => (p.id === id ? { ...p, ...update } : p));\n\n // Track completion order\n if (wasRunning && isNowComplete && !this.completedIds.includes(id)) {\n this.completedIds = [...this.completedIds, id];\n }\n\n this.notify();\n }\n\n appendLines(id: string, newLines: Line[]): void {\n const process = this.processes.find((p) => p.id === id);\n if (process) {\n this.updateProcess(id, { lines: process.lines.concat(newLines) });\n }\n }\n\n getProcess(id: string): ChildProcess | undefined {\n return this.processes.find((p) => p.id === id);\n }\n\n // UI state mutations\n setMode(mode: Mode): void {\n this.mode = mode;\n if (mode === 'interactive') {\n this.selectedIndex = 0;\n } else if (mode === 'errorList') {\n this.selectedErrorIndex = 0;\n }\n this.notify();\n }\n\n // Interactive mode navigation\n selectNext(): void {\n if (this.processes.length > 0) {\n this.selectedIndex = (this.selectedIndex + 1) % this.processes.length;\n this.notify();\n }\n }\n\n selectPrev(): void {\n if (this.processes.length > 0) {\n this.selectedIndex = (this.selectedIndex - 1 + this.processes.length) % this.processes.length;\n this.notify();\n }\n }\n\n getSelectedProcess(): ChildProcess | undefined {\n return this.processes[this.selectedIndex];\n }\n\n selectNextError(): void {\n const failed = this.getFailedProcesses();\n if (failed.length > 0) {\n this.selectedErrorIndex = (this.selectedErrorIndex + 1) % failed.length;\n this.notify();\n }\n }\n\n selectPrevError(): void {\n const failed = this.getFailedProcesses();\n if (failed.length > 0) {\n this.selectedErrorIndex = (this.selectedErrorIndex - 1 + failed.length) % failed.length;\n this.notify();\n }\n }\n\n getSelectedError(): ChildProcess | undefined {\n const failed = this.getFailedProcesses();\n return failed[this.selectedErrorIndex];\n }\n\n // Expansion methods\n toggleExpand(): void {\n const selected = this.getSelectedProcess();\n if (!selected) return;\n\n if (this.expandedId === selected.id) {\n // Collapse\n this.expandedId = null;\n this.scrollOffset = 0;\n } else {\n // Expand\n this.expandedId = selected.id;\n this.scrollOffset = 0;\n }\n this.notify();\n }\n\n collapse(): void {\n this.expandedId = null;\n this.scrollOffset = 0;\n this.notify();\n }\n\n scrollDown(maxVisible: number): void {\n if (!this.expandedId) return;\n const process = this.getProcess(this.expandedId);\n if (!process) return;\n\n const maxOffset = Math.max(0, process.lines.length - maxVisible);\n if (this.scrollOffset < maxOffset) {\n this.scrollOffset++;\n this.notify();\n }\n }\n\n scrollUp(): void {\n if (!this.expandedId) return;\n if (this.scrollOffset > 0) {\n this.scrollOffset--;\n this.notify();\n }\n }\n\n // Exit signaling\n signalExit(callback: () => void): void {\n this.shouldExit = true;\n this.exitCallback = callback;\n this.notify();\n }\n\n getShouldExit = (): boolean => this.shouldExit;\n getExitCallback = (): (() => void) | null => this.exitCallback;\n\n reset(): void {\n this.processes = [];\n this.completedIds = [];\n this.shouldExit = false;\n this.exitCallback = null;\n this.mode = 'normal';\n this.selectedIndex = 0;\n this.selectedErrorIndex = 0;\n this.expandedId = null;\n this.scrollOffset = 0;\n this.header = undefined;\n }\n\n private notify(): void {\n this.listeners.forEach((l) => {\n l();\n });\n }\n}\n\nexport const processStore = new ProcessStore();\nexport type { ProcessStore };\n"],"names":["processStore","ProcessStore","processes","completedIds","listeners","Set","shouldExit","exitCallback","mode","selectedIndex","selectedErrorIndex","expandedId","scrollOffset","subscribe","listener","add","delete","getSnapshot","getRunningProcesses","filter","p","state","getCompletedProcesses","map","id","find","undefined","getFailedProcesses","getRunningCount","length","getMaxGroupLength","Math","DEFAULT_COLUMN_WIDTH","max","group","title","getDoneCount","getErrorCount","getErrorLineCount","reduce","total","lines","l","type","LineType","stderr","getMode","getSelectedIndex","getSelectedErrorIndex","getExpandedId","getScrollOffset","getHeader","header","getShowStatusBar","some","showStatusBar","getIsInteractive","interactive","isAllComplete","every","getShouldExit","getExitCallback","addProcess","process","notify","updateProcess","update","oldProcess","wasRunning","isNowComplete","includes","appendLines","newLines","concat","getProcess","setMode","selectNext","selectPrev","getSelectedProcess","selectNextError","failed","selectPrevError","getSelectedError","toggleExpand","selected","collapse","scrollDown","maxVisible","maxOffset","scrollUp","signalExit","callback","reset","forEach"],"mappings":"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"}
|
package/dist/cjs/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/types.ts"],"sourcesContent":["export type { SpawnCallback, SpawnError, SpawnOptions, SpawnResult } from 'cross-spawn-cb';\n\nimport type { SpawnError, SpawnResult } from 'cross-spawn-cb';\n\nexport type TerminalOptions = {\n group?: string;\n expanded?: boolean;\n};\n\nexport type TerminalCallback = (error?: SpawnError, result?: SpawnResult) => undefined;\n\nexport const LineType = {\n stdout: 1,\n stderr: 2,\n} as const;\n\nexport type Line = {\n type: (typeof LineType)[keyof typeof LineType];\n text: string;\n};\n\nexport type State = 'running' | 'error' | 'success';\nexport type ChildProcess = {\n id: string;\n group?: string;\n title: string;\n state: State;\n lines: Line[];\n expanded?: boolean;\n};\n"],"names":["LineType","stdout","stderr"],"mappings":";;;;+
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/types.ts"],"sourcesContent":["export type { SpawnCallback, SpawnError, SpawnOptions, SpawnResult } from 'cross-spawn-cb';\n\nimport type { SpawnError, SpawnResult } from 'cross-spawn-cb';\n\nexport type TerminalOptions = {\n group?: string;\n expanded?: boolean;\n header?: string;\n showStatusBar?: boolean;\n interactive?: boolean;\n};\n\nexport type TerminalCallback = (error?: SpawnError, result?: SpawnResult) => undefined;\n\nexport const LineType = {\n stdout: 1,\n stderr: 2,\n} as const;\n\nexport type Line = {\n type: (typeof LineType)[keyof typeof LineType];\n text: string;\n};\n\nexport type State = 'running' | 'error' | 'success';\nexport type ChildProcess = {\n id: string;\n group?: string;\n title: string;\n state: State;\n lines: Line[];\n expanded?: boolean;\n header?: string;\n showStatusBar?: boolean;\n interactive?: boolean;\n};\n"],"names":["LineType","stdout","stderr"],"mappings":";;;;+BAcaA;;;eAAAA;;;AAAN,IAAMA,WAAW;IACtBC,QAAQ;IACRC,QAAQ;AACV"}
|
|
@@ -1,14 +1,36 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Box, useApp } from 'ink';
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text, useApp, useInput, useStdin } from 'ink';
|
|
3
3
|
import { useEffect, useSyncExternalStore } from 'react';
|
|
4
|
+
import { EXPANDED_MAX_VISIBLE_LINES } from '../constants.js';
|
|
4
5
|
import { processStore } from '../state/processStore.js';
|
|
5
|
-
import
|
|
6
|
+
import CompactProcessLine from './CompactProcessLine.js';
|
|
7
|
+
import Divider from './Divider.js';
|
|
8
|
+
import ErrorDetailModal from './ErrorDetailModal.js';
|
|
9
|
+
import ErrorListModal from './ErrorListModal.js';
|
|
10
|
+
import ExpandedOutput from './ExpandedOutput.js';
|
|
11
|
+
import StatusBar from './StatusBar.js';
|
|
6
12
|
export default function App() {
|
|
7
13
|
const { exit } = useApp();
|
|
8
|
-
|
|
14
|
+
const { isRawModeSupported } = useStdin();
|
|
15
|
+
// Subscribe to store state
|
|
9
16
|
const processes = useSyncExternalStore(processStore.subscribe, processStore.getSnapshot);
|
|
10
|
-
// Handle exit signal
|
|
11
17
|
const shouldExit = useSyncExternalStore(processStore.subscribe, processStore.getShouldExit);
|
|
18
|
+
const mode = useSyncExternalStore(processStore.subscribe, processStore.getMode);
|
|
19
|
+
const selectedIndex = useSyncExternalStore(processStore.subscribe, processStore.getSelectedIndex);
|
|
20
|
+
const selectedErrorIndex = useSyncExternalStore(processStore.subscribe, processStore.getSelectedErrorIndex);
|
|
21
|
+
const expandedId = useSyncExternalStore(processStore.subscribe, processStore.getExpandedId);
|
|
22
|
+
const scrollOffset = useSyncExternalStore(processStore.subscribe, processStore.getScrollOffset);
|
|
23
|
+
// Derived state
|
|
24
|
+
const failedProcesses = processStore.getFailedProcesses();
|
|
25
|
+
const runningCount = processStore.getRunningCount();
|
|
26
|
+
const doneCount = processStore.getDoneCount();
|
|
27
|
+
const errorCount = processStore.getErrorCount();
|
|
28
|
+
const errorLineCount = processStore.getErrorLineCount();
|
|
29
|
+
const header = processStore.getHeader();
|
|
30
|
+
const showStatusBar = processStore.getShowStatusBar();
|
|
31
|
+
const isInteractive = processStore.getIsInteractive();
|
|
32
|
+
const isAllComplete = processStore.isAllComplete();
|
|
33
|
+
// Handle exit signal
|
|
12
34
|
useEffect(()=>{
|
|
13
35
|
if (shouldExit) {
|
|
14
36
|
exit();
|
|
@@ -17,10 +39,138 @@ export default function App() {
|
|
|
17
39
|
shouldExit,
|
|
18
40
|
exit
|
|
19
41
|
]);
|
|
20
|
-
|
|
42
|
+
// Auto-enter interactive mode when all complete and interactive flag is set
|
|
43
|
+
useEffect(()=>{
|
|
44
|
+
if (isAllComplete && isInteractive && mode === 'normal') {
|
|
45
|
+
processStore.setMode('interactive');
|
|
46
|
+
}
|
|
47
|
+
}, [
|
|
48
|
+
isAllComplete,
|
|
49
|
+
isInteractive,
|
|
50
|
+
mode
|
|
51
|
+
]);
|
|
52
|
+
// Keyboard handling (only active when raw mode is supported)
|
|
53
|
+
useInput((input, key)=>{
|
|
54
|
+
if (mode === 'normal') {
|
|
55
|
+
if (input === 'e' && errorCount > 0) {
|
|
56
|
+
processStore.setMode('errorList');
|
|
57
|
+
}
|
|
58
|
+
} else if (mode === 'interactive') {
|
|
59
|
+
if (input === 'q' || key.escape) {
|
|
60
|
+
if (expandedId) {
|
|
61
|
+
processStore.collapse();
|
|
62
|
+
} else {
|
|
63
|
+
processStore.signalExit(()=>{});
|
|
64
|
+
}
|
|
65
|
+
} else if (key.return) {
|
|
66
|
+
processStore.toggleExpand();
|
|
67
|
+
} else if (key.downArrow) {
|
|
68
|
+
if (expandedId) {
|
|
69
|
+
processStore.scrollDown(EXPANDED_MAX_VISIBLE_LINES);
|
|
70
|
+
} else {
|
|
71
|
+
processStore.selectNext();
|
|
72
|
+
}
|
|
73
|
+
} else if (key.upArrow) {
|
|
74
|
+
if (expandedId) {
|
|
75
|
+
processStore.scrollUp();
|
|
76
|
+
} else {
|
|
77
|
+
processStore.selectPrev();
|
|
78
|
+
}
|
|
79
|
+
} else if (input === 'j') {
|
|
80
|
+
if (expandedId) {
|
|
81
|
+
processStore.scrollDown(EXPANDED_MAX_VISIBLE_LINES);
|
|
82
|
+
} else {
|
|
83
|
+
processStore.selectNext();
|
|
84
|
+
}
|
|
85
|
+
} else if (input === 'k') {
|
|
86
|
+
if (expandedId) {
|
|
87
|
+
processStore.scrollUp();
|
|
88
|
+
} else {
|
|
89
|
+
processStore.selectPrev();
|
|
90
|
+
}
|
|
91
|
+
} else if (input === 'e' && errorCount > 0) {
|
|
92
|
+
processStore.setMode('errorList');
|
|
93
|
+
}
|
|
94
|
+
} else if (mode === 'errorList') {
|
|
95
|
+
if (key.escape) {
|
|
96
|
+
processStore.setMode(isInteractive ? 'interactive' : 'normal');
|
|
97
|
+
} else if (key.downArrow) {
|
|
98
|
+
processStore.selectNextError();
|
|
99
|
+
} else if (key.upArrow) {
|
|
100
|
+
processStore.selectPrevError();
|
|
101
|
+
} else if (key.return) {
|
|
102
|
+
processStore.setMode('errorDetail');
|
|
103
|
+
}
|
|
104
|
+
} else if (mode === 'errorDetail') {
|
|
105
|
+
if (key.escape) {
|
|
106
|
+
processStore.setMode('errorList');
|
|
107
|
+
} else if (key.downArrow) {
|
|
108
|
+
processStore.selectNextError();
|
|
109
|
+
} else if (key.upArrow) {
|
|
110
|
+
processStore.selectPrevError();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}, {
|
|
114
|
+
isActive: isRawModeSupported === true
|
|
115
|
+
});
|
|
116
|
+
// Error list modal
|
|
117
|
+
if (mode === 'errorList') {
|
|
118
|
+
return /*#__PURE__*/ _jsx(ErrorListModal, {
|
|
119
|
+
errors: failedProcesses,
|
|
120
|
+
selectedIndex: selectedErrorIndex,
|
|
121
|
+
totalErrorLines: errorLineCount
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
// Error detail modal
|
|
125
|
+
if (mode === 'errorDetail') {
|
|
126
|
+
const selectedError = processStore.getSelectedError();
|
|
127
|
+
if (selectedError) {
|
|
128
|
+
return /*#__PURE__*/ _jsx(ErrorDetailModal, {
|
|
129
|
+
error: selectedError,
|
|
130
|
+
currentIndex: selectedErrorIndex,
|
|
131
|
+
totalErrors: failedProcesses.length
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
// Fallback if no error selected
|
|
135
|
+
processStore.setMode('errorList');
|
|
136
|
+
}
|
|
137
|
+
// Normal/Interactive view - render in original registration order
|
|
138
|
+
const showSelection = mode === 'interactive';
|
|
139
|
+
return /*#__PURE__*/ _jsxs(Box, {
|
|
21
140
|
flexDirection: "column",
|
|
22
|
-
children:
|
|
23
|
-
|
|
24
|
-
|
|
141
|
+
children: [
|
|
142
|
+
header && /*#__PURE__*/ _jsxs(_Fragment, {
|
|
143
|
+
children: [
|
|
144
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
145
|
+
children: header
|
|
146
|
+
}),
|
|
147
|
+
/*#__PURE__*/ _jsx(Divider, {})
|
|
148
|
+
]
|
|
149
|
+
}),
|
|
150
|
+
processes.map((item, index)=>/*#__PURE__*/ _jsxs(Box, {
|
|
151
|
+
flexDirection: "column",
|
|
152
|
+
children: [
|
|
153
|
+
/*#__PURE__*/ _jsx(CompactProcessLine, {
|
|
154
|
+
item: item,
|
|
155
|
+
isSelected: showSelection && index === selectedIndex
|
|
156
|
+
}),
|
|
157
|
+
expandedId === item.id && /*#__PURE__*/ _jsx(ExpandedOutput, {
|
|
158
|
+
lines: item.lines,
|
|
159
|
+
scrollOffset: scrollOffset
|
|
160
|
+
})
|
|
161
|
+
]
|
|
162
|
+
}, item.id)),
|
|
163
|
+
showStatusBar && processes.length > 0 && /*#__PURE__*/ _jsxs(_Fragment, {
|
|
164
|
+
children: [
|
|
165
|
+
/*#__PURE__*/ _jsx(Divider, {}),
|
|
166
|
+
/*#__PURE__*/ _jsx(StatusBar, {
|
|
167
|
+
running: runningCount,
|
|
168
|
+
done: doneCount,
|
|
169
|
+
errors: errorCount,
|
|
170
|
+
errorLines: errorLineCount
|
|
171
|
+
})
|
|
172
|
+
]
|
|
173
|
+
})
|
|
174
|
+
]
|
|
25
175
|
});
|
|
26
176
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/node/spawn-term/src/components/App.tsx"],"sourcesContent":["import { Box, useApp } from 'ink';\nimport { useEffect, useSyncExternalStore } from 'react';\nimport { processStore } from '../state/processStore.ts';\nimport type { ChildProcess as ChildProcessT } from '../types.ts';\nimport ChildProcess from './ChildProcess.ts';\n\nexport default function App(): React.JSX.Element {\n const { exit } = useApp();\n\n // Subscribe to process state\n const processes = useSyncExternalStore(processStore.subscribe, processStore.getSnapshot);\n\n // Handle exit signal\n const shouldExit = useSyncExternalStore(processStore.subscribe, processStore.getShouldExit);\n\n useEffect(() => {\n if (shouldExit) {\n exit();\n }\n }, [shouldExit, exit]);\n\n return (\n <Box flexDirection=\"column\">\n {processes.map((item: ChildProcessT) => (\n <ChildProcess key={item.id} item={item} />\n ))}\n </Box>\n );\n}\n"],"names":["Box","useApp","useEffect","useSyncExternalStore","processStore","ChildProcess","App","exit","processes","subscribe","getSnapshot","shouldExit","getShouldExit","flexDirection","map","item","id"],"mappings":";AAAA,SAASA,GAAG,EAAEC,MAAM,QAAQ,MAAM;AAClC,SAASC,SAAS,EAAEC,oBAAoB,QAAQ,QAAQ;AACxD,SAASC,YAAY,QAAQ,2BAA2B;AAExD,OAAOC,kBAAkB,oBAAoB;AAE7C,eAAe,SAASC;IACtB,MAAM,EAAEC,IAAI,EAAE,GAAGN;IAEjB,6BAA6B;IAC7B,MAAMO,YAAYL,qBAAqBC,aAAaK,SAAS,EAAEL,aAAaM,WAAW;IAEvF,qBAAqB;IACrB,MAAMC,aAAaR,qBAAqBC,aAAaK,SAAS,EAAEL,aAAaQ,aAAa;IAE1FV,UAAU;QACR,IAAIS,YAAY;YACdJ;QACF;IACF,GAAG;QAACI;QAAYJ;KAAK;IAErB,qBACE,KAACP;QAAIa,eAAc;kBAChBL,UAAUM,GAAG,CAAC,CAACC,qBACd,KAACV;gBAA2BU,MAAMA;eAAfA,KAAKC,EAAE;;AAIlC"}
|
|
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 { processStore } from '../state/processStore.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\nexport default function App(): React.JSX.Element {\n const { exit } = useApp();\n const { isRawModeSupported } = useStdin();\n\n // Subscribe to store state\n const processes = useSyncExternalStore(processStore.subscribe, processStore.getSnapshot);\n const shouldExit = useSyncExternalStore(processStore.subscribe, processStore.getShouldExit);\n const mode = useSyncExternalStore(processStore.subscribe, processStore.getMode);\n const selectedIndex = useSyncExternalStore(processStore.subscribe, processStore.getSelectedIndex);\n const selectedErrorIndex = useSyncExternalStore(processStore.subscribe, processStore.getSelectedErrorIndex);\n const expandedId = useSyncExternalStore(processStore.subscribe, processStore.getExpandedId);\n const scrollOffset = useSyncExternalStore(processStore.subscribe, processStore.getScrollOffset);\n\n // Derived state\n const failedProcesses = processStore.getFailedProcesses();\n const runningCount = processStore.getRunningCount();\n const doneCount = processStore.getDoneCount();\n const errorCount = processStore.getErrorCount();\n const errorLineCount = processStore.getErrorLineCount();\n const header = processStore.getHeader();\n const showStatusBar = processStore.getShowStatusBar();\n const isInteractive = processStore.getIsInteractive();\n const isAllComplete = processStore.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 processStore.setMode('interactive');\n }\n }, [isAllComplete, isInteractive, mode]);\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 processStore.setMode('errorList');\n }\n } else if (mode === 'interactive') {\n if (input === 'q' || key.escape) {\n if (expandedId) {\n processStore.collapse();\n } else {\n processStore.signalExit(() => {});\n }\n } else if (key.return) {\n processStore.toggleExpand();\n } else if (key.downArrow) {\n if (expandedId) {\n processStore.scrollDown(EXPANDED_MAX_VISIBLE_LINES);\n } else {\n processStore.selectNext();\n }\n } else if (key.upArrow) {\n if (expandedId) {\n processStore.scrollUp();\n } else {\n processStore.selectPrev();\n }\n } else if (input === 'j') {\n if (expandedId) {\n processStore.scrollDown(EXPANDED_MAX_VISIBLE_LINES);\n } else {\n processStore.selectNext();\n }\n } else if (input === 'k') {\n if (expandedId) {\n processStore.scrollUp();\n } else {\n processStore.selectPrev();\n }\n } else if (input === 'e' && errorCount > 0) {\n processStore.setMode('errorList');\n }\n } else if (mode === 'errorList') {\n if (key.escape) {\n processStore.setMode(isInteractive ? 'interactive' : 'normal');\n } else if (key.downArrow) {\n processStore.selectNextError();\n } else if (key.upArrow) {\n processStore.selectPrevError();\n } else if (key.return) {\n processStore.setMode('errorDetail');\n }\n } else if (mode === 'errorDetail') {\n if (key.escape) {\n processStore.setMode('errorList');\n } else if (key.downArrow) {\n processStore.selectNextError();\n } else if (key.upArrow) {\n processStore.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 = processStore.getSelectedError();\n if (selectedError) {\n return <ErrorDetailModal error={selectedError} currentIndex={selectedErrorIndex} totalErrors={failedProcesses.length} />;\n }\n // Fallback if no error selected\n processStore.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"],"names":["Box","Text","useApp","useInput","useStdin","useEffect","useSyncExternalStore","EXPANDED_MAX_VISIBLE_LINES","processStore","CompactProcessLine","Divider","ErrorDetailModal","ErrorListModal","ExpandedOutput","StatusBar","App","exit","isRawModeSupported","processes","subscribe","getSnapshot","shouldExit","getShouldExit","mode","getMode","selectedIndex","getSelectedIndex","selectedErrorIndex","getSelectedErrorIndex","expandedId","getExpandedId","scrollOffset","getScrollOffset","failedProcesses","getFailedProcesses","runningCount","getRunningCount","doneCount","getDoneCount","errorCount","getErrorCount","errorLineCount","getErrorLineCount","header","getHeader","showStatusBar","getShowStatusBar","isInteractive","getIsInteractive","isAllComplete","setMode","input","key","escape","collapse","signalExit","return","toggleExpand","downArrow","scrollDown","selectNext","upArrow","scrollUp","selectPrev","selectNextError","selectPrevError","isActive","errors","totalErrorLines","selectedError","getSelectedError","error","currentIndex","totalErrors","length","showSelection","flexDirection","map","item","index","isSelected","id","lines","running","done","errorLines"],"mappings":";AAAA,SAASA,GAAG,EAAEC,IAAI,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,QAAQ,QAAQ,MAAM;AAC5D,SAASC,SAAS,EAAEC,oBAAoB,QAAQ,QAAQ;AACxD,SAASC,0BAA0B,QAAQ,kBAAkB;AAC7D,SAASC,YAAY,QAAQ,2BAA2B;AACxD,OAAOC,wBAAwB,0BAA0B;AACzD,OAAOC,aAAa,eAAe;AACnC,OAAOC,sBAAsB,wBAAwB;AACrD,OAAOC,oBAAoB,sBAAsB;AACjD,OAAOC,oBAAoB,sBAAsB;AACjD,OAAOC,eAAe,iBAAiB;AAEvC,eAAe,SAASC;IACtB,MAAM,EAAEC,IAAI,EAAE,GAAGd;IACjB,MAAM,EAAEe,kBAAkB,EAAE,GAAGb;IAE/B,2BAA2B;IAC3B,MAAMc,YAAYZ,qBAAqBE,aAAaW,SAAS,EAAEX,aAAaY,WAAW;IACvF,MAAMC,aAAaf,qBAAqBE,aAAaW,SAAS,EAAEX,aAAac,aAAa;IAC1F,MAAMC,OAAOjB,qBAAqBE,aAAaW,SAAS,EAAEX,aAAagB,OAAO;IAC9E,MAAMC,gBAAgBnB,qBAAqBE,aAAaW,SAAS,EAAEX,aAAakB,gBAAgB;IAChG,MAAMC,qBAAqBrB,qBAAqBE,aAAaW,SAAS,EAAEX,aAAaoB,qBAAqB;IAC1G,MAAMC,aAAavB,qBAAqBE,aAAaW,SAAS,EAAEX,aAAasB,aAAa;IAC1F,MAAMC,eAAezB,qBAAqBE,aAAaW,SAAS,EAAEX,aAAawB,eAAe;IAE9F,gBAAgB;IAChB,MAAMC,kBAAkBzB,aAAa0B,kBAAkB;IACvD,MAAMC,eAAe3B,aAAa4B,eAAe;IACjD,MAAMC,YAAY7B,aAAa8B,YAAY;IAC3C,MAAMC,aAAa/B,aAAagC,aAAa;IAC7C,MAAMC,iBAAiBjC,aAAakC,iBAAiB;IACrD,MAAMC,SAASnC,aAAaoC,SAAS;IACrC,MAAMC,gBAAgBrC,aAAasC,gBAAgB;IACnD,MAAMC,gBAAgBvC,aAAawC,gBAAgB;IACnD,MAAMC,gBAAgBzC,aAAayC,aAAa;IAEhD,qBAAqB;IACrB5C,UAAU;QACR,IAAIgB,YAAY;YACdL;QACF;IACF,GAAG;QAACK;QAAYL;KAAK;IAErB,4EAA4E;IAC5EX,UAAU;QACR,IAAI4C,iBAAiBF,iBAAiBxB,SAAS,UAAU;YACvDf,aAAa0C,OAAO,CAAC;QACvB;IACF,GAAG;QAACD;QAAeF;QAAexB;KAAK;IAEvC,6DAA6D;IAC7DpB,SACE,CAACgD,OAAOC;QACN,IAAI7B,SAAS,UAAU;YACrB,IAAI4B,UAAU,OAAOZ,aAAa,GAAG;gBACnC/B,aAAa0C,OAAO,CAAC;YACvB;QACF,OAAO,IAAI3B,SAAS,eAAe;YACjC,IAAI4B,UAAU,OAAOC,IAAIC,MAAM,EAAE;gBAC/B,IAAIxB,YAAY;oBACdrB,aAAa8C,QAAQ;gBACvB,OAAO;oBACL9C,aAAa+C,UAAU,CAAC,KAAO;gBACjC;YACF,OAAO,IAAIH,IAAII,MAAM,EAAE;gBACrBhD,aAAaiD,YAAY;YAC3B,OAAO,IAAIL,IAAIM,SAAS,EAAE;gBACxB,IAAI7B,YAAY;oBACdrB,aAAamD,UAAU,CAACpD;gBAC1B,OAAO;oBACLC,aAAaoD,UAAU;gBACzB;YACF,OAAO,IAAIR,IAAIS,OAAO,EAAE;gBACtB,IAAIhC,YAAY;oBACdrB,aAAasD,QAAQ;gBACvB,OAAO;oBACLtD,aAAauD,UAAU;gBACzB;YACF,OAAO,IAAIZ,UAAU,KAAK;gBACxB,IAAItB,YAAY;oBACdrB,aAAamD,UAAU,CAACpD;gBAC1B,OAAO;oBACLC,aAAaoD,UAAU;gBACzB;YACF,OAAO,IAAIT,UAAU,KAAK;gBACxB,IAAItB,YAAY;oBACdrB,aAAasD,QAAQ;gBACvB,OAAO;oBACLtD,aAAauD,UAAU;gBACzB;YACF,OAAO,IAAIZ,UAAU,OAAOZ,aAAa,GAAG;gBAC1C/B,aAAa0C,OAAO,CAAC;YACvB;QACF,OAAO,IAAI3B,SAAS,aAAa;YAC/B,IAAI6B,IAAIC,MAAM,EAAE;gBACd7C,aAAa0C,OAAO,CAACH,gBAAgB,gBAAgB;YACvD,OAAO,IAAIK,IAAIM,SAAS,EAAE;gBACxBlD,aAAawD,eAAe;YAC9B,OAAO,IAAIZ,IAAIS,OAAO,EAAE;gBACtBrD,aAAayD,eAAe;YAC9B,OAAO,IAAIb,IAAII,MAAM,EAAE;gBACrBhD,aAAa0C,OAAO,CAAC;YACvB;QACF,OAAO,IAAI3B,SAAS,eAAe;YACjC,IAAI6B,IAAIC,MAAM,EAAE;gBACd7C,aAAa0C,OAAO,CAAC;YACvB,OAAO,IAAIE,IAAIM,SAAS,EAAE;gBACxBlD,aAAawD,eAAe;YAC9B,OAAO,IAAIZ,IAAIS,OAAO,EAAE;gBACtBrD,aAAayD,eAAe;YAC9B;QACF;IACF,GACA;QAAEC,UAAUjD,uBAAuB;IAAK;IAG1C,mBAAmB;IACnB,IAAIM,SAAS,aAAa;QACxB,qBAAO,KAACX;YAAeuD,QAAQlC;YAAiBR,eAAeE;YAAoByC,iBAAiB3B;;IACtG;IAEA,qBAAqB;IACrB,IAAIlB,SAAS,eAAe;QAC1B,MAAM8C,gBAAgB7D,aAAa8D,gBAAgB;QACnD,IAAID,eAAe;YACjB,qBAAO,KAAC1D;gBAAiB4D,OAAOF;gBAAeG,cAAc7C;gBAAoB8C,aAAaxC,gBAAgByC,MAAM;;QACtH;QACA,gCAAgC;QAChClE,aAAa0C,OAAO,CAAC;IACvB;IAEA,kEAAkE;IAClE,MAAMyB,gBAAgBpD,SAAS;IAC/B,qBACE,MAACvB;QAAI4E,eAAc;;YAEhBjC,wBACC;;kCACE,KAAC1C;kCAAM0C;;kCACP,KAACjC;;;YAKJQ,UAAU2D,GAAG,CAAC,CAACC,MAAMC,sBACpB,MAAC/E;oBAAkB4E,eAAc;;sCAC/B,KAACnE;4BAAmBqE,MAAMA;4BAAME,YAAYL,iBAAiBI,UAAUtD;;wBACtEI,eAAeiD,KAAKG,EAAE,kBAAI,KAACpE;4BAAeqE,OAAOJ,KAAKI,KAAK;4BAAEnD,cAAcA;;;mBAFpE+C,KAAKG,EAAE;YAOlBpC,iBAAiB3B,UAAUwD,MAAM,GAAG,mBACnC;;kCACE,KAAChE;kCACD,KAACI;wBAAUqE,SAAShD;wBAAciD,MAAM/C;wBAAW8B,QAAQ5B;wBAAY8C,YAAY5C;;;;;;AAK7F"}
|