introduce ESM export parser

This commit is contained in:
Seth Trowbridge 2023-07-16 21:29:50 -04:00
parent 0d856e1b4a
commit b8f4ee6618
3 changed files with 46 additions and 22 deletions

View File

@ -11,7 +11,7 @@
}, },
"tasks": "tasks":
{ {
"local": "deno run -A --no-lock ./local.tsx", "local": "deno run -A --no-lock ./run-local.tsx --port=1234",
"serve": "deno run -A --no-lock ./serve.tsx" "serve": "deno run -A --no-lock ./run-serve.tsx --port=1234"
} }
} }

View File

@ -1,7 +1,5 @@
import { parseMediaType } from "https://deno.land/std@0.180.0/media_types/parse_media_type.ts";
type GlyphCheck = (inGlyph:string)=>boolean type GlyphCheck = (inGlyph:string)=>boolean
const isAlphaLike:GlyphCheck =(inGlyph:string)=> const isAlphaLike:GlyphCheck =(inGlyph:string)=>
{ {
const inCode = inGlyph.charCodeAt(0); const inCode = inGlyph.charCodeAt(0);
@ -25,19 +23,15 @@ const contiguous =(inText:string, inStart:number, inTest:GlyphCheck):number=>
{ {
let ok = true; let ok = true;
let index = inStart; let index = inStart;
while(ok) let count = 0;
while(ok && count < inText.length)
{ {
count++;
ok = inTest(inText.charAt(index++)); ok = inTest(inText.charAt(index++));
} }
return index-1; return index-1;
} }
// const str = `seth trowbridge`;
// const hit0 = 0;
// const hit1 = contiguous(str, hit0, isWhiteSpace);
// const hit2 = contiguous(str, hit1+1, isNot(isWhiteSpace));
// console.log(">>"+str.substring(hit1, hit2)+"<<");
const findNextExport =(inFile:string, inIndex=0, inLocal:Array<string>, inForeign:Array<string>)=> const findNextExport =(inFile:string, inIndex=0, inLocal:Array<string>, inForeign:Array<string>)=>
{ {
const pos = inFile.indexOf("export", inIndex); const pos = inFile.indexOf("export", inIndex);
@ -49,7 +43,7 @@ const findNextExport =(inFile:string, inIndex=0, inLocal:Array<string>, inForeig
const nextCharInd = contiguous(inFile, pos+6, isWhiteSpace); const nextCharInd = contiguous(inFile, pos+6, isWhiteSpace);
const nextChar = inFile[nextCharInd]; const nextChar = inFile[nextCharInd];
console.log(inFile.substring(pos, nextCharInd+1), `>>${nextChar}<<`) //console.log(inFile.substring(pos, nextCharInd+1), `>>${nextChar}<<`)
if(nextChar === "*") if(nextChar === "*")
{ {
@ -107,21 +101,32 @@ const findNextExport =(inFile:string, inIndex=0, inLocal:Array<string>, inForeig
} }
}; };
const iterate =(inFile:string)=> export const Exports =(inFile:string)=>
{ {
let match = 0 as number|false; let match = 0 as number|false;
let count = 0; let count = 0;
const local = [] as string[]; const local = [] as string[];
const foreign = [] as string[]; const foreign = [] as string[];
while(match !== false && count <100) while(match !== false && count <200)
{ {
count++; count++;
match = findNextExport(inFile, match, local, foreign); match = findNextExport(inFile, match, local, foreign);
} }
console.log(local, foreign); return[local, foreign] as [local:string[], foreign:string[]];
}; };
iterate(` export const FileExports =async(inURL:string|URL)=>
{
console.log("scanning", inURL, "for exports")
const resp = await fetch(inURL);
const text = await resp.text();
return Exports(text);
}
//console.log(await FileExports(import.meta.resolve("./hmr-listen.tsx")));
/*
const [local, global] = Exports(`
// export in comment // export in comment
export * from "react"; export * from "react";
const fakeexport =()=>{}; const fakeexport =()=>{};
@ -130,3 +135,6 @@ export{ thing1 as remapped, thing2} from 'React';
export export
export const func=()=>{}; export const func=()=>{};
`); `);
console.log(local, global);
*/

View File

@ -1,4 +1,5 @@
import {Configure, Transpile, Extension} from "./run-serve.tsx"; import {Configure, Transpile, Extension} from "./run-serve.tsx";
import * as Collect from "./hmr-static.tsx";
const SocketsLive:Set<WebSocket> = new Set(); const SocketsLive:Set<WebSocket> = new Set();
const SocketsSend =(inData:string)=>{ for (const socket of SocketsLive){ socket.send(inData); } } const SocketsSend =(inData:string)=>{ for (const socket of SocketsLive){ socket.send(inData); } }
@ -28,18 +29,33 @@ Configure({
{ {
if(Transpile.Check(inExt) && !inURL.searchParams.get("reload")) if(Transpile.Check(inExt) && !inURL.searchParams.get("reload"))
{ {
const imp = await import(inConfig.Proxy+inURL.pathname);
const members = [];
for( const key in imp ) { members.push(key); }
// const imp = await import(inConfig.Proxy+inURL.pathname);
// const members = [];
// for( const key in imp ) { members.push(key); }
//
// const code =`
//import {FileListen} from "${import.meta.resolve(`./hmr-listen.tsx`)}";
//import * as Import from "${inURL.pathname}?reload=0";
//${ members.map(m=>`let proxy_${m} = Import.${m}; export { proxy_${m} as ${m} };`).join("\n") }
//FileListen("${inURL.pathname}", (updatedModule)=>
//{
// ${ members.map(m=>`proxy_${m} = updatedModule.${m};`).join("\n") }
//});`
// we dont need to add ?reload= because this fetch is by way the file system not the hosted url
const [local, foreign] = await Collect.FileExports(inConfig.Proxy+inURL.pathname);
console.log(local, foreign);
const code =` const code =`
import {FileListen} from "${import.meta.resolve(`./hmr-listen.tsx`)}"; import {FileListen} from "${import.meta.resolve(`./hmr-listen.tsx`)}";
import * as Import from "${inURL.pathname}?reload=0"; import * as Import from "${inURL.pathname}?reload=0";
${ members.map(m=>`let proxy_${m} = Import.${m}; export { proxy_${m} as ${m} };`).join("\n") } ${ local.map(m=>`let proxy_${m} = Import.${m}; export { proxy_${m} as ${m} };`).join("\n") }
FileListen("${inURL.pathname}", (updatedModule)=> FileListen("${inURL.pathname}", (updatedModule)=>
{ {
${ members.map(m=>`proxy_${m} = updatedModule.${m};`).join("\n") } ${ local.map(m=>`proxy_${m} = updatedModule.${m};`).join("\n") }
});` });
${ foreign.join(";\n") }
`
return new Response(code, {headers:{"content-type":"application/javascript"}}); return new Response(code, {headers:{"content-type":"application/javascript"}});
} }