diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..61dbebd
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,13 @@
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "request": "attach",
+ "name": "Attach",
+ "type": "node"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..6de865a
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "deno.enable": true,
+}
\ No newline at end of file
diff --git a/deno.json b/deno.json
index 9e26dfe..ccc0eff 100644
--- a/deno.json
+++ b/deno.json
@@ -1 +1,5 @@
-{}
\ No newline at end of file
+{
+ "tasks": {
+ "dbg": "deno run -A --inspect-wait junk/module_inspector.test.ts"
+ }
+}
\ No newline at end of file
diff --git a/deno.lock b/deno.lock
new file mode 100644
index 0000000..02fee21
--- /dev/null
+++ b/deno.lock
@@ -0,0 +1,13 @@
+{
+ "version": "3",
+ "remote": {
+ "https://esm.sh/preact@10.23.1": "5c90e3946c882878ada8f82671a1e2cfc3d307eb1253e83cee74f04194cecf41",
+ "https://esm.sh/preact@10.23.1/compat": "e6e124f2c59692ee4dda7d1b9271a6169c57eaa43077495497a44313195fc859",
+ "https://esm.sh/preact@10.23.1/debug": "8d66a656164fe5d5f40078740a444af0cbf38f4eefe415e7bbf76ceefdde4c32",
+ "https://esm.sh/stable/preact@10.23.1/denonext/compat.js": "49c7e42b0555fab75f189e8317d39a252bbb38b49224badf4a110c6a708954f7",
+ "https://esm.sh/stable/preact@10.23.1/denonext/debug.js": "baec17edc90c1c0ba53a2f64c66b3890779169e71289450634543a5a2aab839a",
+ "https://esm.sh/stable/preact@10.23.1/denonext/devtools.js": "bb198cea043a5878c0367867e1be710e9a11581f8ab10ca0a51091e3d2add74d",
+ "https://esm.sh/stable/preact@10.23.1/denonext/hooks.js": "6962ffaaded3eee1cff070f660b6304007754ef1993d63241d2f3807a10ee21e",
+ "https://esm.sh/stable/preact@10.23.1/denonext/preact.mjs": "c30c9bd2ab4b41104f97c0679413cdfe37ec2fa0131a7c5a1a2d3b6f6fae9670"
+ }
+}
diff --git a/index.html b/index.html
index 5f1dc91..10399b5 100644
--- a/index.html
+++ b/index.html
@@ -1,5 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/junk/module_inspector.js b/junk/module_inspector.js
new file mode 100644
index 0000000..dca71ac
--- /dev/null
+++ b/junk/module_inspector.js
@@ -0,0 +1,131 @@
+/**
+ * @typedef {function(string): boolean} GlyphCheck
+ */
+
+/**
+ * @type {GlyphCheck}
+ */
+const isAlphaLike = (inGlyph) => {
+ const inCode = inGlyph.charCodeAt(0);
+
+ if (inCode >= 97 && inCode <= 122) {
+ return true;
+ }
+
+ if (inCode >= 65 && inCode <= 90) {
+ return true;
+ }
+
+ return `$_.`.includes(inGlyph);
+};
+
+/**
+ * @type {GlyphCheck}
+ */
+const isWhiteSpace = (inGlyph) => `\n\r\t `.includes(inGlyph);
+
+/**
+ * @type {GlyphCheck}
+ */
+const isQuote = (inGlyph) => `"'\``.includes(inGlyph);
+
+/**
+ * @param {GlyphCheck} inCheck
+ * @returns {GlyphCheck}
+ */
+const isNot = (inCheck) => (inGlyph) => !inCheck(inGlyph);
+
+/**
+ * @param {string} inText
+ * @param {number} inStart
+ * @param {GlyphCheck} inTest
+ * @returns {number}
+ */
+const contiguous = (inText, inStart, inTest) => {
+ let ok = true;
+ let index = inStart;
+ let count = 0;
+ while (ok && count < inText.length) {
+ count++;
+ ok = inTest(inText.charAt(index++));
+ }
+ return index - 1;
+};
+
+/**
+ * @param {string} inFile
+ * @param {number} [inIndex=0]
+ * @param {Array<{internal: string, external: string}>} inLocal
+ * @param {Array} inForeign
+ * @returns {number|boolean}
+ */
+const findNextExport = (inFile, inIndex = 0, inLocal, inForeign) => {
+ 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];
+
+ if (nextChar === "*") {
+ const firstQuoteInd = contiguous(inFile, nextCharInd + 1, isNot(isQuote));
+ const secondQuoteInd = contiguous(inFile, firstQuoteInd + 1, isNot(isQuote));
+ inForeign.push(inFile.substring(nextCharInd, secondQuoteInd + 1));
+ } else if (nextChar == "{") {
+ const endBracketInd = contiguous(inFile, nextCharInd, (inGlyph) => 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));
+ inForeign.push(inFile.substring(nextCharInd, secondQuoteInd + 1));
+ } else {
+ const members = inFile.substring(nextCharInd + 1, endBracketInd).replaceAll(" as ", "|||").replace(/\s/g, '');
+ members.split(",").forEach(part => {
+ const renamed = part.split("|||");
+ inLocal.push({ internal: renamed, external: renamed || renamed });
+ });
+ }
+ } else if (isAlphaLike(nextChar)) {
+ const keywordEndInd = contiguous(inFile, nextCharInd, isAlphaLike);
+ const keyword = inFile.substring(nextCharInd, keywordEndInd);
+ if (keyword === "default") {
+ inLocal.push({ internal: keyword, external: keyword });
+ } else if (["const", "let", "var", "function", "class"].includes(keyword)) {
+ const varStartInd = contiguous(inFile, keywordEndInd + 1, isWhiteSpace);
+ const varEndInd = contiguous(inFile, varStartInd + 1, isAlphaLike);
+ const keyword = inFile.substring(varStartInd, varEndInd);
+ inLocal.push({ internal: keyword, external: keyword });
+ }
+ }
+ }
+
+ return pos + 7;
+ } else {
+ return false;
+ }
+};
+
+/**
+ * @param {string} inFile
+ * @returns {[local: string[], foreign: string[]]}
+ */
+export const Exports = (inFile) => {
+ let match = /** @type {number|boolean} */ (0);
+ let count = 0;
+ const local = /** @type {string[]} */ ([]);
+ const foreign = /** @type {string[]} */ ([]);
+ while (match !== false && count < 200) {
+ count++;
+ match = findNextExport(inFile, match, local, foreign);
+ }
+ return [local, foreign];
+};
+
+/**
+ * @param {string|URL} inURL
+ * @returns {Promise<[local: string[], foreign: string[]]>}
+ */
+export const FileExports = async (inURL) => {
+ const resp = await fetch(inURL);
+ const text = await resp.text();
+ return Exports(text);
+};
diff --git a/junk/module_inspector.test.ts b/junk/module_inspector.test.ts
index 285801c..b2a1db7 100644
--- a/junk/module_inspector.test.ts
+++ b/junk/module_inspector.test.ts
@@ -1,12 +1,14 @@
import * as Inspector from "./module_inspector.ts";
+console.log();
+
Deno.test("check string parsing", ()=>{
const [local, global] = Inspector.Exports(`
// export in comment
/**
*
-* export const TESTtt
+* export const
* /
const fakeexport =()=>{};
const exportfake =()=>{};
diff --git a/junk/module_inspector.ts b/junk/module_inspector.ts
index 7c72d67..53e774a 100644
--- a/junk/module_inspector.ts
+++ b/junk/module_inspector.ts
@@ -32,7 +32,7 @@ const contiguous =(inText:string, inStart:number, inTest:GlyphCheck):number=>
return index-1;
}
-const findNextExport =(inFile:string, inIndex=0, inLocal:Array, inForeign:Array)=>
+const findNextExport =(inFile:string, inIndex=0, inLocal:Array<{internal:string, external:string }>, inForeign:Array)=>
{
const pos = inFile.indexOf("export", inIndex);
if(pos !== -1)
@@ -65,11 +65,12 @@ const findNextExport =(inFile:string, inIndex=0, inLocal:Array, inForeig
}
else
{
- const members = inFile.substring(nextCharInd+1, endBracketInd).replace(/\s/g, '');
+ const members = inFile.substring(nextCharInd+1, endBracketInd).replaceAll(" as ", "|||").replace(/\s/g, '');
members.split(",").forEach(part=>
{
- const renamed = part.split(" as ");
- inLocal.push(renamed[1] || renamed[0]);
+ const renamed = part.split("|||");
+ //inLocal.push(renamed[1] || renamed[0]);
+ inLocal.push({internal:renamed[0], external:renamed[1]||renamed[0]})
});
}
@@ -80,7 +81,7 @@ const findNextExport =(inFile:string, inIndex=0, inLocal:Array, inForeig
const keyword = inFile.substring(nextCharInd, keywordEndInd);
if(keyword === "default")
{
- inLocal.push(keyword);
+ inLocal.push({internal:keyword, external:keyword});
//console.log(`MEMBER: >>${keyword})}<<`);
}
else if(["const", "let", "var", "function", "class"].includes(keyword))
@@ -88,7 +89,8 @@ const findNextExport =(inFile:string, inIndex=0, inLocal:Array, inForeig
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))
+ const keyword = inFile.substring(varStartInd, varEndInd);
+ inLocal.push({internal:keyword, external:keyword});
}
}
}
diff --git a/preactthing.tsx b/preactthing.tsx
new file mode 100644
index 0000000..12f074a
--- /dev/null
+++ b/preactthing.tsx
@@ -0,0 +1,43 @@
+import { useState as preactUseState, useEffect as preactUseEffect } from 'preact/hooks';
+import { useState as reactUseState, useEffect as reactUseEffect } from 'react';
+import { options as preactOptions } from 'preact';
+
+const isPreact = typeof preactUseState === 'function';
+
+const useState = isPreact ? preactUseState : reactUseState;
+const useEffect = isPreact ? preactUseEffect : reactUseEffect;
+
+function useLogger(componentName) {
+ useEffect(() => {
+ console.log(`${isPreact ? 'Preact' : 'React'}: Component ${componentName} mounted`);
+ return () => {
+ console.log(`${isPreact ? 'Preact' : 'React'}: Component ${componentName} unmounted`);
+ };
+ }, [componentName]);
+
+ useEffect(() => {
+ console.log(`${isPreact ? 'Preact' : 'React'}: Component ${componentName} rendered`);
+ });
+}
+
+if (isPreact) {
+ preactOptions.__r = (vnode) => {
+ console.log('Preact: Rendering component:', vnode);
+ };
+
+ preactOptions.diffed = (vnode) => {
+ console.log('Preact: Component diffed:', vnode);
+ };
+
+ preactOptions.unmount = (vnode) => {
+ console.log('Preact: Unmounting component:', vnode);
+ };
+}
+
+// Example component using the custom hook
+function MyComponent() {
+ useLogger('MyComponent');
+ return My Component
;
+}
+
+export default MyComponent;
diff --git a/state-preserve/index.html b/state-preserve/index.html
new file mode 100644
index 0000000..45951ef
--- /dev/null
+++ b/state-preserve/index.html
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/state-preserve/preact.js b/state-preserve/preact.js
new file mode 100644
index 0000000..fe3c3b8
--- /dev/null
+++ b/state-preserve/preact.js
@@ -0,0 +1,30 @@
+import "https://esm.sh/preact@10.23.1/debug";
+import * as Preact from "https://esm.sh/preact@10.23.1";
+import * as React from "https://esm.sh/preact@10.23.1/compat";
+const H = Preact.h;
+
+console.log(React);
+
+/** @typedef {(vnode:Preact.VNode)=>unknown} DeepHook*/
+
+/** @type {DeepHook|undefined} */
+const renderOld =Preact.options.__r;
+
+/** @type {DeepHook} */
+const renderNew =(vnode)=>
+{
+ console.log("render!")
+ console.log(vnode);
+ // how to examine state context here?
+};
+
+Preact.options.__r = renderOld ? /**@type{DeepHook}*/((vnode)=>{renderOld(vnode); renderNew(vnode);}) : renderNew;
+
+const Component =()=>
+{
+ const [countGet, countSet] = React.useState(3);
+ return H("h1", {onClick(){countSet(countGet+1)}}, `count: ${countGet}`);
+}
+
+const root = document.querySelector("#app")||document.body;
+Preact.render(H(Component, {HEY:"HEY"}), root);
\ No newline at end of file
diff --git a/test_changer.mjs b/test_changer.mjs
index 1f30936..b03ae51 100644
--- a/test_changer.mjs
+++ b/test_changer.mjs
@@ -1,14 +1,20 @@
-export let changing = 2;
+export let changing = 42;
+////////////////////////////////////////////
+let ReImported = {};
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);
+ ReImported = module;
+ for(let key in module)
+ {
+ const statement = `${key}=ReImported.${key}`
+ eval(statement);
+ console.log(statement);
+ }
})
}, 3000);
}
\ No newline at end of file
diff --git a/transpiler/index.html b/transpiler/index.html
new file mode 100644
index 0000000..8171c0c
--- /dev/null
+++ b/transpiler/index.html
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file