@statewalker/fsm 0.14.0 → 0.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index-umd.js CHANGED
@@ -1,4 +1,4 @@
1
- // @statewalker/fsm v0.14.0 https://github.com/statewalker/statewalker-tree Copyright 2022 Mikhail Kotelnikov
1
+ // @statewalker/fsm v0.15.1 https://github.com/statewalker/statewalker-fsm Copyright 2022 Mikhail Kotelnikov
2
2
  (function (global, factory) {
3
3
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@statewalker/tree')) :
4
4
  typeof define === 'function' && define.amd ? define(['exports', '@statewalker/tree'], factory) :
@@ -240,66 +240,6 @@ function newAsyncProcess({
240
240
  return process;
241
241
  }
242
242
 
243
- function initProcess({ config, handler, handleError = console.error }) {
244
- let process;
245
- const before = async (process) => {
246
- process._started = true;
247
- const state = process.current;
248
- handler(state);
249
- await state.init.run();
250
- };
251
- const after = async (process) => {
252
- const state = process.current;
253
- await state.done.run();
254
- };
255
-
256
- process = newAsyncProcess({
257
- config,
258
- before,
259
- after,
260
- newProcess: (descriptor) => {
261
- return {
262
- descriptor,
263
- config,
264
- status: 0,
265
- stack: [],
266
- event: undefined,
267
- current: undefined
268
- };
269
- },
270
- newState: (state) => {
271
- state.init = newStateMethod();
272
- state.done = newStateMethod();
273
- state.dispatch = (...args) => state.process.dispatch(...args);
274
- state.getEvent = () => state.process.event || {};
275
- state.getEventKey = () => state.getEvent().key;
276
- return state;
277
- },
278
- handleError
279
- });
280
- process.dispatch = (key, params = {}) => {
281
- process.next({ key, params });
282
- };
283
- return process;
284
-
285
- function newStateMethod() {
286
- const list = [];
287
- return Object.assign((m) => list.push(m), {
288
- run: async (...args) => {
289
- // We use the index to iterate over the list: the list can be updated by called methods
290
- for (let i = 0; i < list.length; i++) {
291
- try {
292
- list[i] && (await list[i](...args));
293
- } catch (error) {
294
- console.error(error);
295
- await handleError(error);
296
- }
297
- }
298
- }
299
- });
300
- }
301
- }
302
-
303
243
  /**
304
244
  * Returns all possible transitions from the current state of the process.
305
245
  * @param {Object} options - method parameters
@@ -364,7 +304,7 @@ exports.getAllStateKeys = getAllStateKeys;
364
304
  exports.getAllTransitions = getAllTransitions;
365
305
  exports.getStateDescriptor = getStateDescriptor;
366
306
  exports.getTargetStateKey = getTargetStateKey;
367
- exports.initAsyncProcess = initProcess;
307
+ exports.newAsyncProcess = newAsyncProcess;
368
308
  exports.newProcessInstance = newProcessInstance;
369
309
  exports.newSyncProcess = newSyncProcess;
370
310
 
@@ -1,2 +1,2 @@
1
- // @statewalker/fsm v0.14.0 https://github.com/statewalker/statewalker-tree Copyright 2022 Mikhail Kotelnikov
2
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@statewalker/tree")):"function"==typeof define&&define.amd?define(["exports","@statewalker/tree"],t):t(((e="undefined"!=typeof globalThis?globalThis:e||self).statewalker=e.statewalker||{},e.statewalker.fsm=e.statewalker.fsm||{}),e.statewalker.tree)}(this,(function(e,t){"use strict";function n(e={}){const{key:t,transitions:s=[],states:r={},options:o,...c}=e,a={key:t,transitions:{},states:{},options:Object.assign(o||{},c)};for(const e of s){let t,n,s;if(Array.isArray(e))t=e[0],n=e[1],s=e[2];else{const{from:r,event:o,to:c}=e;t=r,n=o,s=c}(a.transitions[t]=a.transitions[t]||{})[n]=s}if(Array.isArray(r))for(const e of r)a.states[e.key]=n(e);else if(r)for(const e of Object.keys(r))a.states[e]=n(r[e]);return a}var s={STATE_ANY:"*",STATE_INITIAL:"",STATE_FINAL:"",EVENT_ANY:"*",EVENT_EMPTY:""};function r(e,t){let n;for(let s=e.stack.length-1;!n&&s>=0;s--){n=(e.stack[s].descriptor.states||{})[t]}return n||{transitions:{},states:{}}}function o(e,t,n){const r=[[t,n],[s.STATE_ANY,n],[t,s.EVENT_ANY],[s.STATE_ANY,s.EVENT_ANY]];let o;for(let t=0,n=r.length;void 0===o&&t<n;t++){const[n,c]=r[t],a=e.transitions[n];a&&(o=a[c],void 0===o&&(o=a[s.EVENT_ANY]))}return void 0!==o?o:s.STATE_FINAL}function c({config:e,descriptor:c,newState:a=(e=>e),newProcess:i=(e=>({descriptor:e,status:0,stack:[],event:void 0,current:void 0}))}){const f=i(c=c||n(e));return[f,()=>{let e,n;if(f.status)if(f.stack.length){const c=f.event.key||s.EVENT_EMPTY;e=o(f.stack[f.stack.length-1].descriptor,f.status&t.MODE.ENTER?s.STATE_INITIAL:f.current?f.current.key:s.STATE_FINAL,c),e&&(n=r(f,e))}else e=s.STATE_FINAL;else n=f.descriptor,e=n.key;return e?a({process:f,key:e,descriptor:n}):null}]}e.KEYS=s,e.buildStateDescriptor=n,e.checkProcessDescriptor=function(e){return function e(t,n=[],r=[]){r=[...r,t.key];const o=Object.assign({key:t.key},function(e){const t={},n={};for(const[s,r]of Object.entries(e.transitions)){t[s]=(t[s]||0)+1;for(const e of Object.values(r))n[e]=(n[e]||0)+1}const r=[],o=[];for(const e of Object.keys(t))e===s.STATE_ANY||e===s.STATE_FINAL||e===s.STATE_INITIAL||e in n||r.push(e);for(const e of Object.keys(n))e===s.STATE_FINAL||e in t||o.push(e);return{unreachableStates:r,deadendStates:o}}(t));if(o.deadendStates.length||o.unreachableStates.length){const e={path:r};n.push(e),o.deadendStates.length&&(e.deadendStates=o.deadendStates),o.unreachableStates.length&&(e.unreachableStates=o.unreachableStates)}for(const s of Object.values(t.states))e(s,n,r);return n}(e)},e.getAllStateKeys=function(e){const t={},n=e=>t[e]=(t[e]||0)+1;return function e(t){n(t.key);for(const[e,s]of Object.entries(t.transitions)){n(e);for(const e of Object.values(s))n(e)}for(const[s,r]of Object.entries(t.states))n(s),e(r)}(e),Object.keys(t).sort()},e.getAllTransitions=function(e){const t=[];let n=e.current?e.current.key:s.STATE_INITIAL;for(let r=e.stack.length-1;r>=0;r--){const o=e.stack[r],c=o.key,a=o.descriptor;for(const e of[n,s.STATE_ANY]){const n=a.transitions[e];if(n)for(const[s,r]of Object.entries(n))t.push([c,e,s,r])}n=c}return t},e.getStateDescriptor=r,e.getTargetStateKey=o,e.initAsyncProcess=function({config:e,handler:n,handleError:s=console.error}){let r;return r=function({config:e,descriptor:n,before:s,after:r,newProcess:o,newState:a,handleError:i=console.error}){const[f,u]=c({config:e,descriptor:n,newProcess:o,newState:a}),l=t.newAsyncTreeWalker(s,r,f);return f.finished=!1,f.next=e=>(f.nextEvent=e,f.running=f.running||Promise.resolve().then((async()=>{try{for(f.event=f.nextEvent,f.nextEvent=void 0;!f.finished&&f.event;)if(f.finished=!await l(u),f.status&t.MODE.EXIT&&f.nextEvent)f.event=f.nextEvent,f.nextEvent=void 0;else if(f.status&t.MODE.LEAF)break}catch(e){i(e)}})).finally((()=>f.running=void 0)).then((()=>!f.finished))),f}({config:e,before:async e=>{e._started=!0;const t=e.current;n(t),await t.init.run()},after:async e=>{const t=e.current;await t.done.run()},newProcess:t=>({descriptor:t,config:e,status:0,stack:[],event:void 0,current:void 0}),newState:e=>(e.init=o(),e.done=o(),e.dispatch=(...t)=>e.process.dispatch(...t),e.getEvent=()=>e.process.event||{},e.getEventKey=()=>e.getEvent().key,e),handleError:s}),r.dispatch=(e,t={})=>{r.next({key:e,params:t})},r;function o(){const e=[];return Object.assign((t=>e.push(t)),{run:async(...t)=>{for(let n=0;n<e.length;n++)try{e[n]&&await e[n](...t)}catch(e){console.error(e),await s(e)}}})}},e.newProcessInstance=c,e.newSyncProcess=function({config:e,descriptor:n,before:s,after:r,newProcess:o,newState:a}){const[i,f]=c({config:e,descriptor:n,newProcess:o,newState:a}),u=t.newTreeWalker(s,r,i);return i.dispatch=i.next=e=>{for("string"==typeof e&&(e={key:e}),i.event=e;i.event;){if(!u(f))return!1;if(i.status&t.MODE.LEAF)return!0}},i},Object.defineProperty(e,"__esModule",{value:!0})}));
1
+ // @statewalker/fsm v0.15.1 https://github.com/statewalker/statewalker-fsm Copyright 2022 Mikhail Kotelnikov
2
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@statewalker/tree")):"function"==typeof define&&define.amd?define(["exports","@statewalker/tree"],t):t(((e="undefined"!=typeof globalThis?globalThis:e||self).statewalker=e.statewalker||{},e.statewalker.fsm=e.statewalker.fsm||{}),e.statewalker.tree)}(this,(function(e,t){"use strict";function n(e={}){const{key:t,transitions:s=[],states:r={},options:o,...c}=e,i={key:t,transitions:{},states:{},options:Object.assign(o||{},c)};for(const e of s){let t,n,s;if(Array.isArray(e))t=e[0],n=e[1],s=e[2];else{const{from:r,event:o,to:c}=e;t=r,n=o,s=c}(i.transitions[t]=i.transitions[t]||{})[n]=s}if(Array.isArray(r))for(const e of r)i.states[e.key]=n(e);else if(r)for(const e of Object.keys(r))i.states[e]=n(r[e]);return i}var s={STATE_ANY:"*",STATE_INITIAL:"",STATE_FINAL:"",EVENT_ANY:"*",EVENT_EMPTY:""};function r(e,t){let n;for(let s=e.stack.length-1;!n&&s>=0;s--){n=(e.stack[s].descriptor.states||{})[t]}return n||{transitions:{},states:{}}}function o(e,t,n){const r=[[t,n],[s.STATE_ANY,n],[t,s.EVENT_ANY],[s.STATE_ANY,s.EVENT_ANY]];let o;for(let t=0,n=r.length;void 0===o&&t<n;t++){const[n,c]=r[t],i=e.transitions[n];i&&(o=i[c],void 0===o&&(o=i[s.EVENT_ANY]))}return void 0!==o?o:s.STATE_FINAL}function c({config:e,descriptor:c,newState:i=(e=>e),newProcess:a=(e=>({descriptor:e,status:0,stack:[],event:void 0,current:void 0}))}){const f=a(c=c||n(e));return[f,()=>{let e,n;if(f.status)if(f.stack.length){const c=f.event.key||s.EVENT_EMPTY;e=o(f.stack[f.stack.length-1].descriptor,f.status&t.MODE.ENTER?s.STATE_INITIAL:f.current?f.current.key:s.STATE_FINAL,c),e&&(n=r(f,e))}else e=s.STATE_FINAL;else n=f.descriptor,e=n.key;return e?i({process:f,key:e,descriptor:n}):null}]}e.KEYS=s,e.buildStateDescriptor=n,e.checkProcessDescriptor=function(e){return function e(t,n=[],r=[]){r=[...r,t.key];const o=Object.assign({key:t.key},function(e){const t={},n={};for(const[s,r]of Object.entries(e.transitions)){t[s]=(t[s]||0)+1;for(const e of Object.values(r))n[e]=(n[e]||0)+1}const r=[],o=[];for(const e of Object.keys(t))e===s.STATE_ANY||e===s.STATE_FINAL||e===s.STATE_INITIAL||e in n||r.push(e);for(const e of Object.keys(n))e===s.STATE_FINAL||e in t||o.push(e);return{unreachableStates:r,deadendStates:o}}(t));if(o.deadendStates.length||o.unreachableStates.length){const e={path:r};n.push(e),o.deadendStates.length&&(e.deadendStates=o.deadendStates),o.unreachableStates.length&&(e.unreachableStates=o.unreachableStates)}for(const s of Object.values(t.states))e(s,n,r);return n}(e)},e.getAllStateKeys=function(e){const t={},n=e=>t[e]=(t[e]||0)+1;return function e(t){n(t.key);for(const[e,s]of Object.entries(t.transitions)){n(e);for(const e of Object.values(s))n(e)}for(const[s,r]of Object.entries(t.states))n(s),e(r)}(e),Object.keys(t).sort()},e.getAllTransitions=function(e){const t=[];let n=e.current?e.current.key:s.STATE_INITIAL;for(let r=e.stack.length-1;r>=0;r--){const o=e.stack[r],c=o.key,i=o.descriptor;for(const e of[n,s.STATE_ANY]){const n=i.transitions[e];if(n)for(const[s,r]of Object.entries(n))t.push([c,e,s,r])}n=c}return t},e.getStateDescriptor=r,e.getTargetStateKey=o,e.newAsyncProcess=function({config:e,descriptor:n,before:s,after:r,newProcess:o,newState:i,handleError:a=console.error}){const[f,u]=c({config:e,descriptor:n,newProcess:o,newState:i}),l=t.newAsyncTreeWalker(s,r,f);return f.finished=!1,f.next=e=>(f.nextEvent=e,f.running=f.running||Promise.resolve().then((async()=>{try{for(f.event=f.nextEvent,f.nextEvent=void 0;!f.finished&&f.event;)if(f.finished=!await l(u),f.status&t.MODE.EXIT&&f.nextEvent)f.event=f.nextEvent,f.nextEvent=void 0;else if(f.status&t.MODE.LEAF)break}catch(e){a(e)}})).finally((()=>f.running=void 0)).then((()=>!f.finished))),f},e.newProcessInstance=c,e.newSyncProcess=function({config:e,descriptor:n,before:s,after:r,newProcess:o,newState:i}){const[a,f]=c({config:e,descriptor:n,newProcess:o,newState:i}),u=t.newTreeWalker(s,r,a);return a.dispatch=a.next=e=>{for("string"==typeof e&&(e={key:e}),a.event=e;a.event;){if(!u(f))return!1;if(a.status&t.MODE.LEAF)return!0}},a},Object.defineProperty(e,"__esModule",{value:!0})}));
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- // @statewalker/fsm v0.14.0 https://github.com/statewalker/statewalker-tree Copyright 2022 Mikhail Kotelnikov
1
+ // @statewalker/fsm v0.15.1 https://github.com/statewalker/statewalker-fsm Copyright 2022 Mikhail Kotelnikov
2
2
  import { MODE, newAsyncTreeWalker, newTreeWalker } from '@statewalker/tree';
3
3
 
4
4
  function buildStateDescriptor(config = {}) {
@@ -236,66 +236,6 @@ function newAsyncProcess({
236
236
  return process;
237
237
  }
238
238
 
239
- function initProcess({ config, handler, handleError = console.error }) {
240
- let process;
241
- const before = async (process) => {
242
- process._started = true;
243
- const state = process.current;
244
- handler(state);
245
- await state.init.run();
246
- };
247
- const after = async (process) => {
248
- const state = process.current;
249
- await state.done.run();
250
- };
251
-
252
- process = newAsyncProcess({
253
- config,
254
- before,
255
- after,
256
- newProcess: (descriptor) => {
257
- return {
258
- descriptor,
259
- config,
260
- status: 0,
261
- stack: [],
262
- event: undefined,
263
- current: undefined
264
- };
265
- },
266
- newState: (state) => {
267
- state.init = newStateMethod();
268
- state.done = newStateMethod();
269
- state.dispatch = (...args) => state.process.dispatch(...args);
270
- state.getEvent = () => state.process.event || {};
271
- state.getEventKey = () => state.getEvent().key;
272
- return state;
273
- },
274
- handleError
275
- });
276
- process.dispatch = (key, params = {}) => {
277
- process.next({ key, params });
278
- };
279
- return process;
280
-
281
- function newStateMethod() {
282
- const list = [];
283
- return Object.assign((m) => list.push(m), {
284
- run: async (...args) => {
285
- // We use the index to iterate over the list: the list can be updated by called methods
286
- for (let i = 0; i < list.length; i++) {
287
- try {
288
- list[i] && (await list[i](...args));
289
- } catch (error) {
290
- console.error(error);
291
- await handleError(error);
292
- }
293
- }
294
- }
295
- });
296
- }
297
- }
298
-
299
239
  /**
300
240
  * Returns all possible transitions from the current state of the process.
301
241
  * @param {Object} options - method parameters
@@ -353,4 +293,4 @@ function newSyncProcess({
353
293
  return process;
354
294
  }
355
295
 
356
- export { KEYS, buildStateDescriptor, checkProcessDescriptor, getAllStateKeys, getAllTransitions, getStateDescriptor, getTargetStateKey, initProcess as initAsyncProcess, newProcessInstance, newSyncProcess };
296
+ export { KEYS, buildStateDescriptor, checkProcessDescriptor, getAllStateKeys, getAllTransitions, getStateDescriptor, getTargetStateKey, newAsyncProcess, newProcessInstance, newSyncProcess };
package/dist/index.min.js CHANGED
@@ -1,2 +1,2 @@
1
- // @statewalker/fsm v0.14.0 https://github.com/statewalker/statewalker-tree Copyright 2022 Mikhail Kotelnikov
2
- import{MODE as t,newAsyncTreeWalker as e,newTreeWalker as n}from"@statewalker/tree";function s(t={}){const{key:e,transitions:n=[],states:r={},options:o,...c}=t,i={key:e,transitions:{},states:{},options:Object.assign(o||{},c)};for(const t of n){let e,n,s;if(Array.isArray(t))e=t[0],n=t[1],s=t[2];else{const{from:r,event:o,to:c}=t;e=r,n=o,s=c}(i.transitions[e]=i.transitions[e]||{})[n]=s}if(Array.isArray(r))for(const t of r)i.states[t.key]=s(t);else if(r)for(const t of Object.keys(r))i.states[t]=s(r[t]);return i}var r={STATE_ANY:"*",STATE_INITIAL:"",STATE_FINAL:"",EVENT_ANY:"*",EVENT_EMPTY:""};function o(t){return function t(e,n=[],s=[]){s=[...s,e.key];const o=Object.assign({key:e.key},function(t){const e={},n={};for(const[s,r]of Object.entries(t.transitions)){e[s]=(e[s]||0)+1;for(const t of Object.values(r))n[t]=(n[t]||0)+1}const s=[],o=[];for(const t of Object.keys(e))t===r.STATE_ANY||t===r.STATE_FINAL||t===r.STATE_INITIAL||t in n||s.push(t);for(const t of Object.keys(n))t===r.STATE_FINAL||t in e||o.push(t);return{unreachableStates:s,deadendStates:o}}(e));if(o.deadendStates.length||o.unreachableStates.length){const t={path:s};n.push(t),o.deadendStates.length&&(t.deadendStates=o.deadendStates),o.unreachableStates.length&&(t.unreachableStates=o.unreachableStates)}for(const r of Object.values(e.states))t(r,n,s);return n}(t)}function c(t,e){let n;for(let s=t.stack.length-1;!n&&s>=0;s--){n=(t.stack[s].descriptor.states||{})[e]}return n||{transitions:{},states:{}}}function i(t){const e={},n=t=>e[t]=(e[t]||0)+1;return function t(e){n(e.key);for(const[t,s]of Object.entries(e.transitions)){n(t);for(const t of Object.values(s))n(t)}for(const[s,r]of Object.entries(e.states))n(s),t(r)}(t),Object.keys(e).sort()}function a(t,e,n){const s=[[e,n],[r.STATE_ANY,n],[e,r.EVENT_ANY],[r.STATE_ANY,r.EVENT_ANY]];let o;for(let e=0,n=s.length;void 0===o&&e<n;e++){const[n,c]=s[e],i=t.transitions[n];i&&(o=i[c],void 0===o&&(o=i[r.EVENT_ANY]))}return void 0!==o?o:r.STATE_FINAL}function f({config:e,descriptor:n,newState:o=(t=>t),newProcess:i=(t=>({descriptor:t,status:0,stack:[],event:void 0,current:void 0}))}){const f=i(n=n||s(e));return[f,()=>{let e,n;if(f.status)if(f.stack.length){const s=f.event.key||r.EVENT_EMPTY;e=a(f.stack[f.stack.length-1].descriptor,f.status&t.ENTER?r.STATE_INITIAL:f.current?f.current.key:r.STATE_FINAL,s),e&&(n=c(f,e))}else e=r.STATE_FINAL;else n=f.descriptor,e=n.key;return e?o({process:f,key:e,descriptor:n}):null}]}function u({config:n,handler:s,handleError:r=console.error}){let o;return o=function({config:n,descriptor:s,before:r,after:o,newProcess:c,newState:i,handleError:a=console.error}){const[u,d]=f({config:n,descriptor:s,newProcess:c,newState:i}),l=e(r,o,u);return u.finished=!1,u.next=e=>(u.nextEvent=e,u.running=u.running||Promise.resolve().then((async()=>{try{for(u.event=u.nextEvent,u.nextEvent=void 0;!u.finished&&u.event;)if(u.finished=!await l(d),u.status&t.EXIT&&u.nextEvent)u.event=u.nextEvent,u.nextEvent=void 0;else if(u.status&t.LEAF)break}catch(t){a(t)}})).finally((()=>u.running=void 0)).then((()=>!u.finished))),u}({config:n,before:async t=>{t._started=!0;const e=t.current;s(e),await e.init.run()},after:async t=>{const e=t.current;await e.done.run()},newProcess:t=>({descriptor:t,config:n,status:0,stack:[],event:void 0,current:void 0}),newState:t=>(t.init=c(),t.done=c(),t.dispatch=(...e)=>t.process.dispatch(...e),t.getEvent=()=>t.process.event||{},t.getEventKey=()=>t.getEvent().key,t),handleError:r}),o.dispatch=(t,e={})=>{o.next({key:t,params:e})},o;function c(){const t=[];return Object.assign((e=>t.push(e)),{run:async(...e)=>{for(let n=0;n<t.length;n++)try{t[n]&&await t[n](...e)}catch(t){console.error(t),await r(t)}}})}}function d(t){const e=[];let n=t.current?t.current.key:r.STATE_INITIAL;for(let s=t.stack.length-1;s>=0;s--){const o=t.stack[s],c=o.key,i=o.descriptor;for(const t of[n,r.STATE_ANY]){const n=i.transitions[t];if(n)for(const[s,r]of Object.entries(n))e.push([c,t,s,r])}n=c}return e}function l({config:e,descriptor:s,before:r,after:o,newProcess:c,newState:i}){const[a,u]=f({config:e,descriptor:s,newProcess:c,newState:i}),d=n(r,o,a);return a.dispatch=a.next=e=>{for("string"==typeof e&&(e={key:e}),a.event=e;a.event;){if(!d(u))return!1;if(a.status&t.LEAF)return!0}},a}export{r as KEYS,s as buildStateDescriptor,o as checkProcessDescriptor,i as getAllStateKeys,d as getAllTransitions,c as getStateDescriptor,a as getTargetStateKey,u as initAsyncProcess,f as newProcessInstance,l as newSyncProcess};
1
+ // @statewalker/fsm v0.15.1 https://github.com/statewalker/statewalker-fsm Copyright 2022 Mikhail Kotelnikov
2
+ import{MODE as t,newAsyncTreeWalker as e,newTreeWalker as n}from"@statewalker/tree";function s(t={}){const{key:e,transitions:n=[],states:r={},options:o,...c}=t,i={key:e,transitions:{},states:{},options:Object.assign(o||{},c)};for(const t of n){let e,n,s;if(Array.isArray(t))e=t[0],n=t[1],s=t[2];else{const{from:r,event:o,to:c}=t;e=r,n=o,s=c}(i.transitions[e]=i.transitions[e]||{})[n]=s}if(Array.isArray(r))for(const t of r)i.states[t.key]=s(t);else if(r)for(const t of Object.keys(r))i.states[t]=s(r[t]);return i}var r={STATE_ANY:"*",STATE_INITIAL:"",STATE_FINAL:"",EVENT_ANY:"*",EVENT_EMPTY:""};function o(t){return function t(e,n=[],s=[]){s=[...s,e.key];const o=Object.assign({key:e.key},function(t){const e={},n={};for(const[s,r]of Object.entries(t.transitions)){e[s]=(e[s]||0)+1;for(const t of Object.values(r))n[t]=(n[t]||0)+1}const s=[],o=[];for(const t of Object.keys(e))t===r.STATE_ANY||t===r.STATE_FINAL||t===r.STATE_INITIAL||t in n||s.push(t);for(const t of Object.keys(n))t===r.STATE_FINAL||t in e||o.push(t);return{unreachableStates:s,deadendStates:o}}(e));if(o.deadendStates.length||o.unreachableStates.length){const t={path:s};n.push(t),o.deadendStates.length&&(t.deadendStates=o.deadendStates),o.unreachableStates.length&&(t.unreachableStates=o.unreachableStates)}for(const r of Object.values(e.states))t(r,n,s);return n}(t)}function c(t,e){let n;for(let s=t.stack.length-1;!n&&s>=0;s--){n=(t.stack[s].descriptor.states||{})[e]}return n||{transitions:{},states:{}}}function i(t){const e={},n=t=>e[t]=(e[t]||0)+1;return function t(e){n(e.key);for(const[t,s]of Object.entries(e.transitions)){n(t);for(const t of Object.values(s))n(t)}for(const[s,r]of Object.entries(e.states))n(s),t(r)}(t),Object.keys(e).sort()}function a(t,e,n){const s=[[e,n],[r.STATE_ANY,n],[e,r.EVENT_ANY],[r.STATE_ANY,r.EVENT_ANY]];let o;for(let e=0,n=s.length;void 0===o&&e<n;e++){const[n,c]=s[e],i=t.transitions[n];i&&(o=i[c],void 0===o&&(o=i[r.EVENT_ANY]))}return void 0!==o?o:r.STATE_FINAL}function f({config:e,descriptor:n,newState:o=(t=>t),newProcess:i=(t=>({descriptor:t,status:0,stack:[],event:void 0,current:void 0}))}){const f=i(n=n||s(e));return[f,()=>{let e,n;if(f.status)if(f.stack.length){const s=f.event.key||r.EVENT_EMPTY;e=a(f.stack[f.stack.length-1].descriptor,f.status&t.ENTER?r.STATE_INITIAL:f.current?f.current.key:r.STATE_FINAL,s),e&&(n=c(f,e))}else e=r.STATE_FINAL;else n=f.descriptor,e=n.key;return e?o({process:f,key:e,descriptor:n}):null}]}function u({config:n,descriptor:s,before:r,after:o,newProcess:c,newState:i,handleError:a=console.error}){const[u,T]=f({config:n,descriptor:s,newProcess:c,newState:i}),E=e(r,o,u);return u.finished=!1,u.next=e=>(u.nextEvent=e,u.running=u.running||Promise.resolve().then((async()=>{try{for(u.event=u.nextEvent,u.nextEvent=void 0;!u.finished&&u.event;)if(u.finished=!await E(T),u.status&t.EXIT&&u.nextEvent)u.event=u.nextEvent,u.nextEvent=void 0;else if(u.status&t.LEAF)break}catch(t){a(t)}})).finally((()=>u.running=void 0)).then((()=>!u.finished))),u}function T(t){const e=[];let n=t.current?t.current.key:r.STATE_INITIAL;for(let s=t.stack.length-1;s>=0;s--){const o=t.stack[s],c=o.key,i=o.descriptor;for(const t of[n,r.STATE_ANY]){const n=i.transitions[t];if(n)for(const[s,r]of Object.entries(n))e.push([c,t,s,r])}n=c}return e}function E({config:e,descriptor:s,before:r,after:o,newProcess:c,newState:i}){const[a,u]=f({config:e,descriptor:s,newProcess:c,newState:i}),T=n(r,o,a);return a.dispatch=a.next=e=>{for("string"==typeof e&&(e={key:e}),a.event=e;a.event;){if(!T(u))return!1;if(a.status&t.LEAF)return!0}},a}export{r as KEYS,s as buildStateDescriptor,o as checkProcessDescriptor,i as getAllStateKeys,T as getAllTransitions,c as getStateDescriptor,a as getTargetStateKey,u as newAsyncProcess,f as newProcessInstance,E as newSyncProcess};
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "@statewalker/fsm",
3
- "version": "0.14.0",
3
+ "version": "0.15.1",
4
4
  "description": "HFSM Implementation",
5
5
  "keywords": [],
6
- "homepage": "https://github.com/statewalker/statewalker-tree",
6
+ "homepage": "https://github.com/statewalker/statewalker-fsm",
7
7
  "author": {
8
8
  "name": "Mikhail Kotelnikov",
9
9
  "email": "mikhail.kotelnikov@gmail.com"
10
10
  },
11
+ "license": "MIT",
11
12
  "type": "module",
12
13
  "files": [
13
14
  "dist/**/package.json",
@@ -15,8 +16,16 @@
15
16
  "src/**/*.js",
16
17
  "index.js"
17
18
  ],
19
+ "module": "src/index.js",
20
+ "main": "src/index.js",
21
+ "jsdelivr": "dist/index.js",
22
+ "unpkg": "dist/index.js",
23
+ "exports": {
24
+ "umd": "./dist/index-umd.min.js",
25
+ "default": "./src/index.js"
26
+ },
18
27
  "dependencies": {
19
- "@statewalker/tree": "0.10.0"
28
+ "@statewalker/tree": "0.10.1"
20
29
  },
21
30
  "devDependencies": {
22
31
  "@statewalker/rollup": "^0.1.4",
@@ -25,12 +34,6 @@
25
34
  "mocha": "^10",
26
35
  "rollup": "^2"
27
36
  },
28
- "module": "src/index.js",
29
- "exports": {
30
- "import": "./src/index.js",
31
- "umd": "./dist/index-umd.min.js",
32
- "default": "./dist/index.js"
33
- },
34
37
  "repository": {
35
38
  "type": "git",
36
39
  "url": "git@github.com:statewalker/statewalker-fsm.git"
@@ -41,9 +44,8 @@
41
44
  "test": "mocha -R spec ./test/index.js && yarn eslint",
42
45
  "prepublishOnly": "rm -rf dist && yarn test && yarn rollup"
43
46
  },
44
- "license": "MIT",
45
47
  "sideEffects": false,
46
48
  "publishConfig": {
47
49
  "access": "public"
48
50
  }
49
- }
51
+ }
package/src/index.js CHANGED
@@ -4,7 +4,7 @@ export { default as getStateDescriptor } from "./getStateDescriptor.js";
4
4
  export { default as getAllStateKeys } from "./getAllStateKeys.js";
