Comparing version 0.0.6 to 0.0.7
@@ -443,3 +443,166 @@ 'use strict'; | ||
}); | ||
describe('and we use the wait helper', function () { | ||
it('should wait till the other action is dispatched', function (done) { | ||
var handler = /*#__PURE__*/regeneratorRuntime.mark(function handler() { | ||
var _ref, a, b, answer; | ||
return regeneratorRuntime.wrap(function handler$(_context9) { | ||
while (1) { | ||
switch (_context9.prev = _context9.next) { | ||
case 0: | ||
_context9.next = 2; | ||
return (0, _helpers.wait)(['push the machine', 'pull the machine']); | ||
case 2: | ||
_ref = _context9.sent; | ||
a = _ref[0]; | ||
b = _ref[1]; | ||
_context9.next = 7; | ||
return (0, _helpers.wait)('stop the machine'); | ||
case 7: | ||
answer = _context9.sent; | ||
return _context9.abrupt('return', 'the answer is ' + answer + ': ' + a + ' + ' + b); | ||
case 9: | ||
case 'end': | ||
return _context9.stop(); | ||
} | ||
} | ||
}, handler, this); | ||
}); | ||
var machine = { | ||
state: { name: 'idle' }, | ||
transitions: { | ||
idle: { | ||
run: handler, | ||
'stop the machine': function stopTheMachine() {}, | ||
'push the machine': function pushTheMachine() {}, | ||
'pull the machine': function pullTheMachine() {} | ||
}, | ||
'the answer is 42: 20 + 22': { a: 'b' } | ||
} | ||
}; | ||
(0, _handleAction2.default)(machine, 'run'); | ||
(0, _handleAction2.default)(machine, 'pull the machine', 22); | ||
setTimeout(function () { | ||
return (0, _handleAction2.default)(machine, 'push the machine', 20); | ||
}, 5); | ||
setTimeout(function () { | ||
return (0, _handleAction2.default)(machine, 'stop the machine', 42); | ||
}, 10); | ||
setTimeout(function () { | ||
expect(machine[_constants.WAIT_LISTENERS_STORAGE]).to.be.undefined; | ||
expect(machine.state).to.deep.equal({ name: 'the answer is 42: 20 + 22' }); | ||
done(); | ||
}, 100); | ||
}); | ||
}); | ||
}); | ||
describe('when we have middlewares registered', function () { | ||
it('should fire the middleware/s if an action is dispatched', function (done) { | ||
var _machine; | ||
var machine = (_machine = { | ||
state: { name: 'idle' }, | ||
transitions: { | ||
idle: { run: 'running' }, | ||
running: { stop: 'idle' } | ||
} | ||
}, _machine[_constants.MIDDLEWARE_STORAGE] = [{ | ||
onActionDispatched: function onActionDispatched(next, actionName) { | ||
expect(actionName).to.equal('run'); | ||
for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { | ||
args[_key - 2] = arguments[_key]; | ||
} | ||
expect(args).to.deep.equal([{ answer: 42 }]); | ||
next(); | ||
expect(machine.state).to.deep.equal({ name: 'running' }); | ||
} | ||
}, { | ||
onActionDispatched: function onActionDispatched(next, actionName) { | ||
expect(actionName).to.equal('run'); | ||
for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { | ||
args[_key2 - 2] = arguments[_key2]; | ||
} | ||
expect(args).to.deep.equal([{ answer: 42 }]); | ||
next(); | ||
expect(machine.state).to.deep.equal({ name: 'running' }); | ||
done(); | ||
} | ||
}], _machine); | ||
(0, _handleAction2.default)(machine, 'run', { answer: 42 }); | ||
}); | ||
it('should skip to the next middleware if there is no appropriate hook defined', function (done) { | ||
var _machine2; | ||
var machine = (_machine2 = { | ||
state: { name: 'idle' }, | ||
transitions: { | ||
idle: { run: 'running' }, | ||
running: { stop: 'idle' } | ||
} | ||
}, _machine2[_constants.MIDDLEWARE_STORAGE] = [{ | ||
onStateChange: function onStateChange(next) { | ||
next(); | ||
} | ||
}, { | ||
onActionDispatched: function onActionDispatched(next, actionName) { | ||
next(); | ||
expect(this.state).to.deep.equal({ name: 'running' }); | ||
done(); | ||
} | ||
}], _machine2); | ||
(0, _handleAction2.default)(machine, 'run', { answer: 42 }); | ||
}); | ||
it('should fire the middleware/s when the state is changed', function (done) { | ||
var _machine3; | ||
var machine = (_machine3 = { | ||
state: { name: 'idle' }, | ||
transitions: { | ||
idle: { run: 'running' }, | ||
running: { stop: 'idle' } | ||
} | ||
}, _machine3[_constants.MIDDLEWARE_STORAGE] = [{ | ||
onStateChange: function onStateChange(next) { | ||
expect(this.state).to.deep.equal({ name: 'idle' }); | ||
next(); | ||
expect(this.state).to.deep.equal({ name: 'running' }); | ||
} | ||
}, { | ||
onStateChange: function onStateChange(next) { | ||
done(); | ||
} | ||
}], _machine3); | ||
(0, _handleAction2.default)(machine, 'run', { answer: 42 }); | ||
}); | ||
}); | ||
describe('when we have have an empty array as middlewares', function () { | ||
it('should NOT try to run a middleware', function () { | ||
var _machine4; | ||
var machine = (_machine4 = { | ||
state: { name: 'idle' }, | ||
transitions: { | ||
idle: { run: 'running' }, | ||
running: { stop: 'idle' } | ||
} | ||
}, _machine4[_constants.MIDDLEWARE_STORAGE] = [], _machine4); | ||
(0, _handleAction2.default)(machine, 'run', { answer: 42 }); | ||
expect(machine.state.name).to.equal('running'); | ||
}); | ||
}); | ||
}); |
@@ -36,2 +36,18 @@ 'use strict'; | ||
}); | ||
describe('when adding middlewares', function () { | ||
it('should send the middlewares to every new machine', function () { | ||
var middlewareA = {}; | ||
var middlewareB = {}; | ||
_.Machine.addMiddleware(middlewareA); | ||
_.Machine.addMiddleware(middlewareB); | ||
var machine = _.Machine.create('app', { | ||
state: { idle: { run: 'running' } }, | ||
transitions: {} | ||
}); | ||
expect(machine[_constants.MIDDLEWARE_STORAGE]).to.deep.equal([middlewareA, middlewareB]); | ||
}); | ||
}); | ||
}); |
@@ -23,2 +23,6 @@ 'use strict'; | ||
return 'You just transitioned the machine to a state (' + state + ') which is not defined or it has no actions. This means that the machine is stuck.'; | ||
}; | ||
}; | ||
// other | ||
var WAIT_LISTENERS_STORAGE = exports.WAIT_LISTENERS_STORAGE = '___@wait'; | ||
var MIDDLEWARE_STORAGE = exports.MIDDLEWARE_STORAGE = '___@middlewares'; |
@@ -51,4 +51,8 @@ 'use strict'; | ||
function createMachine(name, config) { | ||
var machine = { name: name }; | ||
function createMachine(name, config, middlewares) { | ||
var _machine; | ||
var machine = (_machine = { | ||
name: name | ||
}, _machine[_constants.MIDDLEWARE_STORAGE] = middlewares, _machine); | ||
var initialState = config.state, | ||
@@ -59,2 +63,3 @@ transitions = config.transitions; | ||
machine.state = initialState; | ||
machine.transitions = transitions; | ||
@@ -61,0 +66,0 @@ if (validateConfig(config)) { |
@@ -19,2 +19,5 @@ 'use strict'; | ||
var MIDDLEWARE_PROCESS_ACTION = 'onActionDispatched'; | ||
var MIDDLEWARE_PROCESS_STATE_CHANGE = 'onStateChange'; | ||
function isEmptyObject(obj) { | ||
@@ -40,4 +43,4 @@ var name; | ||
if (typeof funcResult.then !== 'undefined') { | ||
funcResult.then(function (r) { | ||
return iterate(generator.next(r)); | ||
funcResult.then(function (result) { | ||
return iterate(generator.next(result)); | ||
}, function (error) { | ||
@@ -55,2 +58,8 @@ return iterate(generator.throw(new Error(error))); | ||
// yield wait | ||
} else if (_typeof(result.value) === 'object' && result.value.__type === 'wait') { | ||
waitFor(machine, result.value.actions, function (result) { | ||
return iterate(generator.next(result)); | ||
}); | ||
// the return statement of the normal function | ||
@@ -71,2 +80,41 @@ } else { | ||
function waitFor(machine, actions, done) { | ||
if (!machine[_constants.WAIT_LISTENERS_STORAGE]) machine[_constants.WAIT_LISTENERS_STORAGE] = []; | ||
machine[_constants.WAIT_LISTENERS_STORAGE].push({ actions: actions, done: done, result: [].concat(actions) }); | ||
} | ||
function flushListeners(machine, action, payload) { | ||
if (!machine[_constants.WAIT_LISTENERS_STORAGE] || machine[_constants.WAIT_LISTENERS_STORAGE].length === 0) return; | ||
// We register the `done` functions that should be called | ||
// because this should happen at the very end of the | ||
// listeners processing. | ||
var callbacks = []; | ||
machine[_constants.WAIT_LISTENERS_STORAGE] = machine[_constants.WAIT_LISTENERS_STORAGE].filter(function (_ref) { | ||
var actions = _ref.actions, | ||
done = _ref.done, | ||
result = _ref.result; | ||
var actionIndex = actions.indexOf(action); | ||
if (actionIndex === -1) return true; | ||
result[result.indexOf(action)] = payload; | ||
actions.splice(actionIndex, 1); | ||
if (actions.length === 0) { | ||
result.length === 1 ? callbacks.push(done.bind(null, result[0])) : callbacks.push(done.bind(null, result)); | ||
return false; | ||
} | ||
return true; | ||
}); | ||
callbacks.forEach(function (c) { | ||
return c(); | ||
}); | ||
// Clean up. There is no need to keep that temporary array | ||
// if all the listeners are flushed. | ||
if (machine[_constants.WAIT_LISTENERS_STORAGE].length === 0) delete machine[_constants.WAIT_LISTENERS_STORAGE]; | ||
} | ||
function updateState(machine, response) { | ||
@@ -86,5 +134,32 @@ var newState; | ||
machine.state = newState; | ||
handleMiddleware(function () { | ||
machine.state = newState; | ||
}, MIDDLEWARE_PROCESS_STATE_CHANGE, machine); | ||
} | ||
function handleMiddleware(done, hook, machine) { | ||
for (var _len = arguments.length, args = Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) { | ||
args[_key - 3] = arguments[_key]; | ||
} | ||
if (!machine[_constants.MIDDLEWARE_STORAGE]) return done(); | ||
var middlewares = machine[_constants.MIDDLEWARE_STORAGE]; | ||
var loop = function loop(index, process) { | ||
return index < middlewares.length - 1 ? process(index + 1) : done(); | ||
}; | ||
(function process(index) { | ||
var middleware = middlewares[index]; | ||
if (middleware && typeof middleware[hook] !== 'undefined') { | ||
middleware[hook].apply(machine, [function () { | ||
return loop(index, process); | ||
}].concat(args)); | ||
} else { | ||
loop(index, process); | ||
} | ||
})(0); | ||
} | ||
function handleAction(machine, action, payload) { | ||
@@ -105,22 +180,26 @@ var state = machine.state, | ||
// string as a handler | ||
if (typeof handler === 'string') { | ||
updateState(machine, _extends({}, state, { name: transitions[state.name][action] })); | ||
handleMiddleware(function () { | ||
flushListeners(machine, action, payload); | ||
// object as a handler | ||
} else if ((typeof handler === 'undefined' ? 'undefined' : _typeof(handler)) === 'object') { | ||
updateState(machine, (0, _validateState2.default)(handler)); | ||
// string as a handler | ||
if (typeof handler === 'string') { | ||
updateState(machine, _extends({}, state, { name: transitions[state.name][action] })); | ||
// function as a handler | ||
} else if (typeof handler === 'function') { | ||
var response = transitions[state.name][action].apply(machine, [machine.state, payload]); | ||
// object as a handler | ||
} else if ((typeof handler === 'undefined' ? 'undefined' : _typeof(handler)) === 'object') { | ||
updateState(machine, (0, _validateState2.default)(handler)); | ||
if (response && typeof response.next === 'function') { | ||
handleGenerator(machine, response, function (response) { | ||
// function as a handler | ||
} else if (typeof handler === 'function') { | ||
var response = transitions[state.name][action].apply(machine, [machine.state, payload]); | ||
if (response && typeof response.next === 'function') { | ||
handleGenerator(machine, response, function (response) { | ||
updateState(machine, response); | ||
}); | ||
} else { | ||
updateState(machine, response); | ||
}); | ||
} else { | ||
updateState(machine, response); | ||
} | ||
} | ||
} | ||
}, MIDDLEWARE_PROCESS_ACTION, machine, action, payload); | ||
@@ -127,0 +206,0 @@ return true; |
'use strict'; | ||
exports.__esModule = true; | ||
exports.call = undefined; | ||
exports.wait = exports.call = undefined; | ||
@@ -10,4 +10,9 @@ var _call = require('./generators/call'); | ||
var _wait = require('./generators/wait'); | ||
var _wait2 = _interopRequireDefault(_wait); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
exports.call = _call2.default; | ||
exports.call = _call2.default; | ||
exports.wait = _wait2.default; |
@@ -21,6 +21,7 @@ 'use strict'; | ||
this.machines = {}; | ||
this.middlewares = []; | ||
} | ||
MachineFactory.prototype.create = function create(name, config) { | ||
return this.machines[name] = (0, _createMachine2.default)(name, config); | ||
return this.machines[name] = (0, _createMachine2.default)(name, config, this.middlewares); | ||
}; | ||
@@ -35,4 +36,9 @@ | ||
this.machines = []; | ||
this.middlewares = []; | ||
}; | ||
MachineFactory.prototype.addMiddleware = function addMiddleware(middleware) { | ||
this.middlewares.push(middleware); | ||
}; | ||
return MachineFactory; | ||
@@ -39,0 +45,0 @@ }(); |
{ | ||
"name": "stent", | ||
"version": "0.0.6", | ||
"version": "0.0.7", | ||
"description": "Stent is a state machines container made for UI development", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -281,6 +281,16 @@ # Stent | ||
.map((MachineA, MachineB) => { | ||
... | ||
// called multiple times | ||
}); | ||
``` | ||
The mapping function by default is called once and then every time when the state of the connected machines changes. So, if you need only that first call use `mapOnce` instead. | ||
```js | ||
connect() | ||
.with('MachineA', 'MachineB') | ||
.mapOnce((MachineA, MachineB) => { | ||
// this gets called only once | ||
}); | ||
``` | ||
There's also a helper for integration with React. It creates a [HOC](https://github.com/krasimir/react-in-patterns/tree/master/patterns/higher-order-components): | ||
@@ -345,4 +355,8 @@ | ||
'fetch data': function * () { | ||
yield wait('init'); | ||
yield wait(['user profile fetched', 'data processed']); | ||
const initActionPayload = yield wait('init'); | ||
const [ userProfilePayload, dataPayload ] = yield wait([ | ||
'user profile fetched', | ||
'data processed' | ||
]); | ||
... | ||
} | ||
@@ -363,19 +377,9 @@ } | ||
console.log(`Action dispatched: ${ actionName }`); | ||
next(...args); | ||
next(); | ||
console.log(`After ${ actionName } action our state is ${ this.state.name }`); | ||
}, | ||
onStateChanged(next, newState) { | ||
console.log(`The new state will be: ${ newState.name }`); | ||
next(newState); | ||
console.log(`The state now is: ${ newState.name }`); | ||
}, | ||
onConnect(next, machineNames) { | ||
console.log(`Someone wants to connect to ${ machineNames } `); // array of strings | ||
next(machines); | ||
console.log(`Someone gets connected to ${ machineNames} `) | ||
}, | ||
onGet(next, machineName) { | ||
console.log(`Someone wants the ${ machineName } machine`); | ||
next(machineName); | ||
console.log(`Someone just gets access to ${ machineName } machine`); | ||
onStateChanged(next) { | ||
console.log(`The new state will be: ${ this.state.name }`); | ||
next(); | ||
console.log(`The state now is: ${ this.state.name }`); | ||
} | ||
@@ -382,0 +386,0 @@ }); |
import handleAction from '../handleAction'; | ||
import { ERROR_MISSING_ACTION_IN_STATE, ERROR_UNCOVERED_STATE } from '../constants'; | ||
import { call } from '../helpers'; | ||
import { | ||
ERROR_MISSING_ACTION_IN_STATE, | ||
ERROR_UNCOVERED_STATE, | ||
WAIT_LISTENERS_STORAGE, | ||
MIDDLEWARE_STORAGE | ||
} from '../constants'; | ||
import { call, wait } from '../helpers'; | ||
@@ -301,4 +306,134 @@ describe('Given the handleAction function', function () { | ||
}); | ||
describe('and we use the wait helper', function () { | ||
it('should wait till the other action is dispatched', function (done) { | ||
const handler = function * () { | ||
const [ a, b ] = yield wait(['push the machine', 'pull the machine']); | ||
const answer = yield wait('stop the machine'); | ||
return `the answer is ${ answer }: ${ a } + ${ b }`; | ||
} | ||
const machine = { | ||
state: { name: 'idle' }, | ||
transitions: { | ||
idle: { | ||
run: handler, | ||
'stop the machine': () => {}, | ||
'push the machine': () => {}, | ||
'pull the machine': () => {}, | ||
}, | ||
'the answer is 42: 20 + 22': { a: 'b' } | ||
} | ||
}; | ||
handleAction(machine, 'run'); | ||
handleAction(machine, 'pull the machine', 22); | ||
setTimeout(() => handleAction(machine, 'push the machine', 20), 5); | ||
setTimeout(() => handleAction(machine, 'stop the machine', 42), 10); | ||
setTimeout(() => { | ||
expect(machine[WAIT_LISTENERS_STORAGE]).to.be.undefined; | ||
expect(machine.state).to.deep.equal({ name: 'the answer is 42: 20 + 22' }); | ||
done(); | ||
}, 100); | ||
}); | ||
}); | ||
}); | ||
describe('when we have middlewares registered', function () { | ||
it('should fire the middleware/s if an action is dispatched', function (done) { | ||
const machine = { | ||
state: { name: 'idle' }, | ||
transitions: { | ||
idle: { run: 'running' }, | ||
running: { stop: 'idle' } | ||
}, | ||
[MIDDLEWARE_STORAGE]: [ | ||
{ | ||
onActionDispatched(next, actionName, ...args) { | ||
expect(actionName).to.equal('run'); | ||
expect(args).to.deep.equal([ { answer: 42 } ]); | ||
next(); | ||
expect(machine.state).to.deep.equal({ name: 'running' }); | ||
} | ||
}, | ||
{ | ||
onActionDispatched(next, actionName, ...args) { | ||
expect(actionName).to.equal('run'); | ||
expect(args).to.deep.equal([ { answer: 42 } ]); | ||
next(); | ||
expect(machine.state).to.deep.equal({ name: 'running' }); | ||
done(); | ||
} | ||
} | ||
] | ||
}; | ||
handleAction(machine, 'run', { answer: 42 }); | ||
}); | ||
it('should skip to the next middleware if there is no appropriate hook defined', function (done) { | ||
const machine = { | ||
state: { name: 'idle' }, | ||
transitions: { | ||
idle: { run: 'running' }, | ||
running: { stop: 'idle' } | ||
}, | ||
[MIDDLEWARE_STORAGE]: [ | ||
{ | ||
onStateChange(next) { next(); } | ||
}, | ||
{ | ||
onActionDispatched(next, actionName, ...args) { | ||
next(); | ||
expect(this.state).to.deep.equal({ name: 'running' }); | ||
done(); | ||
} | ||
} | ||
] | ||
}; | ||
handleAction(machine, 'run', { answer: 42 }); | ||
}); | ||
it('should fire the middleware/s when the state is changed', function (done) { | ||
const machine = { | ||
state: { name: 'idle' }, | ||
transitions: { | ||
idle: { run: 'running' }, | ||
running: { stop: 'idle' } | ||
}, | ||
[MIDDLEWARE_STORAGE]: [ | ||
{ | ||
onStateChange(next) { | ||
expect(this.state).to.deep.equal({ name: 'idle' }); | ||
next(); | ||
expect(this.state).to.deep.equal({ name: 'running' }); | ||
} | ||
}, | ||
{ | ||
onStateChange(next) { | ||
done(); | ||
} | ||
} | ||
] | ||
}; | ||
handleAction(machine, 'run', { answer: 42 }); | ||
}); | ||
}); | ||
describe('when we have have an empty array as middlewares', function () { | ||
it('should NOT try to run a middleware', function () { | ||
const machine = { | ||
state: { name: 'idle' }, | ||
transitions: { | ||
idle: { run: 'running' }, | ||
running: { stop: 'idle' } | ||
}, | ||
[MIDDLEWARE_STORAGE]: [] | ||
}; | ||
handleAction(machine, 'run', { answer: 42 }); | ||
expect(machine.state.name).to.equal('running'); | ||
}); | ||
}); | ||
}); |
import { Machine } from '../'; | ||
import { ERROR_MISSING_MACHINE } from '../constants'; | ||
import { ERROR_MISSING_MACHINE, MIDDLEWARE_STORAGE } from '../constants'; | ||
@@ -30,2 +30,20 @@ const create = (name = 'app') => Machine.create(name, { | ||
}); | ||
describe('when adding middlewares', function () { | ||
it('should send the middlewares to every new machine', function () { | ||
const middlewareA = {}; | ||
const middlewareB = {}; | ||
Machine.addMiddleware(middlewareA); | ||
Machine.addMiddleware(middlewareB); | ||
const machine = Machine.create('app', { | ||
state: { idle: { run: 'running' } }, | ||
transitions: {} | ||
}); | ||
expect(machine[MIDDLEWARE_STORAGE]).to.deep.equal([ | ||
middlewareA, middlewareB | ||
]); | ||
}); | ||
}); | ||
}); |
@@ -11,2 +11,6 @@ // errors | ||
} | ||
export const ERROR_UNCOVERED_STATE = state => `You just transitioned the machine to a state (${ state }) which is not defined or it has no actions. This means that the machine is stuck.`; | ||
export const ERROR_UNCOVERED_STATE = state => `You just transitioned the machine to a state (${ state }) which is not defined or it has no actions. This means that the machine is stuck.`; | ||
// other | ||
export const WAIT_LISTENERS_STORAGE = '___@wait'; | ||
export const MIDDLEWARE_STORAGE = '___@middlewares'; |
import toCamelCase from './helpers/toCamelCase'; | ||
import { ERROR_MISSING_STATE, ERROR_MISSING_TRANSITIONS } from './constants'; | ||
import { | ||
ERROR_MISSING_STATE, | ||
ERROR_MISSING_TRANSITIONS, | ||
MIDDLEWARE_STORAGE | ||
} from './constants'; | ||
import handleAction from './handleAction'; | ||
@@ -29,7 +33,11 @@ | ||
export default function createMachine(name, config) { | ||
const machine = { name }; | ||
export default function createMachine(name, config, middlewares) { | ||
const machine = { | ||
name, | ||
[MIDDLEWARE_STORAGE]: middlewares | ||
}; | ||
const { state: initialState, transitions } = config; | ||
machine.state = initialState; | ||
machine.transitions = transitions; | ||
@@ -36,0 +44,0 @@ if (validateConfig(config)) { |
@@ -1,4 +0,13 @@ | ||
import { ERROR_MISSING_ACTION_IN_STATE, ERROR_UNCOVERED_STATE } from './constants'; | ||
import { | ||
ERROR_MISSING_ACTION_IN_STATE, | ||
ERROR_UNCOVERED_STATE, | ||
WAIT_LISTENERS_STORAGE, | ||
MIDDLEWARE_STORAGE, | ||
TRANSITIONS_STORAGE | ||
} from './constants'; | ||
import validateState from './helpers/validateState'; | ||
const MIDDLEWARE_PROCESS_ACTION = 'onActionDispatched'; | ||
const MIDDLEWARE_PROCESS_STATE_CHANGE = 'onStateChange'; | ||
function isEmptyObject(obj) { | ||
@@ -23,3 +32,3 @@ var name; | ||
funcResult.then( | ||
r => iterate(generator.next(r)), | ||
result => iterate(generator.next(result)), | ||
error => iterate(generator.throw(new Error(error))) | ||
@@ -35,3 +44,7 @@ ); | ||
} | ||
// yield wait | ||
} else if (typeof result.value === 'object' && result.value.__type === 'wait') { | ||
waitFor(machine, result.value.actions, result => iterate(generator.next(result))); | ||
// the return statement of the normal function | ||
@@ -52,2 +65,38 @@ } else { | ||
function waitFor(machine, actions, done) { | ||
if (!machine[WAIT_LISTENERS_STORAGE]) machine[WAIT_LISTENERS_STORAGE] = []; | ||
machine[WAIT_LISTENERS_STORAGE].push({ actions, done, result: [...actions] }); | ||
} | ||
function flushListeners(machine, action, payload) { | ||
if (!machine[WAIT_LISTENERS_STORAGE] || machine[WAIT_LISTENERS_STORAGE].length === 0) return; | ||
// We register the `done` functions that should be called | ||
// because this should happen at the very end of the | ||
// listeners processing. | ||
const callbacks = []; | ||
machine[WAIT_LISTENERS_STORAGE] = | ||
machine[WAIT_LISTENERS_STORAGE].filter(({ actions, done, result }) => { | ||
const actionIndex = actions.indexOf(action); | ||
if (actionIndex === -1) return true; | ||
result[result.indexOf(action)] = payload; | ||
actions.splice(actionIndex, 1); | ||
if (actions.length === 0) { | ||
result.length === 1 ? | ||
callbacks.push(done.bind(null, result[0])) : | ||
callbacks.push(done.bind(null, result)); | ||
return false; | ||
} | ||
return true; | ||
}); | ||
callbacks.forEach(c => c()); | ||
// Clean up. There is no need to keep that temporary array | ||
// if all the listeners are flushed. | ||
if (machine[WAIT_LISTENERS_STORAGE].length === 0) delete machine[WAIT_LISTENERS_STORAGE]; | ||
} | ||
function updateState(machine, response) { | ||
@@ -70,5 +119,24 @@ var newState; | ||
machine.state = newState; | ||
handleMiddleware(() => { | ||
machine.state = newState; | ||
}, MIDDLEWARE_PROCESS_STATE_CHANGE, machine); | ||
} | ||
function handleMiddleware(done, hook, machine, ...args) { | ||
if (!machine[MIDDLEWARE_STORAGE]) return done(); | ||
const middlewares = machine[MIDDLEWARE_STORAGE]; | ||
const loop = (index, process) => index < middlewares.length - 1 ? process(index + 1) : done(); | ||
(function process(index) { | ||
const middleware = middlewares[index]; | ||
if (middleware && typeof middleware[hook] !== 'undefined') { | ||
middleware[hook].apply(machine, [ () => loop(index, process), ...args ]); | ||
} else { | ||
loop(index, process); | ||
} | ||
})(0); | ||
} | ||
export default function handleAction(machine, action, payload) { | ||
@@ -87,24 +155,28 @@ const { state, transitions } = machine; | ||
// string as a handler | ||
if (typeof handler === 'string') { | ||
updateState(machine, { ...state, name: transitions[state.name][action] }); | ||
// object as a handler | ||
} else if (typeof handler === 'object') { | ||
updateState(machine, validateState(handler)); | ||
// function as a handler | ||
} else if (typeof handler === 'function') { | ||
var response = transitions[state.name][action].apply(machine, [ machine.state, payload ]); | ||
if (response && typeof response.next === 'function') { | ||
handleGenerator(machine, response, response => { | ||
handleMiddleware(() => { | ||
flushListeners(machine, action, payload); | ||
// string as a handler | ||
if (typeof handler === 'string') { | ||
updateState(machine, { ...state, name: transitions[state.name][action] }); | ||
// object as a handler | ||
} else if (typeof handler === 'object') { | ||
updateState(machine, validateState(handler)); | ||
// function as a handler | ||
} else if (typeof handler === 'function') { | ||
var response = transitions[state.name][action].apply(machine, [ machine.state, payload ]); | ||
if (response && typeof response.next === 'function') { | ||
handleGenerator(machine, response, response => { | ||
updateState(machine, response); | ||
}); | ||
} else { | ||
updateState(machine, response); | ||
}); | ||
} else { | ||
updateState(machine, response); | ||
} | ||
} | ||
} | ||
}, MIDDLEWARE_PROCESS_ACTION, machine, action, payload); | ||
return true; | ||
}; |
import call from './generators/call'; | ||
import wait from './generators/wait'; | ||
export { call }; | ||
export { call, wait }; |
@@ -7,5 +7,6 @@ import createMachine from './createMachine'; | ||
this.machines = {}; | ||
this.middlewares = []; | ||
} | ||
create(name, config) { | ||
return this.machines[name] = createMachine(name, config); | ||
return this.machines[name] = createMachine(name, config, this.middlewares); | ||
} | ||
@@ -18,3 +19,7 @@ get(name) { | ||
this.machines = []; | ||
this.middlewares = []; | ||
} | ||
addMiddleware(middleware) { | ||
this.middlewares.push(middleware); | ||
} | ||
} | ||
@@ -21,0 +26,0 @@ |
@@ -25,2 +25,6 @@ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.stent = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | ||
}; | ||
// other | ||
var WAIT_LISTENERS_STORAGE = exports.WAIT_LISTENERS_STORAGE = '___@wait'; | ||
var MIDDLEWARE_STORAGE = exports.MIDDLEWARE_STORAGE = '___@middlewares'; | ||
},{}],2:[function(require,module,exports){ | ||
@@ -77,4 +81,8 @@ 'use strict'; | ||
function createMachine(name, config) { | ||
var machine = { name: name }; | ||
function createMachine(name, config, middlewares) { | ||
var _machine; | ||
var machine = (_machine = { | ||
name: name | ||
}, _machine[_constants.MIDDLEWARE_STORAGE] = middlewares, _machine); | ||
var initialState = config.state, | ||
@@ -85,2 +93,3 @@ transitions = config.transitions; | ||
machine.state = initialState; | ||
machine.transitions = transitions; | ||
@@ -114,2 +123,5 @@ if (validateConfig(config)) { | ||
var MIDDLEWARE_PROCESS_ACTION = 'onActionDispatched'; | ||
var MIDDLEWARE_PROCESS_STATE_CHANGE = 'onStateChange'; | ||
function isEmptyObject(obj) { | ||
@@ -135,4 +147,4 @@ var name; | ||
if (typeof funcResult.then !== 'undefined') { | ||
funcResult.then(function (r) { | ||
return iterate(generator.next(r)); | ||
funcResult.then(function (result) { | ||
return iterate(generator.next(result)); | ||
}, function (error) { | ||
@@ -150,2 +162,8 @@ return iterate(generator.throw(new Error(error))); | ||
// yield wait | ||
} else if (_typeof(result.value) === 'object' && result.value.__type === 'wait') { | ||
waitFor(machine, result.value.actions, function (result) { | ||
return iterate(generator.next(result)); | ||
}); | ||
// the return statement of the normal function | ||
@@ -166,2 +184,41 @@ } else { | ||
function waitFor(machine, actions, done) { | ||
if (!machine[_constants.WAIT_LISTENERS_STORAGE]) machine[_constants.WAIT_LISTENERS_STORAGE] = []; | ||
machine[_constants.WAIT_LISTENERS_STORAGE].push({ actions: actions, done: done, result: [].concat(actions) }); | ||
} | ||
function flushListeners(machine, action, payload) { | ||
if (!machine[_constants.WAIT_LISTENERS_STORAGE] || machine[_constants.WAIT_LISTENERS_STORAGE].length === 0) return; | ||
// We register the `done` functions that should be called | ||
// because this should happen at the very end of the | ||
// listeners processing. | ||
var callbacks = []; | ||
machine[_constants.WAIT_LISTENERS_STORAGE] = machine[_constants.WAIT_LISTENERS_STORAGE].filter(function (_ref) { | ||
var actions = _ref.actions, | ||
done = _ref.done, | ||
result = _ref.result; | ||
var actionIndex = actions.indexOf(action); | ||
if (actionIndex === -1) return true; | ||
result[result.indexOf(action)] = payload; | ||
actions.splice(actionIndex, 1); | ||
if (actions.length === 0) { | ||
result.length === 1 ? callbacks.push(done.bind(null, result[0])) : callbacks.push(done.bind(null, result)); | ||
return false; | ||
} | ||
return true; | ||
}); | ||
callbacks.forEach(function (c) { | ||
return c(); | ||
}); | ||
// Clean up. There is no need to keep that temporary array | ||
// if all the listeners are flushed. | ||
if (machine[_constants.WAIT_LISTENERS_STORAGE].length === 0) delete machine[_constants.WAIT_LISTENERS_STORAGE]; | ||
} | ||
function updateState(machine, response) { | ||
@@ -181,5 +238,32 @@ var newState; | ||
machine.state = newState; | ||
handleMiddleware(function () { | ||
machine.state = newState; | ||
}, MIDDLEWARE_PROCESS_STATE_CHANGE, machine); | ||
} | ||
function handleMiddleware(done, hook, machine) { | ||
for (var _len = arguments.length, args = Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) { | ||
args[_key - 3] = arguments[_key]; | ||
} | ||
if (!machine[_constants.MIDDLEWARE_STORAGE]) return done(); | ||
var middlewares = machine[_constants.MIDDLEWARE_STORAGE]; | ||
var loop = function loop(index, process) { | ||
return index < middlewares.length - 1 ? process(index + 1) : done(); | ||
}; | ||
(function process(index) { | ||
var middleware = middlewares[index]; | ||
if (middleware && typeof middleware[hook] !== 'undefined') { | ||
middleware[hook].apply(machine, [function () { | ||
return loop(index, process); | ||
}].concat(args)); | ||
} else { | ||
loop(index, process); | ||
} | ||
})(0); | ||
} | ||
function handleAction(machine, action, payload) { | ||
@@ -200,22 +284,26 @@ var state = machine.state, | ||
// string as a handler | ||
if (typeof handler === 'string') { | ||
updateState(machine, _extends({}, state, { name: transitions[state.name][action] })); | ||
handleMiddleware(function () { | ||
flushListeners(machine, action, payload); | ||
// object as a handler | ||
} else if ((typeof handler === 'undefined' ? 'undefined' : _typeof(handler)) === 'object') { | ||
updateState(machine, (0, _validateState2.default)(handler)); | ||
// string as a handler | ||
if (typeof handler === 'string') { | ||
updateState(machine, _extends({}, state, { name: transitions[state.name][action] })); | ||
// function as a handler | ||
} else if (typeof handler === 'function') { | ||
var response = transitions[state.name][action].apply(machine, [machine.state, payload]); | ||
// object as a handler | ||
} else if ((typeof handler === 'undefined' ? 'undefined' : _typeof(handler)) === 'object') { | ||
updateState(machine, (0, _validateState2.default)(handler)); | ||
if (response && typeof response.next === 'function') { | ||
handleGenerator(machine, response, function (response) { | ||
// function as a handler | ||
} else if (typeof handler === 'function') { | ||
var response = transitions[state.name][action].apply(machine, [machine.state, payload]); | ||
if (response && typeof response.next === 'function') { | ||
handleGenerator(machine, response, function (response) { | ||
updateState(machine, response); | ||
}); | ||
} else { | ||
updateState(machine, response); | ||
}); | ||
} else { | ||
updateState(machine, response); | ||
} | ||
} | ||
} | ||
}, MIDDLEWARE_PROCESS_ACTION, machine, action, payload); | ||
@@ -274,6 +362,7 @@ return true; | ||
this.machines = {}; | ||
this.middlewares = []; | ||
} | ||
MachineFactory.prototype.create = function create(name, config) { | ||
return this.machines[name] = (0, _createMachine2.default)(name, config); | ||
return this.machines[name] = (0, _createMachine2.default)(name, config, this.middlewares); | ||
}; | ||
@@ -288,4 +377,9 @@ | ||
this.machines = []; | ||
this.middlewares = []; | ||
}; | ||
MachineFactory.prototype.addMiddleware = function addMiddleware(middleware) { | ||
this.middlewares.push(middleware); | ||
}; | ||
return MachineFactory; | ||
@@ -292,0 +386,0 @@ }(); |
@@ -1,1 +0,1 @@ | ||
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.stent=f()}})(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){"use strict";exports.__esModule=true;var _typeof=typeof Symbol==="function"&&typeof Symbol.iterator==="symbol"?function(obj){return typeof obj}:function(obj){return obj&&typeof Symbol==="function"&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj};var ERROR_MISSING_MACHINE=exports.ERROR_MISSING_MACHINE=function ERROR_MISSING_MACHINE(name){return"There's no machine with name "+name};var ERROR_MISSING_STATE=exports.ERROR_MISSING_STATE='Configuration error: missing initial "state"';var ERROR_MISSING_TRANSITIONS=exports.ERROR_MISSING_TRANSITIONS='Configuration error: missing "transitions"';var ERROR_MISSING_ACTION_IN_STATE=exports.ERROR_MISSING_ACTION_IN_STATE=function ERROR_MISSING_ACTION_IN_STATE(action,state){return'"'+action+'" action is not available in "'+state+'" state'};var ERROR_WRONG_STATE_FORMAT=exports.ERROR_WRONG_STATE_FORMAT=function ERROR_WRONG_STATE_FORMAT(state){var serialized=(typeof state==="undefined"?"undefined":_typeof(state))==="object"?JSON.stringify(state,null,2):state;return'The state should be an object and it should always have at least "name" property. You passed '+serialized};var ERROR_UNCOVERED_STATE=exports.ERROR_UNCOVERED_STATE=function ERROR_UNCOVERED_STATE(state){return"You just transitioned the machine to a state ("+state+") which is not defined or it has no actions. This means that the machine is stuck."}},{}],2:[function(require,module,exports){"use strict";exports.__esModule=true;var _typeof=typeof Symbol==="function"&&typeof Symbol.iterator==="symbol"?function(obj){return typeof obj}:function(obj){return obj&&typeof Symbol==="function"&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj};exports.registerMethods=registerMethods;exports.validateConfig=validateConfig;exports.default=createMachine;var _toCamelCase=require("./helpers/toCamelCase");var _toCamelCase2=_interopRequireDefault(_toCamelCase);var _constants=require("./constants");var _handleAction=require("./handleAction");var _handleAction2=_interopRequireDefault(_handleAction);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function registerMethods(machine,transitions,dispatch){for(var state in transitions){(function(state){machine[(0,_toCamelCase2.default)("is "+state)]=function(){return machine.state.name===state}})(state);for(var action in transitions[state]){(function(action){machine[(0,_toCamelCase2.default)(action)]=function(payload){return dispatch(action,payload)}})(action)}}}function validateConfig(_ref){var state=_ref.state,transitions=_ref.transitions;if((typeof state==="undefined"?"undefined":_typeof(state))!=="object")throw new Error(_constants.ERROR_MISSING_STATE);if((typeof transitions==="undefined"?"undefined":_typeof(transitions))!=="object")throw new Error(_constants.ERROR_MISSING_TRANSITIONS);return true}function createMachine(name,config){var machine={name:name};var initialState=config.state,transitions=config.transitions;machine.state=initialState;if(validateConfig(config)){registerMethods(machine,transitions,function(action,payload){return(0,_handleAction2.default)(machine,action,payload)})}return machine}},{"./constants":1,"./handleAction":3,"./helpers/toCamelCase":4}],3:[function(require,module,exports){"use strict";exports.__esModule=true;var _extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key]}}}return target};var _typeof=typeof Symbol==="function"&&typeof Symbol.iterator==="symbol"?function(obj){return typeof obj}:function(obj){return obj&&typeof Symbol==="function"&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj};exports.default=handleAction;var _constants=require("./constants");var _validateState=require("./helpers/validateState");var _validateState2=_interopRequireDefault(_validateState);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function isEmptyObject(obj){var name;for(name in obj){if(obj.hasOwnProperty(name))return false}return true}function handleGenerator(machine,generator,done,resultOfPreviousOperation){var iterate=function iterate(result){if(!result.done){if(_typeof(result.value)==="object"&&result.value.__type==="call"){var _result$value;var funcResult=(_result$value=result.value).func.apply(_result$value,result.value.args);if(typeof funcResult.then!=="undefined"){funcResult.then(function(r){return iterate(generator.next(r))},function(error){return iterate(generator.throw(new Error(error)))})}else if(typeof funcResult.next==="function"){handleGenerator(machine,funcResult,function(generatorResult){iterate(generator.next(generatorResult))})}else{iterate(generator.next(funcResult))}}else{updateState(machine,result.value);iterate(generator.next())}}else{done(result.value)}};iterate(generator.next(resultOfPreviousOperation))}function updateState(machine,response){var newState;if(typeof response==="undefined")return;if(typeof response==="string"||typeof response==="number"){newState={name:response.toString()}}else{newState=(0,_validateState2.default)(response)}if(typeof machine.transitions[newState.name]==="undefined"||isEmptyObject(machine.transitions[newState.name])){throw new Error((0,_constants.ERROR_UNCOVERED_STATE)(newState.name))}machine.state=newState}function handleAction(machine,action,payload){var state=machine.state,transitions=machine.transitions;if(!transitions[state.name]){return false}var handler=transitions[state.name][action];if(typeof transitions[state.name][action]==="undefined"){throw new Error((0,_constants.ERROR_MISSING_ACTION_IN_STATE)(action,state.name))}if(typeof handler==="string"){updateState(machine,_extends({},state,{name:transitions[state.name][action]}))}else if((typeof handler==="undefined"?"undefined":_typeof(handler))==="object"){updateState(machine,(0,_validateState2.default)(handler))}else if(typeof handler==="function"){var response=transitions[state.name][action].apply(machine,[machine.state,payload]);if(response&&typeof response.next==="function"){handleGenerator(machine,response,function(response){updateState(machine,response)})}else{updateState(machine,response)}}return true}module.exports=exports["default"]},{"./constants":1,"./helpers/validateState":5}],4:[function(require,module,exports){"use strict";exports.__esModule=true;exports.default=function(text){return text.toLowerCase().replace(/\W+(.)/g,function(match,chr){return chr.toUpperCase()})};module.exports=exports["default"]},{}],5:[function(require,module,exports){"use strict";exports.__esModule=true;var _typeof=typeof Symbol==="function"&&typeof Symbol.iterator==="symbol"?function(obj){return typeof obj}:function(obj){return obj&&typeof Symbol==="function"&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj};exports.default=validateState;var _constants=require("../constants");function validateState(state){if(state&&(typeof state==="undefined"?"undefined":_typeof(state))==="object"&&typeof state.name!=="undefined")return state;throw new Error((0,_constants.ERROR_WRONG_STATE_FORMAT)(state))}module.exports=exports["default"]},{"../constants":1}],6:[function(require,module,exports){"use strict";exports.__esModule=true;exports.Machine=undefined;var _createMachine=require("./createMachine");var _createMachine2=_interopRequireDefault(_createMachine);var _constants=require("./constants");function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}var MachineFactory=function(){function MachineFactory(){_classCallCheck(this,MachineFactory);this.machines={}}MachineFactory.prototype.create=function create(name,config){return this.machines[name]=(0,_createMachine2.default)(name,config)};MachineFactory.prototype.get=function get(name){if(this.machines[name])return this.machines[name];throw new Error((0,_constants.ERROR_MISSING_MACHINE)(name))};MachineFactory.prototype.flush=function flush(){this.machines=[]};return MachineFactory}();var factory=new MachineFactory;exports.Machine=factory},{"./constants":1,"./createMachine":2}]},{},[6])(6)}); | ||
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.stent=f()}})(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){"use strict";exports.__esModule=true;var _typeof=typeof Symbol==="function"&&typeof Symbol.iterator==="symbol"?function(obj){return typeof obj}:function(obj){return obj&&typeof Symbol==="function"&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj};var ERROR_MISSING_MACHINE=exports.ERROR_MISSING_MACHINE=function ERROR_MISSING_MACHINE(name){return"There's no machine with name "+name};var ERROR_MISSING_STATE=exports.ERROR_MISSING_STATE='Configuration error: missing initial "state"';var ERROR_MISSING_TRANSITIONS=exports.ERROR_MISSING_TRANSITIONS='Configuration error: missing "transitions"';var ERROR_MISSING_ACTION_IN_STATE=exports.ERROR_MISSING_ACTION_IN_STATE=function ERROR_MISSING_ACTION_IN_STATE(action,state){return'"'+action+'" action is not available in "'+state+'" state'};var ERROR_WRONG_STATE_FORMAT=exports.ERROR_WRONG_STATE_FORMAT=function ERROR_WRONG_STATE_FORMAT(state){var serialized=(typeof state==="undefined"?"undefined":_typeof(state))==="object"?JSON.stringify(state,null,2):state;return'The state should be an object and it should always have at least "name" property. You passed '+serialized};var ERROR_UNCOVERED_STATE=exports.ERROR_UNCOVERED_STATE=function ERROR_UNCOVERED_STATE(state){return"You just transitioned the machine to a state ("+state+") which is not defined or it has no actions. This means that the machine is stuck."};var WAIT_LISTENERS_STORAGE=exports.WAIT_LISTENERS_STORAGE="___@wait";var MIDDLEWARE_STORAGE=exports.MIDDLEWARE_STORAGE="___@middlewares"},{}],2:[function(require,module,exports){"use strict";exports.__esModule=true;var _typeof=typeof Symbol==="function"&&typeof Symbol.iterator==="symbol"?function(obj){return typeof obj}:function(obj){return obj&&typeof Symbol==="function"&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj};exports.registerMethods=registerMethods;exports.validateConfig=validateConfig;exports.default=createMachine;var _toCamelCase=require("./helpers/toCamelCase");var _toCamelCase2=_interopRequireDefault(_toCamelCase);var _constants=require("./constants");var _handleAction=require("./handleAction");var _handleAction2=_interopRequireDefault(_handleAction);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function registerMethods(machine,transitions,dispatch){for(var state in transitions){(function(state){machine[(0,_toCamelCase2.default)("is "+state)]=function(){return machine.state.name===state}})(state);for(var action in transitions[state]){(function(action){machine[(0,_toCamelCase2.default)(action)]=function(payload){return dispatch(action,payload)}})(action)}}}function validateConfig(_ref){var state=_ref.state,transitions=_ref.transitions;if((typeof state==="undefined"?"undefined":_typeof(state))!=="object")throw new Error(_constants.ERROR_MISSING_STATE);if((typeof transitions==="undefined"?"undefined":_typeof(transitions))!=="object")throw new Error(_constants.ERROR_MISSING_TRANSITIONS);return true}function createMachine(name,config,middlewares){var _machine;var machine=(_machine={name:name},_machine[_constants.MIDDLEWARE_STORAGE]=middlewares,_machine);var initialState=config.state,transitions=config.transitions;machine.state=initialState;machine.transitions=transitions;if(validateConfig(config)){registerMethods(machine,transitions,function(action,payload){return(0,_handleAction2.default)(machine,action,payload)})}return machine}},{"./constants":1,"./handleAction":3,"./helpers/toCamelCase":4}],3:[function(require,module,exports){"use strict";exports.__esModule=true;var _extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key]}}}return target};var _typeof=typeof Symbol==="function"&&typeof Symbol.iterator==="symbol"?function(obj){return typeof obj}:function(obj){return obj&&typeof Symbol==="function"&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj};exports.default=handleAction;var _constants=require("./constants");var _validateState=require("./helpers/validateState");var _validateState2=_interopRequireDefault(_validateState);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}var MIDDLEWARE_PROCESS_ACTION="onActionDispatched";var MIDDLEWARE_PROCESS_STATE_CHANGE="onStateChange";function isEmptyObject(obj){var name;for(name in obj){if(obj.hasOwnProperty(name))return false}return true}function handleGenerator(machine,generator,done,resultOfPreviousOperation){var iterate=function iterate(result){if(!result.done){if(_typeof(result.value)==="object"&&result.value.__type==="call"){var _result$value;var funcResult=(_result$value=result.value).func.apply(_result$value,result.value.args);if(typeof funcResult.then!=="undefined"){funcResult.then(function(result){return iterate(generator.next(result))},function(error){return iterate(generator.throw(new Error(error)))})}else if(typeof funcResult.next==="function"){handleGenerator(machine,funcResult,function(generatorResult){iterate(generator.next(generatorResult))})}else{iterate(generator.next(funcResult))}}else if(_typeof(result.value)==="object"&&result.value.__type==="wait"){waitFor(machine,result.value.actions,function(result){return iterate(generator.next(result))})}else{updateState(machine,result.value);iterate(generator.next())}}else{done(result.value)}};iterate(generator.next(resultOfPreviousOperation))}function waitFor(machine,actions,done){if(!machine[_constants.WAIT_LISTENERS_STORAGE])machine[_constants.WAIT_LISTENERS_STORAGE]=[];machine[_constants.WAIT_LISTENERS_STORAGE].push({actions:actions,done:done,result:[].concat(actions)})}function flushListeners(machine,action,payload){if(!machine[_constants.WAIT_LISTENERS_STORAGE]||machine[_constants.WAIT_LISTENERS_STORAGE].length===0)return;var callbacks=[];machine[_constants.WAIT_LISTENERS_STORAGE]=machine[_constants.WAIT_LISTENERS_STORAGE].filter(function(_ref){var actions=_ref.actions,done=_ref.done,result=_ref.result;var actionIndex=actions.indexOf(action);if(actionIndex===-1)return true;result[result.indexOf(action)]=payload;actions.splice(actionIndex,1);if(actions.length===0){result.length===1?callbacks.push(done.bind(null,result[0])):callbacks.push(done.bind(null,result));return false}return true});callbacks.forEach(function(c){return c()});if(machine[_constants.WAIT_LISTENERS_STORAGE].length===0)delete machine[_constants.WAIT_LISTENERS_STORAGE]}function updateState(machine,response){var newState;if(typeof response==="undefined")return;if(typeof response==="string"||typeof response==="number"){newState={name:response.toString()}}else{newState=(0,_validateState2.default)(response)}if(typeof machine.transitions[newState.name]==="undefined"||isEmptyObject(machine.transitions[newState.name])){throw new Error((0,_constants.ERROR_UNCOVERED_STATE)(newState.name))}handleMiddleware(function(){machine.state=newState},MIDDLEWARE_PROCESS_STATE_CHANGE,machine)}function handleMiddleware(done,hook,machine){for(var _len=arguments.length,args=Array(_len>3?_len-3:0),_key=3;_key<_len;_key++){args[_key-3]=arguments[_key]}if(!machine[_constants.MIDDLEWARE_STORAGE])return done();var middlewares=machine[_constants.MIDDLEWARE_STORAGE];var loop=function loop(index,process){return index<middlewares.length-1?process(index+1):done()};(function process(index){var middleware=middlewares[index];if(middleware&&typeof middleware[hook]!=="undefined"){middleware[hook].apply(machine,[function(){return loop(index,process)}].concat(args))}else{loop(index,process)}})(0)}function handleAction(machine,action,payload){var state=machine.state,transitions=machine.transitions;if(!transitions[state.name]){return false}var handler=transitions[state.name][action];if(typeof transitions[state.name][action]==="undefined"){throw new Error((0,_constants.ERROR_MISSING_ACTION_IN_STATE)(action,state.name))}handleMiddleware(function(){flushListeners(machine,action,payload);if(typeof handler==="string"){updateState(machine,_extends({},state,{name:transitions[state.name][action]}))}else if((typeof handler==="undefined"?"undefined":_typeof(handler))==="object"){updateState(machine,(0,_validateState2.default)(handler))}else if(typeof handler==="function"){var response=transitions[state.name][action].apply(machine,[machine.state,payload]);if(response&&typeof response.next==="function"){handleGenerator(machine,response,function(response){updateState(machine,response)})}else{updateState(machine,response)}}},MIDDLEWARE_PROCESS_ACTION,machine,action,payload);return true}module.exports=exports["default"]},{"./constants":1,"./helpers/validateState":5}],4:[function(require,module,exports){"use strict";exports.__esModule=true;exports.default=function(text){return text.toLowerCase().replace(/\W+(.)/g,function(match,chr){return chr.toUpperCase()})};module.exports=exports["default"]},{}],5:[function(require,module,exports){"use strict";exports.__esModule=true;var _typeof=typeof Symbol==="function"&&typeof Symbol.iterator==="symbol"?function(obj){return typeof obj}:function(obj){return obj&&typeof Symbol==="function"&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj};exports.default=validateState;var _constants=require("../constants");function validateState(state){if(state&&(typeof state==="undefined"?"undefined":_typeof(state))==="object"&&typeof state.name!=="undefined")return state;throw new Error((0,_constants.ERROR_WRONG_STATE_FORMAT)(state))}module.exports=exports["default"]},{"../constants":1}],6:[function(require,module,exports){"use strict";exports.__esModule=true;exports.Machine=undefined;var _createMachine=require("./createMachine");var _createMachine2=_interopRequireDefault(_createMachine);var _constants=require("./constants");function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}var MachineFactory=function(){function MachineFactory(){_classCallCheck(this,MachineFactory);this.machines={};this.middlewares=[]}MachineFactory.prototype.create=function create(name,config){return this.machines[name]=(0,_createMachine2.default)(name,config,this.middlewares)};MachineFactory.prototype.get=function get(name){if(this.machines[name])return this.machines[name];throw new Error((0,_constants.ERROR_MISSING_MACHINE)(name))};MachineFactory.prototype.flush=function flush(){this.machines=[];this.middlewares=[]};MachineFactory.prototype.addMiddleware=function addMiddleware(middleware){this.middlewares.push(middleware)};return MachineFactory}();var factory=new MachineFactory;exports.Machine=factory},{"./constants":1,"./createMachine":2}]},{},[6])(6)}); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
251439
46
2232
535