vaderjs 1.3.3-5b5a772ebe58 → 1.3.3-8924566yt812
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 +9 -5
- package/package.json +1 -1
- package/runtime/router.js +1 -1
- package/runtime/vader.js +1 -1
- package/vader.js +181 -211
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
[](https://github.com/Postr-Inc/Vader.js/blob/main/LICENSE) [](https://www.npmjs.com/package/vaderjs)
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
> Do not use any alpha versions as these where changed multiple times any version under latest is considered lts and are deemed to be stable
|
|
18
18
|
## Get Started
|
|
19
19
|
|
|
20
20
|
2. Install vaderjs
|
|
@@ -81,7 +81,7 @@ export default function(req, res){
|
|
|
81
81
|
|
|
82
82
|
return <>
|
|
83
83
|
<h1>${count}</h1>
|
|
84
|
-
<button onClick={(
|
|
84
|
+
<button onClick={(event)=>{setCount(count + 1)}}>
|
|
85
85
|
</>
|
|
86
86
|
}
|
|
87
87
|
|
|
@@ -126,9 +126,11 @@ export function Layout({title, keywords, description, children}){
|
|
|
126
126
|
|
|
127
127
|
// pages/index.jsx
|
|
128
128
|
|
|
129
|
+
//$= is a ternary operator used for spread like nesting
|
|
130
|
+
|
|
129
131
|
export default function (req, res){
|
|
130
132
|
return <>
|
|
131
|
-
<Layout {
|
|
133
|
+
<Layout $={{title:'home', description:'home page', keywords:'vader.js', logo:''}}>
|
|
132
134
|
<h1> Hello World</h1>
|
|
133
135
|
</Layout>
|
|
134
136
|
</>
|
|
@@ -173,6 +175,8 @@ export default class MyApp extends Component{
|
|
|
173
175
|
contructor(){
|
|
174
176
|
super()
|
|
175
177
|
this.key = 'static key for state changes'
|
|
178
|
+
// or
|
|
179
|
+
this.nokey // disable element generation
|
|
176
180
|
}
|
|
177
181
|
|
|
178
182
|
render(){
|
|
@@ -215,7 +219,7 @@ return <>
|
|
|
215
219
|
</>
|
|
216
220
|
```
|
|
217
221
|
|
|
218
|
-
|
|
222
|
+
Low level invokes are considered top level and can access - any value above the scope !!
|
|
219
223
|
|
|
220
224
|
```jsx
|
|
221
225
|
let car = {
|
|
@@ -223,7 +227,7 @@ let car = {
|
|
|
223
227
|
price: 'toomiuch'
|
|
224
228
|
}
|
|
225
229
|
return <>
|
|
226
|
-
<button onclick={(
|
|
230
|
+
<button onclick={(event)=>{
|
|
227
231
|
console.log(car.model)
|
|
228
232
|
}}>Log</button>
|
|
229
233
|
```
|
package/package.json
CHANGED
package/runtime/router.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Component}from"./vader.js";let middlewares=[];class VaderRouter{constructor(e,t){this.routes=[],this.middlewares=[],this.errorMiddlewares=[],this.listeners=[],this.basePath=e}get(e,t){this.routes.push({path:e,handler:t,method:"get"})}use(e){this.middlewares.push(e)}listen(e,t){e||(e=Math.random().toString(36).substring(7)),window.onpopstate=async e=>{let t=window.location.pathname,r=`/${t.split("/")[1]}`;console.log("route",t),this.checkroute(t)||window.devMode||(t="/404");let n=(new DOMParser).parseFromString(await fetch(r,{cache:"reload"}).then((e=>e.text())),"text/html").documentElement;document.querySelector("#root").innerHTML=n.querySelector("#root").innerHTML,document.title=n.querySelector("title")?n.querySelector("title").innerHTML:document.title,document.querySelector('script[id="router"]').remove();let o=document.createElement("script");o.id="router",o.innerHTML=n.querySelector('script[id="router"]').innerHTML,o.setAttribute("type","module"),document.body.appendChild(o)},window.rehydrate=async()=>{window.location.reload()},this.listeners.push(e),1===this.listeners.length?this.handleRoute(window.location.pathname):this.listeners.pop(),t&&t()}extractParams(e,t){const r=e.split("/").filter((e=>""!==e)),n=t.split("/").filter((e=>""!==e)),o={};return r.forEach(((e,t)=>{if(e.startsWith(":")){const r=e.slice(1);o[r]=n[t]}else if(e.startsWith("*")){n.slice(t).forEach(((e,t)=>{o[t]=e}))}})),o}extractQueryParams(e){const t=e.split("?")[1];if(!t)return{};const r={};return t.split("&").forEach((e=>{const[t,n]=e.split("=");r[t]=n})),r}checkroute(e){return e=e.endsWith("/")?e.slice(0,-1):e,this.routes.find((t=>{if(t.path===e)return!0;if(""===e&&"/"===t.path)return!0;if(e.includes("?")&&(e=e.split("?")[0]),t.path.includes("*")||t.path.includes(":")){const r=t.path.split("/").filter((e=>""!==e)),n=e.split("/").filter((e=>""!==e));if(r.length!==n.length&&!t.path.endsWith("*"))return!1;for(let e=0;e<r.length;e++){const t=r[e],o=n[e];if(!t.startsWith(":")&&!t.startsWith("*")&&t!==o)return!1}return!0}const r=this.extractParams(t.path,e);return Object.keys(r).length>0}))}handleRoute(e){let t=200,r=e,n=this.checkroute(e);n||(n=window.routes.find((e=>!e.url.includes("/404")||this.error||window.devMode?!(this.error||!e.url.includes("/404"))||void 0:(window.history.pushState({},"","/404"),window.dispatchEvent(new Event("popstate")),this.error=!0,!1))),t=n?200:404);const o=this.extractQueryParams(r),s=n&&n.path?this.extractParams(n.path,r):{};Object.keys(s).forEach((e=>{s[e]=s[e].split("?")?s[e].split("?")[0]:s[e]}));const i={headers:{},params:s,query:o,path:e,fileUrl:window.location.href.split(window.location.origin)[1],url:window.location.href,method:n?n.method:"get",pause:!1,timestamp:Date.now()};window.$CURRENT_URL=i.path,window.$FULL_URL=window.location.href.replace("#","");const a={status:t,log:e=>{void 0===e?console.log(`${i.path} ${i.method} ${a.status} ${i.timestamp}`):console.table({"Request Path":i.path,"Request Method":n.method,"Response Status":a.status,"Request Timestamp":i.timestamp})},refresh:()=>{this.handleRoute(window.location.pathname)},redirect:e=>{!e.startsWith("/")&&(e=`/${e}`),window.history.pushState({},"",e),window.dispatchEvent(new Event("popstate"))},render:async(e,t,r,n)=>{function
|
|
1
|
+
import{Component}from"./vader.js";let middlewares=[];class VaderRouter{constructor(e,t){this.routes=[],this.middlewares=[],this.errorMiddlewares=[],this.listeners=[],this.basePath=e}get(e,t){this.routes.push({path:e,handler:t,method:"get"})}use(e){this.middlewares.push(e)}listen(e,t){e||(e=Math.random().toString(36).substring(7)),window.onpopstate=async e=>{let t=window.location.pathname,r=`/${t.split("/")[1]}`;console.log("route",t),this.checkroute(t)||window.devMode||(t="/404");let n=(new DOMParser).parseFromString(await fetch(r,{cache:"reload"}).then((e=>e.text())),"text/html").documentElement;document.querySelector("#root").innerHTML=n.querySelector("#root").innerHTML,document.title=n.querySelector("title")?n.querySelector("title").innerHTML:document.title,document.querySelector('script[id="router"]').remove();let o=document.createElement("script");o.id="router",o.innerHTML=n.querySelector('script[id="router"]').innerHTML,o.setAttribute("type","module"),document.body.appendChild(o)},window.rehydrate=async()=>{window.location.reload()},this.listeners.push(e),1===this.listeners.length?this.handleRoute(window.location.pathname):this.listeners.pop(),t&&t()}extractParams(e,t){const r=e.split("/").filter((e=>""!==e)),n=t.split("/").filter((e=>""!==e)),o={};return r.forEach(((e,t)=>{if(e.startsWith(":")){const r=e.slice(1);o[r]=n[t]}else if(e.startsWith("*")){n.slice(t).forEach(((e,t)=>{o[t]=e}))}})),o}extractQueryParams(e){const t=e.split("?")[1];if(!t)return{};const r={};return t.split("&").forEach((e=>{const[t,n]=e.split("=");r[t]=n})),r}checkroute(e){return e=e.endsWith("/")?e.slice(0,-1):e,this.routes.find((t=>{if(t.path===e)return!0;if(""===e&&"/"===t.path)return!0;if(e.includes("?")&&(e=e.split("?")[0]),t.path.includes("*")||t.path.includes(":")){const r=t.path.split("/").filter((e=>""!==e)),n=e.split("/").filter((e=>""!==e));if(r.length!==n.length&&!t.path.endsWith("*"))return!1;for(let e=0;e<r.length;e++){const t=r[e],o=n[e];if(!t.startsWith(":")&&!t.startsWith("*")&&t!==o)return!1}return!0}const r=this.extractParams(t.path,e);return Object.keys(r).length>0}))}handleRoute(e){let t=200,r=e,n=this.checkroute(e);n||(n=window.routes.find((e=>!e.url.includes("/404")||this.error||window.devMode?!(this.error||!e.url.includes("/404"))||void 0:(window.history.pushState({},"","/404"),window.dispatchEvent(new Event("popstate")),this.error=!0,!1))),t=n?200:404);const o=this.extractQueryParams(r),s=n&&n.path?this.extractParams(n.path,r):{};Object.keys(s).forEach((e=>{s[e]=s[e].split("?")?s[e].split("?")[0]:s[e]}));const i={headers:{},params:s,query:o,path:e,fileUrl:window.location.href.split(window.location.origin)[1],url:window.location.href,method:n?n.method:"get",pause:!1,timestamp:Date.now()};window.$CURRENT_URL=i.path,window.$FULL_URL=window.location.href.replace("#","");const a={status:t,log:e=>{void 0===e?console.log(`${i.path} ${i.method} ${a.status} ${i.timestamp}`):console.table({"Request Path":i.path,"Request Method":n.method,"Response Status":a.status,"Request Timestamp":i.timestamp})},refresh:()=>{this.handleRoute(window.location.pathname)},redirect:e=>{!e.startsWith("/")&&(e=`/${e}`),window.history.pushState({},"",e),window.dispatchEvent(new Event("popstate"))},render:async(e,t,r,n)=>{function isClass(e){return"function"==typeof e&&/^class\s/.test(Function.prototype.toString.call(e))}try{let n=new Component;if(isClass(e.default)){let t=new e.default;n.state=t.state,n=t}else{e.default.toString();n.key=e.default.toString().split('key="')[1]?e.default.toString().split('key="')[1].split('"')[0]:null;let i=e.default.toString().split("this.key")[1]?e.default.toString().split("this.key")[1].split("=")[1].split(";")[0].trim().replaceAll('"',""):null;i&&(n.key=i),console.log("key",n.key);let a={key:n.key,render:()=>{let o=document.createElement("div");return n.key&&o.setAttribute("key",n.key),o.innerHTML=e.default.apply(n,[t,r]),o.outerHTML},request:t,response:r,params:s,queryParams:o,reset:n.reset.bind(n),onMount:n.onMount.bind(n),useState:null,router:{use:n.router.use.bind(n)},bindMount:n.bindMount.bind(n),memoize:n.memoize.bind(n),createComponent:n.createComponent.bind(n),isChild:!1,useState:n.useState.bind(n),parseStyle:n.parseStyle.bind(n),bind:n.bind.bind(n),useRef:n.useRef.bind(n),useReducer:n.useReducer.bind(n),onMount:n.onMount.bind(n),onUnmount:n.onUnmount.bind(n),hydrate:n.hydrate.bind(n)};n.render=a.render,n=a}if(!document.querySelector("#root"))throw new Error("Root element not found, please add an element with id root");n.reset(),n.components={},n.request=t,n.response=r,n.router.use&&!n.isChild?await new Promise((async o=>{if(isClass(e.default))if(isClass(e.default))switch(await n.router.use(t,r),t.pause){case!0:console.log("pausing",t.pause);let e=setInterval((()=>{t.pause?console.log("still pausing",t.pause):(clearInterval(e),o())}),1e3);break;case!1:o()}else o();else switch(await e.default.apply(n,[t,r]),await n.router.use(t,r),t.pause){case!0:let e=setInterval((()=>{t.pause?console.log("still pausing request",t.url):(clearInterval(e),o())}),1e3);break;case!1:o()}})):n.router.use&&n.isChild&&console.warn("Router.use() is not supported in child components");const i=await n.render();document.querySelector("#root").innerHTML!==i&&(document.querySelector("#root").innerHTML=i),n.bindMount(),n.onMount()}catch(e){console.error(e)}},setQuery:e=>{let t="";Object.keys(e).forEach(((r,n)=>{t+=`${0===n?"?":"&"}${r}=${e[r]}`}));let r=window.location.hash.split("?")[0];t=t.replace("/","-").replaceAll("/","-"),window.location.hash=`${r}${t}`},send:e=>{document.querySelector("#root").innerHTML=e},json:e=>{const t=document.querySelector("#root");t.innerHTML="";const r=document.createElement("pre");r.textContent=JSON.stringify(e,null,2),t.appendChild(r)}};middlewares.forEach((e=>{e(i,a)})),n&&n.handler(i,a)}}window.VaderRouter=VaderRouter;export default VaderRouter;
|
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
|
|
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 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 i=new Component(t);if(isClass(e))r.props=t||{},r.props.children=s.join("")||[],r.props.children=s.join(""),r.parentNode=this,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;let r=[];Object.keys(t).forEach((e=>{if(e.startsWith("$props")&&(r.push(t[e]),delete t[e]),e.startsWith("$_ternary")){let s=t[e];delete t[e],Object.keys(s).forEach((e=>{t[e]=s[e]}))}})),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(">,",">")),t.nokey?s:`<div key="${t.key}">${s}</div>`}parseStyle(e){let t="";return Object.keys(e).forEach((s=>{let r=e[s];s=s.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g,"$1-$2").toLowerCase(),t+=`${s}:${r};`})),t}bindMount(){mounts.push(this)}domDifference(e,t){let s=[];for(let r=0;r<e.length;r++){let i=e[r],n=t[r];i&&n&&!i.isEqualNode(n)&&s.push({type:"replace",old:i,new:n.cloneNode(!0)})}return s}updateChangedElements(e){e.forEach((e=>{switch(e.type){case"replace":e.old.replaceWith(e.new);break;case"remove":e.old.remove();break;case"add":e.old.appendChild(e.new.cloneNode(!0))}}))}hydrate(e){if(e){console.log("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{if(this.key?document.querySelector(`[key="${this.key}"]`):null){let e=(new DOMParser).parseFromString(this.render(),"text/html").body.querySelector(`[key="${this.key}"]`),t=document.querySelector(`[key="${this.key}"]`),s=this.domDifference(t.children,e.children);this.updateChangedElements(s)}}}patch(e,t){const s=this.domDifference(e,t);this.updateChangedElements(s)}handleObject(obj){try{obj=JSON.parse(obj)}catch(e){}return eval(obj)}bind(e,t,s,r,...i){return s+=this.key,window["callFunctions"+this.key]=(e,t)=>{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)`}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,i)=>{const n=s(r,t)??t;this.state[e]=n,this.hydrate(i),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){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.link.setAttribute("onclick",`window.history.pushState({}, '', '${this.props?.href}'); window.dispatchEvent(new Event('popstate'));`),this.link.outerHTML}}export class Image extends Component{constructor(e){super(e),this.props={src:e.src,class:e.class,style:e.style,blur:e.blur,width:e.width,height:e.height,optimize:e.optimize||!0,loader:e.loader||!0,alt:e.alt||"image",ref:e.ref||null},this.key=e.src+Math.random(),this.img=document.createElement("img"),this.placeholder=document.createElement("div")}render(){if(window.isServer)return"";let[e,t]=this.useState("loaded",!1),s=this.useRef("hookref",null),r=this.props.width?this.props.width:window.innerWidth/2,i=this.props.height?this.props.height:window.innerHeight/2;if(!this.props.src)throw new Error("Image src is required");return this.img.setAttribute("src",this.props.src),this.img.setAttribute("class",this.props.class),this.img.setAttribute("style",this.props.style?this.props.style:""),this.img.setAttribute("width",r),this.img.setAttribute("ref",s.bind),this.img.referrerPolicy="no-referrer",this.img.setAttribute("height",i),this.img.setAttribute("loading","lazy"),this.img.setAttribute("alt",this.props.alt),this.props.blur&&this.img.setAttribute("style",`filter: blur(${this.props.blur}px);`),this.props.optimize&&this.img.setAttribute("style",`image-rendering: -webkit-optimize-contrast; object-fit: cover; object-position: center; ${this.props.style?this.props.style:""}`),!this.props.loader||e||window.isServer||(this.placeholder.setAttribute("style",`width: ${r}px; height: ${i}px; background: #eee;`),this.placeholder.setAttribute("class","vader-image-placeholder"),this.placeholder.innerHTML=this.props.loader,window.isServer)?void 0:(this.img.onload=()=>{t(!0,s.bind)},`<span ref="${s.bind}">${e?this.img.outerHTML:this.placeholder.outerHTML}</span>`)}}export class Html extends Component{constructor(e){super(e),this.props={children:e.children,lang:e.lang||"en",attributes:e.attributes||{}},this.key="html",this.html=document.createElement("div")}render(){return window.isServer?(this.html.innerHTML=this.props.children,this.html.setAttribute("lang",this.props.lang?this.props.lang:"en"),this.props.attributes&&Object.keys(this.props.attributes).forEach((e=>{this.html.setAttribute(e,this.props.attributes[e])})),this.html.innerHTML):this.props.children}onMount(){console.log("Document Has Been Mounted")}}export class Head extends Component{constructor(e){super(e),this.props=e,this.key="head",this.head=document.createElement("head")}render(){return""}onMount(){if(!this.state.hasMounted&&window.isServer){document.head.innerHTML=this.props.children+document.head.innerHTML,document.querySelectorAll("script[eager]").forEach((async e=>{if(!e.getAttribute("src"))throw new Error("Eager scripts must be external");e.remove();let t=e.getAttribute("src"),s=document.createElement("script"),r=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
|
@@ -22,16 +22,8 @@ let writer = async (file, data) => {
|
|
|
22
22
|
globalThis.isWriting = null
|
|
23
23
|
return { _written: true };
|
|
24
24
|
};
|
|
25
|
-
|
|
26
|
-
let
|
|
27
|
-
let bundleSize = 0;
|
|
28
|
-
let errorCodes = {
|
|
29
|
-
"SyntaxError: Unexpected token '<'": "You forgot to enclose tags in a fragment <></>",
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* define directories
|
|
33
|
-
*/
|
|
34
|
-
|
|
25
|
+
|
|
26
|
+
let bundleSize = 0;
|
|
35
27
|
|
|
36
28
|
if (!fs.existsSync(process.cwd() + '/dist')) {
|
|
37
29
|
fs.mkdirSync(process.cwd() + '/dist')
|
|
@@ -48,58 +40,63 @@ if (typeof process.env.isCloudflare !== "undefined" || !fs.existsSync(process.cw
|
|
|
48
40
|
|
|
49
41
|
|
|
50
42
|
function Compiler(func, file) {
|
|
51
|
-
let string = func;
|
|
52
|
-
// Remove block comments
|
|
53
|
-
|
|
43
|
+
let string = func;
|
|
54
44
|
let returns = []
|
|
55
45
|
let comments = string.match(/\{\s*\/\*.*\*\/\s*}/gs)?.map((comment) => comment.trim());
|
|
56
46
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
?.map((match) => match.trim());
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
62
51
|
|
|
63
|
-
let
|
|
52
|
+
let childs = [];
|
|
64
53
|
|
|
54
|
+
const spreadAttributeRegex = /\s*([a-zA-Z0-9_-]+)(\s*\$\s*=\s*{{((?:[^{}]|(?:\{(?:[^{}]|(?:\{[^{}]*\})*)*\})*)*)}})/gs;
|
|
55
|
+
let spreadMatch;
|
|
56
|
+
while ((spreadMatch = spreadAttributeRegex.exec(string)) !== null) {
|
|
57
|
+
let [, element, spread] = spreadMatch;
|
|
58
|
+
let isJSXComponent = element.match(/[A-Z]/) ? true : false;
|
|
59
|
+
if (isJSXComponent) {
|
|
60
|
+
continue
|
|
65
61
|
|
|
66
|
-
functions && functions.forEach((func) => {
|
|
67
|
-
if (
|
|
68
|
-
!func.match(
|
|
69
|
-
/(?:const|let)\s*([a-zA-Z0-9_-]+)\s*=\s*function\s*\(([^)]*)\)|function\s*([a-zA-Z0-9_-]+)\s*\(([^)]*)\)/gs
|
|
70
|
-
)
|
|
71
|
-
) {
|
|
72
|
-
return;
|
|
73
62
|
}
|
|
63
|
+
let old = spread;
|
|
74
64
|
|
|
75
|
-
|
|
65
|
+
// turn spread into attributes
|
|
66
|
+
spread = spread.replace(/\s*$\s*=\s*/, "");
|
|
67
|
+
spread = spread.replace(/{{/, "");
|
|
68
|
+
spread = spread.replace(/}}/, "");
|
|
69
|
+
spread = spread.replace(/\$\s*=\s*/, "");
|
|
76
70
|
|
|
77
|
-
|
|
71
|
+
// turn : into =
|
|
78
72
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
73
|
+
// do not split inner Objects ex: {color: 'red', background: {color: 'blue'}} -> {color: 'red', background: {color: 'blue'}}
|
|
74
|
+
let splitByCommas = spread.split(/,(?![^{]*})/g);
|
|
75
|
+
splitByCommas = splitByCommas.map((e) => e.trim())
|
|
76
|
+
splitByCommas = splitByCommas.map((e) => {
|
|
77
|
+
switch (true) {
|
|
78
|
+
case e.includes('function') || e.includes('=>'):
|
|
79
|
+
e = e.replace(/:(.*)/gs, '={$1}')
|
|
80
|
+
break;
|
|
81
|
+
case e.includes('style'):
|
|
82
|
+
e = e.replace(/:(.*)/gs, '="${this.parseStyle($1)}"')
|
|
83
|
+
break;
|
|
84
|
+
case e.includes('[') && e.includes(']'):
|
|
85
|
+
e = e.replace(/:(.*)/gs, '={$1.join(" ")}')
|
|
86
|
+
break;
|
|
87
|
+
default:
|
|
88
|
+
e = e.replace(/:(.*)/gs, '=$1')
|
|
89
|
+
break;
|
|
86
90
|
}
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
// get all Obj({}) and parse to JSON.stringify
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
return e.trim()
|
|
93
|
+
})
|
|
93
94
|
|
|
94
|
-
|
|
95
|
-
let key = obj.split("Obj")[1].split("(")[1].split(")")[0].trim();
|
|
96
|
-
let newobj = obj.replaceAll(`Obj(${key})`, `${key}`);
|
|
97
|
-
// let newobj = obj.replaceAll(`Obj(${key})`, `JSON.parse('${key}')`)
|
|
98
|
-
string = string.replaceAll(obj, `this.handleObject('${newobj}')`);
|
|
99
|
-
});
|
|
95
|
+
let newSpread = `\t` + splitByCommas.join(' ') + `\t`
|
|
100
96
|
|
|
97
|
+
string = string.replace(old, newSpread);
|
|
101
98
|
|
|
102
|
-
|
|
99
|
+
}
|
|
103
100
|
|
|
104
101
|
|
|
105
102
|
|
|
@@ -112,41 +109,40 @@ function Compiler(func, file) {
|
|
|
112
109
|
const attributeRegex =
|
|
113
110
|
/\s*([a-zA-Z0-9_-]+)(\s*=\s*("([^"\\]*(\\.[^"\\]*)*)"|'([^'\\]*(\\.[^'\\]*)*)'|\{(?:[^{}]|(?:\{(?:[^{}]|(?:\{[^{}]*\})*)*\})*)*\}|(?:\([^)]*\)|\{[^}]*\}|()=>\s*(?:\{[^}]*\})?)|\[[^\]]*\]))?/gs;
|
|
114
111
|
|
|
115
|
-
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
|
|
116
115
|
const functionAttributeRegex = /\s*([a-zA-Z0-9_-]+)(\s*=\s*{((?:[^{}]|(?:\{(?:[^{}]|(?:\{[^{}]*\})*)*\})*)*)})/gs;
|
|
117
116
|
|
|
118
117
|
let attributesList = [];
|
|
119
118
|
|
|
120
|
-
|
|
119
|
+
let spreadAttributes = [];
|
|
120
|
+
let spreadMatch;
|
|
121
|
+
/**
|
|
122
|
+
* @search - handle spread for html elements
|
|
123
|
+
* @keywords - spread, spread attributes, spread props, spread html attributes
|
|
124
|
+
*/
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* @search - handle function parsing for html elements
|
|
129
|
+
* @keywords - function, function attributes, function props, function html attributes
|
|
130
|
+
*
|
|
131
|
+
*/
|
|
121
132
|
let functionAttributes = [];
|
|
122
133
|
let functionMatch;
|
|
123
134
|
while ((functionMatch = functionAttributeRegex.exec(code)) !== null) {
|
|
124
|
-
let [, attributeName, attributeValue] = functionMatch;
|
|
125
135
|
|
|
136
|
+
let [, attributeName, attributeValue] = functionMatch;
|
|
126
137
|
let attribute = {};
|
|
127
138
|
|
|
128
|
-
if (attributeValue && attributeValue.includes("=>") || attributeValue && attributeValue.includes("function")
|
|
129
|
-
|
|
130
|
-
|
|
139
|
+
if (attributeValue && attributeValue.includes("=>") || attributeValue && attributeValue.includes("function")
|
|
140
|
+
&& !spreadFunctions.includes(attributeValue)
|
|
141
|
+
) {
|
|
142
|
+
|
|
131
143
|
let ref = Math.random().toString(36).substring(2).split('').filter((e) => !Number(e)).join('')
|
|
132
144
|
let old = `${attributeName}${attributeValue}`
|
|
133
|
-
|
|
134
|
-
string.split("\n").forEach((line) => {
|
|
135
|
-
if (line.includes(name) && line.includes("function")) {
|
|
136
|
-
line = line.trim();
|
|
137
|
-
line = line.replace(/\s+/g, " ");
|
|
138
|
-
|
|
139
|
-
let ps = line.split("(").slice(1).join("(").split(")")[0].trim();
|
|
140
|
-
|
|
141
|
-
// remove comments
|
|
142
|
-
ps = ps.match(/\/\*.*\*\//gs)
|
|
143
|
-
? ps.replace(ps.match(/\/\*.*\*\//gs)[0], "")
|
|
144
|
-
: ps;
|
|
145
|
-
functionparams.push({ ref: ref, name: name, params: ps });
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
});
|
|
149
|
-
});
|
|
145
|
+
|
|
150
146
|
let elementMatch = string.match(/<([a-zA-Z0-9_-]+)([^>]*)>/gs);
|
|
151
147
|
let isJSXComponent = false;
|
|
152
148
|
elementMatch.forEach((element) => {
|
|
@@ -200,8 +196,7 @@ function Compiler(func, file) {
|
|
|
200
196
|
newvalue = newvalue.replace(/}\s*$/, '');
|
|
201
197
|
|
|
202
198
|
|
|
203
|
-
|
|
204
|
-
functionparams.length > 0 ? params = params + ',' + functionparams.map((e) => e.name).join(',') : null
|
|
199
|
+
|
|
205
200
|
|
|
206
201
|
newvalue = newvalue.replaceAll(',,', ',')
|
|
207
202
|
let paramnames = params ? params.split(',').map((e) => e.trim()) : null
|
|
@@ -224,6 +219,10 @@ function Compiler(func, file) {
|
|
|
224
219
|
}
|
|
225
220
|
}
|
|
226
221
|
|
|
222
|
+
/**
|
|
223
|
+
* @search - handle attributes for html elements
|
|
224
|
+
* @keywords - attributes, props, html attributes
|
|
225
|
+
*/
|
|
227
226
|
let match;
|
|
228
227
|
while ((match = elementRegex.exec(code)) !== null) {
|
|
229
228
|
let [, element, attributes] = match;
|
|
@@ -248,8 +247,7 @@ function Compiler(func, file) {
|
|
|
248
247
|
let returns = code.match(/return\s*\<>.*\<\/>|return\s*\(.*\)/gs);
|
|
249
248
|
|
|
250
249
|
return returns || [];
|
|
251
|
-
}
|
|
252
|
-
// throw error if return is not wrapped in <></> or
|
|
250
|
+
}
|
|
253
251
|
if (string.match(/return\s*\<>|return\s*\(.*\)/gs) && !string.match(/return\s*\<>.*\<\/>|return\s*\(.*\)/gs)
|
|
254
252
|
|| string.match(/return\s*\<[a-zA-Z0-9_-]+.*>/gs)
|
|
255
253
|
) {
|
|
@@ -265,6 +263,10 @@ function Compiler(func, file) {
|
|
|
265
263
|
let outerReturn = extractOuterReturn(string);
|
|
266
264
|
let contents = "";
|
|
267
265
|
let updatedContents = "";
|
|
266
|
+
/**
|
|
267
|
+
* @search - handle return [...]
|
|
268
|
+
* @keywords - return, return jsx, return html, return [...]
|
|
269
|
+
*/
|
|
268
270
|
outerReturn.forEach((returnStatement) => {
|
|
269
271
|
|
|
270
272
|
let lines = returnStatement.split("\n");
|
|
@@ -278,13 +280,12 @@ function Compiler(func, file) {
|
|
|
278
280
|
}
|
|
279
281
|
let usesBraces = returnStatement.match(/return\s*\(/gs) ? true : false;
|
|
280
282
|
|
|
281
|
-
|
|
282
|
-
// Remove trailing ']' or trailing )
|
|
283
|
+
|
|
283
284
|
contents = contents.trim().replace(/\]$/, "")
|
|
284
285
|
contents = contents.replace(/\)$/, "");
|
|
285
286
|
usesBraces ? !contents.includes('<>') ? contents = `<>${contents}</>` : null : null
|
|
286
287
|
updatedContents = contents;
|
|
287
|
-
|
|
288
|
+
let attributes = extractAttributes(contents);
|
|
288
289
|
|
|
289
290
|
let newAttributes = [];
|
|
290
291
|
let oldAttributes = [];
|
|
@@ -363,9 +364,7 @@ function Compiler(func, file) {
|
|
|
363
364
|
valuestate = valuestate.match(regex) ? valuestate.match(regex)[0].split("useState(")[1].split(")")[0].trim() : valuestate
|
|
364
365
|
|
|
365
366
|
|
|
366
|
-
let newState = `${varType} [${key}, ${setKey}] = this.useState('${key}', ${valuestate}
|
|
367
|
-
|
|
368
|
-
`;
|
|
367
|
+
let newState = `${varType} [${key}, ${setKey}] = this.useState('${key}', ${valuestate}`;
|
|
369
368
|
string = string.replace(line, newState);
|
|
370
369
|
break;
|
|
371
370
|
case line.includes("useRef") && !line.includes("import"):
|
|
@@ -410,25 +409,24 @@ function Compiler(func, file) {
|
|
|
410
409
|
string = string.replaceAll('../src', './src')
|
|
411
410
|
|
|
412
411
|
function parseComponents(body, isChild) {
|
|
413
|
-
let componentRegex = /<([A-Z][A-Za-z0-9_-]+)([^>]*)
|
|
412
|
+
let componentRegex = /<([A-Z][A-Za-z0-9_-]+)\s*([^>]*)>\s*([\s\S]*?)\s*<\/\1>|<([A-Z][A-Za-z0-9_-]+)([^]*?)\/>/gs;
|
|
414
413
|
|
|
415
414
|
let componentMatch = body.match(componentRegex);
|
|
416
415
|
let topComponent = "";
|
|
417
416
|
componentMatch?.forEach(async (component) => {
|
|
418
417
|
|
|
419
418
|
let [, element, attributes] = component;
|
|
420
|
-
|
|
419
|
+
let before = component;
|
|
420
|
+
component = component.trim().replace(/\s+/g, " ");
|
|
421
421
|
|
|
422
422
|
!isChild ? (topComponent = component) : null;
|
|
423
|
-
|
|
423
|
+
|
|
424
424
|
|
|
425
425
|
let myChildrens = [];
|
|
426
426
|
|
|
427
427
|
let name = component.split("<")[1].split(">")[0].split(" ")[0].replace("/", "");
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
const dynamicAttributesRegex = /(\w+)(?:="([^"]*)")?(?:='([^']*)')?(?:=\{([^}]*)\})?(?:=\{(.*?)\})?(?:={([^}]*)})?(?:{([^}]*)})?|(?:{(?:[^{}]+|\{(?:[^{}]+|\{[^}]*\})*\})*\})|(\.{3}\{(?:[^{}]+|\{(?:[^{}]+|\{[^}]*\})*\})*\})/gs;
|
|
431
|
-
|
|
428
|
+
let componentAttributes = component.split("<")[1].split(">")[0].split(" ").join(" ").replace(name, "").trim();
|
|
429
|
+
const dynamicAttributesRegex = /(\w+)(?:="([^"]*)")?(?:='([^']*)')?(?:=\{([^}]*)\})?(?:=\{(.*?)\})?(?:={([^}]*)})?(?:{([^}]*)})?|(?:{(?:[^{}]+|\{(?:[^{}]+|\{[^}]*\})*\})*\})|(\.{3}\{(?:[^{}]+|\{(?:[^{}]+|\{[^}]*\})*\})*\})|\$=\{(?:[^{}]+|\{(?:[^{}]+|\{[^}]*\})*\})*\}/gs;
|
|
432
430
|
|
|
433
431
|
|
|
434
432
|
|
|
@@ -439,18 +437,31 @@ function Compiler(func, file) {
|
|
|
439
437
|
let filteredProps = [];
|
|
440
438
|
let isWithinComponent = false;
|
|
441
439
|
let componentName = name
|
|
440
|
+
let currentProps = []
|
|
441
|
+
|
|
442
|
+
let $_ternaryprops = []
|
|
442
443
|
|
|
443
444
|
for (let prop of props) {
|
|
444
445
|
|
|
445
446
|
if (prop === componentName) {
|
|
446
|
-
|
|
447
|
-
// If the component is encountered, start collecting props
|
|
447
|
+
|
|
448
448
|
isWithinComponent = true;
|
|
449
449
|
filteredProps.push(prop);
|
|
450
450
|
} else if (isWithinComponent && prop.includes('=')) {
|
|
451
451
|
|
|
452
|
-
if (prop.
|
|
453
|
-
|
|
452
|
+
if (prop.startsWith('$=')) {
|
|
453
|
+
let old = prop
|
|
454
|
+
prop = prop.replace('$=', '$_ternary=')
|
|
455
|
+
|
|
456
|
+
// remove trailing }
|
|
457
|
+
prop = prop.replace(/}\s*$/, '')
|
|
458
|
+
component = component.replace(old, prop)
|
|
459
|
+
componentAttributes = componentAttributes.replace(old, prop)
|
|
460
|
+
|
|
461
|
+
$_ternaryprops.push(prop)
|
|
462
|
+
|
|
463
|
+
}
|
|
464
|
+
else if (prop.includes('${')) {
|
|
454
465
|
|
|
455
466
|
prop = prop.replace('="', ':').replace('}"', '}')
|
|
456
467
|
if (prop.includes('${')) {
|
|
@@ -467,7 +478,7 @@ function Compiler(func, file) {
|
|
|
467
478
|
}
|
|
468
479
|
|
|
469
480
|
}
|
|
470
|
-
if (prop.startsWith('={')) {
|
|
481
|
+
else if (prop.startsWith('={')) {
|
|
471
482
|
prop = prop.replace('={', ':`${')
|
|
472
483
|
prop.replace('} ', '}`')
|
|
473
484
|
}
|
|
@@ -487,72 +498,25 @@ function Compiler(func, file) {
|
|
|
487
498
|
filteredProps.push(prop);
|
|
488
499
|
|
|
489
500
|
|
|
490
|
-
}
|
|
491
|
-
else if (isWithinComponent && prop.includes('...')) {
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
// Check if spread props are within curly braces
|
|
496
|
-
if (prop.startsWith('{') && prop.endsWith('}')) {
|
|
497
|
-
const spreadObject = prop
|
|
498
|
-
const hasOtherObjects = spreadObject.split(',').filter((e) => e.includes(':')).length > 0;
|
|
499
|
-
|
|
500
|
-
const isValidSpread = spreadObject.includes('...');
|
|
501
|
-
|
|
502
|
-
let processedSpreadObject = '';
|
|
503
|
-
if (isValidSpread) {
|
|
504
|
-
// Split the spreadObject by commas and process each part individually
|
|
505
|
-
const parts = spreadObject.split(',').map((part) => {
|
|
506
|
-
if (part.trim().startsWith('{') && part.trim().endsWith('}')) {
|
|
507
|
-
const nestedParts = part
|
|
508
|
-
.trim()
|
|
509
|
-
.slice(1, -1) // Remove outer {}
|
|
510
|
-
.split(',')
|
|
511
|
-
.map((nestedPart) => {
|
|
512
|
-
return nestedPart.includes('...') ? nestedPart.trim().replace(/\.\.\./, '') : `...${nestedPart.trim()}`;
|
|
513
|
-
});
|
|
514
|
-
return `{${nestedParts.join(',')}}`;
|
|
515
|
-
} else {
|
|
516
|
-
return part.includes('...') ? part.trim() : part.trim().startsWith('{') ? `...${part.trim()}` : `${part.trim()}`;
|
|
517
|
-
}
|
|
518
|
-
});
|
|
519
|
-
if (!parts.join(',').includes('{(')) {
|
|
520
|
-
|
|
521
|
-
processedSpreadObject = `${parts.join(',')}`
|
|
522
|
-
|
|
523
|
-
} else {
|
|
524
|
-
let prop = parts.join(',')
|
|
525
|
-
prop = prop.replaceAll('{(', '(')
|
|
526
|
-
prop = prop.replaceAll(')}', ')')
|
|
527
|
-
processedSpreadObject = prop
|
|
528
|
-
}
|
|
529
|
-
if (prop.includes('{{')) {
|
|
530
|
-
let prop = parts.join(',')
|
|
531
|
-
prop = prop.replaceAll('{{', '{')
|
|
532
|
-
prop = prop.replaceAll('}}', '}')
|
|
533
|
-
processedSpreadObject = prop
|
|
534
|
-
}
|
|
535
|
-
|
|
536
501
|
|
|
537
|
-
} else {
|
|
538
|
-
// Process nested structures within the object
|
|
539
|
-
processedSpreadObject = `{...${spreadObject}}`;
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
const $propsKey = `$props_${Math.random().toString(36).substring(2)}`;
|
|
543
|
-
filteredProps.push(`${$propsKey}:${processedSpreadObject}`);
|
|
544
|
-
}
|
|
545
502
|
}
|
|
546
503
|
|
|
504
|
+
|
|
547
505
|
else {
|
|
548
506
|
isWithinComponent = false;
|
|
549
507
|
}
|
|
550
508
|
}
|
|
509
|
+
component = component.replaceAll(/\s+/g, " ");
|
|
551
510
|
|
|
552
|
-
|
|
553
|
-
|
|
511
|
+
component = component.replace(componentAttributes, '')
|
|
512
|
+
$_ternaryprops.forEach((prop) => {
|
|
513
|
+
component = component.replace(prop, '')
|
|
514
|
+
})
|
|
554
515
|
|
|
555
|
-
|
|
516
|
+
let children = component.split(`<${name}`)[1].split(`</${name}>`)[0].trim().replace(/\s+/g, " ").trim().replace(/,$/, '').replace('>', '').replace(/\/$/, '').trim()
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
props = filteredProps.join(',').replace(/\s+/g, " ").trim().replace(/,$/, '')
|
|
556
520
|
|
|
557
521
|
let savedname = name;
|
|
558
522
|
|
|
@@ -573,12 +537,13 @@ function Compiler(func, file) {
|
|
|
573
537
|
/<([A-Z][A-Za-z0-9_-]+)([^>]*)>(.*?)<\/\1>|<([A-Z][A-Za-z0-9_-]+)([^]*?)\/>/gs
|
|
574
538
|
);
|
|
575
539
|
if (html) {
|
|
576
|
-
html = html.map((h) => h.trim().replace(/\s+/g, " ")).join(" ");
|
|
540
|
+
html = html.map((h) => h.trim().replace(/\s+/g, " ")).join(" ");
|
|
577
541
|
child.children = child.children.replaceAll(html, `${html}`);
|
|
578
542
|
// remove duplicate quotes
|
|
579
543
|
}
|
|
580
544
|
|
|
581
545
|
myChildrens.push(child.children);
|
|
546
|
+
childs = childs.filter((e) => e.parent !== name);
|
|
582
547
|
}
|
|
583
548
|
});
|
|
584
549
|
|
|
@@ -599,8 +564,10 @@ function Compiler(func, file) {
|
|
|
599
564
|
* @memoize - memoize a component to be remembered on each render and replace the old jsx
|
|
600
565
|
*/
|
|
601
566
|
|
|
567
|
+
|
|
602
568
|
let replace = "";
|
|
603
|
-
replace = `\${this.memoize(this.createComponent(${savedname}, {${props}}, [\`${myChildrens.join(
|
|
569
|
+
replace = `\${this.memoize(this.createComponent(${savedname}, {${props}}, [\`${myChildrens.join('')}\`]))}`;
|
|
570
|
+
|
|
604
571
|
|
|
605
572
|
body = body.replace(before, replace);
|
|
606
573
|
});
|
|
@@ -613,55 +580,56 @@ function Compiler(func, file) {
|
|
|
613
580
|
const importRegex = /import\s*([^\s,]+|\{[^}]+\})\s*from\s*(['"])(.*?)\2/g;
|
|
614
581
|
const imports = string.match(importRegex);
|
|
615
582
|
let replaceMents = [];
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
for
|
|
583
|
+
|
|
584
|
+
|
|
585
|
+
for (let match of imports) {
|
|
619
586
|
let path = match.split('from')[1].trim().replace(/'/g, '').replace(/"/g, '').trim()
|
|
620
587
|
switch (true) {
|
|
621
588
|
case path && !path.includes('./') && !path.includes('/vader.js') && !path.includes('/vaderjs/client') && !path.startsWith('src') && !path.startsWith('public') && !path.includes('http') && !path.includes('https'):
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
589
|
+
let componentFolder = fs.existsSync(process.cwd() + '/node_modules/' + path) ? process.cwd() + '/node_modules/' + path : process.cwd() + '/node_modules/' + path.split('/')[0]
|
|
590
|
+
componentFolder = componentFolder.split(process.cwd())[1]
|
|
591
|
+
if (!fs.existsSync(process.cwd() + componentFolder)) {
|
|
625
592
|
throw new Error('Could not find ' + path + ' at ' + match + ' in file ' + file)
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
if (!fs.existsSync(process.cwd() + '/dist/src/' + componentFolder.split('/').slice(2).join('/'))) {
|
|
596
|
+
fs.mkdirSync(process.cwd() + '/dist/src/' + componentFolder.split('/').slice(2).join('/'), { recursive: true })
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
let baseFolder = componentFolder.split('node_modules')[1].split('/')[1]
|
|
600
|
+
let glp = globSync('**/**/**/**.{jsx,js}', {
|
|
601
|
+
cwd: process.cwd() + '/node_modules/' + baseFolder + '/',
|
|
602
|
+
absolute: true,
|
|
603
|
+
recursive: true
|
|
604
|
+
})
|
|
605
|
+
for (let file of glp) {
|
|
606
|
+
let text = fs.readFileSync(file, "utf8");
|
|
607
|
+
if (!file.endsWith('.js') && file.endsWith('.jsx')) {
|
|
608
|
+
text = Compiler(text, file);
|
|
609
|
+
|
|
630
610
|
}
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
let dest = file.split('node_modules')[1]
|
|
644
|
-
dest = dest.split(baseFolder)[1]
|
|
645
|
-
// write to dist
|
|
646
|
-
writer(process.cwd() + '/dist/src/' + baseFolder + dest, text)
|
|
647
|
-
let importname = match.split('import')[1].split('from')[0].trim()
|
|
648
|
-
let oldImportstring = match.split('from')[1].trim().replace(/'/g, '').replace(/"/g, '').trim()
|
|
649
|
-
let newImport = `/src/${baseFolder + dest}`
|
|
650
|
-
newImport = newImport.replaceAll('.jsx', '.js').replaceAll('\\', '/')
|
|
651
|
-
replaceMents.push({ match: oldImportstring, replace: newImport })
|
|
652
|
-
console.log(`📦 imported Node Package ${baseFolder} `)
|
|
653
|
-
}
|
|
654
|
-
|
|
611
|
+
let dest = file.split('node_modules')[1]
|
|
612
|
+
dest = dest.split(baseFolder)[1]
|
|
613
|
+
// write to dist
|
|
614
|
+
writer(process.cwd() + '/dist/src/' + baseFolder + dest, text)
|
|
615
|
+
let importname = match.split('import')[1].split('from')[0].trim()
|
|
616
|
+
let oldImportstring = match.split('from')[1].trim().replace(/'/g, '').replace(/"/g, '').trim()
|
|
617
|
+
let newImport = `/src/${baseFolder + dest}`
|
|
618
|
+
newImport = newImport.replaceAll('.jsx', '.js').replaceAll('\\', '/')
|
|
619
|
+
replaceMents.push({ match: oldImportstring, replace: newImport })
|
|
620
|
+
console.log(`📦 imported Node Package ${baseFolder} `)
|
|
621
|
+
}
|
|
622
|
+
|
|
655
623
|
|
|
656
624
|
break;
|
|
657
625
|
default:
|
|
658
626
|
break;
|
|
659
627
|
}
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
for(let replace of replaceMents){
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
for (let replace of replaceMents) {
|
|
663
631
|
string = string.replaceAll(replace.match, replace.replace)
|
|
664
|
-
}
|
|
632
|
+
}
|
|
665
633
|
|
|
666
634
|
string = string.replaceAll(/\$\{[^{]*\.{3}/gs, (match) => {
|
|
667
635
|
if (match.includes('...')) {
|
|
@@ -716,7 +684,7 @@ function Compiler(func, file) {
|
|
|
716
684
|
let asyncimportMatch = line.match(/import\s*\((.*)\)/gs);
|
|
717
685
|
// handle import { Component } from 'vaderjs/runtime/vader.js'
|
|
718
686
|
let regularimportMatch = line.match(/import\s*([A-Za-z0-9_-]+)\s*from\s*([A-Za-z0-9_-]+)|import\s*([A-Za-z0-9_-]+)\s*from\s*(".*")|import\s*([A-Za-z0-9_-]+)\s*from\s*('.*')|import\s*([A-Za-z0-9_-]+)\s*from\s*(\{.*\})/gs);
|
|
719
|
-
|
|
687
|
+
|
|
720
688
|
if (asyncimportMatch) {
|
|
721
689
|
asyncimportMatch.forEach(async (match) => {
|
|
722
690
|
let beforeimport = match
|
|
@@ -770,7 +738,7 @@ function Compiler(func, file) {
|
|
|
770
738
|
|
|
771
739
|
let newImport = ''
|
|
772
740
|
let name = match.split('import')[1].split('from')[0].trim()
|
|
773
|
-
|
|
741
|
+
|
|
774
742
|
|
|
775
743
|
switch (true) {
|
|
776
744
|
case path && path.includes('json'):
|
|
@@ -796,9 +764,9 @@ function Compiler(func, file) {
|
|
|
796
764
|
newImport = ``
|
|
797
765
|
break;
|
|
798
766
|
case path && !path.startsWith('./') && !path.includes('/vader.js') && !path.startsWith('src') && !path.startsWith('public') &&
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
767
|
+
path.match(/^[A-Za-z0-9_-]+$/gs) && !path.includes('http') && !path.includes('https'):
|
|
768
|
+
|
|
769
|
+
break;
|
|
802
770
|
default:
|
|
803
771
|
let beforePath = path
|
|
804
772
|
let deep = path.split('/').length - 1
|
|
@@ -856,14 +824,7 @@ async function Build() {
|
|
|
856
824
|
return text;
|
|
857
825
|
};
|
|
858
826
|
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
// Process files in the 'pages' directory
|
|
865
|
-
let appjs = '';
|
|
866
|
-
let hasWritten = []
|
|
827
|
+
|
|
867
828
|
function ssg(routes = []) {
|
|
868
829
|
globalThis.isBuilding = true
|
|
869
830
|
console.log(`Generating html files for ${routes.length} routes`)
|
|
@@ -1019,38 +980,47 @@ async function Build() {
|
|
|
1019
980
|
headless: "new", args: ['--no-sandbox', '--disable-setuid-sandbox'],
|
|
1020
981
|
warning: false,
|
|
1021
982
|
})
|
|
1022
|
-
|
|
983
|
+
|
|
1023
984
|
const browserPID = browser.process().pid
|
|
1024
985
|
try {
|
|
1025
986
|
|
|
1026
987
|
route.url = route.url.replaceAll(/\/:[a-zA-Z0-9_-]+/gs, '')
|
|
1027
988
|
let page = await browser.newPage();
|
|
1028
989
|
await page.goto(`http://localhost:${port}/`, { waitUntil: 'networkidle2' });
|
|
990
|
+
await page.on('console', msg => console.log('PAGE LOG:', msg.text()));
|
|
991
|
+
await page.on('error', err => console.log('PAGE LOG:', err));
|
|
992
|
+
await page.on('pageerror', err => console.log('PAGE LOG:', err));
|
|
993
|
+
await page.evaluate(() => {
|
|
994
|
+
window.onerror = function (msg, url, lineNo, columnNo, error) {
|
|
995
|
+
console.log(msg, url, lineNo, columnNo, error)
|
|
996
|
+
}
|
|
997
|
+
})
|
|
1029
998
|
await page.waitForSelector('#root', { timeout: 10000 })
|
|
1030
999
|
await page.evaluate(() => {
|
|
1031
1000
|
document.getElementById('meta').remove()
|
|
1032
1001
|
document.querySelector('#isServer').innerHTML = 'window.isServer = false'
|
|
1033
1002
|
if (document.head.getAttribute('prerender') === 'false') {
|
|
1034
1003
|
document.querySelector('#root').innerHTML = ''
|
|
1004
|
+
console.log(`Disabled prerendering for ${window.location.pathname}`)
|
|
1035
1005
|
}
|
|
1036
|
-
})
|
|
1006
|
+
})
|
|
1037
1007
|
const html = await page.content();
|
|
1038
1008
|
|
|
1039
1009
|
await page.close();
|
|
1040
1010
|
await writer(process.cwd() + '/dist/' + (route.url === '/' ? 'index.html' : `${route.url}/` + 'index.html'), html)
|
|
1041
1011
|
await browser.close();
|
|
1042
1012
|
server.close()
|
|
1043
|
-
|
|
1013
|
+
|
|
1044
1014
|
} catch (error) {
|
|
1045
1015
|
server.close()
|
|
1046
|
-
await browser.close();
|
|
1016
|
+
await browser.close();
|
|
1047
1017
|
}
|
|
1048
1018
|
finally {
|
|
1049
1019
|
await browser.close();
|
|
1050
|
-
server.close()
|
|
1020
|
+
server.close()
|
|
1051
1021
|
}
|
|
1052
1022
|
try {
|
|
1053
|
-
process.kill(browserPID
|
|
1023
|
+
process.kill(browserPID)
|
|
1054
1024
|
} catch (error) {
|
|
1055
1025
|
}
|
|
1056
1026
|
|
|
@@ -1093,10 +1063,10 @@ async function Build() {
|
|
|
1093
1063
|
|
|
1094
1064
|
|
|
1095
1065
|
let data = await fs.readFileSync(origin, "utf8");
|
|
1066
|
+
console.log(`Compiling ${fileName}...`)
|
|
1096
1067
|
data = Compiler(data, origin);
|
|
1097
1068
|
|
|
1098
1069
|
|
|
1099
|
-
|
|
1100
1070
|
await writer(process.cwd() + "/dist/" + fileName.replace('.jsx', '.js'), data).then(async () => {
|
|
1101
1071
|
|
|
1102
1072
|
|
|
@@ -1259,7 +1229,7 @@ async function Build() {
|
|
|
1259
1229
|
console.log(`📦 Build completed: Build Size -> ${Math.round(bundleSize / 1000)}kb`)
|
|
1260
1230
|
|
|
1261
1231
|
bundleSize = 0;
|
|
1262
|
-
|
|
1232
|
+
|
|
1263
1233
|
return true
|
|
1264
1234
|
}
|
|
1265
1235
|
const s = () => {
|
|
@@ -1389,7 +1359,7 @@ Vader.js v1.3.3
|
|
|
1389
1359
|
}
|
|
1390
1360
|
}).on('error', (err) => console.log(err))
|
|
1391
1361
|
})
|
|
1392
|
-
let p = process.argv[process.argv.indexOf('--watch') + 1] ||
|
|
1362
|
+
let p = process.argv[process.argv.indexOf('--watch') + 1] || process.env.PORT || 3000
|
|
1393
1363
|
|
|
1394
1364
|
process.env.PORT = p
|
|
1395
1365
|
s()
|