Socket
Socket
Sign inDemoInstall

xstate

Package Overview
Dependencies
Maintainers
1
Versions
248
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

xstate - npm Package Compare versions

Comparing version 3.1.0 to 3.1.1

lib/Machine.d.ts

2

dist/xstate.js

@@ -1,1 +0,1 @@

!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.xstate=e():t.xstate=e()}(this,function(){return function(t){function e(i){if(n[i])return n[i].exports;var a=n[i]={i:i,l:!1,exports:{}};return t[i].call(a.exports,a,a.exports,e),a.l=!0,a.exports}var n={};return e.m=t,e.c=n,e.d=function(t,n,i){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:i})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=4)}([function(t,e,n){"use strict";function i(t){try{return"string"==typeof t||"number"==typeof t?""+t:t.type}catch(t){throw new Error("Events must be strings or objects with a string event.type property.")}}function a(t){try{return Array.isArray(t)?t:t.toString().split(".")}catch(e){throw new Error("'"+t+"' is not a valid state path.")}}function r(t){if(t instanceof s.State)return t.value;if("object"==typeof t&&!(t instanceof s.State))return t;var e=a(t);if(1===e.length)return e[0];for(var n={},i=n,r=0;r<e.length-1;r++)r===e.length-2?i[e[r]]=e[r+1]:(i[e[r]]={},i=i[e[r]]);return n}function o(t,e){var n={};return Object.keys(t).forEach(function(i){n[i]=e(t[i],i,t)}),n}Object.defineProperty(e,"__esModule",{value:!0});var s=n(2);e.getEventType=i,e.toStatePath=a,e.toTrie=r,e.mapValues=o},function(t,e,n){"use strict";function i(t){return new l(t)}var a=this&&this.__assign||Object.assign||function(t){for(var e,n=1,i=arguments.length;n<i;n++){e=arguments[n];for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&(t[a]=e[a])}return t};Object.defineProperty(e,"__esModule",{value:!0});var r=n(0),o=n(3);e.matchesState=o.default;var s=n(6);e.mapState=s.default;var c=n(2);e.State=c.State;var u=n(7),f=".",l=function(){function t(e){var n=this;this.config=e,this.__cache={events:void 0,relativeValue:new Map,initialState:void 0},this.key=e.key||"(machine)",this.parent=e.parent,this.machine=this.parent?this.parent.machine:this,this.id=this.parent?this.parent.id+f+this.key:this.key,this.relativeId=this.parent&&this.parent.parent?this.parent.relativeId+f+this.key:this.key,this.initial=e.initial,this.parallel=!!e.parallel,this.states=e.states?r.mapValues(e.states,function(e,i){return new t(a({},e,{key:i,parent:n}))}):{},this.on=e.on,this.strict=!!e.strict,this.onEntry=e.onEntry?[].concat(e.onEntry):void 0,this.onExit=e.onExit?[].concat(e.onExit):void 0,this.data=e.data,this.activities=e.activities}return t.prototype.getStateNodes=function(t){var e=this,n=t instanceof c.State?t.value:r.toTrie(t);if("string"==typeof n){var i=this.states[n].initial;return i?this.getStateNodes((o={},o[n]=i,o)):[this.states[n]]}var a=Object.keys(n);return a.map(function(t){return e.states[t]}).concat(a.map(function(t){return e.states[t].getStateNodes(n[t])}).reduce(function(t,e){return t.concat(e)}));var o},t.prototype.handles=function(t){var e=r.getEventType(t);return!!this.on&&e in this.on},t.prototype.transition=function(t,e,n){if(this.strict){var i=r.getEventType(e);if(-1===this.events.indexOf(i))throw new Error("Machine '"+this.id+"' does not accept event '"+i+"'")}var a=this.transitionStateValue(t,e,n),o=this.stateTransitionToState(a,t);if(!o)return c.State.inert(t);var s,u=o;do{s=u,u=this.stateTransitionToState(this.transitionStateValue(s,"",n),s)}while(u);return s},t.prototype.stateTransitionToState=function(t,e){var n=t.stateValue,i=t.actions,r=t.activities;if(n){var o=e instanceof c.State?e.activities:void 0,s=a({},o,r);return new c.State(n,c.State.from(e),i?i.onExit.concat(i.actions).concat(i.onEntry):[],s,this.getStateNodes(n).reduce(function(t,e){return t[e.id]=e.data,t},{}))}},t.prototype.transitionStateValue=function(t,e,n){var i=this,o=t instanceof c.State?t.history:void 0,s=r.toTrie(t);if("string"==typeof s){if(!this.states[s])throw new Error("State '"+s+"' does not exist on machine '"+this.id+"'");var u=this.states[s];if(!u.states||!u.initial)return u.next(e,o?o.value:void 0,n);var f=u.initialState.value;m={},m[s]=f,s=m}var l=[],h=r.mapValues(s,function(t,a){var r=o?o.value[a]:void 0,s=new c.State(t,r?c.State.from(r):void 0),u=i.states[a],f=u.transitionStateValue(s,e,n);return f.stateValue||l.push(u.next(e,o?o.value:void 0,n)),f});if(Array.prototype.every.call(Object.keys(h),function(t){return void 0===h[t].stateValue})){if(this.parallel)return l.length?l[0]:{stateValue:void 0,actions:{onEntry:[],onExit:[],actions:[]},activities:void 0};var v=Object.keys(h)[0],p=this.states[v].next(e,o?o.value:void 0,n),y=p.stateValue,d=p.actions,E=p.activities,g=h[v].actions,S=h[v].activities,b=a({},S,E);return{stateValue:y,actions:d?g?{onEntry:g.onEntry.concat(d.onEntry),actions:g.actions.concat(d.actions),onExit:g.onExit.concat(d.onExit)}:d:g,activities:b}}this.parallel&&(h=a({},r.mapValues(this.initialState.value,function(t){return{stateValue:t,actions:{onEntry:[],onExit:[],actions:[]},activities:void 0}}),h));var x={onEntry:[],actions:[],onExit:[]},_={};return{stateValue:r.mapValues(h,function(t,e){var n=t.stateValue,i=t.actions,a=t.activities;return i&&(i.onEntry&&(r=x.onEntry).push.apply(r,i.onEntry),i.actions&&(o=x.actions).push.apply(o,i.actions),i.onExit&&(c=x.onExit).push.apply(c,i.onExit)),a&&Object.assign(_,a),n||s[e];var r,o,c}),actions:x,activities:_};var m},t.prototype.next=function(t,e,n){var i=this,o=r.getEventType(t),s={onEntry:[],onExit:[],actions:[]},c={};if(this.onExit&&(s.onExit=this.onExit),this.activities&&this.activities.forEach(function(t){c[r.getEventType(t)]=!1,s.onExit=s.onExit.concat(u.stop(t))}),!this.on||!this.on[o])return{stateValue:void 0,actions:s,activities:c};var l,h=this.on[o];if("string"==typeof h)l=h;else for(var v=Array.isArray(h)?h:Object.keys(h).map(function(t){return a({},h[t],{target:t})}),p=0,y=v;p<y.length;p++){var d=y[p],E=d,g=E.cond,S=E.actions,b=n||{},x="string"==typeof t||"number"==typeof t?{type:t}:t;if(!g||g(b,x)){l=d.target,S&&(s.actions=s.actions.concat(S));break}}if(!l)return{stateValue:void 0,actions:s,activities:c};var _=r.toStatePath(l),m=this.parent,T=e,V=this.key;if(_.forEach(function(e){if(!m||!m.states)throw new Error("Unable to read '"+e+"'");if("$history"===e)if(T)e="object"==typeof T?Object.keys(T)[0]:T;else{if(!m.initial)throw new Error("Cannot read '$history' from state '"+m.id+"': missing 'initial'");e=m.initial}else if(""===e)return s.onExit=[],void(m=m.states[i.key]);if(void 0===(m=m.states[e]))throw new Error("Event '"+t+"' on state '"+V+"' leads to undefined state '"+_.join(f)+"'.");m.onEntry&&(s.onEntry=s.onEntry.concat(m.onEntry)),m.activities&&m.activities.forEach(function(t){c[r.getEventType(t)]=!0,s.onEntry=s.onEntry.concat(u.start(t))}),V=e,T&&(T=T[e])}),!m)throw new Error("no state");for(;m.initial;){if(!m||!m.states)throw new Error("Invalid initial state");m=m.states[m.initial],m.onEntry&&(s.onEntry=s.onEntry.concat(m.onEntry)),m.activities&&m.activities.forEach(function(t){c[r.getEventType(t)]=!0,s.onEntry=s.onEntry.concat(u.start(t))})}return{stateValue:m.getRelativeValue(this.parent),actions:s,activities:c}},Object.defineProperty(t.prototype,"resolvedStateValue",{get:function(){var t=this.key;return this.parallel?(e={},e[t]=r.mapValues(this.states,function(t){return t.resolvedStateValue[t.key]}),e):this.initial?(n={},n[t]=this.states[this.initial].resolvedStateValue,n):t;var e,n},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"initialStateValue",{get:function(){var t=this.__cache.initialState||(this.parallel?r.mapValues(this.states,function(t){return t.initialStateValue}):this.resolvedStateValue[this.key]);return this.__cache.initialState=t,this.__cache.initialState},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"initialState",{get:function(){var t=this.initialStateValue;if(!t)throw new Error("Cannot retrieve initial state from simple state '"+this.id+".'");var e=this.getStateNodes(t).reduce(function(t,e){return e.onEntry?t.concat(e.onEntry):t},[]);return new c.State(t,void 0,e)},enumerable:!0,configurable:!0}),t.prototype.getStates=function(t){var e=this;if("string"==typeof t)return[this.states[t]];var n=[];return Object.keys(t).forEach(function(i){n.push.apply(n,e.states[i].getStates(t[i]))}),n},t.prototype.getState=function(t){var e=r.toStatePath(t);try{return e.reduce(function(t,e){if(!t.states)throw new Error("Cannot retrieve subPath '"+e+"' from node with no states");return t.states[e]},this)}catch(e){throw new Error("State '"+t+" does not exist on machine '"+this.id+"'")}},Object.defineProperty(t.prototype,"events",{get:function(){if(this.__cache.events)return this.__cache.events;var t=this.states,e=new Set(this.on?Object.keys(this.on):void 0);return t&&Object.keys(t).forEach(function(n){var i=t[n];if(i.states)for(var a=0,r=i.events;a<r.length;a++){var o=r[a];e.add(""+o)}}),this.__cache.events=Array.from(e)},enumerable:!0,configurable:!0}),t.prototype.getRelativeValue=function(t){var e=t?this.__cache.relativeValue.get(t):void 0;if(e)return e;for(var n=this.initialStateValue,i=n?(s={},s[this.key]=n,s):this.key,r=this.parent;r&&r!==t;){var o=r.initialStateValue;c={},c[r.key]=r.parallel&&"object"==typeof o&&"object"==typeof i?a({},o,i):i,i=c,r=r.parent}return this.__cache.relativeValue.set(t,i),i;var s,c},t}();e.StateNode=l,e.Machine=i},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=n(5),a=n(0),r=function(){function t(t,e,n,a,r){void 0===n&&(n=[]),void 0===a&&(a=i.EMPTY_ACTIVITY_MAP),void 0===r&&(r={}),this.value=t,this.history=e,this.actions=n,this.activities=a,this.data=r}return t.from=function(e){return e instanceof t?e:new t(a.toTrie(e))},t.inert=function(e){return e instanceof t?e.actions.length?new t(e.value,e.history,[]):e:t.from(e)},t.prototype.toString=function(){if("string"==typeof this.value)return this.value;for(var t=[],e=this.value;;){if("string"==typeof e){t.push(e);break}var n=Object.keys(e),a=n[0];if(n.slice(1).length)return;t.push(a),e=e[a]}return t.join(i.STATE_DELIMITER)},t}();e.State=r},function(t,e,n){"use strict";function i(t,e){var n=a.toTrie(t),r=a.toTrie(e);return"string"==typeof r?"string"==typeof n?r===n:r in n:"string"==typeof n?n in r:Object.keys(n).every(function(t){return t in r&&i(n[t],r[t])})}Object.defineProperty(e,"__esModule",{value:!0});var a=n(0);e.default=i},function(t,e,n){n(1),t.exports=n(1)},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.STATE_DELIMITER=".",e.EMPTY_ACTIVITY_MAP={}},function(t,e,n){"use strict";function i(t,e){var n;return Object.keys(t).forEach(function(t){a.default(t,e)&&(!n||e.length>n.length)&&(n=t)}),t[n]}Object.defineProperty(e,"__esModule",{value:!0});var a=n(3);e.default=i},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=n(0);e.actionTypes={start:"xstate.start",stop:"xstate.stop",raise:"xstate.raise",send:"xstate.send",cancel:"xstate.cancel"};var a=function(t){return function(e){var n="string"==typeof e||"number"==typeof e?{type:e}:e;return{type:t,activity:i.getEventType(e),data:n}}},r=function(t){return"string"==typeof t||"number"==typeof t?{type:t}:t};e.raise=function(t){return{type:e.actionTypes.raise,event:t}},e.send=function(t,n){return{type:e.actionTypes.send,event:r(t),delay:n?n.delay:void 0,id:n&&void 0!==n.id?n.id:i.getEventType(t)}},e.cancel=function(t){return{type:e.actionTypes.cancel,sendId:t}},e.start=a(e.actionTypes.start),e.stop=a(e.actionTypes.stop)}])});
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.xstate=e():t.xstate=e()}(this,function(){return function(t){function e(i){if(n[i])return n[i].exports;var a=n[i]={i:i,l:!1,exports:{}};return t[i].call(a.exports,a,a.exports,e),a.l=!0,a.exports}var n={};return e.m=t,e.c=n,e.d=function(t,n,i){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:i})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=6)}([function(t,e,n){"use strict";function i(t){try{return"string"==typeof t||"number"==typeof t?""+t:t.type}catch(t){throw new Error("Events must be strings or objects with a string event.type property.")}}function a(t){try{return Array.isArray(t)?t:t.toString().split(".")}catch(e){throw new Error("'"+t+"' is not a valid state path.")}}function r(t){if(t instanceof s.State)return t.value;if("object"==typeof t&&!(t instanceof s.State))return t;var e=a(t);if(1===e.length)return e[0];for(var n={},i=n,r=0;r<e.length-1;r++)r===e.length-2?i[e[r]]=e[r+1]:(i[e[r]]={},i=i[e[r]]);return n}function o(t,e){var n={};return Object.keys(t).forEach(function(i){n[i]=e(t[i],i,t)}),n}Object.defineProperty(e,"__esModule",{value:!0});var s=n(2);e.getEventType=i,e.toStatePath=a,e.toStateValue=r,e.mapValues=o,e.path=function(t){return function(e){for(var n=e,i=0,a=t;i<a.length;i++){n=n[a[i]]}return n}}},function(t,e,n){"use strict";function i(t,e){var n=a.toStateValue(t),r=a.toStateValue(e);return"string"==typeof r?"string"==typeof n?r===n:r in n:"string"==typeof n?n in r:Object.keys(n).every(function(t){return t in r&&i(n[t],r[t])})}Object.defineProperty(e,"__esModule",{value:!0});var a=n(0);e.matchesState=i},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=n(7),a=n(0),r=function(){function t(t,e,n,a,r){void 0===n&&(n=[]),void 0===a&&(a=i.EMPTY_ACTIVITY_MAP),void 0===r&&(r={}),this.value=t,this.history=e,this.actions=n,this.activities=a,this.data=r}return t.from=function(e){return e instanceof t?e:new t(a.toStateValue(e))},t.inert=function(e){return e instanceof t?e.actions.length?new t(e.value,e.history,[]):e:t.from(e)},t.prototype.toString=function(){if("string"==typeof this.value)return this.value;for(var t=[],e=this.value;;){if("string"==typeof e){t.push(e);break}var n=Object.keys(e),a=n[0];if(n.slice(1).length)return;t.push(a),e=e[a]}return t.join(i.STATE_DELIMITER)},t}();e.State=r},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=n(1);e.matchesState=i.matchesState;var a=n(8);e.mapState=a.mapState;var r=n(4);e.StateNode=r.StateNode;var o=n(2);e.State=o.State;var s=n(9);e.Machine=s.Machine;var c=n(5);e.actions=c},function(t,e,n){"use strict";function i(t){return new f(t)}var a=this&&this.__assign||Object.assign||function(t){for(var e,n=1,i=arguments.length;n<i;n++){e=arguments[n];for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&(t[a]=e[a])}return t};Object.defineProperty(e,"__esModule",{value:!0});var r=n(0),o=n(1),s=n(2),c=n(5),u=".",f=function(){function t(e){var n=this;this.config=e,this.__cache={events:void 0,relativeValue:new Map,initialState:void 0},this.key=e.key||"(machine)",this.parent=e.parent,this.machine=this.parent?this.parent.machine:this,this.id=this.parent?this.parent.path.concat(this.key).join(u):this.key,this.path=this.parent?this.parent.path.concat(this.key):[this.key],this.initial=e.initial,this.parallel=!!e.parallel,this.states=e.states?r.mapValues(e.states,function(e,i){return new t(a({},e,{key:i,parent:n}))}):{},this.on=e.on,this.strict=!!e.strict,this.onEntry=e.onEntry?[].concat(e.onEntry):void 0,this.onExit=e.onExit?[].concat(e.onExit):void 0,this.data=e.data,this.activities=e.activities}return t.prototype.getStateNodes=function(t){var e=this,n=t instanceof s.State?t.value:r.toStateValue(t);if("string"==typeof n){var i=this.states[n].initial;return i?this.getStateNodes((o={},o[n]=i,o)):[this.states[n]]}var a=Object.keys(n);return a.map(function(t){return e.states[t]}).concat(a.map(function(t){return e.states[t].getStateNodes(n[t])}).reduce(function(t,e){return t.concat(e)}));var o},t.prototype.handles=function(t){var e=r.getEventType(t);return-1!==this.events.indexOf(e)},t.prototype.transition=function(t,e,n){if(this.strict){var i=r.getEventType(e);if(-1===this.events.indexOf(i))throw new Error("Machine '"+this.id+"' does not accept event '"+i+"'")}var a=s.State.from(t),o=this.transitionStateValue(a,e,a,n),c=this.stateTransitionToState(o,a);if(!c)return s.State.inert(a);var u,f=c,h=[];do{h.push.apply(h,f.actions),u=f,f=this.stateTransitionToState(this.transitionStateValue(u,"",f,n),u)}while(f);return u.actions=h,u},t.prototype.stateTransitionToState=function(t,e){var n=t.stateValue,i=t.actions,r=t.activities;if(n){var o=e instanceof s.State?e.activities:void 0,c=a({},o,r);return new s.State(n,s.State.from(e),i?i.onExit.concat(i.actions).concat(i.onEntry):[],c,this.getStateNodes(n).reduce(function(t,e){return void 0!==e.data&&(t[e.id]=e.data),t},{}))}},t.prototype.transitionStateValue=function(t,e,n,i){var o=this,c=t.history,u=t.value;if("string"==typeof u){if(!this.states[u])throw new Error("State '"+u+"' does not exist on machine '"+this.id+"'");var f=this.states[u];if("string"==typeof(u=f.resolvedStateValue))return f.next(e,n,c?c.value:void 0,i)}var h=[],l=r.mapValues(u,function(t,a){var r=c?c.value[a]:void 0,u=new s.State(t,r?s.State.from(r):void 0),f=o.states[a],l=f.transitionStateValue(u,e,n,i);return l.stateValue||h.push(f.next(e,n,c?c.value:void 0,i)),l});if(Array.prototype.every.call(Object.keys(l),function(t){return void 0===l[t].stateValue})){if(this.parallel)return h.length?h[0]:{stateValue:void 0,actions:{onEntry:[],onExit:[],actions:[]},activities:void 0};var v=Object.keys(l)[0],p=this.states[v].next(e,n,c?c.value:void 0,i),y=p.stateValue,d=p.actions,E=p.activities,S=l[v].actions,g=l[v].activities,b=a({},g,E);return{stateValue:y,actions:d?S?{onEntry:S.onEntry.concat(d.onEntry),actions:S.actions.concat(d.actions),onExit:S.onExit.concat(d.onExit)}:d:S,activities:b}}this.parallel&&(l=a({},r.mapValues(this.initialState.value,function(t){return{stateValue:t,actions:{onEntry:[],onExit:[],actions:[]},activities:void 0}}),l));var m={onEntry:[],actions:[],onExit:[]},V={};return{stateValue:r.mapValues(l,function(t,e){var n=t.stateValue,i=t.actions,a=t.activities;return i&&(i.onEntry&&(r=m.onEntry).push.apply(r,i.onEntry),i.actions&&(o=m.actions).push.apply(o,i.actions),i.onExit&&(s=m.onExit).push.apply(s,i.onExit)),a&&Object.assign(V,a),n||u[e];var r,o,s}),actions:m,activities:V}},t.prototype.next=function(t,e,n,i){var s=this,f=r.getEventType(t),h={onEntry:[],onExit:[],actions:[]},l={};if(this.onExit&&(h.onExit=this.onExit),this.activities&&this.activities.forEach(function(t){l[r.getEventType(t)]=!1,h.onExit=h.onExit.concat(c.stop(t))}),!this.on||!this.on[f])return{stateValue:void 0,actions:h,activities:l};var v,p=this.on[f];if("string"==typeof p)v=p;else for(var y=Array.isArray(p)?p:Object.keys(p).map(function(t){return a({},p[t],{target:t})}),d=0,E=y;d<E.length;d++){var S=E[d],g=S,b=g.cond,m=g.in,V=g.actions,_=i||{},j=c.toEventObject(t),x=!m||o.matchesState(r.toStateValue(m),r.path(this.path.slice(1,-2))(e.value));if((!b||b(_,j))&&(!m||x)){v=S.target,V&&(h.actions=h.actions.concat(V));break}}if(!v)return{stateValue:void 0,actions:h,activities:l};var w=r.toStatePath(v),O=this.parent,T=n,k=this.key;if(w.forEach(function(e){if(!O||!O.states)throw new Error("Unable to read '"+e+"'");if("$history"===e)if(0==Object.keys(O.states).length)e="";else if(T)e="object"==typeof T?Object.keys(T)[0]:T;else{if(!O.initial)throw new Error("Cannot read '$history' from state '"+O.id+"': missing 'initial'");e=O.initial}else if(""===e)return h.onExit=[],void(O=O.states[s.key]);if(""!==e&&(O=O.states[e]),void 0===O)throw new Error("Event '"+t+"' on state '"+k+"' leads to undefined state '"+w.join(u)+"'.");O.onEntry&&(h.onEntry=h.onEntry.concat(O.onEntry)),O.activities&&O.activities.forEach(function(t){l[r.getEventType(t)]=!0,h.onEntry=h.onEntry.concat(c.start(t))}),k=e,T&&(T=T[e])}),!O)throw new Error("no state");for(;O.initial;){if(!O||!O.states)throw new Error("Invalid initial state");O=O.states[O.initial],O.onEntry&&(h.onEntry=h.onEntry.concat(O.onEntry)),O.activities&&O.activities.forEach(function(t){l[r.getEventType(t)]=!0,h.onEntry=h.onEntry.concat(c.start(t))})}return{stateValue:O.getRelativeValue(this.parent),actions:h,activities:l}},Object.defineProperty(t.prototype,"resolvedStateValue",{get:function(){var t=this.key;return this.parallel?(e={},e[t]=r.mapValues(this.states,function(t){return t.resolvedStateValue[t.key]}),e):this.initial?(n={},n[t]=this.states[this.initial].resolvedStateValue,n):t;var e,n},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"initialStateValue",{get:function(){var t=this.__cache.initialState||(this.parallel?r.mapValues(this.states,function(t){return t.initialStateValue}):"string"==typeof this.resolvedStateValue?void 0:this.resolvedStateValue[this.key]);return this.__cache.initialState=t,this.__cache.initialState},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"initialState",{get:function(){var t=this.initialStateValue;if(!t)throw new Error("Cannot retrieve initial state from simple state '"+this.id+".'");var e=this.getStateNodes(t).reduce(function(t,e){return e.onEntry?t.concat(e.onEntry):t},[]);return new s.State(t,void 0,e)},enumerable:!0,configurable:!0}),t.prototype.getStates=function(t){var e=this;if("string"==typeof t)return[this.states[t]];var n=[];return Object.keys(t).forEach(function(i){n.push.apply(n,e.states[i].getStates(t[i]))}),n},t.prototype.getState=function(t){var e=r.toStatePath(t);try{return e.reduce(function(t,e){if(!t.states)throw new Error("Cannot retrieve subPath '"+e+"' from node with no states");return t.states[e]},this)}catch(e){throw new Error("State '"+t+" does not exist on machine '"+this.id+"'")}},Object.defineProperty(t.prototype,"events",{get:function(){if(this.__cache.events)return this.__cache.events;var t=this.states,e=new Set(this.on?Object.keys(this.on):void 0);return t&&Object.keys(t).forEach(function(n){var i=t[n];if(i.states)for(var a=0,r=i.events;a<r.length;a++){var o=r[a];e.add(""+o)}}),this.__cache.events=Array.from(e)},enumerable:!0,configurable:!0}),t.prototype.getRelativeValue=function(t){var e=t?this.__cache.relativeValue.get(t):void 0;if(e)return e;for(var n=this.initialStateValue,i=n?(s={},s[this.key]=n,s):this.key,r=this.parent;r&&r!==t;){var o=r.initialStateValue;c={},c[r.key]=r.parallel&&"object"==typeof o&&"object"==typeof i?a({},o,i):i,i=c,r=r.parent}return this.__cache.relativeValue.set(t,i),i;var s,c},t}();e.StateNode=f,e.Machine=i},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=n(0);e.actionTypes={start:"xstate.start",stop:"xstate.stop",raise:"xstate.raise",send:"xstate.send",cancel:"xstate.cancel"};var a=function(t){return function(e){var n="string"==typeof e||"number"==typeof e?{type:e}:e;return{type:t,activity:i.getEventType(e),data:n}}};e.toEventObject=function(t){return"string"==typeof t||"number"==typeof t?{type:t}:t},e.raise=function(t){return{type:e.actionTypes.raise,event:t}},e.send=function(t,n){return{type:e.actionTypes.send,event:e.toEventObject(t),delay:n?n.delay:void 0,id:n&&void 0!==n.id?n.id:i.getEventType(t)}},e.cancel=function(t){return{type:e.actionTypes.cancel,sendId:t}},e.start=a(e.actionTypes.start),e.stop=a(e.actionTypes.stop)},function(t,e,n){n(3),t.exports=n(3)},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.STATE_DELIMITER=".",e.EMPTY_ACTIVITY_MAP={}},function(t,e,n){"use strict";function i(t,e){var n;return Object.keys(t).forEach(function(t){a.matchesState(t,e)&&(!n||e.length>n.length)&&(n=t)}),t[n]}Object.defineProperty(e,"__esModule",{value:!0});var a=n(1);e.mapState=i},function(t,e,n){"use strict";function i(t){return new a.StateNode(t)}Object.defineProperty(e,"__esModule",{value:!0});var a=n(4);e.Machine=i}])});

