boot-function #1
							
								
								
									
										6
									
								
								example/deno.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								example/deno.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					    "imports":
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        "react":"https://esm.sh/preact/compat"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										76
									
								
								hmr/hmr.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								hmr/hmr.tsx
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										77
									
								
								hmr/react.tsx
									
									
									
									
									
										Normal 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};
 | 
				
			||||||
@ -84,6 +84,10 @@ HTTP.serve(async(req: Request)=>
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    const url:URL = new URL(req.url);
 | 
					    const url:URL = new URL(req.url);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(url.pathname.endsWith("/"))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    if(url.pathname === Configure.Reset)
 | 
					    if(url.pathname === Configure.Reset)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return new Response(`cache cleared (${Transpile.Clear()} items)`);
 | 
					        return new Response(`cache cleared (${Transpile.Clear()} items)`);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user