5
5
  export { default as getTargetStateKey } from "./getTargetStateKey.js";
6
6
  export { default as KEYS } from "./KEYS.js";
7
- export { default as initAsyncProcess } from "./initAsyncProcess.js";
7
+ export { default as newAsyncProcess } from "./newAsyncProcess.js";
8
8
  export { default as getAllTransitions } from "./getAllTransitions.js";
9
9
  export { default as newProcessInstance } from "./newProcessInstance.js";
10
- export { default as newSyncProcess } from "./newSyncProcess.js";
10
+ export { default as newSyncProcess } from "./newSyncProcess.js";
@@ -1,61 +0,0 @@
1
- import newAsyncProcess from "./newAsyncProcess.js";
2
-
3
- export default function initProcess({ config, handler, handleError = console.error }) {
4
- let process;
5
- const before = async (process) => {
6
- process._started = true;
7
- const state = process.current;
8
- handler(state);
9
- await state.init.run();
10
- };
11
- const after = async (process) => {
12
- const state = process.current;
13
- await state.done.run();
14
- };
15
-
16
- process = newAsyncProcess({
17
- config,
18
- before,
19
- after,
20
- newProcess: (descriptor) => {
21
- return {
22
- descriptor,
23
- config,
24
- status: 0,
25
- stack: [],
26
- event: undefined,
27
- current: undefined
28
- };
29
- },
30
- newState: (state) => {
31
- state.init = newStateMethod();
32
- state.done = newStateMethod();
33
- state.dispatch = (...args) => state.process.dispatch(...args);
34
- state.getEvent = () => state.process.event || {};
35
- state.getEventKey = () => state.getEvent().key;
36
- return state;
37
- },
38
- handleError
39
- });
40
- process.dispatch = (key, params = {}) => {
41
- process.next({ key, params });
42
- };
43
- return process;
44
-
45
- function newStateMethod() {
46
- const list = [];
47
- return Object.assign((m) => list.push(m), {
48
- run: async (...args) => {
49
- // We use the index to iterate over the list: the list can be updated by called methods
50
- for (let i = 0; i < list.length; i++) {
51
- try {
52
- list[i] && (await list[i](...args));
53
- } catch (error) {
54
- console.error(error);
55
- await handleError(error);
56
- }
57
- }
58
- }
59
- });
60
- }
61
- }