@@ -1,1 +0,1 @@

!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.xstateUtils=e():t.xstateUtils=e()}(this,function(){return function(t){function e(n){if(r[n])return r[n].exports;var a=r[n]={i:n,l:!1,exports:{}};return t[n].call(a.exports,a,a.exports,e),a.l=!0,a.exports}var r={};return e.m=t,e.c=r,e.d=function(t,r,n){e.o(t,r)||Object.defineProperty(t,r,{configurable:!1,enumerable:!0,get:n})},e.n=function(t){var r=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(r,"a",r),r},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=2)}([function(t,e,r){"use strict";function n(t){var e=t.states;return Object.keys(e).reduce(function(t,r){var a=e[r],i=n(e[r]);return t.push.apply(t,[a].concat(i)),t},[])}function a(t){return"string"==typeof t?[{target:t}]:Array.isArray(t)?t:Object.keys(t).map(function(e){return p({target:e},t[e])})}function i(t,e){if(void 0===e&&(e={}),t.parallel)return Object.keys(t.states).map(function(e){return i(t.states[e])}).reduce(function(t,e){return t.concat(e)},[]);var r=t.states;e[t.key]=!0;var n=Object.keys(r).reduce(function(t,n){if(e[n])return t;var a=r[n];return t.push.apply(t,i(a,e)),e[n]=!0,t},[]);if(!t.on)return n;var o=Object.keys(t.on).reduce(function(r,n){if(!t.on||!t.parent)return r;var o=t.parent,s=t.on[n];return s?(a(s).forEach(function(a){var s=a.target,u=a.cond,c=o.getState(s),f={event:n,source:t,target:c,cond:u};r.push(f),e[s]||(r.push.apply(r,i(c,e)),e[s]=!0)}),r):r},[]);return n.concat(o)}function o(t){function e(a){var i=JSON.stringify(a);if(!r[i]){r[i]={};for(var o=0,s=n;o<s.length;o++){var u=s[o],c=t.transition(a,u);r[i][u]={state:c.value},e(c.value)}}}var r={},n=t.events;return e(t.initialState.value),r}function s(t){function e(t){var n=JSON.stringify(t);i.add(n);for(var o=r[n],s=0,u=Object.keys(o);s<u.length;s++){var c=u[s],f=o[c].state;if(f){var p=JSON.stringify(v.toTrie(f));(!a[p]||a[p].length>a[n].length+1)&&(a[p]=(a[n]||[]).concat([{state:t,event:c}]))}}for(var l=0,y=Object.keys(o);l<y.length;l++){var h=y[l],f=o[h].state;if(f){var p=JSON.stringify(f);i.has(p)||e(f)}}return a}if(!t.states)return l;var r=o(t),n=JSON.stringify(t.initialState.value),a=(s={},s[n]=[],s),i=new Set;return e(t.initialState.value),a;var s}function u(t){var e=s(t);return Object.keys(e).map(function(t){return{state:JSON.parse(t),path:e[t]}})}function c(t){function e(t,o){if(n.add(t),t===o)i[o]=i[o]||[],i[o].push(a.slice());else for(var s=0,u=Object.keys(r[t]);s<u.length;s++){var c=u[s],f=r[t][c].state;if(f){var p=JSON.stringify(f);n.has(p)||(a.push({state:JSON.parse(t),event:c}),e(p,o))}}a.pop(),n.delete(t)}if(!t.states)return l;var r=o(t),n=new Set,a=[],i={},s=JSON.stringify(t.initialState.value);return Object.keys(r).forEach(function(t){e(s,t)}),i}function f(t){var e=c(t);return Object.keys(e).map(function(t){return{state:JSON.parse(t),paths:e[t]}})}var p=this&&this.__assign||Object.assign||function(t){for(var e,r=1,n=arguments.length;r<n;r++){e=arguments[r];for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&(t[a]=e[a])}return t};Object.defineProperty(e,"__esModule",{value:!0});var v=r(1),l={};e.getNodes=n,e.getEdges=i,e.getAdjacencyMap=o,e.getShortestPaths=s,e.getShortestPathsAsArray=u,e.getSimplePaths=c,e.getSimplePathsAsArray=f},function(t,e,r){"use strict";function n(t){try{return"string"==typeof t||"number"==typeof t?""+t:t.type}catch(t){throw new Error("Events must be strings or objects with a string event.type property.")}}function a(t){try{return Array.isArray(t)?t:t.toString().split(".")}catch(e){throw new Error("'"+t+"' is not a valid state path.")}}function i(t){if(t instanceof s.State)return t.value;if("object"==typeof t&&!(t instanceof s.State))return t;var e=a(t);if(1===e.length)return e[0];for(var r={},n=r,i=0;i<e.length-1;i++)i===e.length-2?n[e[i]]=e[i+1]:(n[e[i]]={},n=n[e[i]]);return r}function o(t,e){var r={};return Object.keys(t).forEach(function(n){r[n]=e(t[n],n,t)}),r}Object.defineProperty(e,"__esModule",{value:!0});var s=r(3);e.getEventType=n,e.toStatePath=a,e.toTrie=i,e.mapValues=o},function(t,e,r){r(0),t.exports=r(0)},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=r(4),a=r(1),i=function(){function t(t,e,r,a,i){void 0===r&&(r=[]),void 0===a&&(a=n.EMPTY_ACTIVITY_MAP),void 0===i&&(i={}),this.value=t,this.history=e,this.actions=r,this.activities=a,this.data=i}return t.from=function(e){return e instanceof t?e:new t(a.toTrie(e))},t.inert=function(e){return e instanceof t?e.actions.length?new t(e.value,e.history,[]):e:t.from(e)},t.prototype.toString=function(){if("string"==typeof this.value)return this.value;for(var t=[],e=this.value;;){if("string"==typeof e){t.push(e);break}var r=Object.keys(e),a=r[0];if(r.slice(1).length)return;t.push(a),e=e[a]}return t.join(n.STATE_DELIMITER)},t}();e.State=i},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.STATE_DELIMITER=".",e.EMPTY_ACTIVITY_MAP={}}])});
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.xstateUtils=e():t.xstateUtils=e()}(this,function(){return function(t){function e(r){if(n[r])return n[r].exports;var a=n[r]={i:r,l:!1,exports:{}};return t[r].call(a.exports,a,a.exports,e),a.l=!0,a.exports}var n={};return e.m=t,e.c=n,e.d=function(t,n,r){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:r})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=2)}([function(t,e,n){"use strict";function r(t){var e=t.states;return Object.keys(e).reduce(function(t,n){var a=e[n],i=r(e[n]);return t.push.apply(t,[a].concat(i)),t},[])}function a(t,e){var n=t.on[e];return"string"==typeof n?[{source:t,target:t.parent.getState(n),event:e,actions:[]}]:Array.isArray(n)?n.map(function(n){return{source:t,target:t.parent.getState(n.target),event:e,actions:n.actions||[],cond:n.cond}}):Object.keys(n).map(function(r){return{source:t,target:t.parent.getState(r),event:e,actions:n[r].actions||[],cond:n[r].cond}})}function i(t){var e=[];return t.states&&Object.keys(t.states).forEach(function(n){e.push.apply(e,i(t.states[n]))}),t.on&&Object.keys(t.on).forEach(function(n){e.push.apply(e,a(t,n))}),e}function o(t){function e(a){var i=JSON.stringify(a);if(!n[i]){n[i]={};for(var o=0,s=r;o<s.length;o++){var u=s[o],c=t.transition(a,u);n[i][u]={state:c.value},e(c.value)}}}var n={},r=t.events;return e(t.initialState.value),n}function s(t){function e(t){var r=JSON.stringify(t);i.add(r);for(var o=n[r],s=0,u=Object.keys(o);s<u.length;s++){var c=u[s],f=o[c].state;if(f){var l=JSON.stringify(p.toStateValue(f));(!a[l]||a[l].length>a[r].length+1)&&(a[l]=(a[r]||[]).concat([{state:t,event:c}]))}}for(var v=0,y=Object.keys(o);v<y.length;v++){var h=y[v],f=o[h].state;if(f){var l=JSON.stringify(f);i.has(l)||e(f)}}return a}if(!t.states)return l;var n=o(t),r=JSON.stringify(t.initialState.value),a=(s={},s[r]=[],s),i=new Set;return e(t.initialState.value),a;var s}function u(t){var e=s(t);return Object.keys(e).map(function(t){return{state:JSON.parse(t),path:e[t]}})}function c(t){function e(t,o){if(r.add(t),t===o)i[o]=i[o]||[],i[o].push(a.slice());else for(var s=0,u=Object.keys(n[t]);s<u.length;s++){var c=u[s],f=n[t][c].state;if(f){var p=JSON.stringify(f);r.has(p)||(a.push({state:JSON.parse(t),event:c}),e(p,o))}}a.pop(),r.delete(t)}if(!t.states)return l;var n=o(t),r=new Set,a=[],i={},s=JSON.stringify(t.initialState.value);return Object.keys(n).forEach(function(t){e(s,t)}),i}function f(t){var e=c(t);return Object.keys(e).map(function(t){return{state:JSON.parse(t),paths:e[t]}})}Object.defineProperty(e,"__esModule",{value:!0});var p=n(1),l={};e.getNodes=r,e.getEdges=i,e.getAdjacencyMap=o,e.getShortestPaths=s,e.getShortestPathsAsArray=u,e.getSimplePaths=c,e.getSimplePathsAsArray=f},function(t,e,n){"use strict";function r(t){try{return"string"==typeof t||"number"==typeof t?""+t:t.type}catch(t){throw new Error("Events must be strings or objects with a string event.type property.")}}function a(t){try{return Array.isArray(t)?t:t.toString().split(".")}catch(e){throw new Error("'"+t+"' is not a valid state path.")}}function i(t){if(t instanceof s.State)return t.value;if("object"==typeof t&&!(t instanceof s.State))return t;var e=a(t);if(1===e.length)return e[0];for(var n={},r=n,i=0;i<e.length-1;i++)i===e.length-2?r[e[i]]=e[i+1]:(r[e[i]]={},r=r[e[i]]);return n}function o(t,e){var n={};return Object.keys(t).forEach(function(r){n[r]=e(t[r],r,t)}),n}Object.defineProperty(e,"__esModule",{value:!0});var s=n(3);e.getEventType=r,e.toStatePath=a,e.toStateValue=i,e.mapValues=o,e.path=function(t){return function(e){for(var n=e,r=0,a=t;r<a.length;r++){n=n[a[r]]}return n}}},function(t,e,n){n(0),t.exports=n(0)},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var r=n(4),a=n(1),i=function(){function t(t,e,n,a,i){void 0===n&&(n=[]),void 0===a&&(a=r.EMPTY_ACTIVITY_MAP),void 0===i&&(i={}),this.value=t,this.history=e,this.actions=n,this.activities=a,this.data=i}return t.from=function(e){return e instanceof t?e:new t(a.toStateValue(e))},t.inert=function(e){return e instanceof t?e.actions.length?new t(e.value,e.history,[]):e:t.from(e)},t.prototype.toString=function(){if("string"==typeof this.value)return this.value;for(var t=[],e=this.value;;){if("string"==typeof e){t.push(e);break}var n=Object.keys(e),a=n[0];if(n.slice(1).length)return;t.push(a),e=e[a]}return t.join(r.STATE_DELIMITER)},t}();e.State=i},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.STATE_DELIMITER=".",e.EMPTY_ACTIVITY_MAP={}}])});

