From 22aaa7cfd6d6871cdc5fde10a88f0cbdf100d335 Mon Sep 17 00:00:00 2001 From: Seth Trowbridge Date: Sat, 18 Oct 2025 10:24:47 -0400 Subject: [PATCH] pass query to user files --- hmr/hmr-static.tsx | 20 ++++------------ server.ts | 59 ++++++++++++++++++++++++++-------------------- 2 files changed, 38 insertions(+), 41 deletions(-) diff --git a/hmr/hmr-static.tsx b/hmr/hmr-static.tsx index 001f23e..fdf6bb9 100644 --- a/hmr/hmr-static.tsx +++ b/hmr/hmr-static.tsx @@ -100,7 +100,9 @@ const findNextExport =(inFile:string, inIndex=0, inLocal:Array, 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 count = 0; @@ -111,21 +113,7 @@ export const ModuleShape =(inText:string)=> count++; match = findNextExport(inText, match, local, foreign); } - return[local, foreign] as [local:string[], foreign:string[]]; -}; - -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") }`; + return[local, foreign]; }; diff --git a/server.ts b/server.ts index f148a9f..de963ed 100644 --- a/server.ts +++ b/server.ts @@ -1,10 +1,11 @@ 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 keyTranspile = "->"; const keyReload = "hmr:id"; const keysExtension = ["ts", "tsx"]; +const keyReactProxy = `/${keyTranspile}/${import.meta.resolve("./hmr/hmr-listen.tsx")}` const extractExtension =(path:string)=> { const ind = path.lastIndexOf("."); @@ -28,15 +29,13 @@ const bakeConfigPackage:Deno.bundle.Options = const bakeConfigLocal:Deno.bundle.Options = {...bakeConfigPackage, sourcemap:"inline", inlineImports:false }; type FullBakeConfig = { - path:string, - key?:string, + key:string, bundle?:boolean }; async function BakeForce(options:FullBakeConfig) { - const path = options.path; - const key = options.key || path; + const key = options.key; const type = options.bundle; // 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. - const config = {...(type ? bakeConfigPackage : bakeConfigLocal), entrypoints:[path]}; + const config = {...(type ? bakeConfigPackage : bakeConfigLocal), entrypoints:[key]}; console.log("baking", config.entrypoints, "as", key); // store the in-flight promise immediately so concurrent callers reuse it @@ -58,15 +57,14 @@ async function BakeForce(options:FullBakeConfig) if (result.outputFiles) { 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 ? "" : ModuleProxy(body, path, listenerImport, keyReload)]; + const save:CachedTranspile = [body, type ? undefined : ModuleShape(body)]; BakeCache[key] = save; // replace promise with resolved value return save; } } catch (e) { - console.log("Bake error", path, e); + console.log("Bake error", key, e); } // failed - remove cache entry so next attempt can retry delete BakeCache[key]; @@ -92,7 +90,7 @@ async function BakeCheck(options:FullBakeConfig) } 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. const BakeCache:Record | undefined> = {} @@ -111,15 +109,6 @@ const reactValueModified = `/${keyTranspile}/${import.meta.resolve("./hmr/hmr-re denoBody.imports[reactKey] = 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); const importMap = ``; @@ -175,7 +164,7 @@ Deno.serve(async(req:Request)=> { console.log("BUNDLE", parts); const transpiled = await BakeCheck({ - path: parts.slice(1).join("/"), + key: parts.slice(1).join("/"), bundle:true }); return JSResponse(transpiled[0]); @@ -184,7 +173,7 @@ Deno.serve(async(req:Request)=> { console.log("TRANSPILE", parts); const transpiled = await BakeCheck({ - path:parts.slice(1).join("/"), + key:parts.slice(1).join("/"), bundle:false }); return JSResponse(transpiled[0]); @@ -192,9 +181,29 @@ Deno.serve(async(req:Request)=> if(keysExtension.includes(extension)) { console.log("REGULAR", parts); - const transpiled = await BakeCheck({path:"./"+parts.join("/"), bundle:false}); - //return JSResponse(transpiled[0]); - return JSResponse(transpiled[url.searchParams.has(keyReload) ? 0 : 1]); + const key = "./"+parts.join("/"); + + 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) @@ -249,7 +258,7 @@ const Watcher =async()=> console.log("File change", path, key); if(action != "remove") { - await BakeForce({path:keyRel, bundle:false}); + await BakeForce({key:keyRel, bundle:false}); SocketsSend(keyRel); } else