diff --git a/package.json b/package.json index 8d52110..9fb731f 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "author": "PondWader", "description": "A lightweight, no dependency, pluggable CLI spinner library.", "scripts": { - "build": "tsup ./src/index.ts --format cjs,esm --dts --minify", + "build": "tsup ./src/index.ts --format cjs,esm --dts", "format": "prettier --write src", "test": "tsc && c8 --exclude-after-remap node --test", "lint": "npm run lint:format && eslint src", diff --git a/src/index.ts b/src/index.ts index c07e33a..ed8c818 100644 --- a/src/index.ts +++ b/src/index.ts @@ -45,6 +45,7 @@ export class Spinner { start(tickMs = constants.DEFAULT_TICK_MS) { if (this.running) throw new Error('Spinner is already running.'); + if (this.component.finished) this.component.finished = false; this.interval = setInterval(this.tick.bind(this), tickMs); this.running = true; @@ -62,19 +63,17 @@ export class Spinner { } private onProcessExit = (signal?: string | number) => { - if (this.running) { - this.stop(); - // SIGTERM is 15, SIGINT is 2 - let signalCode; - if (signal === 'SIGTERM') { - signalCode = 15 + 128; - } else if (signal === 'SIGINT') { - signalCode = 2 + 128; - } else { - signalCode = Number(signal); - } - process.exit(signalCode); + this.stop(); + // SIGTERM is 15, SIGINT is 2 + let signalCode; + if (signal === 'SIGTERM') { + signalCode = 15 + 128; + } else if (signal === 'SIGINT') { + signalCode = 2 + 128; + } else { + signalCode = Number(signal); } + process.exit(signalCode); }; private addListeners() { @@ -111,7 +110,6 @@ export class Spinner { setText(text: string, render = true) { this.text = text; if (this.running) { - // Clear width cache if (render) this.refresh(); } } diff --git a/src/test/spinner-test.ts b/src/test/spinner-test.ts index 26001aa..8c207b9 100644 --- a/src/test/spinner-test.ts +++ b/src/test/spinner-test.ts @@ -1,7 +1,7 @@ import * as assert from 'node:assert/strict'; import {test} from 'node:test'; import {Spinner, Symbols, renderer} from '../index.js'; -import {createFinishingRenderedLine, createRenderedLine, createRenderedOutput, interceptStdout, TickMeasuredSpinner} from './utils.js'; +import {createFinishingRenderedLine, createRenderedLine, createRenderedOutput, interceptStdout, suppressStdout, TickMeasuredSpinner} from './utils.js'; import process from 'node:process'; import * as constants from '../constants.js'; @@ -110,6 +110,25 @@ test('end methods', async (t) => { process.exit = originalExit; } }); + + await t.test('restart finished spinner with new component', async () => { + const unsuppressStdout = suppressStdout(); + + const spinner = new Spinner(); + try { + spinner.start(); + spinner.succeed(); + assert.ok(spinner['component'].finished, 'component is finished'); + spinner.start(); + assert.ok(!spinner['component'].finished, 'component is not finished'); + spinner.stop(); + } catch (err) { + spinner.stop(); + throw err; + } finally { + unsuppressStdout(); + } + }); }); async function testSpinner(frames?: string[], text?: string, symbolFormatter?: (v: string) => string) {