pass query to user files
This commit is contained in:
parent
d925b8d75e
commit
22aaa7cfd6
@ -100,7 +100,9 @@ const findNextExport =(inFile:string, inIndex=0, inLocal:Array<string>, inForeig
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ModuleShape =(inText:string)=>
|
export type Shape = [local:string[], foreign:string[]];
|
||||||
|
|
||||||
|
export const ModuleShape =(inText:string):Shape=>
|
||||||
{
|
{
|
||||||
let match = 0 as number|false;
|
let match = 0 as number|false;
|
||||||
let count = 0;
|
let count = 0;
|
||||||
@ -111,21 +113,7 @@ export const ModuleShape =(inText:string)=>
|
|||||||
count++;
|
count++;
|
||||||
match = findNextExport(inText, match, local, foreign);
|
match = findNextExport(inText, match, local, foreign);
|
||||||
}
|
}
|
||||||
return[local, foreign] as [local:string[], foreign:string[]];
|
return[local, foreign];
|
||||||
};
|
|
||||||
|
|
||||||
export const ModuleProxy =(inText:string, inPath:string, reactProxy:string, reloadKey:string)=>
|
|
||||||
{
|
|
||||||
const [local, foreign] = ModuleShape(inText);
|
|
||||||
return `
|
|
||||||
import {FileListen} from "${reactProxy}";
|
|
||||||
import * as Import from "${inPath}?${reloadKey}=${new Date().getTime()}";
|
|
||||||
${ local.map(m=>`let proxy_${m} = Import.${m}; export { proxy_${m} as ${m} };`).join("\n") }
|
|
||||||
FileListen("${inPath}", (updatedModule)=>
|
|
||||||
{
|
|
||||||
${ local.map(m=>`proxy_${m} = updatedModule.${m};`).join("\n\t") }
|
|
||||||
});
|
|
||||||
${ foreign.join(";\n") }`;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
59
server.ts
59
server.ts
@ -1,10 +1,11 @@
|
|||||||
import { contentType } from "jsr:@std/media-types";
|
import { contentType } from "jsr:@std/media-types";
|
||||||
import { ModuleProxy } from "./hmr/hmr-static.tsx";
|
import { ModuleShape, type Shape } from "./hmr/hmr-static.tsx";
|
||||||
|
|
||||||
const keyBundle = "=>";
|
const keyBundle = "=>";
|
||||||
const keyTranspile = "->";
|
const keyTranspile = "->";
|
||||||
const keyReload = "hmr:id";
|
const keyReload = "hmr:id";
|
||||||
const keysExtension = ["ts", "tsx"];
|
const keysExtension = ["ts", "tsx"];
|
||||||
|
const keyReactProxy = `/${keyTranspile}/${import.meta.resolve("./hmr/hmr-listen.tsx")}`
|
||||||
const extractExtension =(path:string)=>
|
const extractExtension =(path:string)=>
|
||||||
{
|
{
|
||||||
const ind = path.lastIndexOf(".");
|
const ind = path.lastIndexOf(".");
|
||||||
@ -28,15 +29,13 @@ const bakeConfigPackage:Deno.bundle.Options =
|
|||||||
const bakeConfigLocal:Deno.bundle.Options = {...bakeConfigPackage, sourcemap:"inline", inlineImports:false };
|
const bakeConfigLocal:Deno.bundle.Options = {...bakeConfigPackage, sourcemap:"inline", inlineImports:false };
|
||||||
|
|
||||||
type FullBakeConfig = {
|
type FullBakeConfig = {
|
||||||
path:string,
|
key:string,
|
||||||
key?:string,
|
|
||||||
bundle?:boolean
|
bundle?:boolean
|
||||||
};
|
};
|
||||||
|
|
||||||
async function BakeForce(options:FullBakeConfig)
|
async function BakeForce(options:FullBakeConfig)
|
||||||
{
|
{
|
||||||
const path = options.path;
|
const key = options.key;
|
||||||
const key = options.key || path;
|
|
||||||
const type = options.bundle;
|
const type = options.bundle;
|
||||||
|
|
||||||
// If already baking, return the in-flight promise. (Caller may also call Bake Check which handles this.)
|
// If already baking, return the in-flight promise. (Caller may also call Bake Check which handles this.)
|
||||||
@ -46,7 +45,7 @@ async function BakeForce(options:FullBakeConfig)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a fresh config per bake to avoid shared mutation.
|
// Create a fresh config per bake to avoid shared mutation.
|
||||||
const config = {...(type ? bakeConfigPackage : bakeConfigLocal), entrypoints:[path]};
|
const config = {...(type ? bakeConfigPackage : bakeConfigLocal), entrypoints:[key]};
|
||||||
console.log("baking", config.entrypoints, "as", key);
|
console.log("baking", config.entrypoints, "as", key);
|
||||||
|
|
||||||
// store the in-flight promise immediately so concurrent callers reuse it
|
// store the in-flight promise immediately so concurrent callers reuse it
|
||||||
@ -58,15 +57,14 @@ async function BakeForce(options:FullBakeConfig)
|
|||||||
if (result.outputFiles)
|
if (result.outputFiles)
|
||||||
{
|
{
|
||||||
const body = result.outputFiles.map(file=>file.text()).join("\n");
|
const body = result.outputFiles.map(file=>file.text()).join("\n");
|
||||||
const listenerImport = `/${keyTranspile}/${import.meta.resolve("./hmr/hmr-listen.tsx")}`;
|
const save:CachedTranspile = [body, type ? undefined : ModuleShape(body)];
|
||||||
const save:CachedTranspile = [body, type ? "" : ModuleProxy(body, path, listenerImport, keyReload)];
|
|
||||||
BakeCache[key] = save; // replace promise with resolved value
|
BakeCache[key] = save; // replace promise with resolved value
|
||||||
return save;
|
return save;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (e)
|
catch (e)
|
||||||
{
|
{
|
||||||
console.log("Bake error", path, e);
|
console.log("Bake error", key, e);
|
||||||
}
|
}
|
||||||
// failed - remove cache entry so next attempt can retry
|
// failed - remove cache entry so next attempt can retry
|
||||||
delete BakeCache[key];
|
delete BakeCache[key];
|
||||||
@ -92,7 +90,7 @@ async function BakeCheck(options:FullBakeConfig)
|
|||||||
}
|
}
|
||||||
return lookup as CachedTranspile;
|
return lookup as CachedTranspile;
|
||||||
}
|
}
|
||||||
type CachedTranspile = [file:string, profile:string]
|
type CachedTranspile = [file:string, shape?:Shape]
|
||||||
// BakeCache may hold a resolved cached tuple or an in-flight Promise that resolves to one.
|
// BakeCache may hold a resolved cached tuple or an in-flight Promise that resolves to one.
|
||||||
const BakeCache:Record<string, CachedTranspile | Promise<CachedTranspile|undefined> | undefined> = {}
|
const BakeCache:Record<string, CachedTranspile | Promise<CachedTranspile|undefined> | undefined> = {}
|
||||||
|
|
||||||
@ -111,15 +109,6 @@ const reactValueModified = `/${keyTranspile}/${import.meta.resolve("./hmr/hmr-re
|
|||||||
denoBody.imports[reactKey] = reactValueModified
|
denoBody.imports[reactKey] = reactValueModified
|
||||||
denoBody.imports[reactKey+"/jsx-runtime"] = reactValueModified;
|
denoBody.imports[reactKey+"/jsx-runtime"] = reactValueModified;
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
npm:react | bundle | no-prefix
|
|
||||||
|
|
||||||
hrm/hmr-listen.tsx | transpile | server-prefix
|
|
||||||
|
|
||||||
local/file/component.tsx | transpile | local-prefix
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
console.log(denoBody.imports);
|
console.log(denoBody.imports);
|
||||||
const importMap = `<script type="importmap">{"imports":${JSON.stringify(denoBody.imports, null, 2)}}</script>`;
|
const importMap = `<script type="importmap">{"imports":${JSON.stringify(denoBody.imports, null, 2)}}</script>`;
|
||||||
@ -175,7 +164,7 @@ Deno.serve(async(req:Request)=>
|
|||||||
{
|
{
|
||||||
console.log("BUNDLE", parts);
|
console.log("BUNDLE", parts);
|
||||||
const transpiled = await BakeCheck({
|
const transpiled = await BakeCheck({
|
||||||
path: parts.slice(1).join("/"),
|
key: parts.slice(1).join("/"),
|
||||||
bundle:true
|
bundle:true
|
||||||
});
|
});
|
||||||
return JSResponse(transpiled[0]);
|
return JSResponse(transpiled[0]);
|
||||||
@ -184,7 +173,7 @@ Deno.serve(async(req:Request)=>
|
|||||||
{
|
{
|
||||||
console.log("TRANSPILE", parts);
|
console.log("TRANSPILE", parts);
|
||||||
const transpiled = await BakeCheck({
|
const transpiled = await BakeCheck({
|
||||||
path:parts.slice(1).join("/"),
|
key:parts.slice(1).join("/"),
|
||||||
bundle:false
|
bundle:false
|
||||||
});
|
});
|
||||||
return JSResponse(transpiled[0]);
|
return JSResponse(transpiled[0]);
|
||||||
@ -192,9 +181,29 @@ Deno.serve(async(req:Request)=>
|
|||||||
if(keysExtension.includes(extension))
|
if(keysExtension.includes(extension))
|
||||||
{
|
{
|
||||||
console.log("REGULAR", parts);
|
console.log("REGULAR", parts);
|
||||||
const transpiled = await BakeCheck({path:"./"+parts.join("/"), bundle:false});
|
const key = "./"+parts.join("/");
|
||||||
//return JSResponse(transpiled[0]);
|
|
||||||
return JSResponse(transpiled[url.searchParams.has(keyReload) ? 0 : 1]);
|
const [body, [local, foreign]] = await BakeCheck({key, bundle:false});
|
||||||
|
if(url.searchParams.has(keyReload))
|
||||||
|
{
|
||||||
|
return JSResponse(body);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const params = new URLSearchParams(url.searchParams);
|
||||||
|
params.set(keyReload, new Date().getTime().toString());
|
||||||
|
|
||||||
|
return JSResponse(`
|
||||||
|
import {FileListen} from "${keyReactProxy}";
|
||||||
|
import * as Import from "${key + "?" + params.toString()}";
|
||||||
|
${ local.map(m=>`let proxy_${m} = Import.${m}; export { proxy_${m} as ${m} };`).join("\n") }
|
||||||
|
FileListen("${key}", (updatedModule)=>
|
||||||
|
{
|
||||||
|
${ local.map(m=>`proxy_${m} = updatedModule.${m};`).join("\n\t") }
|
||||||
|
});
|
||||||
|
${ foreign.join(";\n") }`
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!extension)
|
if(!extension)
|
||||||
@ -249,7 +258,7 @@ const Watcher =async()=>
|
|||||||
console.log("File change", path, key);
|
console.log("File change", path, key);
|
||||||
if(action != "remove")
|
if(action != "remove")
|
||||||
{
|
{
|
||||||
await BakeForce({path:keyRel, bundle:false});
|
await BakeForce({key:keyRel, bundle:false});
|
||||||
SocketsSend(keyRel);
|
SocketsSend(keyRel);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user