@gesslar/toolkit 3.38.0 → 3.39.1
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 +1 -1
- package/src/node/lib/Term.js +98 -8
- package/types/node/lib/Term.d.ts +40 -2
- package/types/node/lib/Term.d.ts.map +1 -1
package/package.json
CHANGED
package/src/node/lib/Term.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import c from "@gesslar/colours"
|
|
1
2
|
import console, {Console} from "node:console"
|
|
2
3
|
import process from "node:process"
|
|
3
4
|
import {Writable} from "node:stream"
|
|
4
|
-
import supportsColor from "supports-color"
|
|
5
5
|
import {stripVTControlCharacters} from "node:util"
|
|
6
|
-
import
|
|
6
|
+
import supportsColor from "supports-color"
|
|
7
7
|
|
|
8
|
+
import Promised from "../../browser/lib/Promised.js"
|
|
9
|
+
import Time from "../../browser/lib/Time.js"
|
|
8
10
|
import Sass from "./Sass.js"
|
|
9
11
|
|
|
10
12
|
c.alias.set("success", "{F035}")
|
|
@@ -488,13 +490,15 @@ export default class Term {
|
|
|
488
490
|
* If in Char Mode, it resolves on Enter, Ctrl+D, or the ANSI 'R' terminator.
|
|
489
491
|
*
|
|
490
492
|
* @param {(text: string) => boolean} [terminator] - Optional callback to check if input is complete.
|
|
491
|
-
* @
|
|
493
|
+
* @param {number} [timeoutMs=0] - Optional timeout in milliseconds. Resolves with empty string if exceeded.
|
|
494
|
+
* @returns {Promise<string>} Resolves with the input data, or empty string on timeout.
|
|
492
495
|
*/
|
|
493
|
-
static data(terminator = () => false) {
|
|
496
|
+
static data(terminator = () => false, timeoutMs = 0) {
|
|
494
497
|
process.stdin.resume()
|
|
495
498
|
|
|
496
499
|
return new Promise((resolve, reject) => {
|
|
497
500
|
const chunks = []
|
|
501
|
+
let timer = null
|
|
498
502
|
|
|
499
503
|
function onData(chunk) {
|
|
500
504
|
const s = chunk.toString()
|
|
@@ -532,6 +536,7 @@ export default class Term {
|
|
|
532
536
|
}
|
|
533
537
|
|
|
534
538
|
function cleanup() {
|
|
539
|
+
clearTimeout(timer)
|
|
535
540
|
process.stdin.off("data", onData)
|
|
536
541
|
process.stdin.off("end", onEnd)
|
|
537
542
|
process.stdin.off("error", onError)
|
|
@@ -544,11 +549,15 @@ export default class Term {
|
|
|
544
549
|
process.stdin.on("data", onData)
|
|
545
550
|
process.stdin.once("end", onEnd)
|
|
546
551
|
process.stdin.once("error", onError)
|
|
552
|
+
|
|
553
|
+
if(timeoutMs > 0)
|
|
554
|
+
timer = setTimeout(onEnd, timeoutMs)
|
|
547
555
|
})
|
|
548
556
|
}
|
|
549
557
|
|
|
550
558
|
/**
|
|
551
559
|
* Gets the current cursor position in the terminal.
|
|
560
|
+
* Returns [0, 0] for non-interactive terminals or if the terminal does not respond within the timeout.
|
|
552
561
|
*
|
|
553
562
|
* @returns {Promise<[number, number]>} Resolves with [x, y] cursor position.
|
|
554
563
|
*/
|
|
@@ -567,13 +576,16 @@ export default class Term {
|
|
|
567
576
|
// 2. Start the listener FIRST (do not await yet)
|
|
568
577
|
const dataPromise = this.data((text => {
|
|
569
578
|
return this.isCharMode && text.endsWith("R")
|
|
570
|
-
}).bind(this))
|
|
579
|
+
}).bind(this), 25)
|
|
571
580
|
|
|
572
581
|
// 3. Write to stdout AFTER the listener is ready
|
|
573
582
|
this.write("\x1b[6n")
|
|
574
583
|
|
|
575
584
|
// 4. Now await the response
|
|
576
|
-
const positionData = await
|
|
585
|
+
const positionData = await Promised.race([
|
|
586
|
+
Time.after(25),
|
|
587
|
+
dataPromise
|
|
588
|
+
])
|
|
577
589
|
|
|
578
590
|
// 5. Restore the previous mode
|
|
579
591
|
prevRawMode ? this.setCharMode() : this.setLineMode()
|
|
@@ -601,8 +613,11 @@ export default class Term {
|
|
|
601
613
|
})
|
|
602
614
|
}
|
|
603
615
|
|
|
604
|
-
|
|
605
|
-
|
|
616
|
+
/**
|
|
617
|
+
* Spinner animation frames using Braille patterns (widely supported).
|
|
618
|
+
*
|
|
619
|
+
* @type {readonly string[]}
|
|
620
|
+
*/
|
|
606
621
|
static spinFrames = Object.freeze(["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"])
|
|
607
622
|
|
|
608
623
|
// static async spinimate(delay=300, options = {position: {x: 0,y: 0}}) {
|
|
@@ -648,4 +663,79 @@ export default class Term {
|
|
|
648
663
|
|
|
649
664
|
return this
|
|
650
665
|
}
|
|
666
|
+
|
|
667
|
+
/**
|
|
668
|
+
* Switch to the alternate screen buffer.
|
|
669
|
+
*
|
|
670
|
+
* @returns {void}
|
|
671
|
+
*/
|
|
672
|
+
static altScreen() {
|
|
673
|
+
this.write("\x1b[?1049h")
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
/**
|
|
677
|
+
* Switch back to the main screen buffer.
|
|
678
|
+
*
|
|
679
|
+
* @returns {void}
|
|
680
|
+
*/
|
|
681
|
+
static mainScreen() {
|
|
682
|
+
this.write("\x1b[?1049l")
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
/**
|
|
686
|
+
* Queries the terminal to determine whether the alternate screen buffer is currently active.
|
|
687
|
+
* Returns undefined for non-interactive terminals or if the terminal does not respond within the timeout.
|
|
688
|
+
*
|
|
689
|
+
* @returns {Promise<boolean|undefined>} true if in alt screen, false if in main screen, undefined if unknown.
|
|
690
|
+
*/
|
|
691
|
+
static async isAltScreen() {
|
|
692
|
+
if(!this.isInteractive)
|
|
693
|
+
return undefined
|
|
694
|
+
|
|
695
|
+
const prevRawMode = this.isCharMode
|
|
696
|
+
|
|
697
|
+
// 1. Force Raw Mode so the terminal sends the report immediately
|
|
698
|
+
this.setCharMode()
|
|
699
|
+
process.stdin.setEncoding("utf8")
|
|
700
|
+
|
|
701
|
+
// 2. Start the listener FIRST (do not await yet)
|
|
702
|
+
const dataPromise = this.data((text => {
|
|
703
|
+
return this.isCharMode && text.endsWith("$y")
|
|
704
|
+
}).bind(this), 25)
|
|
705
|
+
|
|
706
|
+
this.write("\x1b[?1049$p")
|
|
707
|
+
|
|
708
|
+
const response = await Promised.race([
|
|
709
|
+
Time.after(25),
|
|
710
|
+
dataPromise
|
|
711
|
+
])
|
|
712
|
+
|
|
713
|
+
prevRawMode ? this.setCharMode() : this.setLineMode()
|
|
714
|
+
|
|
715
|
+
if(response === "\x1b[?1049;1$y")
|
|
716
|
+
return true
|
|
717
|
+
|
|
718
|
+
if(response === "\x1b[?1049;2$y")
|
|
719
|
+
return false
|
|
720
|
+
|
|
721
|
+
return undefined
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
/**
|
|
725
|
+
* Save the current screen contents.
|
|
726
|
+
*
|
|
727
|
+
* @returns {void}
|
|
728
|
+
*/
|
|
729
|
+
static saveScreen() {
|
|
730
|
+
this.write("\x1b[?47h")
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* Restore previously saved screen contents.
|
|
735
|
+
*
|
|
736
|
+
* @returns {void}
|
|
737
|
+
*/
|
|
738
|
+
static restoreScreen() {
|
|
739
|
+
this.write("\x1b[?47l")
|
|
740
|
+
}
|
|
651
741
|
}
|
package/types/node/lib/Term.d.ts
CHANGED
|
@@ -266,11 +266,13 @@ export default class Term {
|
|
|
266
266
|
* If in Char Mode, it resolves on Enter, Ctrl+D, or the ANSI 'R' terminator.
|
|
267
267
|
*
|
|
268
268
|
* @param {(text: string) => boolean} [terminator] - Optional callback to check if input is complete.
|
|
269
|
-
* @
|
|
269
|
+
* @param {number} [timeoutMs=0] - Optional timeout in milliseconds. Resolves with empty string if exceeded.
|
|
270
|
+
* @returns {Promise<string>} Resolves with the input data, or empty string on timeout.
|
|
270
271
|
*/
|
|
271
|
-
static data(terminator?: (text: string) => boolean): Promise<string>;
|
|
272
|
+
static data(terminator?: (text: string) => boolean, timeoutMs?: number): Promise<string>;
|
|
272
273
|
/**
|
|
273
274
|
* Gets the current cursor position in the terminal.
|
|
275
|
+
* Returns [0, 0] for non-interactive terminals or if the terminal does not respond within the timeout.
|
|
274
276
|
*
|
|
275
277
|
* @returns {Promise<[number, number]>} Resolves with [x, y] cursor position.
|
|
276
278
|
*/
|
|
@@ -282,6 +284,11 @@ export default class Term {
|
|
|
282
284
|
* @returns {Promise<void>} Resolves when write completes.
|
|
283
285
|
*/
|
|
284
286
|
static directWrite(output: string): Promise<void>;
|
|
287
|
+
/**
|
|
288
|
+
* Spinner animation frames using Braille patterns (widely supported).
|
|
289
|
+
*
|
|
290
|
+
* @type {readonly string[]}
|
|
291
|
+
*/
|
|
285
292
|
static spinFrames: readonly string[];
|
|
286
293
|
/**
|
|
287
294
|
* Pause stdin, preventing it from emitting data events.
|
|
@@ -301,5 +308,36 @@ export default class Term {
|
|
|
301
308
|
* @returns {typeof Term} The Term class for chaining.
|
|
302
309
|
*/
|
|
303
310
|
static utf8(): typeof Term;
|
|
311
|
+
/**
|
|
312
|
+
* Switch to the alternate screen buffer.
|
|
313
|
+
*
|
|
314
|
+
* @returns {void}
|
|
315
|
+
*/
|
|
316
|
+
static altScreen(): void;
|
|
317
|
+
/**
|
|
318
|
+
* Switch back to the main screen buffer.
|
|
319
|
+
*
|
|
320
|
+
* @returns {void}
|
|
321
|
+
*/
|
|
322
|
+
static mainScreen(): void;
|
|
323
|
+
/**
|
|
324
|
+
* Queries the terminal to determine whether the alternate screen buffer is currently active.
|
|
325
|
+
* Returns undefined for non-interactive terminals or if the terminal does not respond within the timeout.
|
|
326
|
+
*
|
|
327
|
+
* @returns {Promise<boolean|undefined>} true if in alt screen, false if in main screen, undefined if unknown.
|
|
328
|
+
*/
|
|
329
|
+
static isAltScreen(): Promise<boolean | undefined>;
|
|
330
|
+
/**
|
|
331
|
+
* Save the current screen contents.
|
|
332
|
+
*
|
|
333
|
+
* @returns {void}
|
|
334
|
+
*/
|
|
335
|
+
static saveScreen(): void;
|
|
336
|
+
/**
|
|
337
|
+
* Restore previously saved screen contents.
|
|
338
|
+
*
|
|
339
|
+
* @returns {void}
|
|
340
|
+
*/
|
|
341
|
+
static restoreScreen(): void;
|
|
304
342
|
}
|
|
305
343
|
//# sourceMappingURL=Term.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Term.d.ts","sourceRoot":"","sources":["../../../src/node/lib/Term.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Term.d.ts","sourceRoot":"","sources":["../../../src/node/lib/Term.js"],"names":[],"mappings":"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"}
|