vaderjs 1.3.3-7775642-hotfix → 1.3.3-7b27417d42e1
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/client/index.js +221 -222
- package/package.json +1 -1
- package/runtime/router.js +1 -1
- package/runtime/vader.js +1 -1
- package/vader.js +312 -333
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 =
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
|
@@ -478,92 +481,45 @@ function Compiler(func, file) {
|
|
|
478
481
|
let myChildrens = [];
|
|
479
482
|
|
|
480
483
|
let name = component.split("<")[1].split(">")[0].split(" ")[0].replace("/", "");
|
|
481
|
-
let componentAttributes = component.split("<")[1].split(">")[0].split(" ").join(" ").replace(name, "").trim();
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
let filteredProps = [];
|
|
489
|
-
let isWithinComponent = false;
|
|
490
|
-
let componentName = name
|
|
491
|
-
let currentProps = []
|
|
484
|
+
let componentAttributes = component.split("<")[1].split(">")[0].split(" ").join(" ").replace(name, "").trim();
|
|
485
|
+
let props = component.includes('/>')? component.split(`<`)[1].split('/>')[0] : component.split(`<`)[1].split(`>`)[1].split(`</${name}`)[0].trim()
|
|
486
|
+
props = props.replaceAll(/\s+/g, " ").trim()
|
|
487
|
+
props = props.replace(name, '').trim()
|
|
488
|
+
component = component.replace(componentAttributes, '')
|
|
489
|
+
const dynamicAttributesRegex = /([a-zA-Z0-9_-]+)\s*=\s*("(?:[^"\\]*(?:\\.[^"\\]*)*)"|'(?:[^'\\]*(?:\\.[^'\\]*)*)'|\{(?:[^{}]|(?:\{(?:[^{}]|(?:\{(.*.*?)\})*)*\})*)*\}|(?:\([^)]*\)|()\s*=>\s*(?:\{.*.*\})?|\{.*\})|\[[^\]]*\])/gs;
|
|
492
490
|
|
|
491
|
+
const attributeObject = {};
|
|
492
|
+
|
|
493
493
|
let $_ternaryprops = []
|
|
494
494
|
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
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
|
-
|
|
561
|
-
}
|
|
562
|
-
|
|
495
|
+
let match;
|
|
496
|
+
let propstring = ''
|
|
497
|
+
// props right now is just a string with all of them on one line and a space between each
|
|
498
|
+
while ((match = dynamicAttributesRegex.exec(props)) !== null) {
|
|
499
|
+
let str = match[0].trim().replace(/\s+/g, " ");
|
|
500
|
+
if (!str.includes('=')) {
|
|
501
|
+
continue
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
str = str.replaceAll(/\s+/g, " ")
|
|
506
|
+
str = str.split('=')
|
|
507
|
+
let key = str[0].trim()
|
|
508
|
+
let value = str.slice(1).join('=').trim().match(/\{.*\}/gs) ? str.slice(1).join('=').trim().match(/\{.*\}/gs)[0] : str.slice(1).join('=').trim();
|
|
563
509
|
|
|
564
|
-
|
|
565
|
-
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
let isObject = value.startsWith('{{') && value.endsWith('}}')
|
|
513
|
+
if (isObject) {
|
|
514
|
+
value = value.split('{{')[1].split('}}')[0].trim()
|
|
515
|
+
value = `{${value}}`
|
|
516
|
+
propstring += `${key}:${value},`
|
|
517
|
+
} else {
|
|
518
|
+
// remove starting { and ending } using regex
|
|
519
|
+
value = value.replace(/^{/, '').replace(/}$/, '')
|
|
520
|
+
propstring += `${key}:${value},`
|
|
566
521
|
}
|
|
522
|
+
|
|
567
523
|
}
|
|
568
524
|
component = component.replaceAll(/\s+/g, " ");
|
|
569
525
|
|
|
@@ -574,7 +530,7 @@ function Compiler(func, file) {
|
|
|
574
530
|
|
|
575
531
|
let children = new RegExp(`<${name}[^>]*>([^]*)<\/${name}>`, 'gs').exec(component)?.[1] || null;
|
|
576
532
|
|
|
577
|
-
|
|
533
|
+
|
|
578
534
|
|
|
579
535
|
let savedname = name;
|
|
580
536
|
|
|
@@ -607,24 +563,15 @@ function Compiler(func, file) {
|
|
|
607
563
|
|
|
608
564
|
|
|
609
565
|
|
|
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('={', ':')
|
|
566
|
+
propstring = propstring.replace(/,$/, '')
|
|
619
567
|
|
|
620
568
|
|
|
621
569
|
/**
|
|
622
570
|
* @memoize - memoize a component to be remembered on each render and replace the old jsx
|
|
623
571
|
*/
|
|
624
572
|
|
|
625
|
-
|
|
626
573
|
let replace = "";
|
|
627
|
-
replace = `\${this.memoize(this.createComponent(${savedname}, {${
|
|
574
|
+
replace = `\${this.memoize(this.createComponent(${savedname}, {${propstring}}, [\`${myChildrens.join('')}\`]))}`;
|
|
628
575
|
|
|
629
576
|
|
|
630
577
|
body = body.replace(before, replace);
|
|
@@ -640,47 +587,49 @@ function Compiler(func, file) {
|
|
|
640
587
|
let replaceMents = [];
|
|
641
588
|
|
|
642
589
|
|
|
643
|
-
|
|
644
|
-
let
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
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
|
-
|
|
590
|
+
if(imports){
|
|
591
|
+
for (let match of imports) {
|
|
592
|
+
let path = match.split('from')[1].trim().replace(/'/g, '').replace(/"/g, '').trim()
|
|
593
|
+
switch (true) {
|
|
594
|
+
case path && !path.includes('./') && !path.includes('/vader.js') && !path.includes('/vaderjs/client') && !path.startsWith('src') && !path.startsWith('public') && !path.includes('http') && !path.includes('https'):
|
|
595
|
+
let componentFolder = fs.existsSync(process.cwd() + '/node_modules/' + path) ? process.cwd() + '/node_modules/' + path : process.cwd() + '/node_modules/' + path.split('/')[0]
|
|
596
|
+
componentFolder = componentFolder.split(process.cwd())[1]
|
|
597
|
+
if (!fs.existsSync(process.cwd() + componentFolder)) {
|
|
598
|
+
throw new Error('Could not find ' + path + ' at ' + match + ' in file ' + file)
|
|
668
599
|
}
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
let
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
600
|
+
|
|
601
|
+
if (!fs.existsSync(process.cwd() + '/dist/src/' + componentFolder.split('/').slice(2).join('/'))) {
|
|
602
|
+
fs.mkdirSync(process.cwd() + '/dist/src/' + componentFolder.split('/').slice(2).join('/'), { recursive: true })
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
let baseFolder = componentFolder.split('node_modules')[1].split('/')[1]
|
|
606
|
+
let glp = globSync('**/**/**/**.{jsx,js}', {
|
|
607
|
+
cwd: process.cwd() + '/node_modules/' + baseFolder + '/',
|
|
608
|
+
absolute: true,
|
|
609
|
+
recursive: true
|
|
610
|
+
})
|
|
611
|
+
for (let file of glp) {
|
|
612
|
+
let text = fs.readFileSync(file, "utf8");
|
|
613
|
+
if (!file.endsWith('.js') && file.endsWith('.jsx')) {
|
|
614
|
+
text = Compiler(text, file);
|
|
615
|
+
|
|
616
|
+
}
|
|
617
|
+
let dest = file.split('node_modules')[1]
|
|
618
|
+
dest = dest.split(baseFolder)[1]
|
|
619
|
+
writer(process.cwd() + '/dist/src/' + baseFolder + dest, text)
|
|
620
|
+
let importname = match.split('import')[1].split('from')[0].trim()
|
|
621
|
+
let oldImportstring = match.split('from')[1].trim().replace(/'/g, '').replace(/"/g, '').trim()
|
|
622
|
+
let newImport = `/src/${baseFolder + dest}`
|
|
623
|
+
newImport = newImport.replaceAll('.jsx', '.js').replaceAll('\\', '/')
|
|
624
|
+
replaceMents.push({ match: oldImportstring, replace: newImport })
|
|
625
|
+
console.log(`📦 imported Node Package ${baseFolder} `)
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
|
|
629
|
+
break;
|
|
630
|
+
default:
|
|
631
|
+
break;
|
|
632
|
+
}
|
|
684
633
|
}
|
|
685
634
|
}
|
|
686
635
|
|
|
@@ -873,6 +822,8 @@ const glb = await glob("**/**/**/**.{jsx,js}", {
|
|
|
873
822
|
absolute: true,
|
|
874
823
|
recursive: true
|
|
875
824
|
});
|
|
825
|
+
let hasRendered = []
|
|
826
|
+
|
|
876
827
|
async function Build() {
|
|
877
828
|
globalThis.isBuilding = true
|
|
878
829
|
console.log(globalThis.isProduction ? 'Creating Optimized Production Build\n' : '')
|
|
@@ -887,191 +838,130 @@ async function Build() {
|
|
|
887
838
|
|
|
888
839
|
function ssg(routes = []) {
|
|
889
840
|
globalThis.isBuilding = true
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
return e
|
|
899
|
-
} else {
|
|
900
|
-
return null
|
|
841
|
+
let server = http.createServer((req, res) => {
|
|
842
|
+
let route = routes.find((e) => e.url === req.url)
|
|
843
|
+
if (route) {
|
|
844
|
+
let document = globalThis.routeDocuments.find((e) => e.url === req.url)
|
|
845
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
846
|
+
res.end(document.document);
|
|
847
|
+
} else {
|
|
848
|
+
const filePath = process.cwd() + '/dist/' + req.url
|
|
901
849
|
|
|
850
|
+
fs.readFile(filePath, (err, data) => {
|
|
851
|
+
if (err) {
|
|
852
|
+
res.writeHead(404, { 'Content-Type': filePath.includes('js') ? 'text/javascript' : 'text/html' });
|
|
853
|
+
res.end('File not found');
|
|
854
|
+
} else {
|
|
855
|
+
res.writeHead(200, { 'Content-Type': filePath.includes('js') ? 'text/javascript' : 'text/html' });
|
|
856
|
+
res.end(data);
|
|
902
857
|
}
|
|
903
|
-
}
|
|
904
|
-
|
|
905
|
-
|
|
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) => {
|
|
858
|
+
});
|
|
859
|
+
}
|
|
860
|
+
});
|
|
973
861
|
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
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
|
-
});
|
|
862
|
+
let port = 12000
|
|
863
|
+
server.on('error', (err) => {
|
|
864
|
+
if (err.code === 'EADDRINUSE') {
|
|
865
|
+
setTimeout(() => {
|
|
866
|
+
server.close();
|
|
867
|
+
server.listen(++port);
|
|
868
|
+
}, 1000);
|
|
869
|
+
}
|
|
870
|
+
})
|
|
992
871
|
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
server.close();
|
|
999
|
-
server.listen(++port);
|
|
1000
|
-
}, 1000);
|
|
1001
|
-
}
|
|
1002
|
-
})
|
|
872
|
+
const browser = puppeteer.launch({
|
|
873
|
+
headless: "new", args: ['--no-sandbox', '--disable-setuid-sandbox'],
|
|
874
|
+
warning: false,
|
|
875
|
+
})
|
|
876
|
+
server.listen(port);
|
|
1003
877
|
|
|
878
|
+
routes.forEach(async (route) => {
|
|
879
|
+
if (route.url.includes(':')) {
|
|
880
|
+
return
|
|
881
|
+
}
|
|
1004
882
|
globalThis.listen = true;
|
|
1005
883
|
|
|
1006
|
-
const browser = await puppeteer.launch({
|
|
1007
|
-
headless: "new", args: ['--no-sandbox', '--disable-setuid-sandbox'],
|
|
1008
|
-
warning: false,
|
|
1009
|
-
})
|
|
1010
884
|
try {
|
|
1011
885
|
|
|
1012
886
|
route.url = route.url.replaceAll(/\/:[a-zA-Z0-9_-]+/gs, '')
|
|
1013
|
-
let page = await browser.newPage()
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
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
|
-
|
|
887
|
+
let page = (await browser).newPage()
|
|
888
|
+
page.then(async (page) => {
|
|
889
|
+
page.on('error', (err) => {
|
|
890
|
+
console.error('JS ERROR:', JSON.parse(err));
|
|
1024
891
|
});
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
892
|
+
try {
|
|
893
|
+
page.on('pageerror', async err => {
|
|
894
|
+
let errorObj = JSON.parse(await page.evaluate(() => document.documentElement.getAttribute('error')) || '{}')
|
|
895
|
+
console.log('\x1b[31m%s\x1b[0m', 'Compiler Error:', errorObj)
|
|
896
|
+
|
|
897
|
+
console.log('\x1b[31m%s\x1b[0m', 'Error:', err)
|
|
898
|
+
});
|
|
899
|
+
} catch (error) {
|
|
900
|
+
page.close()
|
|
901
|
+
}
|
|
902
|
+
page.on('crash', () => {
|
|
903
|
+
console.error(`Render process crashed for ${route.url}`)
|
|
904
|
+
});
|
|
905
|
+
|
|
906
|
+
await page.goto(`http://localhost:${port}${route.url}`, { waitUntil: 'networkidle2' });
|
|
907
|
+
|
|
908
|
+
page.evaluate(() => {
|
|
909
|
+
document.querySelector('#meta').remove()
|
|
910
|
+
document.querySelector('#isServer').innerHTML = 'window.isServer = false'
|
|
911
|
+
if (document.head.getAttribute('prerender') === 'false') {
|
|
912
|
+
document.querySelector('#root').innerHTML = ''
|
|
913
|
+
console.log(`Disabled prerendering for ${window.location.pathname}`)
|
|
914
|
+
}
|
|
915
|
+
})
|
|
916
|
+
let html = await page.content();
|
|
1039
917
|
|
|
918
|
+
html = await prettier.format(html, { parser: "html" })
|
|
1040
919
|
|
|
920
|
+
writer(process.cwd() + '/dist/' + (route.url === '/' ? 'index.html' : `${route.url}/` + 'index.html'), html)
|
|
1041
921
|
|
|
922
|
+
console.log(`\x1b[32m%s\x1b[0m`, `Prerendered ${route.url}...`)
|
|
1042
923
|
|
|
1043
|
-
|
|
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
|
-
}
|
|
924
|
+
hasRendered.push(route.url)
|
|
1050
925
|
})
|
|
1051
|
-
let html = await page.content();
|
|
1052
|
-
|
|
1053
|
-
html = await prettier.format(html, { parser: "html" })
|
|
1054
926
|
|
|
1055
927
|
|
|
1056
|
-
await writer(process.cwd() + '/dist/' + (route.url === '/' ? 'index.html' : `${route.url}/` + 'index.html'), html)
|
|
1057
928
|
|
|
1058
929
|
|
|
1059
930
|
} catch (error) {
|
|
1060
|
-
console.log(error)
|
|
1061
|
-
}
|
|
931
|
+
console.log('\x1b[31m%s\x1b[0m', 'Error:', error)
|
|
1062
932
|
|
|
933
|
+
}
|
|
1063
934
|
finally {
|
|
1064
|
-
browser.close()
|
|
1065
|
-
server.close()
|
|
1066
935
|
}
|
|
1067
936
|
})
|
|
1068
937
|
|
|
1069
|
-
let timeout = setTimeout(() => {
|
|
1070
|
-
globalThis.isBuilding = false
|
|
1071
|
-
clearTimeout(timeout)
|
|
1072
|
-
}, 1000)
|
|
1073
|
-
}
|
|
1074
938
|
|
|
939
|
+
|
|
940
|
+
|
|
941
|
+
|
|
942
|
+
function kill() {
|
|
943
|
+
console.log(`\x1b[32m%s\x1b[0m`, `\nPrerendered ${routes.length} pages...\n`)
|
|
944
|
+
server.close()
|
|
945
|
+
browser.then((browser) => {
|
|
946
|
+
browser.close()
|
|
947
|
+
})
|
|
948
|
+
hasRendered = []
|
|
949
|
+
globalThis.isBuilding = false
|
|
950
|
+
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
if (hasRendered.length === routes.length) {
|
|
954
|
+
kill()
|
|
955
|
+
} else {
|
|
956
|
+
console.log(`\x1b[32m%s\x1b[0m`, `Prerendering ${routes.length} pages...\n`)
|
|
957
|
+
let interval = setInterval(() => {
|
|
958
|
+
if (hasRendered.length === routes.length) {
|
|
959
|
+
kill()
|
|
960
|
+
clearInterval(interval)
|
|
961
|
+
}
|
|
962
|
+
}, 1000);
|
|
963
|
+
}
|
|
964
|
+
}
|
|
1075
965
|
globalThis.routes = []
|
|
1076
966
|
|
|
1077
967
|
for await (let file of glb) {
|
|
@@ -1171,7 +1061,9 @@ async function Build() {
|
|
|
1171
1061
|
}
|
|
1172
1062
|
|
|
1173
1063
|
|
|
1174
|
-
|
|
1064
|
+
if (!obj.url.includes(':')) {
|
|
1065
|
+
globalThis.routes.push({ fileName: fileName, url: obj.url, html: '/' + (isBasePath ? 'index.html' : `${obj.url}/` + 'index.html') })
|
|
1066
|
+
}
|
|
1175
1067
|
|
|
1176
1068
|
|
|
1177
1069
|
let stats = {
|
|
@@ -1188,7 +1080,92 @@ async function Build() {
|
|
|
1188
1080
|
globalThis.isProduction ? console.log(string) : null
|
|
1189
1081
|
}
|
|
1190
1082
|
|
|
1191
|
-
|
|
1083
|
+
globalThis.routeDocuments = []
|
|
1084
|
+
globalThis.routes.map((route) => {
|
|
1085
|
+
let equalparamroute = globalThis.routes.map((e) => {
|
|
1086
|
+
if (e.url.includes(':')) {
|
|
1087
|
+
let url = e.url.split('/:')[0]
|
|
1088
|
+
if (url && route.url === url) {
|
|
1089
|
+
return e
|
|
1090
|
+
} else {
|
|
1091
|
+
return null
|
|
1092
|
+
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
return null
|
|
1096
|
+
}).filter(Boolean)
|
|
1097
|
+
let document = `
|
|
1098
|
+
<!DOCTYPE html>
|
|
1099
|
+
<html lang="en">
|
|
1100
|
+
<head>
|
|
1101
|
+
<script>
|
|
1102
|
+
window.routes = JSON.parse('${JSON.stringify(globalThis.routes)}')
|
|
1103
|
+
</script>
|
|
1104
|
+
<script type="module" id="meta">
|
|
1105
|
+
window.history.pushState({}, '', '${route.url}')
|
|
1106
|
+
|
|
1107
|
+
</script>
|
|
1108
|
+
<script id="isServer">
|
|
1109
|
+
window.isServer = true
|
|
1110
|
+
</script>
|
|
1111
|
+
<meta charset="UTF-8">
|
|
1112
|
+
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
|
1113
|
+
|
|
1114
|
+
<script type="module" id="router">
|
|
1115
|
+
import VaderRouter from '/router.js'
|
|
1116
|
+
const router = new VaderRouter('${route.url}')
|
|
1117
|
+
router.get('${route.url}', async (req, res) => {
|
|
1118
|
+
try{
|
|
1119
|
+
let module = await import('/${route.fileName.replace('.jsx', '.js')}')
|
|
1120
|
+
if(Object.keys(module).includes('$prerender') && !module.$prerender){
|
|
1121
|
+
document.head.setAttribute('prerender', 'false')
|
|
1122
|
+
}
|
|
1123
|
+
res.render(module, req, res, module.$metadata)
|
|
1124
|
+
}
|
|
1125
|
+
catch(error){
|
|
1126
|
+
let errorMessage = {
|
|
1127
|
+
message: error.message,
|
|
1128
|
+
name: error.name,
|
|
1129
|
+
stack: error.stack,
|
|
1130
|
+
path: window.location.pathname
|
|
1131
|
+
};
|
|
1132
|
+
|
|
1133
|
+
|
|
1134
|
+
document.documentElement.setAttribute('error', JSON.stringify(errorMessage));
|
|
1135
|
+
throw new Error(error)
|
|
1136
|
+
}
|
|
1137
|
+
})
|
|
1138
|
+
${equalparamroute.length > 0 ? equalparamroute.map((e) => {
|
|
1139
|
+
|
|
1140
|
+
|
|
1141
|
+
|
|
1142
|
+
return `router.get('${e.url}', async (req, res) => {
|
|
1143
|
+
let module = await import('/${e.fileName.replace('.jsx', '.js')}')
|
|
1144
|
+
res.render(module, req, res, module.$metadata)
|
|
1145
|
+
})\n`
|
|
1146
|
+
}) : ''}
|
|
1147
|
+
router.listen(3000)
|
|
1148
|
+
|
|
1149
|
+
</script>
|
|
1150
|
+
</head>
|
|
1151
|
+
<body>
|
|
1152
|
+
<div id="root"></div>
|
|
1153
|
+
</body>
|
|
1154
|
+
|
|
1155
|
+
|
|
1156
|
+
</html>
|
|
1157
|
+
`;
|
|
1158
|
+
globalThis.routeDocuments.push({ url: route.url, document: document })
|
|
1159
|
+
})
|
|
1160
|
+
|
|
1161
|
+
if(globalThis.devMode && !globalThis.oneAndDone){
|
|
1162
|
+
ssg(globalThis.routes)
|
|
1163
|
+
globalThis.oneAndDone = true
|
|
1164
|
+
console.log(`In Development Mode, Prerendering ${globalThis.routes.length} pages... Once`)
|
|
1165
|
+
}
|
|
1166
|
+
else if(globalThis.isProduction){
|
|
1167
|
+
ssg(globalThis.routes)
|
|
1168
|
+
}
|
|
1192
1169
|
|
|
1193
1170
|
|
|
1194
1171
|
const scannedSourceFiles = await glob("**/**.{jsx,js,json}", {
|
|
@@ -1216,11 +1193,10 @@ async function Build() {
|
|
|
1216
1193
|
scannedSourceFiles.forEach(async (file) => {
|
|
1217
1194
|
file = file.replace(/\\/g, '/');
|
|
1218
1195
|
let name = file.split('/src/')[1]
|
|
1219
|
-
//parse jsx
|
|
1220
1196
|
|
|
1221
1197
|
let data = await reader(process.cwd() + "/src/" + name)
|
|
1222
1198
|
if (name.includes('.jsx')) {
|
|
1223
|
-
let origin = process.cwd() + "/src/" + name
|
|
1199
|
+
let origin = process.cwd() + "/src/" + name
|
|
1224
1200
|
if (!globalThis.isProduction) {
|
|
1225
1201
|
let { sourceMap } = sourceMapGen({ origin: origin, fileName: name }, await Compiler(data, origin))
|
|
1226
1202
|
data = data + `\n//# sourceMappingURL=/src/maps/${name.replace('.jsx', '.js.map')}\n //#sourceURL=${origin}`
|
|
@@ -1229,11 +1205,13 @@ async function Build() {
|
|
|
1229
1205
|
await writer(process.cwd() + "/dist/src/" + name.split('.jsx').join('.js'), await Compiler(data, origin))
|
|
1230
1206
|
return
|
|
1231
1207
|
}
|
|
1232
|
-
|
|
1208
|
+
if (!name.includes('.map')) {
|
|
1209
|
+
bundleSize += fs.statSync(process.cwd() + "/src/" + name).size;
|
|
1210
|
+
}
|
|
1233
1211
|
await writer(process.cwd() + "/dist/src/" + name, data);
|
|
1234
1212
|
})
|
|
1235
1213
|
|
|
1236
|
-
const scannedPublicFiles = await glob("
|
|
1214
|
+
const scannedPublicFiles = await glob("**/**/**.{css,js,html,mjs,cjs,png,jpg,jpeg,gif,svg,mp4,webm,ogg}", {
|
|
1237
1215
|
ignore: ["node_modules/**/*", "dist/**/*"],
|
|
1238
1216
|
cwd: process.cwd() + '/public/',
|
|
1239
1217
|
absolute: true,
|
|
@@ -1241,7 +1219,7 @@ async function Build() {
|
|
|
1241
1219
|
scannedPublicFiles.forEach(async (file) => {
|
|
1242
1220
|
file = file.replace(/\\/g, '/');
|
|
1243
1221
|
file = file.split('/public/')[1]
|
|
1244
|
-
let data =
|
|
1222
|
+
let data = fs.readFileSync(process.cwd() + "/public/" + file);
|
|
1245
1223
|
bundleSize += fs.statSync(process.cwd() + "/public/" + file).size;
|
|
1246
1224
|
await writer(process.cwd() + "/dist/public/" + file, data);
|
|
1247
1225
|
})
|
|
@@ -1270,17 +1248,18 @@ async function Build() {
|
|
|
1270
1248
|
let data = await reader(process.cwd() + "/node_modules/vaderjs/runtime/" + file)
|
|
1271
1249
|
await writer(process.cwd() + "/dist/" + file, data);
|
|
1272
1250
|
});
|
|
1251
|
+
|
|
1273
1252
|
|
|
1274
1253
|
}
|
|
1275
1254
|
|
|
1276
1255
|
globalThis.isBuilding = false
|
|
1277
|
-
globalThis.isProduction ? console.log(`\nTotal bundle size: ${Math.round(bundleSize / 1000)}kb`) : null
|
|
1278
1256
|
|
|
1257
|
+
globalThis.isProduction ? console.log(`Total Bundle Size: ${Math.round(bundleSize / 1000)}kb`) : null
|
|
1279
1258
|
bundleSize = 0;
|
|
1280
1259
|
|
|
1281
1260
|
return true
|
|
1282
1261
|
}
|
|
1283
|
-
const s = () => {
|
|
1262
|
+
const s = (port) => {
|
|
1284
1263
|
|
|
1285
1264
|
const server = http.createServer((req, res) => {
|
|
1286
1265
|
|
|
@@ -1365,10 +1344,9 @@ const s = () => {
|
|
|
1365
1344
|
return 'application/octet-stream';
|
|
1366
1345
|
}
|
|
1367
1346
|
}
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
console.log(`Server is running on port ${PORT}`);
|
|
1347
|
+
|
|
1348
|
+
server.listen(port, () => {
|
|
1349
|
+
console.log(`Server is running on port ${port}`);
|
|
1372
1350
|
globalThis.ws = ws
|
|
1373
1351
|
});
|
|
1374
1352
|
|
|
@@ -1381,11 +1359,15 @@ switch (true) {
|
|
|
1381
1359
|
|
|
1382
1360
|
globalThis.devMode = true
|
|
1383
1361
|
globalThis.isProduction = false
|
|
1362
|
+
|
|
1363
|
+
let p = process.env.PORT || config.port || process.argv.includes('-p') ? process.argv[process.argv.indexOf('-p') + 1] : 3000
|
|
1364
|
+
globalThis.oneAndDone = false
|
|
1384
1365
|
console.log(`
|
|
1385
|
-
Vader.js
|
|
1366
|
+
Vader.js v${fs.readFileSync(process.cwd() + '/node_modules/vaderjs/package.json', 'utf8').split('"version": "')[1].split('"')[0]}
|
|
1386
1367
|
- Watching for changes in ./pages
|
|
1387
1368
|
- Watching for changes in ./src
|
|
1388
1369
|
- Watching for changes in ./public
|
|
1370
|
+
- Serving on port ${p}
|
|
1389
1371
|
`)
|
|
1390
1372
|
!globalThis.isBuilding ? Build() : null
|
|
1391
1373
|
|
|
@@ -1404,15 +1386,13 @@ Vader.js v1.3.3
|
|
|
1404
1386
|
})
|
|
1405
1387
|
}
|
|
1406
1388
|
|
|
1389
|
+
console.log('\nRebuilding...')
|
|
1407
1390
|
globalThis.isBuilding = true
|
|
1408
1391
|
Build()
|
|
1409
1392
|
}
|
|
1410
1393
|
}).on('error', (err) => console.log(err))
|
|
1411
|
-
})
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
process.env.PORT = p
|
|
1415
|
-
s()
|
|
1394
|
+
})
|
|
1395
|
+
s(p)
|
|
1416
1396
|
|
|
1417
1397
|
globalThis.listen = true;
|
|
1418
1398
|
|
|
@@ -1432,30 +1412,30 @@ Building to ./dist
|
|
|
1432
1412
|
|
|
1433
1413
|
break;
|
|
1434
1414
|
case process.argv.includes('start') && !process.argv.includes('dev') && !process.argv.includes('build'):
|
|
1435
|
-
let port = process.argv[process.argv.indexOf('
|
|
1436
|
-
|
|
1415
|
+
let port = process.env.PORT || config.port || process.argv.includes('-p') ? process.argv[process.argv.indexOf('-p') + 1] : 3000
|
|
1416
|
+
console.log(port)
|
|
1437
1417
|
globalThis.devMode = false
|
|
1438
1418
|
console.log(`
|
|
1439
1419
|
Vader.js v1.3.3
|
|
1440
1420
|
Serving ./dist on port ${port}
|
|
1441
1421
|
url: http://localhost:${port}
|
|
1442
1422
|
`)
|
|
1443
|
-
s()
|
|
1423
|
+
s(port)
|
|
1444
1424
|
break;
|
|
1445
1425
|
default:
|
|
1446
1426
|
// add color
|
|
1447
1427
|
console.log(`
|
|
1448
|
-
Vader.js is a reactive framework for building interactive applications for the web!
|
|
1428
|
+
Vader.js is a reactive framework for building interactive applications for the web built ontop of bun.js!
|
|
1449
1429
|
|
|
1450
1430
|
Usage: vader <command>
|
|
1451
1431
|
|
|
1452
1432
|
Commands:
|
|
1453
1433
|
|
|
1454
|
-
vaderjs dev
|
|
1434
|
+
vaderjs dev -p <number> Start the development server
|
|
1455
1435
|
|
|
1456
1436
|
vaderjs build Build the project to ./dist
|
|
1457
1437
|
|
|
1458
|
-
vaderjs start <
|
|
1438
|
+
vaderjs start -p <number> Production Mode (default 3000 or process.env.PORT)
|
|
1459
1439
|
|
|
1460
1440
|
Learn more about vader: https://vader-js.pages.dev/
|
|
1461
1441
|
|
|
@@ -1463,4 +1443,3 @@ Learn more about vader: https://vader-js.pages.dev/
|
|
|
1463
1443
|
break;
|
|
1464
1444
|
|
|
1465
1445
|
}
|
|
1466
|
-
|