vaderjs 1.3.3-7b27417dd2e1 → 1.3.3-7bn28b17d42e1
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.
- package/README.md +2 -2
- package/package.json +1 -1
- package/runtime/vader.js +1 -1
- package/vader.js +176 -124
package/README.md
CHANGED
|
@@ -81,7 +81,7 @@ export default function(req, res){
|
|
|
81
81
|
|
|
82
82
|
return <>
|
|
83
83
|
<h1>${count}</h1>
|
|
84
|
-
<button onClick={(event)=>{setCount(count
|
|
84
|
+
<button onClick={(event)=>{setCount(++count)}}>
|
|
85
85
|
</>
|
|
86
86
|
}
|
|
87
87
|
|
|
@@ -130,7 +130,7 @@ export function Layout({title, keywords, description, children}){
|
|
|
130
130
|
|
|
131
131
|
export default function (req, res){
|
|
132
132
|
return <>
|
|
133
|
-
<Layout
|
|
133
|
+
<Layout ${{title:'home', description:'home page', keywords:'vader.js', logo:''}}>
|
|
134
134
|
<h1> Hello World</h1>
|
|
135
135
|
</Layout>
|
|
136
136
|
</>
|
package/package.json
CHANGED
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=[],lastRoute=null,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 isClass(e){return"function"==typeof e&&/^class\s/.test(Function.prototype.toString.call(e))}let r=isClass(e)?new e(t):null;if(!e)throw new Error("Component must be defined");let n=[],i=new Component(t);if(isClass(e))r.props=t||{},r.props.children=s.join("")||[],r.props.children=s.join(""),r.parentNode=this,r.type="class ",r.request=this.request,r.response=this.response,r.key=r.props.key?r.props.key:Math.random(),i=r;else{e.toString();i.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:i.key?i.key:Math.random(),isUnique:!!i.key,render:()=>e.apply(i,[t]),request:this.request,isChild:!0,response:this.response,params:this.request.params,queryParams:this.request.query,reset:i.reset.bind(i),onMount:i.onMount.bind(i),useState:null,router:{use:i.router.use.bind(i)},bindMount:i.bindMount.bind(i),memoize:i.memoize.bind(i),createComponent:i.createComponent.bind(i),isChild:!1,useState:i.useState.bind(i),parseStyle:i.parseStyle.bind(i),bind:i.bind.bind(i),useRef:i.useRef.bind(i),request:this.request,response:this.response,useReducer:i.useReducer.bind(i),hydrate:i.hydrate.bind(i),onUnmount:i.onUnmount.bind(i),type:"function",parentNoe:this,props:{...t,children:s.join("")||[]}};i.render=r.render,i=r,i.props.children=s.join("")||[]}return this.components[i.key]||(this.components[i.key]=i),!this.children.includes(i)&&this.children.push(i),this.components[i.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 n=e[r],i=t[r];if(n&&i&&n.childNodes.length>0&&i.childNodes.length>0){switch(!0){case n.attributes&&i.attributes&&n.attributes.length!==i.attributes.length:s.push({type:"attributeSwap",old:n,new:i});break;case!n.isEqualNode(i)&&n.nodeName===i.nodeName&&n.textContent!==i.textContent:s.push({type:"replace",old:n,new:i})}let e=this.domDifference(Array.from(n.childNodes),Array.from(i.childNodes));return s.push(...e),s}n.isEqualNode(i)||n.nodeName!==i.nodeName||n.textContent===i.textContent?!n&&i&&s.push({type:"add",old:n,new:i}):s.push({type:"replace",old:n,new:i})}return s}updateChangedElements(e){e.forEach((e=>{if(e)switch(e.type){case"replace":if(e.old.panrntNode&&"BODY"===e.old.parentNode.nodeName)return;e.old.replaceWith(e.new.cloneNode(!0));break;case"remove":e.old.remove();break;case"attributeSwap":let t=Array.from(e.old.attributes),s=Array.from(e.new.attributes);t.forEach((t=>{e.old.removeAttribute(t.name)})),s.forEach((t=>{e.old.setAttribute(t.name,t.value)}));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));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,...n){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 getValue=()=>this.state[e];let r=getValue();return[getValue(),(t,n)=>{const i=s(r,t)??t;this.state[e]=i,this.hydrate(n),r=getValue()}]}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){switch(super(e),!0){case!e.href:throw new Error("Link href is required");case!e.children:throw new Error("Blank links are not allowed. Please add content to the link :}")}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",this.props.href.includes("https")?`window.open('${this.props.href}', ${this.props.action||"_blank"}).focus()`:`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,n=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",n),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: ${n}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};
|
|
1
|
+
window.Vader={version:"1.3.3"},window.componentRegistry={};let errors={"SyntaxError: Unexpected token '<'":"You forgot to enclose tags in a fragment <></>"},mounts=[],lastRoute=null,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 n=r(e)?new e(t):null;if(!e)throw new Error("Component must be defined");let i=[],o=new Component(t);if(r(e))n.props=t||{},n.props.children=s.join("")||[],n.props.children=s.join(""),n.parentNode=this,n.type="class ",n.request=this.request,n.response=this.response,n.key=n.props.key?n.props.key:Math.random(),o=n;else{e.toString();o.key=e.toString().split('key="')[1]?e.toString().split('key="')[1].split('"')[0]:null,t=t?{...t,...i.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 n=e[r],i=t[r];if(n&&i&&n.childNodes.length>0&&i.childNodes.length>0){switch(!0){case n.attributes&&i.attributes&&n.attributes.length!==i.attributes.length:s.push({type:"attributeSwap",old:n,new:i});break;case!n.isEqualNode(i)&&n.nodeName===i.nodeName&&n.textContent!==i.textContent:s.push({type:"replace",old:n,new:i})}let e=this.domDifference(Array.from(n.childNodes),Array.from(i.childNodes));return s.push(...e),s}n.isEqualNode(i)||n.nodeName!==i.nodeName||n.textContent===i.textContent?!n&&i&&s.push({type:"add",old:n,new:i}):s.push({type:"replace",old:n,new:i})}return s}updateChangedElements(e){e.forEach((e=>{if(e)switch(e.type){case"replace":if(e.old.panrntNode&&"BODY"===e.old.parentNode.nodeName)return;e.old.replaceWith(e.new.cloneNode(!0));break;case"remove":e.old.remove();break;case"attributeSwap":let t=Array.from(e.old.attributes),s=Array.from(e.new.attributes);t.forEach((t=>{e.old.removeAttribute(t.name)})),s.forEach((t=>{e.old.setAttribute(t.name,t.value)}));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));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,...n){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 n=r();return[r(),(t,i)=>{const o=s(n,t)??t;this.state[e]=o,this.hydrate(i),n=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",this.props?.href?.includes("https")||this.props?.href?.includes("http")?`window.open('${this.props.href}', '${this.props.action||"_blank"}').focus()`:`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,n=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",n),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: ${n}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 this.html.setAttribute("lang",this.props.lang?this.props.lang:"en"),window.isServer?(this.html.innerHTML=this.props.children,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"),this.eagerScripts=document.querySelectorAll("script[eager]")}render(){if(!window.isServer&&this.props?.updateOnReload){this.props.children=(new DOMParser).parseFromString(this.props.children,"text/html").head;let e=this.props.children.querySelector("title");e&&e.textContent&&(console.log("title",e.textContent),document.querySelector("title").textContent=e.textContent),this.props.children.querySelectorAll("meta").forEach((e=>{let t=e.getAttribute("name"),s=e.getAttribute("content");t&&s&&document.querySelector(`meta[name="${t}"]`).setAttribute("content",s)})),this.props.children.querySelectorAll("link").forEach((e=>{let t=e.getAttribute("rel"),s=e.getAttribute("href");t&&s&&document.querySelector(`link[rel="${t}"]`).setAttribute("href",s)}))}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
|
@@ -84,7 +84,7 @@ function Compiler(func, file) {
|
|
|
84
84
|
const spreadAttributeRegex = /\s*([a-zA-Z0-9_-]+)\s*(\$\s*=\s*\{\s*\{(?:[^{}]|(?:\{(?:[^{}]|(?:\{[^{}]*\})*)*\})*)*\}\s*\})/gs;
|
|
85
85
|
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
string = parseComponents(string);
|
|
88
88
|
|
|
89
89
|
function extractAttributes(code) {
|
|
90
90
|
// grab $={...} and ={...}
|
|
@@ -117,6 +117,30 @@ function Compiler(func, file) {
|
|
|
117
117
|
let functionAttributes = [];
|
|
118
118
|
let spreadFunctions = [];
|
|
119
119
|
let functionMatch;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* @search - handle attributes for html elements
|
|
123
|
+
* @keywords - attributes, props, html attributes
|
|
124
|
+
*/
|
|
125
|
+
let match;
|
|
126
|
+
while ((match = elementRegex.exec(string)) !== null) {
|
|
127
|
+
let [, element, attributes] = match;
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
let attributesMatch;
|
|
131
|
+
let elementAttributes = {};
|
|
132
|
+
|
|
133
|
+
while ((attributesMatch = attributeRegex.exec(attributes)) !== null) {
|
|
134
|
+
let [, attributeName, attributeValue] = attributesMatch;
|
|
135
|
+
|
|
136
|
+
elementAttributes[attributeName] = attributeValue || null;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
attributesList.push({ element, attributes: elementAttributes });
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
|
|
120
144
|
while ((functionMatch = functionAttributeRegex.exec(code)) !== null) {
|
|
121
145
|
|
|
122
146
|
let [, attributeName, attributeValue] = functionMatch;
|
|
@@ -200,8 +224,9 @@ function Compiler(func, file) {
|
|
|
200
224
|
newvalue = newvalue.replaceAll(/\n/g, ";\n")
|
|
201
225
|
// remove () from newvalue
|
|
202
226
|
newvalue = newvalue.replace(/\(\s*=>/gs, '=>').replace(/\function\s*\([^\)]*\)\s*\{/gs, '{')
|
|
227
|
+
newvalue = newvalue + `\n /**@id=${ref}**/ \n`
|
|
203
228
|
|
|
204
|
-
let bind = isJSXComponent
|
|
229
|
+
let bind = !isJSXComponent && `${attributeName}="\$\{this.bind(function(){${newvalue}}.bind(this), ${isJSXComponent}, "${ref}", "${paramnames ? paramnames.map((e, index) => {
|
|
205
230
|
if (e.length < 1) return ''
|
|
206
231
|
if (e.length > 0) {
|
|
207
232
|
index == 0 ? e : ',' + e
|
|
@@ -209,83 +234,8 @@ function Compiler(func, file) {
|
|
|
209
234
|
return e
|
|
210
235
|
}) : ''}" ${params ? params.split(',').map((e) => e.trim()).filter(Boolean).map((e) => `,${e}`).join('') : ''})}"`
|
|
211
236
|
|
|
212
|
-
string = string.replace(old, bind)
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* @search - handle attributes for html elements
|
|
218
|
-
* @keywords - attributes, props, html attributes
|
|
219
|
-
*/
|
|
220
|
-
let match;
|
|
221
|
-
while ((match = elementRegex.exec(string)) !== null) {
|
|
222
|
-
let [, element, attributes] = match;
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
let attributesMatch;
|
|
226
|
-
let elementAttributes = {};
|
|
227
|
-
|
|
228
|
-
while ((attributesMatch = attributeRegex.exec(attributes)) !== null) {
|
|
229
|
-
let [, attributeName, attributeValue] = attributesMatch;
|
|
230
|
-
|
|
231
|
-
elementAttributes[attributeName] = attributeValue || null;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
attributesList.push({ element, attributes: elementAttributes });
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
let spreadMatch;
|
|
238
|
-
while ((spreadMatch = spreadAttributeRegex.exec(code)) !== null) {
|
|
239
|
-
let [, element, spread] = spreadMatch;
|
|
240
|
-
let isJSXComponent = element.match(/^[A-Z]/) ? true : false;
|
|
241
|
-
if (isJSXComponent) {
|
|
242
|
-
continue;
|
|
237
|
+
string = string.replace(old, bind)
|
|
243
238
|
}
|
|
244
|
-
let old = spread;
|
|
245
|
-
spread = spread.trim().replace(/\s+/g, " ");
|
|
246
|
-
// re,pve $={ and }
|
|
247
|
-
spread = spread.replace(/\s*\$\s*=\s*{\s*{/gs, '')
|
|
248
|
-
|
|
249
|
-
// replace trailing }
|
|
250
|
-
spread = spread.replace(/}}\s*$/, '').replace(/}\s*}$/, '')
|
|
251
|
-
let splitByCommas = spread.split(/,(?![^{}]*})/gs)
|
|
252
|
-
// remove empty strings
|
|
253
|
-
splitByCommas = splitByCommas.filter((e) => e.split(':')[0].trim().length > 0)
|
|
254
|
-
splitByCommas = splitByCommas.map((e, index) => {
|
|
255
|
-
let key = e.split(':')[0].trim()
|
|
256
|
-
switch (true) {
|
|
257
|
-
case e.includes('function') && !e.includes('this.bind') || e && e.includes('=>') && !e.includes('this.bind'):
|
|
258
|
-
let value = e.split(':')[1].trim()
|
|
259
|
-
let ref = Math.random().toString(36).substring(2).split('').filter((e) => !Number(e)).join('');
|
|
260
|
-
value = `this.bind(${value}, false, "${ref}", "")`
|
|
261
|
-
e = `${key}="\${${value}}"`
|
|
262
|
-
break;
|
|
263
|
-
case e.includes('style:'):
|
|
264
|
-
let v2 = e.split('style:')[1].trim().replace(/,$/, '')
|
|
265
|
-
v2 = v2.replace(/,$/, '')
|
|
266
|
-
e = `${key}="\${this.parseStyle(${v2})}"`
|
|
267
|
-
break;
|
|
268
|
-
|
|
269
|
-
default:
|
|
270
|
-
let v = e.split(':')
|
|
271
|
-
key = v[0].trim()
|
|
272
|
-
// remove key from v
|
|
273
|
-
v.shift()
|
|
274
|
-
v = v.join(' ')
|
|
275
|
-
e = `${key}="\${${v}}"`
|
|
276
|
-
|
|
277
|
-
break;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
return e;
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
let newSpread = splitByCommas.join(' ').trim().replace(/,$/, '');
|
|
286
|
-
|
|
287
|
-
// remove trailing }
|
|
288
|
-
string = string.replace(old, newSpread);
|
|
289
239
|
}
|
|
290
240
|
|
|
291
241
|
return attributesList;
|
|
@@ -410,9 +360,15 @@ function Compiler(func, file) {
|
|
|
410
360
|
switch (true) {
|
|
411
361
|
case line.includes("useState") && !line.includes("import"):
|
|
412
362
|
let varType = line.split("[")[0]
|
|
363
|
+
if (!line.split("=")[0].split(",")[1]) {
|
|
364
|
+
throw new Error('You forgot to value selector (useState) ' + ' at ' + `${file}:${string.split(line)[0].split('\n').length}`)
|
|
365
|
+
}
|
|
413
366
|
let key = line.split("=")[0].split(",")[0].trim().split('[')[1];
|
|
414
367
|
|
|
415
|
-
|
|
368
|
+
if (!line.split("=")[0].split(",")[1]) {
|
|
369
|
+
throw new Error('You forgot to add a setter (useState) ' + ' at ' + `${file}:${string.split(line)[0].split('\n').length}`)
|
|
370
|
+
}
|
|
371
|
+
let setKey = line.split("=")[0].split(",")[1].trim().replace("]", "");
|
|
416
372
|
key = key.replace("[", "").replace(",", "");
|
|
417
373
|
let valuestate = line.split("=")[1].split("useState(")[1];
|
|
418
374
|
|
|
@@ -482,49 +438,79 @@ function Compiler(func, file) {
|
|
|
482
438
|
|
|
483
439
|
let name = component.split("<")[1].split(">")[0].split(" ")[0].replace("/", "");
|
|
484
440
|
let componentAttributes = component.split("<")[1].split(">")[0].split(" ").join(" ").replace(name, "").trim();
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
const dynamicAttributesRegex = /([a-zA-Z0-9_-]+)\s*=\s*("(?:[^"\\]*(?:\\.[^"\\]*)*)"|'(?:[^'\\]*(?:\\.[^'\\]*)*)'|\{(?:[^{}]|(?:\{(?:[^{}]|(?:\{.*.*\})*)*\})*)*\}|(?:\([^)]*\)|()\s*=>\s*(?:\{.*\})?|\{[^}]*\})|\[[^\]]*\])/gs;
|
|
441
|
+
let props = component.includes('/>') ? component.split(`<`)[1].split('/>')[0] : component.split(`<`)[1].split(`>`)[0]
|
|
442
|
+
props = props.replaceAll(/\s+/g, " ").trim()
|
|
443
|
+
props = props.replace(name, '').trim()
|
|
444
|
+
component = component.replace(componentAttributes, '')
|
|
445
|
+
// or spread attributes {...{}, ...{}}
|
|
446
|
+
const dynamicAttributesRegex = /([a-zA-Z0-9_-]+)\s*=\s*("(?:[^"\\]*(?:\\.[^"\\]*)*)"|'(?:[^'\\]*(?:\\.[^'\\]*)*)'|\{(?:[^{}]|(?:\{(?:[^{}]|(?:\{(.*.*?)\})*)*\})*)*\}|(?:\([^)]*\)|()\s*=>\s*(?:\{.*.*\})?|\{.*\})|\[[^\]]*\])|\${\{.*\}}/gs;
|
|
492
447
|
|
|
493
448
|
const attributeObject = {};
|
|
449
|
+
let propstring = ''
|
|
450
|
+
let $_ternaryprops = []
|
|
451
|
+
let spreadRegex = /\$\{.*\}/gs;
|
|
452
|
+
let spreadMatch;
|
|
453
|
+
let hasSpread = false;
|
|
454
|
+
while ((spreadMatch = spreadRegex.exec(props)) !== null) {
|
|
455
|
+
let spread = spreadMatch[0].trim().replace(/\s+/g, " ");
|
|
456
|
+
if (!spread.includes('...')) {
|
|
457
|
+
continue
|
|
458
|
+
}
|
|
459
|
+
let old = spread;
|
|
460
|
+
spread = spread.trim().replace(/\s+/g, " ");
|
|
461
|
+
//${...( loaded ? { title: "Malik Whitten - Blog" } : { title: "Loading" } )} -> ...( loaded ? { title: "Malik Whitten - Blog" } : { title: "Loading" } )
|
|
494
462
|
|
|
463
|
+
let spreadContent = spread.match(/\$\{.*\}/gs) ? spread.match(/\$\{.*.*\}/gs)[0] : null
|
|
464
|
+
spreadContent = spread.split('${')[1]
|
|
495
465
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
let currentProps = []
|
|
466
|
+
spreadContent = spread.replace(/\${/, '')
|
|
467
|
+
spreadContent = spreadContent.replaceAll(/\s+/g, " ").trim()
|
|
468
|
+
spreadContent = spreadContent.replace(')}', ')').replace('}}', '}')
|
|
500
469
|
|
|
501
|
-
|
|
470
|
+
propstring += spreadContent + ','
|
|
471
|
+
hasSpread = true
|
|
472
|
+
|
|
473
|
+
}
|
|
502
474
|
|
|
503
475
|
let match;
|
|
504
|
-
|
|
476
|
+
|
|
505
477
|
// props right now is just a string with all of them on one line and a space between each
|
|
506
478
|
while ((match = dynamicAttributesRegex.exec(props)) !== null) {
|
|
507
479
|
let str = match[0].trim().replace(/\s+/g, " ");
|
|
508
480
|
if (!str.includes('=')) {
|
|
509
481
|
continue
|
|
510
482
|
}
|
|
483
|
+
|
|
484
|
+
if (hasSpread) {
|
|
485
|
+
|
|
486
|
+
console.log('\x1b[33m', '🚨 Code confliction detected', '\x1b[0m')
|
|
487
|
+
let line = string.split(match[0])[0].split('\n').length
|
|
488
|
+
try {
|
|
489
|
+
throw new Error('You cannot use spread props and named props\n on the same component at ' + match[0] + ' at ' + `${file}:${line}`)
|
|
490
|
+
} catch (error) {
|
|
491
|
+
console.error(error)
|
|
492
|
+
process.exit(1)
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
str = str.replaceAll(/\s+/g, " ")
|
|
511
497
|
str = str.split('=')
|
|
512
498
|
let key = str[0].trim()
|
|
513
|
-
let value = str[
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
// wrap in respective quotes
|
|
517
|
-
value = value + value[0]
|
|
518
|
-
}
|
|
499
|
+
let value = str.slice(1).join('=').trim().match(/\{.*\}/gs) ? str.slice(1).join('=').trim().match(/\{.*\}/gs)[0] : str.slice(1).join('=').trim();
|
|
500
|
+
|
|
501
|
+
|
|
519
502
|
let isObject = value.startsWith('{{') && value.endsWith('}}')
|
|
520
503
|
if (isObject) {
|
|
521
504
|
value = value.split('{{')[1].split('}}')[0].trim()
|
|
522
505
|
value = `{${value}}`
|
|
506
|
+
propstring += `${key}:${value},`
|
|
523
507
|
} else {
|
|
524
508
|
// remove starting { and ending } using regex
|
|
525
509
|
value = value.replace(/^{/, '').replace(/}$/, '')
|
|
510
|
+
propstring += `${key}:${value},`
|
|
526
511
|
}
|
|
527
|
-
propstring
|
|
512
|
+
propstring = propstring.replaceAll(/\s+/g, " ").trim()
|
|
513
|
+
|
|
528
514
|
}
|
|
529
515
|
component = component.replaceAll(/\s+/g, " ");
|
|
530
516
|
|
|
@@ -592,7 +578,7 @@ function Compiler(func, file) {
|
|
|
592
578
|
let replaceMents = [];
|
|
593
579
|
|
|
594
580
|
|
|
595
|
-
if(imports){
|
|
581
|
+
if (imports) {
|
|
596
582
|
for (let match of imports) {
|
|
597
583
|
let path = match.split('from')[1].trim().replace(/'/g, '').replace(/"/g, '').trim()
|
|
598
584
|
switch (true) {
|
|
@@ -602,11 +588,11 @@ function Compiler(func, file) {
|
|
|
602
588
|
if (!fs.existsSync(process.cwd() + componentFolder)) {
|
|
603
589
|
throw new Error('Could not find ' + path + ' at ' + match + ' in file ' + file)
|
|
604
590
|
}
|
|
605
|
-
|
|
591
|
+
|
|
606
592
|
if (!fs.existsSync(process.cwd() + '/dist/src/' + componentFolder.split('/').slice(2).join('/'))) {
|
|
607
593
|
fs.mkdirSync(process.cwd() + '/dist/src/' + componentFolder.split('/').slice(2).join('/'), { recursive: true })
|
|
608
594
|
}
|
|
609
|
-
|
|
595
|
+
|
|
610
596
|
let baseFolder = componentFolder.split('node_modules')[1].split('/')[1]
|
|
611
597
|
let glp = globSync('**/**/**/**.{jsx,js}', {
|
|
612
598
|
cwd: process.cwd() + '/node_modules/' + baseFolder + '/',
|
|
@@ -617,7 +603,7 @@ function Compiler(func, file) {
|
|
|
617
603
|
let text = fs.readFileSync(file, "utf8");
|
|
618
604
|
if (!file.endsWith('.js') && file.endsWith('.jsx')) {
|
|
619
605
|
text = Compiler(text, file);
|
|
620
|
-
|
|
606
|
+
|
|
621
607
|
}
|
|
622
608
|
let dest = file.split('node_modules')[1]
|
|
623
609
|
dest = dest.split(baseFolder)[1]
|
|
@@ -629,8 +615,8 @@ function Compiler(func, file) {
|
|
|
629
615
|
replaceMents.push({ match: oldImportstring, replace: newImport })
|
|
630
616
|
console.log(`📦 imported Node Package ${baseFolder} `)
|
|
631
617
|
}
|
|
632
|
-
|
|
633
|
-
|
|
618
|
+
|
|
619
|
+
|
|
634
620
|
break;
|
|
635
621
|
default:
|
|
636
622
|
break;
|
|
@@ -655,7 +641,7 @@ function Compiler(func, file) {
|
|
|
655
641
|
string = string.replaceAll(/\$\{\/\*.*\*\/\}/gs, "");
|
|
656
642
|
string = string.replaceAll("<>", "`").replaceAll("</>", "`");
|
|
657
643
|
string = string.replaceAll(".jsx", ".js");
|
|
658
|
-
|
|
644
|
+
|
|
659
645
|
|
|
660
646
|
string = string
|
|
661
647
|
.replaceAll("className", "class")
|
|
@@ -821,15 +807,17 @@ function Compiler(func, file) {
|
|
|
821
807
|
|
|
822
808
|
globalThis.isBuilding = false
|
|
823
809
|
globalThis.isWriting = null
|
|
824
|
-
|
|
825
|
-
ignore: ["node_modules/**/*", "dist/**/*"],
|
|
826
|
-
cwd: process.cwd() + '/pages/',
|
|
827
|
-
absolute: true,
|
|
828
|
-
recursive: true
|
|
829
|
-
});
|
|
810
|
+
|
|
830
811
|
let hasRendered = []
|
|
831
812
|
|
|
832
813
|
async function Build() {
|
|
814
|
+
const glb = await glob("**/**/**/**.{jsx,js}", {
|
|
815
|
+
ignore: ["node_modules/**/*", "dist/**/*"],
|
|
816
|
+
cwd: process.cwd() + '/pages/',
|
|
817
|
+
absolute: true,
|
|
818
|
+
recursive: true
|
|
819
|
+
});
|
|
820
|
+
|
|
833
821
|
globalThis.isBuilding = true
|
|
834
822
|
console.log(globalThis.isProduction ? 'Creating Optimized Production Build\n' : '')
|
|
835
823
|
let str = `Page \t\t\t\t Size\n`
|
|
@@ -907,7 +895,7 @@ async function Build() {
|
|
|
907
895
|
page.on('crash', () => {
|
|
908
896
|
console.error(`Render process crashed for ${route.url}`)
|
|
909
897
|
});
|
|
910
|
-
|
|
898
|
+
|
|
911
899
|
await page.goto(`http://localhost:${port}${route.url}`, { waitUntil: 'networkidle2' });
|
|
912
900
|
|
|
913
901
|
page.evaluate(() => {
|
|
@@ -952,8 +940,7 @@ async function Build() {
|
|
|
952
940
|
})
|
|
953
941
|
hasRendered = []
|
|
954
942
|
globalThis.isBuilding = false
|
|
955
|
-
|
|
956
|
-
bundleSize = 0
|
|
943
|
+
|
|
957
944
|
}
|
|
958
945
|
|
|
959
946
|
if (hasRendered.length === routes.length) {
|
|
@@ -969,6 +956,7 @@ async function Build() {
|
|
|
969
956
|
}
|
|
970
957
|
}
|
|
971
958
|
globalThis.routes = []
|
|
959
|
+
globalThis.paramRoutes = []
|
|
972
960
|
|
|
973
961
|
for await (let file of glb) {
|
|
974
962
|
// Normalize file paths
|
|
@@ -1067,10 +1055,46 @@ async function Build() {
|
|
|
1067
1055
|
}
|
|
1068
1056
|
|
|
1069
1057
|
|
|
1070
|
-
if (
|
|
1058
|
+
if (obj.url.includes(':') && !paramRoutes.includes(obj.url)) {
|
|
1059
|
+
globalThis.paramRoutes.push({ fileName: fileName, url: obj.url, html: '/' + (isBasePath ? 'index.html' : `${obj.url}/` + 'index.html') })
|
|
1060
|
+
} else {
|
|
1061
|
+
|
|
1071
1062
|
globalThis.routes.push({ fileName: fileName, url: obj.url, html: '/' + (isBasePath ? 'index.html' : `${obj.url}/` + 'index.html') })
|
|
1072
1063
|
}
|
|
1073
1064
|
|
|
1065
|
+
// check if route has a index.html file
|
|
1066
|
+
|
|
1067
|
+
if (!fs.existsSync(process.cwd() + '/dist/' + (isBasePath ? 'index.html' : `${obj.url}/` + 'index.html'))
|
|
1068
|
+
&& !obj.url.includes(':') && !globalThis.isProduction
|
|
1069
|
+
) {
|
|
1070
|
+
let document = `<!DOCTYPE html>
|
|
1071
|
+
<html lang="en">
|
|
1072
|
+
<head>
|
|
1073
|
+
<meta charset="UTF-8">
|
|
1074
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
1075
|
+
<title>${obj.url}</title>
|
|
1076
|
+
<script>
|
|
1077
|
+
window.routes = JSON.parse('${JSON.stringify(globalThis.routes)}')
|
|
1078
|
+
</script>
|
|
1079
|
+
<script type="module">
|
|
1080
|
+
import VaderRouter from '/router.js'
|
|
1081
|
+
const router = new VaderRouter('${obj.url}')
|
|
1082
|
+
router.get('${obj.url}', async (req, res) => {
|
|
1083
|
+
let module = await import('/${obj.url === '/' ? 'index.js' : obj.url + '.js'}')
|
|
1084
|
+
if(Object.keys(module).includes('$prerender') && !module.$prerender){
|
|
1085
|
+
document.head.setAttribute('prerender', 'false')
|
|
1086
|
+
}
|
|
1087
|
+
res.render(module, req, res, module.$metadata)
|
|
1088
|
+
})
|
|
1089
|
+
router.listen(3000)
|
|
1090
|
+
</script>
|
|
1091
|
+
</head>
|
|
1092
|
+
<body>
|
|
1093
|
+
<div id="root"></div>
|
|
1094
|
+
</body>
|
|
1095
|
+
</html>`
|
|
1096
|
+
writer(process.cwd() + '/dist/' + (isBasePath ? 'index.html' : `${obj.url}/` + 'index.html'), document)
|
|
1097
|
+
}
|
|
1074
1098
|
|
|
1075
1099
|
let stats = {
|
|
1076
1100
|
route: obj.url.padEnd(30),
|
|
@@ -1088,7 +1112,8 @@ async function Build() {
|
|
|
1088
1112
|
|
|
1089
1113
|
globalThis.routeDocuments = []
|
|
1090
1114
|
globalThis.routes.map((route) => {
|
|
1091
|
-
let equalparamroute = globalThis.
|
|
1115
|
+
let equalparamroute = globalThis.paramRoutes.map((e) => {
|
|
1116
|
+
console
|
|
1092
1117
|
if (e.url.includes(':')) {
|
|
1093
1118
|
let url = e.url.split('/:')[0]
|
|
1094
1119
|
if (url && route.url === url) {
|
|
@@ -1163,11 +1188,14 @@ async function Build() {
|
|
|
1163
1188
|
`;
|
|
1164
1189
|
globalThis.routeDocuments.push({ url: route.url, document: document })
|
|
1165
1190
|
})
|
|
1166
|
-
|
|
1167
|
-
if(globalThis.devMode && !globalThis.oneAndDone){
|
|
1191
|
+
|
|
1192
|
+
if (globalThis.devMode && !globalThis.oneAndDone) {
|
|
1168
1193
|
ssg(globalThis.routes)
|
|
1169
1194
|
globalThis.oneAndDone = true
|
|
1170
|
-
console.log(
|
|
1195
|
+
console.log(`In Development Mode, Prerendering ${globalThis.routes.length} pages... Once`)
|
|
1196
|
+
}
|
|
1197
|
+
else if (globalThis.isProduction) {
|
|
1198
|
+
ssg(globalThis.routes)
|
|
1171
1199
|
}
|
|
1172
1200
|
|
|
1173
1201
|
|
|
@@ -1252,12 +1280,36 @@ async function Build() {
|
|
|
1252
1280
|
await writer(process.cwd() + "/dist/" + file, data);
|
|
1253
1281
|
});
|
|
1254
1282
|
|
|
1283
|
+
|
|
1255
1284
|
}
|
|
1256
1285
|
|
|
1257
1286
|
globalThis.isBuilding = false
|
|
1258
1287
|
|
|
1288
|
+
globalThis.isProduction ? console.log(`Total Bundle Size: ${Math.round(bundleSize / 1000)}kb`) : null
|
|
1259
1289
|
bundleSize = 0;
|
|
1290
|
+
if (!globalThis.isBuilding) {
|
|
1291
|
+
let folders = fs.readdirSync(process.cwd() + '/dist/', { withFileTypes: true })
|
|
1260
1292
|
|
|
1293
|
+
folders.forEach((folder) => {
|
|
1294
|
+
// exclude files
|
|
1295
|
+
if (folder.name.includes('src') || folder.name.includes('public') || folder.name.includes('pages')
|
|
1296
|
+
|| !folder.isDirectory()
|
|
1297
|
+
) {
|
|
1298
|
+
return
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
let existsInPages = fs.existsSync(process.cwd() + '/pages/' + folder.name)
|
|
1302
|
+
|
|
1303
|
+
if (existsInPages) {
|
|
1304
|
+
return
|
|
1305
|
+
}
|
|
1306
|
+
fs.rm(process.cwd() + '/dist/' + folder.name, { recursive: true }, (err) => {
|
|
1307
|
+
if (err) {
|
|
1308
|
+
throw err
|
|
1309
|
+
}
|
|
1310
|
+
})
|
|
1311
|
+
})
|
|
1312
|
+
}
|
|
1261
1313
|
return true
|
|
1262
1314
|
}
|
|
1263
1315
|
const s = (port) => {
|
|
@@ -1267,7 +1319,7 @@ const s = (port) => {
|
|
|
1267
1319
|
const validExtensions = ['.js', '.css', '.mjs', '.cjs', '.html', '.json', '.png', '.jpg', '.jpeg', '.gif', '.svg', '.mp4', '.webm', '.ogg', '.map']
|
|
1268
1320
|
|
|
1269
1321
|
if (!validExtensions.some(ext => req.url.endsWith(ext))) {
|
|
1270
|
-
req.url = req.url
|
|
1322
|
+
req.url = req.url + '/'
|
|
1271
1323
|
req.url = path.join(process.cwd(), 'dist', req.url, 'index.html');
|
|
1272
1324
|
} else {
|
|
1273
1325
|
req.url = path.join(process.cwd(), 'dist', req.url);
|
|
@@ -1345,7 +1397,7 @@ const s = (port) => {
|
|
|
1345
1397
|
return 'application/octet-stream';
|
|
1346
1398
|
}
|
|
1347
1399
|
}
|
|
1348
|
-
|
|
1400
|
+
|
|
1349
1401
|
server.listen(port, () => {
|
|
1350
1402
|
console.log(`Server is running on port ${port}`);
|
|
1351
1403
|
globalThis.ws = ws
|
|
@@ -1360,7 +1412,7 @@ switch (true) {
|
|
|
1360
1412
|
|
|
1361
1413
|
globalThis.devMode = true
|
|
1362
1414
|
globalThis.isProduction = false
|
|
1363
|
-
|
|
1415
|
+
|
|
1364
1416
|
let p = process.env.PORT || config.port || process.argv.includes('-p') ? process.argv[process.argv.indexOf('-p') + 1] : 3000
|
|
1365
1417
|
globalThis.oneAndDone = false
|
|
1366
1418
|
console.log(`
|
|
@@ -1392,7 +1444,7 @@ Vader.js v${fs.readFileSync(process.cwd() + '/node_modules/vaderjs/package.json'
|
|
|
1392
1444
|
Build()
|
|
1393
1445
|
}
|
|
1394
1446
|
}).on('error', (err) => console.log(err))
|
|
1395
|
-
})
|
|
1447
|
+
})
|
|
1396
1448
|
s(p)
|
|
1397
1449
|
|
|
1398
1450
|
globalThis.listen = true;
|