example started

This commit is contained in:
Seth Trowbridge 2023-06-06 22:48:45 -04:00
parent afd760dbfb
commit 083e37a173
4 changed files with 163 additions and 0 deletions

6
example/deno.json Normal file
View File

@ -0,0 +1,6 @@
{
"imports":
{
"react":"https://esm.sh/preact/compat"
}
}

76
hmr/hmr.tsx Normal file
View File

@ -0,0 +1,76 @@
let reloads = 0;
const listeners = new Map() as Map<string, Array<(module:unknown)=>void>>;
const socket:WebSocket = new WebSocket("ws://"+document.location.host);
socket.addEventListener('message', (event) =>
{
let handlers = listeners.get(event.data)??[];
reloads++;
Promise.all(
handlers.map(handler=>
{
return import(event.data+"?reload="+reloads)
.then(updatedModule=>handler(updatedModule));
})
).then(()=>HMR.update());
});
const socketTimer = setInterval(()=>{socket.send("ping")}, 1000);
export const FileListen =(inPath:string, inHandler:()=>void)=>
{
const members = listeners.get(inPath)??[];
members.push(inHandler);
listeners.set(inPath, members);
};
const HMR = {
reloads:0,
registered: new Map() as Map<string, ()=>void>,
states: new Map(),
statesOld: new Map(),
wireframe: false,
onChange(key:string, value:()=>void):void
{
this.registered.set(key, value);
},
update()
{
this.reloads++;
this.registered.forEach(handler=>handler());
this.registered.clear();
this.statesOld = this.states;
this.states = new Map();
this.echoState();
},
echoState()
{
let output = [];
for(const[key, val] of HMR.statesOld)
{
output[key] = val.state+"--"+val.reload;
}
console.log(output);
output = [];
for(const[key, val] of HMR.states)
{
output[key] = val.state+"--"+val.reload;
}
console.log(output);
}
};
export {HMR};
export const MapAt =(inMap, inIndex)=>
{
let index = 0;
for(const kvp of inMap)
{
if(index == inIndex)
{
return kvp;
}
index++;
}
return false;
};

77
hmr/react.tsx Normal file
View File

@ -0,0 +1,77 @@
import * as ReactParts from "react-original";
import { HMR, MapAt } from "./hmr.tsx";
const H = ReactParts.createElement;
const ProxyElement = (props)=>
{
const id = ReactParts.useId();
const [stateGet, stateSet] = ReactParts.useState(0);
ReactParts.useEffect(()=>HMR.onChange(id, ()=>stateSet(stateGet+1)));
const child = H(...props.__args);
if(HMR.wireframe)
{
return H("div", {style:{padding:"10px", border:"2px solid red"}},
H("p", null, stateGet),
child
);
}
else
{
return child;
}
};
const ProxyCreate =(...args)=>
{
return typeof args[0] != "string" ? H(ProxyElement, {__args:args, ...args[1]}) : H(...args);
};
const ProxyState =(arg)=>
{
const id = ReactParts.useId();
const trueArg = arg;
// does statesOld have an entry for this state? use that instead of the passed arg
const check = MapAt(HMR.statesOld, HMR.states.size);
if(check)
{
arg = check[1].state;
console.info(`BOOTING with ${arg}`);
}
const lastKnowReloads = HMR.reloads;
const [stateGet, stateSet] = ReactParts.useState(arg);
ReactParts.useEffect(()=>{
return ()=>{
if(HMR.reloads == lastKnowReloads)
{
// this is a switch/ui change, not a HMR reload change
const oldState = MapAt(HMR.statesOld, HMR.states.size-1);
HMR.statesOld.set(oldState[0], {...oldState[1], state:trueArg});
}
HMR.states.delete(id);
}
}, []);
if(!HMR.states.has(id))
{
HMR.states.set(id, {state:arg, set:stateSet, reload:HMR.reloads});
}
function proxySetter (arg)
{
//console.log("state spy update", id, arg);
HMR.states.set(id, {state:arg, set:stateSet, reload:HMR.reloads});
return stateSet(arg);
}
return [stateGet, proxySetter];
};
export * from "react-original";
export { ProxyCreate as createElement, ProxyState as useState };
export const isProxy = true;
export default {...ReactParts.default, createElement:ProxyCreate, useState:ProxyState, isProxy:true};

View File

@ -84,6 +84,10 @@ HTTP.serve(async(req: Request)=>
{
const url:URL = new URL(req.url);
if(url.pathname.endsWith("/"))
{
}
if(url.pathname === Configure.Reset)
{
return new Response(`cache cleared (${Transpile.Clear()} items)`);