vaderjs 1.3.3-6722242 → 1.3.3-763562-hotfix

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/vader.js +284 -305
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-6722242",
5
+ "version": "1.3.3-763562-hotfix",
6
6
  "bin": {
7
7
  "vader": "./vader.js"
8
8
  },
package/vader.js CHANGED
@@ -143,6 +143,9 @@ function Compiler(func, file) {
143
143
  isJSXComponent = elementTag.match(/^[A-Z]/) ? true : false;
144
144
  }
145
145
  });
146
+ if (isJSXComponent) {
147
+ continue
148
+ }
146
149
  // add ; after newlines
147
150
 
148
151
 
@@ -239,34 +242,34 @@ function Compiler(func, file) {
239
242
  continue;
240
243
  }
241
244
  let old = spread;
242
- spread = spread.trim().replace(/\s+/g, " ");
245
+ spread = spread.trim().replace(/\s+/g, " ");
243
246
  // re,pve $={ and }
244
247
  spread = spread.replace(/\s*\$\s*=\s*{\s*{/gs, '')
245
-
248
+
246
249
  // replace trailing }
247
- spread = spread.replace(/}}\s*$/, '').replace(/}\s*}$/, '')
248
- let splitByCommas = spread.split(/,(?![^{}]*})/gs)
250
+ spread = spread.replace(/}}\s*$/, '').replace(/}\s*}$/, '')
251
+ let splitByCommas = spread.split(/,(?![^{}]*})/gs)
249
252
  // remove empty strings
250
253
  splitByCommas = splitByCommas.filter((e) => e.split(':')[0].trim().length > 0)
