microcosm
Advanced tools
Comparing version 12.8.0 to 12.9.0-alpha
@@ -12,2 +12,3 @@ 'use strict'; | ||
* Shallow copy an object | ||
* @private | ||
*/ | ||
@@ -18,2 +19,3 @@ | ||
* Merge any number of objects into a provided object. | ||
* @private | ||
*/ | ||
@@ -24,2 +26,3 @@ | ||
* Basic prototypal inheritence | ||
* @private | ||
*/ | ||
@@ -31,2 +34,3 @@ | ||
* object. | ||
* @private | ||
*/ | ||
@@ -38,2 +42,3 @@ | ||
* value is the same, don't do anything. Otherwise return a new object. | ||
* @private | ||
*/ | ||
@@ -46,2 +51,3 @@ | ||
* @return {boolean} | ||
* @private | ||
*/ | ||
@@ -54,2 +60,3 @@ | ||
* @return {boolean} | ||
* @private | ||
*/ | ||
@@ -62,2 +69,3 @@ | ||
* @return {boolean} | ||
* @private | ||
*/ | ||
@@ -70,2 +78,3 @@ | ||
* @return {boolean} | ||
* @private | ||
*/ | ||
@@ -78,5 +87,17 @@ function isString(target) { | ||
/** | ||
* Is the provided value a generator function? This is largely | ||
* informed by the regenerator runtime. | ||
* @param {*} value | ||
* @return {boolean} | ||
* @private | ||
*/ | ||
/** | ||
* @private | ||
*/ | ||
/** | ||
* A helper combination of get and set | ||
@@ -87,2 +108,3 @@ * @param {Object} state | ||
* @param {*} fallback value | ||
* @private | ||
*/ | ||
@@ -107,2 +129,3 @@ | ||
* @return {Array} List of keys, like ['users', 2] | ||
* @private | ||
*/ | ||
@@ -125,2 +148,3 @@ function castPath(value) { | ||
* @return {Array} List of paths, like [['users'], ['query', 'focus']] | ||
* @private | ||
*/ | ||
@@ -141,2 +165,3 @@ function getKeyPaths(value) { | ||
* @return {String} Dot separated string, like 'query.focus' | ||
* @private | ||
*/ | ||
@@ -149,2 +174,3 @@ | ||
* @return {Array} Comma key paths, like 'users,query.focus' | ||
* @private | ||
*/ | ||
@@ -159,2 +185,3 @@ | ||
* Given a query (see above), return a subset of an object. | ||
* @private | ||
*/ | ||
@@ -161,0 +188,0 @@ function extract(object, keyPaths, seed) { |
@@ -61,2 +61,152 @@ 'use strict'; | ||
/** | ||
* @fileoverview A general modelling class used by the Presenter's | ||
* getModel function. | ||
*/ | ||
function isObservable(binding) { | ||
return binding && typeof binding.subscribe === 'function'; | ||
} | ||
function isCallable(binding) { | ||
return binding && typeof binding.call === 'function'; | ||
} | ||
function invoke(binding, repo, scope) { | ||
if (isCallable(binding)) { | ||
return binding.call(scope, repo.state, repo); | ||
} | ||
return binding; | ||
} | ||
var Model = function (_Emitter) { | ||
inherits(Model, _Emitter); | ||
/** | ||
* @param {Microcosm} repo Track this Microcosm instance for updates | ||
* @param {scope} scope Scope to invoke functional bindings | ||
*/ | ||
function Model(repo, scope) { | ||
classCallCheck(this, Model); | ||
var _this = possibleConstructorReturn(this, _Emitter.call(this)); | ||
_this.repo = repo; | ||
_this.scope = scope; | ||
_this.bindings = {}; | ||
_this.subscriptions = {}; | ||
_this.value = {}; | ||
_this.repo.on('change', _this.compute, _this); | ||
return _this; | ||
} | ||
/** | ||
* Track an observable. Sending updates to a given key. | ||
* @param {string} key | ||
* @param {Observable} observable | ||
*/ | ||
Model.prototype.track = function track(key, observable) { | ||
var _this2 = this; | ||
var last = this.subscriptions[key]; | ||
var next = observable.subscribe(function (value) { | ||
return _this2.set(key, value); | ||
}); | ||
this.subscriptions[key] = next; | ||
if (last) { | ||
last.unsubscribe(); | ||
} | ||
}; | ||
/** | ||
* @param {Object} bindings A set of key/value pairs for building a model | ||
*/ | ||
Model.prototype.bind = function bind(bindings) { | ||
this.bindings = {}; | ||
for (var key in bindings) { | ||
var binding = bindings[key]; | ||
if (isObservable(binding)) { | ||
this.track(key, binding); | ||
} else { | ||
this.bindings[key] = binding; | ||
} | ||
} | ||
this.compute(); | ||
}; | ||
/** | ||
* Update a specific model key. Emits a change event | ||
* @param {string} key | ||
* @param {*} value | ||
*/ | ||
Model.prototype.set = function set$$1(key, value) { | ||
var next = Microcosm.set(this.value, key, value); | ||
if (this.value !== next) { | ||
this.value = next; | ||
this._emit('change', this.value); | ||
} | ||
}; | ||
/** | ||
* Run through each invokable binding, recomputing the model | ||
* for their associated keys. | ||
*/ | ||
Model.prototype.compute = function compute() { | ||
var last = this.value; | ||
var next = last; | ||
for (var key in this.bindings) { | ||
var value = invoke(this.bindings[key], this.repo, this.scope); | ||
next = Microcosm.set(next, key, value); | ||
} | ||
if (last !== next) { | ||
this.value = next; | ||
this._emit('change', next); | ||
} | ||
}; | ||
/** | ||
* Dispose a model, removing all subscriptions and unsubscribing | ||
* from the repo. | ||
*/ | ||
Model.prototype.teardown = function teardown() { | ||
for (var key in this.subscriptions) { | ||
this.subscriptions[key].unsubscribe(); | ||
} | ||
this.repo.off('change', this.compute, this); | ||
}; | ||
return Model; | ||
}(Microcosm.Emitter); | ||
/** | ||
* @fileoverview Presenter is a specialized React component that | ||
* creates a boundary between "smart" and "dumb" components. This | ||
* improves testing and keeps business logic in a consistent place | ||
* (instead of spread across bunches of components). | ||
* | ||
* Use Presenters to track changes to a Microcosm, push actions, and | ||
* manage application flow. | ||
*/ | ||
function passChildren() { | ||
@@ -69,14 +219,4 @@ return this.props.children ? React.Children.only(this.props.children) : null; | ||
/** | ||
* @fileoverview The Presenter add-on makes it easier to keep | ||
* application logic high within a component tree. It subscribes to | ||
* state changes via a `getModel` method, designed specifically to | ||
* extract and compute properties coming from a Microcosm | ||
* instance. When state changes, model keys are efficiently sent down | ||
* as props to child “passive view” React components. | ||
* | ||
* Presenters also make it easy for components deep within a component | ||
* tree to communicate without passing a long chain of props. The | ||
* `withSend` and `<Form />` may be used to broadcast messages called | ||
* "actions" to parent Presenter components, or straight to a Microcosm | ||
* repo itself if no Presenter intercepts the message. | ||
* @class | ||
* @extends React.PureComponent | ||
*/ | ||
@@ -110,3 +250,3 @@ | ||
this.model = this._prepareModel(); | ||
this.model = this.mediator.updateModel(this.props, this.state); | ||
@@ -129,9 +269,2 @@ this.ready(this.repo, this.props, this.state); | ||
Presenter.prototype._prepareModel = function _prepareModel() { | ||
var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props; | ||
var state = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.state; | ||
return this.mediator.updateModel(props, state); | ||
}; | ||
/** | ||
@@ -169,8 +302,8 @@ * Called when a presenter is created, useful any prep work. `setup` | ||
* @param {Microcosm} repo | ||
* @param {Object} props | ||
* @param {Object} state | ||
* @param {Object} nextProps | ||
* @param {Object} nextState | ||
*/ | ||
; | ||
Presenter.prototype.update = function update(repo, props, state) {} | ||
Presenter.prototype.update = function update(repo, nextProps, nextState) {} | ||
// NOOP | ||
@@ -205,3 +338,3 @@ | ||
Presenter.prototype.componentWillUpdate = function componentWillUpdate(props, state) { | ||
this.model = this._prepareModel(props, state); | ||
this.model = this.mediator.updateModel(props, state); | ||
this.update(this.repo, props, state); | ||
@@ -282,3 +415,8 @@ }; | ||
_this2.send = _this2.send.bind(_this2); | ||
_this2.state = { repo: _this2.repo, send: _this2.send }; | ||
_this2.model = new Model(_this2.repo, _this2.presenter); | ||
_this2.model.on('change', _this2.setState, _this2); | ||
return _this2; | ||
@@ -295,6 +433,2 @@ } | ||
PresenterMediator.prototype.componentWillMount = function componentWillMount() { | ||
if (this.presenter.getModel !== Presenter.prototype.getModel) { | ||
this.repo.on('change', this.setModel, this); | ||
} | ||
this.presenter._beginSetup(this); | ||
@@ -310,4 +444,2 @@ }; | ||
this.repo.off('change', this.setModel, this); | ||
if (this.presenter.didFork) { | ||
@@ -317,2 +449,4 @@ this.repo.shutdown(); | ||
this.model.teardown(); | ||
this.presenter._beginTeardown(); | ||
@@ -337,42 +471,9 @@ }; | ||
PresenterMediator.prototype.updateModel = function updateModel(props, state) { | ||
var model = this.presenter.getModel(props, state); | ||
var data = this.repo.state; | ||
var next = {}; | ||
var bindings = this.presenter.getModel(props, state); | ||
this.propMap = {}; | ||
this.model.bind(bindings); | ||
for (var key in model) { | ||
var entry = model[key]; | ||
if (entry && typeof entry.call === 'function') { | ||
this.propMap[key] = entry; | ||
next[key] = entry.call(this.presenter, data, this.repo); | ||
} else { | ||
next[key] = entry; | ||
} | ||
} | ||
this.setState(next); | ||
return Microcosm.merge(this.state, next); | ||
return this.model.value; | ||
}; | ||
PresenterMediator.prototype.setModel = function setModel(state) { | ||
var last = this.state; | ||
var next = null; | ||
for (var key in this.propMap) { | ||
var value = this.propMap[key].call(this.presenter, state, this.repo); | ||
if (last[key] !== value) { | ||
next = next || {}; | ||
next[key] = value; | ||
} | ||
} | ||
if (next !== null) { | ||
this.setState(next); | ||
} | ||
}; | ||
PresenterMediator.prototype.hasParent = function hasParent() { | ||
@@ -379,0 +480,0 @@ // Do not allow transfer across repos. Check to for inheritence by comparing |
# Changelog | ||
## 12.9.0 Alpha | ||
- Added new `repo.parallel` method. This returns an action that | ||
represents a group of actions processing in parallel. | ||
- The action generator form may now `yeild` an array. This produces | ||
the same behavior as `repo.parallel` | ||
- `Presenter::getModel` assignments | ||
accept [Observables](https://github.com/tc39/proposal-observable). | ||
- Do not warn in strict mode when attempting to change a complete | ||
action. This allows for use cases like, "Cancel this action, but | ||
only if it hasn't finished yet." | ||
- History and Action now serialize to JSON. This supports a new | ||
[debugger](https://github.com/vigetlabs/microcosm-devtools). | ||
## 12.8.0 | ||
@@ -4,0 +18,0 @@ |
@@ -20,10 +20,12 @@ # Actions | ||
```javascript | ||
// axios is an AJAX library | ||
// https://github.com/mzabriskie/axios | ||
import axios from 'axios' | ||
const repo = new Microcosm() | ||
function createPlanet (data) { | ||
let request = fetch('/planets', { method: 'POST', data }) | ||
// This will return a promise, which Microcosm automatically | ||
// understands. Read further for more details. | ||
return request.then(response => response.json()) | ||
return axios.post('/planets', data) | ||
} | ||
@@ -34,3 +36,3 @@ | ||
action.onDone(function () { | ||
// All done! | ||
console.log('All done!') | ||
}) | ||
@@ -70,5 +72,7 @@ ``` | ||
```javascript | ||
import axios from 'axios' | ||
function getPlanet (id) { | ||
// Using your favorite promise-based ajax library (maybe axios or fetch?) | ||
return ajax.get(`/planets/${id}`) | ||
// Any promise-based AJAX library will do. We like axios | ||
return axios(`/planets/${id}`) | ||
} | ||
@@ -146,3 +150,3 @@ | ||
function deleteUser (id) { | ||
return fetch.delete('/users/${id}').then(response => response.json()) | ||
return axios.delete('/users/${id}') | ||
} | ||
@@ -166,2 +170,22 @@ | ||
#### Yielding Actions in Parallel | ||
By yielding an array of actions, you can wait for multiple actions to | ||
complete before continuing: | ||
```javascript | ||
function getUser (id) { | ||
return fetch(`/users/${id}`) | ||
} | ||
function getUsers (ids) { | ||
return function * (repo) { | ||
yield ids.map(id => repo.push(getUser, id)) | ||
} | ||
} | ||
``` | ||
If all actions resolve or cancel, the generator sequence | ||
continues. | ||
### Action status methods are auto-bound | ||
@@ -168,0 +192,0 @@ |
@@ -5,2 +5,3 @@ # History | ||
2. [API](#api) | ||
3. [Events](#events) | ||
@@ -71,2 +72,23 @@ **Note: This is a work in progress document and feature. History has | ||
### Reconciling | ||
What makes History such a powerful feature of Microcosm is its | ||
ability to walk through recorded actions whenever there is a change, | ||
similar to a rebase in git. | ||
Let's say we have four actions pushed to our History, and that three | ||
of the four are completed `(C)`, but the second action we pushed is | ||
taking a long time and is still open `(O)`. | ||
``` | ||
[root] - [one](C) - [two](O) - [three](C) - [four](C) | ||
``` | ||
When our `two` action here resolves or rejects, History will initiate | ||
a reconciliation starting at `two`, and walk forward to `three` and | ||
then `four`. At each step, your Domains will recompute changes to the | ||
state based on the actions. | ||
This ensures that your application state is always accurate based on | ||
the order in which actions were triggered. | ||
## API | ||
@@ -98,3 +120,3 @@ | ||
``` | ||
```javascript | ||
let repo = new Microcosm({ maxHistory: Infinity }) | ||
@@ -115,3 +137,3 @@ | ||
``` | ||
```javascript | ||
// Actions disabled in the prior example | ||
@@ -197,1 +219,130 @@ repo.history.toggle([ one, two ]) | ||
``` | ||
## Events | ||
History emits events any time something of interest happens. This is | ||
how Microcosm knows to update the state to accurately reflect what's | ||
going on given a sequence of actions and their statuses. | ||
You can manage event listeners with the following methods. | ||
### `on(event, callback)` | ||
Adds an event listener to a Microcosm History instance. | ||
```javascript | ||
const repo = new Microcosm() | ||
const history = repo.history | ||
history.on('append', callback) | ||
``` | ||
### `off(event, callback)` | ||
Removes an event listener. | ||
```javascript | ||
history.off('append', callback) | ||
``` | ||
### Event Types | ||
### `append` | ||
Arguments: `action` | ||
Emitted when an action is pushed onto the History stack. | ||
```javascript | ||
history.on('append', function(action) { | ||
console.log('Action pushed:', action.id) | ||
}) | ||
repo.push(newAction) | ||
// Action pushed: 42 | ||
``` | ||
### `remove` | ||
Arguments: `action` | ||
Emitted when an action is removed from the History stack. | ||
```javascript | ||
history.on('remove', function(action) { | ||
console.log('Action removed:', action.id) | ||
}) | ||
action = repo.push(newAction) | ||
history.remove(action) | ||
// Action removed: 42 | ||
``` | ||
### `update` | ||
Arguments: `action` | ||
Whenever there is an update to an action's status, an `update` event | ||
is emitted with that action. | ||
```javascript | ||
history.on('update', function(action) { | ||
console.log('Action status:', action.status) | ||
}) | ||
repo.push(newAction) | ||
// Action status: inactive | ||
// Action status: open | ||
// Action status: update | ||
// Action status: [resolve, reject, cancel] | ||
``` | ||
Whenever an action that precedes other actions has a status update, | ||
History walks forward in time from that action reconciling the | ||
application state (see [Reconciling](#reconciling) for more details.) | ||
For every action in this process, `update` will be emitted. | ||
### `reconcile` | ||
Arguments: `action` | ||
In response to an action's status changing, History triggers a | ||
reconciliation. Once that has completed (and an `update` event has | ||
been emitted for each reconciled action), `reconcile` is emitted with | ||
the action that triggered the walk through. | ||
```javascript | ||
history.on('reconcile', function(action) { | ||
console.log('Action:', action.id) | ||
}) | ||
repo.push(newAction) | ||
// Action: 42 | ||
``` | ||
### `release` | ||
Emitted after a reconciliation pass. In setting up a Microcosm, you | ||
have the option to pass a `batch` option which will cause `release` | ||
to be emitted in batched intervals (used internally to improve state | ||
comparison performance). | ||
```javascript | ||
let repo = new Microcosm({ batch: true }) | ||
let history = repo.history | ||
history.on('append', function(action) { | ||
console.log('Action:', action.id) | ||
}) | ||
history.on('release', function() { | ||
console.log('Released!') | ||
}) | ||
repo.push(newAction) | ||
repo.push(newAction) | ||
repo.push(newAction) | ||
// Action: 1 | ||
// Action: 2 | ||
// Action: 3 | ||
// Released! | ||
``` |
@@ -332,2 +332,19 @@ # Microcosm | ||
### `parallel([...actions])` | ||
Create a new "group" action bound to the resolution of a list of | ||
actions. If all actions resolve or cancel, the group action will | ||
resolve. If any action is rejected, the group action fails: | ||
```javascript | ||
let group = repo.parallel([ | ||
repo.push(actionOne), | ||
repo.push(actionTwo) | ||
]) | ||
group.onDone(function () { | ||
console.log('hurrah!') | ||
}) | ||
``` | ||
### `Microcosm.defaults` | ||
@@ -334,0 +351,0 @@ |
# Presenter | ||
1. [Overview](#overview) | ||
2. [Computed Properties](#computed-properties) | ||
2. [Track changes and compute values](#track-changes-and-compute-values) | ||
3. [Receiving Actions](#receiving-actions) | ||
@@ -10,22 +10,16 @@ 4. [API](#api) | ||
The Presenter add-on makes it easier to keep application logic high | ||
within a component tree. It subscribes to state changes via a | ||
`getModel` method, designed specifically to extract and compute | ||
properties coming from a Microcosm instance. When state changes, model | ||
keys are efficiently sent down as props to child “passive view” React | ||
components. | ||
Presenter is a specialized React component that creates a boundary | ||
between "smart" and "dumb" components. This improves testing and keeps | ||
business logic in a consistent place (instead of spread across bunches | ||
of components). | ||
Presenters also make it easy for components deep within a component | ||
tree to communicate without passing a long chain of props. The | ||
`withSend` and `<Form />` may be used to broadcast messages called | ||
"actions" to parent Presenter components, or straight to a Microcosm | ||
repo itself if no Presenter intercepts the message. | ||
Use Presenters to track changes to a Microcosm, push actions, and | ||
manage application flow. | ||
We'll cover both of these features within this document | ||
## Track changes and compute values | ||
## Computed Properties | ||
Presenter extends from `React.Component` and can be used exactly the | ||
same way. By implementing a `getModel` method, Presenters declare what | ||
information they need from an instance of Microcosm: | ||
Presenter extends from `React.Component`, and can be used just like a | ||
React component: | ||
```javascript | ||
@@ -58,9 +52,13 @@ import React from 'react' | ||
DOM.render(<PlanetsPresenter repo={ repo } />) | ||
// <p>Mercury, Venus, Earth</p> | ||
``` | ||
In the example above, the `PlanetsPresenter` will extract a list of | ||
planets from the Microcosm instance provided to it via the `repo` | ||
prop. This is available as state, which the Presenter can send into a | ||
child component. | ||
Presenters accept a `repo` property; an instance of | ||
Microcosm. Here, `PlanetsPresenter` extracts a list of planets its given | ||
Microcosm and stores it within `this.model`. | ||
Presenters track their Microcosm instance for changes, keeping | ||
`this.model` in sync. | ||
## Receiving Actions | ||
@@ -73,3 +71,4 @@ | ||
The ActionForm add-on can be used to broadcast actions to Presenters: | ||
The [ActionForm](./action-form.md) add-on can be used to broadcast | ||
actions to Presenters: | ||
@@ -140,7 +139,9 @@ ```javascript | ||
up to the associated Presenter including the serialized parameters of | ||
the form. Since this Presenter's intercept method includes `increaseCount`, it will | ||
invoke the method with the associated parameters. | ||
the form. Since this Presenter's intercept method includes | ||
`increaseCount`, it will invoke the method with the associated | ||
parameters. | ||
If a Presenter does not intercept an action, it will bubble up to any | ||
parent Presenters. If no Presenter intercepts the action, it will dispatch the action to the repo. | ||
parent Presenters. If no Presenter intercepts the action, it will | ||
dispatch the action to the repo. | ||
@@ -163,10 +164,43 @@ ```javascript | ||
Called when a presenter is created, useful any prep work. `setup` runs before the first `getModel` invocation. | ||
Called when a presenter is created, useful any prep work. `setup` runs | ||
before the first `getModel` invocation. | ||
```javascript | ||
import { getPlanets } from '../actions/planets' | ||
class PlanetsList extends Presenter { | ||
setup (repo, props, state) { | ||
// Important: this.model is not defined yet! | ||
repo.push(getPlanets) | ||
} | ||
// ... | ||
} | ||
``` | ||
### `ready(repo, props, state)` | ||
Called after the presenter has run `setup` and executed the first `getModel`. This hook is useful for fetching initial data and other start tasks that need access to the model data. | ||
Called after the presenter has run `setup` and executed the first | ||
`getModel`. This hook is useful for fetching initial data and other | ||
start tasks that need access to the model data. | ||
### `update(repo, props, state)` | ||
```javascript | ||
import { getPlanets } from '../actions/planets' | ||
class PlanetsList extends Presenter { | ||
getModel () { | ||
return { | ||
planets: state => state.planets | ||
} | ||
} | ||
ready (repo, props, state) { | ||
if (this.model.planets.length <=0) { | ||
repo.push(getPlanets) | ||
} | ||
} | ||
// ... | ||
} | ||
``` | ||
### `update(repo, nextProps, nextState)` | ||
Called when a presenter gets new props. This is useful for secondary | ||
@@ -176,2 +210,22 @@ data fetching and other work that must happen when a Presenter receives | ||
```javascript | ||
import { getPlanet } from '../actions/planets' | ||
class Planet extends Presenter { | ||
getModel (props) { | ||
const { planetId } = props | ||
return { | ||
planet: state => state.planets.find(planet => planet.id === planetId) | ||
} | ||
} | ||
update (repo, nextProps, nextState) { | ||
if (nextProps.planetId !== this.props.planetId) | ||
repo.push(getPlanet, nextProps.planetId) | ||
} | ||
} | ||
// ... | ||
} | ||
``` | ||
`update` is always executed after the latest model has been calculated. | ||
@@ -181,4 +235,16 @@ | ||
Runs when the presenter unmounts. Useful for tearing down subscriptions and other setup behavior. | ||
Runs when the presenter unmounts. Useful for tearing down | ||
subscriptions and other setup behavior. | ||
```javascript | ||
class Example extends Presenter { | ||
setup () { | ||
this.socket = new WebSocket('ws://localhost:3000') | ||
} | ||
teardown () { | ||
this.socket.close() | ||
} | ||
} | ||
``` | ||
### `getModel(props, state)` | ||
@@ -276,3 +342,3 @@ | ||
} | ||
greet () { | ||
greet (repo, data) { | ||
alert("hello world!") | ||
@@ -317,1 +383,23 @@ } | ||
that is wrapped in the `withSend` higher order component. | ||
```javascript | ||
function AlertButton ({ message, send }) { | ||
return ( | ||
<button onClick=() => send('alert', message)> | ||
Click Me | ||
</button> | ||
) | ||
} | ||
class Example extends Presenter { | ||
intercept () { | ||
return { | ||
alert: message => alert(message) | ||
} | ||
} | ||
render () { | ||
return <AlertButton message="Hey!" send={this.send} /> | ||
} | ||
} | ||
``` |
@@ -172,6 +172,9 @@ # Architecture | ||
```javascript | ||
// axios is an AJAX library | ||
// https://github.com/mzabriskie/axios | ||
import axios from 'axios' | ||
function createPlanet (body) { | ||
// Fetch returns a Promise | ||
// https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch | ||
return fetch('/planets', { method: 'POST', body }) | ||
// axios returns a Promise, handled out of the box | ||
return axios.post('/planets', body) | ||
} | ||
@@ -178,0 +181,0 @@ ``` |
@@ -1,1 +0,1 @@ | ||
"use strict";function r(r){return r&&"object"==typeof r&&"default"in r?r.default:r}function t(r){return"string"==typeof r}function n(r){return""===r||null===r||void 0===r}function e(r){return Array.isArray(r)?r:n(r)?[]:t(r)?r.trim().split(a):[r]}function u(r){var t=r;return!1===Array.isArray(r)&&(t=(""+t).split(f)),t.map(e)}function o(r,t,n){return t.reduce(function(t,n){return i.set(t,n,i.get(r,n))},n||{})}Object.defineProperty(exports,"__esModule",{value:!0});var i=require("../microcosm.js"),l=r(i),a=".",f=",",s=function(){l.prototype.index=function(r,t){for(var n=arguments.length,e=Array(n>2?n-2:0),l=2;l<n;l++)e[l-2]=arguments[l];var a=this,f=u(t),s=null,p=null,c=null,y=function(){for(var r=arguments.length,t=Array(r),n=0;n<r;n++)t[n]=arguments[n];if(a.state!==s){s=a.state;var u=o(s,f,p);u!==p&&(p=u,c=e.reduce(function(r,t){return t.call(a,r,s)},p))}return t.reduce(function(r,t){return t.call(a,r,s)},c)};return this.indexes=i.set(this.indexes||{},r,y),y},l.prototype.lookup=function(r){var t=i.get(this.indexes,r);if(null==t){if(this.parent)return this.parent.lookup(r);throw new TypeError("Unable to find missing index "+r)}return t},l.prototype.compute=function(r){for(var t=arguments.length,n=Array(t>1?t-1:0),e=1;e<t;e++)n[e-1]=arguments[e];return this.lookup(r).apply(void 0,n)},l.prototype.memo=function(r){for(var t=arguments.length,n=Array(t>1?t-1:0),e=1;e<t;e++)n[e-1]=arguments[e];var u=this.lookup(r),o=null,i=null;return function(){var r=u();return r!==o&&(o=r,i=u.apply(void 0,n)),i}}};exports.default=s; | ||
"use strict";function r(r){return r&&"object"==typeof r&&"default"in r?r.default:r}function t(r){return"string"==typeof r}function n(r){return""===r||null===r||void 0===r}function e(r){return Array.isArray(r)?r:n(r)?[]:t(r)?r.trim().split(a):[r]}function u(r){var t=r;return!1===Array.isArray(r)&&(t=(""+t).split(f)),t.map(e)}function o(r,t,n){return t.reduce(function(t,n){return i.set(t,n,i.get(r,n))},n||{})}Object.defineProperty(exports,"__esModule",{value:!0});var i=require("../microcosm.js"),l=r(i),a=".",f=",",s=function(){l.prototype.index=function(r,t){for(var n=arguments.length,e=Array(n>2?n-2:0),l=2;l<n;l++)e[l-2]=arguments[l];var a=this,f=u(t),s=null,p=null,c=null,y=function(){for(var r=arguments.length,t=Array(r),n=0;n<r;n++)t[n]=arguments[n];if(a.state!==s){var u=o(s=a.state,f,p);u!==p&&(p=u,c=e.reduce(function(r,t){return t.call(a,r,s)},p))}return t.reduce(function(r,t){return t.call(a,r,s)},c)};return this.indexes=i.set(this.indexes||{},r,y),y},l.prototype.lookup=function(r){var t=i.get(this.indexes,r);if(null==t){if(this.parent)return this.parent.lookup(r);throw new TypeError("Unable to find missing index "+r)}return t},l.prototype.compute=function(r){for(var t=arguments.length,n=Array(t>1?t-1:0),e=1;e<t;e++)n[e-1]=arguments[e];return this.lookup(r).apply(void 0,n)},l.prototype.memo=function(r){for(var t=arguments.length,n=Array(t>1?t-1:0),e=1;e<t;e++)n[e-1]=arguments[e];var u=this.lookup(r),o=null,i=null;return function(){var r=u();return r!==o&&(o=r,i=u.apply(void 0,n)),i}}};exports.default=s; |
@@ -1,1 +0,1 @@ | ||
"use strict";function t(t){return t&&"object"==typeof t&&"default"in t?t.default:t}function e(){return this.props.children?r.Children.only(this.props.children):null}Object.defineProperty(exports,"__esModule",{value:!0});var r=t(require("react")),o=require("../microcosm.js"),n=t(o),s=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},p=function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)},i=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e},h=function(){},a=function(t){function o(r,n){s(this,o);var p=i(this,t.call(this));return p.render!==o.prototype.render?(p.defaultRender=p.render,p.render=o.prototype.render):p.defaultRender=e,p.send=p.send.bind(p),p}return p(o,t),o.prototype.a=function(t){this.repo=t.repo,this.mediator=t,this.setup(this.repo,this.props,this.state),this.model=this.b(),this.ready(this.repo,this.props,this.state)},o.prototype.c=function(){this.teardown(this.repo,this.props,this.state)},o.prototype.d=function(t){var e=this.props.repo||t,r=this.getRepo(e,this.props,this.state);return this.didFork=r!==e,r},o.prototype.b=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.props,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.state;return this.mediator.updateModel(t,e)},o.prototype.setup=function(t,e,r){},o.prototype.ready=function(t,e,r){},o.prototype.update=function(t,e,r){},o.prototype.teardown=function(t,e,r){},o.prototype.intercept=function(){return{}},o.prototype.componentWillUpdate=function(t,e){this.model=this.b(t,e),this.update(this.repo,t,e)},o.prototype.getRepo=function(t,e){return t?t.fork():new n},o.prototype.send=function(){var t;return(t=this.mediator).send.apply(t,arguments)},o.prototype.getModel=function(t,e){return{}},o.prototype.render=function(){return r.createElement(u,{presenter:this,parentState:this.state,parentProps:this.props})},o}(r.PureComponent),u=function(t){function e(r,o){s(this,e);var n=i(this,t.call(this,r,o));return n.presenter=r.presenter,n.repo=n.presenter.d(o.repo),n.send=n.send.bind(n),n.state={repo:n.repo,send:n.send},n}return p(e,t),e.prototype.getChildContext=function(){return{repo:this.repo,send:this.send}},e.prototype.componentWillMount=function(){this.presenter.getModel!==a.prototype.getModel&&this.repo.on("change",this.setModel,this),this.presenter.a(this)},e.prototype.componentDidMount=function(){this.presenter.refs=this.refs},e.prototype.componentWillUnmount=function(){this.presenter.refs=this.refs,this.repo.off("change",this.setModel,this),this.presenter.didFork&&this.repo.shutdown(),this.presenter.c()},e.prototype.render=function(){this.presenter.model=this.state;var t=this.presenter.view;return null!=t?r.createElement(t,o.merge(this.presenter.props,this.state)):this.presenter.defaultRender()},e.prototype.updateModel=function(t,e){var r=this.presenter.getModel(t,e),n=this.repo.state,s={};this.propMap={};for(var p in r){var i=r[p];i&&"function"==typeof i.call?(this.propMap[p]=i,s[p]=i.call(this.presenter,n,this.repo)):s[p]=i}return this.setState(s),o.merge(this.state,s)},e.prototype.setModel=function(t){var e=this.state,r=null;for(var o in this.propMap){var n=this.propMap[o].call(this.presenter,t,this.repo);e[o]!==n&&(r=r||{},r[o]=n)}null!==r&&this.setState(r)},e.prototype.hasParent=function(){return o.get(this.repo,"history")===o.get(this.context,["repo","history"])},e.prototype.send=function(t){for(var e=arguments.length,r=Array(e>1?e-1:0),n=1;n<e;n++)r[n-1]=arguments[n];var s=o.tag(t),p=this.presenter.intercept(),i=o.getRegistration(p,s,"resolve");return i?i.call.apply(i,[this.presenter,this.repo].concat(r)):this.hasParent()?this.context.send.apply(null,arguments):this.repo.push.apply(this.repo,arguments)},e}(r.PureComponent);u.contextTypes={repo:h,send:h},u.childContextTypes={repo:h,send:h},exports.default=a; | ||
"use strict";function t(t){return t&&"object"==typeof t&&"default"in t?t.default:t}function e(t){return t&&"function"==typeof t.subscribe}function r(t){return t&&"function"==typeof t.call}function n(t,e,n){return r(t)?t.call(n,e.state,e):t}function o(){return this.props.children?i.Children.only(this.props.children):null}Object.defineProperty(exports,"__esModule",{value:!0});var i=t(require("react")),s=require("../microcosm.js"),p=t(s),u=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},h=function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)},c=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e},a=function(t){function r(e,n){u(this,r);var o=c(this,t.call(this));return o.repo=e,o.scope=n,o.bindings={},o.subscriptions={},o.value={},o.repo.on("change",o.compute,o),o}return h(r,t),r.prototype.track=function(t,e){var r=this,n=this.subscriptions[t],o=e.subscribe(function(e){return r.set(t,e)});this.subscriptions[t]=o,n&&n.unsubscribe()},r.prototype.bind=function(t){this.bindings={};for(var r in t){var n=t[r];e(n)?this.track(r,n):this.bindings[r]=n}this.compute()},r.prototype.set=function(t,e){var r=s.set(this.value,t,e);this.value!==r&&(this.value=r,this._emit("change",this.value))},r.prototype.compute=function(){var t=this.value,e=t;for(var r in this.bindings){var o=n(this.bindings[r],this.repo,this.scope);e=s.set(e,r,o)}t!==e&&(this.value=e,this._emit("change",e))},r.prototype.teardown=function(){for(var t in this.subscriptions)this.subscriptions[t].unsubscribe();this.repo.off("change",this.compute,this)},r}(s.Emitter),d=function(){},f=function(t){function e(r,n){u(this,e);var i=c(this,t.call(this));return i.render!==e.prototype.render?(i.defaultRender=i.render,i.render=e.prototype.render):i.defaultRender=o,i.send=i.send.bind(i),i}return h(e,t),e.prototype._beginSetup=function(t){this.repo=t.repo,this.mediator=t,this.setup(this.repo,this.props,this.state),this.model=this.mediator.updateModel(this.props,this.state),this.ready(this.repo,this.props,this.state)},e.prototype._beginTeardown=function(){this.teardown(this.repo,this.props,this.state)},e.prototype._requestRepo=function(t){var e=this.props.repo||t,r=this.getRepo(e,this.props,this.state);return this.didFork=r!==e,r},e.prototype.setup=function(t,e,r){},e.prototype.ready=function(t,e,r){},e.prototype.update=function(t,e,r){},e.prototype.teardown=function(t,e,r){},e.prototype.intercept=function(){return{}},e.prototype.componentWillUpdate=function(t,e){this.model=this.mediator.updateModel(t,e),this.update(this.repo,t,e)},e.prototype.getRepo=function(t,e){return t?t.fork():new p},e.prototype.send=function(){var t;return(t=this.mediator).send.apply(t,arguments)},e.prototype.getModel=function(t,e){return{}},e.prototype.render=function(){return i.createElement(l,{presenter:this,parentState:this.state,parentProps:this.props})},e}(i.PureComponent),l=function(t){function e(r,n){u(this,e);var o=c(this,t.call(this,r,n));return o.presenter=r.presenter,o.repo=o.presenter._requestRepo(n.repo),o.send=o.send.bind(o),o.state={repo:o.repo,send:o.send},o.model=new a(o.repo,o.presenter),o.model.on("change",o.setState,o),o}return h(e,t),e.prototype.getChildContext=function(){return{repo:this.repo,send:this.send}},e.prototype.componentWillMount=function(){this.presenter._beginSetup(this)},e.prototype.componentDidMount=function(){this.presenter.refs=this.refs},e.prototype.componentWillUnmount=function(){this.presenter.refs=this.refs,this.presenter.didFork&&this.repo.shutdown(),this.model.teardown(),this.presenter._beginTeardown()},e.prototype.render=function(){this.presenter.model=this.state;var t=this.presenter.view;return null!=t?i.createElement(t,s.merge(this.presenter.props,this.state)):this.presenter.defaultRender()},e.prototype.updateModel=function(t,e){var r=this.presenter.getModel(t,e);return this.model.bind(r),this.model.value},e.prototype.hasParent=function(){return s.get(this.repo,"history")===s.get(this.context,["repo","history"])},e.prototype.send=function(t){for(var e=arguments.length,r=Array(e>1?e-1:0),n=1;n<e;n++)r[n-1]=arguments[n];var o=s.tag(t),i=this.presenter.intercept(),p=s.getRegistration(i,o,"resolve");return p?p.call.apply(p,[this.presenter,this.repo].concat(r)):this.hasParent()?this.context.send.apply(null,arguments):this.repo.push.apply(this.repo,arguments)},e}(i.PureComponent);l.contextTypes={repo:d,send:d},l.childContextTypes={repo:d,send:d},exports.default=f; |
@@ -1,1 +0,1 @@ | ||
"use strict";function t(t){return""===t||null===t||void 0===t}function e(e){return Array.isArray(e)?e:t(e)?[]:l(e)?e.trim().split(j):[e]}function n(t){var n=t;return!1===Array.isArray(t)&&(n=(""+n).split(O)),n.map(e)}function r(t){return t.join(j)}function o(t){return t.map(r).join(O)}function i(t){if(Array.isArray(t))return t.slice(0);if(!1===h(t))return t;var e={};for(var n in t)e[n]=t[n];return e}function s(){for(var t=null,e=null,n=0,r=arguments.length;n<r;n++){t=t||arguments[n],e=e||t;var o=arguments[n];for(var s in o)t[s]!==o[s]&&(t===e&&(t=i(e)),t[s]=o[s])}return t}function a(t,e,n){return t.__proto__=e,t.prototype=s(Object.create(e.prototype),{constructor:t.prototype.constructor},n),t}function u(t,n,r){if(null==t)return r;for(var o=e(n),i=0,s=o.length;i<s;i++){var a=null==t?void 0:t[o[i]];if(void 0===a)return r;t=a}return t}function c(t,n,r){var o=e(n),s=o.length;if(s<=0)return r;if(u(t,o)===r)return t;for(var a=i(t),c=a,p=0;p<s;p++){var h=o[p],f=r;p<s-1&&(f=h in c?i(c[h]):{}),c[h]=f,c=c[h]}return a}function p(t){return(h(t)||f(t))&&f(t.then)}function h(t){return!!t&&"object"===(void 0===t?"undefined":I(t))}function f(t){return!!t&&"function"==typeof t}function l(t){return"string"==typeof t}function d(t){return"GeneratorFunction"===u(t,H,"")}function y(t,e,n){return f(t)?new t(e,n):Object.create(t)}function v(t,n,r,o){var i=e(n);return!1===f(r)?c(t,i,r):c(t,i,r(u(t,i,o)))}function g(t,e){if(!0===t.a)return t;l(t)&&(e=t,t=function(t){return t}),q+=1;var n=e||(t.name||C)+"."+q;return t.open=n+".open",t.loading=n+".loading",t.update=t.loading,t.done=n,t.resolve=t.done,t.error=n+".error",t.reject=t.error,t.cancel=n+".cancel",t.cancelled=t.cancel,t.toString=function(){return n},t.a=!0,t}function m(t,e){return function(){}}function b(t,e,n){return function(r){return t.status=e,t.complete=n,arguments.length>0&&(t.payload=r),t.b("change",t),t.b(e,t.payload),t}}function w(t,e,n){return t.complete?m(t,e):b(t,e,n)}function x(t){return function(e){!0===t.batch?B(e,J):e()}}function z(t,e){return function(n,r){var o=t;if(e)try{o=r.deserialize(t)}catch(t){throw n.reject(t),t}var i=r.domains.sanitize(o);n.resolve(i)}}function S(t,e,n){var r=Y[n],o=t[e],i=e[n];return h(o)?o[r]||o[n]:t[i]}function k(t,e,n){function r(e){var n=i.next(e);n.done?t.resolve(e):o(n.value)}function o(e){e.onDone(r),e.onCancel(t.cancel,t),e.onError(t.reject,t)}t.open();var i=e(n);return r(),t}function A(t,e,n,r){var o=e.apply(null,n);return p(o)?(t.open.apply(t,n),o.then(function(e){return global.setTimeout(function(){return t.resolve(e)},0)},function(e){return global.setTimeout(function(){return t.reject(e)},0)}),t):d(o)?k(t,o,r):f(o)?(o(t,r),t):t.resolve(o)}Object.defineProperty(exports,"__esModule",{value:!0});var j=".",O=",",I="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},E=function(){function t(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}return function(e,n,r){return n&&t(e.prototype,n),r&&t(e,r),e}}(),P=function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)},D=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e},T="function"==typeof Symbol?Symbol:{},H=T.toStringTag||"@@toStringTag",R=function t(e,n,r,o){_(this,t),this.event=e,this.fn=n,this.scope=r,this.once=o},N=function(){function t(){_(this,t),this.c=[]}return t.prototype.on=function(t,e,n){var r=new R(t,e,n,!1);return this.c.push(r),this},t.prototype.once=function(t,e,n){var r=new R(t,e,n,!0);return this.c.push(r),this},t.prototype.off=function(t,e,n){for(var r=null==e,o=0;o<this.c.length;){var i=this.c[o];i.event===t&&(r||i.fn===e&&i.scope===n)?this.c.splice(o,1):o+=1}return this},t.prototype.removeAllListeners=function(){this.c.length=0},t.prototype.b=function(t){for(var e=0,n=arguments.length,r=Array(n>1?n-1:0),o=1;o<n;o++)r[o-1]=arguments[o];for(;e<this.c.length;){var i=this.c[e];i.event===t&&(i.fn.apply(i.scope||this,r),i.once)?this.c.splice(e,1):e+=1}return this},t.prototype.d=function(t){for(var e=0;e<this.c.length;)t!==this.c[e].scope?e+=1:this.c.splice(e,1)},t}(),q=0,C="_action",L=0,M=function(t){function e(n,r){_(this,e);var o=D(this,t.call(this));return o.id=L++,o.command=g(n),o.status="inactive",o.payload=void 0,o.disabled=!1,o.complete=!1,o.parent=null,o.next=null,o.timestamp=Date.now(),o.children=[],r&&o[r](),o}return P(e,t),e.prototype.onOpen=function(t,e){return this.e("open",t,e),this},e.prototype.onUpdate=function(t,e){return t&&this.on("update",t,e),this},e.prototype.onDone=function(t,e){return this.e("resolve",t,e),this},e.prototype.onError=function(t,e){return this.e("reject",t,e),this},e.prototype.onCancel=function(t,e){return this.e("cancel",t,e),this},e.prototype.is=function(t){return this.command[this.status]===this.command[t]},e.prototype.toggle=function(t){return this.disabled=!this.disabled,t||this.b("change",this),this},e.prototype.then=function(t,e){var n=this;return new Promise(function(t,e){n.onDone(t),n.onError(e)}).then(t,e)},e.prototype.isDisconnected=function(){return!this.parent},e.prototype.prune=function(){this.parent.parent=null},e.prototype.lead=function(t){this.next=t,t&&this.adopt(t)},e.prototype.adopt=function(t){this.children.indexOf(t)<0&&this.children.push(t),t.parent=this},e.prototype.remove=function(){this.parent.abandon(this),this.removeAllListeners()},e.prototype.abandon=function(t){var e=this.children.indexOf(t);e>=0&&(this.children.splice(e,1),t.parent=null),this.next===t&&this.lead(t.next)},e.prototype.e=function(t,e,n){e&&(this.is(t)?e.call(n,this.payload):this.once(t,e,n))},E(e,[{key:"type",get:function(){return this.command[this.status]}},{key:"open",get:function(){return w(this,"open",!1)}},{key:"update",get:function(){return w(this,"update",!1)}},{key:"resolve",get:function(){return w(this,"resolve",!0)}},{key:"reject",get:function(){return w(this,"reject",!0)}},{key:"cancel",get:function(){return w(this,"cancel",!0)}}]),e}(N),B=global.requestIdleCallback||function(t){return setTimeout(t,4)},J={timeout:36},Q=g(function(t,e){return z(t,e)},"$reset"),$=g(function(t,e){return z(t,e)},"$patch"),F=function(){},G=function(){},U=function(t){return t},K={maxHistory:1,batch:!1,updater:x},V=function(t){function e(n){_(this,e);var r=D(this,t.call(this)),o=s(K,n);return r.size=0,r.limit=Math.max(1,o.maxHistory),r.updater=o.updater(o),r.releasing=!1,r.release=function(){return r.closeRelease()},r.begin(),r}return P(e,t),e.prototype.checkout=function(t){return this.head=t||this.head,this.head.parent.next=this.head,this.setSize(),this.reconcile(this.head),this},e.prototype.toggle=function(t){var e=[].concat(t);e.forEach(function(t){return t.toggle("silently")}),this.reconcile(e[0])},e.prototype.toArray=function(){return this.map(function(t){return t})},e.prototype.map=function(t,e){for(var n=this.size,r=Array(n),o=this.head;n--;)r[n]=t.call(e,o),o=o.parent;return r},e.prototype.wait=function(){var t=this,e=this.toArray();return new Promise(function(n,r){var o=function o(){var i=e.every(function(t){return t.complete}),s=e.filter(function(t){return t.is("reject")});i&&(t.off("release",o),s.length?r(s[0].payload):n())};!1===t.releasing&&o(),t.on("release",o)})},e.prototype.then=function(t,e){return this.wait().then(t,e)},e.prototype.begin=function(){this.head=this.root=null,this.append(G,"resolve")},e.prototype.append=function(t,e){var n=new M(t,e);return this.size>0?this.head.lead(n):(new M(F,"resolve").adopt(n),this.root=n),this.head=n,this.size+=1,this.b("append",n),n.on("change",this.reconcile,this),this.head},e.prototype.remove=function(t){if(!t.isDisconnected()){var e=t.next,n=t.parent;if(this.clean(t),this.size<=0)return void this.begin();e?t===this.root&&(this.root=e):e=this.head=n,t.disabled||this.reconcile(e)}},e.prototype.clean=function(t){this.size-=1,this.b("remove",t),t.remove()},e.prototype.reconcile=function(t){for(var e=t;e&&(this.b("update",e),e!==this.head);)e=e.next;this.archive(),this.b("reconcile",t),this.queueRelease()},e.prototype.queueRelease=function(){!1===this.releasing&&(this.releasing=!0,this.updater(this.release))},e.prototype.closeRelease=function(){this.releasing=!1,this.b("release")},e.prototype.archive=function(){for(var t=this.size,e=this.root;t>this.limit&&e.complete;)t-=1,this.b("remove",e.parent),e=e.next;e.prune(),this.root=e,this.size=t},e.prototype.setSize=function(){for(var t=this.head,e=1;t!==this.root;)t=t.parent,e+=1;this.size=e},e}(N),W=function(){function t(){_(this,t),this.pool={}}return t.prototype.create=function(t){this.set(t,this.get(t.parent))},t.prototype.get=function(t,e){var n=this.pool[t.id];return void 0===n?e:n},t.prototype.set=function(t,e){this.pool[t.id]=e},t.prototype.remove=function(t){delete this.pool[t.id]},t}(),X=function(){function t(){_(this,t)}return t.prototype.setup=function(t){this.repo=t},t.prototype.reset=function(t,e){var n=this.repo.domains.sanitize(e);return s(t,this.repo.getInitialState(),n)},t.prototype.patch=function(t,e){return s(t,this.repo.domains.sanitize(e))},t.prototype.addDomain=function(t){return s(this.repo.getInitialState(),t)},t.prototype.register=function(){var t;return t={},t[Q]=this.reset,t[$]=this.patch,t[U]=this.addDomain,t},t}(),Y={inactive:"inactive",open:"open",update:"loading",loading:"update",done:"resolve",resolve:"done",reject:"error",error:"reject",cancel:"cancelled",cancelled:"cancel"},Z=function(){function t(e){_(this,t),this.repo=e,this.domains=[],this.registry={},this.add([],X)}return t.prototype.getHandlers=function(t){for(var e=t.command,n=t.status,r=[],o=0,i=this.domains.length;o<i;o++){var s=this.domains[o],a=s[0],u=s[1];if(u.register){var c=S(u.register(),e,n);c&&r.push({key:a,domain:u,handler:c})}}return r},t.prototype.register=function(t){var e=t.type;return this.registry[e]||(this.registry[e]=this.getHandlers(t)),this.registry[e]},t.prototype.add=function(t,n,r){var o=y(n,r,this.repo);return this.domains.push([e(t),o]),this.registry={},o.setup&&o.setup(this.repo,r),o.teardown&&this.repo.on("teardown",o.teardown,o),o},t.prototype.reduce=function(t,e,n){for(var r=e,o=1,i=this.domains.length;o<i;o++){var s=this.domains[o],a=s[0],u=s[1];r=t.call(n,r,a,u)}return r},t.prototype.sanitize=function(t){for(var e={},n=0,r=this.domains.length;n<r;n++){var o=this.domains[n],i=o[0];i.length&&(e=c(e,i,u(t,i)))}return e},t.prototype.dispatch=function(t,e){for(var n=this.register(e),r=0,o=n.length;r<o;r++){var i=n[r],s=i.key,a=i.domain,p=i.handler,h=u(t,s);t=c(t,s,p.call(a,h,e.payload))}return t},t.prototype.deserialize=function(t){return this.reduce(function(e,n,r){return r.deserialize?c(e,n,r.deserialize(u(t,n))):e},t)},t.prototype.serialize=function(t,e){return this.reduce(function(e,n,r){return r.serialize?c(e,n,r.serialize(u(t,n))):e},e)},t}(),tt=function(){function t(e){_(this,t),this.repo=e,this.effects=[]}return t.prototype.add=function(t,e){var n=y(t,e,this.repo);return n.setup&&n.setup(this.repo,e),n.teardown&&this.repo.on("teardown",n.teardown,n),this.effects.push(n),n},t.prototype.dispatch=function(t){for(var e=t.command,n=t.payload,r=t.status,o=0,i=this.effects.length;o<i;o++){var s=this.effects[o];if(s.register){var a=S(s.register(),e,r);a&&a.call(s,this.repo,n)}}},t}(),et=function(){function t(e,n,r){_(this,t),this.id=e,this.key=n,this.edges=[],this.parent=r||null,r&&r.connect(this)}return t.getId=function(t,e){return e&&e.id?e.id+"."+t:t},t.prototype.connect=function(t){t!==this&&this.edges.indexOf(t)<0&&this.edges.push(t)},t.prototype.disconnect=function(t){var e=this.edges.indexOf(t);~e&&this.edges.splice(e,1)},t.prototype.isAlone=function(){return this.edges.length<=0},t.prototype.orphan=function(){this.parent&&this.parent.disconnect(this)},t}(),nt=function(t){function e(r,o){_(this,e);var i=D(this,t.call(this));return i.id=r,i.keyPaths=n(o),i}return P(e,t),e.getId=function(t){return"query:"+o(n(t))},e.prototype.extract=function(t){for(var e=this.keyPaths.length,n=Array(e),r=0;r<e;r++)n[r]=u(t,this.keyPaths[r]);return n},e.prototype.trigger=function(t){var e=this.extract(t);this.b.apply(this,["change"].concat(e))},e.prototype.isAlone=function(){return this.c.length<=0},e}(N),rt="",ot=function(){function t(e){_(this,t),this.snapshot=e,this.nodes={}}return t.prototype.on=function(t,e,r){for(var o=n(t),i=nt.getId(t),s=this.addQuery(i,o),a=0;a<o.length;a++)this.addBranch(o[a],s);return s.on("change",e,r),s},t.prototype.off=function(t,e,n){var r=nt.getId(t),o=this.nodes[r];o&&(o.off("change",e,n),o.isAlone()&&this.prune(o))},t.prototype.update=function(t){var e=this.snapshot;if(this.snapshot=t,this.nodes[rt])for(var n=this.scan(this.nodes[rt],e,t,[]),r=0;r<n.length;r++)n[r].trigger(t)},t.prototype.addNode=function(t,e){var n=et.getId(t,e);return this.nodes[n]||(this.nodes[n]=new et(n,t,e)),this.nodes[n]},t.prototype.addQuery=function(t,e){return this.nodes[t]||(this.nodes[t]=new nt(t,e)),this.nodes[t]},t.prototype.remove=function(t){delete this.nodes[t.id]},t.prototype.prune=function(t){for(var e=t.keyPaths.map(r),n=0,o=e.length;n<o;n++){var i=this.nodes[e[n]];i.disconnect(t);do{if(!i.isAlone())break;i.orphan(),this.remove(i),i=i.parent}while(i)}this.remove(t)},t.prototype.addBranch=function(t,e){for(var n=this.addNode(rt,null),r=0,o=t.length;r<o;r++)n=this.addNode(t[r],n);n.connect(e)},t.prototype.scan=function(t,e,n,r){if(e!==n)for(var o=t.edges,i=0,s=o.length;i<s;i++){var a=o[i];if(a instanceof nt&&r.indexOf(a)<0)r.push(a);else{var u=null==e?e:e[a.key],c=null==n?n:n[a.key];this.scan(a,u,c,r)}}return r},t}(),it={maxHistory:0,parent:null,batch:!1},st=function(t){function e(n,r,o){_(this,e);var i=D(this,t.call(this)),a=s(it,i.constructor.defaults,n);return i.parent=a.parent,i.initial=i.parent?i.parent.initial:{},i.state=i.parent?i.parent.state:i.initial,i.history=i.parent?i.parent.history:new V(a),i.archive=new W,i.domains=new Z(i),i.effects=new tt(i),i.changes=new ot(i.state),i.history.on("append",i.createSnapshot,i),i.history.on("update",i.updateSnapshot,i),i.history.on("remove",i.removeSnapshot,i),i.history.on("reconcile",i.dispatchEffect,i),i.history.on("release",i.release,i),i.setup(a),r&&i.reset(r,o),i}return P(e,t),e.prototype.setup=function(){},e.prototype.teardown=function(){},e.prototype.getInitialState=function(){return this.initial},e.prototype.recall=function(t,e){return this.archive.get(t,e)},e.prototype.createSnapshot=function(t){this.archive.create(t)},e.prototype.updateSnapshot=function(t){var e=this.recall(t.parent,this.initial);this.parent&&(e=s(e,this.parent.recall(t))),t.disabled||(e=this.domains.dispatch(e,t)),this.archive.set(t,e),this.state=e},e.prototype.removeSnapshot=function(t){this.archive.remove(t)},e.prototype.dispatchEffect=function(t){this.effects.dispatch(t)},e.prototype.release=function(){this.changes.update(this.state)},e.prototype.on=function(t,e,n){var r=t.split(":",2),o=r[0],i=r[1];switch(o){case"change":this.changes.on(i||"",e,n);break;default:N.prototype.on.apply(this,arguments)}return this},e.prototype.off=function(t,e,n){var r=t.split(":",2),o=r[0],i=r[1];switch(o){case"change":this.changes.off(i||"",e,n);break;default:N.prototype.off.apply(this,arguments)}return this},e.prototype.append=function(t,e){return this.history.append(t,e)},e.prototype.push=function(t){for(var e=this.append(t),n=arguments.length,r=Array(n>1?n-1:0),o=1;o<n;o++)r[o-1]=arguments[o];return A(e,e.command,r,this),e},e.prototype.prepare=function(){for(var t=this,e=arguments.length,n=Array(e),r=0;r<e;r++)n[r]=arguments[r];return function(){for(var e=arguments.length,r=Array(e),o=0;o<e;o++)r[o]=arguments[o];return t.push.apply(t,n.concat(r))}},e.prototype.addDomain=function(t,e,n){var r=this.domains.add(t,e,n);return r.getInitialState&&(this.initial=c(this.initial,t,r.getInitialState())),this.push(U,r),r},e.prototype.addEffect=function(t,e){return this.effects.add(t,e)},e.prototype.reset=function(t,e){return this.push(Q,t,e)},e.prototype.patch=function(t,e){return this.push($,t,e)},e.prototype.deserialize=function(t){var e=t;return this.parent?e=this.parent.deserialize(t):l(e)&&(e=JSON.parse(e)),this.domains.deserialize(e)},e.prototype.serialize=function(){var t=this.parent?this.parent.serialize():{};return this.domains.serialize(this.state,t)},e.prototype.toJSON=function(){return this.serialize()},e.prototype.checkout=function(t){return this.history.checkout(t),this},e.prototype.fork=function(){return new e({parent:this})},e.prototype.shutdown=function(){this.teardown(),this.b("teardown",this),this.history.d(this),this.removeAllListeners()},e}(N);exports.default=st,exports.Microcosm=st,exports.Action=M,exports.History=V,exports.tag=g,exports.get=u,exports.set=c,exports.update=v,exports.merge=s,exports.inherit=a,exports.getRegistration=S; | ||
"use strict";function t(t){return""===t||null===t||void 0===t}function e(e){return Array.isArray(e)?e:t(e)?[]:d(e)?e.trim().split(k):[e]}function n(t){var n=t;return!1===Array.isArray(t)&&(n=(""+n).split(A)),n.map(e)}function r(t){return t.join(k)}function o(t){return t.map(r).join(A)}function i(t){return""+t+D++}function s(t){if(Array.isArray(t))return t.slice(0);if(!1===f(t))return t;var e={};for(var n in t)e[n]=t[n];return e}function a(){for(var t=null,e=null,n=0,r=arguments.length;n<r;n++){t=t||arguments[n],e=e||t;var o=arguments[n];for(var i in o)t[i]!==o[i]&&(t===e&&(t=s(e)),t[i]=o[i])}return t}function u(t,e,n){return t.__proto__=e,t.prototype=a(Object.create(e.prototype),{constructor:t.prototype.constructor},n),t}function p(t,n,r){if(null==t)return r;for(var o=e(n),i=0,s=o.length;i<s;i++){var a=null==t?void 0:t[o[i]];if(void 0===a)return r;t=a}return t}function c(t,n,r){var o=e(n),i=o.length;if(i<=0)return r;if(p(t,o)===r)return t;for(var a=s(t),u=a,c=0;c<i;c++){var h=o[c],f=r;c<i-1&&(f=h in u?s(u[h]):{}),u[h]=f,u=u[h]}return a}function h(t){return(f(t)||l(t))&&l(t.then)}function f(t){return!!t&&"object"===(void 0===t?"undefined":j(t))}function l(t){return!!t&&"function"==typeof t}function d(t){return"string"==typeof t}function y(t){return p(t,N,"")}function v(t){return"GeneratorFunction"===y(t)}function g(t,e,n){return l(t)?new t(e,n):Object.create(t)}function m(t,n,r,o){var i=e(n);return!1===l(r)?c(t,i,r):c(t,i,r(p(t,i,o)))}function b(t,e){if(!0===t.__tagged)return t;d(t)&&(e=t,t=function(t){return t}),q+=1;var n=e||(t.name||J)+"."+q;return t.open=n+".open",t.loading=n+".loading",t.update=t.loading,t.done=n,t.resolve=t.done,t.error=n+".error",t.reject=t.error,t.cancel=n+".cancel",t.cancelled=t.cancel,t.toString=function(){return n},t.__tagged=!0,t}function _(t,e,n){return function(r){return!1===t.complete&&(t.status=e,t.complete=n,arguments.length>0&&(t.payload=r),t._emit("change",t),t._emit(e,t.payload)),t}}function w(t){return function(e){!0===t.batch?L(e,M):e()}}function x(t,e){return function(n,r){var o=t;if(e)try{o=r.deserialize(t)}catch(t){throw n.reject(t),t}var i=r.domains.sanitize(o);n.resolve(i)}}function S(t,e,n){var r=Y[n],o=t[e],i=e[n];return f(o)?o[r]||o[n]:t[i]}function O(t,e,n){function r(e){var n=i.next(e);n.done?t.resolve(e):o(n.value)}function o(e){Array.isArray(e)&&(e=n.parallel(e)),e.onDone(r),e.onCancel(t.cancel,t),e.onError(t.reject,t)}t.open();var i=e(n);return r(),t}function z(t,e,n,r){var o=e.apply(null,n);return h(o)?(t.open.apply(t,n),o.then(function(e){return global.setTimeout(function(){return t.resolve(e)},0)},function(e){return global.setTimeout(function(){return t.reject(e)},0)}),t):v(o)?O(t,o,r):l(o)?(o(t,r),t):t.resolve(o)}Object.defineProperty(exports,"__esModule",{value:!0});var k=".",A=",",j="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},E=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},I=function(){function t(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}return function(e,n,r){return n&&t(e.prototype,n),r&&t(e,r),e}}(),P=function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)},R=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e},D=0,H="function"==typeof Symbol?Symbol:{},N=H.toStringTag||"@@toStringTag",T=function t(e,n,r,o){E(this,t),this.event=e,this.fn=n,this.scope=r,this.once=o},C=function(){function t(){E(this,t),this._events=[]}return t.prototype.on=function(t,e,n){var r=new T(t,e,n,!1);return this._events.push(r),this},t.prototype.once=function(t,e,n){var r=new T(t,e,n,!0);return this._events.push(r),this},t.prototype.off=function(t,e,n){for(var r=null==e,o=0;o<this._events.length;){var i=this._events[o];i.event===t&&(r||i.fn===e&&i.scope===n)?this._events.splice(o,1):o+=1}return this},t.prototype.removeAllListeners=function(){this._events.length=0},t.prototype._emit=function(t){for(var e=0,n=arguments.length,r=Array(n>1?n-1:0),o=1;o<n;o++)r[o-1]=arguments[o];for(;e<this._events.length;){var i=this._events[e];i.event===t&&(i.fn.apply(i.scope||this,r),i.once)?this._events.splice(e,1):e+=1}return this},t.prototype._removeScope=function(t){for(var e=0;e<this._events.length;)t!==this._events[e].scope?e+=1:this._events.splice(e,1)},t}(),q=0,J="_action",K=function(t){function e(n,r){E(this,e);var o=R(this,t.call(this));return o.id=i("action"),o.command=b(n),o.status="inactive",o.payload=void 0,o.disabled=!1,o.complete=!1,o.parent=null,o.next=null,o.timestamp=Date.now(),o.children=[],r&&o[r](),o}return P(e,t),e.prototype.onOpen=function(t,e){return this._callOrSubscribeOnce("open",t,e),this},e.prototype.onUpdate=function(t,e){return t&&this.on("update",t,e),this},e.prototype.onDone=function(t,e){return this._callOrSubscribeOnce("resolve",t,e),this},e.prototype.onError=function(t,e){return this._callOrSubscribeOnce("reject",t,e),this},e.prototype.onCancel=function(t,e){return this._callOrSubscribeOnce("cancel",t,e),this},e.prototype.is=function(t){return this.command[this.status]===this.command[t]},e.prototype.toggle=function(t){return this.disabled=!this.disabled,t||this._emit("change",this),this},e.prototype.link=function(t){var e=this,n=t.length,r=function(){(n-=1)<=0&&e.resolve()};return t.forEach(function(t){t.onDone(r),t.onCancel(r),t.onError(e.reject)}),this},e.prototype.then=function(t,e){var n=this;return new Promise(function(t,e){n.onDone(t),n.onError(e)}).then(t,e)},e.prototype.isDisconnected=function(){return!this.parent},e.prototype.prune=function(){this.parent.parent=null},e.prototype.lead=function(t){this.next=t,t&&this.adopt(t)},e.prototype.adopt=function(t){this.children.indexOf(t)<0&&this.children.push(t),t.parent=this},e.prototype.remove=function(){this.parent.abandon(this),this.removeAllListeners()},e.prototype.abandon=function(t){var e=this.children.indexOf(t);e>=0&&(this.children.splice(e,1),t.parent=null),this.next===t&&this.lead(t.next)},e.prototype._callOrSubscribeOnce=function(t,e,n){e&&(this.is(t)?e.call(n,this.payload):this.once(t,e,n))},e.prototype.toJSON=function(){return{id:this.id,status:this.status,type:this.type,payload:this.payload,disabled:this.disabled,children:this.children,next:this.next&&this.next.id}},I(e,[{key:"type",get:function(){return this.command[this.status]}},{key:"open",get:function(){return _(this,"open",!1)}},{key:"update",get:function(){return _(this,"update",!1)}},{key:"resolve",get:function(){return _(this,"resolve",!0)}},{key:"reject",get:function(){return _(this,"reject",!0)}},{key:"cancel",get:function(){return _(this,"cancel",!0)}}]),e}(C),L=global.requestIdleCallback||function(t){return setTimeout(t,4)},M={timeout:36},B=b(function(t,e){return x(t,e)},"$reset"),G=b(function(t,e){return x(t,e)},"$patch"),Q=function(){},U=function(){},$=function(t){return t},F={maxHistory:1,batch:!1,updater:w},V=function(t){function e(n){E(this,e);var r=R(this,t.call(this)),o=a(F,n);return r.size=0,r.limit=Math.max(1,o.maxHistory),r.updater=o.updater(o),r.releasing=!1,r.release=function(){return r.closeRelease()},r.begin(),r}return P(e,t),e.prototype.checkout=function(t){var e=this.sharedRoot(t)||this.head;this.head=t||this.head;for(var n=this.head;n!=e;){var r=n.parent;r.next=n,n=r}return this.setSize(),this.reconcile(e),this},e.prototype.toggle=function(t){var e=[].concat(t);e.forEach(function(t){return t.toggle("silently")});var n=void 0,r=1/0,o=this.toArray();e.forEach(function(t){var e=o.indexOf(t);e>=0&&e<r&&(r=e,n=t)}),n&&this.reconcile(n)},e.prototype.toArray=function(){return this.map(function(t){return t})},e.prototype.map=function(t,e){for(var n=[],r=this.root;r&&(n.push(t.call(e,r)),r!=this.head);)r=r.next;return n},e.prototype.wait=function(){var t=this,e=this.toArray();return new Promise(function(n,r){var o=function o(){var i=e.every(function(t){return t.complete}),s=e.filter(function(t){return t.is("reject")});i&&(t.off("release",o),s.length?r(s[0].payload):n())};!1===t.releasing&&o(),t.on("release",o)})},e.prototype.then=function(t,e){return this.wait().then(t,e)},e.prototype.begin=function(){this.head=this.root=null,this.append(U,"resolve")},e.prototype.append=function(t,e){var n=new K(t,e);return this.size>0?this.head.lead(n):(new K(Q,"resolve").adopt(n),this.root=n),this.head=n,this.size+=1,this._emit("append",n),n.on("change",this.reconcile,this),this.head},e.prototype.remove=function(t){if(!t.isDisconnected()){var e=t.parent,n=t.next,r=this.isActive(t);this.clean(t),this.size<=0?this.begin():(t===this.head?n=this.head=e:t===this.root&&(this.root=n),r&&!t.disabled&&this.reconcile(n))}},e.prototype.clean=function(t){this.size-=1,this._emit("remove",t),t.remove()},e.prototype.reconcile=function(t){for(var e=t;e&&(this._emit("update",e),e!==this.head);)e=e.next;this.archive(),this._emit("reconcile",t),this.queueRelease()},e.prototype.queueRelease=function(){!1===this.releasing&&(this.releasing=!0,this.updater(this.release))},e.prototype.closeRelease=function(){this.releasing=!1,this._emit("release")},e.prototype.archive=function(){for(var t=this.size,e=this.root;t>this.limit&&e.complete;)t-=1,this._emit("remove",e.parent),e=e.next;e.prune(),this.root=e,this.size=t},e.prototype.setSize=function(){for(var t=this.head,e=1;t!==this.root;)t=t.parent,e+=1;this.size=e},e.prototype.isActive=function(t){for(var e=t;e;){if(e===this.head)return!0;e=e.next}return!1},e.prototype.sharedRoot=function(t){for(var e=t;e;){if(this.isActive(e))return e;e=e.parent}},e.prototype.toJSON=function(){return{head:this.head.id,root:this.root.id,size:this.size,tree:this.root}},e}(C),W=function(){function t(){E(this,t),this.pool={}}return t.prototype.create=function(t){this.set(t,this.get(t.parent))},t.prototype.get=function(t,e){var n=this.pool[t.id];return void 0===n?e:n},t.prototype.set=function(t,e){this.pool[t.id]=e},t.prototype.remove=function(t){delete this.pool[t.id]},t}(),X=function(){function t(){E(this,t)}return t.prototype.setup=function(t){this.repo=t},t.prototype.reset=function(t,e){var n=this.repo.domains.sanitize(e);return a(t,this.repo.getInitialState(),n)},t.prototype.patch=function(t,e){return a(t,this.repo.domains.sanitize(e))},t.prototype.addDomain=function(t){return a(this.repo.getInitialState(),t)},t.prototype.register=function(){var t;return t={},t[B]=this.reset,t[G]=this.patch,t[$]=this.addDomain,t},t}(),Y={inactive:"inactive",open:"open",update:"loading",loading:"update",done:"resolve",resolve:"done",reject:"error",error:"reject",cancel:"cancelled",cancelled:"cancel"},Z=function(){function t(e){E(this,t),this.registry={},this.repo=e,this.domains=[],this.add([],X)}return t.prototype.getRepoHandlers=function(t){var e=t.command,n=t.status,r=null;return this.repo.register&&(r=S(this.repo.register(),e,n)),r?[{key:[],domain:this.repo,handler:r}]:[]},t.prototype.getHandlers=function(t){for(var e=this.getRepoHandlers(t),n=t.command,r=t.status,o=0,i=this.domains.length;o<i;o++){var s=this.domains[o],a=s[0],u=s[1];if(u.register){var p=S(u.register(),n,r);p&&e.push({key:a,domain:u,handler:p})}}return e},t.prototype.register=function(t){var e=t.type;return this.registry[e]||(this.registry[e]=this.getHandlers(t)),this.registry[e]},t.prototype.add=function(t,n,r){var o=g(n,r,this.repo);return this.domains.push([e(t),o]),this.registry={},o.setup&&o.setup(this.repo,r),o.teardown&&this.repo.on("teardown",o.teardown,o),o},t.prototype.reduce=function(t,e,n){for(var r=e,o=1,i=this.domains.length;o<i;o++){var s=this.domains[o],a=s[0],u=s[1];r=t.call(n,r,a,u)}return r},t.prototype.supportsKey=function(t){return t in this.repo.state||this.domains.some(function(e){return r(e[0])===t})},t.prototype.sanitize=function(t){var e=this.repo.parent,n={};for(var r in t)e&&e.domains.supportsKey(r)||this.supportsKey(r)&&(n[r]=t[r]);return n},t.prototype.dispatch=function(t,e){for(var n=this.register(e),r=0,o=n.length;r<o;r++){var i=n[r],s=i.key,a=i.domain,u=i.handler,h=p(t,s);t=c(t,s,u.call(a,h,e.payload))}return t},t.prototype.deserialize=function(t){return this.reduce(function(e,n,r){return r.deserialize?c(e,n,r.deserialize(p(t,n))):e},t)},t.prototype.serialize=function(t,e){return this.reduce(function(e,n,r){return r.serialize?c(e,n,r.serialize(p(t,n))):e},e)},t}(),tt=function(){function t(e){E(this,t),this.repo=e,this.effects=[]}return t.prototype.add=function(t,e){var n=g(t,e,this.repo);return n.setup&&n.setup(this.repo,e),n.teardown&&this.repo.on("teardown",n.teardown,n),this.effects.push(n),n},t.prototype.dispatch=function(t){for(var e=t.command,n=t.payload,r=t.status,o=0,i=this.effects.length;o<i;o++){var s=this.effects[o];if(s.register){var a=S(s.register(),e,r);a&&a.call(s,this.repo,n)}}},t}(),et=function(){function t(e,n,r){E(this,t),this.id=e,this.key=n,this.edges=[],this.parent=r||null,r&&r.connect(this)}return t.getId=function(t,e){return e&&e.id?e.id+"."+t:t},t.prototype.connect=function(t){t!==this&&this.edges.indexOf(t)<0&&this.edges.push(t)},t.prototype.disconnect=function(t){var e=this.edges.indexOf(t);~e&&this.edges.splice(e,1)},t.prototype.isAlone=function(){return this.edges.length<=0},t.prototype.orphan=function(){this.parent&&this.parent.disconnect(this)},t}(),nt=function(t){function e(r,o){E(this,e);var i=R(this,t.call(this));return i.id=r,i.keyPaths=n(o),i}return P(e,t),e.getId=function(t){return"query:"+o(n(t))},e.prototype.extract=function(t){for(var e=this.keyPaths.length,n=Array(e),r=0;r<e;r++)n[r]=p(t,this.keyPaths[r]);return n},e.prototype.trigger=function(t){var e=this.extract(t);this._emit.apply(this,["change"].concat(e))},e.prototype.isAlone=function(){return this._events.length<=0},e}(C),rt="",ot=function(){function t(e){E(this,t),this.snapshot=e,this.nodes={}}return t.prototype.on=function(t,e,r){for(var o=n(t),i=nt.getId(t),s=this.addQuery(i,o),a=0;a<o.length;a++)this.addBranch(o[a],s);return s.on("change",e,r),s},t.prototype.off=function(t,e,n){var r=nt.getId(t),o=this.nodes[r];o&&(o.off("change",e,n),o.isAlone()&&this.prune(o))},t.prototype.update=function(t){var e=this.snapshot;if(this.snapshot=t,this.nodes[rt])for(var n=this.scan(this.nodes[rt],e,t,[]),r=0;r<n.length;r++)n[r].trigger(t)},t.prototype.addNode=function(t,e){var n=et.getId(t,e);return this.nodes[n]||(this.nodes[n]=new et(n,t,e)),this.nodes[n]},t.prototype.addQuery=function(t,e){return this.nodes[t]||(this.nodes[t]=new nt(t,e)),this.nodes[t]},t.prototype.remove=function(t){delete this.nodes[t.id]},t.prototype.prune=function(t){for(var e=t.keyPaths.map(r),n=0,o=e.length;n<o;n++){var i=this.nodes[e[n]];i.disconnect(t);do{if(!i.isAlone())break;i.orphan(),this.remove(i),i=i.parent}while(i)}this.remove(t)},t.prototype.addBranch=function(t,e){for(var n=this.addNode(rt,null),r=0,o=t.length;r<o;r++)n=this.addNode(t[r],n);n.connect(e)},t.prototype.scan=function(t,e,n,r){if(e!==n)for(var o=t.edges,i=0,s=o.length;i<s;i++){var a=o[i];if(a instanceof nt&&r.indexOf(a)<0)r.push(a);else{var u=null==e?e:e[a.key],p=null==n?n:n[a.key];this.scan(a,u,p,r)}}return r},t}(),it={maxHistory:0,parent:null,batch:!1},st=function(t){function e(n,r,o){E(this,e);var i=R(this,t.call(this)),s=a(it,i.constructor.defaults,n);return i.parent=s.parent,i.initial=i.parent?i.parent.initial:i.getInitialState(),i.state=i.parent?i.parent.state:i.initial,i.history=i.parent?i.parent.history:new V(s),i.archive=new W,i.domains=new Z(i),i.effects=new tt(i),i.changes=new ot(i.state),i.history.on("append",i.createSnapshot,i),i.history.on("update",i.updateSnapshot,i),i.history.on("remove",i.removeSnapshot,i),i.history.on("reconcile",i.dispatchEffect,i),i.history.on("release",i.release,i),i.setup(s),r&&i.reset(r,o),i}return P(e,t),e.prototype.setup=function(){},e.prototype.teardown=function(){},e.prototype.getInitialState=function(){return null==this.initial?{}:this.initial},e.prototype.recall=function(t,e){return this.archive.get(t,e)},e.prototype.createSnapshot=function(t){this.archive.create(t)},e.prototype.updateSnapshot=function(t){var e=this.recall(t.parent,this.initial);this.parent&&(e=a(e,this.parent.recall(t))),t.disabled||(e=this.domains.dispatch(e,t)),this.archive.set(t,e),this.state=e},e.prototype.removeSnapshot=function(t){this.archive.remove(t)},e.prototype.dispatchEffect=function(t){this.effects.dispatch(t)},e.prototype.release=function(){this.changes.update(this.state)},e.prototype.on=function(t,e,n){var r=t.split(":",2),o=r[0],i=r[1];switch(o){case"change":this.changes.on(i||"",e,n);break;default:C.prototype.on.apply(this,arguments)}return this},e.prototype.off=function(t,e,n){var r=t.split(":",2),o=r[0],i=r[1];switch(o){case"change":this.changes.off(i||"",e,n);break;default:C.prototype.off.apply(this,arguments)}return this},e.prototype.append=function(t,e){return this.history.append(t,e)},e.prototype.push=function(t){for(var e=this.append(t),n=arguments.length,r=Array(n>1?n-1:0),o=1;o<n;o++)r[o-1]=arguments[o];return z(e,e.command,r,this),e},e.prototype.prepare=function(){for(var t=this,e=arguments.length,n=Array(e),r=0;r<e;r++)n[r]=arguments[r];return function(){for(var e=arguments.length,r=Array(e),o=0;o<e;o++)r[o]=arguments[o];return t.push.apply(t,n.concat(r))}},e.prototype.addDomain=function(t,e,n){var r=this.domains.add(t,e,n);return r.getInitialState&&(this.initial=c(this.initial,t,r.getInitialState())),this.push($,r),r},e.prototype.addEffect=function(t,e){return this.effects.add(t,e)},e.prototype.reset=function(t,e){return this.push(B,t,e)},e.prototype.patch=function(t,e){return this.push(G,t,e)},e.prototype.deserialize=function(t){var e=t;return this.parent?e=this.parent.deserialize(t):d(e)&&(e=JSON.parse(e)),this.domains.deserialize(e)},e.prototype.serialize=function(){var t=this.parent?this.parent.serialize():{};return this.domains.serialize(this.state,t)},e.prototype.toJSON=function(){return this.serialize()},e.prototype.checkout=function(t){return this.history.checkout(t),this},e.prototype.fork=function(){return new e({parent:this})},e.prototype.shutdown=function(){this.teardown(),this._emit("teardown",this),this.history._removeScope(this),this.removeAllListeners()},e.prototype.parallel=function(t){return this.append("GROUP").link(t)},e}(C);exports.default=st,exports.Microcosm=st,exports.Action=K,exports.History=V,exports.Emitter=C,exports.tag=b,exports.get=p,exports.set=c,exports.update=m,exports.merge=a,exports.inherit=u,exports.getRegistration=S; |
{ | ||
"name": "microcosm", | ||
"version": "12.8.0", | ||
"version": "12.9.0-alpha", | ||
"description": "Flux with actions at center stage. Write optimistic updates, cancel requests, and track changes with ease.", | ||
@@ -5,0 +5,0 @@ "main": "microcosm.js", |
{ | ||
"name": "microcosm", | ||
"version": "12.8.0", | ||
"version": "12.9.0-alpha", | ||
"description": "Flux with actions at center stage. Write optimistic updates, cancel requests, and track changes with ease.", | ||
@@ -5,0 +5,0 @@ "main": "microcosm.js", |
@@ -10,2 +10,13 @@ # [](http://code.viget.com/microcosm/) | ||
## What you get | ||
- A central place to track all application data | ||
- [Schedule work with actions](./docs/api/actions.md) | ||
- Actions understand Promises out of the box and move through predefined states. | ||
- Keep loading states out of the data layer. Track action progress using [status callbacks](./docs/api/actions.md#ondonecallback-scope). | ||
- [Split up application state in large apps](./docs/api/microcosm.md#fork) while still sharing common data | ||
- [Painless optimistic updates](./docs/recipes/ajax.md) | ||
- Track changes and handle business logic with [Presenter components](./docs/api/presenter.md) | ||
- 5kb gzipped (~15kb minified) | ||
## At a glance | ||
@@ -15,2 +26,3 @@ | ||
import Microcosm, { get, set } from 'microcosm' | ||
import axios from 'axios' | ||
@@ -20,5 +32,5 @@ let repo = new Microcosm() | ||
function getUser (id) { | ||
// This will return a promise. Microcosm automatically understands promises, | ||
// see http://code.viget.com/microcosm/api/actions.html | ||
return fetch(`/users/#{id}`).then(response => response.json()) | ||
// This will return a promise. Microcosm automatically handles promises. | ||
// See http://code.viget.com/microcosm/api/actions.html | ||
return axios(`/users/#{id}`) | ||
} | ||
@@ -37,3 +49,5 @@ | ||
return { | ||
[getUser.done]: this.addUser | ||
[getUser]: { | ||
done: this.addUser | ||
} | ||
} | ||
@@ -105,5 +119,9 @@ } | ||
```javascript | ||
// axios is an AJAX library | ||
// https://github.com/mzabriskie/axios | ||
import axios from 'axios' | ||
function getPlanet (id) { | ||
// Fetch returns a Promise, handled out of the box | ||
return fetch('/planets/' + id).then(response => response.json()) | ||
// axios returns a Promise, handled out of the box | ||
return axios(`/planets/${id}`) | ||
} | ||
@@ -110,0 +128,0 @@ |
@@ -12,2 +12,3 @@ 'use strict'; | ||
* Shallow copy an object | ||
* @private | ||
*/ | ||
@@ -18,2 +19,3 @@ | ||
* Merge any number of objects into a provided object. | ||
* @private | ||
*/ | ||
@@ -24,2 +26,3 @@ | ||
* Basic prototypal inheritence | ||
* @private | ||
*/ | ||
@@ -31,2 +34,3 @@ | ||
* object. | ||
* @private | ||
*/ | ||
@@ -38,2 +42,3 @@ | ||
* value is the same, don't do anything. Otherwise return a new object. | ||
* @private | ||
*/ | ||
@@ -46,2 +51,3 @@ | ||
* @return {boolean} | ||
* @private | ||
*/ | ||
@@ -54,2 +60,3 @@ | ||
* @return {boolean} | ||
* @private | ||
*/ | ||
@@ -62,2 +69,3 @@ | ||
* @return {boolean} | ||
* @private | ||
*/ | ||
@@ -70,2 +78,3 @@ | ||
* @return {boolean} | ||
* @private | ||
*/ | ||
@@ -78,5 +87,17 @@ function isString(target) { | ||
/** | ||
* Is the provided value a generator function? This is largely | ||
* informed by the regenerator runtime. | ||
* @param {*} value | ||
* @return {boolean} | ||
* @private | ||
*/ | ||
/** | ||
* @private | ||
*/ | ||
/** | ||
* A helper combination of get and set | ||
@@ -87,2 +108,3 @@ * @param {Object} state | ||
* @param {*} fallback value | ||
* @private | ||
*/ | ||
@@ -107,2 +129,3 @@ | ||
* @return {Array} List of keys, like ['users', 2] | ||
* @private | ||
*/ | ||
@@ -125,2 +148,3 @@ function castPath(value) { | ||
* @return {Array} List of paths, like [['users'], ['query', 'focus']] | ||
* @private | ||
*/ | ||
@@ -141,2 +165,3 @@ function getKeyPaths(value) { | ||
* @return {String} Dot separated string, like 'query.focus' | ||
* @private | ||
*/ | ||
@@ -149,2 +174,3 @@ | ||
* @return {Array} Comma key paths, like 'users,query.focus' | ||
* @private | ||
*/ | ||
@@ -159,2 +185,3 @@ | ||
* Given a query (see above), return a subset of an object. | ||
* @private | ||
*/ | ||
@@ -161,0 +188,0 @@ function extract(object, keyPaths, seed) { |
@@ -61,2 +61,152 @@ 'use strict'; | ||
/** | ||
* @fileoverview A general modelling class used by the Presenter's | ||
* getModel function. | ||
*/ | ||
function isObservable(binding) { | ||
return binding && typeof binding.subscribe === 'function'; | ||
} | ||
function isCallable(binding) { | ||
return binding && typeof binding.call === 'function'; | ||
} | ||
function invoke(binding, repo, scope) { | ||
if (isCallable(binding)) { | ||
return binding.call(scope, repo.state, repo); | ||
} | ||
return binding; | ||
} | ||
var Model = function (_Emitter) { | ||
inherits(Model, _Emitter); | ||
/** | ||
* @param {Microcosm} repo Track this Microcosm instance for updates | ||
* @param {scope} scope Scope to invoke functional bindings | ||
*/ | ||
function Model(repo, scope) { | ||
classCallCheck(this, Model); | ||
var _this = possibleConstructorReturn(this, _Emitter.call(this)); | ||
_this.repo = repo; | ||
_this.scope = scope; | ||
_this.bindings = {}; | ||
_this.subscriptions = {}; | ||
_this.value = {}; | ||
_this.repo.on('change', _this.compute, _this); | ||
return _this; | ||
} | ||
/** | ||
* Track an observable. Sending updates to a given key. | ||
* @param {string} key | ||
* @param {Observable} observable | ||
*/ | ||
Model.prototype.track = function track(key, observable) { | ||
var _this2 = this; | ||
var last = this.subscriptions[key]; | ||
var next = observable.subscribe(function (value) { | ||
return _this2.set(key, value); | ||
}); | ||
this.subscriptions[key] = next; | ||
if (last) { | ||
last.unsubscribe(); | ||
} | ||
}; | ||
/** | ||
* @param {Object} bindings A set of key/value pairs for building a model | ||
*/ | ||
Model.prototype.bind = function bind(bindings) { | ||
this.bindings = {}; | ||
for (var key in bindings) { | ||
var binding = bindings[key]; | ||
if (isObservable(binding)) { | ||
this.track(key, binding); | ||
} else { | ||
this.bindings[key] = binding; | ||
} | ||
} | ||
this.compute(); | ||
}; | ||
/** | ||
* Update a specific model key. Emits a change event | ||
* @param {string} key | ||
* @param {*} value | ||
*/ | ||
Model.prototype.set = function set$$1(key, value) { | ||
var next = Microcosm.set(this.value, key, value); | ||
if (this.value !== next) { | ||
this.value = next; | ||
this._emit('change', this.value); | ||
} | ||
}; | ||
/** | ||
* Run through each invokable binding, recomputing the model | ||
* for their associated keys. | ||
*/ | ||
Model.prototype.compute = function compute() { | ||
var last = this.value; | ||
var next = last; | ||
for (var key in this.bindings) { | ||
var value = invoke(this.bindings[key], this.repo, this.scope); | ||
next = Microcosm.set(next, key, value); | ||
} | ||
if (last !== next) { | ||
this.value = next; | ||
this._emit('change', next); | ||
} | ||
}; | ||
/** | ||
* Dispose a model, removing all subscriptions and unsubscribing | ||
* from the repo. | ||
*/ | ||
Model.prototype.teardown = function teardown() { | ||
for (var key in this.subscriptions) { | ||
this.subscriptions[key].unsubscribe(); | ||
} | ||
this.repo.off('change', this.compute, this); | ||
}; | ||
return Model; | ||
}(Microcosm.Emitter); | ||
/** | ||
* @fileoverview Presenter is a specialized React component that | ||
* creates a boundary between "smart" and "dumb" components. This | ||
* improves testing and keeps business logic in a consistent place | ||
* (instead of spread across bunches of components). | ||
* | ||
* Use Presenters to track changes to a Microcosm, push actions, and | ||
* manage application flow. | ||
*/ | ||
function passChildren() { | ||
@@ -69,14 +219,4 @@ return this.props.children ? React.Children.only(this.props.children) : null; | ||
/** | ||
* @fileoverview The Presenter add-on makes it easier to keep | ||
* application logic high within a component tree. It subscribes to | ||
* state changes via a `getModel` method, designed specifically to | ||
* extract and compute properties coming from a Microcosm | ||
* instance. When state changes, model keys are efficiently sent down | ||
* as props to child “passive view” React components. | ||
* | ||
* Presenters also make it easy for components deep within a component | ||
* tree to communicate without passing a long chain of props. The | ||
* `withSend` and `<Form />` may be used to broadcast messages called | ||
* "actions" to parent Presenter components, or straight to a Microcosm | ||
* repo itself if no Presenter intercepts the message. | ||
* @class | ||
* @extends React.PureComponent | ||
*/ | ||
@@ -110,3 +250,3 @@ | ||
this.model = this._prepareModel(); | ||
this.model = this.mediator.updateModel(this.props, this.state); | ||
@@ -129,9 +269,2 @@ this.ready(this.repo, this.props, this.state); | ||
Presenter.prototype._prepareModel = function _prepareModel() { | ||
var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props; | ||
var state = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.state; | ||
return this.mediator.updateModel(props, state); | ||
}; | ||
/** | ||
@@ -169,8 +302,8 @@ * Called when a presenter is created, useful any prep work. `setup` | ||
* @param {Microcosm} repo | ||
* @param {Object} props | ||
* @param {Object} state | ||
* @param {Object} nextProps | ||
* @param {Object} nextState | ||
*/ | ||
; | ||
Presenter.prototype.update = function update(repo, props, state) {} | ||
Presenter.prototype.update = function update(repo, nextProps, nextState) {} | ||
// NOOP | ||
@@ -205,3 +338,3 @@ | ||
Presenter.prototype.componentWillUpdate = function componentWillUpdate(props, state) { | ||
this.model = this._prepareModel(props, state); | ||
this.model = this.mediator.updateModel(props, state); | ||
this.update(this.repo, props, state); | ||
@@ -282,3 +415,8 @@ }; | ||
_this2.send = _this2.send.bind(_this2); | ||
_this2.state = { repo: _this2.repo, send: _this2.send }; | ||
_this2.model = new Model(_this2.repo, _this2.presenter); | ||
_this2.model.on('change', _this2.setState, _this2); | ||
return _this2; | ||
@@ -295,6 +433,2 @@ } | ||
PresenterMediator.prototype.componentWillMount = function componentWillMount() { | ||
if (this.presenter.getModel !== Presenter.prototype.getModel) { | ||
this.repo.on('change', this.setModel, this); | ||
} | ||
this.presenter._beginSetup(this); | ||
@@ -310,4 +444,2 @@ }; | ||
this.repo.off('change', this.setModel, this); | ||
if (this.presenter.didFork) { | ||
@@ -317,2 +449,4 @@ this.repo.shutdown(); | ||
this.model.teardown(); | ||
this.presenter._beginTeardown(); | ||
@@ -337,42 +471,9 @@ }; | ||
PresenterMediator.prototype.updateModel = function updateModel(props, state) { | ||
var model = this.presenter.getModel(props, state); | ||
var data = this.repo.state; | ||
var next = {}; | ||
var bindings = this.presenter.getModel(props, state); | ||
this.propMap = {}; | ||
this.model.bind(bindings); | ||
for (var key in model) { | ||
var entry = model[key]; | ||
if (entry && typeof entry.call === 'function') { | ||
this.propMap[key] = entry; | ||
next[key] = entry.call(this.presenter, data, this.repo); | ||
} else { | ||
next[key] = entry; | ||
} | ||
} | ||
this.setState(next); | ||
return Microcosm.merge(this.state, next); | ||
return this.model.value; | ||
}; | ||
PresenterMediator.prototype.setModel = function setModel(state) { | ||
var last = this.state; | ||
var next = null; | ||
for (var key in this.propMap) { | ||
var value = this.propMap[key].call(this.presenter, state, this.repo); | ||
if (last[key] !== value) { | ||
next = next || {}; | ||
next[key] = value; | ||
} | ||
} | ||
if (next !== null) { | ||
this.setState(next); | ||
} | ||
}; | ||
PresenterMediator.prototype.hasParent = function hasParent() { | ||
@@ -379,0 +480,0 @@ // Do not allow transfer across repos. Check to for inheritence by comparing |
{ | ||
"name": "microcosm", | ||
"version": "12.8.0", | ||
"version": "12.9.0-alpha", | ||
"description": "Flux with actions at center stage. Write optimistic updates, cancel requests, and track changes with ease.", | ||
@@ -5,0 +5,0 @@ "main": "microcosm.js", |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
406490
58
6344
426
8