vaderjs 1.3.3-alpha-33 → 1.3.3-alpha-35

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 CHANGED
@@ -73,8 +73,9 @@ For pages that have [params] you can derive it using this.request
73
73
 
74
74
  ```jsx
75
75
  // pages/home.jsx
76
- let {Component, useState} = await import('vaderjs/client') // this will be automatically handled by vader in compile time
77
- let Mycomponent = await require('./pages/mycomponent')
76
+ import {Component, useState, useRef} = from 'vaderjs/client'
77
+ import Mycomponent from './src/mycomponent.jsx'
78
+
78
79
  class Home extends Vader {
79
80
  constructor() {
80
81
  super();
@@ -90,7 +91,7 @@ class Home extends Vader {
90
91
  }
91
92
  }
92
93
 
93
- return {default:Home}
94
+ export default Home
94
95
  ```
95
96
 
96
97
 
@@ -101,9 +102,9 @@ Vaderjs uses partial hydration & full reflection
101
102
  You can pass a reference to the dom target like an id for the element u want to change - or you can just swap the value and the entire component will rerender
102
103
 
103
104
  ```jsx
104
- let {Component, useState, useRef} = await import('vaderjs/client')
105
-
106
- class MyApp extends Component{
105
+ import {Component, useState, useRef} = from 'vaderjs/client'
106
+
107
+ export default class MyApp extends Component{
107
108
  contructor(){
108
109
  super()
109
110
  this.key = 'static key for state changes'
@@ -124,9 +125,7 @@ class MyApp extends Component{
124
125
  </>
125
126
 
126
127
  }
127
- }
128
-
129
- return {default:MyApp}
128
+ }
130
129
  ```
131
130
 
132
131
 
package/client/index.js CHANGED
File without changes
package/logo.png CHANGED
File without changes
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-33",
5
+ "version": "1.3.3-alpha-35",
6
6
  "bin": {
7
7
  "vader": "./vader.js"
8
8
  },
