Skip to content

machty/ember-statecharts

 
 

Repository files navigation

ember-statecharts CI Ember Observer Score

This addon provides a statechart abstraction based on XState for adding statecharts to your Ember.js application. Statecharts can be used to describe complex behaviour of your objects and separate ui-concern from behavioral concerns in your applications. This is especially useful in Ember.Component-architecture but can be used across all layers of your application (e.g. when implementing global application state).

View the docs here.

Compatibility

  • Ember.js v3.24 or above
  • Ember CLI v3.20 or above
  • Node.js v12 or above

For classic Ember.js-versions pre Ember Octane please use the 0.8.x-version of this addon.

For Ember.js versions < 3.24 please use the 0.13.x-version of this addon.

Installation

ember install ember-statecharts

Because ember-statecharts works with XState internally you have to install it as a dependency as well.

yarn add --dev xstate

or

npm install --save-dev xstate

Usage

Statecharts have been around for a long time and have been used to model stateful, reactive system successfully. You can read about statecharts in the original paper Statecharts - A Visual Formalism for Complex Systems by David Harel.

With statecharts we finally have a good abstraction to model and discuss behaviour with other stakeholders of our applications in addition to a design language that visualizes this behaviour. Here's an example of a button component:

button

In addition to their modeling capabilities Statecharts are executable and can be used to drive user experience behavior in your Ember.js applications:

import Component from '@glimmer/component';
import { action } from '@ember/object';
import { task } from 'ember-concurrency';

import { matchesState, useMachine } from 'ember-statecharts';
import { Machine } from 'xstate';

function noop() {}

const buttonMachine = Machine(
  {
    initial: 'idle',
    states: {
      idle: {
        on: {
          SUBMIT: 'busy',
        },
      },
      busy: {
        entry: ['handleSubmit'],
        on: {
          SUCCESS: 'success',
          ERROR: 'error',
        },
      },
      success: {
        entry: ['handleSuccess'],
        on: {
          SUBMIT: 'busy',
        },
      },
      error: {
        entry: ['handleError'],
        on: {
          SUBMIT: 'busy',
        },
      },
    },
  },
  {
    actions: {
      handleSubmit() {},
      handleSuccess() {},
      handleError() {},
    },
  }
);

export default class QuickstartButton extends Component {
  get onClick() {
    return this.args.onClick || noop;
  }

  statechart = useMachine(this, () => {
    const { performSubmitTask, onSuccess, onError } = this;

    return {
      machine: quickstartButtonMachine.withConfig({
        actions: {
          handleSubmit: performSubmitTask,
          handleSuccess: onSuccess,
          handleError: onError,
        },
      }),
    };
  });

  @matchesState('busy')
  isBusy;

  get isDisabled() {
    return this.isBusy || this.args.disabled;
  }

  @task(function* () {
    try {
      const result = yield this.onClick();
      this.statechart.send('SUCCESS', { result });
    } catch (e) {
      this.statechart.send('ERROR', { error: e });
    }
  })
  handleSubmitTask;

  @action
  handleClick() {
    this.statechart.send('SUBMIT');
  }

  @action
  onSuccess(_context, { result }) {
    return (this.args.onSuccess && this.args.onSuccess(result)) || noop();
  }

  @action
  onError(_context, { error }) {
    return (this.args.onError && this.args.onError(error)) || noop();
  }

  @action
  performSubmitTask() {
    this.handleSubmitTask.perform();
  }
}

Please refer to the documentation page for a detailed guide of how you can use statecharts to improve your Ember.js application architecture.

Contributing

See the Contributing guide for details.

License

This project has been developed by https://www.effective-ember.com/ and contributors. It is licensed under the MIT License.

About

Statecharts for Ember.js applications

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

 

Packages

No packages published

Languages

  • JavaScript 58.1%
  • Handlebars 28.0%
  • TypeScript 10.4%
  • HTML 2.8%
  • CSS 0.7%