@jujulego/jill 3.0.0-alpha.7 → 3.0.0-alpha.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jujulego/jill",
3
- "version": "3.0.0-alpha.7",
3
+ "version": "3.0.0-alpha.9",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -30,7 +30,7 @@
30
30
  },
31
31
  "dependencies": {
32
32
  "@jujulego/quick-tag": "^1.0.3",
33
- "@jujulego/tasks": "3.0.0-alpha.6",
33
+ "@jujulego/tasks": "3.0.0-alpha.11",
34
34
  "@kyrielle/injector": "^1.1.0",
35
35
  "@kyrielle/logger": "^2.0.0",
36
36
  "@sentry/node": "^10.5.0",
@@ -55,39 +55,44 @@
55
55
  },
56
56
  "devDependencies": {
57
57
  "@codecov/rollup-plugin": "1.9.1",
58
- "@eslint/js": "9.38.0",
58
+ "@eslint/js": "9.39.1",
59
59
  "@jujulego/2d-maths": "1.6.0",
60
60
  "@jujulego/vite-plugin-swc": "1.2.1",
61
61
  "@microsoft/eslint-formatter-sarif": "3.1.0",
62
62
  "@rollup/plugin-json": "6.1.0",
63
63
  "@rollup/plugin-node-resolve": "16.0.3",
64
- "@sentry/rollup-plugin": "4.5.0",
65
- "@swc/core": "1.13.20",
64
+ "@sentry/rollup-plugin": "4.6.0",
65
+ "@swc/core": "1.15.1",
66
66
  "@types/moo": "0.5.10",
67
- "@types/node": "22.18.12",
67
+ "@types/node": "24.10.0",
68
68
  "@types/normalize-package-data": "2.4.4",
69
69
  "@types/react": "19.2.2",
70
70
  "@types/semver": "7.7.1",
71
71
  "@types/yargs": "17.0.34",
72
- "@typescript-eslint/utils": "8.46.2",
72
+ "@typescript-eslint/utils": "8.46.4",
73
73
  "@vitest/coverage-v8": "3.2.4",
74
- "@vitest/eslint-plugin": "1.3.24",
74
+ "@vitest/eslint-plugin": "1.4.2",
75
75
  "@vitest/expect": "3.2.4",
76
- "eslint": "9.38.0",
76
+ "eslint": "9.39.1",
77
77
  "eslint-plugin-react": "7.37.5",
78
78
  "eslint-plugin-react-hooks": "7.0.1",
79
- "globals": "16.4.0",
79
+ "globals": "16.5.0",
80
80
  "ink-testing-library": "4.0.0",
81
81
  "jiti": "2.6.1",
82
- "memfs": "4.49.0",
83
- "rollup": "4.52.5",
82
+ "memfs": "4.50.0",
83
+ "rollup": "4.53.2",
84
84
  "shx": "0.4.0",
85
85
  "ts-node": "10.9.2",
86
86
  "typescript": "5.9.3",
87
- "typescript-eslint": "8.46.2",
88
- "vite": "7.1.12",
87
+ "typescript-eslint": "8.46.4",
88
+ "vite": "7.2.2",
89
89
  "vite-tsconfig-paths": "5.1.4",
90
90
  "vitest": "3.2.4"
91
91
  },
