centralized fake sockets
This commit is contained in:
parent
5cdb1cbf89
commit
3f9b3ba645
@ -1,6 +1,11 @@
|
||||
|
||||
<script>
|
||||
globalThis.Listen = [];
|
||||
|
||||
</script>
|
||||
<script type="module" src="test_receiver.mjs"></script>
|
||||
|
||||
<!--
|
||||
<!-- if test_rand.mjs exports a random number as default, there will be 4 different values if there is a cachebust on the import
|
||||
<script type="module">
|
||||
import r1 from "./test_rand.mjs?1";
|
||||
import r2 from "./test_rand.mjs?2";
|
||||
|
@ -1,43 +0,0 @@
|
||||
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 <div>My Component</div>;
|
||||
}
|
||||
|
||||
export default MyComponent;
|
@ -2,6 +2,6 @@
|
||||
<head></head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="./preact.js"></script>
|
||||
<script type="module" src="preact.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -3,28 +3,62 @@ 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)=>
|
||||
const SPOOF =(...args)=>
|
||||
{
|
||||
console.log("render!")
|
||||
console.log(vnode);
|
||||
// how to examine state context here?
|
||||
};
|
||||
console.log("spoof state", ...args);
|
||||
|
||||
const [hookGet, hookSet] = React.useState(...args);
|
||||
|
||||
const spoofSetter = (...args)=>{
|
||||
console.log("spoofed setter", ...args);
|
||||
hookSet(...args);
|
||||
}
|
||||
|
||||
return [
|
||||
hookGet,
|
||||
spoofSetter
|
||||
]
|
||||
}
|
||||
|
||||
function OptionsHook(key, hookNew)
|
||||
{
|
||||
const hookOld =Preact.options[key];
|
||||
Preact.options[key] = hookOld ? (...args)=>{hookOld(...args); hookNew(...args);} : hookNew;
|
||||
}
|
||||
|
||||
OptionsHook("__r", (/** @type {Preact.VNode}*/vnode)=>
|
||||
{
|
||||
console.log("render!");
|
||||
console.log();
|
||||
});
|
||||
|
||||
|
||||
OptionsHook("__h", (component_instance, hook_index, hook_state)=>
|
||||
{
|
||||
console.log("Hook!")
|
||||
console.log(hook_index, hook_state);
|
||||
})
|
||||
|
||||
OptionsHook("__", (...args)=>
|
||||
{
|
||||
console.log("unknown!")
|
||||
console.log(...args);
|
||||
})
|
||||
|
||||
|
||||
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 [countGet, countSet] = SPOOF(12345);
|
||||
const [textGet, textSet] = SPOOF("Count is:");
|
||||
return H("h1", {onClick(){countSet(countGet+1)}}, `${textGet} ${countGet}`);
|
||||
}
|
||||
|
||||
const root = document.querySelector("#app")||document.body;
|
||||
Preact.render(H(Component, {HEY:"HEY"}), root);
|
||||
Preact.render(
|
||||
H(Preact.Fragment, null,
|
||||
H(Component),
|
||||
H(Component),
|
||||
), root);
|
@ -1,4 +1,5 @@
|
||||
import {changing} from "./test_changer.mjs";
|
||||
import {changing, Component} from "./test_changer.mjs";
|
||||
import {Component as ComponentOther} from "./test_changer_other.mjs";
|
||||
|
||||
const area = document.createElement("pre");
|
||||
document.body.append(area);
|
||||
@ -8,4 +9,8 @@ export function Render()
|
||||
{
|
||||
console.log("pulling changing", changing)
|
||||
area.innerHTML = changing;
|
||||
|
||||
console.log("compoenent render:")
|
||||
Component();
|
||||
ComponentOther();
|
||||
}
|
@ -1,20 +1,21 @@
|
||||
export let changing = "hello!";
|
||||
|
||||
////////////////////////////////////////////
|
||||
let ReImported = {};
|
||||
/////////////////// injected /////////////////////////
|
||||
const thisURL = new URL(import.meta.url)
|
||||
const thisFile = thisURL.pathname;
|
||||
if(!thisURL.search)
|
||||
{
|
||||
setInterval(()=>{
|
||||
import(thisFile+"?"+Math.random()).then(module=>{
|
||||
ReImported = module;
|
||||
await import("./test_sockets.mjs").then(m=>m.Register(thisFile, (module)=>{
|
||||
for(let key in module)
|
||||
{
|
||||
const statement = `${key}=ReImported.${key}`
|
||||
eval(statement);
|
||||
console.log(statement);
|
||||
eval(`${key}=module.${key}`);
|
||||
}
|
||||
})
|
||||
}, 3000);
|
||||
}));
|
||||
}
|
||||
////////////////////////////////////////////
|
||||
|
||||
import spoofHook from "./test_framework.mjs?changer"
|
||||
export let changing = "123.";
|
||||
|
||||
export function Component()
|
||||
{
|
||||
spoofHook();
|
||||
}
|
21
test_changer_other.mjs
Normal file
21
test_changer_other.mjs
Normal file
@ -0,0 +1,21 @@
|
||||
/////////////////// injected /////////////////////////
|
||||
const thisURL = new URL(import.meta.url)
|
||||
const thisFile = thisURL.pathname;
|
||||
if(!thisURL.search)
|
||||
{
|
||||
await import("./test_sockets.mjs").then(m=>m.Register(thisFile, (module)=>{
|
||||
for(let key in module)
|
||||
{
|
||||
eval(`${key}=module.${key}`);
|
||||
}
|
||||
}));
|
||||
}
|
||||
////////////////////////////////////////////
|
||||
|
||||
import spoofHook from "./test_framework.mjs?changer_other"
|
||||
export let changing = "456";
|
||||
|
||||
export function Component()
|
||||
{
|
||||
spoofHook();
|
||||
}
|
18
test_framework.mjs
Normal file
18
test_framework.mjs
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
const url =new URL(import.meta.url)
|
||||
let context = url.search.substring(1)
|
||||
if(context)
|
||||
{
|
||||
console.log("context found:", context);
|
||||
}
|
||||
else
|
||||
{
|
||||
console.log("no context:", url);
|
||||
}
|
||||
|
||||
|
||||
export default function(){
|
||||
console.log("spoof hook context", context);
|
||||
console.log("spoof hook this", this);
|
||||
|
||||
}
|
@ -1 +0,0 @@
|
||||
export default Math.random();
|
@ -1,5 +1,7 @@
|
||||
import * as App from "./test_application.mjs";
|
||||
|
||||
globalThis.Listen = [];
|
||||
|
||||
const button = document.createElement("button");
|
||||
button.innerHTML = "Reload";
|
||||
button.addEventListener("click", ()=>
|
||||
|
25
test_sockets.mjs
Normal file
25
test_sockets.mjs
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
/** @type {Map<string, ()=>Promise<void>} */
|
||||
const Files = new Map();
|
||||
|
||||
globalThis.MODULE = {};
|
||||
|
||||
/** @type {(file:string, hnadler:()=>void)} */
|
||||
export function Register(file, handler)
|
||||
{
|
||||
console.log("registering", file);
|
||||
const WrapperHandler =()=> import(file+"?"+new Date().getTime()).then(handler);
|
||||
Files.set(file, WrapperHandler);
|
||||
}
|
||||
|
||||
const Loop =async()=>
|
||||
{
|
||||
console.log("looping!");
|
||||
for (const [fileName, handler] of Files.entries())
|
||||
{
|
||||
await handler();
|
||||
}
|
||||
setTimeout(Loop, 3000);
|
||||
}
|
||||
|
||||
Loop();
|
@ -3,6 +3,65 @@
|
||||
<body>
|
||||
<button id="open">open</button>
|
||||
<script type="module">
|
||||
import { openDB } from "https://esm.sh/idb@8.0.0";
|
||||
|
||||
async function initDB() {
|
||||
const db = await openDB('file-handles', 1, {
|
||||
upgrade(db) {
|
||||
if (!db.objectStoreNames.contains('handles')) {
|
||||
db.createObjectStore('handles');
|
||||
}
|
||||
},
|
||||
});
|
||||
return db;
|
||||
}
|
||||
|
||||
async function storeHandle(handle) {
|
||||
const db = await initDB();
|
||||
await db.put('handles', handle, 'directory');
|
||||
}
|
||||
|
||||
async function getStoredHandle() {
|
||||
const db = await initDB();
|
||||
const handle = await db.get('handles', 'directory');
|
||||
return handle;
|
||||
}
|
||||
|
||||
async function verifyPermission(handle, readWrite) {
|
||||
const options = {};
|
||||
if (readWrite) {
|
||||
options.mode = 'readwrite';
|
||||
}
|
||||
if ((await handle.queryPermission(options)) === 'granted') {
|
||||
return true;
|
||||
}
|
||||
if ((await handle.requestPermission(options)) === 'granted') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
async function init() {
|
||||
let handle = await getStoredHandle();
|
||||
if (handle) {
|
||||
const hasPermission = await verifyPermission(handle, true);
|
||||
if (!hasPermission) {
|
||||
handle = null;
|
||||
}
|
||||
}
|
||||
if (!handle) {
|
||||
handle = await globalThis.showDirectoryPicker();
|
||||
await storeHandle(handle);
|
||||
}
|
||||
console.log('Directory handle:', handle);
|
||||
return handle;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// Function to walk through the directory and update file handles
|
||||
async function updateFileHandles(dirHandle, extension, path = "", map) {
|
||||
@ -46,7 +105,8 @@ async function checkModifiedDates(map, date) {
|
||||
|
||||
// Main function to set up the intervals
|
||||
async function main() {
|
||||
const dirHandle = await window.showDirectoryPicker();
|
||||
//const dirHandle = await window.showDirectoryPicker();
|
||||
const dirHandle = await init();
|
||||
const extension = '.html'; // Change this to the desired file extension
|
||||
|
||||
let fileHandlesMap = new Map();
|
||||
|
Loading…
Reference in New Issue
Block a user