From 469c0c4edda302285628391a2493b120c55d85c2 Mon Sep 17 00:00:00 2001 From: Seth Trowbridge Date: Thu, 10 Oct 2024 10:00:12 -0400 Subject: [PATCH] init --- deno.json | 1 + index.html | 11 +++ junk/module_inspector.test.ts | 24 ++++++ junk/module_inspector.ts | 139 ++++++++++++++++++++++++++++++++++ junk/server.tsx | 17 +++++ test_application.mjs | 11 +++ test_changer.mjs | 14 ++++ test_rand.mjs | 1 + test_receiver.mjs | 9 +++ 9 files changed, 227 insertions(+) create mode 100644 deno.json create mode 100644 index.html create mode 100644 junk/module_inspector.test.ts create mode 100644 junk/module_inspector.ts create mode 100644 junk/server.tsx create mode 100644 test_application.mjs create mode 100644 test_changer.mjs create mode 100644 test_rand.mjs create mode 100644 test_receiver.mjs diff --git a/deno.json b/deno.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/deno.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..5f1dc91 --- /dev/null +++ b/index.html @@ -0,0 +1,11 @@ + + + \ No newline at end of file diff --git a/junk/module_inspector.test.ts b/junk/module_inspector.test.ts new file mode 100644 index 0000000..285801c --- /dev/null +++ b/junk/module_inspector.test.ts @@ -0,0 +1,24 @@ +import * as Inspector from "./module_inspector.ts"; + +Deno.test("check string parsing", ()=>{ + + const [local, global] = Inspector.Exports(` +// export in comment +/** + * +* export const TESTtt + * / +const fakeexport =()=>{}; +const exportfake =()=>{}; +export * from "react"; +export{ thing1 as remapped, thing2} +export{ thing1 as remapped, thing2} from 'React'; +export +export default function(){} +export const func=()=>{}; +export let func=()=>{}; +`) + + console.log(local, global); + +}) \ No newline at end of file diff --git a/junk/module_inspector.ts b/junk/module_inspector.ts new file mode 100644 index 0000000..7c72d67 --- /dev/null +++ b/junk/module_inspector.ts @@ -0,0 +1,139 @@ + +type GlyphCheck = (inGlyph:string)=>boolean +const isAlphaLike:GlyphCheck =(inGlyph:string)=> +{ + const inCode = inGlyph.charCodeAt(0); + + if(inCode >= 97 && inCode <= 122) + { + return true; + } + + if(inCode >= 65 && inCode <= 90) + { + return true; + } + + return `$_.`.includes(inGlyph); +} +const isWhiteSpace:GlyphCheck =(inGlyph:string)=> `\n\r\t `.includes(inGlyph); +const isQuote:GlyphCheck =(inGlyph:string)=>`"'\``.includes(inGlyph) +const isNot =(inCheck:GlyphCheck)=> (inGlyph:string)=>!inCheck(inGlyph); +const contiguous =(inText:string, inStart:number, inTest:GlyphCheck):number=> +{ + let ok = true; + let index = inStart; + let count = 0; + while(ok && count < inText.length) + { + count++; + ok = inTest(inText.charAt(index++)); + } + return index-1; +} + +const findNextExport =(inFile:string, inIndex=0, inLocal:Array, inForeign:Array)=> +{ + const pos = inFile.indexOf("export", inIndex); + if(pos !== -1) + { + if(!isAlphaLike(inFile.charAt(pos-1)) || !isAlphaLike(inFile.charAt(pos+6))) + { + + const nextCharInd = contiguous(inFile, pos+6, isWhiteSpace); + const nextChar = inFile[nextCharInd]; + + //console.log(inFile.substring(pos, nextCharInd+1), `>>${nextChar}<<`) + + if(nextChar === "*") + { + const firstQuoteInd = contiguous(inFile, nextCharInd+1, isNot(isQuote) ); + const secondQuoteInd = contiguous(inFile, firstQuoteInd+1, isNot(isQuote) ); + //console.log("ASTERISK:", inFile.substring(pos, secondQuoteInd+1)); + inForeign.push(inFile.substring(nextCharInd, secondQuoteInd+1)); + } + else if(nextChar == "{") + { + const endBracketInd = contiguous(inFile, nextCharInd, (inGlyph:string)=>inGlyph!=="}"); + const nextLetterInd = contiguous(inFile, endBracketInd+1, isWhiteSpace); + if(inFile.substring(nextLetterInd, nextLetterInd+4) == "from") + { + const firstQuoteInd = contiguous(inFile, nextLetterInd+4, isNot(isQuote) ); + const secondQuoteInd = contiguous(inFile, firstQuoteInd+1, isNot(isQuote) ); + //console.log(`BRACKET foreign: >>${inFile.substring(nextCharInd, secondQuoteInd+1)}<<`); + inForeign.push(inFile.substring(nextCharInd, secondQuoteInd+1)); + } + else + { + const members = inFile.substring(nextCharInd+1, endBracketInd).replace(/\s/g, ''); + members.split(",").forEach(part=> + { + const renamed = part.split(" as "); + inLocal.push(renamed[1] || renamed[0]); + }); + } + + } + else if(isAlphaLike(nextChar)) + { + const keywordEndInd = contiguous(inFile, nextCharInd, isAlphaLike); + const keyword = inFile.substring(nextCharInd, keywordEndInd); + if(keyword === "default") + { + inLocal.push(keyword); + //console.log(`MEMBER: >>${keyword})}<<`); + } + else if(["const", "let", "var", "function", "class"].includes(keyword)) + { + const varStartInd = contiguous(inFile, keywordEndInd+1, isWhiteSpace); + const varEndInd = contiguous(inFile, varStartInd+1, isAlphaLike); + //console.log(`MEMBER: >>${inFile.substring(varStartInd, varEndInd)}<<`); + inLocal.push(inFile.substring(varStartInd, varEndInd)) + } + } + } + + return pos + 7; + } + else + { + return false; + } +}; + +export const Exports =(inFile:string)=> +{ + let match = 0 as number|false; + let count = 0; + const local = [] as string[]; + const foreign = [] as string[]; + while(match !== false && count <200) + { + count++; + match = findNextExport(inFile, match, local, foreign); + } + return[local, foreign] as [local:string[], foreign:string[]]; +}; + +export const FileExports =async(inURL:string|URL)=> +{ + 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 * from "react"; +const fakeexport =()=>{}; +export{ thing1 as remapped, thing2} +export{ thing1 as remapped, thing2} from 'React'; +export +export const func=()=>{}; +`); + +console.log(local, global); +*/ \ No newline at end of file diff --git a/junk/server.tsx b/junk/server.tsx new file mode 100644 index 0000000..95ccb79 --- /dev/null +++ b/junk/server.tsx @@ -0,0 +1,17 @@ +const Extension =(inPath:string)=> +{ + const posSlash = inPath.lastIndexOf("/"); + const posDot = inPath.lastIndexOf("."); + return posDot > posSlash ? inPath.substring(posDot+1).toLowerCase() : false; +}; + + + +Deno.serve((r)=>{ + + const url = new URL(r.url); + const ext = Extension(url.pathname); + + + return new Response(); +}) \ No newline at end of file diff --git a/test_application.mjs b/test_application.mjs new file mode 100644 index 0000000..676015c --- /dev/null +++ b/test_application.mjs @@ -0,0 +1,11 @@ +import {changing} from "./test_changer.mjs"; + +const area = document.createElement("pre"); +document.body.append(area); +Render(); + +export function Render() +{ + console.log("pulling changing", changing) + area.innerHTML = changing; +} \ No newline at end of file diff --git a/test_changer.mjs b/test_changer.mjs new file mode 100644 index 0000000..1f30936 --- /dev/null +++ b/test_changer.mjs @@ -0,0 +1,14 @@ +export let changing = 2; + +const thisURL = new URL(import.meta.url) +const thisFile = thisURL.pathname; +if(!thisURL.search) +{ + setInterval(()=>{ + import(thisFile+"?"+Math.random()).then(module=>{ + + changing = module.changing; + console.log(changing); + }) + }, 3000); +} \ No newline at end of file diff --git a/test_rand.mjs b/test_rand.mjs new file mode 100644 index 0000000..6661211 --- /dev/null +++ b/test_rand.mjs @@ -0,0 +1 @@ +export default Math.random(); \ No newline at end of file diff --git a/test_receiver.mjs b/test_receiver.mjs new file mode 100644 index 0000000..62c8acf --- /dev/null +++ b/test_receiver.mjs @@ -0,0 +1,9 @@ +import * as App from "./test_application.mjs"; + +const button = document.createElement("button"); +button.innerHTML = "Reload"; +button.addEventListener("click", ()=> +{ + App.Render(); +}) +document.body.append(button); \ No newline at end of file