mage-engine
Version:
A WebGL Javascript Game Engine, built on top of THREE.js and many other libraries.
1,913 lines (1,632 loc) • 3.05 MB
JavaScript
function _assertThisInitialized(e) {
if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
return e;
}
function _callSuper(t, o, e) {
return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e));
}
function _classCallCheck(a, n) {
if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function");
}
function _defineProperties(e, r) {
for (var t = 0; t < r.length; t++) {
var o = r[t];
o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o);
}
}
function _createClass(e, r, t) {
return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", {
writable: !1
}), e;
}
function _defineProperty$1(e, r, t) {
return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
value: t,
enumerable: !0,
configurable: !0,
writable: !0
}) : e[r] = t, e;
}
function _get() {
return _get = "undefined" != typeof Reflect && Reflect.get ? Reflect.get.bind() : function (e, t, r) {
var p = _superPropBase(e, t);
if (p) {
var n = Object.getOwnPropertyDescriptor(p, t);
return n.get ? n.get.call(arguments.length < 3 ? e : r) : n.value;
}
}, _get.apply(null, arguments);
}
function _getPrototypeOf(t) {
return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) {
return t.__proto__ || Object.getPrototypeOf(t);
}, _getPrototypeOf(t);
}
function _inherits(t, e) {
if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function");
t.prototype = Object.create(e && e.prototype, {
constructor: {
value: t,
writable: !0,
configurable: !0
}
}), Object.defineProperty(t, "prototype", {
writable: !1
}), e && _setPrototypeOf(t, e);
}
function _isNativeReflectConstruct() {
try {
var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
} catch (t) {}
return (_isNativeReflectConstruct = function () {
return !!t;
})();
}
function _possibleConstructorReturn(t, e) {
if (e && ("object" == typeof e || "function" == typeof e)) return e;
if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined");
return _assertThisInitialized(t);
}
function _setPrototypeOf(t, e) {
return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) {
return t.__proto__ = e, t;
}, _setPrototypeOf(t, e);
}
function _superPropBase(t, o) {
for (; !{}.hasOwnProperty.call(t, o) && null !== (t = _getPrototypeOf(t)););
return t;
}
function _superPropGet(t, o, e, r) {
var p = _get(_getPrototypeOf(1 & r ? t.prototype : t), o, e);
return 2 & r && "function" == typeof p ? function (t) {
return p.apply(e, t);
} : p;
}
function _toPrimitive(t, r) {
if ("object" != typeof t || !t) return t;
var e = t[Symbol.toPrimitive];
if (void 0 !== e) {
var i = e.call(t, r || "default");
if ("object" != typeof i) return i;
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return ("string" === r ? String : Number)(t);
}
function _toPropertyKey(t) {
var i = _toPrimitive(t, "string");
return "symbol" == typeof i ? i : i + "";
}/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
var __assign = function () {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __rest(s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
}
return t;
}
function __values(o) {
var m = typeof Symbol === "function" && o[Symbol.iterator],
i = 0;
if (m) return m.call(o);
return {
next: function () {
if (o && i >= o.length) o = void 0;
return {
value: o && o[i++],
done: !o
};
}
};
}
function __read(o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o),
r,
ar = [],
e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
} catch (error) {
e = {
error: error
};
} finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
} finally {
if (e) throw e.error;
}
}
return ar;
}
function __spread() {
for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
return ar;
}var STATE_DELIMITER = '.';
var EMPTY_ACTIVITY_MAP = {};
var DEFAULT_GUARD_TYPE = 'xstate.guard';
var TARGETLESS_KEY = '';var IS_PRODUCTION = "production" === 'production';function keys(value) {
return Object.keys(value);
}
function matchesState(parentStateId, childStateId, delimiter) {
if (delimiter === void 0) {
delimiter = STATE_DELIMITER;
}
var parentStateValue = toStateValue(parentStateId, delimiter);
var childStateValue = toStateValue(childStateId, delimiter);
if (isString$4(childStateValue)) {
if (isString$4(parentStateValue)) {
return childStateValue === parentStateValue;
} // Parent more specific than child
return false;
}
if (isString$4(parentStateValue)) {
return parentStateValue in childStateValue;
}
return keys(parentStateValue).every(function (key) {
if (!(key in childStateValue)) {
return false;
}
return matchesState(parentStateValue[key], childStateValue[key]);
});
}
function getEventType(event) {
try {
return isString$4(event) || typeof event === 'number' ? "" + event : event.type;
} catch (e) {
throw new Error('Events must be strings or objects with a string event.type property.');
}
}
function toStatePath(stateId, delimiter) {
try {
if (isArray$4(stateId)) {
return stateId;
}
return stateId.toString().split(delimiter);
} catch (e) {
throw new Error("'" + stateId + "' is not a valid state path.");
}
}
function isStateLike(state) {
return typeof state === 'object' && 'value' in state && 'context' in state && 'event' in state && '_event' in state;
}
function toStateValue(stateValue, delimiter) {
if (isStateLike(stateValue)) {
return stateValue.value;
}
if (isArray$4(stateValue)) {
return pathToStateValue(stateValue);
}
if (typeof stateValue !== 'string') {
return stateValue;
}
var statePath = toStatePath(stateValue, delimiter);
return pathToStateValue(statePath);
}
function pathToStateValue(statePath) {
if (statePath.length === 1) {
return statePath[0];
}
var value = {};
var marker = value;
for (var i = 0; i < statePath.length - 1; i++) {
if (i === statePath.length - 2) {
marker[statePath[i]] = statePath[i + 1];
} else {
marker[statePath[i]] = {};
marker = marker[statePath[i]];
}
}
return value;
}
function mapValues(collection, iteratee) {
var result = {};
var collectionKeys = keys(collection);
for (var i = 0; i < collectionKeys.length; i++) {
var key = collectionKeys[i];
result[key] = iteratee(collection[key], key, collection, i);
}
return result;
}
function mapFilterValues(collection, iteratee, predicate) {
var e_1, _a;
var result = {};
try {
for (var _b = __values(keys(collection)), _c = _b.next(); !_c.done; _c = _b.next()) {
var key = _c.value;
var item = collection[key];
if (!predicate(item)) {
continue;
}
result[key] = iteratee(item, key, collection);
}
} catch (e_1_1) {
e_1 = {
error: e_1_1
};
} finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
} finally {
if (e_1) throw e_1.error;
}
}
return result;
}
/**
* Retrieves a value at the given path.
* @param props The deep path to the prop of the desired value
*/
var path = function (props) {
return function (object) {
var e_2, _a;
var result = object;
try {
for (var props_1 = __values(props), props_1_1 = props_1.next(); !props_1_1.done; props_1_1 = props_1.next()) {
var prop = props_1_1.value;
result = result[prop];
}
} catch (e_2_1) {
e_2 = {
error: e_2_1
};
} finally {
try {
if (props_1_1 && !props_1_1.done && (_a = props_1.return)) _a.call(props_1);
} finally {
if (e_2) throw e_2.error;
}
}
return result;
};
};
/**
* Retrieves a value at the given path via the nested accessor prop.
* @param props The deep path to the prop of the desired value
*/
function nestedPath(props, accessorProp) {
return function (object) {
var e_3, _a;
var result = object;
try {
for (var props_2 = __values(props), props_2_1 = props_2.next(); !props_2_1.done; props_2_1 = props_2.next()) {
var prop = props_2_1.value;
result = result[accessorProp][prop];
}
} catch (e_3_1) {
e_3 = {
error: e_3_1
};
} finally {
try {
if (props_2_1 && !props_2_1.done && (_a = props_2.return)) _a.call(props_2);
} finally {
if (e_3) throw e_3.error;
}
}
return result;
};
}
function toStatePaths(stateValue) {
if (!stateValue) {
return [[]];
}
if (isString$4(stateValue)) {
return [[stateValue]];
}
var result = flatten$1(keys(stateValue).map(function (key) {
var subStateValue = stateValue[key];
if (typeof subStateValue !== 'string' && (!subStateValue || !Object.keys(subStateValue).length)) {
return [[key]];
}
return toStatePaths(stateValue[key]).map(function (subPath) {
return [key].concat(subPath);
});
}));
return result;
}
function flatten$1(array) {
var _a;
return (_a = []).concat.apply(_a, __spread(array));
}
function toArrayStrict(value) {
if (isArray$4(value)) {
return value;
}
return [value];
}
function toArray$1(value) {
if (value === undefined) {
return [];
}
return toArrayStrict(value);
}
function mapContext(mapper, context, _event) {
var e_5, _a;
if (isFunction$4(mapper)) {
return mapper(context, _event.data);
}
var result = {};
try {
for (var _b = __values(keys(mapper)), _c = _b.next(); !_c.done; _c = _b.next()) {
var key = _c.value;
var subMapper = mapper[key];
if (isFunction$4(subMapper)) {
result[key] = subMapper(context, _event.data);
} else {
result[key] = subMapper;
}
}
} catch (e_5_1) {
e_5 = {
error: e_5_1
};
} finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
} finally {
if (e_5) throw e_5.error;
}
}
return result;
}
function isBuiltInEvent(eventType) {
return /^(done|error)\./.test(eventType);
}
function isPromiseLike(value) {
if (value instanceof Promise) {
return true;
} // Check if shape matches the Promise/A+ specification for a "thenable".
if (value !== null && (isFunction$4(value) || typeof value === 'object') && isFunction$4(value.then)) {
return true;
}
return false;
}
function partition$1(items, predicate) {
var e_6, _a;
var _b = __read([[], []], 2),
truthy = _b[0],
falsy = _b[1];
try {
for (var items_1 = __values(items), items_1_1 = items_1.next(); !items_1_1.done; items_1_1 = items_1.next()) {
var item = items_1_1.value;
if (predicate(item)) {
truthy.push(item);
} else {
falsy.push(item);
}
}
} catch (e_6_1) {
e_6 = {
error: e_6_1
};
} finally {
try {
if (items_1_1 && !items_1_1.done && (_a = items_1.return)) _a.call(items_1);
} finally {
if (e_6) throw e_6.error;
}
}
return [truthy, falsy];
}
function updateHistoryStates(hist, stateValue) {
return mapValues(hist.states, function (subHist, key) {
if (!subHist) {
return undefined;
}
var subStateValue = (isString$4(stateValue) ? undefined : stateValue[key]) || (subHist ? subHist.current : undefined);
if (!subStateValue) {
return undefined;
}
return {
current: subStateValue,
states: updateHistoryStates(subHist, subStateValue)
};
});
}
function updateHistoryValue(hist, stateValue) {
return {
current: stateValue,
states: updateHistoryStates(hist, stateValue)
};
}
function updateContext(context, _event, assignActions, state) {
var updatedContext = context ? assignActions.reduce(function (acc, assignAction) {
var e_7, _a;
var assignment = assignAction.assignment;
var meta = {
state: state,
action: assignAction,
_event: _event
};
var partialUpdate = {};
if (isFunction$4(assignment)) {
partialUpdate = assignment(acc, _event.data, meta);
} else {
try {
for (var _b = __values(keys(assignment)), _c = _b.next(); !_c.done; _c = _b.next()) {
var key = _c.value;
var propAssignment = assignment[key];
partialUpdate[key] = isFunction$4(propAssignment) ? propAssignment(acc, _event.data, meta) : propAssignment;
}
} catch (e_7_1) {
e_7 = {
error: e_7_1
};
} finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
} finally {
if (e_7) throw e_7.error;
}
}
}
return Object.assign({}, acc, partialUpdate);
}, context) : context;
return updatedContext;
} // tslint:disable-next-line:no-empty
var warn = function () {};
if (!IS_PRODUCTION) {
warn = function (condition, message) {
var error = condition instanceof Error ? condition : undefined;
if (!error && condition) {
return;
}
if (console !== undefined) {
var args = ["Warning: " + message];
if (error) {
args.push(error);
} // tslint:disable-next-line:no-console
console.warn.apply(console, args);
}
};
}
function isArray$4(value) {
return Array.isArray(value);
} // tslint:disable-next-line:ban-types
function isFunction$4(value) {
return typeof value === 'function';
}
function isString$4(value) {
return typeof value === 'string';
} // export function memoizedGetter<T, TP extends { prototype: object }>(
// o: TP,
// property: string,
// getter: () => T
// ): void {
// Object.defineProperty(o.prototype, property, {
// get: getter,
// enumerable: false,
// configurable: false
// });
// }
function toGuard(condition, guardMap) {
if (!condition) {
return undefined;
}
if (isString$4(condition)) {
return {
type: DEFAULT_GUARD_TYPE,
name: condition,
predicate: guardMap ? guardMap[condition] : undefined
};
}
if (isFunction$4(condition)) {
return {
type: DEFAULT_GUARD_TYPE,
name: condition.name,
predicate: condition
};
}
return condition;
}
function isObservable$1(value) {
try {
return 'subscribe' in value && isFunction$4(value.subscribe);
} catch (e) {
return false;
}
}
var symbolObservable =
/*#__PURE__*/
function () {
return typeof Symbol === 'function' && Symbol.observable || '@@observable';
}();
function isMachine(value) {
try {
return '__xstatenode' in value;
} catch (e) {
return false;
}
}
var uniqueId =
/*#__PURE__*/
function () {
var currentId = 0;
return function () {
currentId++;
return currentId.toString(16);
};
}();
function toEventObject(event, payload // id?: TEvent['type']
) {
if (isString$4(event) || typeof event === 'number') {
return __assign({
type: event
}, payload);
}
return event;
}
function toSCXMLEvent(event, scxmlEvent) {
if (!isString$4(event) && '$$type' in event && event.$$type === 'scxml') {
return event;
}
var eventObject = toEventObject(event);
return __assign({
name: eventObject.type,
data: eventObject,
$$type: 'scxml',
type: 'external'
}, scxmlEvent);
}
function toTransitionConfigArray(event, configLike) {
var transitions = toArrayStrict(configLike).map(function (transitionLike) {
if (typeof transitionLike === 'undefined' || typeof transitionLike === 'string' || isMachine(transitionLike)) {
// @ts-ignore until Type instantiation is excessively deep and possibly infinite bug is fixed
return {
target: transitionLike,
event: event
};
}
return __assign(__assign({}, transitionLike), {
event: event
});
});
return transitions;
}
function normalizeTarget(target) {
if (target === undefined || target === TARGETLESS_KEY) {
return undefined;
}
return toArray$1(target);
}
function reportUnhandledExceptionOnInvocation(originalError, currentError, id) {
if (!IS_PRODUCTION) {
var originalStackTrace = originalError.stack ? " Stacktrace was '" + originalError.stack + "'" : '';
if (originalError === currentError) {
// tslint:disable-next-line:no-console
console.error("Missing onError handler for invocation '" + id + "', error was '" + originalError + "'." + originalStackTrace);
} else {
var stackTrace = currentError.stack ? " Stacktrace was '" + currentError.stack + "'" : ''; // tslint:disable-next-line:no-console
console.error("Missing onError handler and/or unhandled exception/promise rejection for invocation '" + id + "'. " + ("Original error: '" + originalError + "'. " + originalStackTrace + " Current error is '" + currentError + "'." + stackTrace));
}
}
}function mapState(stateMap, stateId) {
var e_1, _a;
var foundStateId;
try {
for (var _b = __values(keys(stateMap)), _c = _b.next(); !_c.done; _c = _b.next()) {
var mappedStateId = _c.value;
if (matchesState(mappedStateId, stateId) && (!foundStateId || stateId.length > foundStateId.length)) {
foundStateId = mappedStateId;
}
}
} catch (e_1_1) {
e_1 = {
error: e_1_1
};
} finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
} finally {
if (e_1) throw e_1.error;
}
}
return stateMap[foundStateId];
}var ActionTypes$1;
(function (ActionTypes) {
ActionTypes["Start"] = "xstate.start";
ActionTypes["Stop"] = "xstate.stop";
ActionTypes["Raise"] = "xstate.raise";
ActionTypes["Send"] = "xstate.send";
ActionTypes["Cancel"] = "xstate.cancel";
ActionTypes["NullEvent"] = "";
ActionTypes["Assign"] = "xstate.assign";
ActionTypes["After"] = "xstate.after";
ActionTypes["DoneState"] = "done.state";
ActionTypes["DoneInvoke"] = "done.invoke";
ActionTypes["Log"] = "xstate.log";
ActionTypes["Init"] = "xstate.init";
ActionTypes["Invoke"] = "xstate.invoke";
ActionTypes["ErrorExecution"] = "error.execution";
ActionTypes["ErrorCommunication"] = "error.communication";
ActionTypes["ErrorPlatform"] = "error.platform";
ActionTypes["ErrorCustom"] = "xstate.error";
ActionTypes["Update"] = "xstate.update";
ActionTypes["Pure"] = "xstate.pure";
})(ActionTypes$1 || (ActionTypes$1 = {}));
var SpecialTargets;
(function (SpecialTargets) {
SpecialTargets["Parent"] = "#_parent";
SpecialTargets["Internal"] = "#_internal";
})(SpecialTargets || (SpecialTargets = {}));var start$1 = ActionTypes$1.Start;
var stop$1 = ActionTypes$1.Stop;
var raise$1 = ActionTypes$1.Raise;
var send$1 = ActionTypes$1.Send;
var cancel$1 = ActionTypes$1.Cancel;
var nullEvent = ActionTypes$1.NullEvent;
var assign$1 = ActionTypes$1.Assign;
ActionTypes$1.After;
ActionTypes$1.DoneState;
var log$1 = ActionTypes$1.Log;
var init = ActionTypes$1.Init;
var invoke = ActionTypes$1.Invoke;
ActionTypes$1.ErrorExecution;
var errorPlatform = ActionTypes$1.ErrorPlatform;
var error$1 = ActionTypes$1.ErrorCustom;
var update = ActionTypes$1.Update;
var pure = ActionTypes$1.Pure;var initEvent =
/*#__PURE__*/
toSCXMLEvent({
type: init
});
function getActionFunction(actionType, actionFunctionMap) {
return actionFunctionMap ? actionFunctionMap[actionType] || undefined : undefined;
}
function toActionObject(action, actionFunctionMap) {
var actionObject;
if (isString$4(action) || typeof action === 'number') {
var exec = getActionFunction(action, actionFunctionMap);
if (isFunction$4(exec)) {
actionObject = {
type: action,
exec: exec
};
} else if (exec) {
actionObject = exec;
} else {
actionObject = {
type: action,
exec: undefined
};
}
} else if (isFunction$4(action)) {
actionObject = {
// Convert action to string if unnamed
type: action.name || action.toString(),
exec: action
};
} else {
var exec = getActionFunction(action.type, actionFunctionMap);
if (isFunction$4(exec)) {
actionObject = __assign(__assign({}, action), {
exec: exec
});
} else if (exec) {
var type = action.type,
other = __rest(action, ["type"]);
actionObject = __assign(__assign({
type: type
}, exec), other);
} else {
actionObject = action;
}
}
Object.defineProperty(actionObject, 'toString', {
value: function () {
return actionObject.type;
},
enumerable: false,
configurable: true
});
return actionObject;
}
var toActionObjects = function (action, actionFunctionMap) {
if (!action) {
return [];
}
var actions = isArray$4(action) ? action : [action];
return actions.map(function (subAction) {
return toActionObject(subAction, actionFunctionMap);
});
};
function toActivityDefinition(action) {
var actionObject = toActionObject(action);
return __assign(__assign({
id: isString$4(action) ? action : actionObject.id
}, actionObject), {
type: actionObject.type
});
}
/**
* Raises an event. This places the event in the internal event queue, so that
* the event is immediately consumed by the machine in the current step.
*
* @param eventType The event to raise.
*/
function raise(event) {
if (!isString$4(event)) {
return send(event, {
to: SpecialTargets.Internal
});
}
return {
type: raise$1,
event: event
};
}
function resolveRaise(action) {
return {
type: raise$1,
_event: toSCXMLEvent(action.event)
};
}
/**
* Sends an event. This returns an action that will be read by an interpreter to
* send the event in the next step, after the current step is finished executing.
*
* @param event The event to send.
* @param options Options to pass into the send event:
* - `id` - The unique send event identifier (used with `cancel()`).
* - `delay` - The number of milliseconds to delay the sending of the event.
* - `to` - The target of this event (by default, the machine the event was sent from).
*/
function send(event, options) {
return {
to: options ? options.to : undefined,
type: send$1,
event: isFunction$4(event) ? event : toEventObject(event),
delay: options ? options.delay : undefined,
id: options && options.id !== undefined ? options.id : isFunction$4(event) ? event.name : getEventType(event)
};
}
function resolveSend(action, ctx, _event, delaysMap) {
var meta = {
_event: _event
}; // TODO: helper function for resolving Expr
var resolvedEvent = toSCXMLEvent(isFunction$4(action.event) ? action.event(ctx, _event.data, meta) : action.event);
var resolvedDelay;
if (isString$4(action.delay)) {
var configDelay = delaysMap && delaysMap[action.delay];
resolvedDelay = isFunction$4(configDelay) ? configDelay(ctx, _event.data, meta) : configDelay;
} else {
resolvedDelay = isFunction$4(action.delay) ? action.delay(ctx, _event.data, meta) : action.delay;
}
var resolvedTarget = isFunction$4(action.to) ? action.to(ctx, _event.data, meta) : action.to;
return __assign(__assign({}, action), {
to: resolvedTarget,
_event: resolvedEvent,
event: resolvedEvent.data,
delay: resolvedDelay
});
}
/**
* Sends an event to this machine's parent.
*
* @param event The event to send to the parent machine.
* @param options Options to pass into the send event.
*/
function sendParent(event, options) {
return send(event, __assign(__assign({}, options), {
to: SpecialTargets.Parent
}));
}
/**
* Sends an update event to this machine's parent.
*/
function sendUpdate() {
return sendParent(update);
}
/**
* Sends an event back to the sender of the original event.
*
* @param event The event to send back to the sender
* @param options Options to pass into the send event
*/
function respond(event, options) {
return send(event, __assign(__assign({}, options), {
to: function (_, __, _a) {
var _event = _a._event;
return _event.origin; // TODO: handle when _event.origin is undefined
}
}));
}
var defaultLogExpr = function (context, event) {
return {
context: context,
event: event
};
};
/**
*
* @param expr The expression function to evaluate which will be logged.
* Takes in 2 arguments:
* - `ctx` - the current state context
* - `event` - the event that caused this action to be executed.
* @param label The label to give to the logged expression.
*/
function log(expr, label) {
if (expr === void 0) {
expr = defaultLogExpr;
}
return {
type: log$1,
label: label,
expr: expr
};
}
var resolveLog = function (action, ctx, _event) {
return __assign(__assign({}, action), {
value: isString$4(action.expr) ? action.expr : action.expr(ctx, _event.data, {
_event: _event
})
});
};
/**
* Cancels an in-flight `send(...)` action. A canceled sent action will not
* be executed, nor will its event be sent, unless it has already been sent
* (e.g., if `cancel(...)` is called after the `send(...)` action's `delay`).
*
* @param sendId The `id` of the `send(...)` action to cancel.
*/
var cancel = function (sendId) {
return {
type: cancel$1,
sendId: sendId
};
};
/**
* Starts an activity.
*
* @param activity The activity to start.
*/
function start(activity) {
var activityDef = toActivityDefinition(activity);
return {
type: ActionTypes$1.Start,
activity: activityDef,
exec: undefined
};
}
/**
* Stops an activity.
*
* @param activity The activity to stop.
*/
function stop(activity) {
var activityDef = toActivityDefinition(activity);
return {
type: ActionTypes$1.Stop,
activity: activityDef,
exec: undefined
};
}
/**
* Updates the current context of the machine.
*
* @param assignment An object that represents the partial context to update.
*/
var assign = function (assignment) {
return {
type: assign$1,
assignment: assignment
};
};
/**
* Returns an event type that represents an implicit event that
* is sent after the specified `delay`.
*
* @param delayRef The delay in milliseconds
* @param id The state node ID where this event is handled
*/
function after(delayRef, id) {
var idSuffix = id ? "#" + id : '';
return ActionTypes$1.After + "(" + delayRef + ")" + idSuffix;
}
/**
* Returns an event that represents that a final state node
* has been reached in the parent state node.
*
* @param id The final state node's parent state node `id`
* @param data The data to pass into the event
*/
function done(id, data) {
var type = ActionTypes$1.DoneState + "." + id;
var eventObject = {
type: type,
data: data
};
eventObject.toString = function () {
return type;
};
return eventObject;
}
/**
* Returns an event that represents that an invoked service has terminated.
*
* An invoked service is terminated when it has reached a top-level final state node,
* but not when it is canceled.
*
* @param id The final state node ID
* @param data The data to pass into the event
*/
function doneInvoke(id, data) {
var type = ActionTypes$1.DoneInvoke + "." + id;
var eventObject = {
type: type,
data: data
};
eventObject.toString = function () {
return type;
};
return eventObject;
}
function error(id, data) {
var type = ActionTypes$1.ErrorPlatform + "." + id;
var eventObject = {
type: type,
data: data
};
eventObject.toString = function () {
return type;
};
return eventObject;
}
/**
* Forwards (sends) an event to a specified service.
*
* @param target The target service to forward the event to.
* @param options Options to pass into the send action creator.
*/
function forwardTo(target, options) {
return send(function (_, event) {
return event;
}, __assign(__assign({}, options), {
to: target
}));
}
/**
* Escalates an error by sending it as an event to this machine's parent.
*
* @param errorData The error data to send, or the expression function that
* takes in the `context`, `event`, and `meta`, and returns the error data to send.
* @param options Options to pass into the send action creator.
*/
function escalate(errorData, options) {
return sendParent(function (context, event, meta) {
return {
type: error$1,
data: isFunction$4(errorData) ? errorData(context, event, meta) : errorData
};
}, __assign(__assign({}, options), {
to: SpecialTargets.Parent
}));
}var isLeafNode = function (stateNode) {
return stateNode.type === 'atomic' || stateNode.type === 'final';
};
function getChildren(stateNode) {
return keys(stateNode.states).map(function (key) {
return stateNode.states[key];
});
}
function getAllStateNodes(stateNode) {
var stateNodes = [stateNode];
if (isLeafNode(stateNode)) {
return stateNodes;
}
return stateNodes.concat(flatten$1(getChildren(stateNode).map(getAllStateNodes)));
}
function getConfiguration(prevStateNodes, stateNodes) {
var e_1, _a, e_2, _b, e_3, _c, e_4, _d;
var prevConfiguration = new Set(prevStateNodes);
var prevAdjList = getAdjList(prevConfiguration);
var configuration = new Set(stateNodes);
try {
// add all ancestors
for (var configuration_1 = __values(configuration), configuration_1_1 = configuration_1.next(); !configuration_1_1.done; configuration_1_1 = configuration_1.next()) {
var s = configuration_1_1.value;
var m = s.parent;
while (m && !configuration.has(m)) {
configuration.add(m);
m = m.parent;
}
}
} catch (e_1_1) {
e_1 = {
error: e_1_1
};
} finally {
try {
if (configuration_1_1 && !configuration_1_1.done && (_a = configuration_1.return)) _a.call(configuration_1);
} finally {
if (e_1) throw e_1.error;
}
}
var adjList = getAdjList(configuration);
try {
// add descendants
for (var configuration_2 = __values(configuration), configuration_2_1 = configuration_2.next(); !configuration_2_1.done; configuration_2_1 = configuration_2.next()) {
var s = configuration_2_1.value; // if previously active, add existing child nodes
if (s.type === 'compound' && (!adjList.get(s) || !adjList.get(s).length)) {
if (prevAdjList.get(s)) {
prevAdjList.get(s).forEach(function (sn) {
return configuration.add(sn);
});
} else {
s.initialStateNodes.forEach(function (sn) {
return configuration.add(sn);
});
}
} else {
if (s.type === 'parallel') {
try {
for (var _e = (e_3 = void 0, __values(getChildren(s))), _f = _e.next(); !_f.done; _f = _e.next()) {
var child = _f.value;
if (child.type === 'history') {
continue;
}
if (!configuration.has(child)) {
configuration.add(child);
if (prevAdjList.get(child)) {
prevAdjList.get(child).forEach(function (sn) {
return configuration.add(sn);
});
} else {
child.initialStateNodes.forEach(function (sn) {
return configuration.add(sn);
});
}
}
}
} catch (e_3_1) {
e_3 = {
error: e_3_1
};
} finally {
try {
if (_f && !_f.done && (_c = _e.return)) _c.call(_e);
} finally {
if (e_3) throw e_3.error;
}
}
}
}
}
} catch (e_2_1) {
e_2 = {
error: e_2_1
};
} finally {
try {
if (configuration_2_1 && !configuration_2_1.done && (_b = configuration_2.return)) _b.call(configuration_2);
} finally {
if (e_2) throw e_2.error;
}
}
try {
// add all ancestors
for (var configuration_3 = __values(configuration), configuration_3_1 = configuration_3.next(); !configuration_3_1.done; configuration_3_1 = configuration_3.next()) {
var s = configuration_3_1.value;
var m = s.parent;
while (m && !configuration.has(m)) {
configuration.add(m);
m = m.parent;
}
}
} catch (e_4_1) {
e_4 = {
error: e_4_1
};
} finally {
try {
if (configuration_3_1 && !configuration_3_1.done && (_d = configuration_3.return)) _d.call(configuration_3);
} finally {
if (e_4) throw e_4.error;
}
}
return configuration;
}
function getValueFromAdj(baseNode, adjList) {
var childStateNodes = adjList.get(baseNode);
if (!childStateNodes) {
return {}; // todo: fix?
}
if (baseNode.type === 'compound') {
var childStateNode = childStateNodes[0];
if (childStateNode) {
if (isLeafNode(childStateNode)) {
return childStateNode.key;
}
} else {
return {};
}
}
var stateValue = {};
childStateNodes.forEach(function (csn) {
stateValue[csn.key] = getValueFromAdj(csn, adjList);
});
return stateValue;
}
function getAdjList(configuration) {
var e_5, _a;
var adjList = new Map();
try {
for (var configuration_4 = __values(configuration), configuration_4_1 = configuration_4.next(); !configuration_4_1.done; configuration_4_1 = configuration_4.next()) {
var s = configuration_4_1.value;
if (!adjList.has(s)) {
adjList.set(s, []);
}
if (s.parent) {
if (!adjList.has(s.parent)) {
adjList.set(s.parent, []);
}
adjList.get(s.parent).push(s);
}
}
} catch (e_5_1) {
e_5 = {
error: e_5_1
};
} finally {
try {
if (configuration_4_1 && !configuration_4_1.done && (_a = configuration_4.return)) _a.call(configuration_4);
} finally {
if (e_5) throw e_5.error;
}
}
return adjList;
}
function getValue(rootNode, configuration) {
var config = getConfiguration([rootNode], configuration);
return getValueFromAdj(rootNode, getAdjList(config));
}
function has(iterable, item) {
if (Array.isArray(iterable)) {
return iterable.some(function (member) {
return member === item;
});
}
if (iterable instanceof Set) {
return iterable.has(item);
}
return false; // TODO: fix
}
function nextEvents(configuration) {
return flatten$1(__spread(new Set(configuration.map(function (sn) {
return sn.ownEvents;
}))));
}
function isInFinalState(configuration, stateNode) {
if (stateNode.type === 'compound') {
return getChildren(stateNode).some(function (s) {
return s.type === 'final' && has(configuration, s);
});
}
if (stateNode.type === 'parallel') {
return getChildren(stateNode).every(function (sn) {
return isInFinalState(configuration, sn);
});
}
return false;
}function stateValuesEqual(a, b) {
if (a === b) {
return true;
}
if (a === undefined || b === undefined) {
return false;
}
if (isString$4(a) || isString$4(b)) {
return a === b;
}
var aKeys = keys(a);
var bKeys = keys(b);
return aKeys.length === bKeys.length && aKeys.every(function (key) {
return stateValuesEqual(a[key], b[key]);
});
}
function isState(state) {
if (isString$4(state)) {
return false;
}
return 'value' in state && 'history' in state;
}
function bindActionToState(action, state) {
var exec = action.exec;
var boundAction = __assign(__assign({}, action), {
exec: exec !== undefined ? function () {
return exec(state.context, state.event, {
action: action,
state: state,
_event: state._event
});
} : undefined
});
return boundAction;
}
var State =
/*#__PURE__*/
/** @class */
function () {
/**
* Creates a new State instance.
* @param value The state value
* @param context The extended state
* @param historyValue The tree representing historical values of the state nodes
* @param history The previous state
* @param actions An array of action objects to execute as side-effects
* @param activities A mapping of activities and whether they are started (`true`) or stopped (`false`).
* @param meta
* @param events Internal event queue. Should be empty with run-to-completion semantics.
* @param configuration
*/
function State(config) {
var _this = this;
this.actions = [];
this.activities = EMPTY_ACTIVITY_MAP;
this.meta = {};
this.events = [];
this.value = config.value;
this.context = config.context;
this._event = config._event;
this._sessionid = config._sessionid;
this.event = this._event.data;
this.historyValue = config.historyValue;
this.history = config.history;
this.actions = config.actions || [];
this.activities = config.activities || EMPTY_ACTIVITY_MAP;
this.meta = config.meta || {};
this.events = config.events || [];
this.matches = this.matches.bind(this);
this.toStrings = this.toStrings.bind(this);
this.configuration = config.configuration;
this.transitions = config.transitions;
this.children = config.children;
this.done = !!config.done;
Object.defineProperty(this, 'nextEvents', {
get: function () {
return nextEvents(_this.configuration);
}
});
}
/**
* Creates a new State instance for the given `stateValue` and `context`.
* @param stateValue
* @param context
*/
State.from = function (stateValue, context) {
if (stateValue instanceof State) {
if (stateValue.context !== context) {
return new State({
value: stateValue.value,
context: context,
_event: stateValue._event,
_sessionid: null,
historyValue: stateValue.historyValue,
history: stateValue.history,
actions: [],
activities: stateValue.activities,
meta: {},
events: [],
configuration: [],
transitions: [],
children: {}
});
}
return stateValue;
}
var _event = initEvent;
return new State({
value: stateValue,
context: context,
_event: _event,
_sessionid: null,
historyValue: undefined,
history: undefined,
actions: [],
activities: undefined,
meta: undefined,
events: [],
configuration: [],
transitions: [],
children: {}
});
};
/**
* Creates a new State instance for the given `config`.
* @param config The state config
*/
State.create = function (config) {
return new State(config);
};
/**
* Creates a new `State` instance for the given `stateValue` and `context` with no actions (side-effects).
* @param stateValue
* @param context
*/
State.inert = function (stateValue, context) {
if (stateValue instanceof State) {
if (!stateValue.actions.length) {
return stateValue;
}
var _event = initEvent;
return new State({
value: stateValue.value,
context: context,
_event: _event,
_sessionid: null,
historyValue: stateValue.historyValue,
history: stateValue.history,
activities: stateValue.activities,
configuration: stateValue.configuration,
transitions: [],
children: {}
});
}
return State.from(stateValue, context);
};
/**
* Returns an array of all the string leaf state node paths.
* @param stateValue
* @param delimiter The character(s) that separate each subpath in the string state node path.
*/
State.prototype.toStrings = function (stateValue, delimiter) {
var _this = this;
if (stateValue === void 0) {
stateValue = this.value;
}
if (delimiter === void 0) {
delimiter = '.';
}
if (isString$4(stateValue)) {
return [stateValue];
}
var valueKeys = keys(stateValue);
return valueKeys.concat.apply(valueKeys, __spread(valueKeys.map(function (key) {
return _this.toStrings(stateValue[key], delimiter).map(function (s) {
return key + delimiter + s;
});
})));
};
State.prototype.toJSON = function () {
var _a = this;
_a.configuration;
_a.transitions;
var jsonValues = __rest(_a, ["configuration", "transitions"]);
return jsonValues;
};
/**
* Whether the current state value is a subset of the given parent state value.
* @param parentStateValue
*/
State.prototype.matches = function (parentStateValue) {
return matchesState(parentStateValue, this.value);
};
return State;
}();function createNullActor$1(id) {
return {
id: id,
send: function () {
return void 0;
},
subscribe: function () {
return {
unsubscribe: function () {
return void 0;
}
};
},
toJSON: function () {
return {
id: id
};
}
};
}
/**
* Creates a null actor that is able to be invoked given the provided
* invocation information in its `.meta` value.
*
* @param invokeDefinition The meta information needed to invoke the actor.
*/
function createInvocableActor(invokeDefinition) {
var tempActor = createNullActor$1(invokeDefinition.id);
tempActor.meta = invokeDefinition;
return tempActor;
}
function isActor(item) {
try {
return typeof item.send === 'function';
} catch (e) {
return false;
}
}var NULL_EVENT = '';
var STATE_IDENTIFIER = '#';
var WILDCARD = '*';
var EMPTY_OBJECT = {};
var isStateId = function (str) {
return str[0] === STATE_IDENTIFIER;
};
var createDefaultOptions = function () {
return {
actions: {},
guards: {},
services: {},
activities: {},
delays: {}
};
};
var validateArrayifiedTransitions = function (stateNode, event, transitions) {
var hasNonLastUnguardedTarget = transitions.slice(0, -1).some(function (transition) {
return !('cond' in transition) && !('in' in transition) && (isString$4(transition.target) || isMachine(transition.target));
});
var eventText = event === NULL_EVENT ? 'the transient event' : "event '" + event + "'";
warn(!hasNonLastUnguardedTarget, "One or more transitions for " + eventText + " on state '" + stateNode.id + "' are unreachable. " + "Make sure that the default transition is the last one defined.");
};
var StateNode =
/*#__PURE__*/
/** @class */
function () {
function StateNode(
/**
* The raw config used to create the machine.
*/
config, options,
/**
* The initial extended state
*/
context) {
var _this = this;
this.config = config;
this.context = context;
/**
* The order this state node appears. Corresponds to the implicit SCXML document order.
*/
this.order = -1;
this.__xstatenode = true;
this.__cache = {
events: undefined,
relativeValue: new Map(),
initialStateValue: undefined,
initialState: undefined,
on: undefined,
transitions: undefined,
candidates: {},
delayedTransitions: undefined
};
this.idMap = {};
this.options = Object.assign(createDefaultOptions(), options);
this.parent = this.options._parent;
this.key = this.config.key || this.options._key || this.config.id || '(machine)';
this.machine = this.parent ? this.parent.machine : this;
this.path = this.parent ? this.parent.path.concat(this.key) : [];
this.delimiter = this.config.delimiter || (this.parent ? this.parent.delimiter : STATE_DELIMITER);
this.id = this.config.id || __spread([this.machine.key], this.path).join(this.delimiter);
this.version = this.parent ? this.parent.version : this.config.version;
this.type = this.config.type || (this.config.parallel ? 'parallel' : this.config.states && keys(this.config.states).length ? 'compound' : this.config.history ? 'history' : 'atomic');
this.initial = this.config.initial;
this.states = this.config.states ? mapValues(this.config.states, function (stateConfig, key) {
var _a;
var stateNode = new StateNode(stateConfig, {
_parent: _this,
_key: key
});
Object.assign(_this.idMap, __assign((_a = {}, _a[stateNode.id] = stateNode, _a), stateNode.idMap));
return stateNode;
}) : EMPTY_OBJECT; // Document order
var order = 0;
function dfs(stateNode) {
var e_1, _a;
stateNode.order = order++;
try {
for (var _b = __values(getChildren(stateNode)), _c = _b.next(); !_c.done; _c = _b.next()) {
var child = _c.value;
dfs(child);
}
} catch (e_1_1) {
e_1 = {
error: e_1_1
};
} finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
} finally {
if (e_1) throw e_1.error;
}
}
}
dfs(this); // History config
this.history = this.config.history === true ? 'shallow' : this.config.history || false;
this._transient = !this.config.on ? false : Array.isArray(this.config.on) ? this.config.on.some(function (_a) {
var event = _a.event;
return event === NULL_EVENT;
}) : NULL_EVENT in this.config.on;
this.strict = !!this.config.strict; // TODO: deprecate (entry)
this.onEntry = toArray$1(this.config.entry || this.config.onEntry).map(function (action) {
return toActionObject(action);
}); // TODO: deprecate (exit)
this.onExit = toArray$1(this.config.exit || this.config.onExit).map(function (action) {
return toActionObject(action);
});
this.meta = this.config.meta;
this.data = this.type === 'final' ? this.config.data : undefined;
this.invoke = toArray$1(this.config.invoke).map(function (invokeConfig, i) {
var _a, _b;
if (isMachine(invokeConfig)) {
_this.machine.options.services = __assign((_a = {}, _a[invokeConfig.id] = invokeConfig, _a), _this.machine.options.services);
return {
type: invoke,
src: invokeConfig.id,
id: invokeConfig.id
};
} else if (typeof invokeConfig.src !== 'string') {
var invokeSrc = _this.id + ":invocation[" + i + "]"; // TODO: util function
_this.machine.options.services = __assign((_b = {}, _b[invokeSrc] = invokeConfig.src, _b), _this.machine.options.services);
return __assign(__assign({
type: invoke,
id: invokeSrc
}, invokeConfig), {
src: invokeSrc
});
} else {
return __assign(__assign({}, invokeConfig), {
type: invoke,
id: invokeConfig.id || invokeConfig.src,
src: invokeConfig.src
});
}
});
this.activities = toArray$1(this.config.activities).concat(this.invoke).map(function (activity) {
return toActivityDefinition(activity);
});
this.transition = this.transition.bind(this);
}
StateNode.prototype._init = function () {
if (this.__cache.transitions) {
return;
}
getAllStateNodes(this).forEach(function (stateNode) {
return stateNode.on;
});
};
/**
* Clones this state machine with custom options and context.
*
* @param options Options (actions, guards, activities, services) to recursively merge with the existing options.
* @param context Custom context (will override predefined context)
*/
StateNode.prototype.withConfig = function (options, context) {
if (context === void 0) {
context = this.context;
}
var _a = this.options,
actions = _a.actions,
activities = _a.activities,
guards = _a.guards,
services = _a.services,
delays = _a.delays;
return new StateNode(this.config, {
actions: __assign(__assign({}, actions), options.actions),
activities: __assign(__assign({}, activities), options.activities),
guards: __assign(__assign({}, guards), options.guards),
services: _