npm package: @haydenhigg/spinner
Description: A minimal library for creating spinners for command-line apps and utilities.
Author: Hayden Higginbotham
Latest version: 1.0.0

# @haydenhigg/spinner

This is a minimal library for creating spinners for CLIs.

## Basic Usage

```javascript
const Spinner = require('@haydenhigg/spinner');

var options = {
  message: 'loading',
  frames: Spinner.spinners[34],
  onStop: () => console.log('finished loading')
};

var spinner = new Spinner(options);

spinner.resume();

// do some stuff

spinner.stop(); // prints 'finished loading'
```

### The options

All available options and their defaults are shown below.

```javascript
{
  rate = 12.5, // 12.5 fps, 80 ms/frame
  frames = ['/', '-', '\\', '|'],
  message = '',
  direction = 1, // 1 is progressing through frames, -1 is regressing
  onResume = () => {}, // called in .resume()
  onUpdate = () => {}, // called each frame
  onPause = () => {}, // called in .pause(cb?)
  onStop = () => {}, // called in .stop(cb?)
  onInterrupt = () => { // clear line, call onStop, exit
    this._clear();
    this._onStop.call(this);
    process.exit(0);
  }
}
```

### Some important details

- The `rate` options is in FPS, not ms per frame
- The `frames` option is just an array of strings, and is usually retrieved from Spinner.spinners (an array)
- The listeners (`onResume`, `onUpdate`, `onPause`, `onStop`, `onInterrupt`) take no arguments. Within the body of each function, however, `this` is bound to the instance the function is called from
- `onInterrupt` is the only action taken on SIGINT (CTRL+C), so if you want SIGINT to still stop execution then you must call process.exit from within the callback
- The `_clear` method is for clearing the current line and resetting the cursor
- Every option passed to the constructor is assigned to a property with the same name, prefixed by an underscore (`_rate`, `_frames`, `_message`, etc.)
- There is a property called `_frameCounter` that is just the number of frames that have passed since the spinner has resumed the first time
- The `stop` method is exactly the same as the `pause` method except that it calls `_clear` internally, and the two methods of course have different listeners
- `stop` and `pause` can both be called with a callback to override the default listener as defined by the `_onStop` and `_onPause` properties, respectively
- `stop` and `pause` wait until the next frame to take effect

## Advanced Usage

There was some functionality that would be difficult to provide a clean way to implement as a part of the package, so some common things that you may want to do are provided below:

To run the animation both ways (instead of frames 1,2,3,4 and repeat, it would show frame 1,2,3,4,3,2 and repeat):
```javascript
// inside the onUpdate callback:
if ((this._pointer === 0 && this._frameCounter > 0) || this._pointer === this._frames.length - 1) {
  this._direction *= -1;
}
```

To create stylized (colored, blinking, bold, italic, etc.) frames;
```javascript
// when setting the frames property:
frames.map(f => '\u001b[34m' + f + '\u001b[39m')
// or using a library like @haydenhigg/pastel
frames.map(pastel.blue)
```

To see all available animations, go to "framesets.js"