# @lytics/wiz

> A specification for modeling wizard workflows, like the ones used in Lytics products, and a library for consuming these models.

Latest version **3.0.0** (published 2022-06-01) · MIT license · 0 weekly downloads

## Install

```sh
npm install @lytics/wiz
pnpm add @lytics/wiz
yarn add @lytics/wiz
bun add @lytics/wiz
```

Provides the command `validate-wiz-spec`.

## Health

**Score 30/100 (F)** — status: abandoned.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 3.0.0 |
| Published | 2022-06-01 |
| First published | 2020-11-23 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 4 |
| Unpacked size | 106.3 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Maintainers | lyticsnpm |

## Links

- npm: https://www.npmjs.com/package/@lytics/wiz
- npm.io page: https://npm.io/package/@lytics/wiz

## Dependencies (4)

- [chalk](https://npm.io/package/chalk.md) ^4.1.0
- [husky](https://npm.io/package/husky.md) ^4.3.0
- [get-stdin](https://npm.io/package/get-stdin.md) ^8.0.0
- [jsonschema](https://npm.io/package/jsonschema.md) ^1.4.0

## Recent versions

- 3.0.0 (latest) — 2022-06-01
- 2.0.0 — 2022-01-04
- 1.1.0 — 2021-09-15
- 1.0.5 — 2021-01-28
- 1.0.4 — 2021-01-21
- 1.0.3 — 2021-01-07
- 1.0.2 — 2020-12-10
- 1.0.1 — 2020-11-25
- 1.0.0 — 2020-11-23

## README

# @lytics/wiz

A specification for modeling wizard workflows, like the ones used in Lytics products, and a library for consuming these models.

## installation

```
npm install @lytics/wiz
```

## playground

- [An Observable notebook for tinkering with the library](https://observablehq.com/@humanchimp/lytics-wiz-d3-playground)

## examples

Importing the `enter` function from the library:

```javascript
import { enter } from "@lytics/wiz";
```

Define and navigate immutable wizards:

```javascript
// Simple case of a wizard with no branches
const entry = enter([{ id: "1" }, { id: "2" }, { id: "3" }]);

const secondStep = entry.next();

const thirdStep = entry.next().next();

assert(secondStep.next() === thirdStep);

assert(thirdStep.prev() === secondStep);

assert(thirdStep.prev().prev() === entry);
```

Wizards can have alternate steps:

```javascript
const entry = enter([{ id: "1", alt: "1.5" }, { id: "1.5"}, { id: "2" }]);

const secondStep = entry.next();

const alternateStep = entry.alt();

// Subsequent steps have distinct identities...
assert(secondStep.next() !== alternateStep.next());

// ...because you need to be able to navigate back to the correct previous step...
assert(secondStep.next().prev() === secondStep);
assert(alternateStep.next().prev() === alternateStep);

// ...but they both point the same underlying spec...
assert(secondStep.next().spec === alternateStep.next().spec);

// ...going backwards we can arrive at the same entry node...
assert(secondStep.prev() === alternateStep.prev());
```

Wizards can have choicepoints:

```javascript
const entry = enter({
  entrypoint: "choice",
  choices: [
    {
      id: "choice",
      options: ["wimp", "shrimp"]
    }
  ],
  steps: [
    { id: "wimp" },
    { id: "shrimp" }
  ],
});

entry.next(); // Throws! a selection is required.
entry.next("opus"); // Throws! valid options are wimp, shrimp

const wimpCard = entry.next("wimp");
const shrimpCard = entry.next("shrimp");

// ...you can navigate to the previous card
assert(wimpCard.prev() === shrimpCard.prev());

// ...there is no "memory"
wimpCard.prev().next(); // Throws! a selection is required.

// ...for "memory", retain a reference in your program...
assert(wimpCard === entry.next("wimp"));
```

Wizards can specify flows, which are sequences of steps:

```javascript
const { enter } = LyticsWiz;

const simpleFlow = enter({
  entrypoint: "flow",
  flows: [
    {
      id: "flow",
      steps: ["one", "two", "three"],
    },
  ],
  steps: [{ id: "one" }, { id: "two" }, { id: "three" }],
});
```

These features compose orthogonally to one another. Here is kitchen sink example using flows, choices, and alts:

```javascript
const { enter } = LyticsWiz;

const checkoutFlow = enter({
  entrypoint: "gratuity",
  choices: [
    {
      id: "gratuity",
      options: [
        { when: "10-percent", goto: "payment-method" },
        { when: "20-percent", goto: "payment-method" },
        { when: "30-percent", goto: "heavy-tipper" },
      ],
    },
  ],
  flows: [
    {
      id: "heavy-tipper",
      steps: ["thanks-dude", "payment-method"],
    },
  ],
  steps: [
    { id: "payment-method" },
    { id: "thanks-dude", alt: "secret-promo" },
    { id: "secret-promo" },
  ],
});

// normal tip amounts route to the payment-method step
assert(step.next("10-percent").spec.id === "payment-method");
assert(step.next("20-percent").spec.id === "payment-method");

// 30-percent routes to the heavy-tipper flow
assert(step.next("30-percent").spec.id === "thanks-dude");

// "next" continuation routes back to the payment-method step
assert(step.next("30-percent").next().spec.id === "payment-method");

// "alt" continution routes to the secret-promo step before the payment-method step
assert(step.next("30-percent").alt().spec.id === "secret-promo");
assert(step.next("30-percent").alt().next().spec.id === "payment-method");
```

## docs

- [API Docs](doc/modules/_src_wiz_.md)

## specification

- [JSONSchema](schema.json)

---
_Source: https://npm.io/package/@lytics/wiz · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
