vaderjs 1.3.3-662-hotfix → 1.3.3-763562-hotfix

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.
Files changed (3) hide show
  1. package/package.json +1 -1
  2. package/runtime/vader.js +1 -1
  3. package/vader.js +284 -304
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "vaderjs",
3
3
  "description": "A Reactive library aimed to helping you build reactive applications inspired by react.js",
4
4
  "module": "vader.js",
5
- "version": "1.3.3-662-hotfix",
5
+ "version": "1.3.3-763562-hotfix",
6
6
  "bin": {
7
7
  "vader": "./vader.js"
8
8
  },
package/runtime/vader.js CHANGED
@@ -1 +1 @@
1
- window.Vader={version:"1.3.3"},window.componentRegistry={};let errors={"SyntaxError: Unexpected token '<'":"You forgot to enclose tags in a fragment <></>"},mounts=[],hasRan=[];export const strictMount=(e,t)=>{let s=setInterval((()=>{document.querySelector(`[key="${e}"]`)&&!hasRan.includes(e)&&(clearInterval(s),t(),hasRan.push(e))}),120)};export class Component{constructor(){this.$_vaderElement=!0,this.state={},this.key=null,this.components={},this.mounted=!1,this.checkIFMounted(),this.memoizes=[],this.functions=[],this.children=[],this.noKey=!1,this.parentNode={},this.request={headers:{},method:"GET",params:{},path:"",query:{}},this.response={json:e=>{},send:e=>{},redirect:e=>{},render:async e=>{},log:e=>{},setQuery:e=>{}},this.router={use:e=>{}}}createComponent(e,t,s){function r(e){return"function"==typeof e&&/^class\s/.test(Function.prototype.toString.call(e))}let i=r(e)?new e(t):null;if(!e)throw new Error("Component must be defined");let n=[];Object.keys(t).forEach((e=>{if(e.startsWith("$props")&&(n.push(t[e]),delete t[e]),e.startsWith("$_ternary")){let s=t[e];delete t[e],Object.keys(s).forEach((e=>{t[e]=s[e]}))}}));let o=new Component(t);if(r(e))i.props=t||{},i.props.children=s.join("")||[],i.props.children=s.join(""),i.parentNode=this,i.type="class ",i.request=this.request,i.response=this.response,i.key=i.props.key?i.props.key:Math.random(),o=i;else{e.toString();o.key=e.toString().split('key="')[1]?e.toString().split('key="')[1].split('"')[0]:null,t=t?{...t,...n.reduce(((e,t)=>({...e,...t})),{}),children:s.join("")||[]}:{children:s.join("")||[]};let r={key:o.key?o.key:Math.random(),isUnique:!!o.key,render:()=>e.apply(o,[t]),request:this.request,isChild:!0,response:this.response,params:this.request.params,queryParams:this.request.query,reset:o.reset.bind(o),onMount:o.onMount.bind(o),useState:null,router:{use:o.router.use.bind(o)},bindMount:o.bindMount.bind(o),memoize:o.memoize.bind(o),createComponent:o.createComponent.bind(o),isChild:!1,useState:o.useState.bind(o),parseStyle:o.parseStyle.bind(o),bind:o.bind.bind(o),useRef:o.useRef.bind(o),request:this.request,response:this.response,useReducer:o.useReducer.bind(o),hydrate:o.hydrate.bind(o),onUnmount:o.onUnmount.bind(o),type:"function",parentNoe:this,props:{...t,children:s.join("")||[]}};o.render=r.render,o=r,o.props.children=s.join("")||[]}return this.components[o.key]||(this.components[o.key]=o),!this.children.includes(o)&&this.children.push(o),this.components[o.key]}reset(){Object.keys(this.components).forEach((e=>{this.components[e].onUnmount(),delete this.components[e]})),this.state={},this.children=[]}memoize(e){if(!0==!this.memoizes.includes(e.key))this.memoizes.push(e.key),this.components[e.key]=e;let t=this.components[e.key];"class"!==t.type||t.$_vaderElement||console.error(`class ${t.constructor.name} must extend Component`),t.bindMount(),t.parentNode=this,t.props=e.props,t.request=this.request,t.response=this.response,t.onMount=e.onMount.bind(e),t.onUnmount=e.onUnmount.bind(e);let s=t.render();return s&&s.split(">,").length>1&&(s=s.replaceAll(">,",">")),t.nokey||t.noKey?s:`<div key="${t.key}">${s}</div>`}parseStyle(e){let t="";return Object.keys(e).forEach((s=>{let r=e[s];s=s.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g,"$1-$2").toLowerCase(),t+=`${s}:${r};`})),t}bindMount(){mounts.push(this)}domDifference(e,t){let s=[];for(let r=0;r<e.length;r++){let i=e[r],n=t[r];if(i&&n&&i.childNodes.length>0&&n.childNodes.length>0){console.log("equal");let e=this.domDifference(Array.from(i.childNodes),Array.from(n.childNodes));s.push(...e)}i&&n&&0===i.childNodes.length&&0===n.childNodes.length?i.isEqualNode(n)||s.push({type:"replace",old:i,new:n}):i&&n&&Array.from(i.attributes).length!==Array.from(n.attributes).length&&s.push({type:"replace",old:i,new:n})}return s}updateChangedElements(e){e.forEach((e=>{if(e)switch(e.type){case"replace":e.old.replaceWith(e.new);break;case"remove":e.old.remove();break;case"add":e.old.appendChild(e.new.cloneNode(!0))}}))}hydrate(e){if(e){console.log(e.bind);let t=(new DOMParser).parseFromString(this.render(),"text/html").body.querySelectorAll(`[ref="${e.bind?e.bind:e}"]`),s=document.querySelectorAll(`[ref="${e?e.bind:e}"]`);t.forEach((e=>{let t=Array.from(s).find((t=>t.getAttribute("ref")===e.getAttribute("ref")));if(t){let s=this.domDifference(Array.from(t.childNodes),Array.from(e.childNodes))[0];this.updateChangedElements([s])}}))}else{let e=this.key?document.querySelector(`[key="${this.key}"]`):null;if(console.log(e),e){let t=(new DOMParser).parseFromString(this.render(),"text/html").body.querySelector(`[key="${this.key}"]`),s=e,r=this.domDifference([s],[t]);this.updateChangedElements(r)}}}patch(e,t){const s=this.domDifference(e,t);this.updateChangedElements(s)}handleObject(obj){try{obj=JSON.parse(obj)}catch(e){}return eval(obj)}bind(e,t,s,r,...i){return s+=this.key,window["callFunctions"+this.key]=(e,t)=>{let s=this.functions.find((t=>t.ref===e));s&&s.func(t)},this.functions.find((e=>e.ref===s))||this.functions.push({ref:s,func:e}),t?e:`((event)=>{callFunctions${this.key} ? callFunctions${this.key}('${s}', event) : null})(event)`}setState(e,t){this.state=e,this.hydrate(t)}useState(e,t){this.state.hasOwnProperty(e)||(this.state[e]=t);return[(()=>this.state[e])(),(t,s)=>{this.state[e]=t,this.hydrate(s)}]}useRef(e=null,t){this.state[e]||(this.state[e]=t);return{bind:e+this.key,current:(()=>document.querySelector(`[ref="${e+this.key}"]`)||t)()}}useReducer(e=null,t,s=null){this.state[e]||(this.state[e]=t);const r=()=>this.state[e];let i=r();return[r(),(t,n)=>{const o=s(i,t)??t;this.state[e]=o,this.hydrate(n),i=r()}]}render(){}checkIFMounted(){new MutationObserver((e=>{e.forEach((e=>{e.target.querySelector(`[key="${this.key}"]`)&&!this.mounted&&(this.onMount(),this.mounted=!0),Array.from(e.removedNodes).find((e=>e.attributes&&e.attributes.key&&e.attributes.key.value===this.key))&&(this.onUnmount(),this.reset())}))})).observe(document.body,{childList:!0,subtree:!0})}onMount(){}onUnmount(){}}export const useState=(e,t)=>{this.state[e]||(this.state[e]=t);return[states[e],(t,s)=>{states[e]=t,this.hydrate(s)}]};export const useReducer=(e,t)=>[e,e=>{}];export const useRef=e=>({current:e,bind:""});export class Link extends Component{constructor(e){super(e),this.props=e,this.link=document.createElement("a"),this.key=e.href+Math.random(),this.nokey=!0}render(){return this.link.innerHTML=this.props.children,this.link.setAttribute("id",this.props?.href),this.link.style=this.props?.style,this.link.setAttribute("class",this.props?.class||this.props?.className),this.link.setAttribute("onclick",`window.history.pushState({}, '', '${this.props?.href}'); window.dispatchEvent(new Event('popstate'));`),this.link.outerHTML}}export class Image extends Component{constructor(e){super(e),this.props={src:e.src,class:e.class,style:e.style,blur:e.blur,width:e.width,height:e.height,optimize:e.optimize||!0,loader:e.loader||!0,alt:e.alt||"image",ref:e.ref||null},this.key=e.src+Math.random(),this.img=document.createElement("img"),this.placeholder=document.createElement("div")}render(){if(window.isServer)return"";let[e,t]=this.useState("loaded",!1),s=this.useRef("hookref",null),r=this.props.width?this.props.width:window.innerWidth/2,i=this.props.height?this.props.height:window.innerHeight/2;if(!this.props.src)throw new Error("Image src is required");return this.img.setAttribute("src",this.props.src),this.img.setAttribute("class",this.props.class),this.img.setAttribute("style",this.props.style?this.props.style:""),this.img.setAttribute("width",r),this.img.setAttribute("ref",s.bind),this.img.referrerPolicy="no-referrer",this.img.setAttribute("height",i),this.img.setAttribute("loading","lazy"),this.img.setAttribute("alt",this.props.alt),this.props.blur&&this.img.setAttribute("style",`filter: blur(${this.props.blur}px);`),this.props.optimize&&this.img.setAttribute("style",`image-rendering: -webkit-optimize-contrast; object-fit: cover; object-position: center; ${this.props.style?this.props.style:""}`),!this.props.loader||e||window.isServer||(this.placeholder.setAttribute("style",`width: ${r}px; height: ${i}px; background: #eee;`),this.placeholder.setAttribute("class","vader-image-placeholder"),this.placeholder.innerHTML=this.props.loader,window.isServer)?void 0:(this.img.onload=()=>{t(!0,s.bind)},`<span ref="${s.bind}">${e?this.img.outerHTML:this.placeholder.outerHTML}</span>`)}}export class Html extends Component{constructor(e){super(e),this.props={children:e.children,lang:e.lang||"en",attributes:e.attributes||{}},this.key="html",this.html=document.createElement("div")}render(){return window.isServer?(this.html.innerHTML=this.props.children,this.html.setAttribute("lang",this.props.lang?this.props.lang:"en"),this.props.attributes&&Object.keys(this.props.attributes).forEach((e=>{this.html.setAttribute(e,this.props.attributes[e])})),this.html.innerHTML):this.props.children}onMount(){console.log("Document Has Been Mounted")}}export class Head extends Component{constructor(e){super(e),this.props=e,this.key="head",this.head=document.createElement("head")}render(){return""}onMount(){if(!this.state.hasMounted&&window.isServer){console.log(this.props.children),document.head.innerHTML=this.props.children+document.head.innerHTML,document.querySelectorAll("script[eager]").forEach((async e=>{if(!e.getAttribute("src"))throw new Error("Eager scripts must be external");e.remove();let t=e.getAttribute("src"),s=document.createElement("script"),r=null;await fetch(t).then((e=>{if(404===e.status)throw document.documentElement.setAttribute("error",JSON.stringify({error:`File ${t} not found`,status:404})),new Error(`File ${t} not found`);return e.text()})).then((e=>{r=e})).catch((e=>{throw e})),s.innerHTML=r,s.setAttribute("srcid",t),document.querySelector(`[srcid="${t}"]`)||document.head.prepend(s)})),this.state.hasMounted=!0}}}export class Script extends Component{constructor(e){super(e),this.props={children:e.children},this.key="script",this.script=document.createElement("script")}render(){return this.script.innerHTML=this.props.children.split("\n").join(";\n"),this.script.outerHTML}onMount(){document.head.appendChild(this.script),document.body.querySelector(`[key="${this.key}"]`).remove()}}export default{Component:Component,useRef:useRef,useReducer:useReducer,useState:useState,strictMount:strictMount,Link:Link,Image:Image,Head:Head,Script:Script,Html:Html};
1
+ window.Vader={version:"1.3.3"},window.componentRegistry={};let errors={"SyntaxError: Unexpected token '<'":"You forgot to enclose tags in a fragment <></>"},mounts=[],hasRan=[];export const strictMount=(e,t)=>{let s=setInterval((()=>{document.querySelector(`[key="${e}"]`)&&!hasRan.includes(e)&&(clearInterval(s),t(),hasRan.push(e))}),120)};export class Component{constructor(e={}){this.$_vaderElement=!0,this.state={},this.key=null,this.components={},this.mounted=!1,this.checkIFMounted(),this.memoizes=[],this.functions=[],this.props={children:"",$:{},...e},this.children=[],this.noKey=!1,this.parentNode={},this.request={headers:{},method:"GET",params:{},path:"",query:{}},this.response={json:e=>{},send:e=>{},redirect:e=>{},render:async e=>{},log:e=>{},setQuery:e=>{}},this.router={use:e=>{}}}createComponent(e,t,s){function r(e){return"function"==typeof e&&/^class\s/.test(Function.prototype.toString.call(e))}let i=r(e)?new e(t):null;if(!e)throw new Error("Component must be defined");let n=[],o=new Component(t);if(r(e))i.props=t||{},i.props.children=s.join("")||[],i.props.children=s.join(""),i.parentNode=this,i.type="class ",i.request=this.request,i.response=this.response,i.key=i.props.key?i.props.key:Math.random(),o=i;else{e.toString();o.key=e.toString().split('key="')[1]?e.toString().split('key="')[1].split('"')[0]:null,t=t?{...t,...n.reduce(((e,t)=>({...e,...t})),{}),children:s.join("")||[]}:{children:s.join("")||[]};let r={key:o.key?o.key:Math.random(),isUnique:!!o.key,render:()=>e.apply(o,[t]),request:this.request,isChild:!0,response:this.response,params:this.request.params,queryParams:this.request.query,reset:o.reset.bind(o),onMount:o.onMount.bind(o),useState:null,router:{use:o.router.use.bind(o)},bindMount:o.bindMount.bind(o),memoize:o.memoize.bind(o),createComponent:o.createComponent.bind(o),isChild:!1,useState:o.useState.bind(o),parseStyle:o.parseStyle.bind(o),bind:o.bind.bind(o),useRef:o.useRef.bind(o),request:this.request,response:this.response,useReducer:o.useReducer.bind(o),hydrate:o.hydrate.bind(o),onUnmount:o.onUnmount.bind(o),type:"function",parentNoe:this,props:{...t,children:s.join("")||[]}};o.render=r.render,o=r,o.props.children=s.join("")||[]}return this.components[o.key]||(this.components[o.key]=o),!this.children.includes(o)&&this.children.push(o),this.components[o.key]}reset(){Object.keys(this.components).forEach((e=>{this.components[e].onUnmount(),delete this.components[e]})),this.state={},this.children=[]}memoize(e){if(!0==!this.memoizes.includes(e.key))this.memoizes.push(e.key),this.components[e.key]=e;let t=this.components[e.key];"class"!==t.type||t.$_vaderElement||console.error(`class ${t.constructor.name} must extend Component`),t.bindMount(),t.parentNode=this,t.props=e.props,t.request=this.request,t.response=this.response,t.onMount=e.onMount.bind(e),t.onUnmount=e.onUnmount.bind(e);let s=t.render();return s&&s.split(">,").length>1&&(s=s.replaceAll(">,",">")),t.nokey||t.noKey?s:`<div key="${t.key}">${s}</div>`}parseStyle(e){let t="";return Object.keys(e).forEach((s=>{let r=e[s];s=s.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g,"$1-$2").toLowerCase(),t+=`${s}:${r};`})),t}bindMount(){mounts.push(this)}domDifference(e,t){let s=[];for(let r=0;r<e.length;r++){let i=e[r],n=t[r];if(i&&n&&i.childNodes.length>0&&n.childNodes.length>0){let e=this.domDifference(Array.from(i.childNodes),Array.from(n.childNodes));s.push(...e)}i&&n&&0===i.childNodes.length&&0===n.childNodes.length?i.isEqualNode(n)||s.push({type:"replace",old:i,new:n}):i&&n&&Array.from(i.attributes).length!==Array.from(n.attributes).length&&s.push({type:"replace",old:i,new:n})}return s}updateChangedElements(e){e.forEach((e=>{if(e)switch(e.type){case"replace":e.old.replaceWith(e.new);break;case"remove":e.old.remove();break;case"add":e.old.appendChild(e.new.cloneNode(!0))}}))}hydrate(e){if(e){let t=(new DOMParser).parseFromString(this.render(),"text/html").body.querySelectorAll(`[ref="${e.bind?e.bind:e}"]`),s=document.querySelectorAll(`[ref="${e?e.bind:e}"]`);t.forEach((e=>{let t=Array.from(s).find((t=>t.getAttribute("ref")===e.getAttribute("ref")));if(t){let s=this.domDifference(Array.from(t.childNodes),Array.from(e.childNodes))[0];this.updateChangedElements([s])}}))}else{let e=this.key?document.querySelector(`[key="${this.key}"]`):null;if(e){let t=(new DOMParser).parseFromString(this.render(),"text/html").body.querySelector(`[key="${this.key}"]`),s=e,r=this.domDifference([s],[t]);this.updateChangedElements(r)}}}patch(e,t){const s=this.domDifference(e,t);this.updateChangedElements(s)}handleObject(obj){try{obj=JSON.parse(obj)}catch(e){}return eval(obj)}bind(e,t,s,r,...i){return s+=this.key,window["callFunctions"+this.key]=(e,t)=>{let s=this.functions.find((t=>t.ref===e));s&&s.func(t)},this.functions.find((e=>e.ref===s))||this.functions.push({ref:s,func:e}),t?e:`((event)=>{callFunctions${this.key} ? callFunctions${this.key}('${s}', event) : null})(event)`}setState(e,t){this.state=e,this.hydrate(t)}useState(e,t){this.state.hasOwnProperty(e)||(this.state[e]=t);return[(()=>this.state[e])(),(t,s)=>{this.state[e]=t,this.hydrate(s)}]}useRef(e=null,t){this.state[e]||(this.state[e]=t);return{bind:e+this.key,current:(()=>document.querySelector(`[ref="${e+this.key}"]`)||t)()}}useReducer(e=null,t,s=null){this.state[e]||(this.state[e]=t);const r=()=>this.state[e];let i=r();return[r(),(t,n)=>{const o=s(i,t)??t;this.state[e]=o,this.hydrate(n),i=r()}]}render(){}checkIFMounted(){new MutationObserver((e=>{e.forEach((e=>{e.target.querySelector(`[key="${this.key}"]`)&&!this.mounted&&(this.onMount(),this.mounted=!0),Array.from(e.removedNodes).find((e=>e.attributes&&e.attributes.key&&e.attributes.key.value===this.key))&&(this.onUnmount(),this.reset())}))})).observe(document.body,{childList:!0,subtree:!0})}onMount(){}onUnmount(){}}export const useState=(e,t)=>{this.state[e]||(this.state[e]=t);return[states[e],(t,s)=>{states[e]=t,this.hydrate(s)}]};export const useReducer=(e,t)=>[e,e=>{}];export const useRef=e=>({current:e,bind:""});export class Link extends Component{constructor(e){super(e),this.props=e,this.link=document.createElement("a"),this.key=e.href+Math.random(),this.nokey=!0}render(){return this.link.innerHTML=this.props.children,this.link.setAttribute("id",this.props?.href),this.link.style=this.props?.style,this.link.setAttribute("class",this.props?.class||this.props?.className),this.link.setAttribute("onclick",`window.history.pushState({}, '', '${this.props?.href}'); window.dispatchEvent(new Event('popstate'));`),this.link.outerHTML}}export class Image extends Component{constructor(e){super(e),this.props={src:e.src,class:e.class,style:e.style,blur:e.blur,width:e.width,height:e.height,optimize:e.optimize||!0,loader:e.loader||!0,alt:e.alt||"image",ref:e.ref||null},this.key=e.src+Math.random(),this.img=document.createElement("img"),this.placeholder=document.createElement("div")}render(){if(window.isServer)return"";let[e,t]=this.useState("loaded",!1),s=this.useRef("hookref",null),r=this.props.width?this.props.width:window.innerWidth/2,i=this.props.height?this.props.height:window.innerHeight/2;if(!this.props.src)throw new Error("Image src is required");return this.img.setAttribute("src",this.props.src),this.img.setAttribute("class",this.props.class),this.img.setAttribute("style",this.props.style?this.props.style:""),this.img.setAttribute("width",r),this.img.setAttribute("ref",s.bind),this.img.referrerPolicy="no-referrer",this.img.setAttribute("height",i),this.img.setAttribute("loading","lazy"),this.img.setAttribute("alt",this.props.alt),this.props.blur&&this.img.setAttribute("style",`filter: blur(${this.props.blur}px);`),this.props.optimize&&this.img.setAttribute("style",`image-rendering: -webkit-optimize-contrast; object-fit: cover; object-position: center; ${this.props.style?this.props.style:""}`),!this.props.loader||e||window.isServer||(this.placeholder.setAttribute("style",`width: ${r}px; height: ${i}px; background: #eee;`),this.placeholder.setAttribute("class","vader-image-placeholder"),this.placeholder.innerHTML=this.props.loader,window.isServer)?void 0:(this.img.onload=()=>{t(!0,s.bind)},`<span ref="${s.bind}">${e?this.img.outerHTML:this.placeholder.outerHTML}</span>`)}}export class Html extends Component{constructor(e){super(e),this.props={children:e.children,lang:e.lang||"en",attributes:e.attributes||{}},this.key="html",this.html=document.createElement("div")}render(){return window.isServer?(this.html.innerHTML=this.props.children,this.html.setAttribute("lang",this.props.lang?this.props.lang:"en"),this.props.attributes&&Object.keys(this.props.attributes).forEach((e=>{this.html.setAttribute(e,this.props.attributes[e])})),this.html.innerHTML):this.props.children}onMount(){console.log("Document Has Been Mounted")}}export class Head extends Component{constructor(e){super(e),this.props=e,this.key="head",this.head=document.createElement("head")}render(){return""}onMount(){if(!this.state.hasMounted&&window.isServer){document.head.innerHTML=this.props.children+document.head.innerHTML,document.querySelectorAll("script[eager]").forEach((async e=>{if(!e.getAttribute("src"))throw new Error("Eager scripts must be external");e.remove();let t=e.getAttribute("src"),s=document.createElement("script"),r=null;await fetch(t).then((e=>{if(404===e.status)throw document.documentElement.setAttribute("error",JSON.stringify({error:`File ${t} not found`,status:404})),new Error(`File ${t} not found`);return e.text()})).then((e=>{r=e})).catch((e=>{throw e})),s.innerHTML=r,s.setAttribute("srcid",t),document.querySelector(`[srcid="${t}"]`)||document.head.prepend(s)})),this.state.hasMounted=!0}}}export class Script extends Component{constructor(e){super(e),this.props={children:e.children},this.key="script",this.script=document.createElement("script")}render(){return this.script.innerHTML=this.props.children.split("\n").join(";\n"),this.script.outerHTML}onMount(){document.head.appendChild(this.script),document.body.querySelector(`[key="${this.key}"]`).remove()}}export default{Component:Component,useRef:useRef,useReducer:useReducer,useState:useState,strictMount:strictMount,Link:Link,Image:Image,Head:Head,Script:Script,Html:Html};
package/vader.js CHANGED
@@ -143,6 +143,9 @@ function Compiler(func, file) {
143
143
  isJSXComponent = elementTag.match(/^[A-Z]/) ? true : false;
144
144
  }
