Not Providing Milkshakes

    @nichoth/state

    0.1.1 • Public • Published

    old school mutable state

    Abstract state container

    This package provides minimal prototypes for creating state machines. The core is index.js, a class with 2 methods for subscribing to changes and publishing updates. All children inherit from this.

    We use sorted lists of objects so frequently that list.js is included here, which has methods for basic crud operations.

    There are several utility functions also -- extend, a helper for inheriting from this, Merge, which composes multiple state machines, and map.

    install

    $ npm install @nichoth/state
    

    example

    inherit from this module

    var Store = require('../')
    var xtend = require('xtend')
    var assert = require('assert')
    
    // you need to implement _state
    // if _state is an object, it is deep cloned whenever we instantiate a
    // new FooStore
    var FooStore = Store.extend({
        _state: { foo: 'foo' },
    
        // **all methods should be synchronous**
        setFoo: function (value) {
            this._state.foo = value
            return this.publish()
        }
    })
    
    var fooStore = FooStore()
    
    // get state
    var state = fooStore.state()
    console.log('initial state', state)
    assert.deepEqual(state, { foo: 'foo' })
    
    // subscribe to changes
    var stopListening = fooStore.state(function onChange (state) {
        console.log('new state', state)
        assert.equal(state.foo, 'bar')
    })
    fooStore.setFoo('bar')
    
    // unsubscribe
    stopListening()
    var stop = fooStore.state(state => assert.equal(state.foo, 'baz'))
    fooStore.setFoo('baz')
    stop()
    
    
    // `_state` can be a function that returns initial state
    var BarStore = Store.extend({
        _state: function (init) {
            return { bar: init }
        },
    
        setBar: function (val) {
            this._state.bar = val
            return this.publish()
        }
    })
    
    var barStore = BarStore('baz')
    assert.equal(barStore.state().bar, 'baz')

    State.Merge

    Compose multiple state machines, and get change events whenever one of them changes

    // emit a change event whenever one of the children changes
    var merged = Store.Merge({
        foo: fooStore,
        bar: barStore
    })
    
    var unlisten = merged.state(function onChange (state) {
        console.log('merged', state)
        assert.deepEqual(state, {
            foo: { foo: 'aaaaa' },
            bar: { bar: 'baz' }
        })
    })
    
    fooStore.setFoo('aaaaa')
    
    unlisten()

    State.map

    Take an existing store and return a new store that is mapped by a predicate function

    var mapped = Store.map(function (state) {
        return xtend(state, {
            woo: 'woo'
        })
    }, fooStore)
    
    mapped.state(function onChange (state) {
        console.log('mapped', state)
        assert.deepEqual(state, { foo: 'hello', woo: 'woo' })
    })
    
    fooStore.setFoo('hello')

    struct

    A simple observable object with one method, .set.

    var Struct = require('@nichoth/state/struct')
    var assert = require('assert')
    
    var myState = Struct({
        hello: 'world',
        foo: 'bar'
    })
    
    // do a shallow merge
    myState.set({ hello: 'ok' })
    
    assert.deepEqual(myState.state(), {
        hello: 'ok',
        foo: 'bar'
    })

    List

    A sorted list of objects

    var Store = require('../')
    var ListStore = require('../list')
    var assert = require('assert')
    
    var Foos = Store.extend({
        // these are required
        idKey: 'id',
        sortBy: 'hello',
    }, ListStore)
    
    var foos = Foos()
    
    console.log(foos.state())
    assert.deepEqual(foos.state(), {
        data: {},
        sorted: [],
        hasFetched: false
    })

    list.get(array) => list

    Set this store's list of sorted data

    // the get method assumes the list is *already* sorted
    foos.get([{ id: 2, hello: 'ham' }, { id: 1, hello: 'world' }])
    console.log(foos.state())
    assert.deepEqual(foos.state(), {
        data: {
            '1': { id: 1, hello: 'world' },
            '2': { id: 2, hello: 'ham' }
        },
        sorted: [ { id: 2, hello: 'ham' }, { id: 1, hello: 'world' } ],
        hasFetched: true
    })

    list.add(object) => list

    Add an element in the correct sorted position

    foos.add({ id: 3, hello: 'bar' })
    assert.equal(foos.state().sorted[0].hello, 'bar')

    list.edit(object) => list

    Lookup an object by id, and update the given properties

    foos.edit({ id: 3, hello: 'baz' })
    assert.equal(foos.state().sorted[0].hello, 'baz')
    assert.equal(foos.state().data['3'].hello, 'baz')

    list.delete(object) => list

    Lookup an object by id and delete it from the store

    foos.delete({ id: 2 })
    console.log(foos.state())
    assert.deepEqual(foos.state(), {
        data: {
            '1': { id: 1, hello: 'world' },
            '3': { id: 3, hello: 'baz' }
        },
        sorted: [ { id: 3, hello: 'baz' }, { id: 1, hello: 'world' } ],
        hasFetched: true
    })

    Keywords

    none

    Install

    npm i @nichoth/state

    DownloadsWeekly Downloads

    5

    Version

    0.1.1

    License

    ISC

    Unpacked Size

    13.7 kB

    Total Files

    10

    Last publish

    Collaborators

    • nichoth