Skip to content

Commit

Permalink
refactor: remove old API and fix bug with current (#71)
Browse files Browse the repository at this point in the history
* refactor: remove old API and fix bug with current

* refactor: migrate to TS

* ci: add Node.js 18.x

* refactor: remove utils & logSymbols & add SafeSpinner API

* refactor: rename SafeSpinner

* test: add minimal UT

* fix: script infinite while

* chore: remove v16.x support
  • Loading branch information
fraxken authored Jan 26, 2023
1 parent 2d11230 commit ba73a37
Show file tree
Hide file tree
Showing 14 changed files with 2,076 additions and 2,890 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16.x]
node-version: [18.x]
fail-fast: false
steps:
- uses: actions/checkout@v2
Expand Down
4 changes: 1 addition & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,5 @@ typings/
# dotenv environment variables file
.env

# JSDoc
docs/
jsdoc/
temp/
dist/
186 changes: 42 additions & 144 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ All available spinners are part of [cli-spinners](https://github.com/sindresorhu
</p>

## Requirements
- [Node.js](https://nodejs.org/en/) v16 or higher
- [Node.js](https://nodejs.org/en/) v18 or higher

## Getting Started

Expand All @@ -27,12 +27,14 @@ $ yarn add @topcli/spinner

## Usage example
Create and wait multiple spinner at a time.

```js
import * as timers from "node:timers/promises";
import Spinner from "@topcli/spinner";
import { Spinner } from "@topcli/spinner";

async function fnWithSpinner(prefixText, succeed = true) {
const spinner = new Spinner({ prefixText }).start("Start working!");
async function fnWithSpinner(withPrefix, succeed = true) {
const spinner = new Spinner()
.start("Start working!", { withPrefix });

await timers.setTimeout(1000);
spinner.text = "Work in progress...";
Expand All @@ -46,197 +48,93 @@ async function fnWithSpinner(prefixText, succeed = true) {
}
}

await Spinner.startAll([
fnWithSpinner,
Spinner.create(fnWithSpinner),
Spinner.create(fnWithSpinner, "Item 1"),
Spinner.create(fnWithSpinner, "Item 2", false)
await Promise.allSettled([
fnWithSpinner(),
fnWithSpinner("Item 1"),
fnWithSpinner("Item 2", false)
]);
Spinner.reset(); // reset internal count
console.log("All spinners finished!");
```

If you want to only achieve one Spinner by one Spinner, use it like Ora (it will work)
```js
const spinner = new Spinner().start("Start working!");

await sleep(1000);
await timers.setTimeout(1_000);
spinner.text = "Work in progress...";

await sleep(1000);
await timers.setTimeout(1_000);
spinner.succeed("All done !");
```

> 👀 When you are working on a CLI that can be used as an API too, the **verbose** option allow you to disable the Spinner.
## API

Spinner line structure : `${spinner} ${prefixText} - ${text}`

Properties :
```ts
declare namespace Spinner {
public spinner: cliSpinners.Spinner;
public prefixText: string;
public text: string;
public color: string;
public started: boolean;
public startTime: number;
public stream: TTY.WriteStream;
public readonly elapsedTime: number;
}
```

- `spinner`: spinner type (default: `"dots"`)
- `prefixText`: mostly used to differentiate each spinner
- `text`: you can change text at any moment.
- `color`: spinner color
- `elapsedTime`: time elapsed since start() call


<details><summary>constructor(options?: Spinner.options)</summary>
<details><summary>constructor(options?: ISpinnerOptions)</summary>
<br>

Create a new Spinner object. **options** is described by the following TypeScript interface:
Create a new Spinner. The **options** payload is described by the following TypeScript interface:

```ts
declare namespace Spinner {
interface spinnerObj {
frames: string[];
interval: number;
}

interface options {
spinner: SpinnerObj | Spinner.spinners;
text: string;
prefixText: string;
color: string;
verbose: boolean;
}
export interface ISpinnerOptions {
/**
* Spinner name (from cli-spinners lib)
*
* @default "dots"
*/
name?: cliSpinners.SpinnerName;
/**
* Spinner frame color
*
* @default "white"
*/
color?: string;
/**
* Do not log anything when disabled
*
* @default true
*/
verbose?: boolean;
}
```

> 👀 Look [cli-spinners](https://github.com/sindresorhus/cli-spinners#readme) for all kind of available spinners.
> 👀 Check [cli-spinners](https://github.com/sindresorhus/cli-spinners#readme) for all the spinner name.
Example:
```js
import Spinner from "@topcli/spinner";

const spinner = new Spinner();
const dotsSpinner = new Spinner({ spinner: "dots" });
new Spinner({ name: "dots2" });
```
</details>


<details><summary>static startAll(functions: Spinner.Handler[], options?: Spinner.startOpt): Promise&ltany[]&gt</summary>
<br>
Start all functions with spinners passed in array.

> ⚠️ Only accept functions that return a Promise.
Options is described by the following TypeScript interface:
```ts
declare namespace Spinner {
type RecapSet = "none" | "error" | "always";

interface startOpt {
recap: RecapSet;
rejects: boolean;
}
}
```
> Default recap : `always`
</details>

<details><summary>static create(fn: Spinner.Handler, args?: any): Function|[Function, ...any]</summary>
<br>
This method allow to pass arguments to our spinner function. This method prevent execute function to earlier.
<details><summary>start(text?: string, options?: IStartOptions): Spinner</summary>

```js
async function fnWithSpinner(prefixText) {
const spinner = new Spinner({ prefixText }).start("Start working!");
Start the spinner and optionaly write the text passed as first parameter.

await new Promise((resolve) => setTimeout(resolve, 1000));
spinner.text = "Work in progress...";
The **options** payload is described by the following TypeScript interface:

await new Promise((resolve) => setTimeout(resolve, 1000));
spinner.succeed("All done !");
```ts
export interface IStartOptions {
withPrefix?: string;
}

Spinner.startAll([
fnWithSpinner("Item 1"), // <-- Wrong, it's executed directly, not in startAll
Spinner.create(fnWithSpinner, "Item 2") // <-- What you should do
])
.then(() => console.log("All spinners finished!"))
.catch(console.error);
```
</details>

-------------------------------------------------

<details><summary>start(text?: string): Spinner</summary>

Start the spinner in the CLI and write the text passed in param.
```js
import Spinner from "@topcli/spinner";

async function fnWithSpinner() {
const spinner = new Spinner().start("Start working!");
}

Spinner.startAll([
fnWithSpinner
])
.then(() => console.log("All spinners finished!"))
.catch(console.error);
```
</details>

<details><summary>succeed(text?: string): void</summary>

Stop the spinner in the CLI, write the text passed in param and mark it as succeed with a symbol.
```js
import Spinner from "@topcli/spinner";

async function fnWithSpinner() {
const spinner = new Spinner().start("Start working!");

await new Promise((resolve) => setTimeout(resolve, 1000));
spinner.succeed("All done !");
}

Spinner.startAll([
fnWithSpinner
])
.then(() => console.log("All spinners finished!"))
.catch(console.error);
```
</details>

<details><summary>failed(text?: string): void</summary>

Stop the spinner in the CLI, write the text passed in param and mark it as failed with a symbol.

```js
import Spinner from "@topcli/spinner";

async function fnWithSpinner() {
const spinner = new Spinner().start("Start working!");

await new Promise((resolve) => setTimeout(resolve, 1000));
spinner.failed("Something wrong happened !");
}

Spinner.startAll([
fnWithSpinner
])
.then(() => console.log("All spinners finished!"))
.catch(console.error);
```
</details>
<br>

> ⚠️ Functions **start()**, **succeed()** and **failed()** are supposed to be executed in a function which return a promise and will be called by Spinner.startAll().
## Contributors ✨

<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
Expand Down
59 changes: 0 additions & 59 deletions index.d.ts

This file was deleted.

Loading

0 comments on commit ba73a37

Please sign in to comment.