vaderjs 1.3.3-alpha-41 → 1.3.3-alpha-43

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/vader.js CHANGED
@@ -1,22 +1,22 @@
1
1
  #!/usr/bin/env node
2
2
  import fs from "fs";
3
- import { glob, globSync, globStream, globStreamSync, Glob } from 'glob'
4
-
5
- let bundleSize = 0;
6
- if(!fs.existsSync(process.cwd() + '/dist')){
3
+ import { glob, globSync, globStream, globStreamSync, Glob, } from 'glob'
4
+ let bundleSize = 0;
5
+ if (!fs.existsSync(process.cwd() + '/dist')) {
7
6
  fs.mkdirSync(process.cwd() + '/dist')
8
7
  fs.mkdirSync(process.cwd() + '/dist/public')
9
8
  fs.mkdirSync(process.cwd() + '/dist/src')
10
9
  fs.mkdirSync(process.cwd() + '/dist/pages')
11
- }else if(!fs.existsSync(process.cwd() + '/dist/public')){
10
+ } else if (!fs.existsSync(process.cwd() + '/dist/public')) {
12
11
  fs.mkdirSync(process.cwd() + '/dist/public')
13
- }else if(!fs.existsSync(process.cwd() + '/src') && !fs.existsSync(process.cwd() + '/dist/src')){
14
- fs.mkdirSync(process.cwd() + '/dist/src')
15
- fs.mkdirSync(process.cwd() + '/src')
12
+ } else if (!fs.existsSync(process.cwd() + '/src') && !fs.existsSync(process.cwd() + '/dist/src')) {
13
+ fs.mkdirSync(process.cwd() + '/dist/src')
14
+ fs.mkdirSync(process.cwd() + '/src')
16
15
  }
17
-
16
+
18
17
  function Compiler(func) {
19
18
  let string = func;
19
+ let returns = []
20
20
  let comments = string
21
21
 
22
22
  .match(/\{\s*\/\*.*\*\/\s*}/gs)
@@ -39,7 +39,7 @@ function Compiler(func) {
39
39
  )
40
40
  ) {
41
41
  return;
42
- }
42
+ }
43
43
 
44
44
  let name = func.split(" ")[1].split("(")[0].trim();
45
45
 
