xstate
Version:
Finite State Machines and Statecharts for the Modern Web.
138 lines (123 loc) • 3.29 kB
JavaScript
Object.defineProperty(exports, '__esModule', { value: true });
var actions = require('./actions.js');
var Actor = require('./Actor.js');
var utils = require('./utils.js');
/**
* Returns an actor behavior from a reducer and its initial state.
*
* @param transition The pure reducer that returns the next state given the current state and event.
* @param initialState The initial state of the reducer.
* @returns An actor behavior
*/
function fromReducer(transition, initialState) {
return {
transition: transition,
initialState: initialState
};
}
function fromPromise(promiseFn) {
var initialState = {
error: undefined,
data: undefined,
status: 'pending'
};
return {
transition: function (state, event, _a) {
var parent = _a.parent,
id = _a.id,
observers = _a.observers;
switch (event.type) {
case 'fulfill':
parent === null || parent === void 0 ? void 0 : parent.send(actions.doneInvoke(id, event.data));
return {
error: undefined,
data: event.data,
status: 'fulfilled'
};
case 'reject':
parent === null || parent === void 0 ? void 0 : parent.send(actions.error(id, event.error));
observers.forEach(function (observer) {
observer.error(event.error);
});
return {
error: event.error,
data: undefined,
status: 'rejected'
};
default:
return state;
}
},
initialState: initialState,
start: function (_a) {
var self = _a.self;
promiseFn().then(function (data) {
self.send({
type: 'fulfill',
data: data
});
}, function (reason) {
self.send({
type: 'reject',
error: reason
});
});
return initialState;
}
};
}
function spawnBehavior(behavior, options) {
if (options === void 0) {
options = {};
}
var state = behavior.initialState;
var observers = new Set();
var mailbox = [];
var flushing = false;
var flush = function () {
if (flushing) {
return;
}
flushing = true;
while (mailbox.length > 0) {
var event_1 = mailbox.shift();
state = behavior.transition(state, event_1, actorCtx);
observers.forEach(function (observer) {
return observer.next(state);
});
}
flushing = false;
};
var actor = Actor.toActorRef({
id: options.id,
send: function (event) {
mailbox.push(event);
flush();
},
getSnapshot: function () {
return state;
},
subscribe: function (next, handleError, complete) {
var observer = utils.toObserver(next, handleError, complete);
observers.add(observer);
observer.next(state);
return {
unsubscribe: function () {
observers.delete(observer);
}
};
}
});
var actorCtx = {
parent: options.parent,
self: actor,
id: options.id || 'anonymous',
observers: observers
};
state = behavior.start ? behavior.start(actorCtx) : state;
return actor;
}
exports.fromPromise = fromPromise;
exports.fromReducer = fromReducer;
exports.spawnBehavior = spawnBehavior;
;