Skip to content

pixtron/ngxstate

Repository files navigation

@pxtrn/ngxstate

This library contains utilities for using XState with Angular.

Usage

Use an actor

import { Component, Injectable } from '@angular/core';
import { createMachine, assign } from 'xstate';
import { AbstractActor, useActor } from '@pxtrn/ngxstate';

const counterMachine = createMachine({
  context: {
    count: 0,
  }
  on: {
    INC: {
      actions: [assign({count: (context) => context.count + 1})]
    }
  }
});

@Injectable({
  providedIn: 'root',
})
export class CounterActor extends AbstractActor<typeof counterMachine> {
  public readonly actor = useActor(counterMachine);
}

@Component({
  template: `
    <h1>{{ count$ | async }}</h1>
    <button (click)="increment()">+</button>
  `
})
export class MyComponent {
  private counterActor = inject(CounterActor);

  public count$ = this.counterActor.select(state => state.context.count);

  public increment() {
    this.counterActor.send({type: 'INC'});
  }
}

Provide machine implementation

import { Injectable } from '@angular/core';
import { createMachine, assign } from 'xstate';
import { AbstractActor, AbstractImplementation, useActor } from '@pxtrn/ngxstate';

const counterMachine = createMachine({
  context: {
    count: 0,
  }
  on: {
    INC: {
      actions: ['increment']
    }
  }
});

type CounterMachine = typeof counterMachine;

@Injectable({
  providedIn: 'root',
})
export class CounterImplementation extends AbstractImplementation<CounterMachine> {
  public getImplementation(): MachineImplementation<CounterMachine> {
    return {
      actions: {
        increment: assign({ count: context => context.count + 42 }),
      },
    };
  }
}

@Injectable({
  providedIn: 'root',
})
export class CounterActor extends AbstractActor<CounterMachine> {
  public readonly actor = useActor(counterMachine, {
    implementation: inject(CounterImplementation)
  });
}

Rehydrate state

@Injectable({
  providedIn: 'root',
})
export class CounterActor extends AbstractActor<CounterMachine> {
  public readonly actor = useActor(counterMachine, {
    state: JSON.parse(localStorage.getItem('counterSnapshot')) || undefined
  });

  public persistState() {
    const snapshot = this.actor.getSnapshot();
    localStorage.setItem('counterSnapshot', JSON.stringify(snapshot));
  }
}

About

A wrapper library to make using XState state machines in Angular easier

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages