Code Monkey home page Code Monkey logo

objectstate's Introduction

ObjectState

Build Status npm install npm version js-standard-style License

Overview

objectstate exports a function that constructs a stream. The stream is designed to be the source of truth for the state of a system. It represents state as a JavaScript object, and updates it by 'listening' to streams or event emitters.

When any stream or event emitter emits new values, ObjectState updates its state representation, and fires a "data" event. Client code can subscribe to the "data" event for a full representation of the state of the system each time it changes.

Example

var EE = require('events').EventEmitter

var objectState = require('objectstate')
var through = require('through')

var stream = through()

var ee1 = new EE
var ee2 = new EE

var os = objectState()

os.listen(stream, 'rat')
  .listenOn(ee1, 'data', ['cat', 'dog'])
  .listenOn(ee2, 'error', ['hat'])

os.on('data', function (state) {
  console.log(state)
})

stream.queue(5)             // {"rat": 5}
ee1.emit('data', 1)         // {"rat": 5, "cat":1}
ee1.emit('data', 1, 2)      // {"rat": 5, "cat":1, "dog":2}
ee2.emit('data', 100)       // does not log, since os does not listen to ee2's
                            // data event.
stream.queue(5)             // does not log, because this changes nothing.
ee2.emit('error', "hello")  // {"rat": 5, "cat":1, "dog":2, "hat":"hello"}
ee1.emit('data')            // {"rat": 5, "hat":"hello"}

API

objectState(_initial) -> DuplexStream

  • _initial is an optional object to use as the initial state. If a non-object is provided, a TypeError will be thrown.

ObjectState instances are readable/writable streams. ObjectState emits whenever its internal state changes, and can be written to with an object to set its internal state. If a non-object is written, an error event will be emitted. Writes of undefined are ignored entirely.

Notes

ObjectState will never alter any object that is passed to it, instead it makes a deep copy for use internally. Likewise, it only ever emits a deep copy of its state in order to avoid outside mutation.

For performance reasons, deep copy is implemented using JSON.parse(JSON.stringify(state)), which has a few limitations.

  1. It will throw an error if there is a self-reference,
  2. It will have strange side effects on properties that are not null, string, boolean, array, or a plain JavaScript object. This includes functions, typed arrays, and objects with prototype other than Object.prototype.

In practice, these limitations are mostly inconsequential. ObjectState is meant to manage data, not complicated instances.

ObjectState only ever emits when its internal state changes, a condition determined via a deep comparison of the new state object versus the previous one.

ObjectState speaks "keypaths", meaning you can reference deeply nested properties by dot-separated strings. For example, given the object {animals: {cats: {sound: 'meow'}}}, 'animals.cats.sound' would refer to the string 'meow'. If you do not need deep property access, a regular string will work as you would expect.

Instance Methods

os.listen(stream, keypath) -> os

  • stream: A stream
  • keypath: The keypath to update on emit

os.listenOn(ee, eventName, keypaths) -> os

  • ee: An event emitter
  • eventName: When ee emits events named eventName, their objects are recorded on the internal state object.
  • keypaths: An array of keypaths.

When the ee emits the event eventName, ObjectState saves each argument passed to the event handler under the keypaths array element at the same index. The Nth argument passed to the listener is saved under the Nth element of keypaths: state[keypaths[N]] = arguments[N].

If an emitted argument is undefined, ObjectState deletes the corresponding keypath in its internal state object.

If a specified parameter is falsey, it is skipped over during assignment.

os.get(keypath)

Returns the value for state keypath keypath (or undefined if not set).

os.set(keypath, value)

Set the value for keypath keypath to value on the state.

os.remove(keypath)

Delete the keypath keypath from the state.

os.emitState()

Emit the current state as a data event.

os.wait(fn)

fn is a function that is immediately called. All changes that happen during its execution will be collected into a single data event, if the state changed at all.

os.state()

Returns a deep copy of the current state object.

Contributing

Please see CONTRIBUTING for details on how to contribute to this project.

License

This project is licensed under the Apache License, Version 2.0. See LICENSE for the full license.

objectstate's People

Contributors

awinterman avatar fardog avatar jarofghosts avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

objectstate's Issues

OS should not emit if its state has not changed.

currently, any method/call that causes objectstate to possibly update state causes it to emit, whether a state change resulted or not. It should only update when it has received a state 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.