@cfdez11/vex 0.10.3 → 0.10.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- const routeCache=new Map;async function loadRouteComponent(path,importer){if(routeCache.has(path))return routeCache.get(path);const module=await importer();return routeCache.set(path,module),module}async function prefetchRouteComponent(path,importer){try{await loadRouteComponent(path,importer)}catch(e){console.error(`Prefetch failed for route ${path}:`,e)}}function isRouteLoaded(path){return routeCache.has(path)}function clearRouteCache(){routeCache.clear()}var cache_default=routeCache;export{clearRouteCache,cache_default as default,isRouteLoaded,loadRouteComponent,prefetchRouteComponent};
1
+ const o=new Map;async function n(e,r){if(o.has(e))return o.get(e);const t=await r();return o.set(e,t),t}async function c(e,r){try{await n(e,r)}catch(t){console.error(`Prefetch failed for route ${e}:`,t)}}function a(e){return o.has(e)}function u(){o.clear()}var f=o;export{u as clearRouteCache,f as default,a as isRouteLoaded,n as loadRouteComponent,c as prefetchRouteComponent};
@@ -1 +1 @@
1
- (function(){const evtSource=new EventSource("/_vexjs/hmr");evtSource.addEventListener("reload",e=>{console.log(`[HMR] ${e.data||"file changed"} \u2014 reloading`),location.reload()}),evtSource.onerror=()=>{evtSource.close()}})();
1
+ (function(){const e=new EventSource("/_vexjs/hmr");e.addEventListener("reload",o=>{console.log(`[HMR] ${o.data||"file changed"} \u2014 reloading`),location.reload()}),e.onerror=()=>{e.close()}})();
@@ -1 +1 @@
1
- function html(strings,...values){const markers=values.map((_,i)=>`__HTML_MARKER_${i}__`);let htmlString=strings[0];for(let i=0;i<values.length;i++)htmlString+=markers[i]+strings[i+1];const template=document.createElement("template");template.innerHTML=htmlString.trim();const fragment=template.content.cloneNode(!0);processDirectives(fragment,markers,values);const node=fragment.childElementCount===1?fragment.firstElementChild:fragment;return processNode(node,markers,values),node}function processDirectives(node,markers,values){if(node.nodeType!==Node.ELEMENT_NODE&&node.nodeType!==Node.DOCUMENT_FRAGMENT_NODE)return;const children=Array.from(node.childNodes);for(let i=0;i<children.length;i++){const child=children[i];if(child.nodeType===Node.ELEMENT_NODE){if(child.hasAttribute("x-if")){i=handleConditionalChain(node,children,i,markers,values);continue}if(child.hasAttribute("x-for")){handleVFor(child,markers,values);continue}processDirectives(child,markers,values)}}}function handleConditionalChain(parent,children,startIndex,markers,values){const chain=[];let currentIndex=startIndex;for(;currentIndex<children.length;){const element=children[currentIndex];if(element.nodeType!==Node.ELEMENT_NODE){currentIndex++;continue}if(element.hasAttribute("x-if")){if(chain.length>0)break;chain.push({element,type:"if",condition:element.getAttribute("x-if")}),currentIndex++}else if(element.hasAttribute("x-else-if")){if(!chain.length)break;chain.push({element,type:"else-if",condition:element.getAttribute("x-else-if")}),currentIndex++}else if(element.hasAttribute("x-else")){if(!chain.length)break;chain.push({element,type:"else",condition:null}),currentIndex++;break}else break}let kept=null;for(const item of chain){if(kept){item.element.remove();continue}if(item.type==="else")kept=item.element,item.element.removeAttribute("x-else");else{const markerIndex=markers.findIndex(m=>item.condition.includes(m));(markerIndex!==-1?values[markerIndex]:!1)?(kept=item.element,item.element.removeAttribute(item.type==="if"?"x-if":"x-else-if")):item.element.remove()}}return currentIndex-1}function handleVFor(element,markers,values){const vForValue=element.getAttribute("x-for"),markerIndex=markers.findIndex(m=>vForValue.includes(m));if(markerIndex===-1||!Array.isArray(values[markerIndex])){element.removeAttribute("x-for");return}const items=values[markerIndex],parent=element.parentNode,template=element.cloneNode(!0);template.removeAttribute("x-for");const fragment=document.createDocumentFragment();for(const item of items){const clone=template.cloneNode(!0);replaceItemReferences(clone,item),fragment.appendChild(clone)}parent.replaceChild(fragment,element)}function replaceItemReferences(node,item){if(node.nodeType===Node.ELEMENT_NODE){for(const attr of Array.from(node.attributes))if(attr.value.includes("item.")){const prop=attr.value.replace("item.","");node.setAttribute(attr.name,item[prop]??"")}}for(const child of Array.from(node.childNodes))replaceItemReferences(child,item)}function processNode(node,markers,values){if(node.nodeType===Node.TEXT_NODE)return processTextNode(node,markers,values);node.nodeType===Node.ELEMENT_NODE&&processAttributes(node,markers,values);for(const child of Array.from(node.childNodes))processNode(child,markers,values)}function processTextNode(node,markers,values){let text=node.textContent;for(let i=0;i<markers.length;i++){if(!text.includes(markers[i]))continue;const value=values[i],parent=node.parentNode,parts=text.split(markers[i]);if(parts[0]&&parent.insertBefore(document.createTextNode(parts[0]),node),Array.isArray(value))for(const item of value)item instanceof Node?(processNode(item,markers,values),parent.insertBefore(item,node)):parent.insertBefore(document.createTextNode(String(item??"")),node);else value instanceof Node?(processNode(value,markers,values),parent.insertBefore(value,node)):parent.insertBefore(document.createTextNode(String(value??"")),node);text=parts.slice(1).join(markers[i])}node.textContent=text}function getNodePropertyInfo(attrName){return{class:{property:"className",canBeJoined:!0}}[attrName]||{property:attrName,canBeJoined:!1}}function processAttributes(element,markers,values){for(const attr of Array.from(element.attributes)){if(attr.name.startsWith("@")){const event=attr.name.slice(1),idx=markers.findIndex(m=>attr.value.includes(m)),handler=values[idx];typeof handler=="function"&&element.addEventListener(event,handler),element.removeAttribute(attr.name);continue}if(attr.name.startsWith(":")){const{property,canBeJoined}=getNodePropertyInfo(attr.name.slice(1)),idx=markers.findIndex(m=>attr.value.includes(m));if(idx!==-1){const value=values[idx];typeof value=="boolean"?element.toggleAttribute(property,value):element[property]=canBeJoined&&element[property]?`${element[property]} ${value}`:value}element.removeAttribute(attr.name)}if(attr.name==="x-show"){const idx=markers.findIndex(m=>attr.value.includes(m)),value=idx!==-1?values[idx]:!1;element.style.display=value?"":"none",element.removeAttribute("x-show");continue}if(attr.name.startsWith("data-")){const dataAttr=attr.name.slice(5),idx=markers.findIndex(m=>attr.value.includes(m));if(idx!==-1){const value=values[idx];element.dataset[dataAttr]=typeof value=="object"&&value!==null?JSON.stringify(value):String(value??"")}}}}export{html};
1
+ function E(e,...n){const c=n.map((s,f)=>`__HTML_MARKER_${f}__`);let o=e[0];for(let s=0;s<n.length;s++)o+=c[s]+e[s+1];const i=document.createElement("template");i.innerHTML=o.trim();const t=i.content.cloneNode(!0);u(t,c,n);const r=t.childElementCount===1?t.firstElementChild:t;return d(r,c,n),r}function u(e,n,c){if(e.nodeType!==Node.ELEMENT_NODE&&e.nodeType!==Node.DOCUMENT_FRAGMENT_NODE)return;const o=Array.from(e.childNodes);for(let i=0;i<o.length;i++){const t=o[i];if(t.nodeType===Node.ELEMENT_NODE){if(t.hasAttribute("x-if")){i=N(e,o,i,n,c);continue}if(t.hasAttribute("x-for")){x(t,n,c);continue}u(t,n,c)}}}function N(e,n,c,o,i){const t=[];let r=c;for(;r<n.length;){const f=n[r];if(f.nodeType!==Node.ELEMENT_NODE){r++;continue}if(f.hasAttribute("x-if")){if(t.length>0)break;t.push({element:f,type:"if",condition:f.getAttribute("x-if")}),r++}else if(f.hasAttribute("x-else-if")){if(!t.length)break;t.push({element:f,type:"else-if",condition:f.getAttribute("x-else-if")}),r++}else if(f.hasAttribute("x-else")){if(!t.length)break;t.push({element:f,type:"else",condition:null}),r++;break}else break}let s=null;for(const f of t){if(s){f.element.remove();continue}if(f.type==="else")s=f.element,f.element.removeAttribute("x-else");else{const l=o.findIndex(h=>f.condition.includes(h));(l!==-1?i[l]:!1)?(s=f.element,f.element.removeAttribute(f.type==="if"?"x-if":"x-else-if")):f.element.remove()}}return r-1}function x(e,n,c){const o=e.getAttribute("x-for"),i=n.findIndex(l=>o.includes(l));if(i===-1||!Array.isArray(c[i])){e.removeAttribute("x-for");return}const t=c[i],r=e.parentNode,s=e.cloneNode(!0);s.removeAttribute("x-for");const f=document.createDocumentFragment();for(const l of t){const a=s.cloneNode(!0);p(a,l),f.appendChild(a)}r.replaceChild(f,e)}function p(e,n){if(e.nodeType===Node.ELEMENT_NODE){for(const c of Array.from(e.attributes))if(c.value.includes("item.")){const o=c.value.replace("item.","");e.setAttribute(c.name,n[o]??"")}}for(const c of Array.from(e.childNodes))p(c,n)}function d(e,n,c){if(e.nodeType===Node.TEXT_NODE)return m(e,n,c);e.nodeType===Node.ELEMENT_NODE&&A(e,n,c);for(const o of Array.from(e.childNodes))d(o,n,c)}function m(e,n,c){let o=e.textContent;for(let i=0;i<n.length;i++){if(!o.includes(n[i]))continue;const t=c[i],r=e.parentNode,s=o.split(n[i]);if(s[0]&&r.insertBefore(document.createTextNode(s[0]),e),Array.isArray(t))for(const f of t)f instanceof Node?(d(f,n,c),r.insertBefore(f,e)):r.insertBefore(document.createTextNode(String(f??"")),e);else t instanceof Node?(d(t,n,c),r.insertBefore(t,e)):r.insertBefore(document.createTextNode(String(t??"")),e);o=s.slice(1).join(n[i])}e.textContent=o}function y(e){return{class:{property:"className",canBeJoined:!0}}[e]||{property:e,canBeJoined:!1}}function A(e,n,c){for(const o of Array.from(e.attributes)){if(o.name.startsWith("@")){const i=o.name.slice(1),t=n.findIndex(s=>o.value.includes(s)),r=c[t];typeof r=="function"&&e.addEventListener(i,r),e.removeAttribute(o.name);continue}if(o.name.startsWith(":")){const{property:i,canBeJoined:t}=y(o.name.slice(1)),r=n.findIndex(s=>o.value.includes(s));if(r!==-1){const s=c[r];typeof s=="boolean"?e.toggleAttribute(i,s):e[i]=t&&e[i]?`${e[i]} ${s}`:s}e.removeAttribute(o.name)}if(o.name==="x-show"){const i=n.findIndex(r=>o.value.includes(r)),t=i!==-1?c[i]:!1;e.style.display=t?"":"none",e.removeAttribute("x-show");continue}if(o.name.startsWith("data-")){const i=o.name.slice(5),t=n.findIndex(r=>o.value.includes(r));if(t!==-1){const r=c[t];e.dataset[i]=typeof r=="object"&&r!==null?JSON.stringify(r):String(r??"")}}}}export{E as html};
@@ -1 +1 @@
1
- (function(){async function hydrateMarker(marker,props={}){if(marker.dataset.hydrated==="true")return;marker.dataset.hydrated="true";const componentName=marker.getAttribute("data-client:component"),componentProps=marker.getAttribute("data-client:props");let parsedProps={};try{parsedProps=JSON.parse(componentProps||"{}")}catch(e){console.warn(`Failed to parse props for component ${componentName}`,e)}const finalProps={...parsedProps,...props};try{await(await import(`/_vexjs/_components/${componentName}.js`)).hydrateClientComponent(marker,finalProps)}catch(error){console.error(`Failed to load component: ${componentName}`,error)}}async function hydrateComponents(container=document,props={}){let markers;do markers=container.querySelectorAll("[data-client\\:component]:not([data-hydrated='true'])"),await Promise.all([...markers].map(marker=>hydrateMarker(marker,props)));while(markers.length>0)}new MutationObserver(mutations=>{for(const mutation of mutations)for(const node of mutation.addedNodes)node.nodeType===1&&(node.matches?.("[data-client\\:component]")&&hydrateMarker(node),hydrateComponents(node))}).observe(document,{childList:!0,subtree:!0}),document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>hydrateComponents()):hydrateComponents(),window.hydrateComponents=hydrateComponents})();
1
+ (function(){async function d(e,o={}){if(e.dataset.hydrated==="true")return;e.dataset.hydrated="true";const t=e.getAttribute("data-client:component"),r=e.getAttribute("data-client:props");let c={};try{c=JSON.parse(r||"{}")}catch(a){console.warn(`Failed to parse props for component ${t}`,a)}const s={...c,...o};try{await(await import(`/_vexjs/_components/${t}.js`)).hydrateClientComponent(e,s)}catch(a){console.error(`Failed to load component: ${t}`,a)}}async function n(e=document,o={}){let t;do t=e.querySelectorAll("[data-client\\:component]:not([data-hydrated='true'])"),await Promise.all([...t].map(r=>d(r,o)));while(t.length>0)}new MutationObserver(e=>{for(const o of e)for(const t of o.addedNodes)t.nodeType===1&&(t.matches?.("[data-client\\:component]")&&d(t),n(t))}).observe(document,{childList:!0,subtree:!0}),document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>n()):n(),window.hydrateComponents=n})();
@@ -1 +1 @@
1
- window.hydrateTarget=function(targetId,sourceId){const target=document.getElementById(targetId),template=document.getElementById(sourceId);target&&template&&(target.replaceWith(template.content.cloneNode(!0)),template.remove())};
1
+ window.hydrateTarget=function(n,o){const t=document.getElementById(n),e=document.getElementById(o);t&&e&&(t.replaceWith(e.content.cloneNode(!0)),e.remove())};
@@ -1 +1 @@
1
- import{initializeRouter,navigate}from"./navigation/index.js";window.app={navigate},document.addEventListener("DOMContentLoaded",()=>{initializeRouter()});
1
+ import{initializeRouter as e,navigate as t}from"./navigation/index.js";window.app={navigate:t},document.addEventListener("DOMContentLoaded",()=>{e()});
@@ -1 +1 @@
1
- function createLayoutRenderer(){const renderedLayouts=new Map;function cleanNotNeeded(routeLayouts){for(const name of renderedLayouts.keys())routeLayouts.some(l=>l.name===name)||renderedLayouts.delete(name)}function getNearestRendered(routeLayouts){const reversed=routeLayouts.toReversed();for(const layout of reversed)if(renderedLayouts.has(layout.name))return renderedLayouts.get(layout.name);return null}function getLayoutsToRender(routeLayouts,nearestRendered){if(!nearestRendered)return routeLayouts;const reversed=routeLayouts.toReversed(),idx=reversed.findIndex(l=>l.name===nearestRendered.name);return idx===-1?routeLayouts:reversed.slice(0,idx)}async function loadLayoutModules(layouts){return Promise.all(layouts.map(layout=>import(layout.importPath)))}async function generate({routeLayouts=[],pageNode,metadata}){if(!pageNode||routeLayouts.length===0)return{layoutId:null,node:pageNode,metadata};cleanNotNeeded(routeLayouts);const nearestRendered=getNearestRendered(routeLayouts),layoutsToRender=getLayoutsToRender(routeLayouts,nearestRendered),modules=await loadLayoutModules(layoutsToRender);let htmlContainerNode=pageNode,deepestMetadata=metadata;for(let i=modules.length-1;i>=0;i--){const layout=layoutsToRender[i],mod=modules[i],childrenWrapper=document.createElement("vex-root");childrenWrapper.appendChild(htmlContainerNode);const marker=document.createElement("template");htmlContainerNode=mod.hydrateClientComponent(marker,{children:childrenWrapper}),!deepestMetadata&&mod.metadata&&(deepestMetadata=mod.metadata),renderedLayouts.set(layout.name,{name:layout.name,children:childrenWrapper,node:htmlContainerNode})}return{layoutId:nearestRendered?.name??null,node:htmlContainerNode,metadata:deepestMetadata}}function patch(layoutId,node){const record=renderedLayouts.get(layoutId);record&&record.children.replaceChildren(node)}function reset(){renderedLayouts.clear()}return{generate,patch,reset}}export{createLayoutRenderer};
1
+ function C(){const r=new Map;function f(e){for(const n of r.keys())e.some(o=>o.name===n)||r.delete(n)}function h(e){const n=e.toReversed();for(const t of n)if(r.has(t.name))return r.get(t.name);return null}function p(e,n){if(!n)return e;const t=e.toReversed(),o=t.findIndex(a=>a.name===n.name);return o===-1?e:t.slice(0,o)}async function y(e){return Promise.all(e.map(n=>import(n.importPath)))}async function x({routeLayouts:e=[],pageNode:n,metadata:t}){if(!n||e.length===0)return{layoutId:null,node:n,metadata:t};f(e);const o=h(e),a=p(e,o),m=await y(a);let c=n,l=t;for(let d=m.length-1;d>=0;d--){const u=a[d],s=m[d],i=document.createElement("vex-root");i.appendChild(c);const v=document.createElement("template");c=s.hydrateClientComponent(v,{children:i}),!l&&s.metadata&&(l=s.metadata),r.set(u.name,{name:u.name,children:i,node:c})}return{layoutId:o?.name??null,node:c,metadata:l}}function R(e,n){const t=r.get(e);t&&t.children.replaceChildren(n)}function g(){r.clear()}return{generate:x,patch:R,reset:g}}export{C as createLayoutRenderer};
@@ -1 +1 @@
1
- import{setupLinkInterceptor}from"./link-interceptor.js";import{setupPrefetchObserver}from"./prefetch.js";import{navigateInternal}from"./navigate.js";import{findRouteWithParams}from"./router.js";import{createLayoutRenderer}from"./create-layouts.js";function createNavigationRuntime(){let currentNavigationController=null;const layoutRenderer=createLayoutRenderer();function abortPrevious(){currentNavigationController&&currentNavigationController.abort()}async function navigate(path,addToHistory=!0){abortPrevious();const controller=new AbortController;currentNavigationController=controller;try{await navigateInternal({path,addToHistory,controller,layoutRenderer,onFinish:()=>{currentNavigationController===controller&&(currentNavigationController=null)}})}catch(e){e.name!=="AbortError"&&console.error("Navigation error:",e)}}function initialize(){window.addEventListener("popstate",()=>{navigate(location.pathname,!1)}),setupLinkInterceptor(navigate),setupPrefetchObserver(),layoutRenderer.reset();const{route}=findRouteWithParams(location.pathname);route?.meta?.ssr||navigate(location.pathname,!1)}return{navigate,initialize}}export{createNavigationRuntime};
1
+ import{setupLinkInterceptor as s}from"./link-interceptor.js";import{setupPrefetchObserver as f}from"./prefetch.js";import{navigateInternal as m}from"./navigate.js";import{findRouteWithParams as u}from"./router.js";import{createLayoutRenderer as p}from"./create-layouts.js";function w(){let t=null;const n=p();function i(){t&&t.abort()}async function r(e,l=!0){i();const o=new AbortController;t=o;try{await m({path:e,addToHistory:l,controller:o,layoutRenderer:n,onFinish:()=>{t===o&&(t=null)}})}catch(a){a.name!=="AbortError"&&console.error("Navigation error:",a)}}function c(){window.addEventListener("popstate",()=>{r(location.pathname,!1)}),s(r),f(),n.reset();const{route:e}=u(location.pathname);e?.meta?.ssr||r(location.pathname,!1)}return{navigate:r,initialize:c}}export{w as createNavigationRuntime};
@@ -1 +1 @@
1
- import{createNavigationRuntime}from"./create-navigation.js";const navigation=createNavigationRuntime(),initializeRouter=navigation.initialize,navigate=navigation.navigate;import{useRouteParams}from"./use-route-params.js";import{useQueryParams}from"./use-query-params.js";export{initializeRouter,navigate,useQueryParams,useRouteParams};
1
+ import{createNavigationRuntime as e}from"./create-navigation.js";const t=e(),a=t.initialize,o=t.navigate;import{useRouteParams as m}from"./use-route-params.js";import{useQueryParams as u}from"./use-query-params.js";export{a as initializeRouter,o as navigate,u as useQueryParams,m as useRouteParams};
@@ -1 +1 @@
1
- function setupLinkInterceptor(navigate){document.addEventListener("click",event=>{const link=event.target.closest("a");if(!link)return;const href=link.getAttribute("href");if(!href||href.startsWith("#"))return;const url=new URL(href,window.location.origin);url.origin!==window.location.origin||link.dataset.reload!==void 0||link.target==="_blank"||link.rel==="external"||(event.preventDefault(),navigate(url.pathname))})}export{setupLinkInterceptor};
1
+ function o(i){document.addEventListener("click",n=>{const t=n.target.closest("a");if(!t)return;const e=t.getAttribute("href");if(!e||e.startsWith("#"))return;const r=new URL(e,window.location.origin);r.origin!==window.location.origin||t.dataset.reload!==void 0||t.target==="_blank"||t.rel==="external"||(n.preventDefault(),i(r.pathname))})}export{o as setupLinkInterceptor};
@@ -1 +1 @@
1
- function addMetadata(metadata){if(metadata.title&&(document.title=metadata.title),metadata.description){let meta=document.querySelector('meta[name="description"]');meta||(meta=document.createElement("meta"),meta.name="description",document.head.appendChild(meta)),meta.content=metadata.description}}export{addMetadata};
1
+ function i(t){if(t.title&&(document.title=t.title),t.description){let e=document.querySelector('meta[name="description"]');e||(e=document.createElement("meta"),e.name="description",document.head.appendChild(e)),e.content=t.description}}export{i as addMetadata};
@@ -1 +1 @@
1
- import{findRouteWithParams}from"./router.js";import{routes}from"../_routes.js";import{updateRouteParams}from"./use-route-params.js";import{renderPage}from"./render-page.js";import{renderSSRPage}from"./render-ssr.js";async function navigateInternal({path,addToHistory,controller,layoutRenderer,onFinish}){updateRouteParams(path);const routePath=path.split("?")[0],{route:matchedRoute}=findRouteWithParams(routePath),route=matchedRoute??routes.find(r=>r.isNotFound)??null;addToHistory&&history.pushState({},"",path);try{if(route?.meta?.ssr){layoutRenderer.reset(),await renderSSRPage(path,controller.signal);return}if(route?.meta?.requiresAuth&&!app.Store?.loggedIn){location.href="/account/login";return}if(route?.meta?.guestOnly&&app.Store?.loggedIn){location.href="/account";return}await renderPage({route,layoutRenderer})}finally{onFinish()}}export{navigateInternal};
1
+ import{findRouteWithParams as m}from"./router.js";import{routes as f}from"../_routes.js";import{updateRouteParams as c}from"./use-route-params.js";import{renderPage as l}from"./render-page.js";import{renderSSRPage as g}from"./render-ssr.js";async function y({path:t,addToHistory:e,controller:n,layoutRenderer:o,onFinish:a}){c(t);const i=t.split("?")[0],{route:u}=m(i),r=u??f.find(s=>s.isNotFound)??null;e&&history.pushState({},"",t);try{if(r?.meta?.ssr){o.reset(),await g(t,n.signal);return}if(r?.meta?.requiresAuth&&!app.Store?.loggedIn){location.href="/account/login";return}if(r?.meta?.guestOnly&&app.Store?.loggedIn){location.href="/account";return}await l({route:r,layoutRenderer:o})}finally{a()}}export{y as navigateInternal};
@@ -1 +1 @@
1
- import{routes}from"../_routes.js";import{prefetchRouteComponent}from"../cache.js";function setupPrefetchObserver(){const observer=new IntersectionObserver(entries=>{entries.forEach(entry=>{if(!entry.isIntersecting)return;const link=entry.target;if(!link.hasAttribute("data-prefetch"))return;const url=new URL(link.href,location.origin),route=routes.find(r=>r.path===url.pathname);route?.component&&(prefetchRouteComponent(route.path,route.component),observer.unobserve(link))})},{rootMargin:"200px"});document.querySelectorAll("a[data-prefetch]").forEach(link=>{link.__prefetchObserved||(link.__prefetchObserved=!0,observer.observe(link))})}export{setupPrefetchObserver};
1
+ import{routes as s}from"../_routes.js";import{prefetchRouteComponent as p}from"../cache.js";function h(){const o=new IntersectionObserver(e=>{e.forEach(n=>{if(!n.isIntersecting)return;const t=n.target;if(!t.hasAttribute("data-prefetch"))return;const c=new URL(t.href,location.origin),r=s.find(f=>f.path===c.pathname);r?.component&&(p(r.path,r.component),o.unobserve(t))})},{rootMargin:"200px"});document.querySelectorAll("a[data-prefetch]").forEach(e=>{e.__prefetchObserved||(e.__prefetchObserved=!0,o.observe(e))})}export{h as setupPrefetchObserver};
@@ -1 +1 @@
1
- import{addMetadata}from"./metadata.js";async function renderPage({route,layoutRenderer}){if(!route?.component)return;const mod=await route.component();if(!mod.hydrateClientComponent)return;const root=document.getElementById("app-root")||document.body,marker=document.createElement("template"),pageNode=mod.hydrateClientComponent(marker);await hydrateComponents(pageNode);const{node,layoutId,metadata}=await layoutRenderer.generate({routeLayouts:route.layouts,pageNode,metadata:mod.metadata});layoutId?layoutRenderer.patch(layoutId,node):(root.innerHTML="",root.appendChild(node)),metadata&&addMetadata(metadata)}export{renderPage};
1
+ import{addMetadata as p}from"./metadata.js";async function s({route:t,layoutRenderer:a}){if(!t?.component)return;const e=await t.component();if(!e.hydrateClientComponent)return;const n=document.getElementById("app-root")||document.body,c=document.createElement("template"),o=e.hydrateClientComponent(c);await hydrateComponents(o);const{node:d,layoutId:m,metadata:r}=await a.generate({routeLayouts:t.layouts,pageNode:o,metadata:e.metadata});m?a.patch(m,d):(n.innerHTML="",n.appendChild(d)),r&&p(r)}export{s as renderPage};
@@ -1 +1 @@
1
- async function renderSSRPage(path,signal){const res=await fetch(path,{signal});if(!res.body)throw new Error("Invalid SSR response");const reader=res.body.getReader(),decoder=new TextDecoder,parser=new DOMParser;let buffer="";const main=document.querySelector("main");for(;;){const{done,value}=await reader.read();if(done)break;buffer+=decoder.decode(value,{stream:!0}),buffer=processSSRMain(buffer,parser,main),buffer=processSSRTemplates(buffer,parser),buffer=processSSRScripts(buffer,parser),updateSSRMetadata(buffer,parser),hydrateComponents()}}function processSSRMain(buffer,parser,mainEl){const match=buffer.match(/<main[\s\S]*?<\/main>/i);if(!match)return buffer;const newMain=parser.parseFromString(match[0],"text/html").querySelector("main");return newMain&&mainEl&&(mainEl.innerHTML=newMain.innerHTML),buffer.slice(match.index+match[0].length)}function processSSRTemplates(buffer,parser){const regex=/<template\b[^>]*>[\s\S]*?<\/template>/gi;let match,lastIndex=-1;for(;(match=regex.exec(buffer))!==null;){const template=parser.parseFromString(match[0],"text/html").querySelector("template");template?.id&&document.body.appendChild(template),lastIndex=match.index+match[0].length}return lastIndex!==-1?buffer.slice(lastIndex):buffer}function processSSRScripts(buffer,parser){const regex=/<script[\s\S]*?<\/script>/gi;let match;for(;match=regex.exec(buffer);){const script=parser.parseFromString(match[0],"text/html").querySelector("script");if(script)if(script.src){if(![...document.scripts].some(s=>s.src===script.src)){const s=document.createElement("script");s.src=script.src,s.async=!0,document.head.appendChild(s)}}else try{new Function(script.textContent)()}catch(e){console.error("Error executing inline SSR script:",e)}}const end=buffer.lastIndexOf("<\/script>");return end!==-1?buffer.slice(end+9):buffer}function updateSSRMetadata(buffer,parser){const doc=parser.parseFromString(buffer,"text/html"),title=doc.querySelector("title");title&&(document.title=title.textContent);const desc=doc.querySelector('meta[name="description"]');if(desc){let meta=document.querySelector('meta[name="description"]');meta||(meta=document.createElement("meta"),meta.name="description",document.head.appendChild(meta)),meta.content=desc.content}}export{renderSSRPage};
1
+ async function u(n,s){const r=await fetch(n,{signal:s});if(!r.body)throw new Error("Invalid SSR response");const t=r.body.getReader(),o=new TextDecoder,e=new DOMParser;let c="";const i=document.querySelector("main");for(;;){const{done:a,value:d}=await t.read();if(a)break;c+=o.decode(d,{stream:!0}),c=l(c,e,i),c=m(c,e),c=p(c,e),S(c,e),hydrateComponents()}}function l(n,s,r){const t=n.match(/<main[\s\S]*?<\/main>/i);if(!t)return n;const e=s.parseFromString(t[0],"text/html").querySelector("main");return e&&r&&(r.innerHTML=e.innerHTML),n.slice(t.index+t[0].length)}function m(n,s){const r=/<template\b[^>]*>[\s\S]*?<\/template>/gi;let t,o=-1;for(;(t=r.exec(n))!==null;){const c=s.parseFromString(t[0],"text/html").querySelector("template");c?.id&&document.body.appendChild(c),o=t.index+t[0].length}return o!==-1?n.slice(o):n}function p(n,s){const r=/<script[\s\S]*?<\/script>/gi;let t;for(;t=r.exec(n);){const e=s.parseFromString(t[0],"text/html").querySelector("script");if(e)if(e.src){if(![...document.scripts].some(i=>i.src===e.src)){const i=document.createElement("script");i.src=e.src,i.async=!0,document.head.appendChild(i)}}else try{new Function(e.textContent)()}catch(c){console.error("Error executing inline SSR script:",c)}}const o=n.lastIndexOf("<\/script>");return o!==-1?n.slice(o+9):n}function S(n,s){const r=s.parseFromString(n,"text/html"),t=r.querySelector("title");t&&(document.title=t.textContent);const o=r.querySelector('meta[name="description"]');if(o){let e=document.querySelector('meta[name="description"]');e||(e=document.createElement("meta"),e.name="description",document.head.appendChild(e)),e.content=o.content}}export{u as renderSSRPage};
@@ -1 +1 @@
1
- import{routes}from"../_routes.js";function pathToRegex(routePath){const keys=[];return{regex:new RegExp("^"+routePath.replace(/:([^/]+)/g,(_,key)=>(keys.push(key),"([^/]+)"))+"$"),keys}}function findRouteWithParams(path){for(const r of routes)if(typeof r.path=="string"){const{regex,keys}=pathToRegex(r.path),match=path.match(regex);if(match){const params={};return keys.forEach((k,i)=>params[k]=match[i+1]),{route:r,params}}}else if(r.path instanceof RegExp&&r.path.test(path))return{route:r,params:{}};return{route:null,params:{}}}export{findRouteWithParams};
1
+ import{routes as u}from"../_routes.js";function c(e){const t=[];return{regex:new RegExp("^"+e.replace(/:([^/]+)/g,(n,r)=>(t.push(r),"([^/]+)"))+"$"),keys:t}}function i(e){for(const t of u)if(typeof t.path=="string"){const{regex:o,keys:n}=c(t.path),r=e.match(o);if(r){const s={};return n.forEach((a,p)=>s[a]=r[p+1]),{route:t,params:s}}}else if(t.path instanceof RegExp&&t.path.test(e))return{route:t,params:{}};return{route:null,params:{}}}export{i as findRouteWithParams};
@@ -1 +1 @@
1
- function parseRawQuery(search){const out={},qs=new URLSearchParams(search);for(const[k,v]of qs.entries())out[k]=v;return out}function buildQueryString(raw){const qs=new URLSearchParams;for(const k in raw)raw[k]!=null&&qs.set(k,String(raw[k]));return qs.toString()}function useQueryParams(options={}){const{schema={},replace=!1,listen=!0}=options,defaults={};for(const key in schema)defaults[key]=schema[key](void 0);let raw=parseRawQuery(window.location.search);function parseWithSchema(raw2){const parsed={};for(const key in schema){const parser=schema[key];parsed[key]=parser(raw2[key])}for(const key in raw2)key in parsed||(parsed[key]=raw2[key]);return parsed}function serializeWithSchema(next){const out={};for(const key in next){const value=next[key];Array.isArray(value)?out[key]=value.join(","):value!=null&&(out[key]=String(value))}return out}function sync(nextRaw){raw=nextRaw;const qs=buildQueryString(raw),url=window.location.pathname+(qs?`?${qs}`:"")+window.location.hash;history[replace?"replaceState":"pushState"](null,"",url)}function set(next){const serialized=serializeWithSchema(next);sync({...raw,...serialized})}function remove(...keys){const next={...raw};keys.forEach(k=>delete next[k]),sync(next)}function reset(){sync({})}return listen&&window.addEventListener("popstate",()=>{raw=parseRawQuery(window.location.search)}),{get params(){return parseWithSchema(raw)},get raw(){return{...raw}},set,remove,reset}}export{useQueryParams};
1
+ function l(r){const o={},s=new URLSearchParams(r);for(const[a,u]of s.entries())o[a]=u;return o}function S(r){const o=new URLSearchParams;for(const s in r)r[s]!=null&&o.set(s,String(r[s]));return o.toString()}function m(r={}){const{schema:o={},replace:s=!1,listen:a=!0}=r,u={};for(const t in o)u[t]=o[t](void 0);let i=l(window.location.search);function h(t){const n={};for(const e in o){const c=o[e];n[e]=c(t[e])}for(const e in t)e in n||(n[e]=t[e]);return n}function d(t){const n={};for(const e in t){const c=t[e];Array.isArray(c)?n[e]=c.join(","):c!=null&&(n[e]=String(c))}return n}function f(t){i=t;const n=S(i),e=window.location.pathname+(n?`?${n}`:"")+window.location.hash;history[s?"replaceState":"pushState"](null,"",e)}function p(t){const n=d(t);f({...i,...n})}function w(...t){const n={...i};t.forEach(e=>delete n[e]),f(n)}function y(){f({})}return a&&window.addEventListener("popstate",()=>{i=l(window.location.search)}),{get params(){return h(i)},get raw(){return{...i}},set:p,remove:w,reset:y}}export{m as useQueryParams};
@@ -1 +1 @@
1
- import{reactive}from"../reactive.js";import{routes}from"../_routes.js";const routeParams=reactive({});function extractParams(pathname){const pathParts=pathname.split("/").filter(Boolean);for(const route of routes){const routeParts=route.path.split("/").filter(Boolean);if(routeParts.length!==pathParts.length)continue;const params={};let match=!0;for(let i=0;i<routeParts.length;i++){const routePart=routeParts[i],pathPart=pathParts[i];if(routePart.startsWith(":"))params[routePart.slice(1)]=pathPart;else if(routePart!==pathPart){match=!1;break}}if(match)return params}return{}}function updateRouteParams(path=window.location.pathname){const newParams=extractParams(path);Object.keys(routeParams).forEach(k=>delete routeParams[k]),Object.assign(routeParams,newParams)}function useRouteParams(){return routeParams}export{updateRouteParams,useRouteParams};
1
+ import{reactive as f}from"../reactive.js";import{routes as l}from"../_routes.js";const r=f({});function m(o){const t=o.split("/").filter(Boolean);for(const a of l){const n=a.path.split("/").filter(Boolean);if(n.length!==t.length)continue;const i={};let c=!0;for(let e=0;e<n.length;e++){const s=n[e],u=t[e];if(s.startsWith(":"))i[s.slice(1)]=u;else if(s!==u){c=!1;break}}if(c)return i}return{}}function P(o=window.location.pathname){const t=m(o);Object.keys(r).forEach(a=>delete r[a]),Object.assign(r,t)}function g(){return r}export{P as updateRouteParams,g as useRouteParams};
@@ -1 +1 @@
1
- import{useRouteParams,useQueryParams,navigate}from"./navigation/index.js";export{navigate,useQueryParams,useRouteParams};
1
+ import{useRouteParams as r,useQueryParams as s,navigate as u}from"./navigation/index.js";export{u as navigate,s as useQueryParams,r as useRouteParams};
@@ -1 +1 @@
1
- let activeEffect=null;function adaptPrimitiveValue(input){return input===null||typeof input!="object"?{value:input,__isPrimitive:!0}:input}function reactive(obj){obj=adaptPrimitiveValue(obj);const depsMap=new Map;return new Proxy(obj,{get(target,prop){if(target.__isPrimitive&&prop===Symbol.toPrimitive){if(activeEffect){depsMap.has("value")||depsMap.set("value",new Set);const depSet=depsMap.get("value");depSet.add(activeEffect),activeEffect.deps||(activeEffect.deps=[]),activeEffect.deps.push(depSet)}return()=>target.value}const key=target.__isPrimitive?"value":prop;if(activeEffect){depsMap.has(key)||depsMap.set(key,new Set);const depSet=depsMap.get(key);depSet.add(activeEffect),activeEffect.deps||(activeEffect.deps=[]),activeEffect.deps.push(depSet)}return target[key]},set(target,prop,value){const key=target.__isPrimitive?"value":prop;return target[key]=value,depsMap.has(key)&&depsMap.get(key).forEach(effect2=>effect2()),!0}})}function effect(fn){const wrapped=()=>{activeEffect=wrapped,fn(),activeEffect=null};return wrapped(),()=>{wrapped.deps&&wrapped.deps.forEach(depSet=>depSet.delete(wrapped))}}function computed(getter){let value;return effect(()=>{value=getter()}),new Proxy({},{get(_,prop){if(prop===Symbol.toPrimitive)return()=>value;if(prop==="value")return value;const v=value?.[prop];return typeof v=="function"?v.bind(value):v}})}function watch(source,callback,options={}){let oldValue,cleanupFn;const onCleanup=fn=>{cleanupFn=fn};effect(()=>{const newValue=source();if(oldValue===void 0&&!options.immediate){oldValue=newValue;return}Object.is(newValue,oldValue)||(cleanupFn&&(cleanupFn(),cleanupFn=null),callback(newValue,oldValue,onCleanup),oldValue=newValue)})}export{computed,effect,reactive,watch};
1
+ let r=null;function c(n){return n===null||typeof n!="object"?{value:n,__isPrimitive:!0}:n}function a(n){n=c(n);const e=new Map;return new Proxy(n,{get(t,i){if(t.__isPrimitive&&i===Symbol.toPrimitive){if(r){e.has("value")||e.set("value",new Set);const u=e.get("value");u.add(r),r.deps||(r.deps=[]),r.deps.push(u)}return()=>t.value}const s=t.__isPrimitive?"value":i;if(r){e.has(s)||e.set(s,new Set);const u=e.get(s);u.add(r),r.deps||(r.deps=[]),r.deps.push(u)}return t[s]},set(t,i,s){const u=t.__isPrimitive?"value":i;return t[u]=s,e.has(u)&&e.get(u).forEach(o=>o()),!0}})}function l(n){const e=()=>{r=e,n(),r=null};return e(),()=>{e.deps&&e.deps.forEach(f=>f.delete(e))}}function d(n){let e;return l(()=>{e=n()}),new Proxy({},{get(f,t){if(t===Symbol.toPrimitive)return()=>e;if(t==="value")return e;const i=e?.[t];return typeof i=="function"?i.bind(e):i}})}function p(n,e,f={}){let t,i;const s=o=>{i=o};l(()=>{const o=n();if(t===void 0&&!f.immediate){t=o;return}Object.is(o,t)||(i&&(i(),i=null),e(o,t,s),t=o)})}export{d as computed,l as effect,a as reactive,p as watch};
@@ -1 +1 @@
1
- import"dotenv/config";import{build}from"./utils/component-processor.js";import{initializeDirectories}from"./utils/files.js";console.log("\u{1F528} Starting prebuild..."),console.log("\u{1F4C1} Creating directories..."),await initializeDirectories(),console.log("\u2699\uFE0F Generating components and routes..."),await build(),console.log("\u2705 Prebuild complete!");
1
+ import"dotenv/config";import{build}from"./utils/component-processor.js";import{initializeDirectories}from"./utils/files.js";console.log("\u{1F528} Starting prebuild..."),console.log("\u{1F4C1} Creating directories..."),await initializeDirectories(),console.log("\u2699\uFE0F Generating components and routes..."),await build(),console.log("\u2705 Prebuild complete!"),process.exit(0);
@@ -65,4 +65,4 @@ export function hydrateClientComponent(marker, incomingProps = {}) {
65
65
  ssr: false,
66
66
  requiresAuth: false,
67
67
  },
