@jujulego/jill 3.0.0-alpha.6 → 3.0.0-alpha.8

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/bin/jill.js CHANGED
@@ -1,7 +1,4 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- if (process.env.DISABLE_TRACING !== 'true') {
4
- await import('../dist/instrument.js');
5
- }
6
-
3
+ import '../dist/instrument.js';
7
4
  import '../dist/main.js';
package/dist/inked.js CHANGED
@@ -1,4 +1,4 @@
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]="21bcab1f-6a71-4cca-9782-8c6e5e263a4e",e._sentryDebugIdIdentifier="sentry-dbid-21bcab1f-6a71-4cca-9782-8c6e5e263a4e");})();}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.6"};}catch(e){}}();import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
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]="709d1bbb-5a2d-41fa-b3b6-a52a755c1e53",e._sentryDebugIdIdentifier="sentry-dbid-709d1bbb-5a2d-41fa-b3b6-a52a755c1e53");})();}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.8"};}catch(e){}}();import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { startSpan } from '@sentry/node';
3
3
  import { useStderr, render } from 'ink';
4
4
  import { inject$ } from '@kyrielle/injector';
@@ -1,8 +1,9 @@
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]="dbc05b83-04d0-4895-a64e-e1a1d99108a4",e._sentryDebugIdIdentifier="sentry-dbid-dbc05b83-04d0-4895-a64e-e1a1d99108a4");})();}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.6"};}catch(e){}}();import { init } from '@sentry/node';
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]="c2fd80ca-6b66-4bbf-a184-cbd02d33b725",e._sentryDebugIdIdentifier="sentry-dbid-c2fd80ca-6b66-4bbf-a184-cbd02d33b725");})();}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.8"};}catch(e){}}();import { init } from '@sentry/node';
2
2
 
3
3
  init({
4
4
  dsn: 'https://53e6d10c16975ebd025175d9836d039b@o4508229080055808.ingest.de.sentry.io/4509876546895952',
5
5
  sendDefaultPii: false,
6
- tracesSampleRate: 1.0
6
+ tracesSampleRate: 1.0,
7
+ enabled: process.env.DISABLE_TRACING !== 'true'
7
8
  });
8
9
  //# sourceMappingURL=instrument.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"instrument.js","sources":["../src/instrument.ts"],"sourcesContent":["import { init } from '@sentry/node';\n\ninit({\n dsn: 'https://53e6d10c16975ebd025175d9836d039b@o4508229080055808.ingest.de.sentry.io/4509876546895952',\n sendDefaultPii: false,\n tracesSampleRate: 1.0,\n});\n"],"names":["init","dsn","sendDefaultPii","tracesSampleRate"],"mappings":";;AAEAA,IAAAA,CAAK,CAAA;IACHC,GAAAA,EAAK,CAAA,KAAA,CAAA,CAAA,CAAA,gCAAA,CAAA,iBAAA,CAAA,MAAA,CAAA,EAAA,CAAA,MAAA,CAAA,EAAA,CAAA,gBAAA,CAAA,CAAA;IACLC,cAAAA,EAAgB,KAAA,CAAA;IAChBC,gBAAAA,CAAAA,CAAkB,CAAA,CAAA,CAAA;AACpB,CAAA,CAAA"}
