From abf984bd5d97f749671a3710e02f94f7801a8669 Mon Sep 17 00:00:00 2001 From: Brian Sakal Date: Mon, 8 May 2023 21:07:03 -0400 Subject: [PATCH] TypeScript, send() --- src/index.ts | 55 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/src/index.ts b/src/index.ts index 97e079e..d764f93 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,12 +1,13 @@ -export interface Machine_T { +type EventShape = [name:string, payload:any]; +export interface Machine_T { states: Array> } -export interface State_T { +export interface State_T { name: S; ons: Array>; } -export interface On_T { - eventName: E; +export interface On_T { + eventName: E[0]; reactions: Array>; }; export interface Do_T { @@ -19,10 +20,50 @@ export interface Goto_T { targetStateName: S; }; -export const Machine = function(...states:Array>) : Machine_T { return {states}; }; -export const State = function(name:S, ...ons:Array>) : State_T{ return {name, ons}; }; -export const On = function(eventName:E, ...reactions:Array>) : On_T{ return {eventName, reactions}; }; +export const Machine = function(...states:Array>) : Machine_T { return {states}; }; +export const State = function(name:S, ...ons:Array>) : State_T{ return {name, ons}; }; +export const On = function(eventName:E[0], ...reactions:Array>) : On_T{ return {eventName, reactions}; }; export const Do = function(fn:DoFn_T) : Do_T{ return {type:'Do', fn}; }; export const Goto = function(targetStateName:S) : Goto_T { return {type:'Goto', targetStateName} }; + + +export interface Interpreter_T { + machine: Machine_T; + state: S; + context: C | {}; +} +export function interpret(machine:Machine_T, options?:{state?:S, context?:C | {}}) : Interpreter_T{ + let {state, context} = options || {}; + if(typeof state === 'undefined'){ state = machine.states[0].name; } + if(typeof context === 'undefined'){ context = {}; } + return {machine, state, context}; +} + +/** Helper function for `send()` + */ +function getState(interpreter : Interpreter_T) : State_T{ + return interpreter.machine.states.find((state)=>state.name===interpreter.state) as unknown as State_T; +} +/** Helper function for `send()` + */ +function getOns(state : State_T, event:E) : Array>{ + return state.ons.filter((on)=>on.eventName===event[0]); +} +/** 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; + * or it can signify a milestone "within" the current Tick, such that a Tick can be thought of as having + * "sub-Ticks". + * + * This distinction is significant for proper ordering of reaction execution, and also for determining + * 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 function send(interpreter : Interpreter_T, event:E){ + const state = getState(interpreter); + const ons = getOns(state, event); + ons.forEach +} + export const Spawn = function(){}; export const Unspawn = function(){}; \ No newline at end of file