add (p)react hooks

main
Avraham Sakal 2 years ago
parent e24f5ff0bf
commit e36049c963

@ -1,8 +1,8 @@
import * as esbuild from 'esbuild'
await esbuild.build({
entryPoints: ['src/index.ts'],
bundle: true,
entryPoints: ['src/index.ts', 'src/react/index.ts', 'src/preact/index.ts'],
bundle: false,
sourcemap: true,
minify: true,
format: 'esm',

2
dist/index.js vendored

@ -1,2 +1,2 @@
var v=function(...t){return{states:t}},A=function(t,...e){return{name:t,eventReactionCouplings:e}},h=function(t,...e){return{eventName:t,reactions:e}},F=function(t){return{type:"SideEffect",fn:t}},M=function(t){return{type:"Goto",targetStateName:t}},k=function(t){return{type:"ContextMutation",fn:t}},R=function(t,e){return{type:"SetPeer",name:t,peerCreationFunction:e}},w=function(t,e){return{type:"SetPeers",name:t,peerCreationFunction:e}},G=function(t,e){return{type:"AddPeers",name:t,peerCreationFunction:e}};function O(t,e,o){typeof o>"u"&&(o=t.states[0].name);let n={machine:t,state:o,context:e,eventQueue:[],isTransitioning:!1,peers:{},peerSubscriptionIds:new Map,subscriptionsToEvents:{},subscriptionsToState:{},subscriptionsToSettledState:{},isPaused:!0};return n.start=()=>(P(n),n),n.Peer=(i,r)=>(f(n,i,r),n),n.Peers=(i,r)=>(S(n,i,r),n),c(n,["entry",null]),n}function P(t){t.isPaused===!0&&(t.isPaused=!1,T(t))}function m(t){t.isPaused===!1&&(t.isPaused=!0)}function l(t){return t.machine.states.find(e=>e.name===t.state)}function y(t,e){return t.eventReactionCouplings.filter(o=>o.eventName===e[0])}function c(t,e){t.eventQueue.push(e),t.isTransitioning===!1&&T(t)}var Q=c;function T(t){for(t.isTransitioning=!0;t.eventQueue.length>0&&t.isPaused===!1;)g(t);t.isTransitioning=!1,Object.values(t.subscriptionsToSettledState).forEach(e=>{e(t)})}function g(t){let e=t.eventQueue.shift();if(typeof e<"u"){let o=l(t),i=y(o,e).map(s=>s.reactions).flat(),{sideEffects:r,contextMutations:u,peerings:d,goto_:p}=b(i),x=t.context;u.forEach(s=>{t.context=s.fn(t.context,e,t)}),p!==null&&(c(t,["exit",null]),t.state=p.targetStateName,Object.values(t.subscriptionsToState).forEach(s=>{s(e,t)}),c(t,["entry",null])),d.forEach(s=>{s.type==="SetPeer"?f(t,s.name,s.peerCreationFunction(t.context,e,t)):s.type==="SetPeers"?S(t,s.name,s.peerCreationFunction(t.context,e,t)):s.type==="AddPeers"&&E(t,s.name,s.peerCreationFunction(t.context,e,t))}),Object.values(t.subscriptionsToEvents).forEach(s=>{s(e,t)}),r.forEach(s=>{s.fn(t.context,e,t,x)})}}function b(t){let e=[],o=[],n=[],i=null;return t.forEach(r=>{r.type==="SideEffect"?e.push(r):r.type==="ContextMutation"?o.push(r):r.type==="SetPeer"||r.type==="SetPeers"||r.type==="AddPeers"?n.push(r):r.type==="Goto"&&(i=r)}),{sideEffects:e,contextMutations:o,peerings:n,goto_:i}}var a=0;function I(t,e){return a++,t.subscriptionsToSettledState[a.toString()]=e,a.toString()}var j=I;function N(t,e){return a++,t.subscriptionsToState[a.toString()]=e,a.toString()}function C(t,e){return a++,t.subscriptionsToEvents[a.toString()]=e,a.toString()}function _(t,e){delete t.subscriptionsToSettledState[e.toString()],delete t.subscriptionsToState[e.toString()],delete t.subscriptionsToEvents[e.toString()]}function f(t,e,o){t.peers.hasOwnProperty(e)&&_(t,t.peerSubscriptionIds.get(t.peers[e])),t.peers[e]=o;let n=C(o,(i,r)=>{t.isTransitioning===!1&&c(t,[e+"."+i[0],i[1]])});t.peerSubscriptionIds.set(o,n)}function S(t,e,o){t.peers.hasOwnProperty(e)&&t.peers[e].forEach(n=>{_(t,t.peerSubscriptionIds.get(n))}),t.peers[e]=o,o.forEach(n=>{let i=C(n,(r,u)=>{t.isTransitioning===!1&&c(t,[e+"."+r[0],r[1]])});t.peerSubscriptionIds.set(n,i)})}function E(t,e,o){t.peers.hasOwnProperty(e)||(t.peers[e]=[]),t.peers[e]=t.peers[e].concat(o),o.forEach(n=>{let i=C(n,(r,u)=>{t.isTransitioning===!1&&c(t,[e+"."+r[0],r[1]])});t.peerSubscriptionIds.set(n,i)})}export{G as AddPeers,k as Context,M as Goto,O as Interpreter,v as Machine,h as On,R as Peer,w as Peers,F as SideEffect,A as State,E as addPeers,Q as enqueue,m as pause,c as send,f as setPeer,S as setPeers,P as start,I as subscribe,C as subscribeToEvents,j as subscribeToSettledState,N as subscribeToState,_ as unsubscribe};
const v=function(...t){return{states:t}},A=function(t,...e){return{name:t,eventReactionCouplings:e}},h=function(t,...e){return{eventName:t,reactions:e}},F=function(t){return{type:"SideEffect",fn:t}},M=function(t){return{type:"Goto",targetStateName:t}},k=function(t){return{type:"ContextMutation",fn:t}},R=function(t,e){return{type:"SetPeer",name:t,peerCreationFunction:e}},w=function(t,e){return{type:"SetPeers",name:t,peerCreationFunction:e}},G=function(t,e){return{type:"AddPeers",name:t,peerCreationFunction:e}};function O(t,e,o){typeof o>"u"&&(o=t.states[0].name);const n={machine:t,state:o,context:e,eventQueue:[],isTransitioning:!1,peers:{},peerSubscriptionIds:new Map,subscriptionsToEvents:{},subscriptionsToState:{},subscriptionsToSettledState:{},isPaused:!0};return n.start=()=>(P(n),n),n.Peer=(i,r)=>(f(n,i,r),n),n.Peers=(i,r)=>(S(n,i,r),n),c(n,["entry",null]),n}function P(t){t.isPaused===!0&&(t.isPaused=!1,T(t))}function m(t){t.isPaused===!1&&(t.isPaused=!0)}function l(t){return t.machine.states.find(e=>e.name===t.state)}function y(t,e){return t.eventReactionCouplings.filter(o=>o.eventName===e[0])}function c(t,e){t.eventQueue.push(e),t.isTransitioning===!1&&T(t)}const Q=c;function T(t){for(t.isTransitioning=!0;t.eventQueue.length>0&&t.isPaused===!1;)g(t);t.isTransitioning=!1,Object.values(t.subscriptionsToSettledState).forEach(e=>{e(t)})}function g(t){const e=t.eventQueue.shift();if(typeof e<"u"){const o=l(t),i=y(o,e).map(s=>s.reactions).flat(),{sideEffects:r,contextMutations:u,peerings:d,goto_:p}=b(i),x=t.context;u.forEach(s=>{t.context=s.fn(t.context,e,t)}),p!==null&&(c(t,["exit",null]),t.state=p.targetStateName,Object.values(t.subscriptionsToState).forEach(s=>{s(e,t)}),c(t,["entry",null])),d.forEach(s=>{s.type==="SetPeer"?f(t,s.name,s.peerCreationFunction(t.context,e,t)):s.type==="SetPeers"?S(t,s.name,s.peerCreationFunction(t.context,e,t)):s.type==="AddPeers"&&E(t,s.name,s.peerCreationFunction(t.context,e,t))}),Object.values(t.subscriptionsToEvents).forEach(s=>{s(e,t)}),r.forEach(s=>{s.fn(t.context,e,t,x)})}}function b(t){let e=[],o=[],n=[],i=null;return t.forEach(r=>{r.type==="SideEffect"?e.push(r):r.type==="ContextMutation"?o.push(r):r.type==="SetPeer"||r.type==="SetPeers"||r.type==="AddPeers"?n.push(r):r.type==="Goto"&&(i=r)}),{sideEffects:e,contextMutations:o,peerings:n,goto_:i}}let a=0;function I(t,e){return a++,t.subscriptionsToSettledState[a.toString()]=e,a.toString()}const j=I;function N(t,e){return a++,t.subscriptionsToState[a.toString()]=e,a.toString()}function C(t,e){return a++,t.subscriptionsToEvents[a.toString()]=e,a.toString()}function _(t,e){delete t.subscriptionsToSettledState[e.toString()],delete t.subscriptionsToState[e.toString()],delete t.subscriptionsToEvents[e.toString()]}function f(t,e,o){t.peers.hasOwnProperty(e)&&_(t,t.peerSubscriptionIds.get(t.peers[e])),t.peers[e]=o;const n=C(o,(i,r)=>{t.isTransitioning===!1&&c(t,[e+"."+i[0],i[1]])});t.peerSubscriptionIds.set(o,n)}function S(t,e,o){t.peers.hasOwnProperty(e)&&t.peers[e].forEach(n=>{_(t,t.peerSubscriptionIds.get(n))}),t.peers[e]=o,o.forEach(n=>{const i=C(n,(r,u)=>{t.isTransitioning===!1&&c(t,[e+"."+r[0],r[1]])});t.peerSubscriptionIds.set(n,i)})}function E(t,e,o){t.peers.hasOwnProperty(e)||(t.peers[e]=[]),t.peers[e]=t.peers[e].concat(o),o.forEach(n=>{const i=C(n,(r,u)=>{t.isTransitioning===!1&&c(t,[e+"."+r[0],r[1]])});t.peerSubscriptionIds.set(n,i)})}export{G as AddPeers,k as Context,M as Goto,O as Interpreter,v as Machine,h as On,R as Peer,w as Peers,F as SideEffect,A as State,E as addPeers,Q as enqueue,m as pause,c as send,f as setPeer,S as setPeers,P as start,I as subscribe,C as subscribeToEvents,j as subscribeToSettledState,N as subscribeToState,_ as unsubscribe};
//# sourceMappingURL=index.js.map

2
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

@ -0,0 +1,2 @@
import { Interpreter_T } from '../index';
export declare function useInterpreter<C>(createInterpreter: () => Interpreter_T<C>): Interpreter_T<C>;

@ -0,0 +1,2 @@
import{subscribeToEvents as o,unsubscribe as i}from"../index";import{useMemo as c,useState as p,useEffect as b,useCallback as g}from"preact/hooks";let n=0;function d(s){const e=c(s,[]),[a,r]=p(n),t=g(()=>{r(n++)},[r]);return b(()=>{const u=o(e,t);return()=>{i(e,u)}},[t]),e}export{d as useInterpreter};
//# sourceMappingURL=index.js.map

@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/preact/index.ts"],
"sourcesContent": ["import { Interpreter_T, subscribeToEvents, unsubscribe } from '../index';\nimport { useMemo, useState, useEffect, useCallback } from 'preact/hooks';\n\n// need to use an integer instead of toggling a boolean back and forth; probably a bug with useState():\nlet i=0;\nexport function useInterpreter<C>(createInterpreter:()=>Interpreter_T<C>){\n const interpreter = useMemo(createInterpreter,[]);\n // some variable whose value to switch whenever we want to trigger a re-render:\n const [triggerRenderValue, setTriggerRenderValue] = useState(i);\n const triggerRender = useCallback(()=>{ setTriggerRenderValue(i++); }, [setTriggerRenderValue]);\n // ensure only one subscription is ever made, and destroy it when the component unloads:\n useEffect(()=>{\n const subscriptionId = subscribeToEvents(interpreter, triggerRender);\n return ()=>{ unsubscribe(interpreter, subscriptionId); };\n },[triggerRender]);\n return interpreter;\n}"],
"mappings": "AAAA,OAAwB,qBAAAA,EAAmB,eAAAC,MAAmB,WAC9D,OAAS,WAAAC,EAAS,YAAAC,EAAU,aAAAC,EAAW,eAAAC,MAAmB,eAG1D,IAAIC,EAAE,EACC,SAASC,EAAkBC,EAAuC,CACvE,MAAMC,EAAcP,EAAQM,EAAkB,CAAC,CAAC,EAE1C,CAACE,EAAoBC,CAAqB,EAAIR,EAASG,CAAC,EACxDM,EAAgBP,EAAY,IAAI,CAAEM,EAAsBL,GAAG,CAAG,EAAG,CAACK,CAAqB,CAAC,EAE9F,OAAAP,EAAU,IAAI,CACZ,MAAMS,EAAiBb,EAAkBS,EAAaG,CAAa,EACnE,MAAO,IAAI,CAAEX,EAAYQ,EAAaI,CAAc,CAAG,CACzD,EAAE,CAACD,CAAa,CAAC,EACVH,CACT",
"names": ["subscribeToEvents", "unsubscribe", "useMemo", "useState", "useEffect", "useCallback", "i", "useInterpreter", "createInterpreter", "interpreter", "triggerRenderValue", "setTriggerRenderValue", "triggerRender", "subscriptionId"]
}

@ -0,0 +1,2 @@
import { Interpreter_T } from '../index';
export declare function useInterpreter<C>(createInterpreter: () => Interpreter_T<C>): any;

@ -0,0 +1,2 @@
import{subscribeToEvents as o,unsubscribe as i}from"../index";import{useMemo as c,useState as p,useEffect as b,useCallback as g}from"react";let n=0;function d(s){const e=c(s,[]),[a,r]=p(n),t=g(()=>{r(n++)},[r]);return b(()=>{const u=o(e,t);return()=>{i(e,u)}},[t]),e}export{d as useInterpreter};
//# sourceMappingURL=index.js.map

@ -0,0 +1,7 @@
{
"version": 3,
"sources": ["../../src/react/index.ts"],
"sourcesContent": ["import { Interpreter_T, subscribeToEvents, unsubscribe } from '../index';\nimport { useMemo, useState, useEffect, useCallback } from 'react';\n\n// need to use an integer instead of toggling a boolean back and forth; probably a bug with useState():\nlet i=0;\nexport function useInterpreter<C>(createInterpreter:()=>Interpreter_T<C>){\n const interpreter = useMemo(createInterpreter,[]);\n // some variable whose value to switch whenever we want to trigger a re-render:\n const [triggerRenderValue, setTriggerRenderValue] = useState(i);\n const triggerRender = useCallback(()=>{ setTriggerRenderValue(i++); }, [setTriggerRenderValue]);\n // ensure only one subscription is ever made, and destroy it when the component unloads:\n useEffect(()=>{\n const subscriptionId = subscribeToEvents(interpreter, triggerRender);\n return ()=>{ unsubscribe(interpreter, subscriptionId); };\n },[triggerRender]);\n return interpreter;\n}"],
"mappings": "AAAA,OAAwB,qBAAAA,EAAmB,eAAAC,MAAmB,WAC9D,OAAS,WAAAC,EAAS,YAAAC,EAAU,aAAAC,EAAW,eAAAC,MAAmB,QAG1D,IAAIC,EAAE,EACC,SAASC,EAAkBC,EAAuC,CACvE,MAAMC,EAAcP,EAAQM,EAAkB,CAAC,CAAC,EAE1C,CAACE,EAAoBC,CAAqB,EAAIR,EAASG,CAAC,EACxDM,EAAgBP,EAAY,IAAI,CAAEM,EAAsBL,GAAG,CAAG,EAAG,CAACK,CAAqB,CAAC,EAE9F,OAAAP,EAAU,IAAI,CACZ,MAAMS,EAAiBb,EAAkBS,EAAaG,CAAa,EACnE,MAAO,IAAI,CAAEX,EAAYQ,EAAaI,CAAc,CAAG,CACzD,EAAE,CAACD,CAAa,CAAC,EACVH,CACT",
"names": ["subscribeToEvents", "unsubscribe", "useMemo", "useState", "useEffect", "useCallback", "i", "useInterpreter", "createInterpreter", "interpreter", "triggerRenderValue", "setTriggerRenderValue", "triggerRender", "subscriptionId"]
}

@ -7,7 +7,18 @@
"type": "module",
"types": "./dist/index.d.ts",
"exports": {
"import": "./dist/index.js"
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js"
},
"./react": {
"types": "./dist/react/index.d.ts",
"import": "./dist/react/index.js"
},
"./preact": {
"types": "./dist/preact/index.d.ts",
"import": "./dist/preact/index.js"
}
},
"scripts": {
"build": "node build.mjs",
@ -19,5 +30,9 @@
"@types/node": "^20.1.4",
"esbuild": "^0.17.18",
"typescript": "^5.0.4"
},
"peerDependencies": {
"preact": "^10.14.1",
"react": "^18.2.0"
}
}

