moe cleanup

This commit is contained in:
Seth Trowbridge 2023-06-17 14:48:39 -04:00
parent 73cefa9a0e
commit 24ba4e8f5b
3 changed files with 36 additions and 36 deletions

View File

@ -1,7 +1,7 @@
import { type StateCapture } from "./react.tsx"; import { type StateCapture } from "./react.tsx";
type FileHandler = (module:unknown)=>void
const FileListeners = new Map() as Map<string, Array<FileHandler>>; const FileListeners = new Map() as Map<string, Array<(module:unknown)=>void>>;
export const FileListen =(inPath:string, inHandler:()=>void)=> export const FileListen =(inPath:string, inHandler:()=>void)=>
{ {
const members = FileListeners.get(inPath)??[]; const members = FileListeners.get(inPath)??[];
@ -10,37 +10,34 @@ export const FileListen =(inPath:string, inHandler:()=>void)=>
}; };
const Socket:WebSocket = new WebSocket("ws://"+document.location.host); const Socket:WebSocket = new WebSocket("ws://"+document.location.host);
Socket.addEventListener('message', (event:{data:string})=> Socket.addEventListener('message', async(event:{data:string})=>
{ {
// When a file changes, dynamically re-import it to get the updated members
// send the updated members to any listeners for that file
const reImport = await import(event.data+"?reload="+HMR.reloads);
const handlers = FileListeners.get(event.data)??[]; const handlers = FileListeners.get(event.data)??[];
SocketReloads++; handlers.forEach(handler=>handler(reImport));
Promise.all( HMR.update();
handlers.map((handler)=>
{
return import(event.data+"?reload="+SocketReloads)
.then(updatedModule=>handler(updatedModule));
})
).then(()=>HMR.update());
}); });
let SocketReloads = 0; Socket.addEventListener("error", ()=>{clearInterval(SocketTimer); console.log("HRM socket lost")})
// heartbeat
const SocketTimer = setInterval(()=>{Socket.send("ping")}, 5000); const SocketTimer = setInterval(()=>{Socket.send("ping")}, 5000);
const HMR = { const HMR =
reloads:0, {
createdElements: new Map() as Map<string, ()=>void>, reloads:1,
RegisteredComponents: new Map() as Map<string, ()=>void>,
statesNew: new Map() as Map<string, StateCapture>, statesNew: new Map() as Map<string, StateCapture>,
statesOld: new Map() as Map<string, StateCapture>, statesOld: new Map() as Map<string, StateCapture>,
wireframe: false, wireframe: false,
onChange(reactID:string, value:()=>void):void RegisterComponent(reactID:string, value:()=>void):void
{ {
this.createdElements.set(reactID, value); this.RegisteredComponents.set(reactID, value);
}, },
update() update()
{ {
this.reloads++; this.reloads++;
this.createdElements.forEach(handler=>handler()); this.RegisteredComponents.forEach(handler=>handler());
this.createdElements.clear(); this.RegisteredComponents.clear();
this.statesOld = this.statesNew; this.statesOld = this.statesNew;
this.statesNew = new Map(); this.statesNew = new Map();
} }

View File

@ -20,11 +20,24 @@ const MapAt =(inMap:Map<string, StateCapture>, inIndex:number)=>
return false; return false;
}; };
const ProxyCreate =(...args:FuncArgs)=>
{
if(typeof args[0] == "string")
{
return H(...args)
}
else
{
return H(ProxyElement, {__args:args, ...args[1]});
}
};
const ProxyElement = (props:{__args:FuncArgs})=> const ProxyElement = (props:{__args:FuncArgs})=>
{ {
const id = ReactParts.useId();
const [stateGet, stateSet] = ReactParts.useState(0); const [stateGet, stateSet] = ReactParts.useState(0);
ReactParts.useEffect(()=>HMR.onChange(id, ()=>stateSet(stateGet+1))); const id = ReactParts.useId();
HMR.RegisterComponent(id, ()=>stateSet(stateGet+1));
const child = H(...props.__args); const child = H(...props.__args);
@ -37,37 +50,27 @@ const ProxyElement = (props:{__args:FuncArgs})=>
} }
else else
{ {
return child; return child;
} }
}; };
const ProxyCreate =(...args:FuncArgs)=>
{
return typeof args[0] != "string" ? H(ProxyElement, {__args:args, ...args[1]}) : H(...args);
};
const ProxyState =(arg:StateType)=> const ProxyState =(arg:StateType)=>
{ {
const id = ReactParts.useId(); const id = ReactParts.useId();
const trueArg = arg;
// does statesOld have an entry for this state? use that instead of the passed arg // does statesOld have an entry for this state? use that instead of the passed arg
const check = MapAt(HMR.statesOld, HMR.statesNew.size); const check = MapAt(HMR.statesOld, HMR.statesNew.size);
if(check)
{
arg = check[1].state;
console.info(`BOOTING with ${arg}`);
}
const lastKnowReloads = HMR.reloads; const lastKnowReloads = HMR.reloads;
const [stateGet, stateSet] = ReactParts.useState(arg); const [stateGet, stateSet] = ReactParts.useState(check ? check[1].state : arg);
ReactParts.useEffect(()=>{ ReactParts.useEffect(()=>{
return ()=>{ return ()=>{
if(HMR.reloads == lastKnowReloads) if(HMR.reloads == lastKnowReloads)
{ {
// this is a switch/ui change, not a HMR reload change // this is a switch/ui change, not a HMR reload change
const oldState = MapAt(HMR.statesOld, HMR.statesNew.size-1); const oldState = MapAt(HMR.statesOld, HMR.statesNew.size-1);
oldState && HMR.statesOld.set(oldState[0], {...oldState[1], state:trueArg}); oldState && HMR.statesOld.set(oldState[0], {...oldState[1], state:arg});
console.log("check: ui-invoked") console.log("check: ui-invoked")
} }

View File

@ -28,7 +28,7 @@ const Inner =()=>
export default ()=> export default ()=>
{ {
return <CTXString.Provider value="intradestink"> return <CTXString.Provider value="intradestink">
<div><h1>hey???</h1></div> <div><h1>Title</h1></div>
<Outer> <Outer>
<Inner/> <Inner/>
</Outer> </Outer>