diff --git a/README.md b/README.md index de63b21..8485d72 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,25 @@ -Supper Simple Spinner for Node.js -================================= +# Supper Simple Spinner for Node.js This is a supper simple spinner / activity indicator for Node.js. I've used it in a few console tools that I've written in Node.js, where I've wanted to show that there is activity and that the program isn't hung. [![NPM](https://nodei.co/npm/simple-spinner.png?downloads=true)](https://nodei.co/npm/simple-spinner/) -How Simple Is It? ------------------ +## Updates -So simple it only has 3 functions. +Now you can use a spinner from [cli-spinners](https://www.npmjs.com/package/cli-spinners) and use a text with the spinner. - * `start([interval in ms], [options])` - * Obviously this starts the spinner. You can give it how quickly you want it to go through the sequence of characters. Defaults to 250ms. - * **Update (2015-07-24)**: start can now also take an options object with the following keys: - * `hideCursor` (boolean, default: false): When true, hide the console cursor (uses TooTallNate/ansi.js) - * `doNotBlock` (boolean, default: false): When true, unref the timer so it does not prevent the process from exiting. - * `stop()` - * I really shouldn't have to explain this one... - * `change_sequence(sequence)` - * Use this if you don't like the default spinning stick. Give it an array of strings like this `[".", "o", "0", "@", "*"]` +## How Simple Is It? +So simple it only has 2 functions. + +- `start([options])` + - Obviously this starts the spinner. + - **Options**: start can take an options object with the following keys: + - `sequence` (string | array, default: "line"): If it is a string, expect the name of a [cli-spinners](https://www.npmjs.com/package/cli-spinners) spinner. The list of spinners can be reviewed at [cli-spinners JSON](https://github.com/sindresorhus/cli-spinners/blob/main/spinners.json). If it is a array, expect an array of strings like this [".", "o", "0", "@", "*"] + - `interval` (integer, default: 250): Specify how to fast the sequence should go in milliseconds. If a spinner from [cli-spinners](https://www.npmjs.com/package/cli-spinners) is given and an interval is not specified, it will be taken from the information of the spinner in the [cli-spinners JSON](https://github.com/sindresorhus/cli-spinners/blob/main/spinners.json). + - `hideCursor` (boolean, default: false): When true, hide the console cursor (uses TooTallNate/ansi.js) + - `doNotBlock` (boolean, default: false): When true, unref the timer so it does not prevent the process from exiting. + - `text` (string, default: ""): Text that will go along with the spinner. +- `stop()` + - I really shouldn't have to explain this one... diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..94f2a49 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,44 @@ +{ + "name": "simple-spinner", + "version": "0.0.5", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "simple-spinner", + "version": "0.0.5", + "dependencies": { + "ansi": "^0.3.0", + "cli-spinners": "^2.8.0" + } + }, + "node_modules/ansi": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz", + "integrity": "sha512-iFY7JCgHbepc0b82yLaw4IMortylNb6wG4kL+4R0C3iv6i+RHGHux/yUX5BTiRvSX/shMnngjR1YyNMnXEFh5A==" + }, + "node_modules/cli-spinners": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.8.0.tgz", + "integrity": "sha512-/eG5sJcvEIwxcdYM86k5tPwn0MUzkX5YY3eImTGpJOZgVe4SdTMY14vQpcxgBzJ0wXwAYrS8E+c3uHeK4JNyzQ==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "ansi": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz", + "integrity": "sha512-iFY7JCgHbepc0b82yLaw4IMortylNb6wG4kL+4R0C3iv6i+RHGHux/yUX5BTiRvSX/shMnngjR1YyNMnXEFh5A==" + }, + "cli-spinners": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.8.0.tgz", + "integrity": "sha512-/eG5sJcvEIwxcdYM86k5tPwn0MUzkX5YY3eImTGpJOZgVe4SdTMY14vQpcxgBzJ0wXwAYrS8E+c3uHeK4JNyzQ==" + } + } +} diff --git a/package.json b/package.json index 7374d60..3aac152 100644 --- a/package.json +++ b/package.json @@ -1,21 +1,25 @@ { - "name": "simple-spinner", - "description": "A super simple spinner", - "keywords": [ - "simple", - "spinner", - "indicator" - ], - "version": "0.0.5", - "licence": "MIT", - "author": "Ian McCall (http://www.ianmccall.codes/)", - "main": "./spinner", - "repository": { - "type": "git", - "url": "https://github.com/dapuck/node-simple-spinner.git" - }, - "homepage": "https://github.com/dapuck/node-simple-spinner", - "dependencies": { - "ansi": "^0.3.0" - } + "name": "simple-spinner", + "description": "A super simple spinner", + "keywords": [ + "simple", + "spinner", + "indicator" + ], + "version": "0.0.6", + "licence": "MIT", + "author": "Ian McCall (http://www.ianmccall.codes/)", + "contributors": [ + "sgb004" + ], + "main": "./spinner", + "repository": { + "type": "git", + "url": "https://github.com/dapuck/node-simple-spinner.git" + }, + "homepage": "https://github.com/dapuck/node-simple-spinner", + "dependencies": { + "ansi": "^0.3.0", + "cli-spinners": "^2.8.0" + } } diff --git a/spinner.js b/spinner.js index 885e536..d066b24 100644 --- a/spinner.js +++ b/spinner.js @@ -1,53 +1,76 @@ /*********** * Spinner * ***********/ -var cursor = require('ansi')(process.stdout); -var spinner = (function() { - var sequence = ["|","/","-","\\"]; //[".", "o", "0", "@", "*"]; - var index = 0; - var timer; - var opts = {}; - - function start(inv, options) { - options = options || {}; - opts = options; - if(options.hideCursor) { - cursor.hide(); - } - - inv = inv || 250; +const cursor = require('ansi')(process.stdout); +const cliSpinners = require('cli-spinners'); + +const spinner = (function () { + let sequence; + let index = 0; + let timer; + let opts = {}; + + function start(options = {}) { + let interval; + + opts = { + sequence: 'line', + interval: 0, + hideCursor: false, + doNotBlock: false, + text: '', + ...options, + }; + + if (opts.hideCursor) cursor.hide(); + interval = buildSequence(opts.interval); index = 0; process.stdout.write(sequence[index]); - timer = setInterval(function() { - process.stdout.write(sequence[index].replace(/./g,"\b")); - index = (index < sequence.length - 1) ? index + 1 : 0; + + timer = setInterval(function () { + clearLine(); + index = index < sequence.length - 1 ? index + 1 : 0; process.stdout.write(sequence[index]); - },inv); - - if(options.doNotBlock) { - timer.unref(); - } + }, interval); + + if (opts.doNotBlock) timer.unref(); } function stop() { clearInterval(timer); - if(opts.hideCursor) { + + if (opts.hideCursor) { cursor.show(); } - process.stdout.write(sequence[index].replace(/./g,"\b")); + clearLine(); + } + + function clearLine() { + process.stdout.write(sequence[index].replace(/./g, '\b')); + process.stdout.clearLine(); } - function change_sequence(seq) { - if(Array.isArray(seq)) { - sequence = seq; + function buildSequence(interval) { + if (Array.isArray(opts.sequence)) { + sequence = opts.sequence; + } else { + const cliSpinner = cliSpinners[opts.sequence]; + if (cliSpinner == undefined) throw new Error('Spinner not found'); + sequence = cliSpinner.frames; + if (interval == 0) interval = cliSpinner.interval; } + + if (sequence.length == 0) throw new Error('Spinner is empty'); + sequence = opts.text ? sequence.map((character) => character + ' ' + opts.text) : sequence; + + if (interval == 0) interval = 250; + return interval; } return { - start: start, - stop: stop, - change_sequence: change_sequence + start, + stop, }; })(); diff --git a/test.js b/test.js index dccc4d4..bbeeb15 100644 --- a/test.js +++ b/test.js @@ -1,33 +1,40 @@ -var spinner = require('./spinner'); +const spinner = require('./spinner'); function test1() { - spinner.start(); - setTimeout(function() { - spinner.stop(); - test2(); - }, 1000); + spinner.start(); + setTimeout(function () { + spinner.stop(); + test2(); + }, 1000); } function test2() { - spinner.change_sequence(["0o0", "o0o"]); - spinner.start(); - setTimeout(function() { - spinner.stop(); - test3(); - }, 1000); + spinner.start({ sequence: ['0o0', 'o0o'] }); + setTimeout(function () { + spinner.stop(); + test3(); + }, 1000); } function test3() { - spinner.start(50,{ hideCursor : true }); - setTimeout(function() { - spinner.stop(); - spinner.start(100, { doNotBlock : true }); - }, 1000); + spinner.start({ sequence: ['0o0', 'o0o'], interval: 50, hideCursor: true }); + setTimeout(function () { + spinner.stop(); + test4(); + }, 1000); } -process.on("exit", function() { - spinner.stop(); - console.log("Have a nice day"); +function test4() { + spinner.start({ sequence: 'dots', interval: 80, text: 'Loading...' }); + setTimeout(function () { + spinner.stop(); + spinner.start({ interval: 100, doNotBlock: true }); + }, 1500); +} + +process.on('exit', function () { + spinner.stop(); + console.log('Have a nice day'); }); test1();