diff --git a/dist/index.d.ts b/dist/index.d.ts index e09561a..d3f58ba 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -1,58 +1,58 @@ export type Event_T = [name: string, payload: any]; -export interface Machine_T { - states: Array; +export interface Machine_T { + states: Array>; } -export interface State_T { +export interface State_T { name: string; - eventReactionCouplings: Array; + eventReactionCouplings: Array>; } -export interface EventReactionCouplings_T { +export interface EventReactionCouplings_T { eventName: string; - reactions: Array; + reactions: Array>; } -export type Reaction_T = SideEffect_T | ContextMutation_T | Goto_T; -export interface SideEffect_T { +export type Reaction_T = SideEffect_T | ContextMutation_T | Goto_T; +export interface SideEffect_T { type: 'SideEffect'; - fn: SideEffectFunction_T; + fn: SideEffectFunction_T; } -export type SideEffectFunction_T = (ctx: any, e: Event_T, self: Interpreter_T) => void; -export interface ContextMutation_T { +export type SideEffectFunction_T = (ctx: C, e: Event_T, self: Interpreter_T, originalContext: C) => void; +export interface ContextMutation_T { type: 'ContextMutation'; - fn: ContextMutationFunction_T; + fn: ContextMutationFunction_T; } -export type ContextMutationFunction_T = (ctx: any, e: Event_T, self: Interpreter_T) => any; +export type ContextMutationFunction_T = (ctx: C, e: Event_T, self: Interpreter_T) => C; export interface Goto_T { type: 'Goto'; targetStateName: string; } -export declare const Machine: (...states: Array) => Machine_T; -export declare const State: (name: string, ...eventReactionCouplings: Array) => State_T; -export declare const On: (eventName: string, ...reactions: Array) => EventReactionCouplings_T; -export declare const SideEffect: (fn: SideEffectFunction_T) => SideEffect_T; +export declare const Machine: (...states: State_T[]) => Machine_T; +export declare const State: (name: string, ...eventReactionCouplings: EventReactionCouplings_T[]) => State_T; +export declare const On: (eventName: string, ...reactions: Reaction_T[]) => EventReactionCouplings_T; +export declare const SideEffect: (fn: SideEffectFunction_T) => SideEffect_T; export declare const Goto: (targetStateName: string) => Goto_T; -export declare const Context: (fn: ContextMutationFunction_T) => ContextMutation_T; -export interface Interpreter_T { - machine: Machine_T; +export declare const Context: (fn: ContextMutationFunction_T) => ContextMutation_T; +export interface Interpreter_T { + machine: Machine_T; state: string; - context: any; + context: C; eventQueue: Array; - subscriptions: Record; + subscriptions: Record>; isTransitioning: boolean; isPaused: boolean; - start: () => Interpreter_T; + start: () => Interpreter_T; } /** * Description placeholder * * @export * @param {Machine_T} machine - * @param {InitialContextFunction_T} initialContextFunction - in the form of a function rather than a direct value, so as to facilitate co-initialization of peer interpreters. Otherwise, the "parent" interpreter will start, but without a reference to a running child interpreter which it might expect to exist. + * @param {any} initialContext * @param {?string} [initialStateName] * @returns {Interpreter_T} */ -export declare function Interpreter(machine: Machine_T, initialContext: any, initialStateName?: string): Interpreter_T; -export declare function start(interpreter: Interpreter_T): void; -export declare function pause(interpreter: Interpreter_T): void; +export declare function Interpreter(machine: Machine_T, initialContext: any, initialStateName?: string): Interpreter_T; +export declare function start(interpreter: Interpreter_T): void; +export declare function pause(interpreter: Interpreter_T): void; /** Inject an Event into the Interpreter's "tick queue". * * An event can be signify something "new" happening, such that its reactions should run on the next Tick; @@ -63,10 +63,10 @@ export declare function pause(interpreter: Interpreter_T): void; * whether to run a reaction at all. If an Event is received, and is specified to be applied on a past * Tick, it is discarded. */ -export declare function send(interpreter: Interpreter_T, event: Event_T): void; +export declare function send(interpreter: Interpreter_T, event: Event_T): void; export declare const enqueue: typeof send; -export type SubscriptionCallbackFunction_T = (self: Interpreter_T) => void; -export declare function subscribe(interpreter: Interpreter_T, callback: SubscriptionCallbackFunction_T): string; -export declare function unsubscribe(interpreter: Interpreter_T, subscriptionId: string): void; +export type SubscriptionCallbackFunction_T = (self: Interpreter_T) => void; +export declare function subscribe(interpreter: Interpreter_T, callback: SubscriptionCallbackFunction_T): string; +export declare function unsubscribe(interpreter: Interpreter_T, subscriptionId: string): void; export declare const Spawn: () => void; export declare const Unspawn: () => void; diff --git a/dist/index.js b/dist/index.js index 7a37638..f995994 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,2 +1,2 @@ -var y=function(...t){return{states:t}},E=function(t,...e){return{name:t,eventReactionCouplings:e}},d=function(t,...e){return{eventName:t,reactions:e}},v=function(t){return{type:"SideEffect",fn:t}},S=function(t){return{type:"Goto",targetStateName:t}},C=function(t){return{type:"ContextMutation",fn:t}};function b(t,e,n){typeof n>"u"&&(n=t.states[0].name);let o={machine:t,state:n,context:e,eventQueue:[],isTransitioning:!1,subscriptions:{},isPaused:!0};return o.start=()=>(T(o),o),r(o,["entry",null]),o}function T(t){t.isPaused=!1,u(t)}function M(t){t.isPaused=!0}function _(t){return t.machine.states.find(e=>e.name===t.state)}function x(t,e){return t.eventReactionCouplings.filter(n=>n.eventName===e[0])}function r(t,e){t.eventQueue.push(e),t.isTransitioning===!1&&u(t)}var h=r;function u(t){for(t.isTransitioning=!0;t.eventQueue.length>0&&t.isPaused===!1;)l(t);t.isTransitioning=!1,Object.values(t.subscriptions).forEach(e=>{e(t)})}function l(t){let e=t.eventQueue.shift();if(typeof e<"u"){let n=_(t),i=x(n,e).map(s=>s.reactions).flat(),{sideEffects:f,contextMutations:p,goto_:c}=g(i);f.forEach(s=>{s.fn(t.context,e,t)}),p.forEach(s=>{t.context=s.fn(t.context,e,t)}),c!==null&&(r(t,["exit",null]),t.state=c.targetStateName,r(t,["entry",null]))}}function g(t){let e=[],n=[],o=null;return t.forEach(i=>{i.type==="SideEffect"?e.push(i):i.type==="ContextMutation"?n.push(i):i.type==="Goto"&&(o=i)}),{sideEffects:e,contextMutations:n,goto_:o}}var a=0;function I(t,e){return a++,t.subscriptions[a.toString()]=e,a.toString()}function R(t,e){delete t.subscriptions[e.toString()]}var A=function(){},m=function(){};export{C as Context,S as Goto,b as Interpreter,y as Machine,d as On,v as SideEffect,A as Spawn,E as State,m as Unspawn,h as enqueue,M as pause,r as send,T as start,I as subscribe,R as unsubscribe}; +var d=function(...t){return{states:t}},y=function(t,...e){return{name:t,eventReactionCouplings:e}},E=function(t,...e){return{eventName:t,reactions:e}},v=function(t){return{type:"SideEffect",fn:t}},S=function(t){return{type:"Goto",targetStateName:t}},b=function(t){return{type:"ContextMutation",fn:t}};function M(t,e,n){typeof n>"u"&&(n=t.states[0].name);let o={machine:t,state:n,context:e,eventQueue:[],isTransitioning:!1,subscriptions:{},isPaused:!0};return o.start=()=>(_(o),o),a(o,["entry",null]),o}function _(t){t.isPaused===!0&&(t.isPaused=!1,u(t))}function h(t){t.isPaused===!1&&(t.isPaused=!0)}function p(t){return t.machine.states.find(e=>e.name===t.state)}function x(t,e){return t.eventReactionCouplings.filter(n=>n.eventName===e[0])}function a(t,e){t.eventQueue.push(e),t.isTransitioning===!1&&u(t)}var I=a;function u(t){for(t.isTransitioning=!0;t.eventQueue.length>0&&t.isPaused===!1;)l(t);t.isTransitioning=!1,Object.values(t.subscriptions).forEach(e=>{e(t)})}function l(t){let e=t.eventQueue.shift();if(typeof e<"u"){let n=p(t),i=x(n,e).map(s=>s.reactions).flat(),{sideEffects:C,contextMutations:f,goto_:r}=g(i),T=t.context;f.forEach(s=>{t.context=s.fn(t.context,e,t)}),C.forEach(s=>{s.fn(t.context,e,t,T)}),r!==null&&(a(t,["exit",null]),t.state=r.targetStateName,a(t,["entry",null]))}}function g(t){let e=[],n=[],o=null;return t.forEach(i=>{i.type==="SideEffect"?e.push(i):i.type==="ContextMutation"?n.push(i):i.type==="Goto"&&(o=i)}),{sideEffects:e,contextMutations:n,goto_:o}}var c=0;function R(t,e){return c++,t.subscriptions[c.toString()]=e,c.toString()}function A(t,e){delete t.subscriptions[e.toString()]}var m=function(){},F=function(){};export{b as Context,S as Goto,M as Interpreter,d as Machine,E as On,v as SideEffect,m as Spawn,y as State,F as Unspawn,I as enqueue,h as pause,a as send,_ as start,R as subscribe,A as unsubscribe}; //# sourceMappingURL=index.js.map diff --git a/dist/index.js.map b/dist/index.js.map index 6f6d845..33c976f 100644 --- a/dist/index.js.map +++ b/dist/index.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../src/index.ts"], - "sourcesContent": ["export type Event_T = [name:string, payload:any];\nexport interface Machine_T {\n states: Array\n}\nexport interface State_T {\n name: string;\n eventReactionCouplings: Array;\n}\nexport interface EventReactionCouplings_T {\n eventName: string;\n reactions: Array;\n};\nexport type Reaction_T = SideEffect_T | ContextMutation_T | Goto_T;\nexport interface SideEffect_T {\n type: 'SideEffect';\n fn: SideEffectFunction_T;\n};\nexport type SideEffectFunction_T = (ctx:any,e:Event_T,self:Interpreter_T)=>void;\nexport interface ContextMutation_T {\n type: 'ContextMutation';\n fn: ContextMutationFunction_T;\n};\nexport type ContextMutationFunction_T = (ctx:any,e:Event_T,self:Interpreter_T)=>any;\nexport interface Goto_T {\n type: 'Goto';\n targetStateName: string;\n};\n\nexport const Machine = function(...states:Array) : Machine_T { return {states}; };\nexport const State = function(name:string, ...eventReactionCouplings:Array) : State_T{ return {name, eventReactionCouplings}; };\nexport const On = function(eventName:string, ...reactions:Array) : EventReactionCouplings_T{ return {eventName, reactions}; };\nexport const SideEffect = function(fn:SideEffectFunction_T) : SideEffect_T{ return {type:'SideEffect', fn}; };\nexport const Goto = function(targetStateName:string) : Goto_T { return {type:'Goto', targetStateName} };\nexport const Context = function(fn:ContextMutationFunction_T) : ContextMutation_T { return {type:'ContextMutation', fn} };\n\n\n\n\n\nexport interface Interpreter_T {\n machine: Machine_T;\n state: string;\n context: any;\n eventQueue:Array;\n subscriptions: Record;\n isTransitioning: boolean;\n isPaused: boolean;\n start: ()=>Interpreter_T;\n}\n\n/**\n * Description placeholder\n *\n * @export\n * @param {Machine_T} machine\n * @param {InitialContextFunction_T} initialContextFunction - in the form of a function rather than a direct value, so as to facilitate co-initialization of peer interpreters. Otherwise, the \"parent\" interpreter will start, but without a reference to a running child interpreter which it might expect to exist.\n * @param {?string} [initialStateName]\n * @returns {Interpreter_T}\n */\nexport function Interpreter(machine:Machine_T, initialContext:any, initialStateName?:string) : Interpreter_T{\n if(typeof initialStateName === 'undefined'){ initialStateName = machine.states[0].name; }\n //@ts-expect-error\n const interpreter : Interpreter_T = {machine, state: initialStateName, context:initialContext, eventQueue:[], isTransitioning:false, subscriptions: {}, isPaused: true};\n interpreter.start = ()=>{ start(interpreter); return interpreter; }\n send(interpreter, ['entry', null] );\n return interpreter;\n}\nexport function start(interpreter:Interpreter_T){\n interpreter.isPaused = false;\n processEvents(interpreter);\n}\nexport function pause(interpreter:Interpreter_T){\n interpreter.isPaused = true;\n}\n\n/** Helper function for `send()`\n */\nfunction getState(interpreter : Interpreter_T) : State_T{\n return interpreter.machine.states.find((state)=>state.name===interpreter.state) as unknown as State_T;\n}\n/** Helper function for `send()`\n */\nfunction getMatchingEventReactionCouplings(state : State_T, event:Event_T) : Array{\n return state.eventReactionCouplings.filter((eventReactionCoupling)=>eventReactionCoupling.eventName===event[0]);\n}\n/** Inject an Event into the Interpreter's \"tick queue\".\n * \n * An event can be signify something \"new\" happening, such that its reactions should run on the next Tick;\n * or it can signify a milestone \"within\" the current Tick, such that a Tick can be thought of as having \n * \"sub-Ticks\".\n * \n * This distinction is significant for proper ordering of reaction execution, and also for determining\n * whether to run a reaction at all. If an Event is received, and is specified to be applied on a past \n * Tick, it is discarded.\n */\nexport function send(interpreter : Interpreter_T, event:Event_T){\n interpreter.eventQueue.push(event);\n if(interpreter.isTransitioning === false){\n processEvents(interpreter);\n }\n}\nexport const enqueue = send;\nfunction processEvents(interpreter:Interpreter_T){\n interpreter.isTransitioning = true;\n while(interpreter.eventQueue.length > 0 && interpreter.isPaused===false){\n processNextEvent(interpreter);\n }\n interpreter.isTransitioning = false;\n // only run subscriptions here, once the machine's state has settled:\n Object.values(interpreter.subscriptions).forEach((subscriptionCallbackFunction)=>{ subscriptionCallbackFunction(interpreter); });\n}\nfunction processNextEvent(interpreter:Interpreter_T){\n const nextEvent = interpreter.eventQueue.shift();\n if(typeof nextEvent !== 'undefined'){\n const state = getState(interpreter);\n const eventReactionCouplings = getMatchingEventReactionCouplings(state, nextEvent);\n const reactions = eventReactionCouplings\n .map((eventReactionCoupling)=>eventReactionCoupling.reactions)\n .flat();\n const {sideEffects, contextMutations, goto_} = categorizeReactions(reactions);\n // can process sideEffects in parallel:\n sideEffects.forEach((sideEffect)=>{\n sideEffect.fn(interpreter.context, nextEvent, interpreter);\n });\n // must process contextMutations in-series:\n contextMutations.forEach((contextMutation)=>{\n interpreter.context = contextMutation.fn(interpreter.context, nextEvent, interpreter);\n });\n // processing of `goto` must be last:\n if(goto_ !== null){\n send(interpreter, ['exit', null]);\n interpreter.state = goto_.targetStateName;\n send(interpreter, ['entry', null]);\n }\n }\n}\nfunction categorizeReactions(reactions:Array) : {sideEffects:Array, contextMutations:Array, goto_:Goto_T|null}{\n let \n sideEffects:Array = [], \n contextMutations:Array = [], \n goto_:Goto_T|null = null;\n reactions.forEach((reaction)=>{\n if(reaction.type === 'SideEffect'){\n sideEffects.push(reaction);\n }\n else if(reaction.type === 'ContextMutation'){\n contextMutations.push(reaction);\n }\n else if(reaction.type === 'Goto'){\n goto_ = reaction;\n }\n });\n return {sideEffects, contextMutations, goto_};\n}\n\nexport type SubscriptionCallbackFunction_T = (self:Interpreter_T)=>void;\nlet subscriptionId : number = 0;\nexport function subscribe(interpreter:Interpreter_T, callback:SubscriptionCallbackFunction_T){\n subscriptionId++;\n interpreter.subscriptions[subscriptionId.toString()] = callback;\n return subscriptionId.toString();\n}\nexport function unsubscribe(interpreter:Interpreter_T, subscriptionId:string){\n delete interpreter.subscriptions[subscriptionId.toString()];\n}\n\nexport const Spawn = function(){};\nexport const Unspawn = function(){};\n\n/*\nexport function useMachine(machine, options){\n return useMemo(()=>interpret(AppMachine, {context:{}}),[]);\n}\n*/"], - "mappings": "AA4BO,IAAMA,EAAU,YAAYC,EAAmC,CAAE,MAAO,CAAC,OAAAA,CAAM,CAAG,EAC5EC,EAAQ,SAASC,KAAgBC,EAAiE,CAAE,MAAO,CAAC,KAAAD,EAAM,uBAAAC,CAAsB,CAAG,EAC3IC,EAAK,SAASC,KAAqBC,EAAuD,CAAE,MAAO,CAAC,UAAAD,EAAW,UAAAC,CAAS,CAAG,EAC3HC,EAAa,SAASC,EAAuC,CAAE,MAAO,CAAC,KAAK,aAAc,GAAAA,CAAE,CAAG,EAC/FC,EAAO,SAASC,EAAiC,CAAE,MAAO,CAAC,KAAK,OAAQ,gBAAAA,CAAe,CAAE,EACzFC,EAAU,SAASH,EAAkD,CAAE,MAAO,CAAC,KAAK,kBAAmB,GAAAA,CAAE,CAAE,EA0BjH,SAASI,EAAYC,EAAmBC,EAAoBC,EAAyC,CACvG,OAAOA,EAAqB,MAAcA,EAAmBF,EAAQ,OAAO,CAAC,EAAE,MAElF,IAAMG,EAA8B,CAAC,QAAAH,EAAS,MAAOE,EAAkB,QAAQD,EAAgB,WAAW,CAAC,EAAG,gBAAgB,GAAO,cAAe,CAAC,EAAG,SAAU,EAAI,EACtK,OAAAE,EAAY,MAAQ,KAAMC,EAAMD,CAAW,EAAUA,GACrDE,EAAKF,EAAa,CAAC,QAAS,IAAI,CAAE,EAC3BA,CACT,CACO,SAASC,EAAMD,EAA0B,CAC9CA,EAAY,SAAW,GACvBG,EAAcH,CAAW,CAC3B,CACO,SAASI,EAAMJ,EAA0B,CAC9CA,EAAY,SAAW,EACzB,CAIA,SAASK,EAASL,EAAsC,CACtD,OAAOA,EAAY,QAAQ,OAAO,KAAMM,GAAQA,EAAM,OAAON,EAAY,KAAK,CAChF,CAGA,SAASO,EAAkCD,EAAiBE,EAAgD,CAC1G,OAAOF,EAAM,uBAAuB,OAAQG,GAAwBA,EAAsB,YAAYD,EAAM,CAAC,CAAC,CAChH,CAWO,SAASN,EAAKF,EAA6BQ,EAAc,CAC9DR,EAAY,WAAW,KAAKQ,CAAK,EAC9BR,EAAY,kBAAoB,IACjCG,EAAcH,CAAW,CAE7B,CACO,IAAMU,EAAUR,EACvB,SAASC,EAAcH,EAA0B,CAE/C,IADAA,EAAY,gBAAkB,GACxBA,EAAY,WAAW,OAAS,GAAKA,EAAY,WAAW,IAChEW,EAAiBX,CAAW,EAE9BA,EAAY,gBAAkB,GAE9B,OAAO,OAAOA,EAAY,aAAa,EAAE,QAASY,GAA+B,CAAEA,EAA6BZ,CAAW,CAAG,CAAC,CACjI,CACA,SAASW,EAAiBX,EAA0B,CAClD,IAAMa,EAAYb,EAAY,WAAW,MAAM,EAC/C,GAAG,OAAOa,EAAc,IAAY,CAClC,IAAMP,EAAQD,EAASL,CAAW,EAE5BV,EADyBiB,EAAkCD,EAAOO,CAAS,EAE9E,IAAKJ,GAAwBA,EAAsB,SAAS,EAC5D,KAAK,EACF,CAAC,YAAAK,EAAa,iBAAAC,EAAkB,MAAAC,CAAK,EAAIC,EAAoB3B,CAAS,EAE5EwB,EAAY,QAASI,GAAa,CAChCA,EAAW,GAAGlB,EAAY,QAASa,EAAWb,CAAW,CAC3D,CAAC,EAEDe,EAAiB,QAASI,GAAkB,CAC1CnB,EAAY,QAAUmB,EAAgB,GAAGnB,EAAY,QAASa,EAAWb,CAAW,CACtF,CAAC,EAEEgB,IAAU,OACXd,EAAKF,EAAa,CAAC,OAAQ,IAAI,CAAC,EAChCA,EAAY,MAAQgB,EAAM,gBAC1Bd,EAAKF,EAAa,CAAC,QAAS,IAAI,CAAC,GAGvC,CACA,SAASiB,EAAoB3B,EAA8H,CACzJ,IACEwB,EAAkC,CAAC,EACnCC,EAA4C,CAAC,EAC7CC,EAAoB,KACtB,OAAA1B,EAAU,QAAS8B,GAAW,CACzBA,EAAS,OAAS,aACnBN,EAAY,KAAKM,CAAQ,EAEnBA,EAAS,OAAS,kBACxBL,EAAiB,KAAKK,CAAQ,EAExBA,EAAS,OAAS,SACxBJ,EAAQI,EAEZ,CAAC,EACM,CAAC,YAAAN,EAAa,iBAAAC,EAAkB,MAAAC,CAAK,CAC9C,CAGA,IAAIK,EAA0B,EACvB,SAASC,EAAUtB,EAA2BuB,EAAwC,CAC3F,OAAAF,IACArB,EAAY,cAAcqB,EAAe,SAAS,CAAC,EAAIE,EAChDF,EAAe,SAAS,CACjC,CACO,SAASG,EAAYxB,EAA2BqB,EAAsB,CAC3E,OAAOrB,EAAY,cAAcqB,EAAe,SAAS,CAAC,CAC5D,CAEO,IAAMI,EAAQ,UAAU,CAAC,EACnBC,EAAU,UAAU,CAAC", - "names": ["Machine", "states", "State", "name", "eventReactionCouplings", "On", "eventName", "reactions", "SideEffect", "fn", "Goto", "targetStateName", "Context", "Interpreter", "machine", "initialContext", "initialStateName", "interpreter", "start", "send", "processEvents", "pause", "getState", "state", "getMatchingEventReactionCouplings", "event", "eventReactionCoupling", "enqueue", "processNextEvent", "subscriptionCallbackFunction", "nextEvent", "sideEffects", "contextMutations", "goto_", "categorizeReactions", "sideEffect", "contextMutation", "reaction", "subscriptionId", "subscribe", "callback", "unsubscribe", "Spawn", "Unspawn"] + "sourcesContent": ["export type Event_T = [name:string, payload:any];\nexport interface Machine_T {\n states: Array>\n}\nexport interface State_T {\n name: string;\n eventReactionCouplings: Array>;\n}\nexport interface EventReactionCouplings_T {\n eventName: string;\n reactions: Array>;\n};\nexport type Reaction_T = SideEffect_T | ContextMutation_T | Goto_T;\nexport interface SideEffect_T {\n type: 'SideEffect';\n fn: SideEffectFunction_T;\n};\nexport type SideEffectFunction_T = (ctx:C,e:Event_T,self:Interpreter_T,originalContext:C)=>void;\nexport interface ContextMutation_T {\n type: 'ContextMutation';\n fn: ContextMutationFunction_T;\n};\nexport type ContextMutationFunction_T = (ctx:C,e:Event_T,self:Interpreter_T)=>C;\nexport interface Goto_T {\n type: 'Goto';\n targetStateName: string;\n};\n\nexport const Machine = function(...states:Array>) : Machine_T { return {states}; };\nexport const State = function(name:string, ...eventReactionCouplings:Array>) : State_T{ return {name, eventReactionCouplings}; };\nexport const On = function(eventName:string, ...reactions:Array>) : EventReactionCouplings_T{ return {eventName, reactions}; };\nexport const SideEffect = function(fn:SideEffectFunction_T) : SideEffect_T{ return {type:'SideEffect', fn}; };\nexport const Goto = function(targetStateName:string) : Goto_T { return {type:'Goto', targetStateName} };\nexport const Context = function(fn:ContextMutationFunction_T) : ContextMutation_T { return {type:'ContextMutation', fn} };\n\n\n\n\n\nexport interface Interpreter_T {\n machine: Machine_T;\n state: string;\n context: C;\n eventQueue:Array;\n subscriptions: Record>;\n isTransitioning: boolean;\n isPaused: boolean;\n start: ()=>Interpreter_T;\n}\n\n/**\n * Description placeholder\n *\n * @export\n * @param {Machine_T} machine\n * @param {any} initialContext\n * @param {?string} [initialStateName]\n * @returns {Interpreter_T}\n */\nexport function Interpreter(machine:Machine_T, initialContext:any, initialStateName?:string) : Interpreter_T{\n if(typeof initialStateName === 'undefined'){ initialStateName = machine.states[0].name; }\n //@ts-expect-error\n const interpreter : Interpreter_T = {machine, state: initialStateName, context:initialContext, eventQueue:[], isTransitioning:false, subscriptions: {}, isPaused: true};\n interpreter.start = ()=>{ start(interpreter); return interpreter; }\n send(interpreter, ['entry', null] );\n return interpreter;\n}\nexport function start(interpreter:Interpreter_T){\n if(interpreter.isPaused === true){\n interpreter.isPaused = false;\n processEvents(interpreter);\n }\n}\nexport function pause(interpreter:Interpreter_T){\n if(interpreter.isPaused === false){\n interpreter.isPaused = true;\n }\n}\n\n/** Helper function for `send()`\n */\nfunction getState(interpreter : Interpreter_T) : State_T{\n return interpreter.machine.states.find((state)=>state.name===interpreter.state) as unknown as State_T;\n}\n/** Helper function for `send()`\n */\nfunction getMatchingEventReactionCouplings(state : State_T, event:Event_T) : Array>{\n return state.eventReactionCouplings.filter((eventReactionCoupling)=>eventReactionCoupling.eventName===event[0]);\n}\n/** Inject an Event into the Interpreter's \"tick queue\".\n * \n * An event can be signify something \"new\" happening, such that its reactions should run on the next Tick;\n * or it can signify a milestone \"within\" the current Tick, such that a Tick can be thought of as having \n * \"sub-Ticks\".\n * \n * This distinction is significant for proper ordering of reaction execution, and also for determining\n * whether to run a reaction at all. If an Event is received, and is specified to be applied on a past \n * Tick, it is discarded.\n */\nexport function send(interpreter : Interpreter_T, event:Event_T){\n interpreter.eventQueue.push(event);\n if(interpreter.isTransitioning === false){\n processEvents(interpreter);\n }\n}\nexport const enqueue = send;\nfunction processEvents(interpreter:Interpreter_T){\n interpreter.isTransitioning = true;\n while(interpreter.eventQueue.length > 0 && interpreter.isPaused===false){\n processNextEvent(interpreter);\n }\n interpreter.isTransitioning = false;\n // only run subscriptions here, once the machine's state has settled:\n Object.values(interpreter.subscriptions).forEach((subscriptionCallbackFunction)=>{ subscriptionCallbackFunction(interpreter); });\n}\nfunction processNextEvent(interpreter:Interpreter_T){\n const event = interpreter.eventQueue.shift();\n if(typeof event !== 'undefined'){\n const state = getState(interpreter);\n const eventReactionCouplings = getMatchingEventReactionCouplings(state, event);\n const reactions = eventReactionCouplings\n .map((eventReactionCoupling)=>eventReactionCoupling.reactions)\n .flat();\n const {sideEffects, contextMutations, goto_} = categorizeReactions(reactions);\n // save the current context, before it's mutated, so as to pass it to sideEffects below:\n const originalContext = interpreter.context;\n // must process contextMutations in-series:\n contextMutations.forEach((contextMutation)=>{\n interpreter.context = contextMutation.fn(interpreter.context, event, interpreter);\n });\n // can process sideEffects in parallel (though we currently don't due to the overhead of doing so in Node.js):\n // they're processed *after* the context changes, since that's what most sideEffects would be interested in; but nevertheless the original context is passed in case this sideEffect needs it:\n sideEffects.forEach((sideEffect)=>{\n sideEffect.fn(interpreter.context, event, interpreter, originalContext);\n });\n // processing of `goto` must be last:\n if(goto_ !== null){\n send(interpreter, ['exit', null]);\n interpreter.state = goto_.targetStateName;\n send(interpreter, ['entry', null]);\n }\n }\n}\nfunction categorizeReactions(reactions:Array>) : {sideEffects:Array>, contextMutations:Array>, goto_:Goto_T|null}{\n let \n sideEffects:Array> = [], \n contextMutations:Array> = [], \n goto_:Goto_T|null = null;\n reactions.forEach((reaction)=>{\n if(reaction.type === 'SideEffect'){\n sideEffects.push(reaction);\n }\n else if(reaction.type === 'ContextMutation'){\n contextMutations.push(reaction);\n }\n else if(reaction.type === 'Goto'){\n goto_ = reaction;\n }\n });\n return {sideEffects, contextMutations, goto_};\n}\n\nexport type SubscriptionCallbackFunction_T = (self:Interpreter_T)=>void;\nlet subscriptionId : number = 0;\nexport function subscribe(interpreter:Interpreter_T, callback:SubscriptionCallbackFunction_T){\n subscriptionId++;\n interpreter.subscriptions[subscriptionId.toString()] = callback;\n return subscriptionId.toString();\n}\nexport function unsubscribe(interpreter:Interpreter_T, subscriptionId:string){\n delete interpreter.subscriptions[subscriptionId.toString()];\n}\n\nexport const Spawn = function(){};\nexport const Unspawn = function(){};\n\n/*\nexport function useMachine(machine, options){\n return useMemo(()=>interpret(AppMachine, {context:{}}),[]);\n}\n*/"], + "mappings": "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", + "names": ["Machine", "states", "State", "name", "eventReactionCouplings", "On", "eventName", "reactions", "SideEffect", "fn", "Goto", "targetStateName", "Context", "Interpreter", "machine", "initialContext", "initialStateName", "interpreter", "start", "send", "processEvents", "pause", "getState", "state", "getMatchingEventReactionCouplings", "event", "eventReactionCoupling", "enqueue", "processNextEvent", "subscriptionCallbackFunction", "sideEffects", "contextMutations", "goto_", "categorizeReactions", "originalContext", "contextMutation", "sideEffect", "reaction", "subscriptionId", "subscribe", "callback", "unsubscribe", "Spawn", "Unspawn"] }