@@ -1,2 +0,2 @@

import { ActionObject, Action, ActionType, Event, EventObject } from './types';
import { Action, Event, EventObject, ActivityAction, SendAction, SendActionOptions, CancelAction } from './types';
export declare const actionTypes: {

@@ -9,24 +9,7 @@ start: string;

};
export interface ActivityAction extends ActionObject {
activity: ActionType;
data: {
type: ActionType;
[key: string]: any;
};
}
export declare const toEventObject: (event: Event) => EventObject;
export declare const raise: (eventType: string | number) => EventObject;
export interface SendAction extends ActionObject {
event: EventObject;
delay?: number;
}
export interface SendActionOptions {
delay?: number;
id?: string | number;
}
export declare const send: (event: Event, options?: SendActionOptions | undefined) => SendAction;
export interface CancelAction extends ActionObject {
sendId: string | number;
}
export declare const cancel: (sendId: string | number) => CancelAction;
export declare const start: (activity: Action) => ActivityAction;
export declare const stop: (activity: Action) => ActivityAction;

@@ -23,3 +23,3 @@ "use strict";

}; };
var toEventObject = function (event) {
exports.toEventObject = function (event) {
if (typeof event === 'string' || typeof event === 'number') {

@@ -37,3 +37,3 @@ return { type: event };

type: exports.actionTypes.send,
event: toEventObject(event),
event: exports.toEventObject(event),
delay: options ? options.delay : undefined,

@@ -40,0 +40,0 @@ id: options && options.id !== undefined ? options.id : utils_1.getEventType(event)

import { StateNode } from './index';
import { StateValue, Machine, Event, Condition, Action } from './types';
export interface Edge {
event: string;
source: StateNode;
target: StateNode;
cond?: Condition;
actions: Action[];
}
export interface INodesAndEdges {
nodes: StateNode[];
edges: Edge[];
}
import { Machine, Edge, PathMap, PathItem, PathsItem, PathsMap, AdjacencyMap } from './types';
export declare function getNodes(node: StateNode): StateNode[];
export declare function getEdges(node: StateNode): Edge[];
export interface Segment {
state: StateValue;
event: Event;
}
export interface IPathMap {
[key: string]: Segment[];
}
export interface IPathItem {
state: StateValue;
path: Segment[];
}
export interface IPathsItem {
state: StateValue;
paths: Segment[][];
}
export interface IPathsMap {
[key: string]: Segment[][];
}
export interface ITransitionMap {
state: StateValue | undefined;
}
export interface IAdjacencyMap {
[stateId: string]: Record<string, ITransitionMap>;
}
export declare function getAdjacencyMap(node: Machine): IAdjacencyMap;
export declare function getShortestPaths(machine: Machine): IPathMap;
export declare function getShortestPathsAsArray(machine: Machine): IPathItem[];
export declare function getSimplePaths(machine: Machine): IPathsMap;
export declare function getSimplePathsAsArray(machine: Machine): IPathsItem[];
export declare function getAdjacencyMap(node: Machine): AdjacencyMap;
export declare function getShortestPaths(machine: Machine): PathMap;
export declare function getShortestPathsAsArray(machine: Machine): PathItem[];
export declare function getSimplePaths(machine: Machine): PathsMap;
export declare function getSimplePathsAsArray(machine: Machine): PathsItem[];

@@ -104,3 +104,3 @@ "use strict";

}
var nextStateId = JSON.stringify(utils_1.toTrie(nextStateValue));
var nextStateId = JSON.stringify(utils_1.toStateValue(nextStateValue));
if (!pathMap[nextStateId] ||

@@ -107,0 +107,0 @@ pathMap[nextStateId].length > pathMap[stateId].length + 1) {

@@ -1,43 +0,7 @@

import { Event, StateValue, Transition, Action, StandardMachine, ParallelMachine, SimpleOrCompoundStateNodeConfig, MachineConfig, ParallelMachineConfig, EventType, StandardMachineConfig, StateNodeConfig, Activity } from './types';
import matchesState from './matchesState';
import mapState from './mapState';
import { matchesState } from './matchesState';
import { mapState } from './mapState';
import { StateNode } from './StateNode';
import { State } from './State';
declare class StateNode implements StateNodeConfig {
config: SimpleOrCompoundStateNodeConfig | StandardMachineConfig | ParallelMachineConfig;
key: string;
id: string;
relativeId: string;
initial?: string;
parallel?: boolean;
states: Record<string, StateNode>;
on?: Record<string, Transition | undefined>;
onEntry?: Action[];
onExit?: Action[];
activities?: Activity[];
strict: boolean;
parent?: StateNode;
machine: StateNode;
data: object | undefined;
private __cache;
constructor(config: SimpleOrCompoundStateNodeConfig | StandardMachineConfig | ParallelMachineConfig);
getStateNodes(state: StateValue | State): StateNode[];
handles(event: Event): boolean;
transition(state: StateValue | State, event: Event, extendedState?: any): State;
private stateTransitionToState(stateTransition, prevState);
private transitionStateValue(state, event, extendedState?);
private next(event, history?, extendedState?);
private readonly resolvedStateValue;
private readonly initialStateValue;
readonly initialState: State;
getStates(stateValue: StateValue): StateNode[];
getState(relativeStateId: string | string[]): StateNode | undefined;
readonly events: EventType[];
private getRelativeValue(toNode?);
}
export interface MachineFactory {
(config: MachineConfig | ParallelMachineConfig): StandardMachine | ParallelMachine;
standard: (config: MachineConfig) => StandardMachine;
parallel: (config: ParallelMachineConfig) => ParallelMachine;
}
export declare function Machine(config: MachineConfig | ParallelMachineConfig): StandardMachine | ParallelMachine;
export { StateNode, State, matchesState, mapState };
import { Machine } from './Machine';
import * as actions from './actions';
export { Machine, StateNode, State, matchesState, mapState, actions };
"use strict";
var __assign = (this && this.__assign) || Object.assign || function(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;
};
Object.defineProperty(exports, "__esModule", { value: true });
var utils_1 = require("./utils");
var matchesState_1 = require("./matchesState");
exports.matchesState = matchesState_1.default;
exports.matchesState = matchesState_1.matchesState;
var mapState_1 = require("./mapState");
exports.mapState = mapState_1.default;
exports.mapState = mapState_1.mapState;
var StateNode_1 = require("./StateNode");
exports.StateNode = StateNode_1.StateNode;
var State_1 = require("./State");
exports.State = State_1.State;
var actions_1 = require("./actions");
var STATE_DELIMITER = '.';
var HISTORY_KEY = '$history';
var NULL_EVENT = '';
var StateNode = /** @class */ (function () {
function StateNode(config) {
var _this = this;
this.config = config;
this.__cache = {
events: undefined,
relativeValue: new Map(),
initialState: undefined
};
this.key = config.key || '(machine)';
this.parent = config.parent;
this.machine = this.parent ? this.parent.machine : this;
this.id = this.parent
? this.parent.id + STATE_DELIMITER + this.key
: this.key;
this.relativeId =
this.parent && this.parent.parent
? this.parent.relativeId + STATE_DELIMITER + this.key
: this.key;
this.initial = config.initial;
this.parallel = !!config.parallel;
this.states = (config.states
? utils_1.mapValues(config.states, function (stateConfig, key) {
return new StateNode(__assign({}, stateConfig, { key: key, parent: _this }));
})
: {});
this.on = config.on;
this.strict = !!config.strict;
this.onEntry = config.onEntry
? [].concat(config.onEntry)
: undefined;
this.onExit = config.onExit
? [].concat(config.onExit)
: undefined;
this.data = config.data;
this.activities = config.activities;
}
StateNode.prototype.getStateNodes = function (state) {
var _this = this;
var stateValue = state instanceof State_1.State ? state.value : utils_1.toTrie(state);
if (typeof stateValue === 'string') {
var initialStateValue = this.states[stateValue].initial;
return initialStateValue
? this.getStateNodes((_a = {}, _a[stateValue] = initialStateValue, _a))
: [this.states[stateValue]];
}
var subStateKeys = Object.keys(stateValue);
var subStateNodes = subStateKeys.map(function (subStateKey) { return _this.states[subStateKey]; });
return subStateNodes.concat(subStateKeys
.map(function (subStateKey) {
return _this.states[subStateKey].getStateNodes(stateValue[subStateKey]);
})
.reduce(function (a, b) { return a.concat(b); }));
var _a;
};
StateNode.prototype.handles = function (event) {
var eventType = utils_1.getEventType(event);
if (this.on) {
return eventType in this.on;
}
return false;
};
StateNode.prototype.transition = function (state, event, extendedState) {
if (this.strict) {
var eventType = utils_1.getEventType(event);
if (this.events.indexOf(eventType) === -1) {
throw new Error("Machine '" + this.id + "' does not accept event '" + eventType + "'");
}
}
var stateTransition = this.transitionStateValue(state, event, extendedState);
var nextState = this.stateTransitionToState(stateTransition, state);
if (!nextState) {
return State_1.State.inert(state);
}
// Try transitioning from "transient" states from the NULL_EVENT
// until a state with non-transient transitions is found
var maybeNextState = nextState;
var nextStateFromInternalTransition;
do {
nextStateFromInternalTransition = maybeNextState;
maybeNextState = this.stateTransitionToState(this.transitionStateValue(nextStateFromInternalTransition, NULL_EVENT, extendedState), nextStateFromInternalTransition);
} while (maybeNextState);
// TODO: handle internally raised events
return nextStateFromInternalTransition;
};
StateNode.prototype.stateTransitionToState = function (stateTransition, prevState) {
var nextStateValue = stateTransition.stateValue, nextActions = stateTransition.actions, nextActivities = stateTransition.activities;
if (!nextStateValue) {
return undefined;
}
var prevActivities = prevState instanceof State_1.State ? prevState.activities : undefined;
var activities = __assign({}, prevActivities, nextActivities);
return new State_1.State(
// next state value
nextStateValue,
// history
State_1.State.from(prevState),
// effects
nextActions
? nextActions.onExit
.concat(nextActions.actions)
.concat(nextActions.onEntry)
: [],
// activities
activities,
// data
this.getStateNodes(nextStateValue).reduce(function (data, stateNode) {
data[stateNode.id] = stateNode.data;
return data;
}, {}));
};
StateNode.prototype.transitionStateValue = function (state, event, extendedState) {
var _this = this;
var history = state instanceof State_1.State ? state.history : undefined;
var stateValue = utils_1.toTrie(state);
if (typeof stateValue === 'string') {
if (!this.states[stateValue]) {
throw new Error("State '" + stateValue + "' does not exist on machine '" + this.id + "'");
}
var subStateNode = this.states[stateValue];
if (subStateNode.states && subStateNode.initial) {
// Get the initial state value
var initialStateValue = subStateNode.initialState.value;
stateValue = (_a = {}, _a[stateValue] = initialStateValue, _a);
}
else {
// Transition from the substate
return subStateNode.next(event, history ? history.value : undefined, extendedState);
}
}
// Potential transition tuples from parent state nodes
var potentialStateTransitions = [];
var nextStateValue = utils_1.mapValues(stateValue, function (subStateValue, subStateKey) {
var subHistory = history ? history.value[subStateKey] : undefined;
var subState = new State_1.State(subStateValue, subHistory ? State_1.State.from(subHistory) : undefined);
var subStateNode = _this.states[subStateKey];
var subStateTransition = subStateNode.transitionStateValue(subState, event, extendedState);
if (!subStateTransition.stateValue) {
potentialStateTransitions.push(subStateNode.next(event, history ? history.value : undefined, extendedState));
}
return subStateTransition;
});
if (Array.prototype.every.call(Object.keys(nextStateValue), function (key) {
return nextStateValue[key].stateValue === undefined;
})) {
if (this.parallel) {
if (potentialStateTransitions.length) {
return potentialStateTransitions[0];
}
return {
stateValue: undefined,
actions: { onEntry: [], onExit: [], actions: [] },
activities: undefined
};
}
var subStateKey = Object.keys(nextStateValue)[0];
// try with parent
var _b = this.states[subStateKey].next(event, history ? history.value : undefined, extendedState), parentNextValue = _b.stateValue, parentNextActions = _b.actions, parentActivities = _b.activities;
var nextActions = nextStateValue[subStateKey].actions;
var activities = nextStateValue[subStateKey].activities;
var allActivities = __assign({}, activities, parentActivities);
var allActions = parentNextActions
? nextActions
? {
onEntry: nextActions.onEntry.concat(parentNextActions.onEntry),
actions: nextActions.actions.concat(parentNextActions.actions),
onExit: nextActions.onExit.concat(parentNextActions.onExit)
}
: parentNextActions
: nextActions;
return {
stateValue: parentNextValue,
actions: allActions,
activities: allActivities
};
}
if (this.parallel) {
nextStateValue = __assign({}, utils_1.mapValues(this.initialState.value, function (subStateValue) { return ({
stateValue: subStateValue,
actions: { onEntry: [], onExit: [], actions: [] },
activities: undefined
}); }), nextStateValue);
}
var finalActions = {
onEntry: [],
actions: [],
onExit: []
};
var finalActivities = {};
var finalStateValue = utils_1.mapValues(nextStateValue, function (subStateTransition, key) {
var nextSubStateValue = subStateTransition.stateValue, nextSubActions = subStateTransition.actions, nextSubActivities = subStateTransition.activities;
if (nextSubActions) {
if (nextSubActions.onEntry) {
(_a = finalActions.onEntry).push.apply(_a, nextSubActions.onEntry);
}
if (nextSubActions.actions) {
(_b = finalActions.actions).push.apply(_b, nextSubActions.actions);
}
if (nextSubActions.onExit) {
(_c = finalActions.onExit).push.apply(_c, nextSubActions.onExit);
}
}
if (nextSubActivities) {
Object.assign(finalActivities, nextSubActivities);
}
if (!nextSubStateValue) {
return stateValue[key];
}
return nextSubStateValue;
var _a, _b, _c;
});
return {
stateValue: finalStateValue,
actions: finalActions,
activities: finalActivities
};
var _a;
};
StateNode.prototype.next = function (event, history, extendedState) {
var _this = this;
var eventType = utils_1.getEventType(event);
var actionMap = { onEntry: [], onExit: [], actions: [] };
var activityMap = {};
if (this.onExit) {
actionMap.onExit = this.onExit;
}
if (this.activities) {
this.activities.forEach(function (activity) {
activityMap[utils_1.getEventType(activity)] = false;
actionMap.onExit = actionMap.onExit.concat(actions_1.stop(activity));
});
}
if (!this.on || !this.on[eventType]) {
return {
stateValue: undefined,
actions: actionMap,
activities: activityMap
};
}
var transition = this.on[eventType];
var nextStateString;
if (typeof transition === 'string') {
nextStateString = transition;
}
else {
var candidates = Array.isArray(transition)
? transition
: Object.keys(transition).map(function (key) { return (__assign({}, transition[key], { target: key })); });
for (var _i = 0, candidates_1 = candidates; _i < candidates_1.length; _i++) {
var candidate = candidates_1[_i];
var _a = candidate, cond = _a.cond, transitionActions = _a.actions;
var extendedStateObject = extendedState || {};
var eventObject = typeof event === 'string' || typeof event === 'number'
? { type: event }
: event;
if (!cond || cond(extendedStateObject, eventObject)) {
nextStateString = candidate.target;
if (transitionActions) {
actionMap.actions = actionMap.actions.concat(transitionActions);
}
break;
}
}
}
if (!nextStateString) {
return {
stateValue: undefined,
actions: actionMap,
activities: activityMap
};
}
var nextStatePath = utils_1.toStatePath(nextStateString);
var currentState = this.parent;
var currentHistory = history;
var currentPath = this.key;
nextStatePath.forEach(function (subPath) {
if (!currentState || !currentState.states) {
throw new Error("Unable to read '" + subPath + "'");
}
if (subPath === HISTORY_KEY) {
if (currentHistory) {
subPath =
typeof currentHistory === 'object'
? Object.keys(currentHistory)[0]
: currentHistory;
}
else if (currentState.initial) {
subPath = currentState.initial;
}
else {
throw new Error("Cannot read '" + HISTORY_KEY + "' from state '" + currentState.id + "': missing 'initial'");
}
}
else if (subPath === NULL_EVENT) {
actionMap.onExit = [];
currentState = currentState.states[_this.key];
return;
}
currentState = currentState.states[subPath];
if (currentState === undefined) {
throw new Error("Event '" + event + "' on state '" + currentPath + "' leads to undefined state '" + nextStatePath.join(STATE_DELIMITER) + "'.");
}
if (currentState.onEntry) {
actionMap.onEntry = actionMap.onEntry.concat(currentState.onEntry);
}
if (currentState.activities) {
currentState.activities.forEach(function (activity) {
activityMap[utils_1.getEventType(activity)] = true;
actionMap.onEntry = actionMap.onEntry.concat(actions_1.start(activity));
});
}
currentPath = subPath;
if (currentHistory) {
currentHistory = currentHistory[subPath];
}
});
if (!currentState) {
throw new Error('no state');
}
while (currentState.initial) {
if (!currentState || !currentState.states) {
throw new Error("Invalid initial state");
}
currentState = currentState.states[currentState.initial];
if (currentState.onEntry) {
actionMap.onEntry = actionMap.onEntry.concat(currentState.onEntry);
}
if (currentState.activities) {
currentState.activities.forEach(function (activity) {
activityMap[utils_1.getEventType(activity)] = true;
actionMap.onEntry = actionMap.onEntry.concat(actions_1.start(activity));
});
}
}
return {
stateValue: currentState.getRelativeValue(this.parent),
actions: actionMap,
activities: activityMap
};
};
Object.defineProperty(StateNode.prototype, "resolvedStateValue", {
get: function () {
var key = this.key;
if (this.parallel) {
return _a = {},
_a[key] = utils_1.mapValues(this.states, function (stateNode) { return stateNode.resolvedStateValue[stateNode.key]; }),
_a;
}
if (!this.initial) {
// If leaf node, value is just the state node's key
return key;
}
return _b = {},
_b[key] = this.states[this.initial].resolvedStateValue,
_b;
var _a, _b;
},
enumerable: true,
configurable: true
});
Object.defineProperty(StateNode.prototype, "initialStateValue", {
get: function () {
var initialStateValue = this.__cache.initialState ||
(this.parallel
? utils_1.mapValues(this.states, function (state) { return state.initialStateValue; })
: this.resolvedStateValue[this.key]);
this.__cache.initialState = initialStateValue;
return this.__cache.initialState;
},
enumerable: true,
configurable: true
});
Object.defineProperty(StateNode.prototype, "initialState", {
get: function () {
var initialStateValue = this.initialStateValue;
if (!initialStateValue) {
throw new Error("Cannot retrieve initial state from simple state '" + this.id + ".'");
}
var entryActions = this.getStateNodes(initialStateValue).reduce(function (actions, stateNode) {
return stateNode.onEntry ? actions.concat(stateNode.onEntry) : actions;
}, []);
return new State_1.State(initialStateValue, undefined, entryActions);
},
enumerable: true,
configurable: true
});
StateNode.prototype.getStates = function (stateValue) {
var _this = this;
if (typeof stateValue === 'string') {
return [this.states[stateValue]];
}
var stateNodes = [];
Object.keys(stateValue).forEach(function (key) {
stateNodes.push.apply(stateNodes, _this.states[key].getStates(stateValue[key]));
});
return stateNodes;
};
StateNode.prototype.getState = function (relativeStateId) {
var statePath = utils_1.toStatePath(relativeStateId);
try {
return statePath.reduce(function (subState, subPath) {
if (!subState.states) {
throw new Error("Cannot retrieve subPath '" + subPath + "' from node with no states");
}
return subState.states[subPath];
}, this);
}
catch (e) {
throw new Error("State '" + relativeStateId + " does not exist on machine '" + this.id + "'");
}
};
Object.defineProperty(StateNode.prototype, "events", {
get: function () {
if (this.__cache.events) {
return this.__cache.events;
}
var states = this.states;
var events = new Set(this.on ? Object.keys(this.on) : undefined);
if (states) {
Object.keys(states).forEach(function (stateId) {
var state = states[stateId];
if (state.states) {
for (var _i = 0, _a = state.events; _i < _a.length; _i++) {
var event_1 = _a[_i];
events.add("" + event_1);
}
}
});
}
return (this.__cache.events = Array.from(events));
},
enumerable: true,
configurable: true
});
StateNode.prototype.getRelativeValue = function (toNode) {
var memoizedRelativeValue = toNode
? this.__cache.relativeValue.get(toNode)
: undefined;
if (memoizedRelativeValue) {
return memoizedRelativeValue;
}
var initialStateValue = this.initialStateValue;
var relativeValue = initialStateValue
? (_a = {},
_a[this.key] = initialStateValue,
_a) : this.key;
var currentNode = this.parent;
while (currentNode && currentNode !== toNode) {
var currentInitialState = currentNode.initialStateValue;
relativeValue = (_b = {},
_b[currentNode.key] = currentNode.parallel &&
typeof currentInitialState === 'object' &&
typeof relativeValue === 'object'
? __assign({}, currentInitialState, relativeValue) : relativeValue,
_b);
currentNode = currentNode.parent;
}
this.__cache.relativeValue.set(toNode, relativeValue);
return relativeValue;
var _a, _b;
};
return StateNode;
}());
exports.StateNode = StateNode;
function Machine(config) {
return new StateNode(config);
}
exports.Machine = Machine;
var Machine_1 = require("./Machine");
exports.Machine = Machine_1.Machine;
var actions = require("./actions");
exports.actions = actions;

@@ -1,3 +0,3 @@

export default function mapState(stateMap: {
export declare function mapState(stateMap: {
[stateId: string]: any;
}, stateId: string): any;

@@ -7,3 +7,3 @@ "use strict";

Object.keys(stateMap).forEach(function (mappedStateId) {
if (matchesState_1.default(mappedStateId, stateId) &&
if (matchesState_1.matchesState(mappedStateId, stateId) &&
(!foundStateId || stateId.length > foundStateId.length)) {

@@ -15,2 +15,2 @@ foundStateId = mappedStateId;

}
exports.default = mapState;
exports.mapState = mapState;
import { StateValue } from './types';
export default function matchesState(parentStateId: StateValue, childStateId: StateValue): boolean;
export declare function matchesState(parentStateId: StateValue, childStateId: StateValue): boolean;

@@ -5,4 +5,4 @@ "use strict";

function matchesState(parentStateId, childStateId) {
var parentStateValue = utils_1.toTrie(parentStateId);
var childStateValue = utils_1.toTrie(childStateId);
var parentStateValue = utils_1.toStateValue(parentStateId);
var childStateValue = utils_1.toStateValue(childStateId);
if (typeof childStateValue === 'string') {

@@ -24,2 +24,2 @@ if (typeof parentStateValue === 'string') {

}
exports.default = matchesState;
exports.matchesState = matchesState;
import { Machine } from './types';
export declare function fromMachine(machine: Machine): string;
export declare function toMachine(xml: string): any;

@@ -12,42 +12,4 @@ "use strict";

var xml_js_1 = require("xml-js");
var xstate = require("./index");
var utils_1 = require("./utils");
var pedestrianStates = {
initial: 'walk',
states: {
walk: {
on: {
PED_COUNTDOWN: 'wait'
}
},
wait: {
on: {
PED_COUNTDOWN: 'stop'
}
},
stop: {}
}
};
var lightMachine = xstate.Machine({
key: 'light',
initial: 'green',
states: {
green: {
on: {
TIMER: 'yellow',
POWER_OUTAGE: 'red'
}
},
yellow: {
on: {
TIMER: 'red',
POWER_OUTAGE: 'red'
}
},
red: __assign({ on: {
TIMER: 'green',
POWER_OUTAGE: 'red'
} }, pedestrianStates)
}
});
var actions = require("./actions");
function stateNodeToSCXML(stateNode) {

@@ -186,2 +148,70 @@ var parallel = stateNode.parallel;

exports.fromMachine = fromMachine;
console.log(fromMachine(lightMachine));
function indexedRecord(items, identifier) {
var record = {};
var identifierFn = typeof identifier === 'string' ? function (item) { return item[identifier]; } : identifier;
items.forEach(function (item) {
record[identifierFn(item)] = item;
});
return record;
}
function executableContent(elements) {
var transition = {
actions: []
};
elements.forEach(function (element) {
switch (element.name) {
case 'raise':
transition.actions.push(actions.raise(element.attributes.event));
default:
return;
}
});
return transition;
}
function toConfig(nodeJson) {
var initial = nodeJson.attributes.initial;
var states;
var on;
if (nodeJson.elements) {
var stateElements = nodeJson.elements.filter(function (element) { return element.name === 'state'; });
var transitionElements = nodeJson.elements.filter(function (element) { return element.name === 'transition'; });
var onEntryElement = nodeJson.elements.find(function (element) { return element.name === 'onentry'; });
var onExitElement = nodeJson.elements.find(function (element) { return element.name === 'onexit'; });
states = indexedRecord(stateElements, function (item) { return "" + item.attributes.id; });
on = utils_1.mapValues(indexedRecord(transitionElements, function (item) { return item.attributes.event || ''; }), function (value) {
return [
__assign({ target: value.attributes.target }, value.elements ? executableContent(value.elements) : undefined)
];
});
var onEntry = onEntryElement
? onEntryElement.elements.map(function (element) {
switch (element.name) {
case 'raise':
return actions.raise(element.attributes.event);
default:
return 'not-implemented';
}
})
: undefined;
var onExit = onExitElement
? onExitElement.elements.map(function (element) {
switch (element.name) {
case 'raise':
return actions.raise(element.attributes.event);
default:
return 'not-implemented';
}
})
: undefined;
return __assign({}, initial ? { initial: initial } : undefined, stateElements.length
? { states: utils_1.mapValues(states, toConfig) }
: undefined, transitionElements.length ? { on: on } : undefined, onEntry ? { onEntry: onEntry } : undefined, onExit ? { onExit: onExit } : undefined);
}
return {};
}
function toMachine(xml) {
var json = xml_js_1.xml2js(xml);
var machineElement = json.elements.filter(function (element) { return element.name === 'scxml'; })[0];
return toConfig(machineElement);
}
exports.toMachine = toMachine;

@@ -20,3 +20,3 @@ "use strict";

}
return new State(utils_1.toTrie(stateValue));
return new State(utils_1.toStateValue(stateValue));
};

@@ -23,0 +23,0 @@ State.inert = function (stateValue) {

@@ -1,2 +0,2 @@

import { StateNode } from './index';
import { StateNode } from './StateNode';
import { State } from './State';

@@ -25,2 +25,3 @@ export declare type EventType = string | number;

actions?: Action[];
in?: StateValue;
}

@@ -77,3 +78,2 @@ export interface TargetTransitionConfig extends TransitionConfig {

id: string;
relativeId: string;
initial: string | undefined;

@@ -102,3 +102,2 @@ parallel: boolean;

states: Record<string, StateNode>;
on: never;
onEntry: never;

@@ -134,1 +133,55 @@ onExit: never;

}
export interface ActivityAction extends ActionObject {
activity: ActionType;
data: {
type: ActionType;
[key: string]: any;
};
}
export interface SendAction extends ActionObject {
event: EventObject;
delay?: number;
id: string | number;
}
export interface SendActionOptions {
delay?: number;
id?: string | number;
}
export interface CancelAction extends ActionObject {
sendId: string | number;
}
export interface Edge {
event: string;
source: StateNode;
target: StateNode;
cond?: Condition;
actions: Action[];
}
export interface NodesAndEdges {
nodes: StateNode[];
edges: Edge[];
}
export interface Segment {
state: StateValue;
event: Event;
}
export interface PathMap {
[key: string]: Segment[];
}
export interface PathItem {
state: StateValue;
path: Segment[];
}
export interface PathsItem {
state: StateValue;
paths: Segment[][];
}
export interface PathsMap {
[key: string]: Segment[][];
}
export interface TransitionMap {
state: StateValue | undefined;
}
export interface AdjacencyMap {
[stateId: string]: Record<string, TransitionMap>;
}

@@ -5,3 +5,3 @@ import { State } from './State';

export declare function toStatePath(stateId: string | string[]): string[];
export declare function toTrie(stateValue: State | StateValue): StateValue;
export declare function toStateValue(stateValue: State | StateValue): StateValue;
export declare function mapValues<T, P>(collection: {

@@ -14,1 +14,6 @@ [key: string]: T;

};
/**
* Retrieves a value at the given path.
* @param props The deep path to the prop of the desired value
*/
export declare const path: (props: string[]) => any;

@@ -27,3 +27,3 @@ "use strict";

exports.toStatePath = toStatePath;
function toTrie(stateValue) {
function toStateValue(stateValue) {
if (stateValue instanceof State_1.State) {

@@ -52,3 +52,3 @@ return stateValue.value;

}
exports.toTrie = toTrie;
exports.toStateValue = toStateValue;
function mapValues(collection, iteratee) {

@@ -62,1 +62,13 @@ var result = {};

exports.mapValues = mapValues;
/**
* Retrieves a value at the given path.
* @param props The deep path to the prop of the desired value
*/
exports.path = function (props) { return function (object) {
var result = object;
for (var _i = 0, props_1 = props; _i < props_1.length; _i++) {
var prop = props_1[_i];
result = result[prop];
}
return result;
}; };
{
"name": "xstate",
"version": "3.1.0",
"version": "3.1.1",
"description": "Simple JavaScript Finite State Machines and Statecharts",

@@ -5,0 +5,0 @@ "main": "lib/index.js",

import {
ActionObject,
Action,
ActionType,
Event,
EventType,
EventObject
EventObject,
ActivityAction,
SendAction,
SendActionOptions,
CancelAction
} from './types';

@@ -22,10 +24,2 @@ import { getEventType } from './utils';

export interface ActivityAction extends ActionObject {
activity: ActionType;
data: {
type: ActionType;
[key: string]: any;
};
}
const createActivityAction = (actionType: string) => (

@@ -45,3 +39,3 @@ activity: Action

const toEventObject = (event: Event): EventObject => {
export const toEventObject = (event: Event): EventObject => {
if (typeof event === 'string' || typeof event === 'number') {

@@ -59,11 +53,2 @@ return { type: event };

export interface SendAction extends ActionObject {
event: EventObject;
delay?: number;
}
export interface SendActionOptions {
delay?: number;
id?: string | number;
}
export const send = (event: Event, options?: SendActionOptions): SendAction => {

@@ -78,6 +63,2 @@ return {

export interface CancelAction extends ActionObject {
sendId: string | number;
}
export const cancel = (sendId: string | number): CancelAction => {

@@ -84,0 +65,0 @@ return {

import { StateNode } from './index';
import { toTrie } from './utils';
import { toStateValue } from './utils';
import {
// Transition,
StateValue,
Machine,
Event,
// TargetTransitionConfig,
Condition,
Action
Edge,
Segment,
PathMap,
PathItem,
PathsItem,
PathsMap,
AdjacencyMap
} from './types';
const EMPTY_MAP = {};
export interface Edge {
event: string;
source: StateNode;
target: StateNode;
cond?: Condition;
actions: Action[];
}
export interface INodesAndEdges {
nodes: StateNode[];
edges: Edge[];
}

@@ -95,36 +86,5 @@ export function getNodes(node: StateNode): StateNode[] {

export interface Segment {
state: StateValue;
event: Event;
}
export function getAdjacencyMap(node: Machine): AdjacencyMap {
const adjacency: AdjacencyMap = {};
export interface IPathMap {
[key: string]: Segment[];
}
export interface IPathItem {
state: StateValue;
path: Segment[];
}
export interface IPathsItem {
state: StateValue;
paths: Segment[][];
}
export interface IPathsMap {
[key: string]: Segment[][];
}
export interface ITransitionMap {
state: StateValue | undefined;
}
export interface IAdjacencyMap {
[stateId: string]: Record<string, ITransitionMap>;
}
export function getAdjacencyMap(node: Machine): IAdjacencyMap {
const adjacency: IAdjacencyMap = {};
const events = node.events;

@@ -154,3 +114,3 @@

export function getShortestPaths(machine: Machine): IPathMap {
export function getShortestPaths(machine: Machine): PathMap {
if (!machine.states) {

@@ -161,3 +121,3 @@ return EMPTY_MAP;

const initialStateId = JSON.stringify(machine.initialState.value);
const pathMap: IPathMap = {
const pathMap: PathMap = {
[initialStateId]: []

@@ -167,3 +127,3 @@ };

function util(stateValue: StateValue): IPathMap {
function util(stateValue: StateValue): PathMap {
const stateId = JSON.stringify(stateValue);

@@ -180,3 +140,3 @@ visited.add(stateId);

const nextStateId = JSON.stringify(toTrie(nextStateValue));
const nextStateId = JSON.stringify(toStateValue(nextStateValue));

@@ -218,3 +178,3 @@ if (

export function getShortestPathsAsArray(machine: Machine): IPathItem[] {
export function getShortestPathsAsArray(machine: Machine): PathItem[] {
const result = getShortestPaths(machine);

@@ -227,3 +187,3 @@ return Object.keys(result).map(key => ({

export function getSimplePaths(machine: Machine): IPathsMap {
export function getSimplePaths(machine: Machine): PathsMap {
if (!machine.states) {

@@ -236,3 +196,3 @@ return EMPTY_MAP;

const path: Segment[] = [];
const paths: IPathsMap = {};
const paths: PathsMap = {};

@@ -275,3 +235,3 @@ function util(fromPathId: string, toPathId: string) {

export function getSimplePathsAsArray(machine: Machine): IPathsItem[] {
export function getSimplePathsAsArray(machine: Machine): PathsItem[] {
const result = getSimplePaths(machine);

@@ -278,0 +238,0 @@ return Object.keys(result).map(key => ({

@@ -1,694 +0,8 @@

import { getEventType, toStatePath, toTrie, mapValues } from './utils';
import {
Event,
StateValue,
Transition,
Action,
Machine,
StandardMachine,
ParallelMachine,
SimpleOrCompoundStateNodeConfig,
MachineConfig,
ParallelMachineConfig,
EventType,
EventObject,
ActionMap,
StandardMachineConfig,
TransitionConfig,
ActivityMap,
StateNodeConfig,
Activity,
StateTransition
} from './types';
import matchesState from './matchesState';
import mapState from './mapState';
import { matchesState } from './matchesState';
import { mapState } from './mapState';
import { StateNode } from './StateNode';
import { State } from './State';
import { start, stop } from './actions';
import { Machine } from './Machine';
import * as actions from './actions';
const STATE_DELIMITER = '.';
const HISTORY_KEY = '$history';
const NULL_EVENT = '';
class StateNode implements StateNodeConfig {
public key: string;
public id: string;
public relativeId: string;
public initial?: string;
public parallel?: boolean;
public states: Record<string, StateNode>;
public on?: Record<string, Transition | undefined>;
public onEntry?: Action[];
public onExit?: Action[];
public activities?: Activity[];
public strict: boolean;
public parent?: StateNode;
public machine: StateNode;
public data: object | undefined;
private __cache = {
events: undefined as EventType[] | undefined,
relativeValue: new Map() as Map<StateNode, StateValue>,
initialState: undefined as StateValue | undefined
};
constructor(
public config:
| SimpleOrCompoundStateNodeConfig
| StandardMachineConfig
| ParallelMachineConfig
) {
this.key = config.key || '(machine)';
this.parent = config.parent;
this.machine = this.parent ? this.parent.machine : this;
this.id = this.parent
? this.parent.id + STATE_DELIMITER + this.key
: this.key;
this.relativeId =
this.parent && this.parent.parent
? this.parent.relativeId + STATE_DELIMITER + this.key
: this.key;
this.initial = config.initial;
this.parallel = !!config.parallel;
this.states = (config.states
? mapValues<SimpleOrCompoundStateNodeConfig, StateNode>(
config.states,
(stateConfig, key) =>
new StateNode({
...stateConfig,
key,
parent: this
})
)
: {}) as Record<string, StateNode>;
this.on = config.on;
this.strict = !!config.strict;
this.onEntry = config.onEntry
? ([] as Action[]).concat(config.onEntry)
: undefined;
this.onExit = config.onExit
? ([] as Action[]).concat(config.onExit)
: undefined;
this.data = config.data;
this.activities = config.activities;
}
public getStateNodes(state: StateValue | State): StateNode[] {
const stateValue = state instanceof State ? state.value : toTrie(state);
if (typeof stateValue === 'string') {
const initialStateValue = (this.states[stateValue] as StateNode).initial;
return initialStateValue
? this.getStateNodes({ [stateValue]: initialStateValue })
: [this.states[stateValue]];
}
const subStateKeys = Object.keys(stateValue);
const subStateNodes: StateNode[] = subStateKeys.map(
subStateKey => this.states[subStateKey]
);
return subStateNodes.concat(
subStateKeys
.map(subStateKey => {
return this.states[subStateKey].getStateNodes(
stateValue[subStateKey]
);
})
.reduce((a, b) => a.concat(b))
);
}
public handles(event: Event): boolean {
const eventType = getEventType(event);
if (this.on) {
return eventType in this.on;
}
return false;
}
public transition(
state: StateValue | State,
event: Event,
extendedState?: any
): State {
if (this.strict) {
const eventType = getEventType(event);
if (this.events.indexOf(eventType) === -1) {
throw new Error(
`Machine '${this.id}' does not accept event '${eventType}'`
);
}
}
const stateTransition = this.transitionStateValue(
state,
event,
extendedState
);
const nextState = this.stateTransitionToState(stateTransition, state);
if (!nextState) {
return State.inert(state);
}
// Try transitioning from "transient" states from the NULL_EVENT
// until a state with non-transient transitions is found
let maybeNextState: State | undefined = nextState;
let nextStateFromInternalTransition: State;
do {
nextStateFromInternalTransition = maybeNextState;
maybeNextState = this.stateTransitionToState(
this.transitionStateValue(
nextStateFromInternalTransition,
NULL_EVENT,
extendedState
),
nextStateFromInternalTransition
);
} while (maybeNextState);
// TODO: handle internally raised events
return nextStateFromInternalTransition;
}
private stateTransitionToState(
stateTransition: StateTransition,
prevState: StateValue | State
): State | undefined {
const {
stateValue: nextStateValue,
actions: nextActions,
activities: nextActivities
} = stateTransition;
if (!nextStateValue) {
return undefined;
}
const prevActivities =
prevState instanceof State ? prevState.activities : undefined;
const activities = { ...prevActivities, ...nextActivities };
return new State(
// next state value
nextStateValue,
// history
State.from(prevState),
// effects
nextActions
? nextActions.onExit
.concat(nextActions.actions)
.concat(nextActions.onEntry)
: [],
// activities
activities,
// data
this.getStateNodes(nextStateValue).reduce(
(data, stateNode) => {
data[stateNode.id] = stateNode.data;
return data;
},
{} as Record<string, any>
)
);
}
private transitionStateValue(
state: StateValue | State,
event: Event,
extendedState?: any
): StateTransition {
const history = state instanceof State ? state.history : undefined;
let stateValue = toTrie(state);
if (typeof stateValue === 'string') {
if (!this.states[stateValue]) {
throw new Error(
`State '${stateValue}' does not exist on machine '${this.id}'`
);
}
const subStateNode = this.states[stateValue] as StateNode;
if (subStateNode.states && subStateNode.initial) {
// Get the initial state value
const initialStateValue = subStateNode.initialState.value;
stateValue = { [stateValue]: initialStateValue };
} else {
// Transition from the substate
return subStateNode.next(
event,
history ? history.value : undefined,
extendedState
);
}
}
// Potential transition tuples from parent state nodes
const potentialStateTransitions: StateTransition[] = [];
let nextStateValue = mapValues(stateValue, (subStateValue, subStateKey) => {
const subHistory = history ? history.value[subStateKey] : undefined;
const subState = new State(
subStateValue,
subHistory ? State.from(subHistory) : undefined
);
const subStateNode = this.states[subStateKey];
const subStateTransition = subStateNode.transitionStateValue(
subState,
event,
extendedState
);
if (!subStateTransition.stateValue) {
potentialStateTransitions.push(
subStateNode.next(
event,
history ? history.value : undefined,
extendedState
)
);
}
return subStateTransition;
});
if (
Array.prototype.every.call(Object.keys(nextStateValue), key => {
return nextStateValue[key].stateValue === undefined;
})
) {
if (this.parallel) {
if (potentialStateTransitions.length) {
return potentialStateTransitions[0];
}
return {
stateValue: undefined,
actions: { onEntry: [], onExit: [], actions: [] },
activities: undefined
};
}
const subStateKey = Object.keys(nextStateValue)[0];
// try with parent
const {
stateValue: parentNextValue,
actions: parentNextActions,
activities: parentActivities
} = this.states[subStateKey].next(
event,
history ? history.value : undefined,
extendedState
);
const nextActions = nextStateValue[subStateKey].actions;
const activities = nextStateValue[subStateKey].activities;
const allActivities = {
...activities,
...parentActivities
};
const allActions = parentNextActions
? nextActions
? {
onEntry: [...nextActions.onEntry, ...parentNextActions.onEntry],
actions: [...nextActions.actions, ...parentNextActions.actions],
onExit: [...nextActions.onExit, ...parentNextActions.onExit]
}
: parentNextActions
: nextActions;
return {
stateValue: parentNextValue,
actions: allActions,
activities: allActivities
};
}
if (this.parallel) {
nextStateValue = {
...mapValues(
this.initialState.value as Record<string, StateValue>,
subStateValue => ({
stateValue: subStateValue,
actions: { onEntry: [], onExit: [], actions: [] },
activities: undefined
})
),
...nextStateValue
};
}
const finalActions: ActionMap = {
onEntry: [],
actions: [],
onExit: []
};
const finalActivities: ActivityMap = {};
const finalStateValue = mapValues(
nextStateValue,
(subStateTransition, key) => {
const {
stateValue: nextSubStateValue,
actions: nextSubActions,
activities: nextSubActivities
} = subStateTransition;
if (nextSubActions) {
if (nextSubActions.onEntry) {
finalActions.onEntry.push(...nextSubActions.onEntry);
}
if (nextSubActions.actions) {
finalActions.actions.push(...nextSubActions.actions);
}
if (nextSubActions.onExit) {
finalActions.onExit.push(...nextSubActions.onExit);
}
}
if (nextSubActivities) {
Object.assign(finalActivities, nextSubActivities);
}
if (!nextSubStateValue) {
return stateValue[key];
}
return nextSubStateValue;
}
);
return {
stateValue: finalStateValue,
actions: finalActions,
activities: finalActivities
};
}
private next(
event: Event,
history?: StateValue,
extendedState?: any
): StateTransition {
const eventType = getEventType(event);
const actionMap: ActionMap = { onEntry: [], onExit: [], actions: [] };
const activityMap: ActivityMap = {};
if (this.onExit) {
actionMap.onExit = this.onExit;
}
if (this.activities) {
this.activities.forEach(activity => {
activityMap[getEventType(activity)] = false;
actionMap.onExit = actionMap.onExit.concat(stop(activity));
});
}
if (!this.on || !this.on[eventType]) {
return {
stateValue: undefined,
actions: actionMap,
activities: activityMap
};
}
const transition = this.on[eventType] as Transition;
let nextStateString: string | undefined;
if (typeof transition === 'string') {
nextStateString = transition;
} else {
const candidates = Array.isArray(transition)
? transition
: Object.keys(transition).map(key => ({
...transition[key],
target: key
}));
for (const candidate of candidates) {
const {
cond,
actions: transitionActions
} = candidate as TransitionConfig;
const extendedStateObject = extendedState || {};
const eventObject: EventObject =
typeof event === 'string' || typeof event === 'number'
? { type: event }
: event;
if (!cond || cond(extendedStateObject, eventObject)) {
nextStateString = candidate.target;
if (transitionActions) {
actionMap.actions = actionMap.actions.concat(transitionActions);
}
break;
}
}
}
if (!nextStateString) {
return {
stateValue: undefined,
actions: actionMap,
activities: activityMap
};
}
const nextStatePath = toStatePath(nextStateString);
let currentState = this.parent;
let currentHistory = history;
let currentPath = this.key;
nextStatePath.forEach(subPath => {
if (!currentState || !currentState.states) {
throw new Error(`Unable to read '${subPath}'`);
}
if (subPath === HISTORY_KEY) {
if (currentHistory) {
subPath =
typeof currentHistory === 'object'
? Object.keys(currentHistory)[0]
: currentHistory;
} else if (currentState.initial) {
subPath = currentState.initial;
} else {
throw new Error(
`Cannot read '${HISTORY_KEY}' from state '${currentState.id}': missing 'initial'`
);
}
} else if (subPath === NULL_EVENT) {
actionMap.onExit = [];
currentState = currentState.states[this.key];
return;
}
currentState = currentState.states[subPath];
if (currentState === undefined) {
throw new Error(
`Event '${event}' on state '${currentPath}' leads to undefined state '${nextStatePath.join(
STATE_DELIMITER
)}'.`
);
}
if (currentState.onEntry) {
actionMap.onEntry = actionMap.onEntry.concat(currentState.onEntry);
}
if (currentState.activities) {
currentState.activities.forEach(activity => {
activityMap[getEventType(activity)] = true;
actionMap.onEntry = actionMap.onEntry.concat(start(activity));
});
}
currentPath = subPath;
if (currentHistory) {
currentHistory = currentHistory[subPath];
}
});
if (!currentState) {
throw new Error('no state');
}
while (currentState.initial) {
if (!currentState || !currentState.states) {
throw new Error(`Invalid initial state`);
}
currentState = currentState.states[currentState.initial];
if (currentState.onEntry) {
actionMap.onEntry = actionMap.onEntry.concat(currentState.onEntry);
}
if (currentState.activities) {
currentState.activities.forEach(activity => {
activityMap[getEventType(activity)] = true;
actionMap.onEntry = actionMap.onEntry.concat(start(activity));
});
}
}
return {
stateValue: currentState.getRelativeValue(this.parent),
actions: actionMap,
activities: activityMap
};
}
private get resolvedStateValue(): StateValue {
const { key } = this;
if (this.parallel) {
return {
[key]: mapValues(
this.states,
stateNode => stateNode.resolvedStateValue[stateNode.key]
)
};
}
if (!this.initial) {
// If leaf node, value is just the state node's key
return key;
}
return {
[key]: this.states[this.initial].resolvedStateValue
};
}
private get initialStateValue(): StateValue | undefined {
const initialStateValue =
this.__cache.initialState ||
((this.parallel
? mapValues(
this.states as Record<string, StateNode>,
state => state.initialStateValue
)
: this.resolvedStateValue[this.key]) as StateValue);
this.__cache.initialState = initialStateValue;
return this.__cache.initialState;
}
public get initialState(): State {
const { initialStateValue } = this;
if (!initialStateValue) {
throw new Error(
`Cannot retrieve initial state from simple state '${this.id}.'`
);
}
const entryActions = this.getStateNodes(initialStateValue).reduce(
(actions, stateNode) =>
stateNode.onEntry ? actions.concat(stateNode.onEntry) : actions,
[] as Action[]
);
return new State(initialStateValue, undefined, entryActions);
}
public getStates(stateValue: StateValue): StateNode[] {
if (typeof stateValue === 'string') {
return [this.states[stateValue]];
}
const stateNodes: StateNode[] = [];
Object.keys(stateValue).forEach(key => {
stateNodes.push(...this.states[key].getStates(stateValue[key]));
});
return stateNodes;
}
public getState(relativeStateId: string | string[]): StateNode | undefined {
const statePath = toStatePath(relativeStateId);
try {
return statePath.reduce(
(subState, subPath) => {
if (!subState.states) {
throw new Error(
`Cannot retrieve subPath '${subPath}' from node with no states`
);
}
return subState.states[subPath];
},
this as StateNode
);
} catch (e) {
throw new Error(
`State '${relativeStateId} does not exist on machine '${this.id}'`
);
}
}
get events(): EventType[] {
if (this.__cache.events) {
return this.__cache.events;
}
const { states } = this;
const events = new Set(this.on ? Object.keys(this.on) : undefined);
if (states) {
Object.keys(states).forEach(stateId => {
const state = states[stateId];
if (state.states) {
for (const event of state.events) {
events.add(`${event}`);
}
}
});
}
return (this.__cache.events = Array.from(events));
}
private getRelativeValue(toNode?: StateNode): StateValue {
const memoizedRelativeValue = toNode
? this.__cache.relativeValue.get(toNode)
: undefined;
if (memoizedRelativeValue) {
return memoizedRelativeValue;
}
const initialStateValue = this.initialStateValue;
let relativeValue = initialStateValue
? {
[this.key]: initialStateValue
}
: this.key;
let currentNode: StateNode = this.parent as StateNode;
while (currentNode && currentNode !== toNode) {
const currentInitialState = currentNode.initialStateValue;
relativeValue = {
[currentNode.key]:
currentNode.parallel &&
typeof currentInitialState === 'object' &&
typeof relativeValue === 'object'
? { ...currentInitialState, ...relativeValue }
: relativeValue
};
currentNode = currentNode.parent as StateNode;
}
this.__cache.relativeValue.set(toNode as StateNode, relativeValue);
return relativeValue;
}
}
export interface MachineFactory {
(config: MachineConfig | ParallelMachineConfig):
| StandardMachine
| ParallelMachine;
standard: (config: MachineConfig) => StandardMachine;
parallel: (config: ParallelMachineConfig) => ParallelMachine;
}
export function Machine(
config: MachineConfig | ParallelMachineConfig
): StandardMachine | ParallelMachine {
return new StateNode(config) as StandardMachine | ParallelMachine;
}
export { StateNode, State, matchesState, mapState };
export { Machine, StateNode, State, matchesState, mapState, actions };

@@ -1,4 +0,4 @@

import matchesState from './matchesState';
import { matchesState } from './matchesState';
export default function mapState(
export function mapState(
stateMap: { [stateId: string]: any },

@@ -5,0 +5,0 @@ stateId: string

@@ -1,10 +0,10 @@

import { toTrie } from './utils'; // TODO: change to utils
import { toStateValue } from './utils'; // TODO: change to utils
import { StateValue } from './types';
export default function matchesState(
export function matchesState(
parentStateId: StateValue,
childStateId: StateValue
): boolean {
const parentStateValue = toTrie(parentStateId);
const childStateValue = toTrie(childStateId);
const parentStateValue = toStateValue(parentStateId);
const childStateValue = toStateValue(childStateId);

@@ -11,0 +11,0 @@ if (typeof childStateValue === 'string') {

import { StateValue, Action, ActivityMap } from './types';
import { STATE_DELIMITER, EMPTY_ACTIVITY_MAP } from './constants';
import { toTrie } from './utils';
import { toStateValue } from './utils';

@@ -11,3 +11,3 @@ export class State {

return new State(toTrie(stateValue));
return new State(toStateValue(stateValue));
}

@@ -14,0 +14,0 @@ public static inert(stateValue: State | StateValue): State {

@@ -1,2 +0,2 @@

import { StateNode } from './index';
import { StateNode } from './StateNode';
import { State } from './State';

@@ -32,2 +32,3 @@

actions?: Action[];
in?: StateValue;
}

@@ -100,3 +101,2 @@

id: string;
relativeId: string;
initial: string | undefined;

@@ -128,3 +128,2 @@ parallel: boolean;

states: Record<string, StateNode>;
on: never;
onEntry: never;

@@ -169,1 +168,66 @@ onExit: never;

}
export interface ActivityAction extends ActionObject {
activity: ActionType;
data: {
type: ActionType;
[key: string]: any;
};
}
export interface SendAction extends ActionObject {
event: EventObject;
delay?: number;
id: string | number;
}
export interface SendActionOptions {
delay?: number;
id?: string | number;
}
export interface CancelAction extends ActionObject {
sendId: string | number;
}
export interface Edge {
event: string;
source: StateNode;
target: StateNode;
cond?: Condition;
actions: Action[];
}
export interface NodesAndEdges {
nodes: StateNode[];
edges: Edge[];
}
export interface Segment {
state: StateValue;
event: Event;
}
export interface PathMap {
[key: string]: Segment[];
}
export interface PathItem {
state: StateValue;
path: Segment[];
}
export interface PathsItem {
state: StateValue;
paths: Segment[][];
}
export interface PathsMap {
[key: string]: Segment[][];
}
export interface TransitionMap {
state: StateValue | undefined;
}
export interface AdjacencyMap {
[stateId: string]: Record<string, TransitionMap>;
}

@@ -28,3 +28,3 @@ import { State } from './State';

export function toTrie(stateValue: State | StateValue): StateValue {
export function toStateValue(stateValue: State | StateValue): StateValue {
if (stateValue instanceof State) {

@@ -70,1 +70,17 @@ return stateValue.value;

}
/**
* Retrieves a value at the given path.
* @param props The deep path to the prop of the desired value
*/
export const path = (props: string[]): any => <T extends Record<string, any>>(
object: T
): any => {
let result: Record<string, any> = object;
for (const prop of props) {
result = result[prop];
}
return result;
};

@@ -11,3 +11,9 @@ import { Machine } from '../../src/index';

states: {
C: { on: { 2: 'D' } },
C: {
on: {
2: {
D: { in: 'B.E' }
}
}
},
D: { on: { 1: 'C' } }

@@ -40,3 +46,3 @@ }

1: undefined,
2: { A: 'D', B: 'G' },
2: undefined,
3: { A: 'C', B: 'F' }

@@ -43,0 +49,0 @@ }

@@ -7,3 +7,2 @@ import { assert } from 'chai';

getShortestPaths,
IPathMap,
getSimplePaths,

@@ -14,2 +13,3 @@ getAdjacencyMap,

} from '../src/graph';
import { PathMap } from '../src/types';
// tslint:disable-next-line:no-var-requires

@@ -339,3 +339,3 @@ // import * as util from 'util';

assert.lengthOf(
(getShortestPaths(lightMachine) as IPathMap)[
(getShortestPaths(lightMachine) as PathMap)[
JSON.stringify(lightMachine.initialState.value)

@@ -342,0 +342,0 @@ ],

@@ -47,1 +47,227 @@ import { assert } from 'chai';

});
describe('deep history states', () => {
const historyMachine = Machine({
key: 'history',
initial: 'off',
states: {
off: {
on: {
POWER: 'on.$history',
DEEP_POWER: 'on.$history.$history',
DEEPEST_POWER: 'on.$history.$history.$history'
}
},
on: {
initial: 'first',
states: {
first: {
on: { SWITCH: 'second' }
},
second: {
initial: 'A',
states: {
A: {
on: { INNER: 'B' }
},
B: {
initial: 'P',
states: {
P: {
on: { INNER: 'Q' }
},
Q: {}
}
}
}
}
},
on: {
POWER: 'off'
}
}
}
});
describe('$history', () => {
// on.first -> on.second.A
const state2A = historyMachine.transition({ on: 'first' }, 'SWITCH');
// on.second.A -> on.second.B.P
const state2BP = historyMachine.transition(state2A, 'INNER');
// on.second.B.P -> on.second.B.Q
const state2BQ = historyMachine.transition(state2BP, 'INNER');
it('should go to the shallow history', () => {
// on.second.B.P -> off
const stateOff = historyMachine.transition(state2BP, 'POWER');
assert.equal(
historyMachine.transition(stateOff, 'POWER').toString(),
'on.second.A'
);
});
it('should go to the deep history', () => {
// on.second.B.P -> off
const stateOff = historyMachine.transition(state2BP, 'POWER');
assert.equal(
historyMachine.transition(stateOff, 'DEEP_POWER').toString(),
'on.second.B.P'
);
});
it('should go to the deepest history', () => {
// on.second.B.Q -> off
const stateOff = historyMachine.transition(state2BQ, 'POWER');
assert.equal(
historyMachine.transition(stateOff, 'DEEPEST_POWER').toString(),
'on.second.B.Q'
);
});
it('can go to the shallow histor even when $history.$history is used', () => {
const stateOff = historyMachine.transition(state2A, 'POWER');
assert.equal(
historyMachine.transition(stateOff, 'DEEPEST_POWER').toString(),
'on.second.A'
);
});
});
});
describe('parallel history states', () => {
const historyMachine = Machine({
key: 'parallelhistory',
initial: 'off',
states: {
off: {
on: {
SWITCH: 'on', // go to the initial states
POWER: 'on.$history',
DEEP_POWER: 'on.$history.$history',
DEEPEST_POWER: 'on.$history.$history.$history'
}
},
on: {
parallel: true,
states: {
A: {
initial: 'B',
states: {
B: {
on: { INNER_A: 'C' }
},
C: {
initial: 'D',
states: {
D: {
on: { INNER_A: 'E' }
},
E: {}
}
}
}
},
K: {
initial: 'L',
states: {
L: {
on: { INNER_K: 'M' }
},
M: {
initial: 'N',
states: {
N: {
on: { INNER_K: 'O' }
},
O: {}
}
}
}
}
},
on: {
POWER: 'off'
}
}
}
});
describe('$history', () => {
// on.first -> on.second.A
const stateABKL = historyMachine.transition(
historyMachine.initialState,
'SWITCH'
);
// INNER_A twice
const stateACDKL = historyMachine.transition(stateABKL, 'INNER_A');
const stateACEKL = historyMachine.transition(stateACDKL, 'INNER_A');
// INNER_K twice
const stateACEKMN = historyMachine.transition(stateACEKL, 'INNER_K');
const stateACEKMO = historyMachine.transition(stateACEKMN, 'INNER_K');
it('should ignore parallel state history', () => {
const stateOff = historyMachine.transition(stateACDKL, 'POWER');
assert.deepEqual(historyMachine.transition(stateOff, 'POWER').value, {
on: { A: 'B', K: 'L' }
});
});
it('should remember first level state history', () => {
const stateOff = historyMachine.transition(stateACDKL, 'POWER');
assert.deepEqual(
historyMachine.transition(stateOff, 'DEEP_POWER').value,
{
on: { A: { C: 'D' }, K: 'L' }
}
);
});
it('should remember second level state history', () => {
const stateOff = historyMachine.transition(stateACDKL, 'POWER');
assert.deepEqual(
historyMachine.transition(stateOff, 'DEEPEST_POWER').value,
{
on: { A: { C: 'D' }, K: 'L' }
}
);
});
it('should remember second level state history, ignoring too many levels of $history', () => {
const stateOff = historyMachine.transition(stateACDKL, 'POWER');
assert.deepEqual(
historyMachine.transition(stateOff, 'DEEPEST_POWER').value,
{
on: { A: { C: 'D' }, K: 'L' }
}
);
});
it('should remember three levels of state history', () => {
const stateOff = historyMachine.transition(stateACEKL, 'POWER');
assert.deepEqual(
historyMachine.transition(stateOff, 'DEEPEST_POWER').value,
{
on: { A: { C: 'E' }, K: 'L' }
}
);
});
xit('should re-enter each regions of parallel state correctly', () => {
const stateOff = historyMachine.transition(stateACEKMO, 'POWER');
assert.deepEqual(
historyMachine.transition(stateOff, 'DEEP_POWER').value,
{
on: { A: { C: 'D' }, K: { M: 'N' } }
}
);
});
xit('should retain all regions of parallel state', () => {
const stateOff = historyMachine.transition(stateACEKMO, 'POWER');
assert.deepEqual(
historyMachine.transition(stateOff, 'DEEPEST_POWER').value,
{
on: { A: { C: 'E' }, K: { M: 'O' } }
}
);
});
});
});

@@ -48,2 +48,17 @@ import { assert } from 'chai';

const topLevelMachine = Machine({
initial: 'Hidden',
on: {
CLICKED_CLOSE: 'Hidden'
},
states: {
Hidden: {
on: {
PUBLISH_FAILURE: 'Failure'
}
},
Failure: {}
}
});
describe('machine.states', () => {

@@ -78,2 +93,8 @@ it('should properly register machine states', () => {

});
xit('should listen to events declared at top state', () => {
const actualState = topLevelMachine.transition('Failure', 'CLICKED_CLOSE');
assert.deepEqual(actualState.value, 'Hidden');
});
});

@@ -60,2 +60,30 @@ import { Machine } from '../src/index';

});
it('should carry actions from previous transitions within same step', () => {
const machine = Machine({
initial: 'A',
states: {
A: {
onExit: 'exit_A',
on: {
TIMER: {
T: { actions: ['timer'] }
}
}
},
T: {
on: {
'': [{ target: 'B' }]
}
},
B: {
onEntry: 'enter_B'
}
}
});
const state = machine.transition('A', 'TIMER');
assert.deepEqual(state.actions, ['exit_A', 'timer', 'enter_B']);
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc