juxscript 1.0.37 → 1.0.38

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.
@@ -101,12 +101,6 @@
101
101
  "description": "List component",
102
102
  "constructor": "jux.list(id: string, options: ListOptions = {})",
103
103
  "fluentMethods": [
104
- {
105
- "name": "items",
106
- "params": "(value)",
107
- "returns": "this",
108
- "description": "Set items"
109
- },
110
104
  {
111
105
  "name": "addItem",
112
106
  "params": "(value)",
@@ -2059,5 +2053,5 @@
2059
2053
  }
2060
2054
  ],
2061
2055
  "version": "1.0.0",
2062
- "lastUpdated": "2026-01-28T15:24:08.460Z"
2056
+ "lastUpdated": "2026-01-28T17:24:41.869Z"
2063
2057
  }
@@ -419,38 +419,78 @@ export async function bundleJuxFilesToRouter(projectRoot, distDir, options = {})
419
419
  }
420
420
 
421
421
  /**
422
- * Extract shared module exports from a .jux file
423
- *
424
- * @param {string} juxContent - Original .jux file content
425
- * @param {string} moduleName - Module identifier
426
- * @returns {string} Shared module code
422
+ * Extract and replace all string literals with placeholders
423
+ * Handles: template literals WITHOUT interpolations, single quotes, double quotes
424
+ * SKIPS: Template literals WITH ${} interpolations (those are dynamic code)
427
425
  */
428
- function extractSharedModule(juxContent, moduleName) {
429
- // Remove string literals temporarily to avoid false matches
426
+ function extractStrings(code) {
430
427
  const strings = [];
428
+ let result = code;
429
+
430
+ // 1. Template literals WITHOUT interpolations (static strings only)
431
+ // Match backticks that DON'T contain ${
432
+ result = result.replace(/`([^`$\\]|\\[^$])*`/g, (match) => {
433
+ // Double-check it doesn't contain ${
434
+ if (!match.includes('${')) {
435
+ strings.push(match);
436
+ return `__STRING_${strings.length - 1}__`;
437
+ }
438
+ return match; // Leave dynamic templates alone
439
+ });
431
440
 
432
- // Handle template literals, single quotes, and double quotes separately
433
- let code = juxContent
434
- .replace(/`(?:\\.|[^`\\])*`/g, (match) => { strings.push(match); return `__STRING_${strings.length - 1}__`; })
435
- .replace(/"(?:\\.|[^"\\])*"/g, (match) => { strings.push(match); return `__STRING_${strings.length - 1}__`; })
436
- .replace(/'(?:\\.|[^'\\])*'/g, (match) => { strings.push(match); return `__STRING_${strings.length - 1}__`; });
441
+ // 2. Double-quoted strings (with escaped quotes)
442
+ result = result.replace(/"(?:[^"\\]|\\.)*"/g, (match) => {
443
+ strings.push(match);
444
+ return `__STRING_${strings.length - 1}__`;
445
+ });
437
446
 
438
- // Remove ALL imports - including _dev-imports.js
439
- code = code.replace(/import\s+\{[^}]+\}\s+from\s+__STRING_\d+__;?\s*/g, '');
440
- code = code.replace(/import\s+\*\s+as\s+\w+\s+from\s+__STRING_\d+__;?\s*/g, '');
441
- code = code.replace(/import\s+__STRING_\d+__;?\s*/g, '');
447
+ // 3. Single-quoted strings (with escaped quotes)
448
+ result = result.replace(/'(?:[^'\\]|\\.)*'/g, (match) => {
449
+ strings.push(match);
450
+ return `__STRING_${strings.length - 1}__`;
451
+ });
442
452
 
443
- // Convert exports to declarations (keep function keyword for functions)
444
- code = code.replace(/export\s+const\s+/g, 'const ');
445
- code = code.replace(/export\s+let\s+/g, 'let ');
446
- code = code.replace(/export\s+function\s+/g, 'function ');
447
- code = code.replace(/export\s+class\s+/g, 'class ');
448
- code = code.replace(/export\s+\{([^}]+)\}\s*;?\s*/g, '');
453
+ return { code: result, strings };
454
+ }
449
455
 
450
- // Restore string literals
451
- code = code.replace(/__STRING_(\d+)__/g, (_, index) => strings[index]);
456
+ /**
457
+ * Restore string placeholders back to original strings
458
+ */
459
+ function restoreStrings(code, strings) {
460
+ return code.replace(/__STRING_(\d+)__/g, (match, index) => {
461
+ const idx = parseInt(index, 10);
462
+ if (idx >= 0 && idx < strings.length) {
463
+ return strings[idx];
464
+ }
465
+ console.warn(`[Compiler] String placeholder ${match} not found (idx: ${idx}, available: ${strings.length})`);
466
+ return match; // Leave as-is for debugging
467
+ });
468
+ }
452
469
 
