boot-function #1
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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")
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user