92
- "packageManager": "yarn@4.10.3"
93
- }
92
+ "packageManager": "yarn@4.11.0",
93
+ "dependenciesMeta": {
94
+ "@jujulego/tasks@3.0.0-alpha.8": {
95
+ "unplugged": true
96
+ }
97
+ }
98
+ }
package/dist/TaskName.js DELETED
@@ -1,33 +0,0 @@
1
- ;{try{(function(){var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="17363c5b-8c12-425c-9bfc-b22bfcde7f09",e._sentryDebugIdIdentifier="sentry-dbid-17363c5b-8c12-425c-9bfc-b22bfcde7f09");})();}catch(e){}};!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{};e.SENTRY_RELEASE={id:"3.0.0-alpha.7"};}catch(e){}}();import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
- import { Text } from 'ink';
3
- import { a as isScriptCtx } from './main.js';
4
-
5
- // Components
6
- function TaskName({ task, withWorkspace }) {
7
- if (isScriptCtx(task.context)) {
8
- return /*#__PURE__*/ jsxs(Text, {
9
- children: [
10
- "Run ",
11
- /*#__PURE__*/ jsx(Text, {
12
- bold: true,
13
- children: task.context.script
14
- }),
15
- " script",
16
- withWorkspace && /*#__PURE__*/ jsxs(Fragment, {
17
- children: [
18
- ' ',
19
- "in ",
20
- task.context.workspace.name
21
- ]
22
- })
23
- ]
24
- });
25
- } else {
26
- return /*#__PURE__*/ jsx(Text, {
27
- children: task.name
28
- });
29
- }
30
- }
31
-
32
- export { TaskName as T };
33
- //# sourceMappingURL=TaskName.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"TaskName.js","sources":["../src/cli/components/TaskName.tsx"],"sourcesContent":["import { type Task, type TaskSummary } from '@jujulego/tasks';\nimport { Text } from 'ink';\nimport { isScriptCtx } from '../../tasks/script-task.js';\n\n// Components\nexport default function TaskName({ task, withWorkspace }: TaskNameProps) {\n if (isScriptCtx(task.context)) {\n return (\n <Text>\n Run <Text bold>{ task.context.script }</Text> script{ withWorkspace && <>{' '}in { task.context.workspace.name }</> }\n </Text>\n );\n } else {\n return <Text>{ task.name }</Text>;\n }\n}\n\n// Types\nexport interface TaskNameProps {\n readonly task: Task | TaskSummary;\n readonly withWorkspace?: boolean;\n}\n"],"names":["TaskName","task","withWorkspace","isScriptCtx","context","_jsxs","Text","_jsx","bold","script","_Fragment","workspace","name"],"mappings":";;;;AAIA,CAAA,CAAA,CAAA,UAAA;AACe,QAAA,CAASA,QAAAA,CAAS,CAAA,CAAEC,IAAI,CAAA,CAAEC,aAAa,EAAiB,CAAA,CAAA,CAAA;IACrE,IAAIC,WAAAA,CAAYF,IAAAA,CAAKG,OAAO,CAAA,CAAA,CAAG,CAAA;AAC7B,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,MAAA,CAAA,CAAA,CAAA,CAAA,QAAA,CAAA,CAAA,CACEC,IAAA,CAACC,IAAAA,CAAAA,CAAAA,CAAAA;;AAAK,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CAAA,CAAA,CAAA;8BACAC,GAAA,CAACD,IAAAA,CAAAA,CAAAA,CAAAA;oBAAKE,IAAI,EAAA,IAAA,CAAA;8BAAGP,IAAAA,CAAKG,OAAO,CAACK,MAAAA;;AAAe,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,MAAA,CAAA,CAAA;gBAASP,aAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,QAAAA,CAAAA,CAAAA,CAAiBG,IAAA,CAAAK,QAAA,CAAA,CAAA,CAAA;;AAAG,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;AAAI,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA;AAAKT,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,IAAAA,CAAKG,OAAO,CAACO,SAAS,CAACC,IAAAA;;;;;IAGhH,CAAA,CAAA,IAAA,CAAO,CAAA;AACL,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,MAAA,CAAA,CAAA,CAAA,CAAA,QAAA,CAAA,CAAA,CAAOL,GAAA,CAACD,IAAAA,CAAAA,CAAAA,CAAAA;AAAOL,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,QAAAA,CAAAA,CAAAA,IAAAA,CAAKW,IAAAA;;AACtB,CAAA,CAAA,CAAA,CAAA,CAAA;AACF,CAAA;;"}
@@ -1,542 +0,0 @@
1
- ;{try{(function(){var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="48795aa4-e8c2-4511-bb1d-711a7b4268ab",e._sentryDebugIdIdentifier="sentry-dbid-48795aa4-e8c2-4511-bb1d-711a7b4268ab");})();}catch(e){}};!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{};e.SENTRY_RELEASE={id:"3.0.0-alpha.7"};}catch(e){}}();import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
- import { inject$ } from '@kyrielle/injector';
3
- import { waitFor$ } from 'kyrielle';
4
- import process from 'node:process';
5
- import { i as isCommandCtx, S as ScriptTask, C as CommandTask, a as isScriptCtx, T as TASK_MANAGER } from './main.js';
6
- import { Box, Text, Static, useStdout, useInput, useStdin } from 'ink';
7
- import { useState, useLayoutEffect, useMemo, useEffect } from 'react';
8
- import { GroupTask } from '@jujulego/tasks';
9
- import Spinner from 'ink-spinner';
10
- import ms from 'pretty-ms';
11
- import isUnicodeSupported from 'is-unicode-supported';
12
- import { T as TaskName } from './TaskName.js';
13
- import { i as inked } from './inked.js';
14
- import '@sentry/node';
15
- import 'yargs/helpers';
16
- import 'yargs';
17
- import '@kyrielle/logger';
18
- import 'node:fs';
19
- import 'path-scurry';
20
- import '@swc/helpers/_/_apply_decs_2203_r';
21
- import 'node:stream/consumers';
22
- import 'node:path';
23
- import 'glob';
24
- import 'normalize-package-data';
25
- import 'semver';
26
- import 'moo';
27
- import 'node:child_process';
28
- import 'chalk';
29
- import 'slugify';
30
- import '@jujulego/quick-tag';
31
- import 'ajv';
32
- import 'node:os';
33
- import 'cosmiconfig';
34
- import 'chalk-template';
35
-
36
- // Utils
37
- /**
38
- * Sorts tasks according to workspace and script, keeping command at the end
39
- */ function taskComparator(a, b) {
40
- // 1 - compare kind
41
- const kindA = a instanceof CommandTask ? 0 : 1;
42
- const kindB = b instanceof CommandTask ? 0 : 1;
43
- if (kindA !== kindB) {
44
- return kindB - kindA;
45
- }
46
- // 2 - compare workspaces
47
- const wksA = 'workspace' in a.context ? a.context.workspace.name : '\uffff';
48
- const wksB = 'workspace' in b.context ? b.context.workspace.name : '\uffff';
49
- const wksDiff = wksA.localeCompare(wksB);
50
- if (wksDiff !== 0) {
51
- return wksDiff;
52
- }
53
- // 1 - compare scripts
54
- const scriptA = 'script' in a.context ? a.context.script : '\uffff';
55
- const scriptB = 'script' in b.context ? b.context.script : '\uffff';
56
- return scriptA.localeCompare(scriptB);
57
- }
58
- /**
59
- * Extract tasks to be printed, with their level in the tree
60
- */ function* flatTasks(tasks, isVerbose, groupId, level = 0) {
61
- for (const task of tasks){
62
- if (task.group?.id !== groupId) {
63
- continue;
64
- }
65
- yield {
66
- task,
67
- level
68
- };
69
- if (task instanceof GroupTask) {
70
- const isCommandGroup = task.tasks.some((t)=>!isCommandCtx(t.context));
71
- const hasFailed = task.tasks.some((t)=>t.status === 'failed');
72
- const isStarted = task.status === 'running';
73
- if (isVerbose || isCommandGroup || hasFailed || isStarted) {
74
- let tasks = task.tasks;
75
- if (task instanceof ScriptTask) {
76
- tasks = [
77
- ...tasks
78
- ].sort(taskComparator);
79
- }
80
- yield* flatTasks(tasks, isVerbose, task.id, level + 1);
81
- }
82
- }
83
- }
84
- }
85
- // Hook
86
- function useFlatTaskTree(manager, isVerbose = false) {
87
- const [tasks, setTasks] = useState([
88
- ...manager.tasks
89
- ].sort(taskComparator));
90
- const [version, setVersion] = useState(0);
91
- useLayoutEffect(()=>{
92
- let dirty = false;
93
- return manager.events$.on('added', ()=>{
94
- if (!dirty) {
95
- dirty = true;
96
- queueMicrotask(()=>{
97
- setTasks([
98
- ...manager.tasks
99
- ].sort(taskComparator));
100
- dirty = false;
101
- });
102
- }
103
- }).unsubscribe;
104
- }, [
105
- manager
106
- ]);
107
- useLayoutEffect(()=>{
108
- let dirty = false;
109
- return manager.events$.on('started', ()=>{
110
- if (!dirty) {
111
- dirty = true;
112
- setTimeout(()=>{
113
- setVersion((old)=>++old);
114
- dirty = false;
115
- });
116
- }
117
- }).unsubscribe;
118
- }, [
119
- manager
120
- ]);
121
- useLayoutEffect(()=>{
122
- let dirty = false;
123
- return manager.events$.on('completed', ()=>{
124
- if (!dirty) {
125
- dirty = true;
126
- setTimeout(()=>{
127
- setVersion((old)=>++old);
128
- dirty = false;
129
- });
130
- }
131
- }).unsubscribe;
132
- }, [
133
- manager
134
- ]);
135
- return useMemo(()=>{
136
- return Array.from(flatTasks(tasks, isVerbose));
137
- }, [
138
- tasks,
139
- isVerbose,
140
- version
141
- ]); // eslint-disable-line react-hooks/exhaustive-deps
142
- }
143
-
144
- const isSupported = !isUnicodeSupported();
145
- const success = isSupported ? '✔' : '√';
146
- const error = isSupported ? '✖' : '×';
147
-
148
- // Components
149
- function TaskSpinner({ task }) {
150
- // State
151
- const [status, setStatus] = useState(task.status);
152
- const [time, setTime] = useState(task.duration);
153
- // Effects
154
- useLayoutEffect(()=>{
155
- return task.events$.on('status', (event)=>{
156
- setStatus(event.status);
157
- }).unsubscribe;
158
- }, [
159
- task
160
- ]);
161
- useLayoutEffect(()=>{
162
- return task.events$.on('completed', ({ duration })=>{
163
- setTime(duration);
164
- }).unsubscribe;
165
- }, [
166
- task
167
- ]);
168
- // Render
169
- const isScriptChild = (isCommandCtx(task.context) && task.group && isScriptCtx(task.group.context)) ?? false;
170
- switch(status){
171
- case 'blocked':
172
- case 'ready':
173
- case 'starting':
174
- return /*#__PURE__*/ jsxs(Box, {
175
- children: [
176
- /*#__PURE__*/ jsx(Text, {
177
- color: "grey",
178
- children: '\u00B7'
179
- }),
180
- /*#__PURE__*/ jsx(Box, {
181
- paddingLeft: 1,
182
- children: /*#__PURE__*/ jsx(Text, {
183
- color: "grey",
184
- wrap: "truncate",
185
- children: /*#__PURE__*/ jsx(TaskName, {
186
- task: task,
187
- withWorkspace: true
188
- })
189
- })
190
- })
191
- ]
192
- });
193
- case 'running':
194
- return /*#__PURE__*/ jsxs(Box, {
195
- children: [
196
- /*#__PURE__*/ jsx(Text, {
197
- dimColor: isScriptChild,
198
- children: /*#__PURE__*/ jsx(Spinner, {})
199
- }),
200
- /*#__PURE__*/ jsx(Box, {
201
- paddingLeft: 1,
202
- children: /*#__PURE__*/ jsx(Text, {
203
- dimColor: isScriptChild,
204
- wrap: "truncate",
205
- children: /*#__PURE__*/ jsx(TaskName, {
206
- task: task,
207
- withWorkspace: true
208
- })
209
- })
210
- })
211
- ]
212
- });
213
- case 'done':
214
- return /*#__PURE__*/ jsxs(Box, {
215
- children: [
216
- /*#__PURE__*/ jsx(Text, {
217
- color: "green",
218
- children: success
219
- }),
220
- /*#__PURE__*/ jsx(Box, {
221
- paddingLeft: 1,
222
- children: /*#__PURE__*/ jsx(Text, {
223
- dimColor: isScriptChild,
224
- wrap: "truncate",
225
- children: /*#__PURE__*/ jsx(TaskName, {
226
- task: task,
227
- withWorkspace: true
228
- })
229
- })
230
- }),
231
- /*#__PURE__*/ jsx(Box, {
232
- paddingLeft: 1,
233
- flexShrink: 0,
234
- children: /*#__PURE__*/ jsxs(Text, {
235
- color: isScriptChild ? 'grey' : 'dim',
236
- children: [
237
- "(took ",
238
- ms(time),
239
- ")"
240
- ]
241
- })
242
- })
243
- ]
244
- });
245
- case 'failed':
246
- return /*#__PURE__*/ jsxs(Box, {
247
- children: [
248
- /*#__PURE__*/ jsx(Text, {
249
- color: "red",
250
- children: error
251
- }),
252
- /*#__PURE__*/ jsx(Box, {
253
- paddingLeft: 1,
254
- children: /*#__PURE__*/ jsx(Text, {
255
- dimColor: isScriptChild,
256
- wrap: "truncate",
257
- children: /*#__PURE__*/ jsx(TaskName, {
258
- task: task,
259
- withWorkspace: true
260
- })
261
- })
262
- }),
263
- /*#__PURE__*/ jsx(Box, {
264
- paddingLeft: 1,
265
- flexShrink: 0,
266
- children: /*#__PURE__*/ jsxs(Text, {
267
- color: isScriptChild ? 'grey' : 'dim',
268
- children: [
269
- "(took ",
270
- ms(time),
271
- ")"
272
- ]
273
- })
274
- })
275
- ]
276
- });
277
- }
278
- }
279
-
280
- // Component
281
- function TaskTreeStats({ manager }) {
282
- // Follow stats
283
- const [stats, setStats] = useState(()=>{
284
- const base = {
285
- running: 0,
286
- done: 0,
287
- failed: 0
288
- };
289
- for (const task of manager.tasks){
290
- switch(task.status){
291
- case 'starting':
292
- case 'running':
293
- base.running += task.weight;
294
- break;
295
- case 'done':
296
- base.done += task.weight;
297
- break;
298
- case 'failed':
299
- base.failed += task.weight;
300
- break;
301
- }
302
- }
303
- return base;
304
- });
305
- useLayoutEffect(()=>{
306
- return manager.events$.on('started', (task)=>{
307
- setStats((old)=>({
308
- ...old,
309
- running: old.running + task.weight
310
- }));
311
- }).unsubscribe;
312
- }, [
313
- manager
314
- ]);
315
- useLayoutEffect(()=>{
316
- return manager.events$.on('completed', (task)=>{
317
- setStats((old)=>({
318
- running: old.running - task.weight,
319
- done: task.status === 'done' ? old.done + task.weight : old.done,
320
- failed: task.status === 'failed' ? old.failed + task.weight : old.failed
321
- }));
322
- }).unsubscribe;
323
- }, [
324
- manager
325
- ]);
326
- // Render
327
- return /*#__PURE__*/ jsxs(Text, {
328
- children: [
329
- stats.running !== 0 && /*#__PURE__*/ jsxs(Fragment, {
330
- children: [
331
- /*#__PURE__*/ jsx(Spinner, {
332
- type: "sand"
333
- }),
334
- " ",
335
- /*#__PURE__*/ jsx(Text, {
336
- bold: true,
337
- children: stats.running
338
- }),
339
- " running"
340
- ]
341
- }),
342
- stats.running !== 0 && stats.done !== 0 && /*#__PURE__*/ jsx(Fragment, {
343
- children: ", "
344
- }),
345
- stats.done !== 0 && /*#__PURE__*/ jsxs(Text, {
346
- color: "green",
347
- children: [
348
- success,
349
- " ",
350
- stats.done,
351
- " done"
352
- ]
353
- }),
354
- stats.running + stats.done !== 0 && stats.failed !== 0 && /*#__PURE__*/ jsx(Fragment, {
355
- children: ", "
356
- }),
357
- stats.failed !== 0 && /*#__PURE__*/ jsxs(Text, {
358
- color: "red",
359
- children: [
360
- error,
361
- " ",
362
- stats.failed,
363
- " failed"
364
- ]
365
- })
366
- ]
367
- });
368
- }
369
-
370
- // Component
371
- function TaskTreeCompleted({ manager, verbose }) {
372
- // Extract all tasks
373
- const flat = useMemo(()=>{
374
- return Array.from(flatTasks([
375
- ...manager.tasks
376
- ].sort(taskComparator), verbose ?? false));
377
- }, [
378
- manager,
379
- verbose
380
- ]);
381
- // Render
382
- return /*#__PURE__*/ jsxs(Fragment, {
383
- children: [
384
- /*#__PURE__*/ jsx(Static, {
385
- items: flat,
386
- children: ({ task, level })=>/*#__PURE__*/ jsx(Box, {
387
- marginLeft: level * 2,
388
- flexShrink: 0,
389
- children: /*#__PURE__*/ jsx(TaskSpinner, {
390
- task: task
391
- })
392
- }, task.id)
393
- }),
394
- /*#__PURE__*/ jsx(TaskTreeStats, {
395
- manager: manager
396
- })
397
- ]
398
- });
399
- }
400
-
401
- // Component
402
- function TaskTreeFullSpinner({ manager, verbose }) {
403
- const flat = useFlatTaskTree(manager, verbose);
404
- // Render
405
- return /*#__PURE__*/ jsxs(Fragment, {
406
- children: [
407
- /*#__PURE__*/ jsx(Box, {
408
- flexDirection: "column",
409
- children: flat.map(({ task, level })=>/*#__PURE__*/ jsx(Box, {
410
- marginLeft: level * 2,
411
- flexShrink: 0,
412
- children: /*#__PURE__*/ jsx(TaskSpinner, {
413
- task: task
414
- })
415
- }, task.id))
416
- }),
417
- /*#__PURE__*/ jsx(Text, {
418
- children: /*#__PURE__*/ jsx(TaskTreeStats, {
419
- manager: manager
420
- })
421
- })
422
- ]
423
- });
424
- }
425
-
426
- function useStdoutDimensions() {
427
- const { stdout } = useStdout();
428
- const [dimensions, setDimensions] = useState({
429
- columns: stdout.columns ?? Infinity,
430
- rows: stdout.rows ?? Infinity
431
- });
432
- useEffect(()=>{
433
- const handler = ()=>setDimensions({
434
- columns: stdout.columns ?? Infinity,
435
- rows: stdout.rows ?? Infinity
436
- });
437
- stdout.on('resize', handler);
438
- return ()=>{
439
- stdout.off('resize', handler);
440
- };
441
- }, [
442
- stdout
443
- ]);
444
- return dimensions;
445
- }
446
-
447
- // Component
448
- function TaskTreeScrollableSpinner({ manager, verbose }) {
449
- const { rows: termHeight } = useStdoutDimensions();
450
- // Extract all tasks
451
- const flat = useFlatTaskTree(manager, verbose);
452
- const maxHeight = useMemo(()=>Math.min(termHeight - 4, flat.length), [
453
- termHeight,
454
- flat
455
- ]);
456
- // Manage scroll
457
- const [start, setStart] = useState(0);
458
- const slice = useMemo(()=>flat.slice(start, start + maxHeight), [
459
- flat,
460
- start,
461
- maxHeight
462
- ]);
463
- useEffect(()=>{
464
- if (start + maxHeight > flat.length) {
465
- // eslint-disable-next-line react-hooks/set-state-in-effect
466
- setStart(Math.max(flat.length - maxHeight, 0));
467
- }
468
- }, [
469
- start,
470
- flat,
471
- maxHeight
472
- ]);
473
- useInput((_, key)=>{
474
- if (key.upArrow) {
475
- setStart((old)=>Math.max(0, old - 1));
476
- } else if (key.downArrow) {
477
- setStart((old)=>Math.min(flat.length - maxHeight, old + 1));
478
- }
479
- });
480
- // Render
481
- return /*#__PURE__*/ jsxs(Fragment, {
482
- children: [
483
- /*#__PURE__*/ jsx(Box, {
484
- flexDirection: "column",
485
- children: slice.map(({ task, level })=>/*#__PURE__*/ jsx(Box, {
486
- marginLeft: level * 2,
487
- flexShrink: 0,
488
- children: /*#__PURE__*/ jsx(TaskSpinner, {
489
- task: task
490
- })
491
- }, task.id))
492
- }),
493
- /*#__PURE__*/ jsxs(Text, {
494
- children: [
495
- /*#__PURE__*/ jsx(TaskTreeStats, {
496
- manager: manager
497
- }),
498
- maxHeight < flat.length && /*#__PURE__*/ jsx(Text, {
499
- color: "grey",
500
- children: " - use keyboard arrows to scroll"
501
- })
502
- ]
503
- })
504
- ]
505
- });
506
- }
507
-
508
- // Component
509
- function TaskTreeSpinner({ manager, verbose }) {
510
- const stdin = useStdin();
511
- if (stdin.isRawModeSupported) {
512
- return /*#__PURE__*/ jsx(TaskTreeScrollableSpinner, {
513
- manager: manager,
514
- verbose: verbose
515
- });
516
- } else {
517
- return /*#__PURE__*/ jsx(TaskTreeFullSpinner, {
518
- manager: manager,
519
- verbose: verbose
520
- });
521
- }
522
- }
523
-
524
- const TaskExecInk = inked(async function*({ tasks, verbose }) {
525
- const manager = await inject$(TASK_MANAGER);
526
- yield /*#__PURE__*/ jsx(TaskTreeSpinner, {
527
- manager: manager,
528
- verbose: verbose
529
- });
530
- tasks.start(manager);
531
- const results = await waitFor$(tasks.events$, 'finished');
532
- yield /*#__PURE__*/ jsx(TaskTreeCompleted, {
533
- manager: manager,
534
- verbose: verbose
535
- });
536
- if (results.failed > 0) {
537
- process.exitCode = 1;
538
- }
539
- });
540
-
541
- export { TaskExecInk as default };
542
- //# sourceMappingURL=task-exec.ink.js.map