vaderjs 1.3.3-alpha-100 → 1.3.3-alpha-101

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 CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "vaderjs",
3
3
  "description": "A Reactive library aimed to helping you build reactive applications inspired by react.js",
4
4
  "module": "vader.js",
5
- "version": "1.3.3-alpha-100",
5
+ "version": "1.3.3-alpha-101",
6
6
  "bin": {
7
7
  "vader": "./vader.js"
8
8
  },
@@ -28,6 +28,7 @@
28
28
  },
29
29
  "dependencies": {
30
30
  "glob": "latest",
31
- "terser":"latest"
31
+ "terser":"latest",
32
+ "puppeteer":"latest"
32
33
  }
33
34
  }
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)),this.listeners.push(e),1===this.listeners.length?this.handleRoute(window.location.hash):this.listeners.pop(),t&&t(),window.onhashchange=()=>{this.handleRoute(window.location.hash)}}extractParams(e,t){const s=e.split("/"),n=t.split("/"),r={};return s.forEach(((e,t)=>{if(e.startsWith(":")){const s=e.slice(1);r[s]=n[t]}else if(e.startsWith("*")){n.slice(t).forEach(((e,t)=>{r[t]=e}))}})),r}extractQueryParams(e){const t=e.split("?")[1];if(!t)return{};const s={};return t.split("&").forEach((e=>{const[t,n]=e.split("=");s[t]=n})),s}handleRoute(e){let t=200,s=e=e.slice(1),n=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 s=t.path.split("/"),n=e.split("/");if(s.length!==n.length&&!t.path.endsWith("*"))return!1;for(let e=0;e<s.length;e++){const t=s[e],r=n[e];if(!t.startsWith(":")&&!t.startsWith("*")&&t!==r)return!1}return!0}const n=this.extractParams(t.path,s);return Object.keys(n).length>0}));n||(n=this.routes.find((e=>{if(e.path.includes("/404"))return this.error=!0,!0;!this.error&&e.path.includes("/404")&&(window.location.hash=this.basePath)})),t=n?200:404);const r=this.extractQueryParams(s),o=n&&n.path?this.extractParams(n.path,s):{};Object.keys(o).forEach((e=>{o[e]=o[e].split("?")?o[e].split("?")[0]:o[e]}));const a={headers:{},params:o,query:r,path:e,url:window.location.href,method:n?n.method:"get",pause:!1,timestamp:Date.now()};window.$CURRENT_URL=a.path,window.$FULL_URL=window.location.href.replace("#","");const i={status:t,log:e=>{void 0===e?console.log(`${a.path} ${a.method} ${i.status} ${a.timestamp}`):console.table({"Request Path":a.path,"Request Method":n.method,"Response Status":i.status,"Request Timestamp":a.timestamp})},refresh:()=>{this.handleRoute(window.location.hash)},redirect:e=>{!e.startsWith("/")&&(e=`/${e}`),window.location.hash=`#${e}`},render:async(e,t,s)=>{function n(e){return"function"==typeof e&&/^class\s/.test(Function.prototype.toString.call(e))}try{let a=new Component;if(n(e.default)){let t=new e.default;a.state=t.state,a=t}else{if(e.default.toString().includes("this.key"))throw new Error('Using this.key is not supported in functional components use the attribute key="a value" instead');a.key=e.default.toString().split('key="')[1]?e.default.toString().split('key="')[1].split('"')[0]:null;let n={key:a.key,render:()=>e.default.apply(a,[t,s]),request:t,response:s,params:o,queryParams:r,reset:a.reset.bind(a),onMount:a.onMount.bind(a),useState:null,router:{use:a.router.use.bind(a)},bindMount:a.bindMount.bind(a),memoize:a.memoize.bind(a),createComponent:a.createComponent.bind(a),isChild:!1,useState:a.useState.bind(a),parseStyle:a.parseStyle.bind(a),bind:a.bind.bind(a),useRef:a.useRef.bind(a),useReducer:a.useReducer.bind(a),onMount:a.onMount.bind(a),onUnmount:a.onUnmount.bind(a),hydrate:a.hydrate.bind(a)};a.render=n.render,a=n}if(!document.querySelector("#root"))throw new Error("Root element not found, please add an element with id root");a.reset(),a.components={},a.request=t,a.response=s,a.router.use&&!a.isChild?await new Promise((async r=>{if(n(e.default))if(n(e.default))switch(await a.router.use(t,s),t.pause){case!0:console.log("pausing",t.pause);let e=setInterval((()=>{t.pause?console.log("still pausing",t.pause):(clearInterval(e),r())}),1e3);break;case!1:r()}else r();else switch(await e.default.apply(a,[t,s]),await a.router.use(t,s),t.pause){case!0:let e=setInterval((()=>{t.pause?console.log("still pausing request",t.url):(clearInterval(e),r())}),1e3);break;case!1:r()}})):a.router.use&&a.isChild&&console.warn("Router.use() is not supported in child components");const i=await a.render();document.querySelector("#root").innerHTML=i,a.bindMount(),a.onMount()}catch(e){console.error(e)}},setQuery:e=>{let t="";Object.keys(e).forEach(((s,n)=>{t+=`${0===n?"?":"&"}${s}=${e[s]}`}));let s=window.location.hash.split("?")[0];t=t.replace("/","-").replaceAll("/","-"),window.location.hash=`${s}${t}`},send:e=>{document.querySelector("#root").innerHTML=e},json:e=>{const t=document.querySelector("#root");t.innerHTML="";const s=document.createElement("pre");s.textContent=JSON.stringify(e,null,2),t.appendChild(s)}};middlewares.forEach((e=>{e(a,i)})),n&&n.handler(a,i)}}window.VaderRouter=VaderRouter;export default VaderRouter;
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)),this.listeners.push(e),1===this.listeners.length?this.handleRoute(window.location.hash.length>0?window.location.hash:window.location.pathname):this.listeners.pop(),t&&t(),window.onhashchange=()=>{this.handleRoute(window.location.hash)}}extractParams(e,t){const s=e.split("/"),n=t.split("/"),o={};return s.forEach(((e,t)=>{if(e.startsWith(":")){const s=e.slice(1);o[s]=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 s={};return t.split("&").forEach((e=>{const[t,n]=e.split("=");s[t]=n})),s}handleRoute(e){e=e.includes("#")?e.slice(1):e,console.log(e);let t=200,s=e,n=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 s=t.path.split("/"),n=e.split("/");if(s.length!==n.length&&!t.path.endsWith("*"))return!1;for(let e=0;e<s.length;e++){const t=s[e],o=n[e];if(!t.startsWith(":")&&!t.startsWith("*")&&t!==o)return!1}return!0}const n=this.extractParams(t.path,s);return Object.keys(n).length>0}));n||(n=this.routes.find((e=>{if(e.path.includes("/404"))return this.error=!0,!0;!this.error&&e.path.includes("/404")&&(window.location.hash=this.basePath)})),t=n?200:404);const o=this.extractQueryParams(s),r=n&&n.path?this.extractParams(n.path,s):{};Object.keys(r).forEach((e=>{r[e]=r[e].split("?")?r[e].split("?")[0]:r[e]}));const i={headers:{},params:r,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.hash)},redirect:e=>{!e.startsWith("/")&&(e=`/${e}`),window.location.hash=`#${e}`},render:async(e,t,s,n)=>{function i(e){return"function"==typeof e&&/^class\s/.test(Function.prototype.toString.call(e))}try{let n=new Component;if(i(e.default)){let t=new e.default;n.state=t.state,n=t}else{if(e.default.toString().includes("this.key"))throw new Error('Using this.key is not supported in functional components use the attribute key="a value" instead');n.key=e.default.toString().split('key="')[1]?e.default.toString().split('key="')[1].split('"')[0]:null;let i={key:n.key,render:()=>e.default.apply(n,[t,s]),request:t,response:s,params:r,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=i.render,n=i,console.log(t)}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=s,n.router.use&&!n.isChild?await new Promise((async o=>{if(i(e.default))if(i(e.default))switch(await n.router.use(t,s),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,s]),await n.router.use(t,s),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 a=await n.render();document.querySelector("#root").innerHTML!==a&&(console.log("rendering"),document.querySelector("#root").innerHTML=a),n.bindMount(),n.onMount()}catch(e){console.error(e)}},setQuery:e=>{let t="";Object.keys(e).forEach(((s,n)=>{t+=`${0===n?"?":"&"}${s}=${e[s]}`}));let s=window.location.hash.split("?")[0];t=t.replace("/","-").replaceAll("/","-"),window.location.hash=`${s}${t}`},send:e=>{document.querySelector("#root").innerHTML=e},json:e=>{const t=document.querySelector("#root");t.innerHTML="";const s=document.createElement("pre");s.textContent=JSON.stringify(e,null,2),t.appendChild(s)}};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 n=setInterval((()=>{document.querySelector(`[key="${e}"]`)&&!hasRan.includes(e)&&(clearInterval(n),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,n){function s(e){return"function"==typeof e&&/^class\s/.test(Function.prototype.toString.call(e))}let r=s(e)?new e(t):null;if(!e)throw new Error("Component must be defined");let o=new Component(t);if(s(e))r.props=t,r.children=n,r.props.children=n.join(""),r.parentNode=this,r.request=this.request,r.response=this.response,r.key=t.key||null,o=r;else{e.toString();o.key=e.toString().split('key="')[1]?e.toString().split('key="')[1].split('"')[0]:null;let n={key:o.key,render:()=>e.apply(o,[t]),request:this.request,isChild:!0,response:this.response,params:this.request.params,queryParams:this.request.query,reset:o.reset.bind(o),onMount:o.onMount.bind(o),useState:null,router:{use:o.router.use.bind(o)},bindMount:o.bindMount.bind(o),memoize:o.memoize.bind(o),createComponent:o.createComponent.bind(o),isChild:!1,useState:o.useState.bind(o),parseStyle:o.parseStyle.bind(o),bind:o.bind.bind(o),useRef:o.useRef.bind(o),request:this.request,response:this.response,useReducer:o.useReducer.bind(o),hydrate:o.hydrate.bind(o),onUnmount:o.onUnmount.bind(o),parentNoe:this};o.render=n.render,o=n}return this.components[t.key]||(this.components[t.key]=o),!this.children.includes(o)&&this.children.push(o),this.components[t.key]}reset(){Object.keys(this.components).forEach((e=>{this.components[e].onUnmount(),delete this.components[e]})),this.state={},this.children=[]}memoize(e){if(!e.key)throw new Error("Component must have a static key");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 n=t.render();return n&&n.split(">,").length>1&&(n=n.replaceAll(">,",">")),`<div key="${e.key}">${n}</div>`}parseStyle(e){let t="";return Object.keys(e).forEach((n=>{let s=e[n];n=n.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g,"$1-$2").toLowerCase(),t+=`${n}:${s};`})),t}bindMount(){mounts.push(this)}domDifference(e,t){let n=[];for(let s=0;s<e.length;s++){let r=e[s],o=t[s];r&&o&&!r.isEqualNode(o)&&n.push({type:"replace",old:r,new:o.cloneNode(!0)})}return n}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(e);let t=(new DOMParser).parseFromString(this.render(),"text/html").body.querySelector(`[ref="${e}"]`),n=document.querySelector(`[ref="${e}"]`);console.log(t,n)}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 n=this.domDifference(e,t);this.updateChangedElements(n)}handleObject(obj){try{obj=JSON.parse(obj)}catch(e){}return eval(obj)}bind(e,t,n,s,...r){n=n+this.key||2022;let o={},i=(s=s.replace(/,,/g,",")).replaceAll(",,",",");for(var u in r){let e=r[u];o[i.split(",")[u]]=e}s=s.replace(",,",",");let a=null;try{a=new Function(`event, ${s}`,` \n return (async (event, ${s}) => { \n ${e.toString()}\n })(event, ${Object.keys(o).join(",")}) \n `)}catch(e){let{message:t}=e;console.error(`Error in function ${n} ${t}`)}return a=a.bind(this),this.functions.find((e=>e.ref===n))||document.addEventListener(`$dispatch_#id=${n}`,(e=>{let{name:t,event:s}=e.detail;if(t===n){let e=this.functions.find((e=>e.ref===n)).params;Object.keys(e).forEach((t=>{e[t]instanceof CustomEvent&&delete e[t],void 0===e[t]?delete e[t]:e[t]})),a(s,...Object.values(e))}})),window.callFunction=(e,t)=>{document.dispatchEvent(new CustomEvent(`$dispatch_#id=${e}`,{detail:{name:e,params:null,event:t}}))},!this.functions.find((e=>e.ref===n))&&this.functions.push({ref:n,params:o}),t?e:`((event)=>{event.target.ev = event; callFunction('${n}', event.target.ev)})(event)`}useState(e,t){this.state[e]||(this.state[e]=t);let n=()=>this.state[e],s=n();return[s,(t,r)=>{this.state[e]=t,this.hydrate(r),s=n()}]}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,n=null){this.state[e]||(this.state[e]=t);const s=()=>this.state[e];let r=s();return[s(),(t,o)=>{const i=n(r,t)??t;this.state[e]=i,this.hydrate(o),r=s()}]}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,n)=>{states[e]=t,this.hydrate(n)}]};export const useReducer=(e,t)=>[e,e=>{}];export const useRef=e=>({current:e,bind:""});export default{Component:Component,useRef:useRef,useReducer:useReducer,useState:useState,strictMount:strictMount};
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 n=setInterval((()=>{document.querySelector(`[key="${e}"]`)&&!hasRan.includes(e)&&(clearInterval(n),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,n){function s(e){return"function"==typeof e&&/^class\s/.test(Function.prototype.toString.call(e))}let r=s(e)?new e(t):null;if(!e)throw new Error("Component must be defined");let o=new Component(t);if(s(e))r.props=t,r.children=n,r.props.children=n.join(""),r.parentNode=this,r.request=this.request,r.response=this.response,r.key=t.key||null,o=r;else{e.toString();o.key=e.toString().split('key="')[1]?e.toString().split('key="')[1].split('"')[0]:null;let n={key:o.key,render:()=>e.apply(o,[t]),request:this.request,isChild:!0,response:this.response,params:this.request.params,queryParams:this.request.query,reset:o.reset.bind(o),onMount:o.onMount.bind(o),useState:null,router:{use:o.router.use.bind(o)},bindMount:o.bindMount.bind(o),memoize:o.memoize.bind(o),createComponent:o.createComponent.bind(o),isChild:!1,useState:o.useState.bind(o),parseStyle:o.parseStyle.bind(o),bind:o.bind.bind(o),useRef:o.useRef.bind(o),request:this.request,response:this.response,useReducer:o.useReducer.bind(o),hydrate:o.hydrate.bind(o),onUnmount:o.onUnmount.bind(o),parentNoe:this};o.render=n.render,o=n}return this.components[t.key]||(this.components[t.key]=o),!this.children.includes(o)&&this.children.push(o),this.components[t.key]}reset(){Object.keys(this.components).forEach((e=>{this.components[e].onUnmount(),delete this.components[e]})),this.state={},this.children=[]}memoize(e){if(!e.key)throw new Error("Component must have a static key");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 n=t.render();return n&&n.split(">,").length>1&&(n=n.replaceAll(">,",">")),`<div key="${e.key}">${n}</div>`}parseStyle(e){let t="";return Object.keys(e).forEach((n=>{let s=e[n];n=n.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g,"$1-$2").toLowerCase(),t+=`${n}:${s};`})),t}bindMount(){mounts.push(this)}domDifference(e,t){let n=[];for(let s=0;s<e.length;s++){let r=e[s],o=t[s];r&&o&&!r.isEqualNode(o)&&n.push({type:"replace",old:r,new:o.cloneNode(!0)})}return n}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 n=this.domDifference(e,t);this.updateChangedElements(n)}handleObject(obj){try{obj=JSON.parse(obj)}catch(e){}return eval(obj)}bind(e,t,n,s,...r){n=n+this.key||2022;let o={},i=(s=s.replace(/,,/g,",")).replaceAll(",,",",");for(var u in r){let e=r[u];o[i.split(",")[u]]=e}s=s.replace(",,",",");let a=null;try{a=new Function(`event, ${s}`,` \n return (async (event, ${s}) => { \n ${e.toString()}\n })(event, ${Object.keys(o).join(",")}) \n `)}catch(e){let{message:t}=e;console.error(`Error in function ${n} ${t}`)}return a=a.bind(this),this.functions.find((e=>e.ref===n))||document.addEventListener(`$dispatch_#id=${n}`,(e=>{let{name:t,event:s}=e.detail;if(t===n){let e=this.functions.find((e=>e.ref===n)).params;Object.keys(e).forEach((t=>{e[t]instanceof CustomEvent&&delete e[t],void 0===e[t]?delete e[t]:e[t]})),a(s,...Object.values(e))}})),window.callFunction=(e,t)=>{document.dispatchEvent(new CustomEvent(`$dispatch_#id=${e}`,{detail:{name:e,params:null,event:t}}))},!this.functions.find((e=>e.ref===n))&&this.functions.push({ref:n,params:o}),t?e:`((event)=>{event.target.ev = event; callFunction('${n}', event.target.ev)})(event)`}useState(e,t){this.state[e]||(this.state[e]=t);let n=()=>this.state[e],s=n();return[s,(t,r)=>{this.state[e]=t,this.hydrate(r),s=n()}]}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,n=null){this.state[e]||(this.state[e]=t);const s=()=>this.state[e];let r=s();return[s(),(t,o)=>{const i=n(r,t)??t;this.state[e]=i,this.hydrate(o),r=s()}]}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,n)=>{states[e]=t,this.hydrate(n)}]};export const useReducer=(e,t)=>[e,e=>{}];export const useRef=e=>({current:e,bind:""});export default{Component:Component,useRef:useRef,useReducer:useReducer,useState:useState,strictMount:strictMount};
package/vader.js CHANGED
@@ -1,6 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import fs from "fs";
3
3
  import { glob, globSync, globStream, globStreamSync, Glob, } from 'glob'