1
+ {"version":3,"file":"instrument.js","sources":["../src/instrument.ts"],"sourcesContent":["import { init } from '@sentry/node';\n\ninit({\n dsn: 'https://53e6d10c16975ebd025175d9836d039b@o4508229080055808.ingest.de.sentry.io/4509876546895952',\n sendDefaultPii: false,\n tracesSampleRate: 1.0,\n enabled: process.env.DISABLE_TRACING !== 'true',\n});\n"],"names":["init","dsn","sendDefaultPii","tracesSampleRate","enabled","process","env","DISABLE_TRACING"],"mappings":";;AAEAA,IAAAA,CAAK,CAAA;IACHC,GAAAA,EAAK,CAAA,KAAA,CAAA,CAAA,CAAA,gCAAA,CAAA,iBAAA,CAAA,MAAA,CAAA,EAAA,CAAA,MAAA,CAAA,EAAA,CAAA,gBAAA,CAAA,CAAA;IACLC,cAAAA,EAAgB,KAAA,CAAA;IAChBC,gBAAAA,EAAkB,CAAA,CAAA,CAAA,CAAA;AAClBC,CAAAA,CAAAA,CAAAA,CAAAA,OAAAA,CAAAA,CAASC,OAAAA,CAAQC,GAAG,CAACC,eAAe,CAAA,CAAA,CAAA,CAAA,CAAK,CAAA,IAAA,CAAA;AAC3C,CAAA,CAAA"}
@@ -0,0 +1,606 @@
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]="c565de71-f9f2-474d-8656-f5f60a03995d",e._sentryDebugIdIdentifier="sentry-dbid-c565de71-f9f2-474d-8656-f5f60a03995d");})();}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.8"};}catch(e){}}();import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
+ import { WorkloadState, isWorkloadEnded } from '@jujulego/tasks';
3
+ import { inject$ } from '@kyrielle/injector';
4
+ import { pipe$, map$, collect$, off$, waitFor$, filter$ } from 'kyrielle';
5
+ import process from 'node:process';
6
+ import { S as SCHEDULER } from './main.js';
7
+ import { Text, Box, Static, useStdout, useInput, useStdin } from 'ink';
8
+ import { createHash } from 'node:crypto';
9
+ import { useState, useEffect, useMemo } from 'react';
10
+ import Spinner from 'ink-spinner';
11
+ import ms from 'pretty-ms';
12
+ import isUnicodeSupported from 'is-unicode-supported';
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
+ // Hook
37
+ function useWorkflowFlatTree(workload, verbose) {
38
+ const [tree, setTree] = useState(()=>buildTree(workload, verbose));
39
+ useEffect(()=>{
40
+ const oldHash = hashTree(tree);
41
+ let dirty = false;
42
+ function update() {
43
+ if (!dirty) return;
44
+ const updated = buildTree(workload, verbose);
45
+ if (hashTree(updated) !== oldHash) {
46
+ setTree(updated);
47
+ }
48
+ dirty = false;
49
+ }
50
+ const off = pipe$(tree, map$(({ workload })=>workload.state$.subscribe(()=>{
51
+ dirty = true;
52
+ queueMicrotask(update);
53
+ })), collect$(off$()));
54
+ return ()=>{
55
+ dirty = false;
56
+ off.unsubscribe();
57
+ };
58
+ }, [
59
+ tree,
60
+ verbose,
61
+ workload
62
+ ]);
63
+ return tree;
64
+ }
65
+ // Utils
66
+ function* listRoots(workload) {
67
+ const marks = new Set();
68
+ const queue = [
69
+ workload
70
+ ];
71
+ while(queue.length){
72
+ const item = queue.shift();
73
+ // Mark all member of workflows, so they're not added as root
74
+ if (isWorkflow(item)) {
75
+ for (const wkl of item.workloads()){
76
+ marks.add(wkl.id);
77
+ queue.unshift(wkl);
78
+ }
79
+ }
80
+ // Load job dependencies
81
+ if (isJob(item)) {
82
+ for (const dep of item.dependencies()){
83
+ queue.push(dep);
84
+ }
85
+ }
86
+ // Ignore marked workloads
87
+ if (marks.has(item.id)) {
88
+ continue;
89
+ }
90
+ yield item;
91
+ marks.add(item.id);
92
+ }
93
+ }
94
+ function buildTree(workload, verbose = false) {
95
+ const tree = [];
96
+ const stack = pipe$(listRoots(workload), map$((workload)=>({
97
+ workload,
98
+ level: 0
99
+ })), collect$());
100
+ while(stack.length > 0){
101
+ const item = stack.pop();
102
+ const mustShow = [
103
+ WorkloadState.Starting,
104
+ WorkloadState.Running,
105
+ WorkloadState.Failed
106
+ ].includes(item.workload.state());
107
+ if (!verbose && !isWorkflow(item.workload) && !mustShow && item.level > 0) {
108
+ continue;
109
+ }
110
+ // Add to tree
111
+ let level = item.level;
112
+ if (item.workload.label !== '[hidden]') {
113
+ tree.push(item);
114
+ level++;
115
+ }
116
+ // Load "member" tasks
117
+ if (isWorkflow(item.workload)) {
118
+ const children = [
119
+ ...item.workload.workloads()
120
+ ].reverse();
121
+ for (const workload of children){
122
+ stack.push({
123
+ workload,
124
+ level
125
+ });
126
+ }
127
+ }
128
+ }
129
+ return tree;
130
+ }
131
+ function isJob(workload) {
132
+ return 'dependencies' in workload && typeof workload.dependencies === 'function';
133
+ }
134
+ function isWorkflow(workload) {
135
+ return 'workloads' in workload && typeof workload.workloads === 'function';
136
+ }
137
+ function hashTree(tree) {
138
+ const hash = createHash('sha256');
139
+ for (const { workload } of tree){
140
+ hash.update(workload.id);
141
+ }
142
+ return hash.digest('hex');
143
+ }
144
+
145
+ const isSupported = !isUnicodeSupported();
146
+ const success = isSupported ? '✔' : '√';
147
+ const error = isSupported ? '✖' : '×';
148
+
149
+ function capitalize(str) {
150
+ return str.charAt(0).toUpperCase() + str.slice(1);
151
+ }
152
+
153
+ // Component
154
+ function WorkloadName({ workload, withWorkspace, ...rest }) {
155
+ if (isScriptWorkflow(workload)) {
156
+ return /*#__PURE__*/ jsxs(Text, {
157
+ ...rest,
158
+ children: [
159
+ "Run ",
160
+ /*#__PURE__*/ jsx(Text, {
161
+ bold: true,
162
+ children: workload.script
163
+ }),
164
+ " script",
165
+ withWorkspace && /*#__PURE__*/ jsxs(Fragment, {
166
+ children: [
167
+ ' ',
168
+ "in ",
169
+ workload.workspace.name
170
+ ]
171
+ })
172
+ ]
173
+ });
174
+ }
175
+ let name = workload.label;
176
+ if (workload.type !== 'spawn') {
177
+ name = capitalize(name);
178
+ }
179
+ return /*#__PURE__*/ jsx(Text, {
180
+ ...rest,
181
+ children: name
182
+ });
183
+ }
184
+ // Utils
185
+ function isScriptWorkflow(workload) {
186
+ return workload.type === 'script';
187
+ }
188
+
189
+ // Component
190
+ function WorkloadSpinner({ workload }) {
191
+ // Track task state
192
+ const [state, setState] = useState(workload.state());
193
+ useEffect(()=>{
194
+ const sub = workload.state$.subscribe(setState);
195
+ return sub.unsubscribe;
196
+ }, [
197
+ workload.state$
198
+ ]);
199
+ // Render
200
+ const dim = workload.type === 'spawn';
201
+ const time = workload.duration().seconds() * 1000;
202
+ switch(state){
203
+ case WorkloadState.Blocked:
204
+ case WorkloadState.Ready:
205
+ case WorkloadState.Starting:
206
+ return /*#__PURE__*/ jsxs(Box, {
207
+ children: [
208
+ /*#__PURE__*/ jsx(Text, {
209
+ color: "grey",
210
+ children: '\u00B7'
211
+ }),
212
+ /*#__PURE__*/ jsx(Box, {
213
+ paddingLeft: 1,
214
+ children: /*#__PURE__*/ jsx(WorkloadName, {
215
+ color: "grey",
216
+ wrap: "truncate",
217
+ workload: workload,
218
+ withWorkspace: true
219
+ })
220
+ })
221
+ ]
222
+ });
223
+ case WorkloadState.Running:
224
+ return /*#__PURE__*/ jsxs(Box, {
225
+ children: [
226
+ /*#__PURE__*/ jsx(Text, {
227
+ dimColor: dim,
228
+ children: /*#__PURE__*/ jsx(Spinner, {})
229
+ }),
230
+ /*#__PURE__*/ jsx(Box, {
231
+ paddingLeft: 1,
232
+ children: /*#__PURE__*/ jsx(WorkloadName, {
233
+ dimColor: dim,
234
+ wrap: "truncate",
235
+ workload: workload,
236
+ withWorkspace: true
237
+ })
238
+ })
239
+ ]
240
+ });
241
+ case WorkloadState.Canceling:
242
+ return /*#__PURE__*/ jsxs(Box, {
243
+ children: [
244
+ /*#__PURE__*/ jsx(Text, {
245
+ dimColor: dim,
246
+ color: "grey",
247
+ children: /*#__PURE__*/ jsx(Spinner, {
248
+ type: "line2"
249
+ })
250
+ }),
251
+ /*#__PURE__*/ jsx(Box, {
252
+ paddingLeft: 1,
253
+ children: /*#__PURE__*/ jsx(WorkloadName, {
254
+ dimColor: dim,
255
+ color: "grey",
256
+ wrap: "truncate",
257
+ workload: workload,
258
+ withWorkspace: true
259
+ })
260
+ })
261
+ ]
262
+ });
263
+ case WorkloadState.Succeeded:
264
+ return /*#__PURE__*/ jsxs(Box, {
265
+ children: [
266
+ /*#__PURE__*/ jsx(Text, {
267
+ color: "green",
268
+ children: success
269
+ }),
270
+ /*#__PURE__*/ jsx(Box, {
271
+ paddingLeft: 1,
272
+ children: /*#__PURE__*/ jsx(WorkloadName, {
273
+ dimColor: dim,
274
+ wrap: "truncate",
275
+ workload: workload,
276
+ withWorkspace: true
277
+ })
278
+ }),
279
+ /*#__PURE__*/ jsx(Box, {
280
+ paddingLeft: 1,
281
+ flexShrink: 0,
282
+ children: /*#__PURE__*/ jsxs(Text, {
283
+ color: dim ? 'grey' : 'dim',
284
+ children: [
285
+ "(took ",
286
+ ms(time),
287
+ ")"
288
+ ]
289
+ })
290
+ })
291
+ ]
292
+ });
293
+ case WorkloadState.Failed:
294
+ return /*#__PURE__*/ jsxs(Box, {
295
+ children: [
296
+ /*#__PURE__*/ jsx(Text, {
297
+ color: "red",
298
+ children: error
299
+ }),
300
+ /*#__PURE__*/ jsx(Box, {
301
+ paddingLeft: 1,
302
+ children: /*#__PURE__*/ jsx(WorkloadName, {
303
+ dimColor: dim,
304
+ wrap: "truncate",
305
+ workload: workload,
306
+ withWorkspace: true
307
+ })
308
+ }),
309
+ /*#__PURE__*/ jsx(Box, {
310
+ paddingLeft: 1,
311
+ flexShrink: 0,
312
+ children: /*#__PURE__*/ jsxs(Text, {
313
+ color: dim ? 'grey' : 'dim',
314
+ children: [
315
+ "(took ",
316
+ ms(time),
317
+ ")"
318
+ ]
319
+ })
320
+ })
321
+ ]
322
+ });
323
+ case WorkloadState.Canceled:
324
+ return /*#__PURE__*/ jsxs(Box, {
325
+ children: [
326
+ /*#__PURE__*/ jsx(Text, {
327
+ dimColor: true,
328
+ children: "-"
329
+ }),
330
+ /*#__PURE__*/ jsx(Box, {
331
+ paddingLeft: 1,
332
+ children: /*#__PURE__*/ jsx(WorkloadName, {
333
+ dimColor: true,
334
+ wrap: "truncate",
335
+ workload: workload,
336
+ withWorkspace: true
337
+ })
338
+ }),
339
+ /*#__PURE__*/ jsx(Box, {
340
+ paddingLeft: 1,
341
+ flexShrink: 0,
342
+ children: /*#__PURE__*/ jsxs(Text, {
343
+ color: dim ? 'grey' : 'dim',
344
+ children: [
345
+ "(took ",
346
+ ms(time),
347
+ ")"
348
+ ]
349
+ })
350
+ })
351
+ ]
352
+ });
353
+ }
354
+ }
355
+
356
+ // Hook
357
+ function useScriptsStats(workloads) {
358
+ const [stats, setStats] = useState(()=>countScripts(workloads));
359
+ useEffect(()=>{
360
+ let dirty = false;
361
+ function recount() {
362
+ if (!dirty) return;
363
+ setStats(countScripts(workloads));
364
+ dirty = false;
365
+ }
366
+ const off = pipe$(workloads, map$((wkl)=>wkl.state$.subscribe(()=>{
367
+ dirty = true;
368
+ queueMicrotask(recount);
369
+ })), collect$(off$()));
370
+ return ()=>{
371
+ dirty = false;
372
+ off.unsubscribe();
373
+ };
374
+ }, [
375
+ workloads
376
+ ]);
377
+ return stats;
378
+ }
379
+ // Utils
380
+ function countScripts(workloads) {
381
+ const stats = {
382
+ [WorkloadState.Ready]: 0,
383
+ [WorkloadState.Blocked]: 0,
384
+ [WorkloadState.Starting]: 0,
385
+ [WorkloadState.Running]: 0,
386
+ [WorkloadState.Succeeded]: 0,
387
+ [WorkloadState.Failed]: 0,
388
+ [WorkloadState.Canceling]: 0,
389
+ [WorkloadState.Canceled]: 0
390
+ };
391
+ for (const workload of workloads){
392
+ if (workload.type === 'script') {
393
+ stats[workload.state()] += 1;
394
+ }
395
+ }
396
+ return stats;
397
+ }
398
+
399
+ // Component
400
+ function WorkloadTreeStats({ tree, ...rest }) {
401
+ const workloads = useMemo(()=>tree.map((item)=>item.workload), [
402
+ tree
403
+ ]);
404
+ const stats = useScriptsStats(workloads);
405
+ // Render
406
+ const running = stats[WorkloadState.Running] + stats[WorkloadState.Starting] + stats[WorkloadState.Canceling];
407
+ const done = stats[WorkloadState.Succeeded];
408
+ const failed = stats[WorkloadState.Failed];
409
+ const canceled = stats[WorkloadState.Canceled];
410
+ return /*#__PURE__*/ jsxs(Text, {
411
+ ...rest,
412
+ children: [
413
+ running > 0 && /*#__PURE__*/ jsxs(Fragment, {
414
+ children: [
415
+ /*#__PURE__*/ jsx(Spinner, {
416
+ type: "sand"
417
+ }),
418
+ " ",
419
+ /*#__PURE__*/ jsx(Text, {
420
+ bold: true,
421
+ children: running
422
+ }),
423
+ " running"
424
+ ]
425
+ }),
426
+ running > 0 && done > 0 && ', ',
427
+ done > 0 && /*#__PURE__*/ jsxs(Text, {
428
+ color: "green",
429
+ children: [
430
+ success,
431
+ " ",
432
+ done,
433
+ " done"
434
+ ]
435
+ }),
436
+ running + done > 0 && failed > 0 && ', ',
437
+ failed > 0 && /*#__PURE__*/ jsxs(Text, {
438
+ color: "red",
439
+ children: [
440
+ error,
441
+ " ",
442
+ failed,
443
+ " failed"
444
+ ]
445
+ }),
446
+ running + done + failed > 0 && canceled > 0 && ', ',
447
+ canceled > 0 && /*#__PURE__*/ jsxs(Text, {
448
+ dimColor: true,
449
+ children: [
450
+ "- ",
451
+ canceled,
452
+ " canceled"
453
+ ]
454
+ })
455
+ ]
456
+ });
457
+ }
458
+
459
+ // Component
460
+ function WorkloadTreeCompleted({ workload, verbose }) {
461
+ const tree = useWorkflowFlatTree(workload, verbose);
462
+ // Render
463
+ return /*#__PURE__*/ jsxs(Fragment, {
464
+ children: [
465
+ /*#__PURE__*/ jsx(Static, {
466
+ items: tree,
467
+ children: ({ workload, level })=>/*#__PURE__*/ jsx(Box, {
468
+ marginLeft: level * 2,
469
+ flexShrink: 0,
470
+ children: /*#__PURE__*/ jsx(WorkloadSpinner, {
471
+ workload: workload
472
+ })
473
+ }, workload.id)
474
+ }),
475
+ /*#__PURE__*/ jsx(WorkloadTreeStats, {
476
+ tree: tree
477
+ })
478
+ ]
479
+ });
480
+ }
481
+
482
+ // Component
483
+ function WorkloadTreeFullSpinner({ workload, verbose }) {
484
+ const tree = useWorkflowFlatTree(workload, verbose);
485
+ // Render
486
+ return /*#__PURE__*/ jsxs(Fragment, {
487
+ children: [
488
+ /*#__PURE__*/ jsx(Box, {
489
+ flexDirection: "column",
490
+ children: tree.map(({ workload, level })=>/*#__PURE__*/ jsx(Box, {
491
+ marginLeft: level * 2,
492
+ flexShrink: 0,
493
+ children: /*#__PURE__*/ jsx(WorkloadSpinner, {
494
+ workload: workload
495
+ })
496
+ }, workload.id))
497
+ }),
498
+ /*#__PURE__*/ jsx(WorkloadTreeStats, {
499
+ tree: tree
500
+ })
501
+ ]
502
+ });
503
+ }
504
+
505
+ function useStdoutDimensions() {
506
+ const { stdout } = useStdout();
507
+ const [dimensions, setDimensions] = useState({
508
+ columns: stdout.columns ?? Infinity,
509
+ rows: stdout.rows ?? Infinity
510
+ });
511
+ useEffect(()=>{
512
+ const handler = ()=>setDimensions({
513
+ columns: stdout.columns ?? Infinity,
514
+ rows: stdout.rows ?? Infinity
515
+ });
516
+ stdout.on('resize', handler);
517
+ return ()=>{
518
+ stdout.off('resize', handler);
519
+ };
520
+ }, [
521
+ stdout
522
+ ]);
523
+ return dimensions;
524
+ }
525
+
526
+ // Component
527
+ function WorkloadTreeScrollableSpinner({ workload, verbose }) {
528
+ const tree = useWorkflowFlatTree(workload, verbose);
529
+ // Manage scroll
530
+ const { rows: termRows } = useStdoutDimensions();
531
+ const [scroll, setScroll] = useState(0);
532
+ const maxRows = Math.min(termRows - 4, tree.length);
533
+ const firstIndex = Math.max(0, tree.length - scroll - maxRows);
534
+ const lastIndex = Math.min(tree.length, firstIndex + maxRows);
535
+ const effectiveScroll = tree.length - lastIndex;
536
+ useInput((_, key)=>{
537
+ if (key.upArrow) {
538
+ setScroll(Math.min(tree.length - maxRows, effectiveScroll + 1));
539
+ } else {
540
+ setScroll(Math.max(0, effectiveScroll - 1));
541
+ }
542
+ });
543
+ // Render
544
+ const slice = tree.slice(firstIndex, lastIndex);
545
+ return /*#__PURE__*/ jsxs(Fragment, {
546
+ children: [
547
+ /*#__PURE__*/ jsx(Box, {
548
+ flexDirection: "column",
549
+ children: slice.map(({ workload, level })=>/*#__PURE__*/ jsx(Box, {
550
+ marginLeft: level * 2,
551
+ flexShrink: 0,
552
+ children: /*#__PURE__*/ jsx(WorkloadSpinner, {
553
+ workload: workload
554
+ })
555
+ }, workload.id))
556
+ }),
557
+ /*#__PURE__*/ jsxs(Text, {
558
+ children: [
559
+ /*#__PURE__*/ jsx(WorkloadTreeStats, {
560
+ tree: tree
561
+ }),
562
+ termRows < tree.length && /*#__PURE__*/ jsx(Text, {
563
+ color: "grey",
564
+ children: " | use keyboard arrows to scroll"
565
+ })
566
+ ]
567
+ })
568
+ ]
569
+ });
570
+ }
571
+
572
+ // Component
573
+ function WorkloadTreeSpinner({ workload, verbose }) {
574
+ const stdin = useStdin();
575
+ if (stdin.isRawModeSupported) {
576
+ return /*#__PURE__*/ jsx(WorkloadTreeScrollableSpinner, {
577
+ workload: workload,
578
+ verbose: verbose
579
+ });
580
+ } else {
581
+ return /*#__PURE__*/ jsx(WorkloadTreeFullSpinner, {
582
+ workload: workload,
583
+ verbose: verbose
584
+ });
585
+ }
586
+ }
587
+
588
+ const JobExecInk = inked(async function*({ job, verbose }) {
589
+ const scheduler = await inject$(SCHEDULER);
590
+ yield /*#__PURE__*/ jsx(WorkloadTreeSpinner, {
591
+ workload: job,
592
+ verbose: verbose
593
+ });
594
+ scheduler.register(job);
595
+ const outcome = await waitFor$(pipe$(job.state$, filter$(isWorkloadEnded)));
596
+ yield /*#__PURE__*/ jsx(WorkloadTreeCompleted, {
597
+ workload: job,
598
+ verbose: verbose
599
+ });
600
+ if (outcome !== WorkloadState.Succeeded) {
601
+ process.exitCode = 1;
602
+ }
603
+ });
604
+
605
+ export { JobExecInk as default };
606
+ //# sourceMappingURL=job-exec.ink.js.map