diff --git a/app.js b/app.js index 636e6e7..b8a99ad 100644 --- a/app.js +++ b/app.js @@ -15,7 +15,7 @@ const css = Gale({ const Components = { Title() { - const titleString = HMR("title", "default!") + const titleString = Van.state("title"); return ()=> div({class:css("Board"), onclick(){ titleString.val = Math.random(); }}, titleString.val); @@ -23,7 +23,7 @@ const Components = { } const {div} = Van.tags; -Van.add(document.body, Components.Title()); +Van.add(document.querySelector("#app"), Components.Title()); const World = { diff --git a/index.html b/index.html index 903178d..50a7af0 100644 --- a/index.html +++ b/index.html @@ -2,6 +2,7 @@ +

Le App

diff --git a/lib/van/van.js b/lib/van/van.js index cd5ab53..0d42c00 100644 --- a/lib/van/van.js +++ b/lib/van/van.js @@ -119,20 +119,109 @@ let handler = ns => ({get: (_, name) => tag.bind(_undefined, ns, name)}) let update = (dom, newDom) => newDom ? newDom !== dom && dom.replaceWith(newDom) : dom.remove() -let updateDoms = () => { - let iter = 0, derivedStatesArray = [...changedStates].filter(s => s.rawVal !== s._oldVal) - do { - derivedStates = new Set - for (let l of new Set(derivedStatesArray.flatMap(s => s._listeners = keepConnected(s._listeners)))) - derive(l.f, l.s, l._dom), l._dom = _undefined - } while (++iter < 100 && (derivedStatesArray = [...derivedStates]).length) - let changedStatesArray = [...changedStates].filter(s => s.rawVal !== s._oldVal) - changedStates = _undefined - for (let b of new Set(changedStatesArray.flatMap(s => s._bindings = keepConnected(s._bindings)))) - update(b._dom, bind(b.f, b._dom)), b._dom = _undefined - for (let s of changedStatesArray) s._oldVal = s.rawVal +//let updateDoms = () => { +// let iter = 0, derivedStatesArray = [...changedStates].filter(s => s.rawVal !== s._oldVal) +// do { +// derivedStates = new Set +// for (let l of new Set(derivedStatesArray.flatMap(s => s._listeners = keepConnected(s._listeners)))) +// derive(l.f, l.s, l._dom), l._dom = _undefined +// } while (++iter < 100 && (derivedStatesArray = [...derivedStates]).length) +// let changedStatesArray = [...changedStates].filter(s => s.rawVal !== s._oldVal) +// changedStates = _undefined +// for (let b of new Set(changedStatesArray.flatMap(s => s._bindings = keepConnected(s._bindings)))) +// update(b._dom, bind(b.f, b._dom)), b._dom = _undefined +// for (let s of changedStatesArray) s._oldVal = s.rawVal +//} +/*********************************************** */ +// Map to track state-to-DOM relationships +const stateDomMap = new Map(); + + +function pathHash(/** @type {HTMLElement} */element) { + + console.log(element); + + const path = []; + let currentElement = element; + + while (currentElement && currentElement !== document.body && currentElement.parentNode) { + const siblings = Array.from(currentElement.parentNode.children); + const index = siblings.indexOf(currentElement); + path.unshift(index); // Push the index of the current element at the start of the path + currentElement = currentElement.parentNode; + } + + // Include the body in the path as the final part, with index 0 (since it's the root) + path.unshift(0); + + return path.join('-'); // Return the path as a string, e.g., "1-0-0-2" } +/** + * Logs a relationship between a state and a DOM element. + * @param {any} state - The state object being tracked. + * @param {Element} dom - The DOM element affected by the state. + */ +const trackStateDomRelationship = (state, dom, thing) => { + console.log(state, thing); + const hash = pathHash(dom); + if (!stateDomMap.has(hash)) { + stateDomMap.set(hash, new Set()); + } + stateDomMap.get(hash).add(state); +}; + +// Enhanced updateDoms function +let updateDoms = () => { + let iter = 0; + let derivedStatesArray = [...changedStates].filter(s => s.rawVal !== s._oldVal); + + do { + // Clear derivedStates for this iteration + derivedStates = new Set(); + + // Process listeners for derived states + for (let l of new Set(derivedStatesArray.flatMap(s => s._listeners = keepConnected(s._listeners)))) { + derive(l.f, l.s, l._dom); + + // Track which DOM element is being touched by this listener's state + if (l._dom) trackStateDomRelationship(l.s, l._dom); + + l._dom = _undefined; + } + } while (++iter < 100 && (derivedStatesArray = [...derivedStates]).length); + + // Update bindings for changed states + let changedStatesArray = [...changedStates].filter(s => s.rawVal !== s._oldVal); + changedStates = _undefined; + + + for (let b of new Set(changedStatesArray.flatMap(s => s._bindings = keepConnected(s._bindings)))) { + + // Track which DOM element is being touched by this binding's state + if (b._dom) trackStateDomRelationship(b.f, b._dom); + + update(b._dom, bind(b.f, b._dom)); + + b._dom = _undefined; + } + + // Update old values for changed states + for (let s of changedStatesArray) { + s._oldVal = s.rawVal; + } +}; + +// Debugging helper to log the state-DOM relationships +globalThis.Divulge = () => { + console.log("State-DOM Relationships:"); + for (const [state, domSet] of stateDomMap.entries()) { + console.log(state, [...domSet]); + } +}; +globalThis.path = pathHash; +/*********************************************** */ + export default { tags: new Proxy(ns => new Proxy(tag, handler(ns)), handler()), hydrate: (dom, f) => update(dom, bind(f, dom)),