npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@2toad/fluent-state

v2.0.1

Published

A fluent JavaScript State Machine with full TypeScript support

Downloads

16

Readme

Fluent State 🔄

GitHub Release Downloads Build status

A fluent JavaScript State Machine with full TypeScript support

Getting Started

Install package

npm i @2toad/fluent-state

Usage

import { fluentState } from '@2toad/fluent-state';
// or
const { fluentState } = require('@2toad/fluent-state');
fluentState
  .from('vegetable').to('diced').or('pickled')
  .from('diced').to('salad').or('trash');

fluentState
  .when('diced').do(() => console.log('diced'));

fluentState.transition('diced');
// or
fluentState.next();

API

Properties

state: State;

The current state

Methods

from(name: string): State

Adds a state

// Add the 'vegetable' state
fluentState.from('vegetable');

to(name: string): Transition

Adds a transition to a state

fluentState
  .from('vegetable') // Add the 'vegetable' state
  .to('diced');      // add the 'diced' state, with a transtion from 'vegetable'

or(name: string): Transition

Adds a transition to a state

fluentState
  .from('vegetable') // Add the 'vegetable' state
  .to('diced')       // add the 'diced' state, with a transtion from 'vegetable'
  .or('pickled')     // add the 'pickled' state, with a transtion from 'vegetable'
  .or('discarded');  // add the 'discarded' state, with a transtion from 'vegetable'

setState(name: string): void

Explicitly set the state without triggering a transition

fluentState.setState('diced');

NOTE: the state is initially set to the first state you add via from(), and it is implicitly set when you transition to a new state via transition() or next()

has(name: string): boolean

Returns true if the state exists

fluentState.has('vegetable');

remove(name: string): void

Removes a state (and all of its transitions)

fluentState.remove('vegetable');

clear(): void

Removes all states

fluentState.clear();

transition(...names: string[]): boolean

  • Transitions to another state.
  • If multiple states are specified, a state is chosen at random.
  • Returns true upon success.
// Transition to the 'diced' state
fluentState.transition('diced');

// Transition to the 'diced' or 'discarded' state (selected at random)
fluentState.transition('diced', 'discarded');

next(...exclude: string[]): boolean

  • If the current state contains a single transition, that state is transitioned to.
  • If the current state contains multiple transitions, a transition is selected at random.
    • With the option to exclude specified states from the random selection.
  • Returns true upon success.
fluentState.next();

// A random state, excluding 'pickled' and 'discarded'
fluentState.next('pickled', 'discarded');

Callbacks

You can add callbacks to any state

when(name: string): Event

Specifies the state you want to add a callback to

fluentState.when('diced');

do(handler: (previousState: State, fluentState: FluentState) => any): Handler

Adds a callback

fluentState
  .when('diced')
  .do((previousState, fluentState) => {
    console.log(`Transitioned from "${previousState.name}"`);
  });

and(handler: (previousState: State, fluentState: FluentState) => any): Handler

Adds another callback

fluentState
  .when('diced')
  .do(() => console.log('Transitioned to "diced"'))
  .and((previousState, fluentState) => {
    console.log(`Transitioned from "${previousState.name}"`);
  });

And of course it's all chainable

fluentState
  .when('diced').do(() => console.log('Transitioned to "diced"'))
  .when('pickled').do(() => console.log('Transitioned to "pickled"'));

Lifecycle

You can hook into the state machine lifecycle via the observe method.

fluentState.observe(Lifecycle.BeforeTransition, (currentState, newState) => {
  // You can prevent the transition by returning false from this event
  return false;
});

// Chainable
fluentState
  .observe(Lifecycle.FailedTransition, () => console.log('Transition failed'))
  .observe(Lifecycle.FailedTransition, () => console.log('Multiple hooks allowed on each event'))
  .observe(Lifecycle.AfterTransition, () => console.log('Transition complete'));

Events

Order: BeforeTransition -> FailedTransition -> AfterTransition

  • BeforeTransition

    (currentState: State, nextState: string): boolean
  • FailedTransition

    (currentState: State, targetState: string): void
  • AfterTransition

    (previousState: State, currentState: State): void

Contributing 🤝

So you want to contribute to the Fluent State project? Fantastic! Please read the Contribute doc to get started.