an experiment in opinionated helpers for inu
npm install --save inux
- holodex/app#compost: full-stack user directory app using
inu
,inux
, andvas
inu
provides the foundation, inux
lets us fly. :)
inux
introduces some opinionated concepts to inu
:
a unique String
or Symbol
that corresponds to a type of action or effect payload
const SET_TEXT = 'NOTEPAD_SET_TEXT'
// or
const SET_TEXT = Symbol('setText')
a function that returns an action or effect object of the form { type, payload }
function setText (text) {
return {
type: SET_TEXT,
payload: text
}
}
like an inu
app, but
- optionally namespaced to
name
property, which determines where the domain model will be merged into the overall app model update
orrun
can be objects mapping types of actions or effects, respectively, to handler functionsroutes
can be an array of arrays describing routes forsheet-router
in this example, textEditor
refers to a hypothetical re-usable view component.
{
name: 'notepad',
init: {
model: '',
effect:
}
update: {
[SET_TEXT]: (model, text) {
return text
}
},
routes: [
['/notepad', function (params, model, dispatch) {
return html`
<div>
${textEditor(model.notepad, save)}
</div>
`
function save (text) {
dispatch(setText(text))
}
}]
]
}
a function that take an inu
app and return another inu
app
function log (app) {
return extend(app, {
init: () => {
const state = app.init()
console.log('init:', state)
return state
},
update: (model, action) => {
console.log('update before:', model, action)
const state = app.update(model, action)
console.log('update after:', state)
return state
},
run: (effect, sources) => {
console.log('run', effect)
return app.run(effect, sources)
}
})
}
(for a better inu
log enhancer, see inu-log
)
a list of domains to become a single inu
app
each domain is a group of functionality corresponding to a small specific theme in your overall app.
[
notepad,
settings,
auth
]
const { start, html } = require('inu')
const { App, Domain, Action } = require('inux')
const extend = require('xtend')
const INCREMENT = Symbol('increment')
const DECREMENT = Symbol('decrement')
const SET = Symbol('set')
const increment = Action(INCREMENT)
const decrement = Action(DECREMENT)
const set = Action(SET)
const view = (model, dispatch) => html`
<div>
<button onclick=${(e) =>
dispatch(decrement())
}> - </button>
<input type='number'
oninput=${(ev) => {
dispatch(set(Number(ev.target.value)))
}}
value=${model}
/>
<button onclick=${(e) =>
dispatch(increment())
}> + </button>
</div>
`
const counter = Domain({
name: 'counter',
init: () => ({ model: 0 }),
update: {
[INCREMENT]: (model) => ({ model: model + 1 }),
[DECREMENT]: (model) => ({ model: model - 1 }),
[SET]: (model, value) => ({ model: value })
},
routes: [
['/', (params, model, dispatch) => {
return view(model.counter, dispatch)
}]
]
})
const app = App([
counter
])
// const sources = start(app) ...
extends domain.update
and domain.run
with handleActions
and handleEffects
, respectively.
combines an Array
of inux
domains into a single inu
app.
each domains's model is namespaced to domain.name
,
any domains's effect is added to an Array
of effects.
also
- adds
inux.apps.href
domain to handlehref
changes - adds
inux.apps.run
domain to handlerun
actions - sets
app.view
using `route(combinedRoutes, app) - enhances resulting app with
inu-multi
create an action or effect creator.
creator returns object of form
{
type: type,
payload: payloadCreator(...args)
}
creates action objects to run an effect.
corresponding inux.apps.run
update:
{
[RUN]: (model, effect) => ({ model, effect })
}
app to handle run
actions.
app to track window.location.href
.
combines an array of apps into a single app.
given an app with app.routes
and a function of the form (routes) => (model, dispatch) => ...
,
creates the router with Router(app.routes)
and sets the corresponding view as app.view
.
given an array of routes, return a router using sheet-router
.
the last route will be used as the default route.
given an Object
of String
or Symbol
keys to action handlers, returns a single update Function
.
each String
or Symbol
key corresponds to an action.type
.
each action handler is a Function
of the form (model, action.payload) => state
.
given an Object
of String
or Symbol
keys to effect handlers, returns a single update Function
.
each String
or Symbol
key corresponds to an effect.type
.
each effect handler is a Function
of the form (effect.payload, sources) => nextActions or null
.
given an update function and a key, returns a new update function that namespaces updates at the key.
given a list of update functions, return a new update function that is the result of applying all of them.
given a list of run functions, return a new run function that is the result of applying all of them.
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.