251
- splitByCommas = splitByCommas.map((e, index) => {
254
+ splitByCommas = splitByCommas.map((e, index) => {
252
255
  let key = e.split(':')[0].trim()
253
256
  switch (true) {
254
257
  case e.includes('function') && !e.includes('this.bind') || e && e.includes('=>') && !e.includes('this.bind'):
255
258
  let value = e.split(':')[1].trim()
256
- let ref = Math.random().toString(36).substring(2).split('').filter((e) => !Number(e)).join('');
259
+ let ref = Math.random().toString(36).substring(2).split('').filter((e) => !Number(e)).join('');
257
260
  value = `this.bind(${value}, false, "${ref}", "")`
258
261
  e = `${key}="\${${value}}"`
259
262
  break;
260
- case e.includes('style:'):
261
- let v2 = e.split('style:')[1].trim().replace(/,$/, '')
262
- v2 = v2.replace(/,$/, '')
263
+ case e.includes('style:'):
264
+ let v2 = e.split('style:')[1].trim().replace(/,$/, '')
265
+ v2 = v2.replace(/,$/, '')
263
266
  e = `${key}="\${this.parseStyle(${v2})}"`
264
- break;
265
-
266
- default:
267
- let v = e.split(':')
267
+ break;
268
+
269
+ default:
270
+ let v = e.split(':')
268
271
  key = v[0].trim()
269
- // remove key from v
272
+ // remove key from v
270
273
  v.shift()
271
274
  v = v.join(' ')
272
275
  e = `${key}="\${${v}}"`
@@ -277,7 +280,7 @@ function Compiler(func, file) {
277
280
 
278
281
  return e;
279
282
  });
280
-
283
+
281
284
 
282
285
  let newSpread = splitByCommas.join(' ').trim().replace(/,$/, '');
283
286
 
@@ -348,7 +351,7 @@ function Compiler(func, file) {
348
351
  newAttributes.push(attribute);
349
352
  for (let key in attributes) {
350
353
 
351
- let value = attributes[key];
354
+ let value = attributes[key];
352
355
  let oldvalue = value;
353
356
  if (value && !value.new) {
354
357
 
@@ -479,11 +482,16 @@ function Compiler(func, file) {
479
482
 
480
483
  let name = component.split("<")[1].split(">")[0].split(" ")[0].replace("/", "");
481
484
  let componentAttributes = component.split("<")[1].split(">")[0].split(" ").join(" ").replace(name, "").trim();
482
- const dynamicAttributesRegex = /(\w+)(?:="([^"]*?)"|='([^']*?)'|(?:=\{([^}]*?)\})?|(?:=\{(.*?)*\})?|(?:={([^}]*?)})?|(?:{([^}]*?)})?|(?:}))?|\$=\s*\{\s*\{\s*([^]*?)\s*\}\s*\}/gs;
485
+ // catchall = "" ={} =[]
486
+
487
+
488
+ let props = component.split("<")[1].split(">")[0]
483
489
 
484
490
 
491
+ const dynamicAttributesRegex = /([a-zA-Z0-9_-]+)\s*=\s*("(?:[^"\\]*(?:\\.[^"\\]*)*)"|'(?:[^'\\]*(?:\\.[^'\\]*)*)'|\{(?:[^{}]|(?:\{(?:[^{}]|(?:\{.*.*\})*)*\})*)*\}|(?:\([^)]*\)|()\s*=>\s*(?:\{.*\})?|\{[^}]*\})|\[[^\]]*\])/gs;
492
+
493
+ const attributeObject = {};
485
494
 
486
- let props = component.match(dynamicAttributesRegex)
487
495
 
488
496
  let filteredProps = [];
489
497
  let isWithinComponent = false;
@@ -492,78 +500,31 @@ function Compiler(func, file) {
492
500
 
493
501
  let $_ternaryprops = []
494
502
 
495
- for (let prop of props) {
496
-
497
- if (prop === componentName) {
498
-
499
- isWithinComponent = true;
500
- filteredProps.push(prop);
501
- } else if (isWithinComponent && prop.includes('=')) {
502
-
503
- if (prop.startsWith('$=')) {
504
- let old = prop
505
- let match = prop.replace(/\$\s*=\s*\{\s*\{\s*([^]*?)\s*\}\s*\}/gs, '$1')
506
- match = match.replace('$:', '$_ternary:')
507
- component = component.replace(old, '')
508
- componentAttributes = componentAttributes.replace(old, match)
509
-
510
- $_ternaryprops.push(prop)
511
-
512
- }
513
- else if (prop.includes('${')) {
514
-
515
-
516
- prop = prop.replace('="', ':')
517
- if (prop.includes('${')) {
518
- prop = prop.replace('="', ':')
519
- prop = prop.replace('${', '')
520
- }
521
- if (prop.includes('="${{')) {
522
- prop = prop.replace('${{', '{')
523
- prop = prop.replace('}}', '}')
524
- prop = prop.replace('="', ':')
525
- prop = prop.replace('}"', '}')
526
- }
527
-
528
- }
529
- if (prop.includes('={')) {
530
- let value = prop.split('={')
531
- let isObj = value[1].match(/^{.*}$/gs) ? true : false
532
- if (!isObj) {
533
- // remove trailing }
534
- value[1] = value[1].replace(/}\s*$/, '')
535
- }
536
-
537
- if (value[0] == 'style' && isObj) {
538
- value[1] = `this.parseStyle(${value[1]})`
539
- }
540
- prop = `${value[0]}:${value[1]}`
541
- }
542
-
543
- if (prop.includes('function') || prop.includes('=>')) {
544
- // parse 'function' to function
545
- prop = prop.replace("'", '')
546
-
547
- if (prop.endsWith("}'")) {
548
- prop = prop.replace("}'", '}')
549
-
550
- }
551
-
552
- prop = prop.replace('=function', ':function')
553
- }
554
-
555
- filteredProps.push(prop);
556
-
557
-
558
-
559
- } else if (isWithinComponent && prop.includes('}')) {
560
-
503
+ let match;
504
+ let propstring = ''
505
+ // props right now is just a string with all of them on one line and a space between each
506
+ while ((match = dynamicAttributesRegex.exec(props)) !== null) {
507
+ let str = match[0].trim().replace(/\s+/g, " ");
508
+ if (!str.includes('=')) {
509
+ continue
561
510
  }
562
-
563
-
564
- else {
565
- isWithinComponent = false;
511
+ str = str.split('=')
512
+ let key = str[0].trim()
513
+ let value = str[1].trim()
514
+ if (value.startsWith('"') && !value.endsWith('"') || value.startsWith("'") && !value.endsWith("'")
515
+ || value.startsWith('`') && !value.endsWith('`')) {
516
+ // wrap in respective quotes
517
+ value = value + value[0]
566
518
  }
519
+ let isObject = value.startsWith('{{') && value.endsWith('}}')
520
+ if (isObject) {
521
+ value = value.split('{{')[1].split('}}')[0].trim()
522
+ value = `{${value}}`
523
+ } else {
524
+ // remove starting { and ending } using regex
525
+ value = value.replace(/^{/, '').replace(/}$/, '')
526
+ }
527
+ propstring += `${key}:${value},`
567
528
  }
568
529
  component = component.replaceAll(/\s+/g, " ");
569
530
 
@@ -574,7 +535,7 @@ function Compiler(func, file) {
574
535
 
575
536
  let children = new RegExp(`<${name}[^>]*>([^]*)<\/${name}>`, 'gs').exec(component)?.[1] || null;
576
537
 
577
- props = filteredProps.join(',').replace(/\s+/g, " ").trim().replace(/,$/, '')
538
+
578
539
 
579
540
  let savedname = name;
580
541
 
@@ -607,24 +568,15 @@ function Compiler(func, file) {
607
568
 
608
569
 
609
570
 
610
-
611
- props = props.replaceAll(`,${savedname}`, '').replaceAll(savedname, '')
612
- if (props.startsWith(',')) {
613
- props = props.replace(',', '')
614
- }
615
- props = props.replaceAll("='", ":'")
616
- .replaceAll('=`', ':`')
617
- .replaceAll('="', ':"')
618
- .replaceAll('={', ':')
571
+ propstring = propstring.replace(/,$/, '')
619
572
 
620
573
 
621
574
  /**
622
575
  * @memoize - memoize a component to be remembered on each render and replace the old jsx
623
576
  */
624
577
 
625
-
626
578
  let replace = "";
627
- replace = `\${this.memoize(this.createComponent(${savedname}, {${props}}, [\`${myChildrens.join('')}\`]))}`;
579
+ replace = `\${this.memoize(this.createComponent(${savedname}, {${propstring}}, [\`${myChildrens.join('')}\`]))}`;
628
580
 
629
581
 
630
582
  body = body.replace(before, replace);
@@ -640,47 +592,49 @@ function Compiler(func, file) {
640
592
  let replaceMents = [];
641
593
 
642
594
 
643
- for (let match of imports) {
644
- let path = match.split('from')[1].trim().replace(/'/g, '').replace(/"/g, '').trim()
645
- switch (true) {
646
- case path && !path.includes('./') && !path.includes('/vader.js') && !path.includes('/vaderjs/client') && !path.startsWith('src') && !path.startsWith('public') && !path.includes('http') && !path.includes('https'):
647
- let componentFolder = fs.existsSync(process.cwd() + '/node_modules/' + path) ? process.cwd() + '/node_modules/' + path : process.cwd() + '/node_modules/' + path.split('/')[0]
648
- componentFolder = componentFolder.split(process.cwd())[1]
649
- if (!fs.existsSync(process.cwd() + componentFolder)) {
650
- throw new Error('Could not find ' + path + ' at ' + match + ' in file ' + file)
651
- }
652
-
653
- if (!fs.existsSync(process.cwd() + '/dist/src/' + componentFolder.split('/').slice(2).join('/'))) {
654
- fs.mkdirSync(process.cwd() + '/dist/src/' + componentFolder.split('/').slice(2).join('/'), { recursive: true })
655
- }
656
-
657
- let baseFolder = componentFolder.split('node_modules')[1].split('/')[1]
658
- let glp = globSync('**/**/**/**.{jsx,js}', {
659
- cwd: process.cwd() + '/node_modules/' + baseFolder + '/',
660
- absolute: true,
661
- recursive: true
662
- })
663
- for (let file of glp) {
664
- let text = fs.readFileSync(file, "utf8");
665
- if (!file.endsWith('.js') && file.endsWith('.jsx')) {
666
- text = Compiler(text, file);
667
-
595
+ if(imports){
596
+ for (let match of imports) {
597
+ let path = match.split('from')[1].trim().replace(/'/g, '').replace(/"/g, '').trim()
598
+ switch (true) {
599
+ case path && !path.includes('./') && !path.includes('/vader.js') && !path.includes('/vaderjs/client') && !path.startsWith('src') && !path.startsWith('public') && !path.includes('http') && !path.includes('https'):
600
+ let componentFolder = fs.existsSync(process.cwd() + '/node_modules/' + path) ? process.cwd() + '/node_modules/' + path : process.cwd() + '/node_modules/' + path.split('/')[0]
601
+ componentFolder = componentFolder.split(process.cwd())[1]
602
+ if (!fs.existsSync(process.cwd() + componentFolder)) {
603
+ throw new Error('Could not find ' + path + ' at ' + match + ' in file ' + file)
668
604
  }
669
- let dest = file.split('node_modules')[1]
670
- dest = dest.split(baseFolder)[1]
671
- writer(process.cwd() + '/dist/src/' + baseFolder + dest, text)
672
- let importname = match.split('import')[1].split('from')[0].trim()
673
- let oldImportstring = match.split('from')[1].trim().replace(/'/g, '').replace(/"/g, '').trim()
674
- let newImport = `/src/${baseFolder + dest}`
675
- newImport = newImport.replaceAll('.jsx', '.js').replaceAll('\\', '/')
676
- replaceMents.push({ match: oldImportstring, replace: newImport })
677
- console.log(`📦 imported Node Package ${baseFolder} `)
678
- }
679
-
680
-
681
- break;
682
- default:
683
- break;
605
+
606
+ if (!fs.existsSync(process.cwd() + '/dist/src/' + componentFolder.split('/').slice(2).join('/'))) {
607
+ fs.mkdirSync(process.cwd() + '/dist/src/' + componentFolder.split('/').slice(2).join('/'), { recursive: true })
608
+ }
609
+
610
+ let baseFolder = componentFolder.split('node_modules')[1].split('/')[1]
611
+ let glp = globSync('**/**/**/**.{jsx,js}', {
612
+ cwd: process.cwd() + '/node_modules/' + baseFolder + '/',
613
+ absolute: true,
614
+ recursive: true
615
+ })
616
+ for (let file of glp) {
617
+ let text = fs.readFileSync(file, "utf8");
618
+ if (!file.endsWith('.js') && file.endsWith('.jsx')) {
619
+ text = Compiler(text, file);
620
+
621
+ }
622
+ let dest = file.split('node_modules')[1]
623
+ dest = dest.split(baseFolder)[1]
624
+ writer(process.cwd() + '/dist/src/' + baseFolder + dest, text)
625
+ let importname = match.split('import')[1].split('from')[0].trim()
626
+ let oldImportstring = match.split('from')[1].trim().replace(/'/g, '').replace(/"/g, '').trim()
627
+ let newImport = `/src/${baseFolder + dest}`
628
+ newImport = newImport.replaceAll('.jsx', '.js').replaceAll('\\', '/')
629
+ replaceMents.push({ match: oldImportstring, replace: newImport })
630
+ console.log(`📦 imported Node Package ${baseFolder} `)
631
+ }
632
+
633
+
634
+ break;
635
+ default:
636
+ break;
637
+ }
684
638
  }
685
639
  }
686
640
 
@@ -873,6 +827,8 @@ const glb = await glob("**/**/**/**.{jsx,js}", {
873
827
  absolute: true,
874
828
  recursive: true
875
829
  });
830
+ let hasRendered = []
831
+
876
832
  async function Build() {
877
833
  globalThis.isBuilding = true
878
834
  console.log(globalThis.isProduction ? 'Creating Optimized Production Build\n' : '')
@@ -887,191 +843,133 @@ async function Build() {
887
843
 
888
844
  function ssg(routes = []) {
889
845
  globalThis.isBuilding = true
890
- routes.forEach(async (route) => {
891
- if (route.url.includes(':')) {
892
- return
893
- }
894
- let equalparamroute = routes.map((e) => {
895
- if (e.url.includes(':')) {
896
- let url = e.url.split('/:')[0]
897
- if (url && route.url === url) {
898
- return e
899
- } else {
900
- return null
846
+ let server = http.createServer((req, res) => {
847
+ let route = routes.find((e) => e.url === req.url)
848
+ if (route) {
849
+ let document = globalThis.routeDocuments.find((e) => e.url === req.url)
850
+ res.writeHead(200, { 'Content-Type': 'text/html' });
851
+ res.end(document.document);
852
+ } else {
853
+ const filePath = process.cwd() + '/dist/' + req.url
901
854
 
855
+ fs.readFile(filePath, (err, data) => {
856
+ if (err) {
857
+ res.writeHead(404, { 'Content-Type': filePath.includes('js') ? 'text/javascript' : 'text/html' });
858
+ res.end('File not found');
859
+ } else {
860
+ res.writeHead(200, { 'Content-Type': filePath.includes('js') ? 'text/javascript' : 'text/html' });
861
+ res.end(data);
902
862
  }
903
- }
904
- return null
905
- }).filter(Boolean)
906
- let document = `
907
- <!DOCTYPE html>
908
- <html lang="en">
909
- <head>
910
- <script>
911
- window.routes = JSON.parse('${JSON.stringify(routes)}')
912
-
913
-
914
- </script>
915
- <script id="isServer">
916
- window.isServer = true
917
- </script>
918
- <meta charset="UTF-8">
919
- <meta name="viewport" content="width=device-width,initial-scale=1.0">
920
- <script type="module" id="meta">
921
- window.history.pushState({}, '', '${route.url}')
922
-
923
- </script>
924
- <script type="module" id="router">
925
- import VaderRouter from '/router.js'
926
- const router = new VaderRouter('${route.url}', 3000)
927
- router.get('${route.url}', async (req, res) => {
928
- try{
929
- let module = await import('/${route.fileName.replace('.jsx', '.js')}')
930
- if(Object.keys(module).includes('$prerender') && !module.$prerender){
931
- document.head.setAttribute('prerender', 'false')
932
- }
933
- res.render(module, req, res, module.$metadata)
934
- }
935
- catch(error){
936
- let errorMessage = {
937
- message: error.message,
938
- name: error.name,
939
- stack: error.stack,
940
- path: window.location.pathname
941
- };
942
-
943
-
944
- document.documentElement.setAttribute('error', JSON.stringify(errorMessage));
945
- throw new Error(error)
946
- }
947
- })
948
- ${equalparamroute.length > 0 ? equalparamroute.map((e) => {
949
-
950
-
951
-
952
- return `router.get('${e.url}', async (req, res) => {
953
- let module = await import('/${e.fileName.replace('.jsx', '.js')}')
954
- res.render(module, req, res, module.$metadata)
955
- })\n`
956
- }) : ''}
957
- router.listen(3000)
958
-
959
- </script>
960
- </head>
961
- <body>
962
- <div id="root"></div>
963
- </body>
964
-
965
-
966
- </html>
967
- `;
968
-
969
- // generate random but common ports
970
- let port = Math.floor(Math.random() * (65535 - 49152 + 1) + 49152)
971
-
972
- const server = http.createServer((req, res) => {
863
+ });
864
+ }
865
+ });
973
866
 
974
- if (req.url === '/') {
975
- res.writeHead(200, { 'Content-Type': 'text/html' });
976
- res.end(document);
977
- } else {
978
- // Serve static files (adjust the file paths based on your project structure)
979
- const filePath = process.cwd() + '/dist/' + req.url
980
-
981
- fs.readFile(filePath, (err, data) => {
982
- if (err) {
983
- res.writeHead(404, { 'Content-Type': filePath.includes('js') ? 'text/javascript' : 'text/html' });
984
- res.end('File not found');
985
- } else {
986
- res.writeHead(200, { 'Content-Type': filePath.includes('js') ? 'text/javascript' : 'text/html' });
987
- res.end(data);
988
- }
989
- });
990
- }
991
- });
867
+ let port = 12000
868
+ server.on('error', (err) => {
869
+ if (err.code === 'EADDRINUSE') {
870
+ setTimeout(() => {
871
+ server.close();
872
+ server.listen(++port);
873
+ }, 1000);
874
+ }
875
+ })
992
876
 
993
- server.listen(port)
994
- server.on('error', (err) => {
995
- if (err.code === 'EADDRINUSE') {
996
- console.log(`Port ${port} is in use, trying another port...`);
997
- setTimeout(() => {
998
- server.close();
999
- server.listen(++port);
1000
- }, 1000);
1001
- }
1002
- })
877
+ const browser = puppeteer.launch({
878
+ headless: "new", args: ['--no-sandbox', '--disable-setuid-sandbox'],
879
+ warning: false,
880
+ })
881
+ server.listen(port);
1003
882
 
883
+ routes.forEach(async (route) => {
884
+ if (route.url.includes(':')) {
885
+ return
886
+ }
1004
887
  globalThis.listen = true;
1005
888
 
1006
- const browser = await puppeteer.launch({
1007
- headless: "new", args: ['--no-sandbox', '--disable-setuid-sandbox'],
1008
- warning: false,
1009
- })
1010
889
  try {
1011
890
 
1012
891
  route.url = route.url.replaceAll(/\/:[a-zA-Z0-9_-]+/gs, '')
1013
- let page = await browser.newPage();
1014
- // Handle browser errors
1015
- page.on('error', (err) => {
1016
- console.error('BROWSER ERROR:', JSON.parse(err));
1017
- });
1018
-
1019
- try {
1020
- page.on('pageerror', async err => {
1021
- let errorObj = JSON.parse(await page.evaluate(() => document.documentElement.getAttribute('error')) || '{}')
1022
- console.log('\x1b[31m%s\x1b[0m', 'Compiler Error:', errorObj)
1023
-
892
+ let page = (await browser).newPage()
893
+ page.then(async (page) => {
894
+ page.on('error', (err) => {
895
+ console.error('JS ERROR:', JSON.parse(err));
1024
896
  });
1025
- } catch (error) {
1026
- browser.close()
1027
- }
1028
- // Handle page crashes
1029
- page.on('crash', () => {
1030
- console.error('PAGE CRASHED');
1031
- });
1032
- page.on('requestfailed', request => {
1033
- console.error('REQUEST FAILED:', request.url(), request.failure().errorText);
1034
- });
1035
- await page.goto(`http://localhost:${port}/`, { waitUntil: 'networkidle2' });
1036
-
1037
-
1038
-
897
+ try {
898
+ page.on('pageerror', async err => {
899
+ let errorObj = JSON.parse(await page.evaluate(() => document.documentElement.getAttribute('error')) || '{}')
900
+ console.log('\x1b[31m%s\x1b[0m', 'Compiler Error:', errorObj)
901
+
902
+ console.log('\x1b[31m%s\x1b[0m', 'Error:', err)
903
+ });
904
+ } catch (error) {
905
+ page.close()
906
+ }
907
+ page.on('crash', () => {
908
+ console.error(`Render process crashed for ${route.url}`)
909
+ });
910
+ page.on('requestfailed', request => {
911
+ console.error('REQUEST FAILED:', request.url(), request.failure().errorText);
912
+ });
913
+ await page.goto(`http://localhost:${port}${route.url}`, { waitUntil: 'networkidle2' });
914
+
915
+ page.evaluate(() => {
916
+ document.querySelector('#meta').remove()
917
+ document.querySelector('#isServer').innerHTML = 'window.isServer = false'
918
+ if (document.head.getAttribute('prerender') === 'false') {
919
+ document.querySelector('#root').innerHTML = ''
920
+ console.log(`Disabled prerendering for ${window.location.pathname}`)
921
+ }
922
+ })
923
+ let html = await page.content();
1039
924
 
925
+ html = await prettier.format(html, { parser: "html" })
1040
926
 
927
+ writer(process.cwd() + '/dist/' + (route.url === '/' ? 'index.html' : `${route.url}/` + 'index.html'), html)
1041
928
 
929
+ console.log(`\x1b[32m%s\x1b[0m`, `Prerendered ${route.url}...`)
1042
930
 
1043
- await page.evaluate(() => {
1044
- document.getElementById('meta').remove()
1045
- document.querySelector('#isServer').innerHTML = 'window.isServer = false'
1046
- if (document.head.getAttribute('prerender') === 'false') {
1047
- document.querySelector('#root').innerHTML = ''
1048
- console.log(`Disabled prerendering for ${window.location.pathname}`)
1049
- }
931
+ hasRendered.push(route.url)
1050
932
  })
1051
- let html = await page.content();
1052
933
 
1053
- html = await prettier.format(html, { parser: "html" })
1054
934
 
1055
935
 
1056
- await writer(process.cwd() + '/dist/' + (route.url === '/' ? 'index.html' : `${route.url}/` + 'index.html'), html)
1057
-
1058
936
 
1059
937
  } catch (error) {
1060
- console.log(error)
1061
- }
938
+ console.log('\x1b[31m%s\x1b[0m', 'Error:', error)
1062
939
 
940
+ }
1063
941
  finally {
1064
- browser.close()
1065
- server.close()
1066
942
  }
1067
943
  })
1068
944
 
1069
- let timeout = setTimeout(() => {
945
+
946
+
947
+
948
+
949
+ function kill() {
950
+ console.log(`\x1b[32m%s\x1b[0m`, `\nPrerendered ${routes.length} pages...\n`)
951
+ server.close()
952
+ browser.then((browser) => {
953
+ browser.close()
954
+ })
955
+ hasRendered = []
1070
956
  globalThis.isBuilding = false
1071
- clearTimeout(timeout)
1072
- }, 1000)
1073
- }
957
+ globalThis.isProduction ? console.log(`Total Bundle Size: ${Math.round(bundleSize / 1000)}kb`) : null
958
+ bundleSize = 0
959
+ }
1074
960
 
961
+ if (hasRendered.length === routes.length) {
962
+ kill()
963
+ } else {
964
+ console.log(`\x1b[32m%s\x1b[0m`, `Prerendering ${routes.length} pages...\n`)
965
+ let interval = setInterval(() => {
966
+ if (hasRendered.length === routes.length) {
967
+ kill()
968
+ clearInterval(interval)
969
+ }
970
+ }, 1000);
971
+ }
972
+ }
1075
973
  globalThis.routes = []
1076
974
 
1077
975
  for await (let file of glb) {
@@ -1171,7 +1069,9 @@ async function Build() {
1171
1069
  }
1172
1070
 
1173
1071
 
1174
- globalThis.routes.push({ fileName: fileName, url: obj.url, html: '/' + (isBasePath ? 'index.html' : `${obj.url}/` + 'index.html') })
1072
+ if (!obj.url.includes(':')) {
1073
+ globalThis.routes.push({ fileName: fileName, url: obj.url, html: '/' + (isBasePath ? 'index.html' : `${obj.url}/` + 'index.html') })
1074
+ }
1175
1075
 
1176
1076
 
1177
1077
  let stats = {
@@ -1188,6 +1088,84 @@ async function Build() {
1188
1088
  globalThis.isProduction ? console.log(string) : null
1189
1089
  }
1190
1090
 
1091
+ globalThis.routeDocuments = []
1092
+ globalThis.routes.map((route) => {
1093
+ let equalparamroute = globalThis.routes.map((e) => {
1094
+ if (e.url.includes(':')) {
1095
+ let url = e.url.split('/:')[0]
1096
+ if (url && route.url === url) {
1097
+ return e
1098
+ } else {
1099
+ return null
1100
+
1101
+ }
1102
+ }
1103
+ return null
1104
+ }).filter(Boolean)
1105
+ let document = `
1106
+ <!DOCTYPE html>
1107
+ <html lang="en">
1108
+ <head>
1109
+ <script>
1110
+ window.routes = JSON.parse('${JSON.stringify(globalThis.routes)}')
1111
+ </script>
1112
+ <script type="module" id="meta">
1113
+ window.history.pushState({}, '', '${route.url}')
1114
+
1115
+ </script>
1116
+ <script id="isServer">
1117
+ window.isServer = true
1118
+ </script>
1119
+ <meta charset="UTF-8">
1120
+ <meta name="viewport" content="width=device-width,initial-scale=1.0">
1121
+
1122
+ <script type="module" id="router">
1123
+ import VaderRouter from '/router.js'
1124
+ const router = new VaderRouter('${route.url}')
1125
+ router.get('${route.url}', async (req, res) => {
1126
+ try{
1127
+ let module = await import('/${route.fileName.replace('.jsx', '.js')}')
1128
+ if(Object.keys(module).includes('$prerender') && !module.$prerender){
1129
+ document.head.setAttribute('prerender', 'false')
1130
+ }
1131
+ res.render(module, req, res, module.$metadata)
1132
+ }
1133
+ catch(error){
1134
+ let errorMessage = {
1135
+ message: error.message,
1136
+ name: error.name,
1137
+ stack: error.stack,
1138
+ path: window.location.pathname
1139
+ };
1140
+
1141
+
1142
+ document.documentElement.setAttribute('error', JSON.stringify(errorMessage));
1143
+ throw new Error(error)
1144
+ }
1145
+ })
1146
+ ${equalparamroute.length > 0 ? equalparamroute.map((e) => {
1147
+
1148
+
1149
+
1150
+ return `router.get('${e.url}', async (req, res) => {
1151
+ let module = await import('/${e.fileName.replace('.jsx', '.js')}')
1152
+ res.render(module, req, res, module.$metadata)
1153
+ })\n`
1154
+ }) : ''}
1155
+ router.listen(3000)
1156
+
1157
+ </script>
1158
+ </head>
1159
+ <body>
1160
+ <div id="root"></div>
1161
+ </body>
1162
+
1163
+
1164
+ </html>
1165
+ `;
1166
+ globalThis.routeDocuments.push({ url: route.url, document: document })
1167
+ })
1168
+
1191
1169
  ssg(globalThis.routes)
1192
1170
 
1193
1171
 
@@ -1216,11 +1194,10 @@ async function Build() {
1216
1194
  scannedSourceFiles.forEach(async (file) => {
1217
1195
  file = file.replace(/\\/g, '/');
1218
1196
  let name = file.split('/src/')[1]
1219
- //parse jsx
1220
1197
 
1221
1198
  let data = await reader(process.cwd() + "/src/" + name)
1222
1199
  if (name.includes('.jsx')) {
1223
- let origin = process.cwd() + "/src/" + name
1200
+ let origin = process.cwd() + "/src/" + name
1224
1201
  if (!globalThis.isProduction) {
1225
1202
  let { sourceMap } = sourceMapGen({ origin: origin, fileName: name }, await Compiler(data, origin))
1226
1203
  data = data + `\n//# sourceMappingURL=/src/maps/${name.replace('.jsx', '.js.map')}\n //#sourceURL=${origin}`
@@ -1229,11 +1206,13 @@ async function Build() {
1229
1206
  await writer(process.cwd() + "/dist/src/" + name.split('.jsx').join('.js'), await Compiler(data, origin))
1230
1207
  return
1231
1208
  }
1232
- bundleSize += fs.statSync(process.cwd() + "/src/" + name).size;
1209
+ if (!name.includes('.map')) {
1210
+ bundleSize += fs.statSync(process.cwd() + "/src/" + name).size;
1211
+ }
1233
1212
  await writer(process.cwd() + "/dist/src/" + name, data);
1234
1213
  })
1235
1214
 
1236
- const scannedPublicFiles = await glob("**/**.{css,js,html,mjs,cjs}", {
1215
+ const scannedPublicFiles = await glob("**/**/**.{css,js,html,mjs,cjs,png,jpg,jpeg,gif,svg,mp4,webm,ogg}", {
1237
1216
  ignore: ["node_modules/**/*", "dist/**/*"],
1238
1217
  cwd: process.cwd() + '/public/',
1239
1218
  absolute: true,
@@ -1241,7 +1220,7 @@ async function Build() {
1241
1220
  scannedPublicFiles.forEach(async (file) => {
1242
1221
  file = file.replace(/\\/g, '/');
1243
1222
  file = file.split('/public/')[1]
1244
- let data = await reader(process.cwd() + "/public/" + file)
1223
+ let data = fs.readFileSync(process.cwd() + "/public/" + file);
1245
1224
  bundleSize += fs.statSync(process.cwd() + "/public/" + file).size;
1246
1225
  await writer(process.cwd() + "/dist/public/" + file, data);
1247
1226
  })
@@ -1274,7 +1253,6 @@ async function Build() {
1274
1253
  }
1275
1254
 
1276
1255
  globalThis.isBuilding = false
1277
- console.log(`\nTotal bundle size: ${Math.round(bundleSize / 1000)}kb`)
1278
1256
 
1279
1257
  bundleSize = 0;
1280
1258
 
@@ -1382,7 +1360,7 @@ switch (true) {
1382
1360
  globalThis.devMode = true
1383
1361
  globalThis.isProduction = false
1384
1362
  console.log(`
1385
- Vader.js v1.3.3
1363
+ Vader.js v${fs.readFileSync(process.cwd() + '/node_modules/vaderjs/package.json', 'utf8').split('"version": "')[1].split('"')[0]}
1386
1364
  - Watching for changes in ./pages
1387
1365
  - Watching for changes in ./src
1388
1366
  - Watching for changes in ./public
@@ -1404,6 +1382,7 @@ Vader.js v1.3.3
1404
1382
  })
1405
1383
  }
1406
1384
 
1385
+ console.log('\nRebuilding...')
1407
1386
  globalThis.isBuilding = true
1408
1387
  Build()
1409
1388
  }