vaderjs 1.3.3-alpha-151 → 1.3.3-alpha-152
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/package.json +1 -1
- package/runtime/vader.js +1 -1
- package/vader.js +235 -255
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=[],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.state={},this.key=null,this.components={},this.mounted=!1,this.checkIFMounted(),this.memoizes=[],this.functions=[],this.children=[],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=new Component(t);if(r(e))n.props=t||{},n.props.children=s.join("")||[],n.props.children=s.join(""),n.parentNode=this,n.request=this.request,n.response=this.response,n.key=n.props.key?n.props.key:Math.random(),i=n;else{e.toString();i.key=e.toString().split('key="')[1]?e.toString().split('key="')[1].split('"')[0]:null;let r=[];Object.keys(t).forEach((e=>{e.startsWith("$props")&&(r.push(t[e]),delete t[e])})),t=t?{...t,...r.reduce(((e,t)=>({...e,...t})),{}),children:s.join("")||[]}:{children:s.join("")||[]};let n={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),parentNoe:this,props:{...t,children:s.join("")||[]}};i.render=n.render,i=n,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];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(">,",">")),`<span key="${e.key}" >${s}</span>`}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];n&&i&&!n.isEqualNode(i)&&s.push({type:"replace",old:n,new:i.cloneNode(!0)})}return s}updateChangedElements(e){e.forEach((e=>{switch(e.type){case"replace":e.old.parentNode.replaceChild(e.new,e.old);break;case"remove":e.old.remove();break;case"add":e.old.appendChild(e.new.cloneNode(!0))}}))}hydrate(e){if(e){(new DOMParser).parseFromString(this.render(),"text/html").body.querySelector(`[ref="${e}"]`),document.querySelector(`[ref="${e}"]`)}else{let e=this.key?document.querySelector(`[key="${this.key}"]`):null,t=(new DOMParser).parseFromString(this.render(),"text/html").body;if(t=document.createElement("div").appendChild(t),!e&&(e=document.querySelector(`[key="${t.attributes?.key?.value||null}"]`)),!e)return void console.error('Hydration failed, component not found got ensure you have set key="a value" on the component or this.key inside of function or render method body');t.querySelectorAll("*").forEach((e=>{e.hasAttribute("key")&&e.innerHTML!==document.querySelector(`[key="${e.attributes.key.value}"]`).innerHTML&&document.querySelector(`[key="${e.attributes.key.value}"]`).replaceWith(e)}))}}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){s=s+this.key||2022;let i={},o=(r=r.replace(/,,/g,",")).replaceAll(",,",",");for(var h in n){let e=n[h];i[o.split(",")[h]]=e}r=r.replace(",,",",");return this.functions.find((e=>e.ref===s))||document.addEventListener(`$dispatch_#id=${s}`,(t=>{let{name:r,event:n}=t.detail;if(r===s){let t=this.functions.find((e=>e.ref===s)).params;Object.keys(t).forEach((e=>{t[e]instanceof CustomEvent&&delete t[e],void 0===t[e]?delete t[e]:t[e]}));let r=n;console.log(r),e(n.detail.event)}})),window.callFunction=(e,t)=>{document.dispatchEvent(new CustomEvent(`$dispatch_#id=${e}`,{detail:{name:e,params:null,event:t}}))},!this.functions.find((e=>e.ref===s))&&this.functions.push({ref:s,params:i}),t?e:`((event)=>{event.target.ev = event; callFunction('${s}', event.target.ev)})(event)`}useState(e,t){this.state[e]||(this.state[e]=t);let s=()=>this.state[e],r=s();return[r,(t,n)=>{console.log(t),this.state[e]=t,r=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)=>{states[e]||(states[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()}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.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,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=await fetch(t).then((e=>e.text()));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(){this.state={},this.key=null,this.components={},this.mounted=!1,this.checkIFMounted(),this.memoizes=[],this.functions=[],this.children=[],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=new Component(t);if(r(e))n.props=t||{},n.props.children=s.join("")||[],n.props.children=s.join(""),n.parentNode=this,n.request=this.request,n.response=this.response,n.key=n.props.key?n.props.key:Math.random(),i=n;else{e.toString();i.key=e.toString().split('key="')[1]?e.toString().split('key="')[1].split('"')[0]:null;let r=[];Object.keys(t).forEach((e=>{e.startsWith("$props")&&(r.push(t[e]),delete t[e])})),t=t?{...t,...r.reduce(((e,t)=>({...e,...t})),{}),children:s.join("")||[]}:{children:s.join("")||[]};let n={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),parentNoe:this,props:{...t,children:s.join("")||[]}};i.render=n.render,i=n,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];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(">,",">")),`<span key="${e.key}" >${s}</span>`}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];n&&i&&!n.isEqualNode(i)&&s.push({type:"replace",old:n,new:i.cloneNode(!0)})}return s}updateChangedElements(e){e.forEach((e=>{switch(e.type){case"replace":e.old.parentNode.replaceChild(e.new,e.old);break;case"remove":e.old.remove();break;case"add":e.old.appendChild(e.new.cloneNode(!0))}}))}hydrate(e){if(e){console.log("hydrating");let t=(new DOMParser).parseFromString(this.render(),"text/html").body.querySelector(`[ref="${e}"]`);document.querySelector(`[ref="${e}"]`);document.querySelector(`[ref="${e}"]`).replaceWith(t)}else{let e=this.key?document.querySelector(`[key="${this.key}"]`):null;e&&(e.innerHTML=this.render())}}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)=>{console.log("called");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)`}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()}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.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,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=await fetch(t).then((e=>e.text()));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
|
@@ -4,10 +4,10 @@ import { glob, globSync, globStream, globStreamSync, Glob, } from 'glob'
|
|
|
4
4
|
import puppeteer from 'puppeteer';
|
|
5
5
|
import http from 'http'
|
|
6
6
|
import { WebSocketServer } from 'ws'
|
|
7
|
-
import { watch } from "fs";
|
|
7
|
+
import { watch } from "fs";
|
|
8
8
|
import path from 'path'
|
|
9
|
-
let config =
|
|
10
|
-
|
|
9
|
+
let config = await import('file://' + process.cwd() + '/vader.config.js').then((e) => e.default || e)
|
|
10
|
+
|
|
11
11
|
|
|
12
12
|
let start = Date.now()
|
|
13
13
|
let bundleSize = 0;
|
|
@@ -31,7 +31,7 @@ if (typeof process.env.isCloudflare !== "undefined" || !fs.existsSync(process.cw
|
|
|
31
31
|
fs.writeFileSync(process.cwd() + "/dist/index.html", htmlFile)
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
|
|
35
35
|
|
|
36
36
|
function Compiler(func, file) {
|
|
37
37
|
let string = func;
|
|
@@ -108,6 +108,7 @@ function Compiler(func, file) {
|
|
|
108
108
|
let functionMatch;
|
|
109
109
|
while ((functionMatch = functionAttributeRegex.exec(code)) !== null) {
|
|
110
110
|
let [, attributeName, attributeValue] = functionMatch;
|
|
111
|
+
|
|
111
112
|
let attribute = {};
|
|
112
113
|
|
|
113
114
|
if (attributeValue && attributeValue.includes("=>") || attributeValue && attributeValue.includes("function")) {
|
|
@@ -143,7 +144,7 @@ function Compiler(func, file) {
|
|
|
143
144
|
.split(" ")[0];
|
|
144
145
|
isJSXComponent = elementTag.match(/^[A-Z]/) ? true : false;
|
|
145
146
|
}
|
|
146
|
-
});
|
|
147
|
+
});
|
|
147
148
|
// add ; after newlines
|
|
148
149
|
|
|
149
150
|
|
|
@@ -193,10 +194,10 @@ function Compiler(func, file) {
|
|
|
193
194
|
paramnames = paramnames ? paramnames.filter((e) => e.length > 0) : null
|
|
194
195
|
// remove comments
|
|
195
196
|
paramnames = paramnames ? paramnames.map((e) => e.match(/\/\*.*\*\//gs) ? e.replace(e.match(/\/\*.*\*\//gs)[0], "") : e) : null
|
|
196
|
-
|
|
197
|
+
|
|
197
198
|
// add ; after newlines
|
|
198
199
|
newvalue = newvalue.replaceAll(/\n/g, ";\n")
|
|
199
|
-
|
|
200
|
+
|
|
200
201
|
let bind = isJSXComponent ? `${attributeName}='function(${params}){${newvalue}}'` : `${attributeName}="\$\{this.bind(function(){${newvalue}}.bind(this), ${isJSXComponent}, "${ref}", "${paramnames ? paramnames.map((e, index) => {
|
|
201
202
|
if (e.length < 1) return ''
|
|
202
203
|
if (e.length > 0) {
|
|
@@ -204,7 +205,7 @@ function Compiler(func, file) {
|
|
|
204
205
|
}
|
|
205
206
|
return e
|
|
206
207
|
}) : ''}" ${params ? params.split(',').map((e) => e.trim()).filter(Boolean).map((e) => `,${e}`).join('') : ''})}"`
|
|
207
|
-
|
|
208
|
+
|
|
208
209
|
string = string.replace(old, bind);
|
|
209
210
|
}
|
|
210
211
|
}
|
|
@@ -230,15 +231,21 @@ function Compiler(func, file) {
|
|
|
230
231
|
|
|
231
232
|
function extractOuterReturn(code) {
|
|
232
233
|
// match return [...]
|
|
233
|
-
let returns = code.match(/return\s
|
|
234
|
+
let returns = code.match(/return\s*\<>.*\<\/>|return\s*\(.*\)/gs);
|
|
234
235
|
|
|
235
236
|
return returns || [];
|
|
236
237
|
}
|
|
237
|
-
// throw error if return is not wrapped in <></>
|
|
238
|
-
if (string.match(/return\s
|
|
238
|
+
// throw error if return is not wrapped in <></> or
|
|
239
|
+
if (string.match(/return\s*\<>|return\s*\(.*\)/gs) && !string.match(/return\s*\<>.*\<\/>|return\s*\(.*\)/gs)
|
|
239
240
|
|| string.match(/return\s*\<[a-zA-Z0-9_-]+.*>/gs)
|
|
240
241
|
) {
|
|
241
|
-
|
|
242
|
+
|
|
243
|
+
try {
|
|
244
|
+
throw new SyntaxError("You forgot to enclose jsx in a fragment return <> jsx html </> or return (<> jsx html </>) at line " + string.split(/return\s*\<[a-zA-Z0-9_-]+.*>/gs)[0].split('\n').length + ' in file ' + file)
|
|
245
|
+
} catch (error) {
|
|
246
|
+
console.error(error)
|
|
247
|
+
process.exit(1)
|
|
248
|
+
}
|
|
242
249
|
}
|
|
243
250
|
|
|
244
251
|
let outerReturn = extractOuterReturn(string);
|
|
@@ -250,16 +257,20 @@ function Compiler(func, file) {
|
|
|
250
257
|
|
|
251
258
|
for (let i = 0; i < lines.length; i++) {
|
|
252
259
|
let line = lines[i];
|
|
253
|
-
if (line.match(/return\s
|
|
260
|
+
if (line.match(/return\s*\<>|return\s*\(/gs)) {
|
|
254
261
|
continue;
|
|
255
262
|
}
|
|
256
263
|
contents += line + "\n";
|
|
257
264
|
}
|
|
265
|
+
let usesBraces = returnStatement.match(/return\s*\(/gs) ? true : false;
|
|
258
266
|
|
|
259
|
-
// Remove trailing ']'
|
|
260
|
-
contents = contents.trim().replace(/\]$/, "");
|
|
261
|
-
updatedContents = contents;
|
|
262
267
|
let attributes = extractAttributes(contents);
|
|
268
|
+
// Remove trailing ']' or trailing )
|
|
269
|
+
contents = contents.trim().replace(/\]$/, "")
|
|
270
|
+
contents = contents.replace(/\)$/, "");
|
|
271
|
+
usesBraces ? !contents.includes('<>') ? contents = `<>${contents}</>` : null : null
|
|
272
|
+
updatedContents = contents;
|
|
273
|
+
|
|
263
274
|
|
|
264
275
|
let newAttributes = [];
|
|
265
276
|
let oldAttributes = [];
|
|
@@ -283,6 +294,7 @@ function Compiler(func, file) {
|
|
|
283
294
|
? value = `{this.parseStyle({${value.split('{{')[1].split('}}')[0]}})}` : null
|
|
284
295
|
|
|
285
296
|
|
|
297
|
+
|
|
286
298
|
value = `="\$${value}",`;
|
|
287
299
|
string = string.replace(oldvalue, value);
|
|
288
300
|
|
|
@@ -294,34 +306,13 @@ function Compiler(func, file) {
|
|
|
294
306
|
|
|
295
307
|
}
|
|
296
308
|
} else if (value && value.new) {
|
|
297
|
-
string = string.replace(
|
|
309
|
+
string = string.replace(oldvalue, value.new);
|
|
298
310
|
}
|
|
299
311
|
}
|
|
300
312
|
});
|
|
301
313
|
});
|
|
302
314
|
|
|
303
|
-
let retursnString = [];
|
|
304
|
-
let outerReturnString = extractOuterReturn(string);
|
|
305
|
-
|
|
306
|
-
outerReturnString.forEach((returnStatement) => {
|
|
307
|
-
let lines = returnStatement.split("\n");
|
|
308
|
-
let code = "";
|
|
309
|
-
for (let i = 0; i < lines.length; i++) {
|
|
310
|
-
let line = lines[i];
|
|
311
|
-
|
|
312
|
-
code += line + "\n";
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
code = code.trim().replace(/\<\/\>$/, "");
|
|
316
|
-
retursnString.push(code);
|
|
317
|
-
});
|
|
318
|
-
|
|
319
|
-
retursnString.forEach((returnStatement, index) => {
|
|
320
|
-
let old = outerReturnString[index];
|
|
321
315
|
|
|
322
|
-
let newReturn = `${returnStatement}</>`;
|
|
323
|
-
string = string.replace(old, newReturn);
|
|
324
|
-
});
|
|
325
316
|
|
|
326
317
|
if (comments) {
|
|
327
318
|
comments.forEach((comment) => {
|
|
@@ -410,149 +401,154 @@ function Compiler(func, file) {
|
|
|
410
401
|
let componentMatch = body.match(componentRegex);
|
|
411
402
|
let topComponent = "";
|
|
412
403
|
componentMatch?.forEach(async (component) => {
|
|
413
|
-
|
|
404
|
+
|
|
414
405
|
let [, element, attributes] = component;
|
|
415
|
-
|
|
406
|
+
|
|
416
407
|
|
|
417
408
|
!isChild ? (topComponent = component) : null;
|
|
418
|
-
let before = component;
|
|
409
|
+
let before = component;
|
|
419
410
|
|
|
420
411
|
let myChildrens = [];
|
|
421
412
|
|
|
422
413
|
let name = component.split("<")[1].split(">")[0].split(" ")[0].replace("/", "");
|
|
423
414
|
// some components will have props that have html inside of them we need to only get the props ex: <Header title={<h1>hello</h1>}></Header> -> title={<h1>hello</h1>} // also spread props ex: <Header {...props}></Header> -> {...props} or {...props, title: 'hello'} or {...props, color:{color: 'red'}}
|
|
424
415
|
// grab ...( spread props )
|
|
425
|
-
const dynamicAttributesRegex = /(\w+)(?:="([^"]*)")?(?:='([^']*)')?(?:=\{([^}]*)\})?(?:=\{(.*?)\})?(?:={([^}]*)})?(?:{([^}]*)})?|(\{(?:[^{}]+|\{(?:[^{}]+|\{[^}]*\})*\})*\})/gs;
|
|
416
|
+
const dynamicAttributesRegex = /(\w+)(?:="([^"]*)")?(?:='([^']*)')?(?:=\{([^}]*)\})?(?:=\{(.*?)\})?(?:={([^}]*)})?(?:{([^}]*)})?|(?:{(?:[^{}]+|\{(?:[^{}]+|\{[^}]*\})*\})*\})|(\.{3}\{(?:[^{}]+|\{(?:[^{}]+|\{[^}]*\})*\})*\})/gs;
|
|
417
|
+
|
|
418
|
+
|
|
426
419
|
|
|
427
420
|
|
|
428
421
|
|
|
429
422
|
|
|
430
|
-
|
|
431
423
|
let props = component.match(dynamicAttributesRegex)
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
424
|
+
|
|
425
|
+
let filteredProps = [];
|
|
426
|
+
let isWithinComponent = false;
|
|
427
|
+
let componentName = name
|
|
428
|
+
|
|
429
|
+
for (let prop of props) {
|
|
430
|
+
|
|
431
|
+
if (prop.includes(componentName)) {
|
|
432
|
+
// If the component is encountered, start collecting props
|
|
433
|
+
isWithinComponent = true;
|
|
434
|
+
filteredProps.push(prop);
|
|
435
|
+
} else if (isWithinComponent && prop.includes('=')) {
|
|
436
|
+
|
|
437
|
+
if (prop.includes('${')) {
|
|
438
|
+
// if it has an object inside of it then we should just do soemting:object else we should do something: `${object}`
|
|
439
|
+
|
|
440
|
+
prop = prop.replace('="', ':').replace('}"', '}')
|
|
441
|
+
if (prop.includes('${')) {
|
|
442
|
+
prop = prop.replace('="', ':')
|
|
443
|
+
prop = prop.replace('${', '')
|
|
444
|
+
prop = prop.replace('}', '')
|
|
445
|
+
|
|
446
|
+
}
|
|
447
|
+
if (prop.includes('="${{')) {
|
|
448
|
+
prop = prop.replace('${{', '{')
|
|
449
|
+
prop = prop.replace('}}', '}')
|
|
450
|
+
prop = prop.replace('="', ':')
|
|
451
|
+
prop = prop.replace('}"', '}')
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
}
|
|
455
|
+
if (prop.startsWith('={')) {
|
|
456
|
+
prop = prop.replace('={', ':`${')
|
|
457
|
+
prop.replace('} ', '}`')
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
if (prop.includes('function')) {
|
|
461
|
+
// parse 'function' to function
|
|
462
|
+
prop = prop.replace("'", '')
|
|
463
|
+
|
|
464
|
+
if (prop.endsWith("}'")) {
|
|
465
|
+
prop = prop.replace("}'", '}')
|
|
466
|
+
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
prop = prop.replace('=function', ':function')
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
filteredProps.push(prop);
|
|
473
|
+
|
|
474
|
+
|
|
476
475
|
}
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
476
|
+
else if (isWithinComponent && prop.includes('...')) {
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
// Check if spread props are within curly braces
|
|
481
|
+
if (prop.startsWith('{') && prop.endsWith('}')) {
|
|
482
|
+
const spreadObject = prop
|
|
483
|
+
const hasOtherObjects = spreadObject.split(',').filter((e) => e.includes(':')).length > 0;
|
|
484
|
+
|
|
485
|
+
const isValidSpread = spreadObject.includes('...');
|
|
486
|
+
|
|
487
|
+
let processedSpreadObject = '';
|
|
488
|
+
if (isValidSpread) {
|
|
489
|
+
// Split the spreadObject by commas and process each part individually
|
|
490
|
+
const parts = spreadObject.split(',').map((part) => {
|
|
491
|
+
if (part.trim().startsWith('{') && part.trim().endsWith('}')) {
|
|
492
|
+
const nestedParts = part
|
|
493
|
+
.trim()
|
|
494
|
+
.slice(1, -1) // Remove outer {}
|
|
495
|
+
.split(',')
|
|
496
|
+
.map((nestedPart) => {
|
|
497
|
+
return nestedPart.includes('...') ? nestedPart.trim().replace(/\.\.\./, '') : `...${nestedPart.trim()}`;
|
|
498
|
+
});
|
|
499
|
+
return `{${nestedParts.join(',')}}`;
|
|
500
|
+
} else {
|
|
501
|
+
return part.includes('...') ? part.trim() : part.trim().startsWith('{') ? `...${part.trim()}` : `${part.trim()}`;
|
|
502
|
+
}
|
|
503
|
+
});
|
|
504
|
+
if (!parts.join(',').includes('{(')) {
|
|
480
505
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
if (part.trim().startsWith('{') && part.trim().endsWith('}')) {
|
|
501
|
-
// Handle nested spreads within the object
|
|
502
|
-
const nestedParts = part
|
|
503
|
-
.trim()
|
|
504
|
-
.slice(1, -1) // Remove outer {}
|
|
505
|
-
.split(',')
|
|
506
|
-
.map((nestedPart) => {
|
|
507
|
-
return nestedPart.includes('...') ? nestedPart.trim().replace(/\.\.\./, '') : `...${nestedPart.trim()}`;
|
|
508
|
-
});
|
|
509
|
-
return `{${nestedParts.join(',')}}`;
|
|
510
|
-
} else {
|
|
511
|
-
return part.includes('...') ? part.trim() : part.trim().startsWith('{') ? `...${part.trim()}` : `${part.trim()}`;
|
|
506
|
+
processedSpreadObject = `${parts.join(',')}`
|
|
507
|
+
|
|
508
|
+
} else {
|
|
509
|
+
let prop = parts.join(',')
|
|
510
|
+
prop = prop.replaceAll('{(', '(')
|
|
511
|
+
prop = prop.replaceAll(')}', ')')
|
|
512
|
+
processedSpreadObject = prop
|
|
513
|
+
}
|
|
514
|
+
if (prop.includes('{{')) {
|
|
515
|
+
let prop = parts.join(',')
|
|
516
|
+
prop = prop.replaceAll('{{', '{')
|
|
517
|
+
prop = prop.replaceAll('}}', '}')
|
|
518
|
+
processedSpreadObject = prop
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
|
|
522
|
+
} else {
|
|
523
|
+
// Process nested structures within the object
|
|
524
|
+
processedSpreadObject = `{...${spreadObject}}`;
|
|
512
525
|
}
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
processedSpreadObject = `${parts.join(',')}`
|
|
517
|
-
|
|
518
|
-
}else{
|
|
519
|
-
let prop = parts.join(',')
|
|
520
|
-
prop = prop.replaceAll('{(', '(')
|
|
521
|
-
prop = prop.replaceAll(')}', ')')
|
|
522
|
-
processedSpreadObject = prop
|
|
526
|
+
|
|
527
|
+
const $propsKey = `$props_${Math.random().toString(36).substring(2)}`;
|
|
528
|
+
filteredProps.push(`${$propsKey}:${processedSpreadObject}`);
|
|
523
529
|
}
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
const $propsKey = `$props_${Math.random().toString(36).substring(2)}`;
|
|
532
|
-
filteredProps.push(`${$propsKey}:${processedSpreadObject}`);
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
else{
|
|
537
|
-
isWithinComponent = false;
|
|
538
|
-
}
|
|
539
|
-
}
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
else {
|
|
533
|
+
isWithinComponent = false;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
540
536
|
|
|
541
537
|
// get inner content of <Component>inner content</Component>
|
|
542
538
|
let children = new RegExp(`<${name}[^>]*>(.*?)<\/${name}>`, "gs").exec(component) ? new RegExp(`<${name}[^>]*>(.*?)<\/${name}>`, "gs").exec(component)[1] : null;
|
|
543
|
-
|
|
539
|
+
|
|
544
540
|
props = filteredProps.join(',')
|
|
545
|
-
|
|
541
|
+
|
|
546
542
|
let savedname = name;
|
|
547
|
-
|
|
548
|
-
|
|
543
|
+
|
|
544
|
+
|
|
549
545
|
|
|
550
546
|
name = name + Math.random().toString(36).substring(2);
|
|
551
547
|
if (children && children.match(componentRegex)) {
|
|
552
548
|
children = parseComponents(children, true);
|
|
553
549
|
childs.push({ parent: name, children: children });
|
|
554
550
|
} else {
|
|
555
|
-
|
|
551
|
+
|
|
556
552
|
children ? childs.push({ parent: name, children: children }) : null;
|
|
557
553
|
}
|
|
558
554
|
|
|
@@ -574,24 +570,22 @@ function Compiler(func, file) {
|
|
|
574
570
|
|
|
575
571
|
|
|
576
572
|
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
573
|
+
|
|
574
|
+
props = props.replaceAll(`,${savedname}`, '').replaceAll(savedname, '')
|
|
575
|
+
if (props.startsWith(',')) {
|
|
576
|
+
props = props.replace(',', '')
|
|
577
|
+
}
|
|
578
|
+
props = props.replaceAll("='", ":'")
|
|
579
|
+
.replaceAll('=`', ':`')
|
|
584
580
|
.replaceAll('="', ':"')
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
.replaceAll('={', ":`")
|
|
588
|
-
|
|
581
|
+
.replaceAll('={', ':')
|
|
582
|
+
|
|
589
583
|
|
|
590
584
|
/**
|
|
591
585
|
* @memoize - memoize a component to be remembered on each render and replace the old jsx
|
|
592
586
|
*/
|
|
593
587
|
|
|
594
|
-
let replace = "";
|
|
588
|
+
let replace = "";
|
|
595
589
|
replace = `\${this.memoize(this.createComponent(${savedname}, {${props}}, [\`${myChildrens.join(" ")}\`]))}`;
|
|
596
590
|
|
|
597
591
|
body = body.replace(before, replace);
|
|
@@ -781,6 +775,12 @@ function Compiler(func, file) {
|
|
|
781
775
|
|
|
782
776
|
globalThis.isBuilding = false
|
|
783
777
|
globalThis.isWriting = null
|
|
778
|
+
const glb = await glob("**/**/**/**.{jsx,js}", {
|
|
779
|
+
ignore: ["node_modules/**/*", "dist/**/*"],
|
|
780
|
+
cwd: process.cwd() + '/pages/',
|
|
781
|
+
absolute: true,
|
|
782
|
+
recursive: true
|
|
783
|
+
});
|
|
784
784
|
async function Build() {
|
|
785
785
|
globalThis.isBuilding = true
|
|
786
786
|
console.log('Compiling......')
|
|
@@ -806,12 +806,7 @@ async function Build() {
|
|
|
806
806
|
};
|
|
807
807
|
|
|
808
808
|
|
|
809
|
-
|
|
810
|
-
ignore: ["node_modules/**/*", "dist/**/*"],
|
|
811
|
-
cwd: process.cwd() + '/pages/',
|
|
812
|
-
absolute: true,
|
|
813
|
-
recursive: true
|
|
814
|
-
});
|
|
809
|
+
|
|
815
810
|
|
|
816
811
|
// Process files in the 'pages' directory
|
|
817
812
|
let appjs = '';
|
|
@@ -823,10 +818,10 @@ async function Build() {
|
|
|
823
818
|
if (route.url.includes(':')) {
|
|
824
819
|
console.log('Route ' + route.url + ' is a dynamic route and will not be generated')
|
|
825
820
|
return
|
|
826
|
-
}
|
|
827
|
-
let equalparamroute = routes.map((e) => {
|
|
821
|
+
}
|
|
822
|
+
let equalparamroute = routes.map((e) => {
|
|
828
823
|
if (e.url.includes(':')) {
|
|
829
|
-
let url = e.url.split('/:')[0]
|
|
824
|
+
let url = e.url.split('/:')[0]
|
|
830
825
|
if (url && route.url === url) {
|
|
831
826
|
return e
|
|
832
827
|
} else {
|
|
@@ -910,14 +905,14 @@ async function Build() {
|
|
|
910
905
|
res.render(module, req, res, module.$metadata)
|
|
911
906
|
})
|
|
912
907
|
${equalparamroute.length > 0 ? equalparamroute.map((e) => {
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
908
|
+
|
|
909
|
+
|
|
910
|
+
|
|
911
|
+
return `router.get('${e.url}', async (req, res) => {
|
|
917
912
|
let module = await import('/${e.fileName.replace('.jsx', '.js')}')
|
|
918
913
|
res.render(module, req, res, module.$metadata)
|
|
919
914
|
})\n`
|
|
920
|
-
|
|
915
|
+
}) : ''}
|
|
921
916
|
router.listen(3000)
|
|
922
917
|
|
|
923
918
|
</script>
|
|
@@ -934,8 +929,8 @@ async function Build() {
|
|
|
934
929
|
let port = Math.floor(Math.random() * (65535 - 49152 + 1) + 49152)
|
|
935
930
|
|
|
936
931
|
const server = http.createServer((req, res) => {
|
|
937
|
-
|
|
938
|
-
if (req.url === '/') {
|
|
932
|
+
|
|
933
|
+
if (req.url === '/') {
|
|
939
934
|
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
940
935
|
res.end(document);
|
|
941
936
|
} else {
|
|
@@ -967,26 +962,26 @@ async function Build() {
|
|
|
967
962
|
|
|
968
963
|
globalThis.listen = true;
|
|
969
964
|
|
|
970
|
-
const browser
|
|
971
|
-
headless:
|
|
965
|
+
const browser = await puppeteer.launch({
|
|
966
|
+
headless: "new", args: ['--no-sandbox', '--disable-setuid-sandbox'],
|
|
972
967
|
warning: false,
|
|
973
968
|
})
|
|
974
969
|
|
|
975
970
|
try {
|
|
976
|
-
|
|
971
|
+
|
|
977
972
|
route.url = route.url.replaceAll(/\/:[a-zA-Z0-9_-]+/gs, '')
|
|
978
973
|
let page = await browser.newPage();
|
|
979
|
-
await page.goto(`http://localhost:${port}
|
|
974
|
+
await page.goto(`http://localhost:${port}/`, { waitUntil: 'networkidle2' });
|
|
980
975
|
await page.waitForSelector('#root');
|
|
981
976
|
await page.evaluate(() => {
|
|
982
977
|
document.getElementById('meta').remove()
|
|
983
978
|
document.querySelector('#isServer').innerHTML = 'window.isServer = false'
|
|
984
|
-
if(document.head.getAttribute('prerender') === 'false'){
|
|
979
|
+
if (document.head.getAttribute('prerender') === 'false') {
|
|
985
980
|
document.querySelector('#root').innerHTML = ''
|
|
986
981
|
}
|
|
987
982
|
})
|
|
988
983
|
const html = await page.content();
|
|
989
|
-
|
|
984
|
+
|
|
990
985
|
await page.close();
|
|
991
986
|
await writer(process.cwd() + '/dist/' + (route.url === '/' ? 'index.html' : `${route.url}/` + 'index.html'), html)
|
|
992
987
|
await browser.close();
|
|
@@ -994,11 +989,11 @@ async function Build() {
|
|
|
994
989
|
console.log(error)
|
|
995
990
|
await browser.close();
|
|
996
991
|
}
|
|
997
|
-
finally{
|
|
992
|
+
finally {
|
|
998
993
|
await browser.close();
|
|
999
994
|
server.close()
|
|
1000
995
|
}
|
|
1001
|
-
|
|
996
|
+
|
|
1002
997
|
|
|
1003
998
|
})
|
|
1004
999
|
|
|
@@ -1006,6 +1001,7 @@ async function Build() {
|
|
|
1006
1001
|
globalThis.isBuilding = false
|
|
1007
1002
|
clearTimeout(timeout)
|
|
1008
1003
|
}, 1000)
|
|
1004
|
+
console.log(`Generated ${routes.length} html files for ${routes.length} routes`)
|
|
1009
1005
|
}
|
|
1010
1006
|
|
|
1011
1007
|
globalThis.routes = []
|
|
@@ -1043,75 +1039,72 @@ async function Build() {
|
|
|
1043
1039
|
|
|
1044
1040
|
await writer(process.cwd() + "/dist/" + fileName.replace('.jsx', '.js'), data).then(async () => {
|
|
1045
1041
|
|
|
1046
|
-
let { minify } = await import('terser')
|
|
1047
|
-
|
|
1048
|
-
try {
|
|
1049
|
-
let minified = await minify(data, {
|
|
1050
|
-
toplevel: true,
|
|
1051
|
-
ecma: 2016,
|
|
1052
|
-
enclose: false,
|
|
1053
|
-
module: true,
|
|
1054
|
-
compress: true,
|
|
1055
|
-
keep_fnames: true,
|
|
1056
1042
|
|
|
1057
|
-
})
|
|
1058
1043
|
|
|
1059
|
-
|
|
1044
|
+
await writer(process.cwd() + "/dist/" + fileName.replace('.jsx', '.js'), data)
|
|
1060
1045
|
|
|
1061
|
-
await writer(process.cwd() + "/dist/" + fileName.replace('.jsx', '.js'), minified.code)
|
|
1062
|
-
} catch (error) {
|
|
1063
|
-
console.log(error)
|
|
1064
|
-
}
|
|
1065
1046
|
})
|
|
1066
1047
|
|
|
1048
|
+
// configure routing for each page
|
|
1067
1049
|
|
|
1068
1050
|
obj.compiledPath = process.cwd() + "/dist/pages/" + fileName.replace('.jsx', '.js')
|
|
1069
|
-
let providerRedirects = {cloudflare: '_redirects', vercel: 'vercel.json', netlify:'_redirects'}
|
|
1070
|
-
switch(true){
|
|
1051
|
+
let providerRedirects = { cloudflare: '_redirects', vercel: 'vercel.json', netlify: '_redirects' }
|
|
1052
|
+
switch (true) {
|
|
1071
1053
|
case config && config.host && !config.host['_redirect']:
|
|
1072
1054
|
let host = config.host.provider
|
|
1073
|
-
|
|
1074
|
-
let provider = providerRedirects[host]
|
|
1075
|
-
if(provider){
|
|
1076
|
-
|
|
1077
|
-
let redirectFile =
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1055
|
+
|
|
1056
|
+
let provider = providerRedirects[host]
|
|
1057
|
+
if (provider) {
|
|
1058
|
+
|
|
1059
|
+
let redirectFile = null
|
|
1060
|
+
switch (true) {
|
|
1061
|
+
case provider === '_redirects':
|
|
1062
|
+
redirectFile = fs.existsSync(process.cwd() + '/dist/' + provider) ? fs.readFileSync(process.cwd() + '/dist/' + provider, 'utf8') : ''
|
|
1063
|
+
break;
|
|
1064
|
+
case provider === 'vercel.json':
|
|
1065
|
+
redirectFile = fs.existsSync(process.cwd() + '/' + provider) ? fs.readFileSync(process.cwd() + '/' + provider, 'utf8') : ''
|
|
1066
|
+
break;
|
|
1067
|
+
default:
|
|
1068
|
+
break;
|
|
1069
|
+
}
|
|
1070
|
+
let type = provider === '_redirects' ? 'text/plain' : 'application/json'
|
|
1071
|
+
|
|
1072
|
+
let root = obj.url.includes(':') ? obj.url.split('/:')[0] : obj.url
|
|
1073
|
+
switch (true) {
|
|
1082
1074
|
case root === '/':
|
|
1083
1075
|
break;
|
|
1084
1076
|
case type === 'text/plain' && !redirectFile.includes(obj.url) && obj.url.includes(':'):
|
|
1085
1077
|
let page = obj.pathname.split('/pages/')[1].replace('.jsx', '.js')
|
|
1086
1078
|
redirectFile += `\n/${page} /${page} 200\n${obj.url} ${root} 200\n`
|
|
1087
1079
|
!redirectFile.includes('/404') ? redirectFile += `\n/404 /404 404` : null
|
|
1088
|
-
fs.writeFileSync(process.cwd() + '/dist/' + provider, redirectFile)
|
|
1080
|
+
fs.writeFileSync(process.cwd() + '/dist/' + provider, redirectFile)
|
|
1089
1081
|
console.log(`Added ${obj.url} ${obj.url} 200 to ${provider}`)
|
|
1090
1082
|
break;
|
|
1091
|
-
case
|
|
1092
|
-
let json = JSON.parse(redirectFile)
|
|
1083
|
+
case type === 'application/json' && !redirectFile?.includes(`${obj.url}`):
|
|
1084
|
+
let json = redirectFile ? JSON.parse(redirectFile) : {}
|
|
1093
1085
|
let isVercel = provider === 'vercel.json' ? true : false
|
|
1094
|
-
if(isVercel){
|
|
1086
|
+
if (isVercel) {
|
|
1095
1087
|
json['rewrites'] = json['rewrites'] || []
|
|
1096
|
-
json['rewrites'].push({ "source":
|
|
1088
|
+
json['rewrites'].push({ "source": obj.url, "destination": `${root}/index.html` })
|
|
1089
|
+
fs.writeFileSync(process.cwd() + '/' + provider, JSON.stringify(json, null, 2))
|
|
1090
|
+
console.log(`Added ${obj.url} ${root}/index.html to ${provider}`)
|
|
1097
1091
|
}
|
|
1098
|
-
|
|
1099
|
-
console.log(`Added ${root}/* ${root} 200 to ${provider}`)
|
|
1092
|
+
|
|
1100
1093
|
}
|
|
1101
1094
|
}
|
|
1102
1095
|
break;
|
|
1103
1096
|
case config && config.host && config.host['_redirect']:
|
|
1104
|
-
let file =
|
|
1097
|
+
let file = config.host['_redirect']
|
|
1105
1098
|
file = file.split('./').join('')
|
|
1106
|
-
let redirectFile =
|
|
1099
|
+
let redirectFile = fs.existsSync(process.cwd() + '/' + file) ? fs.readFileSync(process.cwd() + '/' + file, 'utf8') : ''
|
|
1107
1100
|
fs.writeFileSync(process.cwd() + '/dist/' + file, redirectFile)
|
|
1108
1101
|
console.log(`Using ${file} for redirects`)
|
|
1109
1102
|
default:
|
|
1110
1103
|
break;
|
|
1111
1104
|
|
|
1112
1105
|
}
|
|
1113
|
-
|
|
1114
|
-
|
|
1106
|
+
|
|
1107
|
+
|
|
1115
1108
|
globalThis.routes.push({ fileName: fileName, url: obj.url, html: '/' + (isBasePath ? 'index.html' : `${obj.url}/` + 'index.html') })
|
|
1116
1109
|
|
|
1117
1110
|
|
|
@@ -1153,18 +1146,7 @@ async function Build() {
|
|
|
1153
1146
|
data = Compiler(data, process.cwd() + "/src/" + name);
|
|
1154
1147
|
|
|
1155
1148
|
await writer(process.cwd() + "/dist/src/" + name.split('.jsx').join('.js'), data).then(async () => {
|
|
1156
|
-
|
|
1157
|
-
try {
|
|
1158
|
-
let minified = await minify(data, {
|
|
1159
|
-
ecma: " 2016",
|
|
1160
|
-
module: true,
|
|
1161
|
-
compress: true,
|
|
1162
|
-
keep_fnames: true,
|
|
1163
|
-
})
|
|
1164
|
-
await writer(process.cwd() + "/dist/src/" + name.replace('.jsx', '.js'), minified.code)
|
|
1165
|
-
} catch (error) {
|
|
1166
|
-
console.log(error)
|
|
1167
|
-
}
|
|
1149
|
+
await writer(process.cwd() + "/dist/src/" + name.replace('.jsx', '.js'), data)
|
|
1168
1150
|
|
|
1169
1151
|
})
|
|
1170
1152
|
return
|
|
@@ -1236,18 +1218,17 @@ const s = () => {
|
|
|
1236
1218
|
|
|
1237
1219
|
fs.readFile(filePath, (err, data) => {
|
|
1238
1220
|
if (err) {
|
|
1239
|
-
console.log(err)
|
|
1240
1221
|
res.writeHead(404, { 'Content-Type': 'text/html' });
|
|
1241
1222
|
res.end(fs.existsSync(process.cwd() + '/dist/404') ? fs.readFileSync(process.cwd() + '/dist/404/index.html') : '404');
|
|
1242
1223
|
} else {
|
|
1243
|
-
const contentType = getContentType(filePath);
|
|
1224
|
+
const contentType = getContentType(filePath);
|
|
1244
1225
|
switch (true) {
|
|
1245
1226
|
case contentType === 'text/html' && globalThis.devMode:
|
|
1246
1227
|
data = data.toString() + `<script type="module">
|
|
1247
|
-
let ws = new WebSocket('ws://localhost
|
|
1228
|
+
let ws = new WebSocket('ws://localhost:${process.env.PORT || 3000}')
|
|
1248
1229
|
ws.onmessage = (e) => {
|
|
1249
1230
|
if(e.data === 'reload'){
|
|
1250
|
-
window.
|
|
1231
|
+
window.location.reload()
|
|
1251
1232
|
}
|
|
1252
1233
|
}
|
|
1253
1234
|
</script>
|
|
@@ -1262,13 +1243,13 @@ const s = () => {
|
|
|
1262
1243
|
|
|
1263
1244
|
const ws = new WebSocketServer({ server });
|
|
1264
1245
|
ws.on('connection', (socket) => {
|
|
1265
|
-
console.log('Client connected');
|
|
1266
|
-
socket.on('close', () => console.log('Client disconnected'));
|
|
1246
|
+
console.log('WebSocket Hydration Client connected');
|
|
1247
|
+
socket.on('close', () => console.log('WebSocket Hydration Client disconnected'));
|
|
1267
1248
|
});
|
|
1268
1249
|
|
|
1269
1250
|
|
|
1270
1251
|
function getContentType(filePath) {
|
|
1271
|
-
let ext =
|
|
1252
|
+
let ext = ['.js', '.css', '.mjs', '.cjs', '.html', '.json', '.png', '.jpg', '.jpeg', '.gif', '.svg', '.mp4', '.webm', '.ogg'].includes(path.extname(filePath)) ? path.extname(filePath) : '.html'
|
|
1272
1253
|
switch (ext) {
|
|
1273
1254
|
case '.js':
|
|
1274
1255
|
return 'text/javascript';
|
|
@@ -1310,21 +1291,20 @@ const s = () => {
|
|
|
1310
1291
|
let i =
|
|
1311
1292
|
setInterval(() => {
|
|
1312
1293
|
if (globalThis.isBuilding && globalThis.devMode) {
|
|
1313
|
-
|
|
1314
|
-
console.log(globalThis.isBuilding)
|
|
1315
|
-
console.log('Reloading page...')
|
|
1294
|
+
|
|
1316
1295
|
ws.clients.forEach((client) => {
|
|
1317
1296
|
client.send('reload')
|
|
1318
|
-
console.log('Reloaded page')
|
|
1319
1297
|
})
|
|
1320
|
-
}
|
|
1298
|
+
} else {
|
|
1299
|
+
clearInterval(i)
|
|
1300
|
+
}
|
|
1321
1301
|
}, 120)
|
|
1322
1302
|
|
|
1323
1303
|
}
|
|
1324
1304
|
|
|
1325
1305
|
|
|
1326
1306
|
switch (true) {
|
|
1327
|
-
case process.argv.includes('--watch'):
|
|
1307
|
+
case process.argv.includes('--watch') && !process.argv.includes('--build') && !process.argv.includes('--serve'):
|
|
1328
1308
|
|
|
1329
1309
|
globalThis.devMode = true
|
|
1330
1310
|
console.log(`
|
|
@@ -1354,7 +1334,7 @@ Vader.js v1.3.3
|
|
|
1354
1334
|
globalThis.listen = true;
|
|
1355
1335
|
|
|
1356
1336
|
break;
|
|
1357
|
-
case process.argv.includes('--build'):
|
|
1337
|
+
case process.argv.includes('--build') && !process.argv.includes('--watch') && !process.argv.includes('--serve'):
|
|
1358
1338
|
globalThis.devMode = false
|
|
1359
1339
|
console.log(`
|
|
1360
1340
|
Vader.js v1.3.3
|
|
@@ -1363,7 +1343,7 @@ Building to ./dist
|
|
|
1363
1343
|
Build()
|
|
1364
1344
|
|
|
1365
1345
|
break;
|
|
1366
|
-
case process.argv.includes('--serve'):
|
|
1346
|
+
case process.argv.includes('--serve') && !process.argv.includes('--watch') && !process.argv.includes('--build'):
|
|
1367
1347
|
let port = process.argv[process.argv.indexOf('--serve') + 1] || 3000
|
|
1368
1348
|
process.env.PORT = port
|
|
1369
1349
|
globalThis.devMode = false
|
|
@@ -1381,9 +1361,9 @@ Vader.js is a reactive framework for building interactive applications for the w
|
|
|
1381
1361
|
Usage: vader <command>
|
|
1382
1362
|
|
|
1383
1363
|
Commands:
|
|
1384
|
-
--watch Watch the pages folder for changes
|
|
1364
|
+
--watch Watch the pages folder for changes with hot reloading
|
|
1385
1365
|
|
|
1386
|
-
--build Build the project
|
|
1366
|
+
--build Build the project to ./dist
|
|
1387
1367
|
|
|
1388
1368
|
--serve Serve the project on a port (default 3000)
|
|
1389
1369
|
|