145
145
  });
146
+ if (isJSXComponent) {
147
+ continue
148
+ }
146
149
  // add ; after newlines
147
150
 
148
151
 
@@ -239,34 +242,34 @@ function Compiler(func, file) {
239
242
  continue;
240
243
  }
241
244
  let old = spread;
242
- spread = spread.trim().replace(/\s+/g, " ");
245
+ spread = spread.trim().replace(/\s+/g, " ");
243
246
  // re,pve $={ and }
244
247
  spread = spread.replace(/\s*\$\s*=\s*{\s*{/gs, '')
245
-
248
+
246
249
  // replace trailing }
247
- spread = spread.replace(/}}\s*$/, '').replace(/}\s*}$/, '')
248
- let splitByCommas = spread.split(/,(?![^{}]*})/gs)
250
+ spread = spread.replace(/}}\s*$/, '').replace(/}\s*}$/, '')
251
+ let splitByCommas = spread.split(/,(?![^{}]*})/gs)
249
252
  // remove empty strings
250
253
  splitByCommas = splitByCommas.filter((e) => e.split(':')[0].trim().length > 0)
251
- splitByCommas = splitByCommas.map((e, index) => {
254
+ splitByCommas = splitByCommas.map((e, index) => {
252
255
  let key = e.split(':')[0].trim()
253
256
  switch (true) {
254
257
  case e.includes('function') && !e.includes('this.bind') || e && e.includes('=>') && !e.includes('this.bind'):
255
258
  let value = e.split(':')[1].trim()
256
- let ref = Math.random().toString(36).substring(2).split('').filter((e) => !Number(e)).join('');
259
+ let ref = Math.random().toString(36).substring(2).split('').filter((e) => !Number(e)).join('');
257
260
  value = `this.bind(${value}, false, "${ref}", "")`
258
261
  e = `${key}="\${${value}}"`
259
262
  break;
260
- case e.includes('style:'):
261
- let v2 = e.split('style:')[1].trim().replace(/,$/, '')
262
- v2 = v2.replace(/,$/, '')
263
+ case e.includes('style:'):
264
+ let v2 = e.split('style:')[1].trim().replace(/,$/, '')
265
+ v2 = v2.replace(/,$/, '')
263
266
  e = `${key}="\${this.parseStyle(${v2})}"`
264
- break;
265
-
266
- default:
267
- let v = e.split(':')
267
+ break;
268
+
269
+ default:
270
+ let v = e.split(':')
268
271
  key = v[0].trim()
269
- // remove key from v
272
+ // remove key from v
270
273
  v.shift()
271
274
  v = v.join(' ')
272
275
  e = `${key}="\${${v}}"`
@@ -277,7 +280,7 @@ function Compiler(func, file) {
277
280
 
278
281
  return e;
279
282
  });
280
-
283
+
281
284
 
282
285
  let newSpread = splitByCommas.join(' ').trim().replace(/,$/, '');
283
286
 
@@ -348,7 +351,7 @@ function Compiler(func, file) {
348
351
  newAttributes.push(attribute);
349
352
  for (let key in attributes) {
350
353
 
351
- let value = attributes[key];
354
+ let value = attributes[key];
352
355
  let oldvalue = value;
353
356
  if (value && !value.new) {
354
357
 
@@ -479,11 +482,16 @@ function Compiler(func, file) {
479
482
 
480
483
  let name = component.split("<")[1].split(">")[0].split(" ")[0].replace("/", "");
481
484
  let componentAttributes = component.split("<")[1].split(">")[0].split(" ").join(" ").replace(name, "").trim();
482
- const dynamicAttributesRegex = /(\w+)(?:="([^"]*?)"|='([^']*?)'|(?:=\{([^}]*?)\})?|(?:=\{(.*?)*\})?|(?:={([^}]*?)})?|(?:{([^}]*?)})?|(?:}))?|\$=\s*\{\s*\{\s*([^]*?)\s*\}\s*\}/gs;
485
+ // catchall = "" ={} =[]
486
+
487
+
488
+ let props = component.split("<")[1].split(">")[0]
483
489
 
484
490
 
491
+ const dynamicAttributesRegex = /([a-zA-Z0-9_-]+)\s*=\s*("(?:[^"\\]*(?:\\.[^"\\]*)*)"|'(?:[^'\\]*(?:\\.[^'\\]*)*)'|\{(?:[^{}]|(?:\{(?:[^{}]|(?:\{.*.*\})*)*\})*)*\}|(?:\([^)]*\)|()\s*=>\s*(?:\{.*\})?|\{[^}]*\})|\[[^\]]*\])/gs;
492
+
493
+ const attributeObject = {};
485
494
 
486
- let props = component.match(dynamicAttributesRegex)
487
495
 
488
496
  let filteredProps = [];
489
497
  let isWithinComponent = false;
@@ -492,78 +500,31 @@ function Compiler(func, file) {
492
500
 
493
501
  let $_ternaryprops = []
494
502
 
495
- for (let prop of props) {
496
-
497
- if (prop === componentName) {
498
-
499
- isWithinComponent = true;
500
- filteredProps.push(prop);
501
- } else if (isWithinComponent && prop.includes('=')) {
502
-
503
- if (prop.startsWith('$=')) {
504
- let old = prop
505
- prop = prop.replace(/\$\s*=\s*\{\s*\{/, '').replace(/\}\s*\}/, '}').replace(/}\s*$/, '')
506
-
507
- component = component.replace(old, prop)
508
- componentAttributes = componentAttributes.replace(old, prop)
509
-
510
- $_ternaryprops.push(prop)
511
-
512
- }
513
- else if (prop.includes('${')) {
514
-
515
-
516
- prop = prop.replace('="', ':')
517
- if (prop.includes('${')) {
518
- prop = prop.replace('="', ':')
519
- prop = prop.replace('${', '')
520
- }
521
- if (prop.includes('="${{')) {
522
- prop = prop.replace('${{', '{')
523
- prop = prop.replace('}}', '}')
524
- prop = prop.replace('="', ':')
525
- prop = prop.replace('}"', '}')
526
- }
527
-
528
- }
529
- if (prop.includes('={')) {
530
- let value = prop.split('={')
531
- let isObj = value[1].match(/^{.*}$/gs) ? true : false
532
- if (!isObj) {
533
- // remove trailing }
534
- value[1] = value[1].replace(/}\s*$/, '')
535
- }
536
-
537
- if (value[0] == 'style' && isObj) {
538
- value[1] = `this.parseStyle(${value[1]})`
539
- }
540
- prop = `${value[0]}:${value[1]}`
541
- }
542
-
543
- if (prop.includes('function') || prop.includes('=>')) {
544
- // parse 'function' to function
545
- prop = prop.replace("'", '')
546
-
547
- if (prop.endsWith("}'")) {
548
- prop = prop.replace("}'", '}')
549
-
550
- }
551
-
552
- prop = prop.replace('=function', ':function')
553
- }
554
-
555
- filteredProps.push(prop);
556
-
557
-
558
-
559
- } else if (isWithinComponent && prop.includes('}')) {
560
-
503
+ let match;
504
+ let propstring = ''
505
+ // props right now is just a string with all of them on one line and a space between each
506
+ while ((match = dynamicAttributesRegex.exec(props)) !== null) {
507
+ let str = match[0].trim().replace(/\s+/g, " ");
508
+ if (!str.includes('=')) {
509
+ continue
561
510
  }
562
-
563
-
564
- else {
565
- isWithinComponent = false;
511
+ str = str.split('=')
512
+ let key = str[0].trim()
513
+ let value = str[1].trim()
514
+ if (value.startsWith('"') && !value.endsWith('"') || value.startsWith("'") && !value.endsWith("'")
515
+ || value.startsWith('`') && !value.endsWith('`')) {
516
+ // wrap in respective quotes
517
+ value = value + value[0]
518
+ }
519
+ let isObject = value.startsWith('{{') && value.endsWith('}}')
520
+ if (isObject) {
521
+ value = value.split('{{')[1].split('}}')[0].trim()
522
+ value = `{${value}}`
523
+ } else {
524
+ // remove starting { and ending } using regex
525
+ value = value.replace(/^{/, '').replace(/}$/, '')
566
526
  }
527
+ propstring += `${key}:${value},`
567
528
  }
568
529
  component = component.replaceAll(/\s+/g, " ");
569
530
 
@@ -574,7 +535,7 @@ function Compiler(func, file) {
574
535
 
575
536
  let children = new RegExp(`<${name}[^>]*>([^]*)<\/${name}>`, 'gs').exec(component)?.[1] || null;
576
537
 
577
- props = filteredProps.join(',').replace(/\s+/g, " ").trim().replace(/,$/, '')
538
+
578
539
 
579
540
  let savedname = name;
580
541
 
@@ -607,24 +568,15 @@ function Compiler(func, file) {
607
568
 
608
569
 
609
570
 
610
-
611
- props = props.replaceAll(`,${savedname}`, '').replaceAll(savedname, '')
612
- if (props.startsWith(',')) {
613
- props = props.replace(',', '')
614
- }
615
- props = props.replaceAll("='", ":'")
616
- .replaceAll('=`', ':`')
617
- .replaceAll('="', ':"')
618
- .replaceAll('={', ':')
571
+ propstring = propstring.replace(/,$/, '')
619
572
 
620
573
 
621
574
  /**
622
575
  * @memoize - memoize a component to be remembered on each render and replace the old jsx
623
576
  */
624
577
 
625
-
626
578
  let replace = "";
627
- replace = `\${this.memoize(this.createComponent(${savedname}, {${props}}, [\`${myChildrens.join('')}\`]))}`;
579
+ replace = `\${this.memoize(this.createComponent(${savedname}, {${propstring}}, [\`${myChildrens.join('')}\`]))}`;
628
580
 
629
581
 
630
582
  body = body.replace(before, replace);
@@ -640,47 +592,49 @@ function Compiler(func, file) {
640
592
  let replaceMents = [];
641
593
 
642
594
 
643
- for (let match of imports) {
644
- let path = match.split('from')[1].trim().replace(/'/g, '').replace(/"/g, '').trim()
645
- switch (true) {
646
- case path && !path.includes('./') && !path.includes('/vader.js') && !path.includes('/vaderjs/client') && !path.startsWith('src') && !path.startsWith('public') && !path.includes('http') && !path.includes('https'):
647
- let componentFolder = fs.existsSync(process.cwd() + '/node_modules/' + path) ? process.cwd() + '/node_modules/' + path : process.cwd() + '/node_modules/' + path.split('/')[0]
648
- componentFolder = componentFolder.split(process.cwd())[1]
649
- if (!fs.existsSync(process.cwd() + componentFolder)) {
650
- throw new Error('Could not find ' + path + ' at ' + match + ' in file ' + file)
651
- }
652
-
653
- if (!fs.existsSync(process.cwd() + '/dist/src/' + componentFolder.split('/').slice(2).join('/'))) {
654
- fs.mkdirSync(process.cwd() + '/dist/src/' + componentFolder.split('/').slice(2).join('/'), { recursive: true })
655
- }
656
-
657
- let baseFolder = componentFolder.split('node_modules')[1].split('/')[1]
658
- let glp = globSync('**/**/**/**.{jsx,js}', {
659
- cwd: process.cwd() + '/node_modules/' + baseFolder + '/',
660
- absolute: true,
661
- recursive: true
662
- })
663
- for (let file of glp) {
664
- let text = fs.readFileSync(file, "utf8");
665
- if (!file.endsWith('.js') && file.endsWith('.jsx')) {
666
- text = Compiler(text, file);
667
-
595
+ if(imports){
596
+ for (let match of imports) {
597
+ let path = match.split('from')[1].trim().replace(/'/g, '').replace(/"/g, '').trim()
598
+ switch (true) {
599
+ case path && !path.includes('./') && !path.includes('/vader.js') && !path.includes('/vaderjs/client') && !path.startsWith('src') && !path.startsWith('public') && !path.includes('http') && !path.includes('https'):
600
+ let componentFolder = fs.existsSync(process.cwd() + '/node_modules/' + path) ? process.cwd() + '/node_modules/' + path : process.cwd() + '/node_modules/' + path.split('/')[0]
601
+ componentFolder = componentFolder.split(process.cwd())[1]
602
+ if (!fs.existsSync(process.cwd() + componentFolder)) {
603
+ throw new Error('Could not find ' + path + ' at ' + match + ' in file ' + file)
668
604
  }
669
- let dest = file.split('node_modules')[1]
670
- dest = dest.split(baseFolder)[1]
671
- writer(process.cwd() + '/dist/src/' + baseFolder + dest, text)
672
- let importname = match.split('import')[1].split('from')[0].trim()
673
- let oldImportstring = match.split('from')[1].trim().replace(/'/g, '').replace(/"/g, '').trim()
674
- let newImport = `/src/${baseFolder + dest}`
675
- newImport = newImport.replaceAll('.jsx', '.js').replaceAll('\\', '/')
676
- replaceMents.push({ match: oldImportstring, replace: newImport })
677
- console.log(`📦 imported Node Package ${baseFolder} `)
678
- }
679
-
680
-
681
- break;
682
- default:
683
- break;
605
+
606
+ if (!fs.existsSync(process.cwd() + '/dist/src/' + componentFolder.split('/').slice(2).join('/'))) {
607
+ fs.mkdirSync(process.cwd() + '/dist/src/' + componentFolder.split('/').slice(2).join('/'), { recursive: true })
608
+ }
609
+
610
+ let baseFolder = componentFolder.split('node_modules')[1].split('/')[1]
611
+ let glp = globSync('**/**/**/**.{jsx,js}', {
612
+ cwd: process.cwd() + '/node_modules/' + baseFolder + '/',
613
+ absolute: true,
614
+ recursive: true
615
+ })
616
+ for (let file of glp) {
617
+ let text = fs.readFileSync(file, "utf8");
618
+ if (!file.endsWith('.js') && file.endsWith('.jsx')) {
619
+ text = Compiler(text, file);
620
+
621
+ }
622
+ let dest = file.split('node_modules')[1]
623
+ dest = dest.split(baseFolder)[1]
624
+ writer(process.cwd() + '/dist/src/' + baseFolder + dest, text)
625
+ let importname = match.split('import')[1].split('from')[0].trim()
626
+ let oldImportstring = match.split('from')[1].trim().replace(/'/g, '').replace(/"/g, '').trim()
627
+ let newImport = `/src/${baseFolder + dest}`
628
+ newImport = newImport.replaceAll('.jsx', '.js').replaceAll('\\', '/')
629
+ replaceMents.push({ match: oldImportstring, replace: newImport })
630
+ console.log(`📦 imported Node Package ${baseFolder} `)
631
+ }
632
+
633
+
634
+ break;
635
+ default:
636
+ break;
637
+ }
684
638
  }
685
639
  }
686
640
 
@@ -873,6 +827,8 @@ const glb = await glob("**/**/**/**.{jsx,js}", {
873
827
  absolute: true,
874
828
  recursive: true
875
829
  });
830
+ let hasRendered = []
831
+
876
832
  async function Build() {
877
833
  globalThis.isBuilding = true
878
834
  console.log(globalThis.isProduction ? 'Creating Optimized Production Build\n' : '')
@@ -887,190 +843,133 @@ async function Build() {
887
843
 
888
844
  function ssg(routes = []) {
889
845
  globalThis.isBuilding = true
890
- routes.forEach(async (route) => {
891
- if (route.url.includes(':')) {
892
- return
893
- }
894
- let equalparamroute = routes.map((e) => {
895
- if (e.url.includes(':')) {
896
- let url = e.url.split('/:')[0]
897
- if (url && route.url === url) {
898
- return e
899
- } else {
900
- return null
846
+ let server = http.createServer((req, res) => {
847
+ let route = routes.find((e) => e.url === req.url)
848
+ if (route) {
849
+ let document = globalThis.routeDocuments.find((e) => e.url === req.url)
850
+ res.writeHead(200, { 'Content-Type': 'text/html' });
851
+ res.end(document.document);
852
+ } else {
853
+ const filePath = process.cwd() + '/dist/' + req.url
901
854
 
855
+ fs.readFile(filePath, (err, data) => {
856
+ if (err) {
857
+ res.writeHead(404, { 'Content-Type': filePath.includes('js') ? 'text/javascript' : 'text/html' });
858
+ res.end('File not found');
859
+ } else {
860
+ res.writeHead(200, { 'Content-Type': filePath.includes('js') ? 'text/javascript' : 'text/html' });
861
+ res.end(data);
902
862
  }
903
- }
904
- return null
905
- }).filter(Boolean)
906
- let document = `
907
- <!DOCTYPE html>
908
- <html lang="en">
909
- <head>
910
- <script>
911
- window.routes = JSON.parse('${JSON.stringify(routes)}')
912
- </script>
913
- <script id="isServer">
914
- window.isServer = true
915
- </script>
916
- <meta charset="UTF-8">
917
- <meta name="viewport" content="width=device-width,initial-scale=1.0">
918
- <script type="module" id="meta">
919
- window.history.pushState({}, '', '${route.url}')
920
- </script>
921
- <script type="module" id="router">
922
- import VaderRouter from '/router.js'
923
- const router = new VaderRouter('${route.url}', 3000)
924
- router.get('${route.url}', async (req, res) => {
925
- try{
926
- let module = await import('/${route.fileName.replace('.jsx', '.js')}')
927
- if(Object.keys(module).includes('$prerender') && !module.$prerender){
928
- document.head.setAttribute('prerender', 'false')
929
- }
930
- res.render(module, req, res, module.$metadata)
931
- }
932
- catch(error){
933
- let errorMessage = {
934
- message: error.message,
935
- name: error.name,
936
- stack: error.stack,
937
- path: window.location.pathname
938
- };
939
-
940
-
941
- document.documentElement.setAttribute('error', JSON.stringify(errorMessage));
942
- throw new Error(error)
943
- }
944
- })
945
- ${equalparamroute.length > 0 ? equalparamroute.map((e) => {
946
-
947
-
948
-
949
- return `router.get('${e.url}', async (req, res) => {
950
- let module = await import('/${e.fileName.replace('.jsx', '.js')}')
951
- res.render(module, req, res, module.$metadata)
952
- })\n`
953
- }) : ''}
954
- router.listen(3000)
955
-
956
- </script>
957
- </head>
958
- <body>
959
- <div id="root"></div>
960
- </body>
961
-
962
-
963
- </html>
964
- `;
965
-
966
- // generate random but common ports
967
- let port = Math.floor(Math.random() * (65535 - 49152 + 1) + 49152)
968
-
969
- const server = http.createServer((req, res) => {
863
+ });
864
+ }
865
+ });
970
866
 
971
- if (req.url === '/') {
972
- res.writeHead(200, { 'Content-Type': 'text/html' });
973
- res.end(document);
974
- } else {
975
- // Serve static files (adjust the file paths based on your project structure)
976
- const filePath = process.cwd() + '/dist/' + req.url
977
-
978
- fs.readFile(filePath, (err, data) => {
979
- if (err) {
980
- res.writeHead(404, { 'Content-Type': filePath.includes('js') ? 'text/javascript' : 'text/html' });
981
- res.end('File not found');
982
- } else {
983
- res.writeHead(200, { 'Content-Type': filePath.includes('js') ? 'text/javascript' : 'text/html' });
984
- res.end(data);
985
- }
986
- });
987
- }
988
- });
867
+ let port = 12000
868
+ server.on('error', (err) => {
869
+ if (err.code === 'EADDRINUSE') {
870
+ setTimeout(() => {
871
+ server.close();
872
+ server.listen(++port);
873
+ }, 1000);
874
+ }
875
+ })
989
876
 
990
- server.listen(port)
991
- server.on('error', (err) => {
992
- if (err.code === 'EADDRINUSE') {
993
- console.log(`Port ${port} is in use, trying another port...`);
994
- setTimeout(() => {
995
- server.close();
996
- server.listen(++port);
997
- }, 1000);
998
- }
999
- })
877
+ const browser = puppeteer.launch({
878
+ headless: "new", args: ['--no-sandbox', '--disable-setuid-sandbox'],
879
+ warning: false,
880
+ })
881
+ server.listen(port);
1000
882
 
883
+ routes.forEach(async (route) => {
884
+ if (route.url.includes(':')) {
885
+ return
886
+ }
1001
887
  globalThis.listen = true;
1002
888
 
1003
- const browser = await puppeteer.launch({
1004
- headless: "new", args: ['--no-sandbox', '--disable-setuid-sandbox'],
1005
- warning: false,
1006
- })
1007
889
  try {
1008
890
 
1009
891
  route.url = route.url.replaceAll(/\/:[a-zA-Z0-9_-]+/gs, '')
1010
- let page = await browser.newPage();
1011
- // Handle browser errors
1012
- page.on('error', (err) => {
1013
- console.error('BROWSER ERROR:', JSON.parse(err));
1014
- });
1015
-
1016
- try {
1017
- page.on('pageerror', async err => {
1018
- let errorObj = JSON.parse(await page.evaluate(() => document.documentElement.getAttribute('error')) || '{}')
1019
- console.log('\x1b[31m%s\x1b[0m', 'Compiler Error:', errorObj)
1020
- if(globalThis.isProduction){
1021
- process.exit(1)
1022
- }
892
+ let page = (await browser).newPage()
893
+ page.then(async (page) => {
894
+ page.on('error', (err) => {
895
+ console.error('JS ERROR:', JSON.parse(err));
1023
896
  });
1024
- } catch (error) {
1025
- browser.close()
1026
- }
1027
- // Handle page crashes
1028
- page.on('crash', () => {
1029
- console.error('PAGE CRASHED');
1030
- });
1031
- page.on('requestfailed', request => {
1032
- console.error('REQUEST FAILED:', request.url(), request.failure().errorText);
1033
- });
1034
- await page.goto(`http://localhost:${port}/`, { waitUntil: 'networkidle2' });
1035
-
1036
-
1037
-
897
+ try {
898
+ page.on('pageerror', async err => {
899
+ let errorObj = JSON.parse(await page.evaluate(() => document.documentElement.getAttribute('error')) || '{}')
900
+ console.log('\x1b[31m%s\x1b[0m', 'Compiler Error:', errorObj)
901
+
902
+ console.log('\x1b[31m%s\x1b[0m', 'Error:', err)
903
+ });
904
+ } catch (error) {
905
+ page.close()
906
+ }
907
+ page.on('crash', () => {
908
+ console.error(`Render process crashed for ${route.url}`)
909
+ });
910
+ page.on('requestfailed', request => {
911
+ console.error('REQUEST FAILED:', request.url(), request.failure().errorText);
912
+ });
913
+ await page.goto(`http://localhost:${port}${route.url}`, { waitUntil: 'networkidle2' });
914
+
915
+ page.evaluate(() => {
916
+ document.querySelector('#meta').remove()
917
+ document.querySelector('#isServer').innerHTML = 'window.isServer = false'
918
+ if (document.head.getAttribute('prerender') === 'false') {
919
+ document.querySelector('#root').innerHTML = ''
920
+ console.log(`Disabled prerendering for ${window.location.pathname}`)
921
+ }
922
+ })
923
+ let html = await page.content();
1038
924
 
925
+ html = await prettier.format(html, { parser: "html" })
1039
926
 
927
+ writer(process.cwd() + '/dist/' + (route.url === '/' ? 'index.html' : `${route.url}/` + 'index.html'), html)
1040
928
 
929
+ console.log(`\x1b[32m%s\x1b[0m`, `Prerendered ${route.url}...`)
1041
930
 
1042
- await page.evaluate(() => {
1043
- document.getElementById('meta').remove()
1044
- document.querySelector('#isServer').innerHTML = 'window.isServer = false'
1045
- if (document.head.getAttribute('prerender') === 'false') {
1046
- document.querySelector('#root').innerHTML = ''
1047
- console.log(`Disabled prerendering for ${window.location.pathname}`)
1048
- }
931
+ hasRendered.push(route.url)
1049
932
  })
1050
- let html = await page.content();
1051
-
1052
- html = await prettier.format(html, { parser: "html" })
1053
933
 
1054
934
 
1055
- await writer(process.cwd() + '/dist/' + (route.url === '/' ? 'index.html' : `${route.url}/` + 'index.html'), html)
1056
935
 
1057
936
 
1058
937
  } catch (error) {
1059
- console.log(error)
1060
- }
938
+ console.log('\x1b[31m%s\x1b[0m', 'Error:', error)
1061
939
 
940
+ }
1062
941
  finally {
1063
- browser.close()
1064
- server.close()
1065
942
  }
1066
943
  })
1067
944
 
1068
- let timeout = setTimeout(() => {
945
+
946
+
947
+
948
+
949
+ function kill() {
950
+ console.log(`\x1b[32m%s\x1b[0m`, `\nPrerendered ${routes.length} pages...\n`)
951
+ server.close()
952
+ browser.then((browser) => {
953
+ browser.close()
954
+ })
955
+ hasRendered = []
1069
956
  globalThis.isBuilding = false
1070
- clearTimeout(timeout)
1071
- }, 1000)
1072
- }
957
+ globalThis.isProduction ? console.log(`Total Bundle Size: ${Math.round(bundleSize / 1000)}kb`) : null
958
+ bundleSize = 0
959
+ }
1073
960
 
961
+ if (hasRendered.length === routes.length) {
962
+ kill()
963
+ } else {
964
+ console.log(`\x1b[32m%s\x1b[0m`, `Prerendering ${routes.length} pages...\n`)
965
+ let interval = setInterval(() => {
966
+ if (hasRendered.length === routes.length) {
967
+ kill()
968
+ clearInterval(interval)
969
+ }
970
+ }, 1000);
971
+ }
972
+ }
1074
973
  globalThis.routes = []
1075
974
 
1076
975
  for await (let file of glb) {
@@ -1170,7 +1069,9 @@ async function Build() {
1170
1069
  }
1171
1070
 
1172
1071
 
1173
- globalThis.routes.push({ fileName: fileName, url: obj.url, html: '/' + (isBasePath ? 'index.html' : `${obj.url}/` + 'index.html') })
1072
+ if (!obj.url.includes(':')) {
1073
+ globalThis.routes.push({ fileName: fileName, url: obj.url, html: '/' + (isBasePath ? 'index.html' : `${obj.url}/` + 'index.html') })
1074
+ }
1174
1075
 
1175
1076
 
1176
1077
  let stats = {
@@ -1187,6 +1088,84 @@ async function Build() {
1187
1088
  globalThis.isProduction ? console.log(string) : null
1188
1089
  }
1189
1090
 
1091
+ globalThis.routeDocuments = []
1092
+ globalThis.routes.map((route) => {
1093
+ let equalparamroute = globalThis.routes.map((e) => {
1094
+ if (e.url.includes(':')) {
1095
+ let url = e.url.split('/:')[0]
1096
+ if (url && route.url === url) {
1097
+ return e
1098
+ } else {
1099
+ return null
1100
+
1101
+ }
1102
+ }
1103
+ return null
1104
+ }).filter(Boolean)
1105
+ let document = `
1106
+ <!DOCTYPE html>
1107
+ <html lang="en">
1108
+ <head>
1109
+ <script>
1110
+ window.routes = JSON.parse('${JSON.stringify(globalThis.routes)}')
1111
+ </script>
1112
+ <script type="module" id="meta">
1113
+ window.history.pushState({}, '', '${route.url}')
1114
+
1115
+ </script>
1116
+ <script id="isServer">
1117
+ window.isServer = true
1118
+ </script>
1119
+ <meta charset="UTF-8">
1120
+ <meta name="viewport" content="width=device-width,initial-scale=1.0">
1121
+
1122
+ <script type="module" id="router">
1123
+ import VaderRouter from '/router.js'
1124
+ const router = new VaderRouter('${route.url}')
1125
+ router.get('${route.url}', async (req, res) => {
1126
+ try{
1127
+ let module = await import('/${route.fileName.replace('.jsx', '.js')}')
1128
+ if(Object.keys(module).includes('$prerender') && !module.$prerender){
1129
+ document.head.setAttribute('prerender', 'false')
1130
+ }
1131
+ res.render(module, req, res, module.$metadata)
1132
+ }
1133
+ catch(error){
1134
+ let errorMessage = {
1135
+ message: error.message,
1136
+ name: error.name,
1137
+ stack: error.stack,
1138
+ path: window.location.pathname
1139
+ };
1140
+
1141
+
1142
+ document.documentElement.setAttribute('error', JSON.stringify(errorMessage));
1143
+ throw new Error(error)
1144
+ }
1145
+ })
1146
+ ${equalparamroute.length > 0 ? equalparamroute.map((e) => {
1147
+
1148
+
1149
+
1150
+ return `router.get('${e.url}', async (req, res) => {
1151
+ let module = await import('/${e.fileName.replace('.jsx', '.js')}')
1152
+ res.render(module, req, res, module.$metadata)
1153
+ })\n`
1154
+ }) : ''}
1155
+ router.listen(3000)
1156
+
1157
+ </script>
1158
+ </head>
1159
+ <body>
1160
+ <div id="root"></div>
1161
+ </body>
1162
+
1163
+
1164
+ </html>
1165
+ `;
1166
+ globalThis.routeDocuments.push({ url: route.url, document: document })
1167
+ })
1168
+
1190
1169
  ssg(globalThis.routes)
1191
1170
 
1192
1171
 
@@ -1215,11 +1194,10 @@ async function Build() {
1215
1194
  scannedSourceFiles.forEach(async (file) => {
1216
1195
  file = file.replace(/\\/g, '/');
1217
1196
  let name = file.split('/src/')[1]
1218
- //parse jsx
1219
1197
 
1220
1198
  let data = await reader(process.cwd() + "/src/" + name)
1221
1199
  if (name.includes('.jsx')) {
1222
- let origin = process.cwd() + "/src/" + name
1200
+ let origin = process.cwd() + "/src/" + name
1223
1201
  if (!globalThis.isProduction) {
1224
1202
  let { sourceMap } = sourceMapGen({ origin: origin, fileName: name }, await Compiler(data, origin))
1225
1203
  data = data + `\n//# sourceMappingURL=/src/maps/${name.replace('.jsx', '.js.map')}\n //#sourceURL=${origin}`
@@ -1228,11 +1206,13 @@ async function Build() {
1228
1206
  await writer(process.cwd() + "/dist/src/" + name.split('.jsx').join('.js'), await Compiler(data, origin))
1229
1207
  return
1230
1208
  }
1231
- bundleSize += fs.statSync(process.cwd() + "/src/" + name).size;
1209
+ if (!name.includes('.map')) {
1210
+ bundleSize += fs.statSync(process.cwd() + "/src/" + name).size;
1211
+ }
1232
1212
  await writer(process.cwd() + "/dist/src/" + name, data);
1233
1213
  })
1234
1214
 
1235
- const scannedPublicFiles = await glob("**/**.{css,js,html,mjs,cjs}", {
1215
+ const scannedPublicFiles = await glob("**/**/**.{css,js,html,mjs,cjs,png,jpg,jpeg,gif,svg,mp4,webm,ogg}", {
1236
1216
  ignore: ["node_modules/**/*", "dist/**/*"],
1237
1217
  cwd: process.cwd() + '/public/',
1238
1218
  absolute: true,
@@ -1240,7 +1220,7 @@ async function Build() {
1240
1220
  scannedPublicFiles.forEach(async (file) => {
1241
1221
  file = file.replace(/\\/g, '/');
1242
1222
  file = file.split('/public/')[1]
1243
- let data = await reader(process.cwd() + "/public/" + file)
1223
+ let data = fs.readFileSync(process.cwd() + "/public/" + file);
1244
1224
  bundleSize += fs.statSync(process.cwd() + "/public/" + file).size;
1245
1225
  await writer(process.cwd() + "/dist/public/" + file, data);
1246
1226
  })
@@ -1273,7 +1253,6 @@ async function Build() {
1273
1253
  }
1274
1254
 
1275
1255
  globalThis.isBuilding = false
1276
- console.log(`\nTotal bundle size: ${Math.round(bundleSize / 1000)}kb`)
1277
1256
 
1278
1257
  bundleSize = 0;
1279
1258
 
@@ -1381,7 +1360,7 @@ switch (true) {
1381
1360
  globalThis.devMode = true
1382
1361
  globalThis.isProduction = false
1383
1362
  console.log(`
1384
- Vader.js v1.3.3
1363
+ Vader.js v${fs.readFileSync(process.cwd() + '/node_modules/vaderjs/package.json', 'utf8').split('"version": "')[1].split('"')[0]}
1385
1364
  - Watching for changes in ./pages
1386
1365
  - Watching for changes in ./src
1387
1366
  - Watching for changes in ./public
@@ -1403,6 +1382,7 @@ Vader.js v1.3.3
1403
1382
  })
1404
1383
  }
1405
1384
 
1385
+ console.log('\nRebuilding...')
1406
1386
  globalThis.isBuilding = true
1407
1387
  Build()
1408
1388
  }