File without changes
package/runtime/router.js CHANGED
@@ -134,6 +134,7 @@ class VaderRouter{
134
134
  hash = hash.slice(1);
135
135
  let status = 200;
136
136
  let paramsCatchall = {}
137
+ let hashBefore = hash;
137
138
  let route = this.routes.find((route) => {
138
139
  if (route.path === hash) {
139
140
  return true;
@@ -143,6 +144,9 @@ class VaderRouter{
143
144
  return true
144
145
  }
145
146
 
147
+ if(hash.includes('?')){
148
+ hash = hash.split('?')[0]
149
+ }
146
150
  if (route.path.includes('*') || route.path.includes(':')) {
147
151
  const routeParts = route.path.split('/');
148
152
  const hashParts = hash.split('/');
@@ -168,15 +172,14 @@ class VaderRouter{
168
172
 
169
173
  return true;
170
174
  }
171
-
172
- const params = this.extractParams(route.path, hash);
175
+
176
+ const params = this.extractParams(route.path, hashBefore);
173
177
  return Object.keys(params).length > 0;
174
- });
178
+ });
175
179
 
176
180
 
177
181
  if (!route) {
178
182
  route = this.routes.find((errorRoute) => {
179
- console.log(errorRoute)
180
183
  if (errorRoute.path.includes('/404')){
181
184
  this.error = true;
182
185
  return true;
@@ -188,8 +191,8 @@ class VaderRouter{
188
191
  status = route ? 200 : 404;
189
192
  }
190
193
 
191
- const queryParams = this.extractQueryParams(hash);
192
- const params = route && route.path ? this.extractParams(route.path, hash) : {};
194
+ const queryParams = this.extractQueryParams(hashBefore);
195
+ const params = route && route.path ? this.extractParams(route.path, hashBefore) : {};
193
196
  const req = {
194
197
  headers: {},
195
198
  params: params,
package/runtime/vader.js CHANGED
@@ -236,7 +236,33 @@ export class Component {
236
236
  * @param {*} Component
237
237
  */
238
238
  render: async (Component) => {},
239
+ /**
240
+ * @method log
241
+ * @description This method is used to log the request and response
242
+ * @param {String} type
243
+ */
244
+ log: (type) => {},
245
+ /**
246
+ * @method setQuery
247
+ * @description This method is used to set the query object for the current route
248
+ */
249
+ setQuery: (query) => {},
250
+
239
251
  }
252
+ /**
253
+ * @method router
254
+ * @description use router methods directly from the parent component
255
+ */
256
+
257
+ this.router = {
258
+ /**
259
+ * @method use
260
+ * @description add a middleware to the current route
261
+ * @param {Function} middleware
262
+ * @returns {void}
263
+ */
264
+ use: (/**@type {Function} */ middleware) => {},
265
+ }
240
266
  }
241
267
 
242
268
  createComponent(/**@type {Component}**/component, props, children) {
package/vader.js CHANGED
@@ -409,7 +409,8 @@ function Compiler(func) {
409
409
  if (line.includes("useState") && !line.includes("import")) {
410
410
  line = line.trim();
411
411
  // derive [key, value] from line
412
- let type = line.split(" ")[0];
412
+ let varType = line.split(" ")[0];
413
+ let type = ''
413
414
  let key = line
414
415
  .split("=")[0]
415
416
  .split(" ")[1]
@@ -420,11 +421,55 @@ function Compiler(func) {
420
421
 
421
422
  key = key.replace("[", "").replace(",", "");
422
423
  let value = line.split("=")[1].split("useState(")[1]
424
+
423
425
  let regex = /useState\((.*)\)/gs
424
426
  value = value.match(regex) ? value.match(regex)[0].split("useState(")[1].split(")")[0].trim() : value
427
+ switch(true){
428
+ case value.startsWith("'"):
429
+ type = "String"
430
+ break;
431
+ case value.startsWith('"'):
432
+ type = "String"
433
+ break;
434
+ case value.startsWith("`"):
435
+ type = "String"
436
+ break;
437
+ case value.startsWith("{"):
438
+ type = "Object"
439
+ break;
440
+ case value.startsWith("["):
441
+ type = "Array"
442
+ break;
443
+ case value.includes("function"):
444
+ type = "Function"
445
+ break;
446
+ case value.includes("=>"):
447
+ type = "Function"
448
+ break;
449
+ case value.includes("true"):
450
+ type = "Boolean"
451
+ break;
452
+ case value.includes("false"):
453
+ type = "Boolean"
454
+ break;
455
+ case value.includes("null"):
456
+ type = "Null"
457
+ break;
458
+ case value.includes("undefined"):
459
+ type = "Undefined"
460
+ break;
461
+ case value.includes("?") && value.includes(":"):
462
+ type = "Any"
463
+ break;
464
+ default:
465
+ type = "*"
466
+ break;
467
+ }
468
+
469
+ let typejsdoc = `/** @type {${type}} */`;
470
+
425
471
 
426
-
427
- let newState = `${type} [${key}, ${setKey}] = this.useState('${key}', ${value}
472
+ let newState = `${varType} [${typejsdoc}${key}, ${setKey}] = this.useState('${key}', ${value}
428
473
 
429
474
  `;
430
475
 
@@ -614,7 +659,113 @@ function Compiler(func) {
614
659
  string += `\n\n //wascompiled`;
615
660
 
616
661
  string = string.replaceAll("undefined", "");
617
-
662
+ string.split('\n').forEach(line => {
663
+ if(line.includes('import')){
664
+ let asyncimportMatch = line.match(/import\((.*)\)/gs)
665
+ // handle other imports like import { useState } from 'vaderjs/client' or import vader from 'vaderjs/client'
666
+ let regularimportMatch = line.match(/import\s*(.*)\s*from\s*(.*)/gs)
667
+ if(asyncimportMatch){
668
+ asyncimportMatch.forEach(async (match) => {
669
+ let beforeimport = match
670
+ let path = match.split('(')[1].split(')')[0].trim()
671
+ let newImport = ''
672
+ switch(true){
673
+ case path && path.includes('json'):
674
+ // return default json
675
+ newImport = `import(${path}, {assert:{type:'json'}}).then((data) => data.default)`
676
+ let htmlPrefetch = `<link rel="prefetch" href="${path}" as="fetch">`
677
+ let beforeHTML = fs.existsSync(process.cwd() + "/dist/index.html") ? fs.readFileSync(process.cwd() + "/dist/index.html", "utf8") : '';
678
+ if(!beforeHTML.includes(htmlPrefetch)){
679
+ let newHTML = beforeHTML + `\n${htmlPrefetch}`
680
+ fs.writeFileSync(process.cwd() + "/dist/index.html", newHTML);
681
+ }
682
+ break;
683
+
684
+ }
685
+ if(newImport){
686
+ string = string.replace(beforeimport, newImport)
687
+ }
688
+ })
689
+ }
690
+
691
+ if(regularimportMatch){
692
+ regularimportMatch.forEach(async (match) => {
693
+ let beforeimport = match
694
+ let path = match.split('from')[1].trim()
695
+ let newImport = ''
696
+ let name = match.split('import')[1].split('from')[0].trim()
697
+ switch(true){
698
+ case path && path.includes('json'):
699
+ // return default json
700
+ newImport = `let ${name} = await import(${path}, {assert:{type:'json'}}).then((data) => data.default)`
701
+ let htmlPrefetch = `<link rel="prefetch" href="${path.replace(/'/g, '')}" as="fetch">`
702
+ let beforeHTML = fs.existsSync(process.cwd() + "/dist/index.html") ? fs.readFileSync(process.cwd() + "/dist/index.html", "utf8") : '';
703
+ if(!beforeHTML.includes(htmlPrefetch)){
704
+ let newHTML = beforeHTML + `\n${htmlPrefetch}`
705
+ fs.writeFileSync(process.cwd() + "/dist/index.html", newHTML);
706
+ }
707
+ break;
708
+ case path && path.includes('.jsx'):
709
+ newImport = `let ${name} = await require(${path})`
710
+ break;
711
+ default:
712
+ newImport = `let ${name} = await import(${path})`
713
+ break;
714
+ }
715
+ if(newImport){
716
+ string = string.replace(beforeimport, newImport)
717
+ }
718
+ })
719
+ }
720
+ }else if (line.includes('export')) {
721
+ let b4line = line;
722
+ let exports = line.split('export')[1].trim();
723
+ let isDefault = exports.includes('default');
724
+ let newExport = '';
725
+ let name = ''
726
+ switch (true) {
727
+ case exports && isDefault:
728
+ let expt = exports.split('default')[1].trim();
729
+ // Check if it's a class definition
730
+ if (expt.includes('class')) {
731
+ // also capture extends
732
+ let match = expt.match(/class\s*([a-zA-Z0-9_-]+)\s*extends\s*([a-zA-Z0-9_-]+)/gs)
733
+ let className = match ? match[0].split('class')[1].split('extends')[0].trim() : expt.split('class')[1].split('{')[0].trim();
734
+ name = className
735
+
736
+ newExport = isDefault ? `return {default: ${className}}` : `return ${className}`;
737
+ } else if (expt.includes('function')) {
738
+ let funcName = expt.split('function')[1].split('(')[0].trim();
739
+ name = funcName
740
+ newExport = isDefault ? `return {default: ${funcName}}` : `return ${funcName}`;
741
+ }else{
742
+ name = expt
743
+ newExport = isDefault ? `return {default: ${expt}}` : `return ${expt}`;
744
+ }
745
+ break;
746
+
747
+ default:
748
+ let expt2 = exports
749
+ if(expt2.includes('function')){
750
+ let funcName = expt2.split('function')[1].split('(')[0].trim();
751
+ newExport = `return ${funcName}`;
752
+ }else if(expt2.includes('class')){
753
+ let match = expt2.match(/class\s*([a-zA-Z0-9_-]+)\s*extends\s*([a-zA-Z0-9_-]+)/gs)
754
+ let className = match ? match[0].split('class')[1].split('extends')[0].trim() : expt2.split('class')[1].split('{')[0].trim();
755
+ name = className
756
+ newExport = `return ${className}`;
757
+ }
758
+ break;
759
+ }
760
+
761
+ if (newExport) {
762
+ string = string.replace(b4line, b4line.replaceAll(/\s+/g, " ").trim().split('export').join('').split('default').join('').trim());
763
+ string = `${string}\n${newExport}`;
764
+ }
765
+ }
766
+
767
+ })
768
+
618
769
  return string;
619
770
  }
620
771
  let bindings = []
@@ -666,15 +817,13 @@ async function Build() {
666
817
  aburl = aburl.split('...').join('*').split(':*').join('*')
667
818
  aburl = aburl.replaceAll('./index', '')
668
819
 
669
- }
670
-
820
+ }
671
821
  // Create an object with URL and pathname properties
672
822
  let obj = {
673
- url: isBasePath ? '/' : aburl.replaceAll('index', ''),
823
+ url: isBasePath ? '/' : aburl.replaceAll('/index', ''),
674
824
  pathname: `/pages/${origin.split('pages/')[1].split('.jsx')[0].replace('.jsx', '')}.jsx`,
675
825
  fullpath: origin,
676
- };
677
-
826
+ };
678
827
 
679
828
  // Read and compile file content
680
829
  let data = await fs.readFileSync(origin, "utf8");
@@ -704,7 +853,7 @@ async function Build() {
704
853
 
705
854
 
706
855
 
707
- const scannedSourceFiles = await glob("**/**.{jsx,js}", {
856
+ const scannedSourceFiles = await glob("**/**.{jsx,js,json}", {
708
857
  ignore: ["node_modules/**/*", "dist/**/*"],
709
858
  cwd: process.cwd() + '/src/',
710
859
  absolute: true,
@@ -727,8 +876,7 @@ async function Build() {
727
876
  })
728
877
  scannedSourceFiles.forEach(async (file) => {
729
878
  file = file.replace(/\\/g, '/');
730
- let name = file.split('/src/')[1]
731
- console.log(`Compiling ${name} to /src/${name}`)
879
+ let name = file.split('/src/')[1]
732
880
  //parse jsx
733
881
 
734
882
  let data = await reader(process.cwd() + "/src/" + name)
@@ -764,10 +912,9 @@ async function Build() {
764
912
 
765
913
  if (file === "app.js") {
766
914
  return
767
- }
768
- console.log(`Compiling ${file} to /dist/${file}`)
915
+ }
769
916
  if(file.includes('index.html') && fs.existsSync(process.cwd() + "/runtime/" + file)){
770
- console.log(`Compiling ${file} to /dist/${file}`)
917
+
771
918
  return
772
919
  }
773
920
  bundleSize += fs.statSync(process.cwd() + "/runtime/" + file).size;