add `(un)subscribe` function

main
Avraham Sakal 2 years ago
parent aed7cbc9de
commit a3bb0f281c

@ -0,0 +1,10 @@
import * as esbuild from 'esbuild'
await esbuild.build({
entryPoints: ['src/index.ts'],
bundle: true,
sourcemap: true,
minify: true,
format: 'esm',
outdir: 'dist',
})

2
dist/index.js vendored

@ -1,2 +1,2 @@
var d=function(...t){return{states:t}},y=function(t,...e){return{name:t,ons:e}},v=function(t,...e){return{eventName:t,reactions:e}},D=function(t){return{type:"Do",fn:t}},k=function(t){return{type:"Goto",targetStateName:t}},c=function(t){return{doFunctions:t}};function l(t,e){let{state:o,context:s}=e;return typeof o>"u"&&(o=t.states[0].name),{machine:t,state:o,context:s,tickQueues:[]}}function i(t){return t.machine.states.find(e=>e.name===t.state)}function _(t,e){return t.ons.filter(o=>o.eventName===e[0])}function C(){}function G(t,e){let o=i(t),r=_(o,e).map(n=>n.reactions).flat(),a=r.findIndex(n=>n.type==="Goto"),E=a===-1?r.length-1:a,S=r.slice(0,E+1).map(n=>n.type==="Do"?n.fn:n.type==="Goto"?(p,f,T)=>{T.state=n.targetStateName}:C);c(S).doFunctions.forEach(n=>{n(t.context,e,t)})}var m=function(){},A=function(){};export{D as Do,k as Goto,d as Machine,v as On,m as Spawn,y as State,A as Unspawn,l as interpret,G as send};
var l=function(...t){return{states:t}},g=function(t,...n){return{name:t,eventReactionCouplings:n}},y=function(t,...n){return{eventName:t,reactions:n}},E=function(t){return{type:"SideEffect",fn:t}},S=function(t){return{type:"Goto",targetStateName:t}},v=function(t){return{type:"ContextMutation",fn:t}};function d(t,n){let{state:e,context:i}=n;typeof e>"u"&&(e=t.states[0].name);let o={machine:t,state:e,context:i,eventQueue:[],isTransitioning:!1,subscriptions:{}};return c(o,["entry",null]),o}function T(t){return t.machine.states.find(n=>n.name===t.state)}function p(t,n){return t.eventReactionCouplings.filter(e=>e.eventName===n[0])}function c(t,n){if(t.eventQueue.push(n),t.isTransitioning===!1){for(t.isTransitioning=!0;t.eventQueue.length>0;)_(t);t.isTransitioning=!1,Object.values(t.subscriptions).forEach(e=>{e(t)})}}var C=c;function _(t){let n=t.eventQueue.shift();if(typeof n<"u"){let e=T(t),o=p(e,n).map(a=>a.reactions).flat(),{sideEffects:u,contextMutations:f,goto_:r}=x(o);u.forEach(a=>{a.fn(t.context,n,t)}),f.forEach(a=>{t.context=a.fn(t.context,n,t)}),r!==null&&(c(t,["exit",null]),t.state=r.targetStateName,c(t,["entry",null]))}}function x(t){let n=[],e=[],i=null;return t.forEach(o=>{o.type==="SideEffect"?n.push(o):o.type==="ContextMutation"?e.push(o):o.type==="Goto"&&(i=o)}),{sideEffects:n,contextMutations:e,goto_:i}}var s=0;function M(t,n){return s++,t.subscriptions[s.toString()]=n,s}function b(t,n){delete t.subscriptions[n.toString()]}var h=function(){},R=function(){};export{v as Context,S as Goto,l as Machine,y as On,E as SideEffect,h as Spawn,g as State,R as Unspawn,C as enqueue,d as interpret,c as send,M as subscribe,b as unsubscribe};
//# sourceMappingURL=index.js.map

6
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

@ -43,11 +43,12 @@ export interface Interpreter_T {
context: any;
eventQueue:Array<Event_T>;
isTransitioning: boolean;
subscriptions: Record<string, SubscriptionCallbackFunction_T>
}
export function interpret(machine:Machine_T, options:{state?:string, context:any}) : Interpreter_T{
let {state, context} = options;
if(typeof state === 'undefined'){ state = machine.states[0].name; }
const interpreter = {machine, state, context, eventQueue:[], isTransitioning:false}
const interpreter = {machine, state, context, eventQueue:[], isTransitioning:false, subscriptions: {}}
send(interpreter, ['entry', null] );
return interpreter;
}
@ -80,6 +81,8 @@ export function send(interpreter : Interpreter_T, event:Event_T){
processNextEvent(interpreter);
}
interpreter.isTransitioning = false;
// only run subscriptions here, once the machine's state has settled:
Object.values(interpreter.subscriptions).forEach((subscriptionCallbackFunction)=>{ subscriptionCallbackFunction(interpreter); });
}
}
export const enqueue = send;
@ -102,6 +105,7 @@ function processNextEvent(interpreter:Interpreter_T){
});
// processing of `goto` must be last:
if(goto_ !== null){
send(interpreter, ['exit', null]);
interpreter.state = goto_.targetStateName;
send(interpreter, ['entry', null]);
}
@ -126,5 +130,22 @@ function categorizeReactions(reactions:Array<Reaction_T>) : {sideEffects:Array<S
return {sideEffects, contextMutations, goto_};
}
export type SubscriptionCallbackFunction_T = (self:Interpreter_T)=>void;
let subscriptionId : number = 0;
export function subscribe(interpreter:Interpreter_T, callback:SubscriptionCallbackFunction_T){
subscriptionId++;
interpreter.subscriptions[subscriptionId.toString()] = callback;
return subscriptionId;
}
export function unsubscribe(interpreter:Interpreter_T, subscriptionId:string){
delete interpreter.subscriptions[subscriptionId.toString()];
}
export const Spawn = function(){};
export const Unspawn = function(){};
/*
export function useMachine(machine, options){
return useMemo(()=>interpret(AppMachine, {context:{}}),[]);
}
*/

@ -0,0 +1,7 @@
{
"compilerOptions": {
"emitDeclarationOnly": true,
"declaration": true,
"lib": ["ES2020"]
}
}
Loading…
Cancel
Save