68
- }`)}return data}async function generateRoutes(){const pageFiles=await getPageFiles(),serverRoutes=[],clientRoutes=[],routeFilesPromises=pageFiles.map(pageFile=>getRouteFileData(pageFile)),routeFiles=await Promise.all(routeFilesPromises);for(const routeFile of routeFiles){const{serverRoutes:serverRoutesFile,clientRoutes:clientRoutesFile}=routeFile;serverRoutesFile?.length&&serverRoutes.push(...serverRoutesFile),clientRoutesFile?.length&&clientRoutes.push(...clientRoutesFile)}return await Promise.all([saveClientRoutesFile(clientRoutes),saveServerRoutesFile(serverRoutes)]),{serverRoutes}}async function buildUserFile(filePath){const rel=path.relative(SRC_DIR,filePath).replace(/\\/g,"/"),outfile=path.join(USER_GENERATED_DIR,rel);await esbuild.build({entryPoints:[filePath],bundle:!0,format:"esm",outfile,plugins:[createVexAliasPlugin()],minify:process.env.NODE_ENV==="production"})}async function buildUserFiles(){const collect=async dir=>{let entries;try{entries=await fs.readdir(dir,{withFileTypes:!0})}catch{return}await Promise.all(entries.map(async entry=>{if(WATCH_IGNORE.has(entry.name))return;const full=path.join(dir,entry.name);if(entry.isDirectory())await collect(full);else if(entry.name.endsWith(".js"))try{await buildUserFile(full)}catch(e){console.error(`[build] Failed to bundle user file ${full}:`,e.message)}}))};await collect(SRC_DIR)}async function build(){return await generateComponentsAndFillCache(),await buildUserFiles(),generateRoutes()}export{build,generateClientComponentModule,generateComponentsAndFillCache,generateRoutes,processClientComponent,processHtmlFile,renderHtmlFile,renderPageWithLayout};
68
+ }`)}return data}async function generateRoutes(){const pageFiles=await getPageFiles(),serverRoutes=[],clientRoutes=[],routeFilesPromises=pageFiles.map(pageFile=>getRouteFileData(pageFile)),routeFiles=await Promise.all(routeFilesPromises);for(const routeFile of routeFiles){const{serverRoutes:serverRoutesFile,clientRoutes:clientRoutesFile}=routeFile;serverRoutesFile?.length&&serverRoutes.push(...serverRoutesFile),clientRoutesFile?.length&&clientRoutes.push(...clientRoutesFile)}return await Promise.all([saveClientRoutesFile(clientRoutes),saveServerRoutesFile(serverRoutes)]),{serverRoutes}}async function buildUserFile(filePath){const rel=path.relative(SRC_DIR,filePath).replace(/\\/g,"/"),outfile=path.join(USER_GENERATED_DIR,rel);await esbuild.build({entryPoints:[filePath],bundle:!0,format:"esm",outfile,plugins:[createVexAliasPlugin()],minify:process.env.NODE_ENV==="production"})}async function buildUserFiles(){const collect=async dir=>{let entries;try{entries=await fs.readdir(dir,{withFileTypes:!0})}catch{return}await Promise.all(entries.map(async entry=>{if(WATCH_IGNORE.has(entry.name))return;const full=path.join(dir,entry.name);if(entry.isDirectory())await collect(full);else if(entry.name.endsWith(".js")){const rel=path.relative(SRC_DIR,full).replace(/\\/g,"/");if(WATCH_IGNORE_FILES.some(pattern=>path.matchesGlob(rel,pattern)))return;try{await buildUserFile(full)}catch(e){console.error(`[build] Failed to bundle user file ${full}:`,e.message)}}}))};await collect(SRC_DIR)}async function build(){return await generateComponentsAndFillCache(),await buildUserFiles(),generateRoutes()}export{build,generateClientComponentModule,generateComponentsAndFillCache,generateRoutes,processClientComponent,processHtmlFile,renderHtmlFile,renderPageWithLayout};
@@ -1,4 +1,4 @@
1
- import fs from"fs/promises";import{watch,existsSync,statSync,readFileSync}from"fs";import path from"path";import crypto from"crypto";import{fileURLToPath,pathToFileURL}from"url";import esbuild from"esbuild";const __filename=fileURLToPath(import.meta.url),__dirname=path.dirname(__filename),FRAMEWORK_DIR=path.resolve(__dirname,"..",".."),PROJECT_ROOT=process.cwd(),ROOT_DIR=PROJECT_ROOT;let _vexConfig={};try{_vexConfig=JSON.parse(readFileSync(path.join(PROJECT_ROOT,"vex.config.json"),"utf-8"))}catch{}const SRC_DIR=path.resolve(PROJECT_ROOT,_vexConfig.srcDir||"."),WATCH_IGNORE=new Set(["dist","build","out",".output",".vexjs","public","node_modules",".git",".svn","coverage",".nyc_output",".next",".nuxt",".svelte-kit",".astro","tmp","temp",".cache",".claude",...(_vexConfig.watchIgnore||[]).filter(p=>!/[\/\*\.]/.test(p))]),WATCH_IGNORE_FILES=(_vexConfig.watchIgnore||[]).filter(p=>/[\/\*\.]/.test(p)),PAGES_DIR=path.resolve(SRC_DIR,"pages"),SERVER_APP_DIR=path.join(FRAMEWORK_DIR,"server"),CLIENT_DIR=path.join(FRAMEWORK_DIR,"client"),CLIENT_SERVICES_DIR=path.join(CLIENT_DIR,"services"),GENERATED_DIR=path.join(PROJECT_ROOT,".vexjs"),CACHE_DIR=path.join(GENERATED_DIR,"_cache"),CLIENT_COMPONENTS_DIR=path.join(GENERATED_DIR,"_components"),USER_GENERATED_DIR=path.join(GENERATED_DIR,"user"),ROOT_HTML_USER=path.join(PROJECT_ROOT,"root.html"),ROOT_HTML_DEFAULT=path.join(FRAMEWORK_DIR,"server","root.html"),ROOT_HTML_DIR=ROOT_HTML_USER;async function minifyServicesDir(src,dest){const jsFiles=[],otherFiles=[],collect=async(srcDir,destDir)=>{const entries=await fs.readdir(srcDir,{withFileTypes:!0});await Promise.all(entries.map(async entry=>{const srcPath=path.join(srcDir,entry.name),destPath=path.join(destDir,entry.name);entry.isDirectory()?(await fs.mkdir(destPath,{recursive:!0}),await collect(srcPath,destPath)):entry.name.endsWith(".js")?jsFiles.push({in:srcPath,out:destPath}):otherFiles.push({src:srcPath,dest:destPath})}))};await collect(src,dest),await Promise.all([esbuild.build({entryPoints:jsFiles.map(f=>f.in),bundle:!1,format:"esm",platform:"browser",minify:!0,legalComments:"none",outdir:dest,outbase:src,logLevel:"silent"}),...otherFiles.map(f=>fs.copyFile(f.src,f.dest))])}async function initializeDirectories(){try{const servicesDir=path.join(GENERATED_DIR,"services");return await Promise.all([fs.mkdir(GENERATED_DIR,{recursive:!0}),fs.mkdir(CACHE_DIR,{recursive:!0}),fs.mkdir(CLIENT_COMPONENTS_DIR,{recursive:!0}),fs.mkdir(USER_GENERATED_DIR,{recursive:!0}),fs.mkdir(servicesDir,{recursive:!0})]),process.env.NODE_ENV==="production"?await minifyServicesDir(CLIENT_SERVICES_DIR,servicesDir):await fs.cp(CLIENT_SERVICES_DIR,servicesDir,{recursive:!0}),!0}catch(err){console.error("Failed to create cache directory:",err)}}function adjustClientModulePath(modulePath,importStatement,componentFilePath=null){if(modulePath.startsWith("/_vexjs/"))return{path:modulePath,importStatement};const isRelative=(modulePath.startsWith("./")||modulePath.startsWith("../"))&&componentFilePath,isAtAlias=modulePath.startsWith("@/")||modulePath==="@";if(isRelative||isAtAlias){let resolvedPath;if(isAtAlias)resolvedPath=path.resolve(SRC_DIR,modulePath.replace(/^@\//,"").replace(/^@$/,""));else{const componentDir=path.dirname(componentFilePath);resolvedPath=path.resolve(componentDir,modulePath)}path.extname(resolvedPath)||(existsSync(resolvedPath+".js")?resolvedPath+=".js":existsSync(path.join(resolvedPath,"index.js"))?resolvedPath=path.join(resolvedPath,"index.js"):resolvedPath+=".js");const adjustedPath2=`/_vexjs/user/${path.relative(SRC_DIR,resolvedPath).replace(/\\/g,"/")}`,adjustedImportStatement2=importStatement.replace(modulePath,adjustedPath2);return{path:adjustedPath2,importStatement:adjustedImportStatement2}}let relative=modulePath.replace(/^vex\//,""),adjustedPath=`/_vexjs/services/${relative}`;const fsPath=path.join(CLIENT_SERVICES_DIR,relative);existsSync(fsPath)&&statSync(fsPath).isDirectory()?adjustedPath+="/index.js":path.extname(adjustedPath)||(adjustedPath+=".js");const adjustedImportStatement=importStatement.replace(modulePath,adjustedPath);return{path:adjustedPath,importStatement:adjustedImportStatement}}function getRelativePath(from,to){return path.relative(from,to)}function getDirectoryName(filePath){return path.dirname(filePath)}const layoutPathsCache=new Map;process.env.NODE_ENV!=="production"&&watch(PAGES_DIR,{recursive:!0},(_,filename)=>{(filename==="layout.vex"||filename?.endsWith(`${path.sep}layout.vex`))&&layoutPathsCache.clear()});async function _getLayoutPaths(pagePath){const layouts=[],relativePath=getRelativePath(PAGES_DIR,pagePath),pathSegments=getDirectoryName(relativePath).split(path.sep),baseLayout=path.join(PAGES_DIR,"layout.vex");await fileExists(baseLayout)&&layouts.push(baseLayout);let currentPath=PAGES_DIR;for(const segment of pathSegments){if(segment==="."||segment==="..")continue;currentPath=path.join(currentPath,segment);const layoutPath=path.join(currentPath,"layout.vex");await fileExists(layoutPath)&&layouts.push(layoutPath)}return layouts}async function getLayoutPaths(pagePath){if(layoutPathsCache.has(pagePath))return layoutPathsCache.get(pagePath);const result=await _getLayoutPaths(pagePath);return layoutPathsCache.set(pagePath,result),result}function formatFileContent(content){return content.trim()}async function writeFile(filePath,content){const formattedContent=formatFileContent(content);return fs.writeFile(filePath,formattedContent,"utf-8")}function readFile(filePath){return fs.readFile(filePath,"utf-8")}async function fileExists(filePath){try{return await fs.access(filePath),!0}catch{return!1}}function getAutogeneratedComponentName(componentPath){return`_${componentPath.replace(ROOT_DIR+path.sep,"").split(path.sep).filter(Boolean).join("_").replaceAll(".vex","").replaceAll(path.sep,"_").replaceAll("-","_").replaceAll(":","")}`}function generateComponentId(componentPath,options={}){const{length=8,prefix=!0}=options,relativePath=componentPath.replace(ROOT_DIR+path.sep,""),hash=crypto.createHash("sha256").update(relativePath).digest("hex").slice(0,length),baseName=getAutogeneratedComponentName(componentPath).replace(/^_/,"");return prefix?`_${baseName}_${hash}`:hash}const getPagePath=pageName=>path.resolve(PAGES_DIR,pageName,"page.vex"),getRootTemplate=async()=>{try{return await fs.access(ROOT_HTML_USER),await fs.readFile(ROOT_HTML_USER,"utf-8")}catch{return await fs.readFile(ROOT_HTML_DEFAULT,"utf-8")}};async function readDirectoryRecursive(dir){const entries=await fs.readdir(dir,{withFileTypes:!0}),files=[];for(const entry of entries){const fullpath=path.join(dir,entry.name);entry.isDirectory()?files.push(...await readDirectoryRecursive(fullpath)):files.push({path:fullpath.replace(ROOT_DIR,""),fullpath,name:entry.name})}return files}const getComponentNameFromPath=(fullFilepath,fileName)=>{const filePath=fullFilepath.replace(ROOT_DIR+path.sep,"");if(filePath.startsWith(path.join("pages",path.sep))){const segments=filePath.split(path.sep);return segments.length===2?segments[0].replace(".vex",""):segments[segments.length-2].replace(".vex","")}return fileName.replace(".vex","")};async function getComponentHtmlDisk({componentPath}){const filePath=path.join(CACHE_DIR,generateComponentId(componentPath)+".html"),metaPath=filePath+".meta.json",[existsHtml,existsMeta]=await Promise.all([fileExists(filePath),fileExists(metaPath)]);if(!existsMeta||!existsHtml)return{html:null,meta:null};const[html,meta]=await Promise.all([fs.readFile(filePath,"utf-8"),fs.readFile(metaPath,"utf-8")]).then(([htmlContent,metaContent])=>[htmlContent,JSON.parse(metaContent)]);return{html,meta}}async function saveComponentHtmlDisk({componentPath,html}){const filePath=path.join(CACHE_DIR,generateComponentId(componentPath)+".html"),metaPath=filePath+".meta.json",meta={generatedAt:Date.now(),isStale:!1,path:componentPath};await Promise.all([writeFile(filePath,html,"utf-8"),writeFile(metaPath,JSON.stringify(meta),"utf-8")])}async function markComponentHtmlStale({componentPath}){const metaPath=path.join(CACHE_DIR,generateComponentId(componentPath)+".html")+".meta.json";if(!await fileExists(metaPath))return;const meta=JSON.parse(await fs.readFile(metaPath,"utf-8"));meta.isStale=!0,await writeFile(metaPath,JSON.stringify(meta),"utf-8")}async function saveServerRoutesFile(serverRoutes){await writeFile(path.join(GENERATED_DIR,"_routes.js"),`// Auto-generated by prebuild \u2014 do not edit manually.
1
+ import fs from"fs/promises";import{watch,existsSync,statSync,readFileSync}from"fs";import path from"path";import crypto from"crypto";import{fileURLToPath,pathToFileURL}from"url";import esbuild from"esbuild";const __filename=fileURLToPath(import.meta.url),__dirname=path.dirname(__filename),FRAMEWORK_DIR=path.resolve(__dirname,"..",".."),PROJECT_ROOT=process.cwd(),ROOT_DIR=PROJECT_ROOT;let _vexConfig={};try{_vexConfig=JSON.parse(readFileSync(path.join(PROJECT_ROOT,"vex.config.json"),"utf-8"))}catch{}const SRC_DIR=path.resolve(PROJECT_ROOT,_vexConfig.srcDir||"."),WATCH_IGNORE=new Set(["dist","build","out",".output",".vexjs","public","node_modules",".git",".svn","coverage",".nyc_output",".next",".nuxt",".svelte-kit",".astro","tmp","temp",".cache",".claude",...(_vexConfig.watchIgnore||[]).filter(p=>!/[\/\*\.]/.test(p))]),WATCH_IGNORE_FILES=["server.js",...(_vexConfig.watchIgnore||[]).filter(p=>/[\/\*\.]/.test(p))],PAGES_DIR=path.resolve(SRC_DIR,"pages"),SERVER_APP_DIR=path.join(FRAMEWORK_DIR,"server"),CLIENT_DIR=path.join(FRAMEWORK_DIR,"client"),CLIENT_SERVICES_DIR=path.join(CLIENT_DIR,"services"),GENERATED_DIR=path.join(PROJECT_ROOT,".vexjs"),CACHE_DIR=path.join(GENERATED_DIR,"_cache"),CLIENT_COMPONENTS_DIR=path.join(GENERATED_DIR,"_components"),USER_GENERATED_DIR=path.join(GENERATED_DIR,"user"),ROOT_HTML_USER=path.join(PROJECT_ROOT,"root.html"),ROOT_HTML_DEFAULT=path.join(FRAMEWORK_DIR,"server","root.html"),ROOT_HTML_DIR=ROOT_HTML_USER;async function minifyServicesDir(src,dest){const jsFiles=[],otherFiles=[],collect=async(srcDir,destDir)=>{const entries=await fs.readdir(srcDir,{withFileTypes:!0});await Promise.all(entries.map(async entry=>{const srcPath=path.join(srcDir,entry.name),destPath=path.join(destDir,entry.name);entry.isDirectory()?(await fs.mkdir(destPath,{recursive:!0}),await collect(srcPath,destPath)):entry.name.endsWith(".js")?jsFiles.push({in:srcPath,out:destPath}):otherFiles.push({src:srcPath,dest:destPath})}))};await collect(src,dest),await Promise.all([esbuild.build({entryPoints:jsFiles.map(f=>f.in),bundle:!1,format:"esm",platform:"browser",minify:!0,legalComments:"none",outdir:dest,outbase:src,logLevel:"silent"}),...otherFiles.map(f=>fs.copyFile(f.src,f.dest))])}async function initializeDirectories(){try{const servicesDir=path.join(GENERATED_DIR,"services");return await Promise.all([fs.mkdir(GENERATED_DIR,{recursive:!0}),fs.mkdir(CACHE_DIR,{recursive:!0}),fs.mkdir(CLIENT_COMPONENTS_DIR,{recursive:!0}),fs.mkdir(USER_GENERATED_DIR,{recursive:!0}),fs.mkdir(servicesDir,{recursive:!0})]),process.env.NODE_ENV==="production"?await minifyServicesDir(CLIENT_SERVICES_DIR,servicesDir):await fs.cp(CLIENT_SERVICES_DIR,servicesDir,{recursive:!0}),!0}catch(err){console.error("Failed to create cache directory:",err)}}function adjustClientModulePath(modulePath,importStatement,componentFilePath=null){if(modulePath.startsWith("/_vexjs/"))return{path:modulePath,importStatement};const isRelative=(modulePath.startsWith("./")||modulePath.startsWith("../"))&&componentFilePath,isAtAlias=modulePath.startsWith("@/")||modulePath==="@";if(isRelative||isAtAlias){let resolvedPath;if(isAtAlias)resolvedPath=path.resolve(SRC_DIR,modulePath.replace(/^@\//,"").replace(/^@$/,""));else{const componentDir=path.dirname(componentFilePath);resolvedPath=path.resolve(componentDir,modulePath)}path.extname(resolvedPath)||(existsSync(resolvedPath+".js")?resolvedPath+=".js":existsSync(path.join(resolvedPath,"index.js"))?resolvedPath=path.join(resolvedPath,"index.js"):resolvedPath+=".js");const adjustedPath2=`/_vexjs/user/${path.relative(SRC_DIR,resolvedPath).replace(/\\/g,"/")}`,adjustedImportStatement2=importStatement.replace(modulePath,adjustedPath2);return{path:adjustedPath2,importStatement:adjustedImportStatement2}}let relative=modulePath.replace(/^vex\//,""),adjustedPath=`/_vexjs/services/${relative}`;const fsPath=path.join(CLIENT_SERVICES_DIR,relative);existsSync(fsPath)&&statSync(fsPath).isDirectory()?adjustedPath+="/index.js":path.extname(adjustedPath)||(adjustedPath+=".js");const adjustedImportStatement=importStatement.replace(modulePath,adjustedPath);return{path:adjustedPath,importStatement:adjustedImportStatement}}function getRelativePath(from,to){return path.relative(from,to)}function getDirectoryName(filePath){return path.dirname(filePath)}const layoutPathsCache=new Map;process.env.NODE_ENV!=="production"&&watch(PAGES_DIR,{recursive:!0},(_,filename)=>{(filename==="layout.vex"||filename?.endsWith(`${path.sep}layout.vex`))&&layoutPathsCache.clear()});async function _getLayoutPaths(pagePath){const layouts=[],relativePath=getRelativePath(PAGES_DIR,pagePath),pathSegments=getDirectoryName(relativePath).split(path.sep),baseLayout=path.join(PAGES_DIR,"layout.vex");await fileExists(baseLayout)&&layouts.push(baseLayout);let currentPath=PAGES_DIR;for(const segment of pathSegments){if(segment==="."||segment==="..")continue;currentPath=path.join(currentPath,segment);const layoutPath=path.join(currentPath,"layout.vex");await fileExists(layoutPath)&&layouts.push(layoutPath)}return layouts}async function getLayoutPaths(pagePath){if(layoutPathsCache.has(pagePath))return layoutPathsCache.get(pagePath);const result=await _getLayoutPaths(pagePath);return layoutPathsCache.set(pagePath,result),result}function formatFileContent(content){return content.trim()}async function writeFile(filePath,content){const formattedContent=formatFileContent(content);return fs.writeFile(filePath,formattedContent,"utf-8")}function readFile(filePath){return fs.readFile(filePath,"utf-8")}async function fileExists(filePath){try{return await fs.access(filePath),!0}catch{return!1}}function getAutogeneratedComponentName(componentPath){return`_${componentPath.replace(ROOT_DIR+path.sep,"").split(path.sep).filter(Boolean).join("_").replaceAll(".vex","").replaceAll(path.sep,"_").replaceAll("-","_").replaceAll(":","")}`}function generateComponentId(componentPath,options={}){const{length=8,prefix=!0}=options,relativePath=componentPath.replace(ROOT_DIR+path.sep,""),hash=crypto.createHash("sha256").update(relativePath).digest("hex").slice(0,length),baseName=getAutogeneratedComponentName(componentPath).replace(/^_/,"");return prefix?`_${baseName}_${hash}`:hash}const getPagePath=pageName=>path.resolve(PAGES_DIR,pageName,"page.vex"),getRootTemplate=async()=>{try{return await fs.access(ROOT_HTML_USER),await fs.readFile(ROOT_HTML_USER,"utf-8")}catch{return await fs.readFile(ROOT_HTML_DEFAULT,"utf-8")}};async function readDirectoryRecursive(dir){const entries=await fs.readdir(dir,{withFileTypes:!0}),files=[];for(const entry of entries){const fullpath=path.join(dir,entry.name);entry.isDirectory()?files.push(...await readDirectoryRecursive(fullpath)):files.push({path:fullpath.replace(ROOT_DIR,""),fullpath,name:entry.name})}return files}const getComponentNameFromPath=(fullFilepath,fileName)=>{const filePath=fullFilepath.replace(ROOT_DIR+path.sep,"");if(filePath.startsWith(path.join("pages",path.sep))){const segments=filePath.split(path.sep);return segments.length===2?segments[0].replace(".vex",""):segments[segments.length-2].replace(".vex","")}return fileName.replace(".vex","")};async function getComponentHtmlDisk({componentPath}){const filePath=path.join(CACHE_DIR,generateComponentId(componentPath)+".html"),metaPath=filePath+".meta.json",[existsHtml,existsMeta]=await Promise.all([fileExists(filePath),fileExists(metaPath)]);if(!existsMeta||!existsHtml)return{html:null,meta:null};const[html,meta]=await Promise.all([fs.readFile(filePath,"utf-8"),fs.readFile(metaPath,"utf-8")]).then(([htmlContent,metaContent])=>[htmlContent,JSON.parse(metaContent)]);return{html,meta}}async function saveComponentHtmlDisk({componentPath,html}){const filePath=path.join(CACHE_DIR,generateComponentId(componentPath)+".html"),metaPath=filePath+".meta.json",meta={generatedAt:Date.now(),isStale:!1,path:componentPath};await Promise.all([writeFile(filePath,html,"utf-8"),writeFile(metaPath,JSON.stringify(meta),"utf-8")])}async function markComponentHtmlStale({componentPath}){const metaPath=path.join(CACHE_DIR,generateComponentId(componentPath)+".html")+".meta.json";if(!await fileExists(metaPath))return;const meta=JSON.parse(await fs.readFile(metaPath,"utf-8"));meta.isStale=!0,await writeFile(metaPath,JSON.stringify(meta),"utf-8")}async function saveServerRoutesFile(serverRoutes){await writeFile(path.join(GENERATED_DIR,"_routes.js"),`// Auto-generated by prebuild \u2014 do not edit manually.
2
2
  export const routes = ${JSON.stringify(serverRoutes,null,2)};
3
3
  `)}async function saveClientRoutesFile(clientRoutes){const clientFileCode=`
4
4
  import { loadRouteComponent } from './cache.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cfdez11/vex",
3
- "version": "0.10.3",
3
+ "version": "0.10.5",
4
4
  "description": "A vanilla JavaScript meta-framework with file-based routing, SSR/CSR/SSG/ISR and Vue-like reactivity",
5
5
  "type": "module",
6
6
  "main": "./dist/server/index.js",