diff --git a/.gitignore b/.gitignore index 3c3629e..d97910c 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,9 @@ +### Node ### + +# Logs +logs +*.log +npm-debug.log* + +# Dependency directory node_modules diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..cf19192 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,11 @@ +language: node_js +node_js: + - "5.5" + - "5.4" + - "5.3" + - "5.2" + - "5.1" + - "5.0" + - "4.2" + - "4.1" + - "4.0" diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0bbef25 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2015 Ivan Gabriele + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/LICENSE.txt b/LICENSE.txt deleted file mode 100644 index 38c6bf2..0000000 --- a/LICENSE.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) [year] [fullname] - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README.md b/README.md index de63b21..f695a1b 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,58 @@ -Supper Simple Spinner for Node.js -================================= +# loading-spinner +**Loading spinner for NodeJS.** -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. +[![Build Status](https://travis-ci.org/ivangabriele/loading-spinner.svg?branch=master)](https://travis-ci.org/ivangabriele/loading-spinner) +[![NPM Version](https://img.shields.io/npm/v/loading-spinner.svg?style=flat)](https://www.npmjs.org/package/loading-spinner) +[![NPM Downloads](https://img.shields.io/npm/dm/loading-spinner.svg?style=flat)](https://www.npmjs.org/package/loading-spinner) +[![Dependency Status](https://david-dm.org/ivangabriele/loading-spinner.svg)](https://david-dm.org/ivangabriele/loading-spinner) -[![NPM](https://nodei.co/npm/simple-spinner.png?downloads=true)](https://nodei.co/npm/simple-spinner/) +--- -How Simple Is It? ------------------ +## Installation -So simple it only has 3 functions. + npm install loading-spinner --save - * `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", "@", "*"]` +## Usage + var loadingSpinner = require('loading-spinner'); + + // Start the loading spinner + loadingSpinner.start( + [Integer, default: 100], // Interval (in ms) between each spinner sequence element + { + clearChar: [Boolean, default: false], // Clear the spinner when stop() is called + clearLine: [Boolean, default: false], // Clear the entire line when stop() is called + doNotBlock: [Boolean, default: false], // Does not prevent the process from exiting + hideCursor: [Boolean, default: false] // Hide the cursor until stop() is called + } + ); + + // Stop the loading spinner + loadingSpinner.stop(); + + // Customize the spinner sequence + loadingSpinner.setSequence( + [Array, default: ['|','/','-','\\']], // Sequence of spinner elements + ); + +## Example + + var loadingSpinner = require('loading-spinner'); + + var dary = function() { + loadingSpinner.stop(); + + process.stdout.write('DA-RY !'); + }; + + var legend = function() { + process.stdout.write('It\'s gonna be LE-GEN... Wait for it... '); + + loadingSpinner.start(100, { + clearChar: true + }); + + setTimeout(dary, 1000); + }; + + legend(); diff --git a/lib/loading-spinner.js b/lib/loading-spinner.js new file mode 100644 index 0000000..3e4d44a --- /dev/null +++ b/lib/loading-spinner.js @@ -0,0 +1,68 @@ +const cursor = require('ansi')(process.stdout); +const readline = require('readline'); + +var loadingSpinner = (function() { + var index = 0, + sequence = ['|', '/', '-', '\\'], + settings = {}, + spinnerTimer; + + function start(interval, options) { + interval = interval || 100; + options = options || {}; + + settings = { + clearChar: !!options.clearChar, + clearLine: !!options.clearLine, + doNotBlock: !!options.doNotBlock, + hideCursor: !!options.hideCursor + }; + + if (settings.hideCursor) { + cursor.hide(); + } + + index = 0; + process.stdout.write(sequence[index]); + spinnerTimer = setInterval(function() { + process.stdout.write(sequence[index].replace(/./g, '\b')); + index = (index < sequence.length - 1) ? index + 1 : 0; + process.stdout.write(sequence[index]); + }, interval); + + if (settings.doNotBlock) { + spinnerTimer.unref(); + } + } + + function stop() { + clearInterval(spinnerTimer); + + if (settings.clearChar) { + readline.moveCursor(process.stdout, -1, 0); + readline.clearLine(process.stdout, 1); + } + + if (settings.clearLine) { + readline.clearLine(process.stdout, 0); + } + + if (settings.hideCursor) { + cursor.show(); + } + } + + function setSequence(customSequence) { + if (customSequence.constructor === Array) { + sequence = customSequence; + } + } + + return { + start: start, + stop: stop, + setSequence: setSequence + }; +})(); + +module.exports = loadingSpinner; diff --git a/package.json b/package.json index 7374d60..f3e9837 100644 --- a/package.json +++ b/package.json @@ -1,15 +1,31 @@ { - "name": "simple-spinner", - "description": "A super simple spinner", + "name": "loading-spinner", + "main": "./lib/loading-spinner", + "version": "1.1.0", + "description": "Loading spinner for NodeJS.", + "scripts": { + "test": "mocha" + }, + "author": { + "name": "Ivan Gabriele", + "email": "ivan.gabriele@gmail.com", + "url": "http://www.ivangabriele.com" + }, + "contributors": [ + { + "name": "Ian McCall", + "email": "imccall@da-puck.com", + "url": "http://www.ianmccall.codes" + } + ], + "license": "MIT", "keywords": [ - "simple", - "spinner", - "indicator" + "load", + "loading", + "bar", + "indicator", + "spinner" ], - "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" @@ -17,5 +33,8 @@ "homepage": "https://github.com/dapuck/node-simple-spinner", "dependencies": { "ansi": "^0.3.0" + }, + "devDependencies": { + "mocha": "^2.4.5" } } diff --git a/spinner.js b/spinner.js deleted file mode 100644 index 885e536..0000000 --- a/spinner.js +++ /dev/null @@ -1,54 +0,0 @@ -/*********** - * 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; - 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; - process.stdout.write(sequence[index]); - },inv); - - if(options.doNotBlock) { - timer.unref(); - } - } - - function stop() { - clearInterval(timer); - if(opts.hideCursor) { - cursor.show(); - } - - process.stdout.write(sequence[index].replace(/./g,"\b")); - } - - function change_sequence(seq) { - if(Array.isArray(seq)) { - sequence = seq; - } - } - - return { - start: start, - stop: stop, - change_sequence: change_sequence - }; -})(); - -module.exports = spinner; diff --git a/test.js b/test.js deleted file mode 100644 index dccc4d4..0000000 --- a/test.js +++ /dev/null @@ -1,33 +0,0 @@ -var spinner = require('./spinner'); - -function test1() { - spinner.start(); - setTimeout(function() { - spinner.stop(); - test2(); - }, 1000); -} - -function test2() { - spinner.change_sequence(["0o0", "o0o"]); - spinner.start(); - setTimeout(function() { - spinner.stop(); - test3(); - }, 1000); -} - -function test3() { - spinner.start(50,{ hideCursor : true }); - setTimeout(function() { - spinner.stop(); - spinner.start(100, { doNotBlock : true }); - }, 1000); -} - -process.on("exit", function() { - spinner.stop(); - console.log("Have a nice day"); -}); - -test1(); diff --git a/test/loading-spinner.js b/test/loading-spinner.js new file mode 100644 index 0000000..4b05c95 --- /dev/null +++ b/test/loading-spinner.js @@ -0,0 +1,48 @@ +var loadingSpinner = require('../lib/loading-spinner'); + +var dary = function() { + loadingSpinner.stop(); + process.stdout.write('DA-RY !'); +}; + +var legend = function() { + process.stdout.write('It\'s gonna be LE-GEN... Wait for it... '); + loadingSpinner.start(100, { + clearChar: true + }); + setTimeout(dary, 1000); +}; + +legend(); + +/*function test1() { + loadingSpinner.start(); + setTimeout(function() { + loadingSpinner.stop(); + test2(); + }, 1000); +} + +function test2() { + loadingSpinner.changeSequence(['0o0', 'o0o']); + loadingSpinner.start(); + setTimeout(function() { + loadingSpinner.stop(); + test3(); + }, 1000); +} + +function test3() { + loadingSpinner.start(50,{ hideCursor : true }); + setTimeout(function() { + loadingSpinner.stop(); + loadingSpinner.start(100, { doNotBlock : true }); + }, 1000); +} + +process.on('exit', function() { + loadingSpinner.stop(); + console.log('Have a nice day'); +}); + +test1();*/