diff --git a/index.js b/index.js index e098c14..0d951ad 100644 --- a/index.js +++ b/index.js @@ -7,9 +7,7 @@ import stripAnsi from 'strip-ansi'; import wcwidth from 'wcwidth'; import isInteractive from 'is-interactive'; import isUnicodeSupported from 'is-unicode-supported'; -import {StdinDiscarder} from './utilities.js'; - -let stdinDiscarder; +import stdinDiscarder from 'stdin-discarder'; class Ora { #linesToClear = 0; @@ -30,10 +28,6 @@ class Ora { color; constructor(options) { - if (!stdinDiscarder) { - stdinDiscarder = new StdinDiscarder(); - } - if (typeof options === 'string') { options = { text: options, diff --git a/package.json b/package.json index 45ef518..7f6ef46 100644 --- a/package.json +++ b/package.json @@ -20,8 +20,7 @@ }, "files": [ "index.js", - "index.d.ts", - "utilities.js" + "index.d.ts" ], "keywords": [ "cli", @@ -40,13 +39,13 @@ "idle" ], "dependencies": { - "bl": "^5.0.0", "chalk": "^5.0.0", "cli-cursor": "^4.0.0", "cli-spinners": "^2.6.1", "is-interactive": "^2.0.0", "is-unicode-supported": "^1.1.0", "log-symbols": "^5.1.0", + "stdin-discarder": "^0.1.0", "strip-ansi": "^7.0.1", "wcwidth": "^1.0.1" }, diff --git a/readme.md b/readme.md index e837459..727556f 100644 --- a/readme.md +++ b/readme.md @@ -128,7 +128,7 @@ Default: `true` Discard stdin input (except Ctrl+C) while running if it's TTY. This prevents the spinner from twitching on input, outputting broken lines on Enter key presses, and prevents buffering of input while the spinner is running. -This has no effect on Windows as there's no good way to implement discarding stdin properly there. +This has no effect on Windows as there is no good way to implement discarding stdin properly there. ### Instance diff --git a/utilities.js b/utilities.js deleted file mode 100644 index d4c9731..0000000 --- a/utilities.js +++ /dev/null @@ -1,85 +0,0 @@ -import process from 'node:process'; -import readline from 'node:readline'; -import {BufferListStream} from 'bl'; - -const ASCII_ETX_CODE = 0x03; // Ctrl+C emits this code - -export class StdinDiscarder { - #requests = 0; - #mutedStream = new BufferListStream(); - #ourEmit; - #rl; - - constructor() { - this.#mutedStream.pipe(process.stdout); - - const self = this; // eslint-disable-line unicorn/no-this-assignment - this.#ourEmit = function (event, data, ...args) { - const {stdin} = process; - if (self.#requests > 0 || stdin.emit === self.#ourEmit) { - if (event === 'keypress') { // Fixes readline behavior - return; - } - - if (event === 'data' && data.includes(ASCII_ETX_CODE)) { - process.emit('SIGINT'); - } - - Reflect.apply(self.#ourEmit, this, [event, data, ...args]); - } else { - Reflect.apply(process.stdin.emit, this, [event, data, ...args]); - } - }; - } - - start() { - this.#requests++; - - if (this.#requests === 1) { - this._realStart(); - } - } - - stop() { - if (this.#requests <= 0) { - throw new Error('`stop` called more times than `start`'); - } - - this.#requests--; - - if (this.#requests === 0) { - this._realStop(); - } - } - - // TODO: Use private methods when targeting Node.js 14. - _realStart() { - // No known way to make it work reliably on Windows - if (process.platform === 'win32') { - return; - } - - this.#rl = readline.createInterface({ - input: process.stdin, - output: this.#mutedStream, - }); - - this.#rl.on('SIGINT', () => { - if (process.listenerCount('SIGINT') === 0) { - process.emit('SIGINT'); - } else { - this.#rl.close(); - process.kill(process.pid, 'SIGINT'); - } - }); - } - - _realStop() { - if (process.platform === 'win32') { - return; - } - - this.#rl.close(); - this.#rl = undefined; - } -}