4
+ import puppeteer from 'puppeteer';
5
+ import http from 'http'
4
6
  let bundleSize = 0;
5
7
  let errorCodes = {
6
8
  "SyntaxError: Unexpected token '<'": "You forgot to enclose tags in a fragment <></>",
@@ -8,24 +10,14 @@ let errorCodes = {
8
10
  /**
9
11
  * define directories
10
12
  */
11
- let dirs = {
12
- ...fs.existsSync(process.cwd() + '/pages') ? { pages: true } : { pages: false },
13
- ...fs.existsSync(process.cwd() + '/src') ? { components: true } : { components: false },
14
- ...fs.existsSync(process.cwd() + '/public') ? { public: true } : { public: false },
15
- ...fs.existsSync(process.cwd() + '/dist') ? { dist: true } : { dist: false },
16
- ...fs.existsSync(process.cwd() + '/dist/pages') ? { distpages: true } : { distpages: false },
17
- ...fs.existsSync(process.cwd() + '/dist/src') ? { distcomponents: true } : { distcomponents: false },
18
- ...fs.existsSync(process.cwd() + '/dist/public') ? { distpublic: true } : { distpublic: false },
19
- }
13
+
20
14
 
15
+ if(!fs.existsSync(process.cwd() + '/dist')){
16
+ fs.mkdirSync(process.cwd() + '/dist')
17
+ }
21
18
 
22
- Object.keys(dirs).map((key, index) => {
23
- if (!dirs[key]) {
24
- fs.mkdirSync(process.cwd() + '/' + key)
25
- }
26
- }).filter(Boolean)[0]
27
19
 
28
- if (process.env.isCloudflare) {
20
+ if (process.env.isCloudflare || !process.cwd() + '/dist/index.html') {
29
21
  let htmlFile = fs.readFileSync(process.cwd() + "/node_modules/vaderjs/runtime/index.html", 'utf8')
30
22
  fs.writeFileSync(process.cwd() + "/dist/index.html", htmlFile)
31
23
  }
@@ -663,18 +655,7 @@ function Compiler(func, file) {
663
655
 
664
656
  }
665
657
 
666
- let html = fs.existsSync(process.cwd() + '/dist/index.html') ? fs.readFileSync(process.cwd() + '/dist/index.html', 'utf8') : ''
667
- if (!html.includes(`<link rel="preload" href="${path.replace(/'/g, '').trim()}" as="${path.replace(/'/g, '').trim().includes('.css') ? 'style' : 'script'}">`)
668
- && !path.includes('.module.css')
669
- ) {
670
- let preload = `
671
- ${path.trim().includes('.css') ? `<link rel="stylesheet" href="${path.trim().replace(/'/g, '').trim()}">` : ''
672
- }
673
- ${!path.trim().includes('.css') ? `<link rel="modulepreload" href="${path.trim().replace(/'/g, '').trim()}">` : ''}<link rel="preload" href="${path.trim().replace(/'/g, '').trim()}" as="${path.trim().includes('.css') ? 'style' : 'script'}">`
674
- html = html.replace('</head>', `${preload}\n</head>`)
675
-
676
- fs.writeFileSync(process.cwd() + '/dist/index.html', html)
677
- }
658
+
678
659
  if (newImport) {
679
660
  string = string.replace(beforeimport, newImport)
680
661
  }
@@ -716,24 +697,8 @@ async function Build() {
716
697
  globalThis.isWriting = null
717
698
  return { _written: true };
718
699
  };
719
- const scannedVaderFiles = await glob("**/**.{html,js}", {
720
- cwd: process.cwd() + '/node_modules/vaderjs/runtime',
721
- absolute: true,
722
- });
723
-
724
- scannedVaderFiles.forEach(async (file) => {
725
- file = file.replace(/\\/g, '/');
726
700
 
727
701
 
728
- let name = file.split('/node_modules/vaderjs/runtime/')[1]
729
- if (file.includes('index.html') && fs.existsSync(process.cwd() + "/dist/" + name)) {
730
- return
731
- }
732
- let data = await reader(file)
733
- bundleSize += fs.statSync(file).size;
734
- await writer(process.cwd() + "/dist/" + name, data);
735
- })
736
-
737
702
  const glb = await glob("**/**/**/**.{jsx,js}", {
738
703
  ignore: ["node_modules/**/*", "dist/**/*"],
739
704
  cwd: process.cwd() + '/pages/',
@@ -744,12 +709,146 @@ async function Build() {
744
709
  // Process files in the 'pages' directory
745
710
  let appjs = '';
746
711
  let hasWritten = []
747
- const writejs = () => {
748
-
749
- writer(process.cwd() + '/dist/app.js', appjs)
712
+ function ssg(routes = []) {
713
+ console.log(`Generating html files for ${routes.length} routes`)
714
+ routes.forEach(async (route) => {
715
+ if(route.url.includes(':')){
716
+ let url = route.url.split('/:')[0]
717
+ route.url = url
718
+ }
719
+ let equalparamroute = routes.map((e) => {
720
+
721
+ if (e.url.includes(':')) {
722
+ let url = e.url.split('/:')[0]
723
+ if(url&&route.url === url){
724
+ return e
725
+ }else{
726
+ return null
727
+
728
+ }
729
+ }
730
+ return null
731
+ }).filter(Boolean)
732
+ let document = `
733
+ <!DOCTYPE html>
734
+ <html lang="en">
735
+ <head>
736
+ <meta charset="UTF-8">
737
+ <meta name="viewport" content="width=device-width,initial-scale=1.0">
738
+ <script type="module" id="meta">
739
+ window.module = await import('/${route.fileName.replace('.jsx', '.js')}')
740
+ let metadata = await module.$metadata
741
+ if(metadata && metadata.title){
742
+ document.head.innerHTML += '<title>' + metadata.title + '</title>'
743
+ }
744
+ if(metadata && metadata.description){
745
+ document.head.innerHTML += '<meta name="description" content="' + metadata.description + '">'
746
+ }
747
+ if(metadata && metadata.keywords){
748
+ document.head.innerHTML += '<meta name="keywords" content="' + metadata.keywords + '">'
749
+ }
750
+ if(metadata && metadata.author){
751
+ document.head.innerHTML += '<meta name="author" content="' + metadata.author + '">'
752
+ }
753
+ if(metadata && metadata.image){
754
+ document.head.innerHTML += '<meta property="og:image" content="' + metadata.image + '">'
755
+ }
756
+ if(metadata && metadata.url){
757
+ document.head.innerHTML += '<meta property="og:url" content="' + metadata.url + '">'
758
+ }
759
+ if(metadata && metadata.styles){
760
+ metadata.styles.forEach(style => {
761
+ style = style.replaceAll('./', '/')
762
+ style = style.replaceAll('../', '/')
763
+ style = style.replace("'", '')
764
+ document.head.innerHTML += '<link rel="stylesheet" href="' + style + '">'
765
+ })
766
+ }
767
+ if(metadata && metadata.icon){
768
+ document.head.innerHTML += '<link rel="icon" href="' + metadata.icon + '">'
769
+ }
770
+ </script>
771
+ </head>
772
+ <body>
773
+ <div id="root"></div>
774
+ </body>
775
+
776
+ <script type="module">
777
+ import VaderRouter from '/router.js'
778
+ const router = new VaderRouter('${route.url}', 3000)
779
+ router.get('${route.url}', async (req, res) => {
780
+ let module = await import('/${route.fileName.replace('.jsx', '.js')}')
781
+ res.render(module, req, res, module.$metadata)
782
+ })
783
+ ${equalparamroute.length > 0 ? equalparamroute.map((e) => {
784
+ let folderName = '/' + e.url.split('/')[1]
785
+
786
+ e.url = e.url.replace(folderName, '')
787
+
788
+ return `router.get('${e.url}', async (req, res) => {
789
+ let module = await import('/${e.fileName.replace('.jsx', '.js')}')
790
+ res.render(module, req, res, module.$metadata)
791
+ })\n`
792
+ }): ''}
793
+ router.listen(3000)
794
+ </script>
795
+ </html>
796
+ `;
797
+
798
+ let port = Math.floor(Math.random() * 10000) + 1;
799
+
800
+ const server = http.createServer((req, res) => {
801
+ if (req.url === '/') {
802
+ // Respond with the generated HTML
803
+ res.writeHead(200, { 'Content-Type': 'text/html' });
804
+ res.end(document);
805
+ } else {
806
+ // Serve static files (adjust the file paths based on your project structure)
807
+ const filePath = process.cwd() + '/dist/' + req.url
808
+
809
+ fs.readFile(filePath, (err, data) => {
810
+ if (err) {
811
+ res.writeHead(404, { 'Content-Type': filePath.includes('js') ? 'text/javascript' : 'text/html' });
812
+ res.end('File not found');
813
+ } else {
814
+ res.writeHead(200, { 'Content-Type': filePath.includes('js') ? 'text/javascript' : 'text/html' });
815
+ res.end(data);
816
+ }
817
+ });
818
+ }
819
+ });
820
+
821
+ server.listen(port)
822
+
823
+ globalThis.listen = true;
824
+
825
+ puppeteer.launch({ headless: "new", args: ['--no-sandbox', '--disable-setuid-sandbox'],
826
+ warning: false,
827
+ }).then(async (browser) => {
828
+
829
+ // remove /: from route
830
+ route.url = route.url.replaceAll(/\/:[a-zA-Z0-9_-]+/gs, '')
831
+ const page = await browser.newPage();
832
+ await page.goto(`http://localhost:${port}` + '#' + route.url, { waitUntil: 'networkidle2' });
833
+ await page.waitForSelector('#root');
834
+ await page.evaluate(() => {
835
+ document.getElementById('meta').remove()
836
+ })
837
+ const html = await page.content();
838
+ await page.close();
839
+ let isBasePath = route.url === '/' ? true : false
840
+ await writer(process.cwd() + '/dist/' + (isBasePath ? 'index.html' : `${route.url}/` + 'index.html'), html)
841
+ await browser.close();
842
+ // close http
843
+ server.close()
844
+ })
845
+
846
+ })
847
+
848
+ console.log('Done')
750
849
  }
751
-
752
-
850
+
851
+ globalThis.routes = []
753
852
 
754
853
  for await (let file of glb) {
755
854
  // Normalize file paths
@@ -774,22 +873,14 @@ async function Build() {
774
873
  fullpath: origin,
775
874
  };
776
875
 
777
- if(process.cwd() + '/dist/index.html'){
778
- let html = fs.readFileSync(process.cwd() + '/dist/index.html', 'utf8')
779
- if (!html.includes(`<link rel="preload" href="${obj.url}" as="script">`)) {
780
- html = html.replace('</head>', `<link rel="preload" href="./pages/${fileName.replace('.jsx', '.js')}" as="script">\n</head>`)
781
- fs.writeFileSync(process.cwd() + '/dist/index.html', html)
782
- }
783
- }
784
-
785
876
 
786
877
 
787
878
  let data = await fs.readFileSync(origin, "utf8");
788
879
  data = Compiler(data, origin);
880
+
789
881
 
790
882
 
791
-
792
- await writer(process.cwd() + "/dist/pages/" + fileName.replace('.jsx', '.js'), data).then(async () => {
883
+ await writer(process.cwd() + "/dist/" + fileName.replace('.jsx', '.js'), data).then(async () => {
793
884
 
794
885
  let { minify } = await import('terser')
795
886
 
@@ -804,7 +895,9 @@ async function Build() {
804
895
 
805
896
  })
806
897
 
807
- await writer(process.cwd() + "/dist/pages/" + fileName.replace('.jsx', '.js'), minified.code)
898
+ minified.code += `\n\n window.params = ${JSON.stringify(obj.url.split('/').filter((e) => e.includes(':')).map((e) => e.split(':')[1]))}`
899
+
900
+ await writer(process.cwd() + "/dist/" + fileName.replace('.jsx', '.js'), minified.code)
808
901
  } catch (error) {
809
902
  console.log(error)
810
903
  }
@@ -814,22 +907,15 @@ async function Build() {
814
907
  obj.compiledPath = process.cwd() + "/dist/pages/" + fileName.replace('.jsx', '.js')
815
908
 
816
909
 
817
- // Generate routing logic
818
- let js = `
819
- router.get('${obj.url}', async (req, res) => {
820
- res.render(await import('./pages/${fileName.replace('.jsx', '.js')}'), req, res)
821
- })
822
- //@desc ${obj.pathname}
823
- ` + '\n';
824
- appjs += js
825
-
826
- writejs()
827
-
910
+
911
+ globalThis.routes.push({fileName:fileName, url:obj.url})
912
+
828
913
 
829
914
 
830
915
 
831
916
  }
832
917
 
918
+ ssg(globalThis.routes)
833
919
 
834
920
 
835
921
  const scannedSourceFiles = await glob("**/**.{jsx,js,json}", {
@@ -837,7 +923,23 @@ async function Build() {
837
923
  cwd: process.cwd() + '/src/',
838
924
  absolute: true,
839
925
  });
840
-
926
+ const scannedVaderFiles = await glob("**/**.{html,js}", {
927
+ cwd: process.cwd() + '/node_modules/vaderjs/runtime',
928
+ absolute: true,
929
+ });
930
+
931
+ scannedVaderFiles.forEach(async (file) => {
932
+ file = file.replace(/\\/g, '/');
933
+
934
+
935
+ let name = file.split('/node_modules/vaderjs/runtime/')[1]
936
+ if (file.includes('index.html') && fs.existsSync(process.cwd() + "/dist/" + name)) {
937
+ return
938
+ }
939
+ let data = await reader(file)
940
+ bundleSize += fs.statSync(file).size;
941
+ await writer(process.cwd() + "/dist/" + name, data);
942
+ })
841
943
  scannedSourceFiles.forEach(async (file) => {
842
944
  file = file.replace(/\\/g, '/');
843
945
  let name = file.split('/src/')[1]
@@ -868,7 +970,7 @@ async function Build() {
868
970
  await writer(process.cwd() + "/dist/src/" + name, data);
869
971
  })
870
972
 
871
- const scannedPublicFiles = await glob("**/**.{css,js,html,mjs,cjs,umd.js}", {
973
+ const scannedPublicFiles = await glob("**/**.{css,js,html,mjs,cjs}", {
872
974
  ignore: ["node_modules/**/*", "dist/**/*"],
873
975
  cwd: process.cwd() + '/public/',
874
976
  absolute: true,
@@ -894,15 +996,15 @@ async function Build() {
894
996
 
895
997
  let objCase = {
896
998
  ...file == "app.js" ? { exit: true } : null,
897
- ...file.includes("index.html") && fs.existsSync(process.cwd() + "/runtime/" + file) ? { exit: true } : null,
999
+ ...file.includes("index.html") && fs.existsSync(process.cwd() + "/dist/" + file) ? { exit: true } : null,
898
1000
 
899
1001
  }
900
1002
  if (objCase.exit) {
901
1003
  console.log('exiting')
902
- return
1004
+ return true
903
1005
  }
904
- bundleSize += fs.statSync(process.cwd() + "/runtime/" + file).size;
905
- let data = await reader(process.cwd() + "/runtime/" + file)
1006
+ bundleSize += fs.statSync(process.cwd() + "/node_modules/vaderjs/runtime/" + file).size;
1007
+ let data = await reader(process.cwd() + "/node_modules/vaderjs/runtime/" + file)
906
1008
  await writer(process.cwd() + "/dist/" + file, data);
907
1009
  });
908
1010