UNPKG

flexium

Version:

A lightweight, signals-based UI framework with cross-platform renderers

1 lines 4.37 kB
{"version":3,"sources":["../src/renderers/dom/hydrate.ts"],"names":["hydrate","vnode","container","hydrateNode","domNode","isSignal","effect","result","el","key","eventName","childDom","children","child"],"mappings":"mdAEO,SAASA,EAAQC,CAAAA,CAAYC,CAAAA,CAAoB,CAWpDC,CAAAA,CAAYF,CAAAA,CAAOC,EAAU,UAAkB,EACnD,CAEA,SAASC,EAAYF,CAAAA,CAAYG,CAAAA,CAAmC,CAChE,GAAI,CAACA,GAAW,CAACH,CAAAA,CAAO,OAAO,IAAA,CAE/B,IAAI,OAAOA,CAAAA,EAAU,UAAY,OAAOA,CAAAA,EAAU,WAC1CG,CAAAA,CAAQ,QAAA,GAAa,KAAK,SAAA,CAC1B,OAAIA,EAAQ,WAAA,GAAgB,MAAA,CAAOH,CAAK,CAAA,GACpCG,CAAAA,CAAQ,YAAc,MAAA,CAAOH,CAAK,CAAA,CAAA,CAE/BG,CAAAA,CAAQ,YAIvB,GAAIC,CAAAA,CAASJ,CAAK,CAAA,EAEVG,CAAAA,CAAQ,WAAa,IAAA,CAAK,SAAA,CAC1B,OAAAE,CAAAA,CAAO,IAAM,CACTF,CAAAA,CAAQ,YAAc,MAAA,CAAOH,CAAAA,CAAM,KAAK,EAC5C,CAAC,CAAA,CACMG,CAAAA,CAAQ,YAIvB,GAAI,OAAOH,EAAM,IAAA,EAAS,UAAA,CAAY,CAClC,IAAMM,CAAAA,CAASN,EAAM,IAAA,CAAKA,CAAAA,CAAM,OAAS,EAAE,EAC3C,OAAOE,CAAAA,CAAYI,EAAQH,CAAO,CACtC,CAEA,GAAI,OAAOH,CAAAA,CAAM,IAAA,EAAS,UAClBG,CAAAA,CAAQ,QAAA,GAAa,KAAK,YAAA,EAAiBA,CAAAA,CAAoB,OAAA,CAAQ,WAAA,KAAkBH,CAAAA,CAAM,IAAA,CAAK,aAAY,CAAG,CACnH,IAAMO,CAAAA,CAAKJ,CAAAA,CAGX,GAAIH,CAAAA,CAAM,OACN,IAAA,IAAWQ,CAAAA,IAAOR,EAAM,KAAA,CACpB,GAAIQ,EAAI,UAAA,CAAW,IAAI,EAAG,CACtB,IAAMC,EAAYD,CAAAA,CAAI,KAAA,CAAM,CAAC,CAAA,CAAE,WAAA,GAC/BD,CAAAA,CAAG,gBAAA,CAAiBE,CAAAA,CAAWT,CAAAA,CAAM,MAAMQ,CAAG,CAAC,EACnD,CAAA,CAKR,IAAIE,EAAWH,CAAAA,CAAG,UAAA,CAClB,GAAIP,CAAAA,CAAM,SAAU,CAChB,IAAMW,EAAW,KAAA,CAAM,OAAA,CAAQX,EAAM,QAAQ,CAAA,CAAIA,CAAAA,CAAM,QAAA,CAAW,CAACA,CAAAA,CAAM,QAAQ,EACjF,IAAA,IAAWY,CAAAA,IAASD,EAChBD,CAAAA,CAAWR,CAAAA,CAAYU,EAAOF,CAAQ,EAE9C,CAEA,OAAOH,CAAAA,CAAG,WACd,CAGJ,OAAOJ,EAAQ,WACnB","file":"dom.mjs","sourcesContent":["import { effect, isSignal } from '../../core/signal';\n\nexport function hydrate(vnode: any, container: Element) {\n // Simple hydration strategy: \n // For this MVP, we will clear the container and re-render.\n // True hydration requires matching VDOM to existing DOM nodes, which is complex.\n // Re-rendering is a valid \"hydration\" strategy for simple frameworks to ensure interactivity,\n // although less performant than true hydration.\n\n // TODO: Implement true hydration that walks the DOM tree.\n // For now, we reuse the existing render logic but we need to be careful not to double-mount.\n\n // Actually, let's try a basic true hydration approach.\n hydrateNode(vnode, container.firstChild as Node);\n}\n\nfunction hydrateNode(vnode: any, domNode: Node | null): Node | null {\n if (!domNode || !vnode) return null;\n\n if (typeof vnode === 'string' || typeof vnode === 'number') {\n if (domNode.nodeType === Node.TEXT_NODE) {\n if (domNode.textContent !== String(vnode)) {\n domNode.textContent = String(vnode);\n }\n return domNode.nextSibling;\n }\n }\n\n if (isSignal(vnode)) {\n // For signals, we create an effect to update the text node\n if (domNode.nodeType === Node.TEXT_NODE) {\n effect(() => {\n domNode.textContent = String(vnode.value);\n });\n return domNode.nextSibling;\n }\n }\n\n if (typeof vnode.type === 'function') {\n const result = vnode.type(vnode.props || {});\n return hydrateNode(result, domNode);\n }\n\n if (typeof vnode.type === 'string') {\n if (domNode.nodeType === Node.ELEMENT_NODE && (domNode as Element).tagName.toLowerCase() === vnode.type.toLowerCase()) {\n const el = domNode as Element;\n\n // Attach events\n if (vnode.props) {\n for (const key in vnode.props) {\n if (key.startsWith('on')) {\n const eventName = key.slice(2).toLowerCase();\n el.addEventListener(eventName, vnode.props[key]);\n }\n }\n }\n\n // Hydrate children\n let childDom = el.firstChild;\n if (vnode.children) {\n const children = Array.isArray(vnode.children) ? vnode.children : [vnode.children];\n for (const child of children) {\n childDom = hydrateNode(child, childDom) as ChildNode | null;\n }\n }\n\n return el.nextSibling;\n }\n }\n\n return domNode.nextSibling;\n}\n"]}