juxscript 1.0.95 → 1.0.97
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/machinery/compiler3.js +102 -2
- package/package.json +1 -1
package/machinery/compiler3.js
CHANGED
|
@@ -318,7 +318,6 @@ async function __juxLoadSources() {
|
|
|
318
318
|
return __juxSources;
|
|
319
319
|
}
|
|
320
320
|
|
|
321
|
-
// Find source file from error stack
|
|
322
321
|
function __juxFindSource(stack) {
|
|
323
322
|
var match = stack.match(/render(\\w+)/);
|
|
324
323
|
if (match) {
|
|
@@ -329,6 +328,12 @@ function __juxFindSource(stack) {
|
|
|
329
328
|
}
|
|
330
329
|
}
|
|
331
330
|
}
|
|
331
|
+
// Also try to find by filename in stack
|
|
332
|
+
for (var file in __juxSources || {}) {
|
|
333
|
+
if (stack.indexOf(file) > -1) {
|
|
334
|
+
return { file: file, source: __juxSources[file] };
|
|
335
|
+
}
|
|
336
|
+
}
|
|
332
337
|
return null;
|
|
333
338
|
}
|
|
334
339
|
|
|
@@ -501,7 +506,7 @@ var __juxErrorOverlay = {
|
|
|
501
506
|
}
|
|
502
507
|
};
|
|
503
508
|
|
|
504
|
-
//
|
|
509
|
+
// Install global error handlers IMMEDIATELY
|
|
505
510
|
window.addEventListener('error', function(e) {
|
|
506
511
|
__juxErrorOverlay.show(e.error || new Error(e.message), 'Uncaught Error');
|
|
507
512
|
}, true);
|
|
@@ -509,6 +514,101 @@ window.addEventListener('error', function(e) {
|
|
|
509
514
|
window.addEventListener('unhandledrejection', function(e) {
|
|
510
515
|
__juxErrorOverlay.show(e.reason || new Error('Promise rejected'), 'Unhandled Promise Rejection');
|
|
511
516
|
}, true);
|
|
517
|
+
`;
|
|
518
|
+
|
|
519
|
+
// --- END ERROR HANDLER ---
|
|
520
|
+
|
|
521
|
+
|
|
522
|
+
const allIssues = [];
|
|
523
|
+
const sourceSnapshot = {};
|
|
524
|
+
|
|
525
|
+
const juxImports = new Set();
|
|
526
|
+
[...views, ...dataModules, ...sharedModules].forEach(m => {
|
|
527
|
+
for (const match of m.content.matchAll(/import\s*\{\s*([^}]+)\s*\}\s*from\s*['"]juxscript['"]/g)) {
|
|
528
|
+
match[1].split(',').map(s => s.trim()).forEach(imp => {
|
|
529
|
+
if (imp) juxImports.add(imp);
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
});
|
|
533
|
+
|
|
534
|
+
if (juxImports.size > 0) {
|
|
535
|
+
entry += `import { ${[...juxImports].sort().join(', ')} } from 'juxscript';\n\n`;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
dataModules.forEach(m => {
|
|
539
|
+
entry += `import * as ${this.sanitizeName(m.name)}Data from './jux/${m.file}';\n`;
|
|
540
|
+
});
|
|
541
|
+
sharedModules.forEach(m => {
|
|
542
|
+
entry += `import * as ${this.sanitizeName(m.name)}Shared from './jux/${m.file}';\n`;
|
|
543
|
+
});
|
|
544
|
+
|
|
545
|
+
entry += `\n// Expose to window\n`;
|
|
546
|
+
dataModules.forEach(m => entry += `Object.assign(window, ${this.sanitizeName(m.name)}Data);\n`);
|
|
547
|
+
sharedModules.forEach(m => entry += `Object.assign(window, ${this.sanitizeName(m.name)}Shared);\n`);
|
|
548
|
+
|
|
549
|
+
if (juxImports.size > 0) {
|
|
550
|
+
entry += `\nObject.assign(window, { ${[...juxImports].join(', ')} });\n`;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
entry += `\n// --- VIEW FUNCTIONS ---\n`;
|
|
554
|
+
|
|
555
|
+
views.forEach(v => {
|
|
556
|
+
const capitalized = v.name.charAt(0).toUpperCase() + v.name.slice(1);
|
|
557
|
+
allIssues.push(...this.validateViewCode(v.name, v.content));
|
|
558
|
+
|
|
559
|
+
sourceSnapshot[v.file] = {
|
|
560
|
+
name: v.name,
|
|
561
|
+
file: v.file,
|
|
562
|
+
content: v.content,
|
|
563
|
+
lines: v.content.split('\n')
|
|
564
|
+
};
|
|
565
|
+
|
|
566
|
+
let viewCode = this.removeImports(v.content).replace(/^\s*export\s+default\s+.*$/gm, '');
|
|
567
|
+
const asyncPrefix = viewCode.includes('await ') ? 'async ' : '';
|
|
568
|
+
|
|
569
|
+
entry += `\n${asyncPrefix}function render${capitalized}() {\n${viewCode}\n}\n`;
|
|
570
|
+
});
|
|
571
|
+
|
|
572
|
+
dataModules.forEach(m => {
|
|
573
|
+
sourceSnapshot[m.file] = { name: m.name, file: m.file, content: m.content, lines: m.content.split('\n') };
|
|
574
|
+
});
|
|
575
|
+
sharedModules.forEach(m => {
|
|
576
|
+
sourceSnapshot[m.file] = { name: m.name, file: m.file, content: m.content, lines: m.content.split('\n') };
|
|
577
|
+
});
|
|
578
|
+
|
|
579
|
+
this._sourceSnapshot = sourceSnapshot;
|
|
580
|
+
this._validationIssues = allIssues;
|
|
581
|
+
entry += this._generateRouter(views);
|
|
582
|
+
return entry;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
reportValidationIssues() {
|
|
586
|
+
const issues = this._validationIssues || [];
|
|
587
|
+
const errors = issues.filter(i => i.type === 'error');
|
|
588
|
+
const warnings = issues.filter(i => i.type === 'warning');
|
|
589
|
+
|
|
590
|
+
if (issues.length > 0) {
|
|
591
|
+
console.log('\n⚠️ Validation Issues:\n');
|
|
592
|
+
issues.forEach(issue => {
|
|
593
|
+
const icon = issue.type === 'error' ? '❌' : '⚠️';
|
|
594
|
+
console.log(`${icon} [${issue.view}:${issue.line}] ${issue.message}`);
|
|
595
|
+
});
|
|
596
|
+
console.log('');
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
return { isValid: errors.length === 0, errors, warnings };
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
_generateRouter(views) {
|
|
603
|
+
let routeMap = '';
|
|
604
|
+
views.forEach(v => {
|
|
605
|
+
const cap = v.name.charAt(0).toUpperCase() + v.name.slice(1);
|
|
606
|
+
if (v.name.toLowerCase() === 'index') routeMap += ` '/': render${cap},\n`;
|
|
607
|
+
routeMap += ` '/${v.name.toLowerCase()}': render${cap},\n`;
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
// Router only - error handlers are now at the top of the bundle
|
|
611
|
+
return `
|
|
512
612
|
|
|
513
613
|
// --- JUX ROUTER ---
|
|
514
614
|
const routes = {\n${routeMap}};
|