deprecate-deno-deploy #24
@ -4,9 +4,8 @@
 | 
			
		||||
    ]},
 | 
			
		||||
    "imports": {
 | 
			
		||||
        "react": "https://esm.sh/preact@10.13.2/compat",
 | 
			
		||||
        
 | 
			
		||||
        "preact": "https://esm.sh/preact@10.13.2/compat",
 | 
			
		||||
        "react-original": "https://esm.sh/preact@10.13.2/compat",
 | 
			
		||||
        "@eno/app": "./example/app.tsx",
 | 
			
		||||
        "@eno/iso": "./lib/iso.tsx"
 | 
			
		||||
    },
 | 
			
		||||
    "tasks":
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										16
									
								
								deno.lock
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								deno.lock
									
									
									
									
									
								
							@ -1,16 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
  "version": "2",
 | 
			
		||||
  "remote": {
 | 
			
		||||
    "http://localhost:4507/lib/iso.tsx": "edf1cf4c539900040c75824eac8472e0ec43098b13af4049bd79ddbd76a5346d",
 | 
			
		||||
    "https://esm.sh/preact@10.13.2/compat": "1cf68e0c8c6c84b60d42f30665403b67229c16ff5206824709b19df60ba9cdc3",
 | 
			
		||||
    "https://esm.sh/stable/preact@10.13.2/deno/compat.js": "3151a948abd84aa75dfc9e57733da7e1a45fff7a25de58c7b6025b923874b508",
 | 
			
		||||
    "https://esm.sh/stable/preact@10.13.2/deno/hooks.js": "c7a8e703bcbc6a05949f329b618c33d5d1ea5fee113ddcea44ff0f527af8556f",
 | 
			
		||||
    "https://esm.sh/stable/preact@10.13.2/deno/preact.mjs": "365fab897381f4f403f859c5d12939084560545567108cc90dae901bbe892578",
 | 
			
		||||
    "https://esm.sh/v116/preact@10.13.2/compat/src/index.d.ts": "d02f015638a40e32649151e011cfda7b520d66f7fbd3c12a28fa03de2a5e1421",
 | 
			
		||||
    "https://esm.sh/v116/preact@10.13.2/compat/src/suspense-list.d.ts": "b8e274324392157ce476ef3a48ae215c9f7003b08525d140645f19eab20d1948",
 | 
			
		||||
    "https://esm.sh/v116/preact@10.13.2/compat/src/suspense.d.ts": "81f5266e0977a94347505d11b8103024211f2b4f3b2eb2aa276a10d8fd169e65",
 | 
			
		||||
    "https://esm.sh/v116/preact@10.13.2/hooks/src/index.d.ts": "5c29febb624fc25d71cb0e125848c9b711e233337a08f7eacfade38fd4c14cc3",
 | 
			
		||||
    "https://esm.sh/v116/preact@10.13.2/src/index.d.ts": "65398710de6aa0a07412da79784e05e6e96763f51c7c91b77344d2d0af06385c",
 | 
			
		||||
    "https://esm.sh/v116/preact@10.13.2/src/jsx.d.ts": "9ac9b82c199fa7b04748807d750eba1a106c0be52041b8617416f88d6fc0a257"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -3,34 +3,36 @@ import * as Iso from "@eno/iso";
 | 
			
		||||
 | 
			
		||||
const Comp = React.lazy(()=>import("./deep/component.tsx"));
 | 
			
		||||
 | 
			
		||||
export default ()=>
 | 
			
		||||
{
 | 
			
		||||
    return <div class="p-4 font-sans">
 | 
			
		||||
        <Iso.Meta.Metas title="Main Page!"/>
 | 
			
		||||
        <nav class="p-4">
 | 
			
		||||
            <a class="text-red-500" href="/">Home</a>
 | 
			
		||||
            <a href="/about">About</a>
 | 
			
		||||
        </nav>
 | 
			
		||||
 | 
			
		||||
        <h1 class="my-2 font(bold serif) text(3xl)">Title!!</h1>
 | 
			
		||||
        <h2>suspended:</h2>
 | 
			
		||||
        <React.Suspense fallback={<div>Loading!</div>}>
 | 
			
		||||
            <Comp/>
 | 
			
		||||
        </React.Suspense>
 | 
			
		||||
        <Iso.Switch>
 | 
			
		||||
            <Iso.Case value="page">
 | 
			
		||||
                <Iso.Switch>
 | 
			
		||||
                    <Iso.Case value="about-us">
 | 
			
		||||
                        <>
 | 
			
		||||
                            <Iso.Meta.Metas title="About US"/>
 | 
			
		||||
                            About us!
 | 
			
		||||
                        </>
 | 
			
		||||
                    </Iso.Case>
 | 
			
		||||
                    <Iso.Case default>sorry no page</Iso.Case>
 | 
			
		||||
                </Iso.Switch>
 | 
			
		||||
            </Iso.Case>
 | 
			
		||||
            <Iso.Case value="lol/idk">lol/idk</Iso.Case>
 | 
			
		||||
            <Iso.Case default><p>404!</p></Iso.Case>
 | 
			
		||||
        </Iso.Switch>
 | 
			
		||||
    </div>;
 | 
			
		||||
};
 | 
			
		||||
Iso.Boot(
 | 
			
		||||
    ()=>
 | 
			
		||||
    {
 | 
			
		||||
        return <div class="p-4 font-sans">
 | 
			
		||||
            <Iso.Meta.Metas title="Main Page!"/>
 | 
			
		||||
            <nav class="p-4">
 | 
			
		||||
                <a class="text-red-500" href="/">Home</a>
 | 
			
		||||
                <a href="/about">About</a>
 | 
			
		||||
            </nav>
 | 
			
		||||
    
 | 
			
		||||
            <h1 class="my-2 font(bold serif) text(3xl)">Title!!!!!!</h1>
 | 
			
		||||
            <h2>suspended:</h2>
 | 
			
		||||
            <React.Suspense fallback={<div>Loading!</div>}>
 | 
			
		||||
                <Comp/>
 | 
			
		||||
            </React.Suspense>
 | 
			
		||||
            <Iso.Switch>
 | 
			
		||||
                <Iso.Case value="page">
 | 
			
		||||
                    <Iso.Switch>
 | 
			
		||||
                        <Iso.Case value="about-us">
 | 
			
		||||
                            <>
 | 
			
		||||
                                <Iso.Meta.Metas title="About US"/>
 | 
			
		||||
                                About us!
 | 
			
		||||
                            </>
 | 
			
		||||
                        </Iso.Case>
 | 
			
		||||
                        <Iso.Case default>sorry no page</Iso.Case>
 | 
			
		||||
                    </Iso.Switch>
 | 
			
		||||
                </Iso.Case>
 | 
			
		||||
                <Iso.Case value="lol/idk">lol/idk</Iso.Case>
 | 
			
		||||
                <Iso.Case default><p>404!</p></Iso.Case>
 | 
			
		||||
            </Iso.Switch>
 | 
			
		||||
        </div>;
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
@ -5,10 +5,9 @@
 | 
			
		||||
        "react": "https://esm.sh/stable/preact@10.13.2/compat",
 | 
			
		||||
        "preact": "https://esm.sh/stable/preact@10.13.2/",
 | 
			
		||||
        "@deep/": "./deep/",
 | 
			
		||||
        "@eno/app": "./app.tsx",
 | 
			
		||||
        "@eno/iso": "http://localhost:4507/lib/iso.tsx"
 | 
			
		||||
    },
 | 
			
		||||
    "tasks": {
 | 
			
		||||
        "dev": "deno run -A --unstable --reload=http://localhost:4507/ --no-lock app.tsx --dev"
 | 
			
		||||
        "dev": "deno run -A --unstable --reload=http://localhost:4507/ --no-lock app.tsx"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,35 +0,0 @@
 | 
			
		||||
import {Fetch} from "./lib/iso.tsx";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const delay =async(inHandler:()=>void, inDelay:number):Promise<void>=>
 | 
			
		||||
{
 | 
			
		||||
    return new Promise((accept)=>{
 | 
			
		||||
        setTimeout(()=>{
 | 
			
		||||
            accept(inHandler());
 | 
			
		||||
        }, inDelay);
 | 
			
		||||
    });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const queue = [1, 2, 3];
 | 
			
		||||
while(queue.length)
 | 
			
		||||
{
 | 
			
		||||
    await(delay(()=>{console.log(queue.pop())}, 1000))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
console.log("all done!");
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
let r1, r2, r3;
 | 
			
		||||
 | 
			
		||||
delay(()=>{r1 = Fetch.Request(`https://catfact.ninja/fact`, undefined, 0.2); console.log(r1); }, 10);
 | 
			
		||||
delay(()=>{r2 = Fetch.Request(`https://catfact.ninja/fact`, undefined, 0.2); console.log(r2); }, 20);
 | 
			
		||||
delay(()=>{r3 = Fetch.Request(`https://catfact.ninja/fact`, undefined, 0.2); console.log(r3); }, 2000);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
await delay(()=>{}, 3000);
 | 
			
		||||
 | 
			
		||||
console.log(r1);
 | 
			
		||||
console.log(r2);
 | 
			
		||||
console.log(r3);
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
							
								
								
									
										30
									
								
								lib/boot-client.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								lib/boot-client.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,30 @@
 | 
			
		||||
import React, {hydrate} from "react";
 | 
			
		||||
import * as Twind from "https://esm.sh/v115/@twind/core@1.1.3/es2022/core.mjs";
 | 
			
		||||
import {Router, CSS, Meta} from "@eno/iso";
 | 
			
		||||
 | 
			
		||||
export function Boot(inApp:()=>React.JSX.Element, inCSS?:object)
 | 
			
		||||
{
 | 
			
		||||
    console.log(inApp, inCSS);
 | 
			
		||||
    Twind.install(inCSS ? {...CSS, ...inCSS} : CSS);
 | 
			
		||||
 | 
			
		||||
    const HMRWrap =()=> React.createElement(inApp, null, null);
 | 
			
		||||
 | 
			
		||||
    const root = document.querySelector("#app");
 | 
			
		||||
 | 
			
		||||
    if(root)
 | 
			
		||||
    {
 | 
			
		||||
        hydrate(
 | 
			
		||||
            <Router.Provider url={new URL(window.location.href)}>
 | 
			
		||||
                <Meta.Provider>
 | 
			
		||||
                    <HMRWrap/>
 | 
			
		||||
                </Meta.Provider>
 | 
			
		||||
            </Router.Provider>,
 | 
			
		||||
            root
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        console.log(`no "#app" element is present!`)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
@ -1,17 +1,20 @@
 | 
			
		||||
import TWPreTail from "https://esm.sh/v115/@twind/preset-tailwind@1.1.4/es2022/preset-tailwind.mjs";
 | 
			
		||||
import TWPreAuto from "https://esm.sh/v115/@twind/preset-autoprefix@1.0.7/es2022/preset-autoprefix.mjs";
 | 
			
		||||
import React from "react";
 | 
			
		||||
import { Boot as _Boot } from "../server.tsx";
 | 
			
		||||
 | 
			
		||||
export const CSS = {
 | 
			
		||||
    presets: [TWPreTail(), TWPreAuto()],
 | 
			
		||||
    hash:false
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
if(!window.innerWidth)
 | 
			
		||||
 | 
			
		||||
export function Boot(inApp:React.FunctionComponent, inCSS?:object)
 | 
			
		||||
{
 | 
			
		||||
    import(import.meta.resolve("../../server.tsx")).then(()=>{console.log("...imported!");});
 | 
			
		||||
    _Boot(inApp, inCSS);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
type MetasInputs = { [Property in MetaKeys]?: string };
 | 
			
		||||
type MetasModeArgs = {concatListed?:boolean; dropUnlisted?:boolean};
 | 
			
		||||
type MetasStackItem = MetasModeArgs&MetasInputs&{id:string, depth:number}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										0
									
								
								lib/mid.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								lib/mid.tsx
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										323
									
								
								server.tsx
									
									
									
									
									
								
							
							
						
						
									
										323
									
								
								server.tsx
									
									
									
									
									
								
							@ -2,14 +2,13 @@ import * as ESBuild from 'https://deno.land/x/esbuild@v0.17.4/mod.js';
 | 
			
		||||
import * as MIME from "https://deno.land/std@0.180.0/media_types/mod.ts";
 | 
			
		||||
import { debounce } from "https://deno.land/std@0.151.0/async/debounce.ts";
 | 
			
		||||
import { parse as JSONC} from "https://deno.land/std@0.185.0/jsonc/mod.ts";
 | 
			
		||||
import { toFileUrl } from "https://deno.land/std@0.185.0/path/mod.ts";
 | 
			
		||||
import SSR from "https://esm.sh/v113/preact-render-to-string@6.0.2";
 | 
			
		||||
import Prepass from "https://esm.sh/preact-ssr-prepass@1.2.0";
 | 
			
		||||
import * as Twind from "https://esm.sh/@twind/core@1.1.3";
 | 
			
		||||
import React from "react";
 | 
			
		||||
import * as Iso from "@eno/iso";
 | 
			
		||||
 | 
			
		||||
Deno.env.set("initialized", "true");
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Setup a transpiler.
 | 
			
		||||
 * @param inDevMode When true, starts a file-watcher
 | 
			
		||||
@ -134,6 +133,7 @@ function Transpiler(inDevMode:boolean)
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ImportMap = {imports?:Record<string, string>, importMap?:string};
 | 
			
		||||
/**
 | 
			
		||||
 * Extract all configuration info form a project's deno.jsonc file
 | 
			
		||||
 * @param inDevMode When true, proxies react to an HMR-enabled version
 | 
			
		||||
@ -142,8 +142,7 @@ function Transpiler(inDevMode:boolean)
 | 
			
		||||
 */
 | 
			
		||||
async function Configure(inDevMode:boolean, inLibPath:string)
 | 
			
		||||
{
 | 
			
		||||
    type ImportMap = {imports?:Record<string, string>, importMap?:string};
 | 
			
		||||
    const output:{Imports?:ImportMap, App?:React.FunctionComponent, TwindInst?:Twind.Twind, Error?:string} = {};
 | 
			
		||||
    const output:{Imports?:ImportMap, Error?:string} = {};
 | 
			
		||||
    let ImportObject:ImportMap = {};
 | 
			
		||||
    try
 | 
			
		||||
    {
 | 
			
		||||
@ -204,52 +203,6 @@ async function Configure(inDevMode:boolean, inLibPath:string)
 | 
			
		||||
                return output;
 | 
			
		||||
            }
 | 
			
		||||
    
 | 
			
		||||
            const importApp = output.Imports.imports["@eno/app"];
 | 
			
		||||
            if(importApp)
 | 
			
		||||
            {
 | 
			
		||||
                let appImport 
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    appImport = await import(Path.Active+importApp);
 | 
			
		||||
                }
 | 
			
		||||
                catch(e)
 | 
			
		||||
                {
 | 
			
		||||
                    output.Error = `"@eno/app" entry-point (${importApp}) file not found`;
 | 
			
		||||
                    return output;
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
                if(typeof appImport.default == "function" )
 | 
			
		||||
                {
 | 
			
		||||
                    output.App = appImport.default;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    output.Error = `"@eno/app" entry-point (${importApp}) needs to export a default function to use as the app root.`;
 | 
			
		||||
                    return output;
 | 
			
		||||
                }
 | 
			
		||||
    
 | 
			
		||||
                let twindConfig = Iso.CSS;
 | 
			
		||||
                if(typeof appImport.CSS == "object")
 | 
			
		||||
                {
 | 
			
		||||
                    twindConfig = {...twindConfig, ...appImport.CSS};
 | 
			
		||||
                }
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    // @ts-ignore
 | 
			
		||||
                    output.TwindInst = Twind.install(twindConfig);
 | 
			
		||||
                }
 | 
			
		||||
                catch(e)
 | 
			
		||||
                {
 | 
			
		||||
                    output.Error = `CSS configuration is malformed`;
 | 
			
		||||
                    return output;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                output.Error = `"imports" configuration does not alias an entry-point file as "@eno/app"`;
 | 
			
		||||
                return output;
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
    
 | 
			
		||||
            Object.entries(output.Imports.imports).forEach(([key, value])=>{
 | 
			
		||||
                if(value.startsWith("./") && output.Imports?.imports)
 | 
			
		||||
@ -272,158 +225,180 @@ async function Configure(inDevMode:boolean, inLibPath:string)
 | 
			
		||||
    return output;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const Flags:Record<string, string|boolean> = {};
 | 
			
		||||
Deno.args.forEach(arg=>
 | 
			
		||||
{
 | 
			
		||||
    if(arg.startsWith("--"))
 | 
			
		||||
    {
 | 
			
		||||
        const kvp = arg.substring(2).split("=");
 | 
			
		||||
        Flags[kvp[0]] = kvp[1] ? kvp[1] : true; 
 | 
			
		||||
        Deno.env.set(kvp[0], kvp[1] ? kvp[1] : "true");
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
let DevMode = Flags.dev ? true : false;
 | 
			
		||||
let DevMode = Deno.env.get("dev") ? true : false;
 | 
			
		||||
let hosted = import.meta.resolve("./");
 | 
			
		||||
const Path = {
 | 
			
		||||
    Hosted: hosted.substring(0, hosted.length-1),
 | 
			
		||||
    Active: `file://${Deno.cwd().replaceAll("\\", "/")}`,
 | 
			
		||||
    LibDir: "lib"
 | 
			
		||||
    LibDir: "lib",
 | 
			
		||||
    AppDir: ""
 | 
			
		||||
};
 | 
			
		||||
console.log(Path);
 | 
			
		||||
console.log(`Dev Mode: ${DevMode}`);
 | 
			
		||||
console.log(`Args seen: `, Flags);
 | 
			
		||||
console.log(`Dev Mode:`, DevMode);
 | 
			
		||||
console.log(`import.meta.url:`, import.meta.url);
 | 
			
		||||
console.log(`Deno.cwd():`, Deno.cwd());
 | 
			
		||||
console.log(`Deno.mainModule:`, Deno.mainModule);
 | 
			
		||||
 | 
			
		||||
const {Transpileable, TranspileURL, SocketsHandler} = Transpiler(DevMode);
 | 
			
		||||
const {Imports, App, TwindInst, Error} = await Configure(DevMode, Path.LibDir);
 | 
			
		||||
if(Error)
 | 
			
		||||
 | 
			
		||||
let Booted = false;
 | 
			
		||||
let TwindInst:Twind.Twind;
 | 
			
		||||
export function Boot(inApp:React.FunctionComponent, inCSS?:object)
 | 
			
		||||
{
 | 
			
		||||
    console.log(Error);
 | 
			
		||||
    if(Booted){return;}
 | 
			
		||||
    Booted = true;
 | 
			
		||||
 | 
			
		||||
    const pathInit = Deno.mainModule;
 | 
			
		||||
    const pathProj = toFileUrl(Deno.cwd());
 | 
			
		||||
    
 | 
			
		||||
    //@ts-ignore
 | 
			
		||||
    TwindInst = Twind.install({...Iso.CSS, ...inCSS||{}});
 | 
			
		||||
 | 
			
		||||
    const App = inApp;
 | 
			
		||||
    Path.AppDir = pathInit.split(pathProj.toString())[1];
 | 
			
		||||
 | 
			
		||||
    Server(App, Path.AppDir, TwindInst);
 | 
			
		||||
}
 | 
			
		||||
else if(App && TwindInst)
 | 
			
		||||
 | 
			
		||||
async function Server(App:React.FunctionComponent, AppPath:string, TwindInst:Twind.Twind)
 | 
			
		||||
{
 | 
			
		||||
    Deno.serve({ port: Flags?.port||3000 }, async(_req:Request) =>
 | 
			
		||||
    const {Transpileable, TranspileURL, SocketsHandler} = Transpiler(DevMode);
 | 
			
		||||
    const {Imports, Error} = await Configure(DevMode, Path.LibDir);
 | 
			
		||||
    if(Error)
 | 
			
		||||
    {
 | 
			
		||||
        const url:URL = new URL(_req.url);
 | 
			
		||||
        const pathParts = url.pathname.substring(1, url.pathname.endsWith("/") ? url.pathname.length-1 : url.pathname.length).split("/");
 | 
			
		||||
        const pathLast = pathParts.at(-1);
 | 
			
		||||
        const pathExt:string|undefined = pathLast?.split(".")[1];
 | 
			
		||||
        
 | 
			
		||||
        const resp = SocketsHandler(_req);
 | 
			
		||||
        if(resp){ return resp; }
 | 
			
		||||
    
 | 
			
		||||
        try
 | 
			
		||||
        console.log(Error);
 | 
			
		||||
    }
 | 
			
		||||
    else if(App && TwindInst)
 | 
			
		||||
    {
 | 
			
		||||
        Deno.serve({ port: Deno.env.get("port")||3000 }, async(_req:Request) =>
 | 
			
		||||
        {
 | 
			
		||||
            // serve index by default
 | 
			
		||||
            let type = `text/html`;
 | 
			
		||||
            let body:BodyInit = ``;
 | 
			
		||||
    
 | 
			
		||||
            const isLib = url.pathname.startsWith(`/${Path.LibDir}/`);
 | 
			
		||||
    
 | 
			
		||||
            if(Transpileable(url.pathname))
 | 
			
		||||
            const url:URL = new URL(_req.url);
 | 
			
		||||
            const pathParts = url.pathname.substring(1, url.pathname.endsWith("/") ? url.pathname.length-1 : url.pathname.length).split("/");
 | 
			
		||||
            const pathLast = pathParts.at(-1);
 | 
			
		||||
            const pathExt:string|undefined = pathLast?.split(".")[1];
 | 
			
		||||
            
 | 
			
		||||
            const resp = SocketsHandler(_req);
 | 
			
		||||
            if(resp){ return resp; }
 | 
			
		||||
        
 | 
			
		||||
            console.log(url.pathname);
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                type = `application/javascript`;
 | 
			
		||||
                if(isLib)
 | 
			
		||||
                // serve index by default
 | 
			
		||||
                let type = `text/html`;
 | 
			
		||||
                let body:BodyInit = ``;
 | 
			
		||||
        
 | 
			
		||||
                const isLib = url.pathname.startsWith(`/${Path.LibDir}/`);
 | 
			
		||||
        
 | 
			
		||||
                if(Transpileable(url.pathname))
 | 
			
		||||
                {
 | 
			
		||||
                    body = await TranspileURL(Path.Hosted+url.pathname, url.pathname, true);
 | 
			
		||||
                    type = `application/javascript`;
 | 
			
		||||
                    if(isLib)
 | 
			
		||||
                    {
 | 
			
		||||
                        body = await TranspileURL(Path.Hosted+url.pathname, url.pathname, true);
 | 
			
		||||
                    }
 | 
			
		||||
                    else if(url.pathname == "/server.tsx")
 | 
			
		||||
                    {
 | 
			
		||||
                        body = await TranspileURL(`${Path.Hosted}/${Path.LibDir}/boot-client.tsx`, url.pathname, true);
 | 
			
		||||
                    }
 | 
			
		||||
                    else if(DevMode && !url.searchParams.get("reload"))
 | 
			
		||||
                    {
 | 
			
		||||
                        const imp = await import(Path.Active+url.pathname);
 | 
			
		||||
                        const members = [];
 | 
			
		||||
                        for( const key in imp ) { members.push(key); }
 | 
			
		||||
                        body =
 | 
			
		||||
        `
 | 
			
		||||
        import {FileListen} from "/${Path.LibDir}/hmr.tsx";
 | 
			
		||||
        import * as Import from "${url.pathname}?reload=0";
 | 
			
		||||
        ${ members.map(m=>`let proxy_${m} = Import.${m};
 | 
			
		||||
        export { proxy_${m} as ${m} };
 | 
			
		||||
        `).join(" ") }
 | 
			
		||||
        const reloadHandler = (updatedModule)=>
 | 
			
		||||
        {
 | 
			
		||||
            ${ members.map(m=>`proxy_${m} = updatedModule.${m};`).join("\n") }
 | 
			
		||||
        };
 | 
			
		||||
        FileListen("${url.pathname}", reloadHandler);`;
 | 
			
		||||
        
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        body = await TranspileURL(Path.Active+url.pathname, url.pathname, true);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else if(DevMode && !url.searchParams.get("reload"))
 | 
			
		||||
                // serve static media
 | 
			
		||||
                else if( pathExt )
 | 
			
		||||
                {
 | 
			
		||||
                    const imp = await import(Path.Active+url.pathname);
 | 
			
		||||
                    const members = [];
 | 
			
		||||
                    for( const key in imp ) { members.push(key); }
 | 
			
		||||
                    body =
 | 
			
		||||
    `
 | 
			
		||||
    import {FileListen} from "/${Path.LibDir}/hmr.tsx";
 | 
			
		||||
    import * as Import from "${url.pathname}?reload=0";
 | 
			
		||||
    ${ members.map(m=>`let proxy_${m} = Import.${m};
 | 
			
		||||
    export { proxy_${m} as ${m} };
 | 
			
		||||
    `).join(" ") }
 | 
			
		||||
    const reloadHandler = (updatedModule)=>
 | 
			
		||||
    {
 | 
			
		||||
        ${ members.map(m=>`proxy_${m} = updatedModule.${m};`).join("\n") }
 | 
			
		||||
    };
 | 
			
		||||
    FileListen("${url.pathname}", reloadHandler);`;
 | 
			
		||||
    
 | 
			
		||||
                    type = MIME.typeByExtension(pathExt) || "text/html";
 | 
			
		||||
                    const _fetch = await fetch((Path.Active)+url.pathname);
 | 
			
		||||
                    body = await _fetch.text();
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    body = await TranspileURL(Path.Active+url.pathname, url.pathname, true);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            // serve static media
 | 
			
		||||
            else if( pathExt )
 | 
			
		||||
            {
 | 
			
		||||
                type = MIME.typeByExtension(pathExt) || "text/html";
 | 
			
		||||
                const _fetch = await fetch((Path.Active)+url.pathname);
 | 
			
		||||
                body = await _fetch.text();
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                Iso.Fetch.ServerBlocking = [];
 | 
			
		||||
                Iso.Fetch.ServerTouched = new Set();
 | 
			
		||||
                Iso.Fetch.ServerRemove = new Set();
 | 
			
		||||
                let app = <Iso.Router.Provider url={url}><App/></Iso.Router.Provider>;
 | 
			
		||||
                await Prepass(app)
 | 
			
		||||
                let bake = SSR(app);
 | 
			
		||||
                while(Iso.Fetch.ServerBlocking.length)
 | 
			
		||||
                {
 | 
			
		||||
                    await Promise.all(Iso.Fetch.ServerBlocking);
 | 
			
		||||
                    Iso.Fetch.ServerBlocking = [];
 | 
			
		||||
                    // at this point, anything that was requested that was not cached, has now been loaded and cached
 | 
			
		||||
                    // this next render will use cached resources. using a cached resource (if its "Seed" is true) adds it to the "touched" set.
 | 
			
		||||
                    app = <Iso.Router.Provider url={url}><App/></Iso.Router.Provider>;
 | 
			
		||||
                    Iso.Fetch.ServerTouched = new Set();
 | 
			
		||||
                    Iso.Fetch.ServerRemove = new Set();
 | 
			
		||||
                    let app = <Iso.Router.Provider url={url}><Iso.Meta.Provider><App/></Iso.Meta.Provider></Iso.Router.Provider>;
 | 
			
		||||
                    await Prepass(app)
 | 
			
		||||
                    bake = SSR(app);
 | 
			
		||||
                    let bake = SSR(app);
 | 
			
		||||
                    while(Iso.Fetch.ServerBlocking.length)
 | 
			
		||||
                    {
 | 
			
		||||
                        await Promise.all(Iso.Fetch.ServerBlocking);
 | 
			
		||||
                        Iso.Fetch.ServerBlocking = [];
 | 
			
		||||
                        // at this point, anything that was requested that was not cached, has now been loaded and cached
 | 
			
		||||
                        // this next render will use cached resources. using a cached resource (if its "Seed" is true) adds it to the "touched" set.
 | 
			
		||||
                        app = <Iso.Router.Provider url={url}><Iso.Meta.Provider><App/></Iso.Meta.Provider></Iso.Router.Provider>;
 | 
			
		||||
                        await Prepass(app)
 | 
			
		||||
                        bake = SSR(app);
 | 
			
		||||
                    }
 | 
			
		||||
        
 | 
			
		||||
                    const seed:Iso.FetchRecord[] = [];
 | 
			
		||||
                    Iso.Fetch.ServerTouched.forEach((record)=>{
 | 
			
		||||
                        const r:Iso.FetchRecord = {...record};
 | 
			
		||||
                        delete r.Promise;
 | 
			
		||||
                        seed.push(r);
 | 
			
		||||
                    });
 | 
			
		||||
                    Iso.Fetch.ServerTouched = false;
 | 
			
		||||
        
 | 
			
		||||
                    const results = Twind.extract(bake, TwindInst);
 | 
			
		||||
        
 | 
			
		||||
                    type = `text/html`;
 | 
			
		||||
                    body =
 | 
			
		||||
        `<!doctype html>
 | 
			
		||||
        <html lang="en">
 | 
			
		||||
            <head>
 | 
			
		||||
                <title>${Iso.Meta.Meta.title}</title>
 | 
			
		||||
                <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
			
		||||
                <meta charset="utf-8"/>
 | 
			
		||||
                <style data-twind>${results.css}</style>
 | 
			
		||||
                <script type="importmap">${JSON.stringify(Imports)}</script>
 | 
			
		||||
            </head>
 | 
			
		||||
            <body>
 | 
			
		||||
                <div id="app">${results.html}</div>
 | 
			
		||||
                <script type="module">
 | 
			
		||||
                    import {Fetch} from "@eno/iso";
 | 
			
		||||
                    Fetch.Seed(${JSON.stringify(seed)});
 | 
			
		||||
 | 
			
		||||
                    import "${AppPath}";
 | 
			
		||||
                </script>
 | 
			
		||||
            </body>
 | 
			
		||||
        </html>`;
 | 
			
		||||
                }
 | 
			
		||||
    
 | 
			
		||||
                const seed:Iso.FetchRecord[] = [];
 | 
			
		||||
                Iso.Fetch.ServerTouched.forEach((record)=>{
 | 
			
		||||
                    const r:Iso.FetchRecord = {...record};
 | 
			
		||||
                    delete r.Promise;
 | 
			
		||||
                    seed.push(r);
 | 
			
		||||
                });
 | 
			
		||||
                Iso.Fetch.ServerTouched = false;
 | 
			
		||||
    
 | 
			
		||||
                const results = Twind.extract(bake, TwindInst);
 | 
			
		||||
    
 | 
			
		||||
                type = `text/html`;
 | 
			
		||||
                body =
 | 
			
		||||
    `<!doctype html>
 | 
			
		||||
    <html lang="en">
 | 
			
		||||
        <head>
 | 
			
		||||
            <title>${Iso.Meta.Meta.title}</title>
 | 
			
		||||
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
			
		||||
            <meta charset="utf-8"/>
 | 
			
		||||
            <style data-twind>${results.css}</style>
 | 
			
		||||
            <script type="importmap">${JSON.stringify(Imports)}</script>
 | 
			
		||||
        </head>
 | 
			
		||||
        <body>
 | 
			
		||||
            <div id="app">${results.html}</div>
 | 
			
		||||
            <script type="module">
 | 
			
		||||
                import {hydrate, createElement as H} from "react";
 | 
			
		||||
                import * as Twind from "https://esm.sh/v115/@twind/core@1.1.3/es2022/core.mjs";
 | 
			
		||||
                import * as App from "@eno/app";
 | 
			
		||||
                import {Router, Fetch, CSS, Meta} from "@eno/iso";
 | 
			
		||||
                Twind.install(App.CSS ? {...CSS, ...App.CSS} : CSS);
 | 
			
		||||
                Fetch.Seed(${JSON.stringify(seed)});
 | 
			
		||||
                const hmrWrap = H( ()=>H(App.default) );
 | 
			
		||||
                hydrate(
 | 
			
		||||
                    H(Router.Provider, null,
 | 
			
		||||
                        H(Meta.Provider, null, hmrWrap)
 | 
			
		||||
                    ),
 | 
			
		||||
                    document.querySelector("#app")
 | 
			
		||||
                );
 | 
			
		||||
            </script>
 | 
			
		||||
        </body>
 | 
			
		||||
    </html>`;
 | 
			
		||||
        
 | 
			
		||||
                return new Response(body, {headers:{"content-type":type as string, "Access-Control-Allow-Origin":"*", charset:"utf-8"}});
 | 
			
		||||
            }
 | 
			
		||||
    
 | 
			
		||||
            return new Response(body, {headers:{"content-type":type as string, "Access-Control-Allow-Origin":"*", charset:"utf-8"}});
 | 
			
		||||
        }
 | 
			
		||||
        catch(error)
 | 
			
		||||
        {
 | 
			
		||||
            console.log(error);
 | 
			
		||||
            return new Response(error, {status:404});
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
            catch(error)
 | 
			
		||||
            {
 | 
			
		||||
                console.log(error);
 | 
			
		||||
                return new Response(error, {status:404});
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user