453
- return code;
470
+ /**
471
+ * Extract shared module exports from a .jux file
472
+ *
473
+ * @param {string} juxContent - Original .jux file content
474
+ * @param {string} moduleName - Module identifier
475
+ * @returns {string} Shared module code
476
+ */
477
+ function extractSharedModule(juxContent, moduleName) {
478
+ const { code, strings } = extractStrings(juxContent);
479
+
480
+ // Remove ALL imports
481
+ let result = code.replace(/import\s+\{[^}]+\}\s+from\s+__STRING_\d+__;?\s*/g, '');
482
+ result = result.replace(/import\s+\*\s+as\s+\w+\s+from\s+__STRING_\d+__;?\s*/g, '');
483
+ result = result.replace(/import\s+__STRING_\d+__;?\s*/g, '');
484
+
485
+ // Convert exports to declarations
486
+ result = result.replace(/export\s+const\s+/g, 'const ');
487
+ result = result.replace(/export\s+let\s+/g, 'let ');
488
+ result = result.replace(/export\s+function\s+/g, 'function ');
489
+ result = result.replace(/export\s+class\s+/g, 'class ');
490
+ result = result.replace(/export\s+\{([^}]+)\}\s*;?\s*/g, '');
491
+
492
+ // Restore strings
493
+ return restoreStrings(result, strings);
454
494
  }
455
495
 
456
496
  /**
@@ -464,36 +504,27 @@ function extractSharedModule(juxContent, moduleName) {
464
504
  * @returns {string} View function code
465
505
  */
466
506
  function transformJuxToViewFunction(juxContent, functionName, pageName, relativePath, sharedModules) {
467
- // Remove string literals temporarily to avoid false matches
468
- const strings = [];
469
-
470
- // Handle template literals, single quotes, and double quotes separately
471
- let code = juxContent
472
- .replace(/`(?:\\.|[^`\\])*`/g, (match) => { strings.push(match); return `__STRING_${strings.length - 1}__`; })
473
- .replace(/"(?:\\.|[^"\\])*"/g, (match) => { strings.push(match); return `__STRING_${strings.length - 1}__`; })
474
- .replace(/'(?:\\.|[^'\\])*'/g, (match) => { strings.push(match); return `__STRING_${strings.length - 1}__`; });
475
-
476
- // Remove ALL imports - now matching against placeholders
477
- code = code.replace(/import\s+\{[^}]+\}\s+from\s+__STRING_\d+__;?\s*/g, '');
478
- code = code.replace(/import\s+\*\s+as\s+\w+\s+from\s+__STRING_\d+__;?\s*/g, '');
479
- code = code.replace(/import\s+__STRING_\d+__;?\s*/g, '');
507
+ const { code, strings } = extractStrings(juxContent);
480
508
 
481
- // Handle exports - convert named exports to const declarations
482
- code = code.replace(/export\s+const\s+(\w+)\s*=/g, 'const $1 =');
483
- code = code.replace(/export\s+let\s+(\w+)\s*=/g, 'let $1 =');
484
- code = code.replace(/export\s+function\s+(\w+)/g, 'const $1 = function');
485
- code = code.replace(/export\s+class\s+/g, 'class ');
486
- code = code.replace(/export\s+default\s+/g, '');
487
- code = code.replace(/export\s+\{([^}]+)\}\s*;?\s*/g, '');
509
+ // Remove ALL imports
510
+ let result = code.replace(/import\s+\{[^}]+\}\s+from\s+__STRING_\d+__;?\s*/g, '');
511
+ result = result.replace(/import\s+\*\s+as\s+\w+\s+from\s+__STRING_\d+__;?\s*/g, '');
512
+ result = result.replace(/import\s+__STRING_\d+__;?\s*/g, '');
488
513
 
489
- // Only replace .renderTo(container) calls - leave explicit render targets alone
490
- code = code.replace(/\.renderTo\(container\)/g, '.render("#app")');
514
+ // Handle exports
515
+ result = result.replace(/export\s+const\s+(\w+)\s*=/g, 'const $1 =');
516
+ result = result.replace(/export\s+let\s+(\w+)\s*=/g, 'let $1 =');
517
+ result = result.replace(/export\s+function\s+(\w+)/g, 'const $1 = function');
518
+ result = result.replace(/export\s+class\s+/g, 'class ');
519
+ result = result.replace(/export\s+default\s+/g, '');
520
+ result = result.replace(/export\s+\{([^}]+)\}\s*;?\s*/g, '');
491
521
 
492
- // Only replace empty .render() calls (no arguments)
493
- code = code.replace(/\.render\(\s*\)/g, '.render("#app")');
522
+ // Replace render patterns
523
+ result = result.replace(/\.renderTo\(container\)/g, '.render("#app")');
524
+ result = result.replace(/\.render\(\s*\)/g, '.render("#app")');
494
525
 
495
- // Restore string literals
496
- code = code.replace(/__STRING_(\d+)__/g, (_, index) => strings[index]);
526
+ // Restore strings
527
+ result = restoreStrings(result, strings);
497
528
 
498
529
  const cleanName = functionName
499
530
  .replace(/[-_]/g, ' ')
@@ -504,7 +535,7 @@ function transformJuxToViewFunction(juxContent, functionName, pageName, relative
504
535
  return `
505
536
  // View: ${cleanName}
506
537
  function ${cleanName}() {
507
- ${code}
538
+ ${result}
508
539
 
509
540
  return document.getElementById('app');
510
541
  }`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "juxscript",
3
- "version": "1.0.37",
3
+ "version": "1.0.38",
4
4
  "type": "module",
5
5
  "description": "A JavaScript UX authorship platform",
6
6
  "main": "lib/jux.js",