juxscript 1.0.36 → 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.
|
@@ -4,6 +4,20 @@ import { BaseComponent } from './base/BaseComponent.js';
|
|
|
4
4
|
const TRIGGER_EVENTS = [] as const;
|
|
5
5
|
const CALLBACK_EVENTS = [] as const;
|
|
6
6
|
|
|
7
|
+
// Deprecation warning constant
|
|
8
|
+
const DEPRECATION_WARNING = (feature: string) =>
|
|
9
|
+
`[JUX Deprecation Warning] Container.${feature} will be removed in v1.0.30+ (January 30, 2026). Please use CSS or the .style() method instead. See: https://juxscript.com/docs/migration`;
|
|
10
|
+
|
|
11
|
+
// Track which warnings we've already shown (to avoid spam)
|
|
12
|
+
const _shownWarnings = new Set<string>();
|
|
13
|
+
|
|
14
|
+
function warnOnce(feature: string): void {
|
|
15
|
+
if (!_shownWarnings.has(feature)) {
|
|
16
|
+
console.warn(DEPRECATION_WARNING(feature));
|
|
17
|
+
_shownWarnings.add(feature);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
7
21
|
export interface ContainerOptions {
|
|
8
22
|
direction?: 'row' | 'column'; // should deprecate.
|
|
9
23
|
gap?: number | string; // should deprecate.
|
|
@@ -28,6 +42,14 @@ type ContainerState = {
|
|
|
28
42
|
|
|
29
43
|
export class Container extends BaseComponent<ContainerState> {
|
|
30
44
|
constructor(id: string, options: ContainerOptions = {}) {
|
|
45
|
+
// Warn for deprecated options
|
|
46
|
+
if (options.direction !== undefined) warnOnce('direction (option)');
|
|
47
|
+
if (options.gap !== undefined) warnOnce('gap (option)');
|
|
48
|
+
if (options.wrap !== undefined) warnOnce('wrap (option)');
|
|
49
|
+
if (options.align !== undefined) warnOnce('align (option)');
|
|
50
|
+
if (options.justify !== undefined) warnOnce('justify (option)');
|
|
51
|
+
if (options.padding !== undefined) warnOnce('padding (option)');
|
|
52
|
+
|
|
31
53
|
super(id, {
|
|
32
54
|
direction: options.direction ?? 'column',// should deprecate.
|
|
33
55
|
gap: options.gap ?? 0, //should deprecate.
|
|
@@ -61,31 +83,37 @@ export class Container extends BaseComponent<ContainerState> {
|
|
|
61
83
|
// - bind(), sync(), renderTo()
|
|
62
84
|
|
|
63
85
|
direction(value: 'row' | 'column'): this {
|
|
86
|
+
warnOnce('direction()');
|
|
64
87
|
this.state.direction = value;
|
|
65
88
|
return this;
|
|
66
89
|
}
|
|
67
90
|
|
|
68
91
|
gap(value: number | string): this {
|
|
92
|
+
warnOnce('gap()');
|
|
69
93
|
this.state.gap = value;
|
|
70
94
|
return this;
|
|
71
95
|
}
|
|
72
96
|
|
|
73
97
|
wrap(value: boolean): this {
|
|
98
|
+
warnOnce('wrap()');
|
|
74
99
|
this.state.wrap = value;
|
|
75
100
|
return this;
|
|
76
101
|
}
|
|
77
102
|
|
|
78
103
|
align(value: 'start' | 'center' | 'end' | 'stretch'): this {
|
|
104
|
+
warnOnce('align()');
|
|
79
105
|
this.state.align = value;
|
|
80
106
|
return this;
|
|
81
107
|
}
|
|
82
108
|
|
|
83
109
|
justify(value: 'start' | 'center' | 'end' | 'space-between' | 'space-around' | 'space-evenly'): this {
|
|
110
|
+
warnOnce('justify()');
|
|
84
111
|
this.state.justify = value;
|
|
85
112
|
return this;
|
|
86
113
|
}
|
|
87
114
|
|
|
88
115
|
padding(value: string): this {
|
|
116
|
+
warnOnce('padding()');
|
|
89
117
|
this.state.padding = value;
|
|
90
118
|
return this;
|
|
91
119
|
}
|
|
@@ -112,28 +140,34 @@ export class Container extends BaseComponent<ContainerState> {
|
|
|
112
140
|
|
|
113
141
|
stateObj.subscribe((val: any) => {
|
|
114
142
|
const transformed = transform(val);
|
|
115
|
-
|
|
143
|
+
|
|
116
144
|
if (property === 'direction') {
|
|
145
|
+
warnOnce('direction (sync)');
|
|
117
146
|
this.state.direction = String(transformed);
|
|
118
147
|
wrapper.style.flexDirection = this.state.direction;
|
|
119
148
|
} else if (property === 'gap') {
|
|
149
|
+
warnOnce('gap (sync)');
|
|
120
150
|
this.state.gap = transformed;
|
|
121
151
|
const gapVal = typeof transformed === 'number' ? `${transformed}px` : transformed;
|
|
122
152
|
wrapper.style.gap = gapVal;
|
|
123
153
|
} else if (property === 'wrap') {
|
|
154
|
+
warnOnce('wrap (sync)');
|
|
124
155
|
this.state.wrap = Boolean(transformed);
|
|
125
156
|
wrapper.style.flexWrap = this.state.wrap ? 'wrap' : 'nowrap';
|
|
126
157
|
} else if (property === 'align') {
|
|
158
|
+
warnOnce('align (sync)');
|
|
127
159
|
this.state.align = String(transformed);
|
|
128
160
|
wrapper.style.alignItems = this.state.align;
|
|
129
161
|
} else if (property === 'justify') {
|
|
162
|
+
warnOnce('justify (sync)');
|
|
130
163
|
this.state.justify = String(transformed);
|
|
131
164
|
wrapper.style.justifyContent = this.state.justify;
|
|
132
165
|
} else if (property === 'padding') {
|
|
166
|
+
warnOnce('padding (sync)');
|
|
133
167
|
this.state.padding = String(transformed);
|
|
134
168
|
wrapper.style.padding = this.state.padding;
|
|
135
169
|
}
|
|
136
|
-
|
|
170
|
+
|
|
137
171
|
});
|
|
138
172
|
|
|
139
173
|
});
|
|
@@ -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-
|
|
2056
|
+
"lastUpdated": "2026-01-28T17:24:41.869Z"
|
|
2063
2057
|
}
|
package/machinery/compiler.js
CHANGED
|
@@ -419,38 +419,78 @@ export async function bundleJuxFilesToRouter(projectRoot, distDir, options = {})
|
|
|
419
419
|
}
|
|
420
420
|
|
|
421
421
|
/**
|
|
422
|
-
* Extract
|
|
423
|
-
*
|
|
424
|
-
*
|
|
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
|
|
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
|
-
//
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
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
|
-
//
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
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
|
-
|
|
444
|
-
|
|
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
|
-
|
|
451
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
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
|
-
//
|
|
490
|
-
|
|
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
|
-
//
|
|
493
|
-
|
|
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
|
|
496
|
-
|
|
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
|
-
${
|
|
538
|
+
${result}
|
|
508
539
|
|
|
509
540
|
return document.getElementById('app');
|
|
510
541
|
}`;
|