JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 48
  • Score
    100M100P100Q53567F
  • License Apache-2.0

composable user interface state and effects manager

Package Exports

  • inu

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (inu) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

inu stability

npm version build status test coverage downloads js-standard-style

simple composable unidirectional user interfaces using pull streams

npm install --save inu

shiba inu

why?

explained best by jarvisaoieong/redux-architecture,

In classical Redux, which side effect is handled by thunk middleware, is not fractal (a term that is nicely explained by @stalz)

Even with some new Redux additions, like redux-saga, are also not composable in a fractal way with the rest of architecture.

I think elm architecture has found the proper way to do it right. Beside composing Views, State and Reducers (which are already composed in classical Redux), Actions and Effects should be composed too. All that leads to composition of application pieces at the higher level.

inu's implementation is more or less a direct port of tom using pull streams instead of rx.

example

const { start, html, pull } = require('inu')
const delay = require('pull-delay')

const app = {

  init: () => ({
    model: 0,
    effect: 'SCHEDULE_TICK' // start perpetual motion
  }),

  update: (model, action) => {
    switch (action) {
      case 'TICK':
        return {
          model: (model + 1) % 60,
          effect: 'SCHEDULE_TICK'
        }
      default:
        return { model }
    }
  },

  view: (model, dispatch) => html`
    <div class='clock'>
      Seconds Elapsed: ${model}
    </div>
  `,

  run: (effect) => {
    switch (effect) {
      case 'SCHEDULE_TICK':
        return pull(
          pull.values(['TICK']),
          delay(1000)
        )
    }
  }
}

const main = document.querySelector('.main')
const { views } = start(app)

pull(
  views(),
  pull.drain(function (view) {
    html.update(main, view)
  })
)

for a full example of composing multiple apps together, see source and demo.

usage

where state is an object with a required key model and an optional key effect,

an inu app is defined by an object with the following (optional) keys:

  • init: a function returning the initial state
  • update: a update(model, action) pure function, returns the new state
  • view: a view(model, dispatch) pure function, returns the user interface declaration
  • run: a run(effect, actions) function, returns an optional pull source stream of future actions

inu = require('inu')

the top-level inu module is a grab bag of all inu/* modules.

you can also require each module separately like require('inu/start').

streams = inu.start(app)

streams is an object with the following keys:

streams flow diagram

* in this context, state-ful means that the pull source stream will always start with the last value (if any) first.

inu.html === require('yo-yo')

inu.pull === require('pull-stream')

examples

inspiration

license

The Apache License

Copyright © 2016 Michael Williams

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.