@cfdez11/vex 0.10.12 → 0.10.14

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
- function o(i){document.addEventListener("click",r=>{const t=r.target.closest("a");if(!t)return;const e=t.getAttribute("href");if(!e||e.startsWith("#"))return;const n=new URL(e,window.location.origin);n.origin!==window.location.origin||t.dataset.reload!==void 0||t.target==="_blank"||t.rel==="external"||(r.preventDefault(),i(n.pathname+n.hash))})}export{o as setupLinkInterceptor};
1
+ function a(i){document.addEventListener("click",r=>{const t=r.target.closest("a");if(!t)return;const e=t.getAttribute("href");if(!e||e.startsWith("#"))return;const n=new URL(e,window.location.origin);n.origin!==window.location.origin||t.dataset.reload!==void 0||t.target==="_blank"||t.rel==="external"||n.pathname===window.location.pathname&&n.hash||(r.preventDefault(),i(n.pathname+n.hash))})}export{a as setupLinkInterceptor};
@@ -1 +1 @@
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
+ import{findRouteWithParams as l}from"./router.js";import{routes as m}from"../_routes.js";import{updateRouteParams as c}from"./use-route-params.js";import{renderPage as f}from"./render-page.js";import{renderSSRPage as d}from"./render-ssr.js";async function S({path:t,addToHistory:n,controller:i,layoutRenderer:r,onFinish:a}){c(t);const s=t.split("?")[0],{route:u}=l(s),e=u??m.find(o=>o.isNotFound)??null;n&&history.pushState({},"",t);try{if(e?.meta?.ssr){r.reset(),await d(t,i.signal);return}if(e?.meta?.requiresAuth&&!app.Store?.loggedIn){location.href="/account/login";return}if(e?.meta?.guestOnly&&app.Store?.loggedIn){location.href="/account";return}await f({route:e,layoutRenderer:r})}finally{a();const o=t.includes("#")?t.slice(t.indexOf("#")+1):null;o&&document.getElementById(o)?.scrollIntoView()}}export{S as navigateInternal};
@@ -1,4 +1,4 @@
1
- import{watch}from"fs";import fs from"fs/promises";import path from"path";import esbuild from"esbuild";import{compileTemplateToHTML}from"./template.js";import{getOriginalRoutePath,getPageFiles,getRoutePath,saveClientRoutesFile,saveComponentHtmlDisk,saveServerRoutesFile,readFile,getImportData,generateComponentId,adjustClientModulePath,PAGES_DIR,ROOT_HTML_DIR,getLayoutPaths,SRC_DIR,WATCH_IGNORE,WATCH_IGNORE_FILES,CLIENT_COMPONENTS_DIR,USER_GENERATED_DIR}from"./files.js";import{renderComponents}from"./streaming.js";import{getRevalidateSeconds}from"./cache.js";import{withCache}from"./data-cache.js";import{createVexAliasPlugin}from"./esbuild-plugin.js";function redirect(redirectPath,statusCode=302){const err=new Error("REDIRECT");throw err.redirect={path:redirectPath,statusCode},err}const processHtmlFileCache=new Map;let rootTemplate=await readFile(ROOT_HTML_DIR);if(process.env.NODE_ENV!=="production"){const{hmrEmitter}=await import("./hmr.js");watch(SRC_DIR,{recursive:!0},async(_,filename)=>{if(!filename||filename.split(path.sep).some(part=>WATCH_IGNORE.has(part)))return;const normalizedFilename=filename.replace(/\\/g,"/");if(!WATCH_IGNORE_FILES.some(pattern=>path.matchesGlob(normalizedFilename,pattern))){if(filename.endsWith(".vex")){const fullPath=path.join(SRC_DIR,filename);processHtmlFileCache.delete(fullPath),processedComponentsInBuild.delete(fullPath);try{await generateComponentAndFillCache(fullPath)}catch(e){console.error(`[HMR] Re-generation failed for ${filename}:`,e.message)}hmrEmitter.emit("reload",filename)}else if(filename.endsWith(".js")){const fullPath=path.join(SRC_DIR,filename);try{await buildUserFile(fullPath)}catch(e){console.error(`[HMR] Failed to rebuild user file ${filename}:`,e.message)}hmrEmitter.emit("reload",filename)}}}),watch(ROOT_HTML_DIR,async()=>{rootTemplate=await readFile(ROOT_HTML_DIR),hmrEmitter.emit("reload","root.html")})}const DEFAULT_METADATA={title:"Vanilla JS App",description:"Default description"},getScriptImports=async(script,isClientSide=!1,filePath=null)=>{const componentRegistry=new Map,imports={},clientImports={},importRegex=/import\s+(?:([a-zA-Z_$][\w$]*)|\{([^}]*)\})\s+from\s+['"]([^'"]+)['"]/g;let match;for(;(match=importRegex.exec(script))!==null;){const[importStatement,defaultImport,namedImports,modulePath]=match,{path:path2,fileUrl}=await getImportData(modulePath,filePath);if(path2.endsWith(".vex"))defaultImport&&componentRegistry.set(defaultImport,{path:path2,originalPath:modulePath,importStatement});else if(isClientSide)if(defaultImport){const adjustedClientModule=adjustClientModulePath(modulePath,importStatement,filePath);clientImports[defaultImport||namedImports]={fileUrl,originalPath:adjustedClientModule.path,importStatement:adjustedClientModule.importStatement,originalImportStatement:importStatement}}else namedImports.split(",").forEach(name=>{const trimmedName=name.trim(),adjustedClientModule=adjustClientModulePath(modulePath,importStatement,filePath);clientImports[trimmedName]={fileUrl,originalPath:adjustedClientModule.path,importStatement:adjustedClientModule.importStatement,originalImportStatement:importStatement}});else{const module=await import(fileUrl);defaultImport&&(imports[defaultImport]=module.default||module[defaultImport]),namedImports&&namedImports.split(",").forEach(name=>{const trimmedName=name.trim();imports[trimmedName]=module[trimmedName]})}}return{imports,componentRegistry,clientImports}};async function _processHtmlFile(filePath){const content=await readFile(filePath),serverMatch=content.match(/<script server>([\s\S]*?)<\/script>/),clientMatch=content.match(/<script client>([\s\S]*?)<\/script>/),templateMatch=content.match(/<template>([\s\S]*?)<\/template>/),template=templateMatch?templateMatch[1].trim():"",clientCode=clientMatch?clientMatch[1].trim():"";let serverComponents=new Map,clientComponents=new Map,clientImports={},getData=null,getStaticPaths=null,getMetadata=null;if(serverMatch){const scriptContent=serverMatch[1],{componentRegistry,imports}=await getScriptImports(scriptContent);serverComponents=componentRegistry;const cleanedScript=scriptContent.replace(/import\s+(?:(?:[a-zA-Z_$][\w$]*)|\{[^}]*\})\s+from\s+['"][^'"]*['"];?\n?/g,"").replace(/export\s+/g,"").trim();if(cleanedScript){const AsyncFunction=Object.getPrototypeOf(async function(){}).constructor,fn=new AsyncFunction("redirect","withCache",...Object.keys(imports),`
1
+ import{watch}from"fs";import fs from"fs/promises";import path from"path";import esbuild from"esbuild";import{compileTemplateToHTML}from"./template.js";import{getOriginalRoutePath,getPageFiles,getRoutePath,saveClientRoutesFile,saveComponentHtmlDisk,saveServerRoutesFile,readFile,getImportData,generateComponentId,adjustClientModulePath,PAGES_DIR,ROOT_HTML_DIR,getLayoutPaths,SRC_DIR,WATCH_IGNORE,WATCH_IGNORE_FILES,CLIENT_COMPONENTS_DIR,USER_GENERATED_DIR}from"./files.js";import{renderComponents}from"./streaming.js";import{getRevalidateSeconds}from"./cache.js";import{withCache}from"./data-cache.js";import{createVexAliasPlugin}from"./esbuild-plugin.js";function redirect(redirectPath,statusCode=302){const err=new Error("REDIRECT");throw err.redirect={path:redirectPath,statusCode},err}const processHtmlFileCache=new Map;let rootTemplate=await readFile(ROOT_HTML_DIR);if(process.env.NODE_ENV!=="production"){const{hmrEmitter}=await import("./hmr.js");watch(SRC_DIR,{recursive:!0},async(_,filename)=>{if(!filename||filename.split(path.sep).some(part=>WATCH_IGNORE.has(part)))return;const normalizedFilename=filename.replace(/\\/g,"/");if(!WATCH_IGNORE_FILES.some(pattern=>path.matchesGlob(normalizedFilename,pattern))){if(filename.endsWith(".vex")){const fullPath=path.join(SRC_DIR,filename);processHtmlFileCache.delete(fullPath),processedComponentsInBuild.delete(fullPath);try{await generateComponentAndFillCache(fullPath)}catch(e){console.error(`[HMR] Re-generation failed for ${filename}:`,e.message)}hmrEmitter.emit("reload",filename)}else if(filename.endsWith(".js")){const fullPath=path.join(SRC_DIR,filename);try{await buildUserFile(fullPath)}catch(e){console.error(`[HMR] Failed to rebuild user file ${filename}:`,e.message)}hmrEmitter.emit("reload",filename)}}}),watch(ROOT_HTML_DIR,async()=>{rootTemplate=await readFile(ROOT_HTML_DIR),hmrEmitter.emit("reload","root.html")})}const DEFAULT_METADATA={title:"Vanilla JS App",description:"Default description"},getScriptImports=async(script,isClientSide=!1,filePath=null)=>{const componentRegistry=new Map,imports={},clientImports={},importRegex=/import\s+(?:([a-zA-Z_$][\w$]*)|\{([^}]*)\})\s+from\s+['"]([^'"]+)['"]/g;let match;for(;(match=importRegex.exec(script))!==null;){const[importStatement,defaultImport,namedImports,modulePath]=match,{path:path2,fileUrl}=await getImportData(modulePath,filePath);if(path2.endsWith(".vex"))defaultImport&&componentRegistry.set(defaultImport,{path:path2,originalPath:modulePath,importStatement});else if(isClientSide)if(defaultImport){const adjustedClientModule=adjustClientModulePath(modulePath,importStatement,filePath);clientImports[defaultImport||namedImports]={fileUrl,originalPath:adjustedClientModule.path,importStatement:adjustedClientModule.importStatement,originalImportStatement:importStatement}}else namedImports.split(",").forEach(name=>{const trimmedName=name.trim(),adjustedClientModule=adjustClientModulePath(modulePath,importStatement,filePath);clientImports[trimmedName]={fileUrl,originalPath:adjustedClientModule.path,importStatement:adjustedClientModule.importStatement,originalImportStatement:importStatement}});else{const module=await import(fileUrl);defaultImport&&(imports[defaultImport]=module.default||module[defaultImport]),namedImports&&namedImports.split(",").forEach(name=>{const trimmedName=name.trim();imports[trimmedName]=module[trimmedName]})}}return{imports,componentRegistry,clientImports}};async function _processHtmlFile(filePath){const content=await readFile(filePath),serverMatch=content.match(/<script server>([\s\S]*?)<\/script>/),clientMatch=content.match(/<script client>([\s\S]*?)<\/script>/),templateMatch=content.match(/<template>([\s\S]*?)<\/template>/),template=templateMatch?templateMatch[1].trim():"",clientCode=clientMatch?clientMatch[1].trim():"";let serverComponents=new Map,clientComponents=new Map,clientImports={},getData=null,getStaticPaths=null,getMetadata=null;if(serverMatch){const scriptContent=serverMatch[1],{componentRegistry,imports}=await getScriptImports(scriptContent,!1,filePath);serverComponents=componentRegistry;const cleanedScript=scriptContent.replace(/import\s+(?:(?:[a-zA-Z_$][\w$]*)|\{[^}]*\})\s+from\s+['"][^'"]*['"];?\n?/g,"").replace(/export\s+/g,"").trim();if(cleanedScript){const AsyncFunction=Object.getPrototypeOf(async function(){}).constructor,fn=new AsyncFunction("redirect","withCache",...Object.keys(imports),`
2
2
  ${cleanedScript}
3
3
  ${cleanedScript.includes("getData")?"":"const getData = null;"}
4
4
  ${cleanedScript.includes("const metadata = ")?"":"const metadata = null;"}
@@ -1 +1 @@
1
- import{parseDocument,DomUtils}from"htmlparser2";import{render}from"dom-serializer";const fnCache=new Map;function getDataValue(expression,scope){const keys=Object.keys(scope),cacheKey=`${expression}::${keys.join(",")}`;fnCache.has(cacheKey)||fnCache.set(cacheKey,Function(...keys,`return (${expression})`));try{return fnCache.get(cacheKey)(...Object.values(scope))}catch{return""}}function isEmptyTextNode(node){return node.type==="text"&&/^\s*$/.test(node.data)}function parseHTMLToNodes(html){try{const cleanHtml=html.replace(/[\r\n\t]+/g," ").replace(/ +/g," ").trim(),dom=parseDocument(cleanHtml,{xmlMode:!0});return DomUtils.getChildren(dom)}catch(error){return console.error("Error parsing HTML:",error),[]}}function processNode(node,scope,previousRendered=!1){if(node.type==="text")return node.data=node.data.replace(/(?<!\\)\{\{(.+?)\}\}/g,(_,expr)=>getDataValue(expr.trim(),scope)).replace(/\\\{\{/g,"{{"),node;if(node.type==="tag"){const attrs=node.attribs||{};for(const[attrName,attrValue]of Object.entries(attrs))typeof attrValue=="string"&&(attrs[attrName]=attrValue.replace(/(?<!\\)\{\{(.+?)\}\}/g,(_,expr)=>getDataValue(expr.trim(),scope)).replace(/\\\{\{/g,"{{"));if("x-if"in attrs){const show=getDataValue(attrs["x-if"],scope);if(delete attrs["x-if"],!show)return null}if("x-else-if"in attrs){const show=getDataValue(attrs["x-else-if"],scope);if(delete attrs["x-else-if"],previousRendered||!show)return null}if("x-else"in attrs&&(delete attrs["x-else"],previousRendered))return null;if("x-show"in attrs){const show=getDataValue(attrs["x-show"],scope);delete attrs["x-show"],show||(attrs.style=(attrs.style||"")+"display:none;")}if("x-for"in attrs){const exp=attrs["x-for"];delete attrs["x-for"];const match=exp.match(/(.+?)\s+in\s+(.+)/);if(!match)throw new Error("Invalid x-for format: "+exp);const itemName=match[1].trim(),listExpr=match[2].trim(),list=getDataValue(listExpr,scope);if(!Array.isArray(list))return null;const clones=[];for(const item of list){const cloned=structuredClone(node),newScope={...scope,[itemName]:item};clones.push(processNode(cloned,newScope))}return clones}for(const[name,value]of Object.entries({...attrs})){if(name.startsWith(":")){const isSuspenseFallback=name===":fallback"&&node.name==="Suspense",realName=name.slice(1);if(isSuspenseFallback)attrs[realName]=value;else{const val=getDataValue(value,scope);attrs[realName]=val!=null&&typeof val=="object"?JSON.stringify(val):String(val??"")}delete attrs[name]}if(name.startsWith("x-bind:")){const realName=name.slice(7),val=getDataValue(value,scope);attrs[realName]=val!=null&&typeof val=="object"?JSON.stringify(val):String(val??""),delete attrs[name]}}for(const[name]of Object.entries({...attrs}))(name.startsWith("@")||name.startsWith("x-on:"))&&delete attrs[name];if(node.children){const result=[];let isPreviousRendered=!1;for(const child of node.children){if(isEmptyTextNode(child))continue;const processed=processNode(child,scope,isPreviousRendered);Array.isArray(processed)?(result.push(...processed),isPreviousRendered=processed.length>0):processed?(result.push(processed),isPreviousRendered=!0):isPreviousRendered=!1}node.children=result}return node}return node}const parsedTemplateCache=new Map;function compileTemplateToHTML(template,data={}){try{parsedTemplateCache.has(template)||parsedTemplateCache.set(template,parseHTMLToNodes(template));const processed=structuredClone(parsedTemplateCache.get(template)).map(n=>processNode(n,data)).flat().filter(Boolean);return render(processed,{encodeEntities:!1})}catch(error){throw console.error("Error compiling template:",error),error}}export{compileTemplateToHTML};
1
+ import{parseDocument,DomUtils}from"htmlparser2";import{render}from"dom-serializer";const fnCache=new Map;function getDataValue(expression,scope){const keys=Object.keys(scope),cacheKey=`${expression}::${keys.join(",")}`;fnCache.has(cacheKey)||fnCache.set(cacheKey,Function(...keys,`return (${expression})`));try{return fnCache.get(cacheKey)(...Object.values(scope))}catch{return""}}function isEmptyTextNode(node){return node.type==="text"&&/^\s*$/.test(node.data)}function parseHTMLToNodes(html){try{const dom=parseDocument(html,{xmlMode:!0});return DomUtils.getChildren(dom)}catch(error){return console.error("Error parsing HTML:",error),[]}}function processNode(node,scope,previousRendered=!1){if(node.type==="text")return node.data=node.data.replace(/(?<!\\)\{\{(.+?)\}\}/g,(_,expr)=>getDataValue(expr.trim(),scope)).replace(/\\\{\{/g,"{{"),node;if(node.type==="tag"){const attrs=node.attribs||{};for(const[attrName,attrValue]of Object.entries(attrs))typeof attrValue=="string"&&(attrs[attrName]=attrValue.replace(/(?<!\\)\{\{(.+?)\}\}/g,(_,expr)=>getDataValue(expr.trim(),scope)).replace(/\\\{\{/g,"{{"));if("x-if"in attrs){const show=getDataValue(attrs["x-if"],scope);if(delete attrs["x-if"],!show)return null}if("x-else-if"in attrs){const show=getDataValue(attrs["x-else-if"],scope);if(delete attrs["x-else-if"],previousRendered||!show)return null}if("x-else"in attrs&&(delete attrs["x-else"],previousRendered))return null;if("x-show"in attrs){const show=getDataValue(attrs["x-show"],scope);delete attrs["x-show"],show||(attrs.style=(attrs.style||"")+"display:none;")}if("x-for"in attrs){const exp=attrs["x-for"];delete attrs["x-for"];const match=exp.match(/(.+?)\s+in\s+(.+)/);if(!match)throw new Error("Invalid x-for format: "+exp);const itemName=match[1].trim(),listExpr=match[2].trim(),list=getDataValue(listExpr,scope);if(!Array.isArray(list))return null;const clones=[];for(const item of list){const cloned=structuredClone(node),newScope={...scope,[itemName]:item};clones.push(processNode(cloned,newScope))}return clones}for(const[name,value]of Object.entries({...attrs})){if(name.startsWith(":")){const isSuspenseFallback=name===":fallback"&&node.name==="Suspense",realName=name.slice(1);if(isSuspenseFallback)attrs[realName]=value;else{const val=getDataValue(value,scope);attrs[realName]=val!=null&&typeof val=="object"?JSON.stringify(val):String(val??"")}delete attrs[name]}if(name.startsWith("x-bind:")){const realName=name.slice(7),val=getDataValue(value,scope);attrs[realName]=val!=null&&typeof val=="object"?JSON.stringify(val):String(val??""),delete attrs[name]}}for(const[name]of Object.entries({...attrs}))(name.startsWith("@")||name.startsWith("x-on:"))&&delete attrs[name];if(node.children){const result=[];let isPreviousRendered=!1;for(const child of node.children){if(isEmptyTextNode(child))continue;const processed=processNode(child,scope,isPreviousRendered);Array.isArray(processed)?(result.push(...processed),isPreviousRendered=processed.length>0):processed?(result.push(processed),isPreviousRendered=!0):isPreviousRendered=!1}node.children=result}return node}return node}const parsedTemplateCache=new Map;function compileTemplateToHTML(template,data={}){try{parsedTemplateCache.has(template)||parsedTemplateCache.set(template,parseHTMLToNodes(template));const processed=structuredClone(parsedTemplateCache.get(template)).map(n=>processNode(n,data)).flat().filter(Boolean);return render(processed,{encodeEntities:!1})}catch(error){throw console.error("Error compiling template:",error),error}}export{compileTemplateToHTML};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cfdez11/vex",
3
- "version": "0.10.12",
3
+ "version": "0.10.14",
4
4
  "description": "A vanilla JavaScript meta-framework with file-based routing, SSR/CSR/SSG/ISR and Vue-like reactivity",
5
5
  "repository": {
6
6
  "type": "git",