@ -0,0 +1,17 @@
import { Interpreter_T, subscribeToEvents, unsubscribe } from '../index';
import { useMemo, useState, useEffect, useCallback } from 'preact/hooks';
// need to use an integer instead of toggling a boolean back and forth; probably a bug with useState():
let i=0;
export function useInterpreter<C>(createInterpreter:()=>Interpreter_T<C>){
const interpreter = useMemo(createInterpreter,[]);
// some variable whose value to switch whenever we want to trigger a re-render:
const [triggerRenderValue, setTriggerRenderValue] = useState(i);
const triggerRender = useCallback(()=>{ setTriggerRenderValue(i++); }, [setTriggerRenderValue]);
// ensure only one subscription is ever made, and destroy it when the component unloads:
useEffect(()=>{
const subscriptionId = subscribeToEvents(interpreter, triggerRender);
return ()=>{ unsubscribe(interpreter, subscriptionId); };
},[triggerRender]);
return interpreter;
}

@ -0,0 +1,17 @@
import { Interpreter_T, subscribeToEvents, unsubscribe } from '../index';
import { useMemo, useState, useEffect, useCallback } from 'react';
// need to use an integer instead of toggling a boolean back and forth; probably a bug with useState():
let i=0;
export function useInterpreter<C>(createInterpreter:()=>Interpreter_T<C>){
const interpreter = useMemo(createInterpreter,[]);
// some variable whose value to switch whenever we want to trigger a re-render:
const [triggerRenderValue, setTriggerRenderValue] = useState(i);
const triggerRender = useCallback(()=>{ setTriggerRenderValue(i++); }, [setTriggerRenderValue]);
// ensure only one subscription is ever made, and destroy it when the component unloads:
useEffect(()=>{
const subscriptionId = subscribeToEvents(interpreter, triggerRender);
return ()=>{ unsubscribe(interpreter, subscriptionId); };
},[triggerRender]);
return interpreter;
}

@ -145,6 +145,30 @@ esbuild@^0.17.18:
"@esbuild/win32-ia32" "0.17.18"
"@esbuild/win32-x64" "0.17.18"
"js-tokens@^3.0.0 || ^4.0.0":
version "4.0.0"
resolved "https://verdaccio.torahanytime.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
loose-envify@^1.1.0:
version "1.4.0"
resolved "https://verdaccio.torahanytime.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
dependencies:
js-tokens "^3.0.0 || ^4.0.0"
preact@^10.14.1:
version "10.14.1"
resolved "https://verdaccio.torahanytime.com/preact/-/preact-10.14.1.tgz#1e15ef6a09e241a48d12c872b90557914b03abac"
integrity sha512-4XDSnUisk3YFBb3p9WeKeH1mKoxdFUsaXcvxs9wlpYR1wax/TWJVqhwmIWbByX0h7jMEJH6Zc5J6jqc58FKaNQ==
react@^18.2.0:
version "18.2.0"
resolved "https://verdaccio.torahanytime.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
dependencies:
loose-envify "^1.1.0"
typescript@^5.0.4:
version "5.0.4"
resolved "https://verdaccio.torahanytime.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b"

Loading…
Cancel
Save