0.3.3 • Published 6 years ago

listick v0.3.3

Weekly downloads
2
License
MIT
Repository
github
Last release
6 years ago

listick

Listick allows to do predictable state modification using TypeScript

Services

Services are any type of object that can be injected in another service or react component.

@inject export class CounterService
{
    constructor(private counterEvents: CounterEvents)
    { }

    public Increment(): void
    {
        this.counterEvents.increment.fire(this, 1);
    }

    public Decrement(): void
    {
        this.counterEvents.decrement.fire(this, 1);
    }
}

This is a service that inject events container and fires increment and decrement events when appropriate method is called. In reality this can be more complex, and one service method can fire more than one event. All services must be marked with @inject decorator

Events containers

Events container are classes that combine several events by one common idea

export class CounterEvents
{
    public increment = new Event<number>();

    public decrement = new Event<number>();
}

Here we see that events container contains two events, and each of them has argument number.

Istead of integrated events you can use rxJs for this you need to declare Observable properties and then subscribe StateModifier to its events.

State modifiers

State modifier are classes that do state mutation.

import { subscribe } from "listick"

export interface ICounterState
{
    counter: number;
}

export class CounterStateModifier implements IStateModifier<ICounterState>
{
    initialState: ICounterState = { counter: 2 }

    @subscribe(CounterEvents, ce => ce.increment)
    public onIncrement(prevState: ICounterState, args: number): Partial<ICounterState>
    {
        return {
            counter: prevState.counter + args
        };
    }

    @subscribe(CounterEvents, ce => ce.decrement)
    public onDecrement(prevState: ICounterState, args: number): Partial<ICounterState>
    {
        return {
            counter: prevState.counter - args
        }
    }
}

Inside state modifier we have to define initial state for state modifier. Implementation of IStateModifier<TState> is optional because of duck typing. Each method of state modifier that must listen for events and mutate state must be marked by @subscribe decorator. It defines which event must be listened. Method itself returns mutated part of state. If state is simple type, this simple type can be returned.

Also it is possible to subscribe to rxjs observables for this you need to use use special import for subscribe decorator.

import { subscribe } from 'listick/rx';

export interface ICounterState
{
    counter: number;
}

export class CounterStateModifier implements IStateModifier<ICounterState>
{
    initialState: ICounterState = { counter: 2 }

    @subscribe(CounterEvents, ce => ce.increment)
    public onIncrement(prevState: ICounterState, args: number): Partial<ICounterState>
    {
        return {
            counter: prevState.counter + args
        };
    }

    @subscribe(CounterEvents, ce => ce.decrement)
    public onDecrement(prevState: ICounterState, args: number): Partial<ICounterState>
    {
        return {
            counter: prevState.counter - args
        }
    }
}

Store

Store combines all these modules together.

@store({
    eventContainers: [CounterEvents],
    services: [CounterService]
})
export class AppStore
{
    @state(CounterStateModifier)
    public counterState: ICounterState;
}

Here @store decorator describes which services and events are used inside this store. Each state field must be marked with state decorator. This decorator binds state property with state modifier. And this field will be automatically modified by state modifier.

Then all you need is to call buildStore function and provide class prototype:

const appStore = buildStore(AppStore);
0.3.3

6 years ago

0.3.2

6 years ago

0.3.1

6 years ago

0.2.1

6 years ago

0.1.2

6 years ago

0.1.1

6 years ago

0.1.0

6 years ago