@@ -71,7 +71,7 @@ function Compiler(func) {
71
71
  let childs = [];
72
72
 
73
73
 
74
-
74
+
75
75
  function extractAttributes(code) {
76
76
  // Match elements with opening tags
77
77
  const elementRegex = /<([a-zA-Z0-9_-]+)([^>]*)>/gs;
@@ -100,8 +100,8 @@ function Compiler(func) {
100
100
 
101
101
  //ex: (params)=>{console.log(params)} => console.log(params
102
102
  // do not split all =>
103
- let newvalue = attributeValue.split("=>").slice(1).join("=>").trim();
104
-
103
+ let newvalue = attributeValue.split("=>").slice(1).join("=>").trim();
104
+
105
105
 
106
106
  newvalue = newvalue.trim();
107
107
 
@@ -113,6 +113,10 @@ function Compiler(func) {
113
113
  .split("(")[1]
114
114
  .split(")")[0]
115
115
  .trim();
116
+ params = params.match(/\/\*.*\*\//gs)
117
+ ? params.replace(params.match(/\/\*.*\*\//gs)[0], "")
118
+ : params;
119
+
116
120
  let functionparams = [];
117
121
  // split first {}
118
122
  newvalue = newvalue.trim();
@@ -121,7 +125,7 @@ function Compiler(func) {
121
125
  newvalue = newvalue.split("{")[1];
122
126
  }
123
127
 
124
- switch(true){
128
+ switch (true) {
125
129
  case newvalue.endsWith("}}"):
126
130
  newvalue = newvalue.replace("}}", "");
127
131
  break;
@@ -130,121 +134,53 @@ function Compiler(func) {
130
134
  break;
131
135
  }
132
136
 
133
-
134
137
 
135
- if (functionNames.length > 0) {
136
- functionNames.forEach((name) => {
137
- string.split("\n").forEach((line) => {
138
- if (line.includes(name) && line.includes("function")) {
139
- line = line.trim();
140
- line = line.replace(/\s+/g, " ");
141
138
 
142
- let ps = line.split("(").slice(1).join("(").split(")")[0].trim();
139
+ let currentParams = params
140
+ let name = functionNames.map((name) => { return newvalue.includes(name) ? name : null }).filter(Boolean)[0]
141
+ if (name) {
143
142
 
144
- // remove comments
145
- ps = ps.match(/\/\*.*\*\//gs)
146
- ? ps.replace(ps.match(/\/\*.*\*\//gs)[0], "")
147
- : ps;
143
+ if (newvalue.includes('function')) {
144
+ return
145
+ }
148
146
 
149
- functionparams.push({ ref: ref, name: name, params: ps });
150
- }
151
- });
152
- newvalue = newvalue.trim();
153
- let lines = newvalue.split("\n");
154
-
155
- for (let i = 0; i < lines.length; i++) {
156
- let line = lines[i];
157
-
158
- if (line.includes(name) && !line.includes("useFunction")) {
159
- let hasParams = line.includes("(") && line.includes(")");
160
- let params = hasParams
161
- ? line.split("(")[1].split(")")[0].trim()
162
- : null;
163
-
164
- if (
165
- functionparams.length > 0 &&
166
- functionparams.find((p) => p.name == name)
167
- ) {
168
- let params = functionparams.find((p) => p.name == name).params;
169
- line.includes(params) ? (params = params) : (params = null);
170
- }
147
+ name && string.split("\n").forEach((line) => {
148
+ if (line.includes(name) && line.includes("function")) {
149
+ line = line.trim();
150
+ line = line.replace(/\s+/g, " ");
171
151
 
172
- let elementMatch = string.match(/<([a-zA-Z0-9_-]+)([^>]*)>/gs);
173
- let isJSXComponent = false;
174
- elementMatch.forEach((element) => {
175
- element = element.trim().replace(/\s+/g, " ");
176
- if (element.includes(attributeName)) {
177
- let elementTag = element
178
- .split("<")[1]
179
- .split(">")[0]
180
- .split(" ")[0];
181
- isJSXComponent = elementTag.match(/^[A-Z]/) ? true : false;
182
- }
183
- });
184
-
185
- if(isJSXComponent){
186
- return
187
- }
188
- let replacement = `this.useFunction(${name} ${isJSXComponent ? "" : ","
189
- } ${params || null}${isJSXComponent ? "" : ","} true ${isJSXComponent ? "" : ","
190
- } '${ref}')`;
191
-
192
- newvalue = newvalue.replace(
193
- hasParams ? `${name}(${params})` : name,
194
- `this.callFunction(\${${replacement}}, ${isJSXComponent ? true : false
195
- }, event, \${JSON.stringify(${params || null})})`
196
- );
197
- }
198
- }
152
+ let ps = line.split("(").slice(1).join("(").split(")")[0].trim();
199
153
 
200
- params = params.match(/\/\*.*\*\//gs)
201
- ? params.replace(params.match(/\/\*.*\*\//gs)[0], "")
202
- : params;
203
-
204
- // get full element with function from string
205
- let elementMatch = string.match(/<([a-zA-Z0-9_-]+)([^>]*)>/gs);
206
- let isJSXComponent = false;
207
- elementMatch.forEach((element) => {
208
- element = element.trim().replace(/\s+/g, " ");
209
- if (element.includes(attributeName)) {
210
- let elementTag = element
211
- .split("<")[1]
212
- .split(">")[0]
213
- .split(" ")[0];
214
- isJSXComponent = elementTag.match(/^[A-Z]/) ? true : false;
215
- }
154
+ // remove comments
155
+ ps = ps.match(/\/\*.*\*\//gs)
156
+ ? ps.replace(ps.match(/\/\*.*\*\//gs)[0], "")
157
+ : ps;
216
158
 
217
- });
218
-
219
-
220
-
221
- let otherdata = {};
222
-
223
- params ? (otherdata["params"] = params) : null;
224
- otherdata["jsx"] = isJSXComponent;
225
- otherdata["ref"] = ref;
226
-
227
- newvalue = newvalue.split('\n').map(line => line.trim() ? line.trim() + ';' : line).join('\n');
228
-
229
- // turn params into param1, param2, param3
230
-
231
-
232
- let paramString = params ? params.split(' ').map(param => param + ',').join('') : "";
233
-
234
- paramString = paramString.replaceAll(',,', ',')
235
- let jsxAttribute = `${attributeName}=function(${paramString}){${newvalue}}.bind(this),`
236
- let newatribute = `${attributeName}="\${this.bind(\`${newvalue}\`, ${isJSXComponent ? true : false}, '${ref}', "${paramString}", ${params || null})}",`
237
-
238
- attribute[attributeName] = {
239
- old: old,
240
- new: isJSXComponent ? jsxAttribute : newatribute,
241
- attribute: attributeName,
242
- };
243
- attributesList.push({
244
- element: attributeName,
245
- attributes: attribute,
246
- });
159
+ functionparams.push({ ref: ref, name: name, params: ps });
160
+ }
161
+ });
162
+ let hasParams = newvalue.includes("(") && newvalue.includes(")");
163
+ let isJSXComponent = false;
164
+ let elementMatch = string.match(/<([a-zA-Z0-9_-]+)([^>]*)>/gs);
165
+ elementMatch.forEach((element) => {
166
+ element = element.trim().replace(/\s+/g, " ");
167
+ if (element.includes(attributeName)) {
168
+ let elementTag = element
169
+ .split("<")[1]
170
+ .split(">")[0]
171
+ .split(" ")[0];
172
+ isJSXComponent = elementTag.match(/^[A-Z]/) ? true : false;
173
+ }
247
174
  });
175
+
176
+ let functionParmas = functionparams.map((param) => { return param.params }).join(',')
177
+ let suppliedParams = newvalue.split("(")[1].split(")")[0].trim();
178
+
179
+ let replacement = `this.bind(${name}, true, ${isJSXComponent ? true : false}, '${ref}', "${functionParmas}", event, ${suppliedParams || null})`
180
+ let newattribute = `${attributeName}="\${${replacement}}", usesEvent="true", eventType="${attributeName}",data-ref="${ref}", `
181
+
182
+ string = string.replace(old, newattribute);
183
+
248
184
  }
249
185
  else {
250
186
  let elementMatch = string.match(/<([a-zA-Z0-9_-]+)([^>]*)>/gs);
@@ -265,15 +201,15 @@ function Compiler(func) {
265
201
  let otherdata = {};
266
202
  params ? (otherdata["params"] = params) : null;
267
203
  otherdata["jsx"] = isJSXComponent;
268
- otherdata["ref"] = ref;
204
+ otherdata["ref"] = ref;
269
205
  // since js is all in one line split it
270
- newvalue = newvalue.split('\n').map(line => line.trim() ? line.trim() + ';' : line).join('\n');
206
+ newvalue = newvalue.split('\n').map(line => line.trim() ? line.trim() + ';' : line).join('\n');
271
207
  let paramString = params ? params.split(' ').map(param => param + ',').join('') : "";
272
208
  paramString = paramString.replaceAll(',,', ',')
273
209
  let jsxAttribute = `${attributeName}=function(${paramString}){${newvalue}}.bind(this),`
274
- let newattribute = `${attributeName}="\${this.bind(\`${newvalue}\`, ${isJSXComponent ? true : false}, '${ref}', "${paramString}", ${params || null})}",`
210
+ let newattribute = `${attributeName}="\${this.bind(\`${newvalue}\`, false, ${isJSXComponent ? true : false}, '${ref}', "${paramString}", ${params || null})}", usesEvent="true", eventType="${attributeName}",data-ref="${ref}", `
275
211
  newattribute = newattribute.replace(/\s+/g, " ")
276
- string = string.replace(old, isJSXComponent ? jsxAttribute : newattribute);
212
+ string = string.replace(old, isJSXComponent ? jsxAttribute : newattribute);
277
213
  }
278
214
  }
279
215
  }
@@ -308,7 +244,7 @@ function Compiler(func) {
308
244
  let contents = "";
309
245
  let updatedContents = "";
310
246
  outerReturn.forEach((returnStatement) => {
311
-
247
+
312
248
  let lines = returnStatement.split("\n");
313
249
 
314
250
  for (let i = 0; i < lines.length; i++) {
@@ -317,7 +253,7 @@ function Compiler(func) {
317
253
  continue;
318
254
  }
319
255
  contents += line + "\n";
320
- }
256
+ }
321
257
 
322
258
  // Remove trailing ']'
323
259
  contents = contents.trim().replace(/\]$/, "");
@@ -330,26 +266,26 @@ function Compiler(func) {
330
266
  const { element, attributes } = attribute;
331
267
  if (Object.keys(attributes).length === 0) return;
332
268
 
333
-
269
+
334
270
  newAttributes.push(attribute);
335
271
  for (let key in attributes) {
336
272
 
337
273
  let value = attributes[key];
338
274
  let oldvalue = value;
339
- if (value && !value.new) {
275
+ if (value && !value.new) {
340
276
  if (value && value.includes("={")) {
341
277
  value = value.replace("=", "");
342
278
  value == "undefined" ? (value = '"') : (value = value);
343
-
279
+
344
280
  key == 'style' ? value = `{this.parseStyle({${value.split('{{')[1].split('}}')[0]}})}` : null
345
281
 
346
-
282
+
347
283
  value = `="\$${value}",`;
348
284
  string = string.replace(oldvalue, value);
349
285
 
350
286
  } else if (value && value.includes("={`")) {
351
287
  value = value.replace("=", "");
352
-
288
+
353
289
  value = `"\$${value}",`;
354
290
  string = string.replace(oldvalue, value);
355
291
 
@@ -420,11 +356,11 @@ function Compiler(func) {
420
356
  let setKey = line.split("=")[0].split(",")[1].trim().replace("]", "");
421
357
 
422
358
  key = key.replace("[", "").replace(",", "");
423
- let value = line.split("=")[1].split("useState(")[1]
424
-
359
+ let value = line.split("=")[1].split("useState(")[1]
360
+
425
361
  let regex = /useState\((.*)\)/gs
426
362
  value = value.match(regex) ? value.match(regex)[0].split("useState(")[1].split(")")[0].trim() : value
427
- switch(true){
363
+ switch (true) {
428
364
  case value.startsWith("'"):
429
365
  type = "String"
430
366
  break;
@@ -451,7 +387,7 @@ function Compiler(func) {
451
387
  break;
452
388
  case value.includes("false"):
453
389
  type = "Boolean"
454
- break;
390
+ break;
455
391
  case value.includes("null"):
456
392
  type = "Null"
457
393
  break;
@@ -460,19 +396,19 @@ function Compiler(func) {
460
396
  break;
461
397
  case value.includes("?") && value.includes(":"):
462
398
  type = "Any"
463
- break;
399
+ break;
464
400
  default:
465
401
  type = "*"
466
402
  break;
467
403
  }
468
-
404
+
469
405
  let typejsdoc = `/** @type {${type}} */`;
470
406
 
471
-
407
+
472
408
  let newState = `${varType} [${typejsdoc}${key}, ${setKey}] = this.useState('${key}', ${value}
473
409
 
474
410
  `;
475
-
411
+
476
412
 
477
413
  // get setkey calls and replace with this.setKey
478
414
  string.split("\n").forEach((line) => {
@@ -492,12 +428,31 @@ function Compiler(func) {
492
428
  // let ref = useRef(null)
493
429
  let type = line.split(" ")[0];
494
430
  let key = line.split("=")[0].split(" ")[1].trim();
495
- let value = line.split("=")[1].split("useRef(")[1]
496
-
431
+ let value = line.split("=")[1].split("useRef(")[1]
432
+
497
433
  let regex = /useState\((.*)\)/gs
498
434
  value = value.match(regex) ? value.match(regex)[0].split("useRef(")[1].split(")")[0].trim() : value
499
435
  let newState = `${type} ${key} = this.useRef('${key}', ${value}`;
500
436
 
437
+ string = string.replace(line, newState);
438
+ } else if (line.includes("useReducer") && !line.includes("import")) {
439
+ //ex: const [state, dispatch] = useReducer(function, initialState);
440
+
441
+ line = line.trim();
442
+ line = line.replaceAll(/\s+/g, " ");
443
+
444
+ // derive [key, value] from line
445
+ let varType = line.split(" ")[0];
446
+ let type = ''
447
+ let key = line
448
+ .split("=")[0]
449
+ .split(" ")[1]
450
+ .trim()
451
+ .replace("[", "")
452
+ .replace(",", "");
453
+ let setKey = line.split("=")[0].split(",")[1].trim().replace("]", "");
454
+ let reducer = line.split("=")[1].split("useReducer(")[1]
455
+ let newState = `${varType} [${key}, ${setKey}] = this.useReducer('${key}', ${line.includes('=>') ? reducer + '=>{' : reducer}`
501
456
  string = string.replace(line, newState);
502
457
  }
503
458
  }
@@ -535,7 +490,7 @@ function Compiler(func) {
535
490
  string = string.replaceAll(/\$\{\/\*.*\*\/\}/gs, "");
536
491
 
537
492
  string = string.replaceAll('../src', './src')
538
-
493
+
539
494
 
540
495
  // capture <Component />, <Component></Component>, and <Component>content</Component>
541
496
 
@@ -556,9 +511,9 @@ function Compiler(func) {
556
511
  let myChildrens = [];
557
512
 
558
513
  let name = component.split("<")[1].split(">")[0].split(" ")[0].replace("/", "");
559
- let props = component.split(`<${name}`)[1].split(">")[0].trim()
560
-
561
-
514
+ let props = component.split(`<${name}`)[1].split(">")[0].trim()
515
+
516
+
562
517
  let savedname = name;
563
518
  let children = props
564
519
  ? component
@@ -593,46 +548,46 @@ function Compiler(func) {
593
548
  myChildrens.push(child.children);
594
549
  }
595
550
  });
596
-
597
-
551
+
552
+
598
553
 
599
554
  /**
600
555
  * @prop {string} props
601
556
  * @description replace any given possible value in props and parse the string to a valid JSON object
602
557
  */
603
- props = props
604
- .replaceAll('"', "'")
605
-
606
-
607
- .replaceAll(",,", ',')
608
- .replaceAll("className", "class")
609
- .replaceAll("classname", "class")
610
- .replaceAll("'${", "")
611
- .replaceAll("}'", "")
612
- .split("$:")
613
- .join("")
614
- // replace / with '' at the end of the string
615
- .replace(/\/\s*$/, "")
616
-
617
- .replace(/,\s*$/, "")
618
- .replaceAll('="', ':"')
619
- .replaceAll("='", ":'")
620
- .replaceAll('=`', ':`')
621
- .replaceAll(`={\``, ':`')
622
- .replaceAll('`}', '`')
623
- .replaceAll(",,", ',')
624
- .replaceAll(/=(?=(?:(?:[^"']*["'][^"']*['"])*[^"']*$))/g, ':');
625
-
626
- props = props.replace(/:('[^']*'|"[^"]*")/g, ':$1,');
558
+ props = props
559
+ .replaceAll('"', "'")
560
+
561
+
562
+ .replaceAll(",,", ',')
563
+ .replaceAll("className", "class")
564
+ .replaceAll("classname", "class")
565
+ .replaceAll("'${", "")
566
+ .replaceAll("}'", "")
567
+ .split("$:")
568
+ .join("")
569
+ // replace / with '' at the end of the string
570
+ .replace(/\/\s*$/, "")
571
+
572
+ .replace(/,\s*$/, "")
573
+ .replaceAll('="', ':"')
574
+ .replaceAll("='", ":'")
575
+ .replaceAll('=`', ':`')
576
+ .replaceAll(`={\``, ':`')
577
+ .replaceAll('`}', '`')
578
+ .replaceAll(",,", ',')
579
+ .replaceAll(/=(?=(?:(?:[^"']*["'][^"']*['"])*[^"']*$))/g, ':');
580
+
581
+ props = props.replace(/:('[^']*'|"[^"]*")/g, ':$1,');
627
582
  // ANY VALUE NUMBER BOOLEAN OR STRING
628
583
  props = props.replace(/=(\d+)/g, ':$1,');
629
584
  props = props.replaceAll(',,', ',')
630
-
631
-
632
- /**
633
- * @memoize - memoize a component to be remembered on each render and replace the old jsx
634
- */
635
-
585
+
586
+
587
+ /**
588
+ * @memoize - memoize a component to be remembered on each render and replace the old jsx
589
+ */
590
+
636
591
  let replace = "";
637
592
  replace = isChild
638
593
  ? `this.memoize(this.createComponent(${savedname.replaceAll('/', '')}, ${props}, [${myChildrens.length > 0 ? myChildrens.join(",") : ""
@@ -648,10 +603,10 @@ function Compiler(func) {
648
603
 
649
604
 
650
605
 
651
- string = string.replaceAll('vaderjs/client', './vader.js')
606
+ string = string.replaceAll('vaderjs/client', '/vader.js')
652
607
  string = string.replaceAll("<>", "`").replaceAll("</>", "`");
653
608
  string = parseComponents(string);
654
-
609
+
655
610
  string = string
656
611
  .replaceAll("className", "class")
657
612
  .replaceAll("classname", "class");
@@ -659,127 +614,108 @@ function Compiler(func) {
659
614
  string += `\n\n //wascompiled`;
660
615
 
661
616
  string = string.replaceAll("undefined", "");
662
- let exportss = {}
663
- string.split('\n').forEach(line => {
664
- if(line.includes('import')){
665
- // Regular expression for matching import() statements
666
- let asyncimportMatch = line.match(/import\s*\((.*)\)/gs);
667
617
 
668
- // Regular expression for matching regular import statements excluding lines with HTML elements
669
- let regularimportMatch = line.match(/import\s+([\w\s{},]*)\s*from\s*(['"][^'"]+['"])(?![^<]*>)/gs);
618
+ string.split('\n').forEach(line => {
619
+ if (line.includes('import')) {
620
+ // Regular expression for matching import() statements
621
+ let asyncimportMatch = line.match(/import\s*\((.*)\)/gs);
622
+ let regularimportMatch = line.match(/import\s+([\w\s{},]*)\s*from\s*(['"][^'"]+['"])(?![^<]*>)/gs);
670
623
 
671
- if(asyncimportMatch){
624
+ if (asyncimportMatch) {
672
625
  asyncimportMatch.forEach(async (match) => {
673
626
  let beforeimport = match
674
627
  let path = match.split('(')[1].split(')')[0].trim()
675
628
  let newImport = ''
676
- switch(true){
629
+ switch (true) {
677
630
  case path && path.includes('json'):
678
- path = path.replace(';', '')
679
- newImport = `JSON.parse(require(${path}))`
680
- let htmlPrefetch = `<link rel="prefetch" href="${path}" as="fetch">`
681
- let beforeHTML = fs.existsSync(process.cwd() + "/dist/index.html") ? fs.readFileSync(process.cwd() + "/dist/index.html", "utf8") : '';
682
- if(!beforeHTML.includes(htmlPrefetch)){
683
- let newHTML = beforeHTML + `\n${htmlPrefetch}`
684
- fs.writeFileSync(process.cwd() + "/dist/index.html", newHTML);
685
- }
686
- break;
687
-
631
+ path = path.replace(';', '')
632
+ newImport = `JSON.parse(await fetch(${path}).then(res => res.json()))`
633
+
634
+ break;
635
+ default:
636
+ let deep = path.split('/').length - 1
637
+ for (let i = 0; i < deep; i++) {
638
+ path = path.split('../').join('')
639
+ path = path.split('./').join('')
640
+ }
641
+ path = path.replace(/'/g, '').trim().replace(/"/g, '').trim()
642
+ // remove double / from path
643
+ path = path.split('//').join('/')
644
+ if (!path.startsWith('./') && !path.includes('/vader.js') && !path.startsWith('src')) {
645
+ path = 'src/' + path
646
+ }
647
+
648
+ path = path.replaceAll('.jsx', '.js');
649
+ newImport = `await import(${path})`
650
+
688
651
  }
689
- if(newImport){
652
+ if (newImport) {
690
653
  string = string.replace(beforeimport, newImport)
691
654
  }
692
655
  })
693
656
  }
694
-
695
- if(regularimportMatch){
657
+
658
+ if (regularimportMatch) {
696
659
  regularimportMatch.forEach(async (match) => {
697
-
660
+
698
661
  let beforeimport = match
699
662
  let path = match.split('from')[1].trim()
700
663
  let newImport = ''
701
664
  let name = match.split('import')[1].split('from')[0].trim()
702
- switch(true){
665
+ switch (true) {
703
666
  case path && path.includes('json'):
704
- path = path.replace(';', '')
705
- newImport = `let ${name} = await require(${path}, {type: 'json'})`
706
- let htmlPrefetch = `<link rel="prefetch" href="${path.replace(/'/g, '')}" as="fetch">`
707
- let beforeHTML = fs.existsSync(process.cwd() + "/dist/index.html") ? fs.readFileSync(process.cwd() + "/dist/index.html", "utf8") : '';
708
- if(!beforeHTML.includes(htmlPrefetch)){
709
- let newHTML = beforeHTML + `\n${htmlPrefetch}`
710
- fs.writeFileSync(process.cwd() + "/dist/index.html", newHTML);
711
- }
712
- break;
713
- case path && path.includes('.jsx'):
714
-
715
- newImport = `let ${name} = await require(${path})`
716
- break;
717
- default:
718
- newImport = `let ${name} = await import(${path})`
667
+ path = path.replace(';', '')
668
+ // remove any ../
669
+ path = path.replaceAll('../', '')
670
+ path = `src/${path.replace(/'/g, '')}`
671
+ newImport = `let ${name} = await fetch('${path}').then(res => res.json())`
672
+
673
+ string = string.replace(beforeimport, newImport)
719
674
  break;
720
- }
721
- if(newImport){
722
- string = string.replace(beforeimport, newImport)
675
+ default:
676
+ let beforePath = path
677
+ let deep = path.split('/').length - 1
678
+ for (let i = 0; i < deep; i++) {
679
+ path = path.split('../').join('')
680
+ path = path.split('./').join('')
681
+ }
682
+ path = path.replace(/'/g, '').trim().replace(/"/g, '').trim()
683
+ // remove double / from path
684
+ path = path.split('//').join('/')
685
+ if (!path.startsWith('./') && !path.includes('/vader.js') && !path.startsWith('src')) {
686
+ path.includes('src') ? path.split('src')[1] : null
687
+ path = '/src/' + path
688
+ } else if (path.startsWith('src')) {
689
+ path = '/' + path
690
+ }
691
+ path = path.replaceAll('.jsx', '.js');
692
+ let html = fs.existsSync(process.cwd() + '/dist/index.html') ? fs.readFileSync(process.cwd() + '/dist/index.html', 'utf8') : ''
693
+ if (!html.includes(`<link rel="modulepreload" href="${path.replace(/'/g, '').trim()}">`)) {
694
+ if (!html.includes(`</head>`)) {
695
+ throw new Error('Could not find </head> in index.html')
696
+ }
697
+ let preload = `<link rel="modulepreload" href="${path.trim()}"><link rel="preload" href="${path.trim()}" as="script">`
698
+
699
+ html = html.replace('</head>', `${preload}</head>`)
700
+
701
+ fs.writeFileSync(process.cwd() + '/dist/index.html', html)
702
+ }
703
+
704
+ string = string.replace(beforePath, "'" + path + "'")
723
705
  }
724
706
  })
725
707
  }
726
- }else if (line.includes('export') && !line.includes('>') && !line.includes('<')) {
727
- let b4line = line;
728
- let exports = line.split('export')[1].trim();
729
- let isDefault = exports.includes('default');
730
-
731
- let name = ''
732
- switch (true) {
733
- case exports && isDefault:
734
-
735
- let expt = exports.split('default')[1].trim();
736
- // Check if it's a class definition
737
- if (expt.includes('class')) {
738
- // also capture extends
739
- let match = expt.match(/class\s*([a-zA-Z0-9_-]+)\s*extends\s*([a-zA-Z0-9_-]+)/gs)
740
- let className = match ? match[0].split('class')[1].split('extends')[0].trim() : expt.split('class')[1].split('{')[0].trim();
741
- name = className
742
-
743
- exportss[isDefault ? 'default' : className] = className
744
- } else if (expt.includes('function')) {
745
- let funcName = expt.split('function')[1].split('(')[0].trim();
746
- name = funcName
747
- exportss[isDefault ? 'default' : funcName] = funcName
748
- }else{
749
- name = expt
750
- exportss[isDefault ? 'default' : expt] = expt
751
-
752
- }
753
- break;
754
-
755
- default:
756
- let expt2 = exports
757
- if(expt2.includes('function')){
758
- let funcName = expt2.split('function')[1].split('(')[0].trim();
759
- exportss[funcName] = funcName
760
- }else if(expt2.includes('class')){
761
- let match = expt2.match(/class\s*([a-zA-Z0-9_-]+)\s*extends\s*([a-zA-Z0-9_-]+)/gs)
762
- let className = match ? match[0].split('class')[1].split('extends')[0].trim() : expt2.split('class')[1].split('{')[0].trim();
763
- name = className
764
- exportss[className] = className
765
- }
766
- break;
767
- }
768
-
769
- string = string.replace(b4line, b4line.replaceAll(/\s+/g, " ").trim().split('export').join('').split('default').join('').trim());
770
708
  }
771
-
772
-
709
+
710
+
773
711
  })
774
- if(exportss){
775
- let exports = Object.keys(exportss).map(key => key + ':' + exportss[key]).join(',')
776
-
777
- Object.keys(exportss).length > 1 ? string += `\n\n return {${exports}}` : string += `\n\nreturn ${Object.keys(exportss) == 'default' ? `{default: ${Object.values(exportss)[0]}}` : `${Object.keys(exportss)[0]}`}`
778
- }
779
-
780
- return string;
712
+
713
+ return string
781
714
  }
782
715
  let bindings = []
716
+ let exec = await import('child_process').then((child) => {
717
+ return child.exec
718
+ })
783
719
  globalThis.isBuilding = false
784
720
  async function Build() {
785
721
  globalThis.isBuilding = true
@@ -794,7 +730,7 @@ async function Build() {
794
730
  fs.mkdirSync(file.split('/').slice(0, -1).join('/'), { recursive: true })
795
731
  break;
796
732
  }
797
- await fs.writeFileSync(file, data);
733
+ await fs.writeFileSync(file, data);
798
734
 
799
735
  return { _written: true };
800
736
  };
@@ -806,102 +742,140 @@ async function Build() {
806
742
  absolute: true,
807
743
  recursive: true
808
744
  });
809
-
745
+
810
746
  // Process files in the 'pages' directory
811
747
  let appjs = '';
812
748
  let hasWritten = []
813
- const writejs = () =>{
749
+ const writejs = () => {
750
+
814
751
  writer(process.cwd() + '/dist/app.js', appjs)
815
752
  }
753
+
754
+
755
+
816
756
  for await (let file of glb) {
817
757
  // Normalize file paths
818
758
  let origin = file.replace(/\\/g, '/');
819
- let fileName = origin.split('/pages/')[1].split('.jsx')[0].replace('.jsx', '') + '.jsx';
759
+ let fileName = origin.split('/pages/')[1].split('.jsx')[0].replace('.jsx', '') + '.jsx';
820
760
  let isBasePath = fileName === 'index.jsx';
821
-
761
+
822
762
  // Extract all dynamic parameters from the file path [param1]/[param2]/[param3
823
- let aburl = origin.split('/pages')[1].split('.jsx')[0].replace('.jsx', '').split('[').join(':').split(']').join('');
824
-
825
- if(aburl.includes('...')){
763
+ let aburl = origin.split('/pages')[1].split('.jsx')[0].replace('.jsx', '').split('[').join(':').split(']').join('');
764
+
765
+ if (aburl.includes('...')) {
826
766
  // this is a catch all route
827
767
  // it should be /pages/[...]/index.jsx or /pages/[...].jsx
828
768
  aburl = aburl.split('...').join('*').split(':*').join('*')
829
- aburl = aburl.replaceAll('./index', '')
830
-
831
- }
769
+ aburl = aburl.replaceAll('./index', '')
770
+
771
+ }
832
772
  // Create an object with URL and pathname properties
833
773
  let obj = {
834
774
  url: isBasePath ? '/' : aburl.replaceAll('/index', ''),
835
775
  pathname: `/pages/${origin.split('pages/')[1].split('.jsx')[0].replace('.jsx', '')}.jsx`,
836
776
  fullpath: origin,
837
- };
838
-
839
- // Read and compile file content
777
+ };
778
+
779
+
780
+
840
781
  let data = await fs.readFileSync(origin, "utf8");
841
- data = Compiler(data)
842
-
843
- await writer(process.cwd() + "/dist/pages/" + fileName, data);
844
-
782
+ data = Compiler(data)
783
+
784
+
785
+
786
+ await writer(process.cwd() + "/dist/pages/" + fileName.replace('.jsx', '.js'), data).then(async () => {
787
+
788
+ let { minify } = await import('terser')
789
+ try {
790
+ let minified = await minify(data, {
791
+ ecma: " 2016",
792
+ module: true,
793
+ compress: true,
794
+ mangle: true
795
+ })
796
+ await writer(process.cwd() + "/dist/pages/" + fileName.replace('.jsx', '.js'), minified.code)
797
+ } catch (error) {
798
+ console.log(error)
799
+ }
800
+ })
801
+
802
+
803
+ obj.compiledPath = process.cwd() + "/dist/pages/" + fileName.replace('.jsx', '.js')
804
+
805
+
845
806
  // Generate routing logic
846
807
  let js = `
847
808
  router.get('${obj.url}', async (req, res) => {
848
- res.render(await require('.${obj.pathname}'), req, res)
809
+ res.render(await import('./pages/${fileName.replace('.jsx', '.js')}'), req, res)
849
810
  })
850
811
  //@desc ${obj.pathname}
851
812
  ` + '\n';
852
813
  appjs += js
853
-
814
+
854
815
  writejs()
855
816
 
856
-
857
817
 
858
- let beforeHTML = fs.existsSync(process.cwd() + "/dist/index.html") ? await reader(process.cwd() + "/dist/index.html") : '';
859
- if(!beforeHTML.includes(`<link rel="prefetch" href="/pages/${origin.split('pages/')[1] }" as="fetch">`)){
860
- let newHTML = beforeHTML + `\n<link rel="prefetch" href="/pages/${origin.split('pages/')[1] }" as="fetch">`
861
- await writer(process.cwd() + "/dist/index.html", newHTML);
862
- }
818
+
819
+ console.log(`Compilation finished`)
820
+
863
821
  }
864
-
865
-
866
-
822
+
823
+
824
+
867
825
  const scannedSourceFiles = await glob("**/**.{jsx,js,json}", {
868
826
  ignore: ["node_modules/**/*", "dist/**/*"],
869
827
  cwd: process.cwd() + '/src/',
870
828
  absolute: true,
871
829
  });
872
- const scannedVaderFiles = await glob("**/**.{html,js}", {
830
+ const scannedVaderFiles = await glob("**/**.{html,js}", {
873
831
  cwd: process.cwd() + '/node_modules/vaderjs/runtime',
874
832
  absolute: true,
875
- });
876
- scannedVaderFiles.forEach(async (file) => {
877
- file = file.replace(/\\/g, '/');
878
-
879
-
880
- let name = file.split( '/node_modules/vaderjs/runtime/')[1]
881
- if(file.includes('index.html') && fs.existsSync(process.cwd() + "/dist/" + name)){
882
- return
883
- }
833
+ });
834
+ scannedVaderFiles.forEach(async (file) => {
835
+ file = file.replace(/\\/g, '/');
836
+
837
+
838
+ let name = file.split('/node_modules/vaderjs/runtime/')[1]
839
+ if (file.includes('index.html') && fs.existsSync(process.cwd() + "/dist/" + name)) {
840
+ return
841
+ }
884
842
  let data = await reader(file)
885
843
  bundleSize += fs.statSync(file).size;
886
844
  await writer(process.cwd() + "/dist/" + name, data);
887
845
  })
888
- scannedSourceFiles.forEach(async (file) => {
889
- file = file.replace(/\\/g, '/');
890
- let name = file.split('/src/')[1]
846
+ scannedSourceFiles.forEach(async (file) => {
847
+ file = file.replace(/\\/g, '/');
848
+ let name = file.split('/src/')[1]
891
849
  //parse jsx
892
-
850
+
893
851
  let data = await reader(process.cwd() + "/src/" + name)
894
852
  if (name.includes('.jsx')) {
895
- data = Compiler(data)
853
+ data = Compiler(data)
854
+
855
+ await writer(process.cwd() + "/dist/src/" + name.split('.jsx').join('.js'), data).then(async () => {
856
+ let { minify } = await import('terser')
857
+ try {
858
+ let minified = await minify(data, {
859
+ ecma: " 2016",
860
+ module: true,
861
+ compress: true,
862
+ })
863
+ await writer(process.cwd() + "/dist/src/" + name.replace('.jsx', '.js'), minified.code)
864
+ } catch (error) {
865
+ console.log(error)
866
+ }
867
+
868
+ })
869
+ return
896
870
  }
897
871
  bundleSize += fs.statSync(process.cwd() + "/src/" + name).size;
898
872
  await writer(process.cwd() + "/dist/src/" + name, data);
899
873
  })
900
-
901
- const scannedPublicFiles = await glob("**/**.{css,js,html}", {
874
+
875
+ const scannedPublicFiles = await glob("**/**.{css,js,html}", {
902
876
  ignore: ["node_modules/**/*", "dist/**/*"],
903
877
  cwd: process.cwd() + '/public/',
904
- absolute: true,
878
+ absolute: true,
905
879
  });
906
880
  scannedPublicFiles.forEach(async (file) => {
907
881
  file = file.replace(/\\/g, '/');
@@ -909,74 +883,75 @@ async function Build() {
909
883
  let data = await reader(process.cwd() + "/public/" + file)
910
884
  bundleSize += fs.statSync(process.cwd() + "/public/" + file).size;
911
885
  await writer(process.cwd() + "/dist/public/" + file, data);
912
- })
886
+ })
913
887
  const scannedFiles = await glob("**/**.{css,js,html}", {
914
888
  ignore: ["node_modules/**/*", "dist/**/*"],
915
- cwd: process.cwd() + "/runtime/",
889
+ cwd: process.cwd() + "/runtime/",
916
890
  absolute: true,
917
- })
891
+ })
918
892
 
919
893
  if (!fs.existsSync(process.cwd() + "/dist/index.html")) {
920
-
894
+
921
895
  scannedFiles.forEach(async (file) => {
922
896
  file = file.split(process.cwd() + '/runtime/')[1]
923
897
 
924
898
  if (file === "app.js") {
925
899
  return
926
- }
927
- if(file.includes('index.html') && fs.existsSync(process.cwd() + "/runtime/" + file)){
928
-
929
- return
930
900
  }
931
- bundleSize += fs.statSync(process.cwd() + "/runtime/" + file).size;
901
+ if (file.includes('index.html') && fs.existsSync(process.cwd() + "/runtime/" + file)) {
902
+
903
+ return
904
+ }
905
+ bundleSize += fs.statSync(process.cwd() + "/runtime/" + file).size;
932
906
  let data = await reader(process.cwd() + "/runtime/" + file)
933
907
  await writer(process.cwd() + "/dist/" + file, data);
934
908
  });
935
-
909
+
936
910
  }
937
-
911
+
938
912
  globalThis.isBuilding = false
939
913
  }
940
- import { watch } from "fs";
914
+ import { watch } from "fs";
941
915
 
942
916
  switch (true) {
943
917
  case process.argv.includes('--watch'):
944
918
 
919
+ globalThis.devMode = true
945
920
  console.log(`
946
921
  Vader.js v1.3.3
947
922
  - Watching for changes in ./pages
948
923
  - Watching for changes in ./src
949
924
  `)
950
925
  Build()
951
-
952
- const watcher = watch(
953
- process.cwd() + '/pages',
954
- { recursive: true },
955
- (event, filename) => {
956
- if (event == 'change'
926
+
927
+ const watcher = watch(
928
+ process.cwd() + '/pages',
929
+ { recursive: true },
930
+ (event, filename) => {
931
+ if (event == 'change'
957
932
  && !globalThis.isBuilding
958
- ) {
959
- Build()
960
- }
961
- },
962
- );
963
- const watcher2 = watch(
964
- process.cwd() + '/src',
965
- { recursive: true },
966
- (event, filename) => {
967
- if (event == 'change'
933
+ ) {
934
+ Build()
935
+ }
936
+ },
937
+ );
938
+ const watcher2 = watch(
939
+ process.cwd() + '/src',
940
+ { recursive: true },
941
+ (event, filename) => {
942
+ if (event == 'change'
968
943
  && !globalThis.isBuilding
969
- ) {
970
- Build()
971
- }
972
- },
973
- );
974
- watcher2.on('error', (err) => console.log(err))
975
- watcher.on('error', (err) => console.log(err))
976
-
944
+ ) {
945
+ Build()
946
+ }
947
+ },
948
+ );
949
+ watcher2.on('error', (err) => console.log(err))
950
+ watcher.on('error', (err) => console.log(err))
951
+
977
952
  break;
978
953
  case process.argv.includes('--build'):
979
-
954
+ globalThis.devMode = false
980
955
  console.log(`
981
956
  Vader.js v1.3.3
982
957
  Building to ./dist