Giter Site home page Giter Site logo

state's Introduction

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.

Sorted lists are also included here in list.js, which has methods for basic crud operations.

struct.js is a simple observable object.

There are several utility functions also -- extend, a helper for inheriting, 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
// _state can also be a function that returns a new object. It will
// be called during construction
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
})

state's People

Contributors

nichoth avatar

Stargazers

Andrejs Agejevs avatar

Watchers

James Cloos avatar  avatar  avatar

state's Issues

store methods API

You could make a helper that takes functions (you store's methods) and will call them then call publish afterward. That would get rid of a little bit of boilerplate.

var MyStore = createStore({ mystate }).actions(function (state) {
  return {
    set: function (data) {
      state.hello = data
      return false  // you can return false to omit publishing a change
    }
  }
})
  

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.