sygnalyze

v0.0.7
Angular Signals with Superpowers

Sygnalyze

Enhance 🚦 Angular Signals 🚦 with Super Powers!

Installation

npm i sygnalyze

API

sygnal

Enhanced Angular Signal - with 2 differences:

readonly update

The update method parameter (current value) is DeepReadonly in order to avoid unintentional mutations

const person = sygnal({
  name: 'john',
  age: 40
})
sygnal.update(current => ...)
//            ^? current is DeepReadonly

draftUpdate(mutatingCallback)

An additional method draftUpdate(mutatingCallback) allows to mutate the current value of the signal, but thanks to using immer, the value is replaced with an immutable

const person = sygnal({
  name: 'john',
  age: 40
})

person.draftUpdate(draft => {
  draft.age++;
})

In above code, a new object is set as the value, so the signal notifies all its dependents.

memento / withMemento(writableSignal)

Make a snapshot (memento) of the signal's value at a certain point in time. Whenever memento gets restored, the signal goes back to that value.

import { memento, withMemento, Memento } from 'sygnalyze'

export class TheComponent {
  item = memento({ age: 40 }) // Sygnal
  // or:
  item = withMemento(signal({ age: 40 })) // original Signal
  ...

  memento?: Memento

  createMemento(){
    this.memento = this.item.memento()
  }

  restoreMemento(){
    this.memento?.restore()
  }
}

toggle / withToggle(writableSignal)

Creates a boolean signal with simple toggle() updating method.

import { toggle, withToggle } from 'sygnalyze'

export class TheComponent {
  showTheThing = toggle(true) // Sygnal
  // or:
  showTheThing = withToggle(signal(true)) // original Signal

  ...

  theMethod(){
    this.showTheThing.toggle()
  }
}

immutablePatchState

The NGRX Signal Store patchState function enhanced with immer immutability:

import { immutablePatchState } from 'sygnalyze/ngrx'

export const Store = signalStore(
  withMethods((store) => ({
    updateOrder(order: 'asc' | 'desc'): void {
      immutablePatchState(store, (draft) => { draft.filter.order = order });
    },
  })
)

The immutablePatchState function callback can now mutate the state draft object and return nothing. immer will create a new object by applying all recorded changes. You don't have to worry about applying immutable changes manually.

Compare with default approach:

import { signalStore, withMethods, ... } from '@ngrx/signals'
import { immutablePatchState } from 'sygnalyze/ngrx'

export const Store = signalStore(
  //...
  withMethods((store) => ({
    // state: WritableDraft<StateType>
    updateOrderMutative(order: 'asc' | 'desc'): void {
      immutablePatchState(store, (draft) => { draft.filter.order = order });
    },
    // BEFORE: having to apply immutability manually by spread operator:
    updateOrder(order: 'asc' | 'desc'): void {
      patchState(store, (state) => ({ filter: { ...state.filter, order } }));
    },
  })
)
npm i sygnalyze

Metadata

  • MIT
  • Whatever
  • Tomasz Ducin
  • released 2/18/2024

Downloads

Maintainers