juxscript 1.0.96 → 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 +98 -27
- package/package.json +1 -1
package/machinery/compiler3.js
CHANGED
|
@@ -215,16 +215,97 @@ export class JuxCompiler {
|
|
|
215
215
|
}
|
|
216
216
|
|
|
217
217
|
generateEntryPoint(views, dataModules, sharedModules) {
|
|
218
|
+
let entry = `// Auto-generated JUX entry point\n\n`;
|
|
218
219
|
const allIssues = [];
|
|
219
220
|
const sourceSnapshot = {};
|
|
220
221
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
222
|
+
const juxImports = new Set();
|
|
223
|
+
[...views, ...dataModules, ...sharedModules].forEach(m => {
|
|
224
|
+
for (const match of m.content.matchAll(/import\s*\{\s*([^}]+)\s*\}\s*from\s*['"]juxscript['"]/g)) {
|
|
225
|
+
match[1].split(',').map(s => s.trim()).forEach(imp => {
|
|
226
|
+
if (imp) juxImports.add(imp);
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
if (juxImports.size > 0) {
|
|
232
|
+
entry += `import { ${[...juxImports].sort().join(', ')} } from 'juxscript';\n\n`;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
dataModules.forEach(m => {
|
|
236
|
+
entry += `import * as ${this.sanitizeName(m.name)}Data from './jux/${m.file}';\n`;
|
|
237
|
+
});
|
|
238
|
+
sharedModules.forEach(m => {
|
|
239
|
+
entry += `import * as ${this.sanitizeName(m.name)}Shared from './jux/${m.file}';\n`;
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
entry += `\n// Expose to window\n`;
|
|
243
|
+
dataModules.forEach(m => entry += `Object.assign(window, ${this.sanitizeName(m.name)}Data);\n`);
|
|
244
|
+
sharedModules.forEach(m => entry += `Object.assign(window, ${this.sanitizeName(m.name)}Shared);\n`);
|
|
245
|
+
|
|
246
|
+
if (juxImports.size > 0) {
|
|
247
|
+
entry += `\nObject.assign(window, { ${[...juxImports].join(', ')} });\n`;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
entry += `\n// --- VIEW FUNCTIONS ---\n`;
|
|
251
|
+
|
|
252
|
+
views.forEach(v => {
|
|
253
|
+
const capitalized = v.name.charAt(0).toUpperCase() + v.name.slice(1);
|
|
254
|
+
allIssues.push(...this.validateViewCode(v.name, v.content));
|
|
255
|
+
|
|
256
|
+
sourceSnapshot[v.file] = {
|
|
257
|
+
name: v.name,
|
|
258
|
+
file: v.file,
|
|
259
|
+
content: v.content,
|
|
260
|
+
lines: v.content.split('\n')
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
let viewCode = this.removeImports(v.content).replace(/^\s*export\s+default\s+.*$/gm, '');
|
|
264
|
+
const asyncPrefix = viewCode.includes('await ') ? 'async ' : '';
|
|
265
|
+
|
|
266
|
+
entry += `\n${asyncPrefix}function render${capitalized}() {\n${viewCode}\n}\n`;
|
|
267
|
+
});
|
|
226
268
|
|
|
227
|
-
|
|
269
|
+
dataModules.forEach(m => {
|
|
270
|
+
sourceSnapshot[m.file] = { name: m.name, file: m.file, content: m.content, lines: m.content.split('\n') };
|
|
271
|
+
});
|
|
272
|
+
sharedModules.forEach(m => {
|
|
273
|
+
sourceSnapshot[m.file] = { name: m.name, file: m.file, content: m.content, lines: m.content.split('\n') };
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
this._sourceSnapshot = sourceSnapshot;
|
|
277
|
+
this._validationIssues = allIssues;
|
|
278
|
+
entry += this._generateRouter(views);
|
|
279
|
+
return entry;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
reportValidationIssues() {
|
|
283
|
+
const issues = this._validationIssues || [];
|
|
284
|
+
const errors = issues.filter(i => i.type === 'error');
|
|
285
|
+
const warnings = issues.filter(i => i.type === 'warning');
|
|
286
|
+
|
|
287
|
+
if (issues.length > 0) {
|
|
288
|
+
console.log('\n⚠️ Validation Issues:\n');
|
|
289
|
+
issues.forEach(issue => {
|
|
290
|
+
const icon = issue.type === 'error' ? '❌' : '⚠️';
|
|
291
|
+
console.log(`${icon} [${issue.view}:${issue.line}] ${issue.message}`);
|
|
292
|
+
});
|
|
293
|
+
console.log('');
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
return { isValid: errors.length === 0, errors, warnings };
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
_generateRouter(views) {
|
|
300
|
+
let routeMap = '';
|
|
301
|
+
views.forEach(v => {
|
|
302
|
+
const cap = v.name.charAt(0).toUpperCase() + v.name.slice(1);
|
|
303
|
+
if (v.name.toLowerCase() === 'index') routeMap += ` '/': render${cap},\n`;
|
|
304
|
+
routeMap += ` '/${v.name.toLowerCase()}': render${cap},\n`;
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
return `
|
|
308
|
+
// --- JUX SOURCE LOADER ---
|
|
228
309
|
var __juxSources = null;
|
|
229
310
|
async function __juxLoadSources() {
|
|
230
311
|
if (__juxSources) return __juxSources;
|
|
@@ -247,9 +328,9 @@ function __juxFindSource(stack) {
|
|
|
247
328
|
}
|
|
248
329
|
}
|
|
249
330
|
}
|
|
250
|
-
// Also
|
|
331
|
+
// Also try to find by filename in stack
|
|
251
332
|
for (var file in __juxSources || {}) {
|
|
252
|
-
if (stack.indexOf(file) > -1
|
|
333
|
+
if (stack.indexOf(file) > -1) {
|
|
253
334
|
return { file: file, source: __juxSources[file] };
|
|
254
335
|
}
|
|
255
336
|
}
|
|
@@ -416,6 +497,7 @@ var __juxErrorOverlay = {
|
|
|
416
497
|
|
|
417
498
|
document.body.appendChild(overlay);
|
|
418
499
|
|
|
500
|
+
// Trigger transition
|
|
419
501
|
requestAnimationFrame(function() {
|
|
420
502
|
overlay.classList.add('visible');
|
|
421
503
|
});
|
|
@@ -424,10 +506,7 @@ var __juxErrorOverlay = {
|
|
|
424
506
|
}
|
|
425
507
|
};
|
|
426
508
|
|
|
427
|
-
//
|
|
428
|
-
// INSTALL GLOBAL ERROR HANDLERS IMMEDIATELY (before imports!)
|
|
429
|
-
// This catches errors during module loading
|
|
430
|
-
// ═══════════════════════════════════════════════════════════════
|
|
509
|
+
// Install global error handlers IMMEDIATELY
|
|
431
510
|
window.addEventListener('error', function(e) {
|
|
432
511
|
__juxErrorOverlay.show(e.error || new Error(e.message), 'Uncaught Error');
|
|
433
512
|
}, true);
|
|
@@ -435,16 +514,14 @@ window.addEventListener('error', function(e) {
|
|
|
435
514
|
window.addEventListener('unhandledrejection', function(e) {
|
|
436
515
|
__juxErrorOverlay.show(e.reason || new Error('Promise rejected'), 'Unhandled Promise Rejection');
|
|
437
516
|
}, true);
|
|
517
|
+
`;
|
|
438
518
|
|
|
439
|
-
//
|
|
440
|
-
// NOW SAFE TO IMPORT MODULES
|
|
441
|
-
// ═══════════════════════════════════════════════════════════════
|
|
519
|
+
// --- END ERROR HANDLER ---
|
|
442
520
|
|
|
443
|
-
`;
|
|
444
521
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
522
|
+
const allIssues = [];
|
|
523
|
+
const sourceSnapshot = {};
|
|
524
|
+
|
|
448
525
|
const juxImports = new Set();
|
|
449
526
|
[...views, ...dataModules, ...sharedModules].forEach(m => {
|
|
450
527
|
for (const match of m.content.matchAll(/import\s*\{\s*([^}]+)\s*\}\s*from\s*['"]juxscript['"]/g)) {
|
|
@@ -473,9 +550,6 @@ window.addEventListener('unhandledrejection', function(e) {
|
|
|
473
550
|
entry += `\nObject.assign(window, { ${[...juxImports].join(', ')} });\n`;
|
|
474
551
|
}
|
|
475
552
|
|
|
476
|
-
// ═══════════════════════════════════════════════════════════════
|
|
477
|
-
// STEP 3: View functions
|
|
478
|
-
// ═══════════════════════════════════════════════════════════════
|
|
479
553
|
entry += `\n// --- VIEW FUNCTIONS ---\n`;
|
|
480
554
|
|
|
481
555
|
views.forEach(v => {
|
|
@@ -504,10 +578,6 @@ window.addEventListener('unhandledrejection', function(e) {
|
|
|
504
578
|
|
|
505
579
|
this._sourceSnapshot = sourceSnapshot;
|
|
506
580
|
this._validationIssues = allIssues;
|
|
507
|
-
|
|
508
|
-
// ═══════════════════════════════════════════════════════════════
|
|
509
|
-
// STEP 4: Router (no error overlay code - it's already at top)
|
|
510
|
-
// ═══════════════════════════════════════════════════════════════
|
|
511
581
|
entry += this._generateRouter(views);
|
|
512
582
|
return entry;
|
|
513
583
|
}
|
|
@@ -537,8 +607,9 @@ window.addEventListener('unhandledrejection', function(e) {
|
|
|
537
607
|
routeMap += ` '/${v.name.toLowerCase()}': render${cap},\n`;
|
|
538
608
|
});
|
|
539
609
|
|
|
540
|
-
// Router
|
|
610
|
+
// Router only - error handlers are now at the top of the bundle
|
|
541
611
|
return `
|
|
612
|
+
|
|
542
613
|
// --- JUX ROUTER ---
|
|
543
614
|
const routes = {\n${routeMap}};
|
|
544
615
|
|