rip-lang 3.10.6 → 3.10.7
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/README.md +1 -1
- package/docs/RIP-LANG.md +109 -0
- package/docs/dist/rip-ui.min.js +169 -159
- package/docs/dist/rip-ui.min.js.br +0 -0
- package/docs/dist/rip.browser.min.js +170 -160
- package/docs/dist/rip.browser.min.js.br +0 -0
- package/docs/results/images/cover_bg.jpg +0 -0
- package/docs/results/images/crossover.svg +20 -0
- package/docs/results/images/heart.png +0 -0
- package/docs/results/images/human_body.png +0 -0
- package/docs/results/images/pancreas.png +0 -0
- package/docs/results/images/yoga_lady.jpg +0 -0
- package/docs/results/index.html +1117 -0
- package/package.json +1 -1
- package/src/compiler.js +10 -0
- package/src/components.js +151 -53
package/package.json
CHANGED
package/src/compiler.js
CHANGED
|
@@ -2980,6 +2980,16 @@ function __state(initialValue) {
|
|
|
2980
2980
|
},
|
|
2981
2981
|
|
|
2982
2982
|
read() { return value; },
|
|
2983
|
+
touch() {
|
|
2984
|
+
if (dead || notifying) return;
|
|
2985
|
+
notifying = true;
|
|
2986
|
+
for (const sub of subscribers) {
|
|
2987
|
+
if (sub.markDirty) sub.markDirty();
|
|
2988
|
+
else __pendingEffects.add(sub);
|
|
2989
|
+
}
|
|
2990
|
+
if (!__batching) __flushEffects();
|
|
2991
|
+
notifying = false;
|
|
2992
|
+
},
|
|
2983
2993
|
lock() { locked = true; return state; },
|
|
2984
2994
|
free() { subscribers.clear(); return state; },
|
|
2985
2995
|
kill() { dead = true; subscribers.clear(); return value; },
|
package/src/components.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
//
|
|
8
8
|
// Naming: All render-tree generators use generate* (consistent with compiler).
|
|
9
9
|
|
|
10
|
-
import { TEMPLATE_TAGS } from './tags.js';
|
|
10
|
+
import { TEMPLATE_TAGS, SVG_TAGS } from './tags.js';
|
|
11
11
|
|
|
12
12
|
// ============================================================================
|
|
13
13
|
// Constants
|
|
@@ -24,6 +24,8 @@ const BOOLEAN_ATTRS = new Set([
|
|
|
24
24
|
'allowfullscreen', 'inert',
|
|
25
25
|
]);
|
|
26
26
|
|
|
27
|
+
const SVG_NS = 'http://www.w3.org/2000/svg';
|
|
28
|
+
|
|
27
29
|
// ============================================================================
|
|
28
30
|
// Standalone Utilities
|
|
29
31
|
// ============================================================================
|
|
@@ -792,6 +794,7 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
792
794
|
this._createLines = [];
|
|
793
795
|
this._setupLines = [];
|
|
794
796
|
this._blockFactories = [];
|
|
797
|
+
this._loopVarStack = [];
|
|
795
798
|
|
|
796
799
|
const statements = this.is(body, 'block') ? body.slice(1) : [body];
|
|
797
800
|
|
|
@@ -855,7 +858,12 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
855
858
|
// Static tag without content (possibly with #id)
|
|
856
859
|
const [tagStr, idStr] = str.split('#');
|
|
857
860
|
const elVar = this.newElementVar();
|
|
858
|
-
|
|
861
|
+
const actualTag = tagStr || 'div';
|
|
862
|
+
if (SVG_TAGS.has(actualTag) || this._svgDepth > 0) {
|
|
863
|
+
this._createLines.push(`${elVar} = document.createElementNS('${SVG_NS}', '${actualTag}');`);
|
|
864
|
+
} else {
|
|
865
|
+
this._createLines.push(`${elVar} = document.createElement('${actualTag}');`);
|
|
866
|
+
}
|
|
859
867
|
if (idStr) this._createLines.push(`${elVar}.id = '${idStr}';`);
|
|
860
868
|
return elVar;
|
|
861
869
|
}
|
|
@@ -1011,16 +1019,27 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1011
1019
|
|
|
1012
1020
|
proto.generateTag = function(tag, classes, args, id) {
|
|
1013
1021
|
const elVar = this.newElementVar();
|
|
1014
|
-
|
|
1022
|
+
const isSvg = SVG_TAGS.has(tag) || this._svgDepth > 0;
|
|
1023
|
+
if (isSvg) {
|
|
1024
|
+
this._createLines.push(`${elVar} = document.createElementNS('${SVG_NS}', '${tag}');`);
|
|
1025
|
+
} else {
|
|
1026
|
+
this._createLines.push(`${elVar} = document.createElement('${tag}');`);
|
|
1027
|
+
}
|
|
1015
1028
|
|
|
1016
1029
|
if (id) {
|
|
1017
1030
|
this._createLines.push(`${elVar}.id = '${id}';`);
|
|
1018
1031
|
}
|
|
1019
1032
|
if (classes.length > 0) {
|
|
1020
|
-
|
|
1033
|
+
if (isSvg) {
|
|
1034
|
+
this._createLines.push(`${elVar}.setAttribute('class', '${classes.join(' ')}');`);
|
|
1035
|
+
} else {
|
|
1036
|
+
this._createLines.push(`${elVar}.className = '${classes.join(' ')}';`);
|
|
1037
|
+
}
|
|
1021
1038
|
}
|
|
1022
1039
|
|
|
1040
|
+
if (tag === 'svg') this._svgDepth = (this._svgDepth || 0) + 1;
|
|
1023
1041
|
this.appendChildren(elVar, args);
|
|
1042
|
+
if (tag === 'svg') this._svgDepth--;
|
|
1024
1043
|
return elVar;
|
|
1025
1044
|
};
|
|
1026
1045
|
|
|
@@ -1030,7 +1049,11 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1030
1049
|
|
|
1031
1050
|
proto.generateDynamicTag = function(tag, classExprs, children) {
|
|
1032
1051
|
const elVar = this.newElementVar();
|
|
1033
|
-
|
|
1052
|
+
if (SVG_TAGS.has(tag) || this._svgDepth > 0) {
|
|
1053
|
+
this._createLines.push(`${elVar} = document.createElementNS('${SVG_NS}', '${tag}');`);
|
|
1054
|
+
} else {
|
|
1055
|
+
this._createLines.push(`${elVar} = document.createElement('${tag}');`);
|
|
1056
|
+
}
|
|
1034
1057
|
|
|
1035
1058
|
// Defer className emission so class: attributes can merge with .() classes
|
|
1036
1059
|
const classArgs = classExprs.map(e => this.generateInComponent(e, 'value'));
|
|
@@ -1039,11 +1062,18 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1039
1062
|
this._pendingClassArgs = classArgs;
|
|
1040
1063
|
this._pendingClassEl = elVar;
|
|
1041
1064
|
|
|
1065
|
+
if (tag === 'svg') this._svgDepth = (this._svgDepth || 0) + 1;
|
|
1042
1066
|
this.appendChildren(elVar, children);
|
|
1067
|
+
if (tag === 'svg') this._svgDepth--;
|
|
1043
1068
|
|
|
1044
1069
|
if (this._pendingClassArgs.length > 0) {
|
|
1045
1070
|
const combined = this._pendingClassArgs.join(', ');
|
|
1046
|
-
|
|
1071
|
+
const isSvg = SVG_TAGS.has(tag) || this._svgDepth > 0;
|
|
1072
|
+
if (isSvg) {
|
|
1073
|
+
this._setupLines.push(`__effect(() => { ${elVar}.setAttribute('class', __clsx(${combined})); });`);
|
|
1074
|
+
} else {
|
|
1075
|
+
this._setupLines.push(`__effect(() => { ${elVar}.className = __clsx(${combined}); });`);
|
|
1076
|
+
}
|
|
1047
1077
|
}
|
|
1048
1078
|
this._pendingClassArgs = prevClassArgs;
|
|
1049
1079
|
this._pendingClassEl = prevClassEl;
|
|
@@ -1087,9 +1117,17 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1087
1117
|
if (this._pendingClassArgs && this._pendingClassEl === elVar) {
|
|
1088
1118
|
this._pendingClassArgs.push(valueCode);
|
|
1089
1119
|
} else if (this.hasReactiveDeps(value)) {
|
|
1090
|
-
this.
|
|
1120
|
+
if (this._svgDepth > 0) {
|
|
1121
|
+
this._setupLines.push(`__effect(() => { ${elVar}.setAttribute('class', __clsx(${valueCode})); });`);
|
|
1122
|
+
} else {
|
|
1123
|
+
this._setupLines.push(`__effect(() => { ${elVar}.className = __clsx(${valueCode}); });`);
|
|
1124
|
+
}
|
|
1091
1125
|
} else {
|
|
1092
|
-
this.
|
|
1126
|
+
if (this._svgDepth > 0) {
|
|
1127
|
+
this._createLines.push(`${elVar}.setAttribute('class', ${valueCode});`);
|
|
1128
|
+
} else {
|
|
1129
|
+
this._createLines.push(`${elVar}.className = ${valueCode};`);
|
|
1130
|
+
}
|
|
1093
1131
|
}
|
|
1094
1132
|
continue;
|
|
1095
1133
|
}
|
|
@@ -1117,7 +1155,12 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1117
1155
|
}
|
|
1118
1156
|
|
|
1119
1157
|
this._setupLines.push(`__effect(() => { ${elVar}.${prop} = ${valueCode}; });`);
|
|
1120
|
-
|
|
1158
|
+
let assignCode = `${valueCode} = ${valueAccessor}`;
|
|
1159
|
+
const rootMember = !this.isSimpleAssignable(value) && this.findRootReactiveMember(value);
|
|
1160
|
+
if (rootMember) {
|
|
1161
|
+
assignCode += `; this.${rootMember}.touch?.()`;
|
|
1162
|
+
}
|
|
1163
|
+
this._createLines.push(`${elVar}.addEventListener('${event}', (e) => { ${assignCode}; });`);
|
|
1121
1164
|
continue;
|
|
1122
1165
|
}
|
|
1123
1166
|
|
|
@@ -1126,15 +1169,19 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1126
1169
|
// Smart two-way binding for value/checked when bound to reactive state
|
|
1127
1170
|
if ((key === 'value' || key === 'checked') && this.hasReactiveDeps(value)) {
|
|
1128
1171
|
this._setupLines.push(`__effect(() => { ${elVar}.${key} = ${valueCode}; });`);
|
|
1129
|
-
//
|
|
1130
|
-
//
|
|
1131
|
-
|
|
1132
|
-
if (this.isSimpleAssignable(value)) {
|
|
1172
|
+
// Generate reverse binding for simple assignable targets or nested
|
|
1173
|
+
// reactive paths (with touch() for Svelte-style invalidation)
|
|
1174
|
+
const rootMemberImplicit = !this.isSimpleAssignable(value) && this.findRootReactiveMember(value);
|
|
1175
|
+
if (this.isSimpleAssignable(value) || rootMemberImplicit) {
|
|
1133
1176
|
const event = key === 'checked' ? 'change' : 'input';
|
|
1134
1177
|
const accessor = key === 'checked' ? 'e.target.checked'
|
|
1135
1178
|
: (inputType === 'number' || inputType === 'range') ? 'e.target.valueAsNumber'
|
|
1136
1179
|
: 'e.target.value';
|
|
1137
|
-
|
|
1180
|
+
let assignCode = `${valueCode} = ${accessor}`;
|
|
1181
|
+
if (rootMemberImplicit) {
|
|
1182
|
+
assignCode += `; this.${rootMemberImplicit}.touch?.()`;
|
|
1183
|
+
}
|
|
1184
|
+
this._createLines.push(`${elVar}.addEventListener('${event}', (e) => { ${assignCode}; });`);
|
|
1138
1185
|
}
|
|
1139
1186
|
continue;
|
|
1140
1187
|
}
|
|
@@ -1194,6 +1241,10 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1194
1241
|
|
|
1195
1242
|
const condCode = this.generateInComponent(condition, 'value');
|
|
1196
1243
|
|
|
1244
|
+
// Collect loop variables from enclosing for-loops
|
|
1245
|
+
const loopParams = this._loopVarStack.map(v => `${v.itemVar}, ${v.indexVar}`).join(', ');
|
|
1246
|
+
const extraArgs = loopParams ? `, ${loopParams}` : '';
|
|
1247
|
+
|
|
1197
1248
|
const thenBlockName = this.newBlockVar();
|
|
1198
1249
|
this.generateConditionBranch(thenBlockName, thenBlock);
|
|
1199
1250
|
|
|
@@ -1221,17 +1272,17 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1221
1272
|
setupLines.push(` showing = want;`);
|
|
1222
1273
|
setupLines.push(``);
|
|
1223
1274
|
setupLines.push(` if (want === 'then') {`);
|
|
1224
|
-
setupLines.push(` currentBlock = ${thenBlockName}(this);`);
|
|
1275
|
+
setupLines.push(` currentBlock = ${thenBlockName}(this${extraArgs});`);
|
|
1225
1276
|
setupLines.push(` currentBlock.c();`);
|
|
1226
1277
|
setupLines.push(` currentBlock.m(anchor.parentNode, anchor.nextSibling);`);
|
|
1227
|
-
setupLines.push(` currentBlock.p(this);`);
|
|
1278
|
+
setupLines.push(` currentBlock.p(this${extraArgs});`);
|
|
1228
1279
|
setupLines.push(` }`);
|
|
1229
1280
|
if (elseBlock) {
|
|
1230
1281
|
setupLines.push(` if (want === 'else') {`);
|
|
1231
|
-
setupLines.push(` currentBlock = ${elseBlockName}(this);`);
|
|
1282
|
+
setupLines.push(` currentBlock = ${elseBlockName}(this${extraArgs});`);
|
|
1232
1283
|
setupLines.push(` currentBlock.c();`);
|
|
1233
1284
|
setupLines.push(` currentBlock.m(anchor.parentNode, anchor.nextSibling);`);
|
|
1234
|
-
setupLines.push(` currentBlock.p(this);`);
|
|
1285
|
+
setupLines.push(` currentBlock.p(this${extraArgs});`);
|
|
1235
1286
|
setupLines.push(` }`);
|
|
1236
1287
|
}
|
|
1237
1288
|
setupLines.push(` });`);
|
|
@@ -1262,8 +1313,12 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1262
1313
|
|
|
1263
1314
|
const localizeVar = (line) => this.localizeVar(line);
|
|
1264
1315
|
|
|
1316
|
+
// Include enclosing loop variables in the factory signature
|
|
1317
|
+
const loopParams = this._loopVarStack.map(v => `${v.itemVar}, ${v.indexVar}`).join(', ');
|
|
1318
|
+
const extraParams = loopParams ? `, ${loopParams}` : '';
|
|
1319
|
+
|
|
1265
1320
|
const factoryLines = [];
|
|
1266
|
-
factoryLines.push(`function ${blockName}(ctx) {`);
|
|
1321
|
+
factoryLines.push(`function ${blockName}(ctx${extraParams}) {`);
|
|
1267
1322
|
|
|
1268
1323
|
// Declare local variables
|
|
1269
1324
|
const localVars = new Set();
|
|
@@ -1295,7 +1350,7 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1295
1350
|
factoryLines.push(` },`);
|
|
1296
1351
|
|
|
1297
1352
|
// p() - update/patch
|
|
1298
|
-
factoryLines.push(` p(ctx) {`);
|
|
1353
|
+
factoryLines.push(` p(ctx${extraParams}) {`);
|
|
1299
1354
|
if (hasEffects) {
|
|
1300
1355
|
factoryLines.push(` disposers.forEach(d => d());`);
|
|
1301
1356
|
factoryLines.push(` disposers = [];`);
|
|
@@ -1379,7 +1434,9 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1379
1434
|
this._createLines = [];
|
|
1380
1435
|
this._setupLines = [];
|
|
1381
1436
|
|
|
1437
|
+
this._loopVarStack.push({ itemVar, indexVar });
|
|
1382
1438
|
const itemNode = this.generateTemplateBlock(body);
|
|
1439
|
+
this._loopVarStack.pop();
|
|
1383
1440
|
const itemCreateLines = this._createLines;
|
|
1384
1441
|
const itemSetupLines = this._setupLines;
|
|
1385
1442
|
|
|
@@ -1469,32 +1526,32 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1469
1526
|
const setupLines = [];
|
|
1470
1527
|
setupLines.push(`// Loop: ${blockName}`);
|
|
1471
1528
|
setupLines.push(`{`);
|
|
1472
|
-
setupLines.push(` const
|
|
1473
|
-
setupLines.push(` const
|
|
1529
|
+
setupLines.push(` const __anchor = ${anchorVar};`);
|
|
1530
|
+
setupLines.push(` const __map = new Map();`);
|
|
1474
1531
|
setupLines.push(` __effect(() => {`);
|
|
1475
|
-
setupLines.push(` const
|
|
1476
|
-
setupLines.push(` const
|
|
1477
|
-
setupLines.push(` const
|
|
1532
|
+
setupLines.push(` const __items = ${collectionCode};`);
|
|
1533
|
+
setupLines.push(` const __parent = __anchor.parentNode;`);
|
|
1534
|
+
setupLines.push(` const __newMap = new Map();`);
|
|
1478
1535
|
setupLines.push(``);
|
|
1479
|
-
setupLines.push(` for (let ${indexVar} = 0; ${indexVar} <
|
|
1480
|
-
setupLines.push(` const ${itemVar} =
|
|
1481
|
-
setupLines.push(` const
|
|
1482
|
-
setupLines.push(` let
|
|
1483
|
-
setupLines.push(` if (!
|
|
1484
|
-
setupLines.push(`
|
|
1485
|
-
setupLines.push(`
|
|
1536
|
+
setupLines.push(` for (let ${indexVar} = 0; ${indexVar} < __items.length; ${indexVar}++) {`);
|
|
1537
|
+
setupLines.push(` const ${itemVar} = __items[${indexVar}];`);
|
|
1538
|
+
setupLines.push(` const __key = ${keyExpr};`);
|
|
1539
|
+
setupLines.push(` let __block = __map.get(__key);`);
|
|
1540
|
+
setupLines.push(` if (!__block) {`);
|
|
1541
|
+
setupLines.push(` __block = ${blockName}(this, ${itemVar}, ${indexVar});`);
|
|
1542
|
+
setupLines.push(` __block.c();`);
|
|
1486
1543
|
setupLines.push(` }`);
|
|
1487
|
-
setupLines.push(`
|
|
1488
|
-
setupLines.push(`
|
|
1489
|
-
setupLines.push(`
|
|
1544
|
+
setupLines.push(` __block.m(__parent, __anchor);`);
|
|
1545
|
+
setupLines.push(` __block.p(this, ${itemVar}, ${indexVar});`);
|
|
1546
|
+
setupLines.push(` __newMap.set(__key, __block);`);
|
|
1490
1547
|
setupLines.push(` }`);
|
|
1491
1548
|
setupLines.push(``);
|
|
1492
|
-
setupLines.push(` for (const [
|
|
1493
|
-
setupLines.push(` if (!
|
|
1549
|
+
setupLines.push(` for (const [__k, __b] of __map) {`);
|
|
1550
|
+
setupLines.push(` if (!__newMap.has(__k)) __b.d(true);`);
|
|
1494
1551
|
setupLines.push(` }`);
|
|
1495
1552
|
setupLines.push(``);
|
|
1496
|
-
setupLines.push(`
|
|
1497
|
-
setupLines.push(` for (const [
|
|
1553
|
+
setupLines.push(` __map.clear();`);
|
|
1554
|
+
setupLines.push(` for (const [__k, __v] of __newMap) __map.set(__k, __v);`);
|
|
1498
1555
|
setupLines.push(` });`);
|
|
1499
1556
|
setupLines.push(`}`);
|
|
1500
1557
|
|
|
@@ -1510,7 +1567,7 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1510
1567
|
proto.generateChildComponent = function(componentName, args) {
|
|
1511
1568
|
const instVar = this.newElementVar('inst');
|
|
1512
1569
|
const elVar = this.newElementVar('el');
|
|
1513
|
-
const { propsCode, childrenSetupLines } = this.buildComponentProps(args);
|
|
1570
|
+
const { propsCode, reactiveProps, childrenSetupLines } = this.buildComponentProps(args);
|
|
1514
1571
|
|
|
1515
1572
|
this._createLines.push(`${instVar} = new ${componentName}(${propsCode});`);
|
|
1516
1573
|
this._createLines.push(`${elVar} = ${instVar}._create();`);
|
|
@@ -1518,6 +1575,10 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1518
1575
|
|
|
1519
1576
|
this._setupLines.push(`if (${instVar}._setup) ${instVar}._setup();`);
|
|
1520
1577
|
|
|
1578
|
+
for (const { key, valueCode } of reactiveProps) {
|
|
1579
|
+
this._setupLines.push(`__effect(() => { if (${instVar}.${key}) ${instVar}.${key}.value = ${valueCode}; });`);
|
|
1580
|
+
}
|
|
1581
|
+
|
|
1521
1582
|
for (const line of childrenSetupLines) {
|
|
1522
1583
|
this._setupLines.push(line);
|
|
1523
1584
|
}
|
|
@@ -1531,6 +1592,7 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1531
1592
|
|
|
1532
1593
|
proto.buildComponentProps = function(args) {
|
|
1533
1594
|
const props = [];
|
|
1595
|
+
const reactiveProps = [];
|
|
1534
1596
|
let childrenVar = null;
|
|
1535
1597
|
const childrenSetupLines = [];
|
|
1536
1598
|
|
|
@@ -1539,13 +1601,22 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1539
1601
|
for (let i = 1; i < arg.length; i++) {
|
|
1540
1602
|
const [key, value] = arg[i];
|
|
1541
1603
|
if (typeof key === 'string') {
|
|
1542
|
-
//
|
|
1543
|
-
//
|
|
1544
|
-
const
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1604
|
+
// Simple reactive identifier — pass signal directly for shared reactivity.
|
|
1605
|
+
// Complex expressions — use normal .value unwrapping to compute the value.
|
|
1606
|
+
const isSimpleReactive = this.reactiveMembers && (
|
|
1607
|
+
(typeof value === 'string' && this.reactiveMembers.has(value)) ||
|
|
1608
|
+
(Array.isArray(value) && value[0] === '.' && value[1] === 'this' && typeof value[2] === 'string' && this.reactiveMembers.has(value[2]))
|
|
1609
|
+
);
|
|
1610
|
+
if (isSimpleReactive) {
|
|
1611
|
+
const member = typeof value === 'string' ? value : value[2];
|
|
1612
|
+
props.push(`${key}: this.${member}`);
|
|
1613
|
+
} else {
|
|
1614
|
+
const valueCode = this.generateInComponent(value, 'value');
|
|
1615
|
+
props.push(`${key}: ${valueCode}`);
|
|
1616
|
+
if (this.hasReactiveDeps(value)) {
|
|
1617
|
+
reactiveProps.push({ key, valueCode });
|
|
1618
|
+
}
|
|
1619
|
+
}
|
|
1549
1620
|
}
|
|
1550
1621
|
}
|
|
1551
1622
|
} else if (Array.isArray(arg) && (arg[0] === '->' || arg[0] === '=>')) {
|
|
@@ -1559,11 +1630,20 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1559
1630
|
for (let i = 1; i < child.length; i++) {
|
|
1560
1631
|
const [key, value] = child[i];
|
|
1561
1632
|
if (typeof key === 'string') {
|
|
1562
|
-
const
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1633
|
+
const isSimpleReactive = this.reactiveMembers && (
|
|
1634
|
+
(typeof value === 'string' && this.reactiveMembers.has(value)) ||
|
|
1635
|
+
(Array.isArray(value) && value[0] === '.' && value[1] === 'this' && typeof value[2] === 'string' && this.reactiveMembers.has(value[2]))
|
|
1636
|
+
);
|
|
1637
|
+
if (isSimpleReactive) {
|
|
1638
|
+
const member = typeof value === 'string' ? value : value[2];
|
|
1639
|
+
props.push(`${key}: this.${member}`);
|
|
1640
|
+
} else {
|
|
1641
|
+
const valueCode = this.generateInComponent(value, 'value');
|
|
1642
|
+
props.push(`${key}: ${valueCode}`);
|
|
1643
|
+
if (this.hasReactiveDeps(value)) {
|
|
1644
|
+
reactiveProps.push({ key, valueCode });
|
|
1645
|
+
}
|
|
1646
|
+
}
|
|
1567
1647
|
}
|
|
1568
1648
|
}
|
|
1569
1649
|
} else {
|
|
@@ -1598,7 +1678,7 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1598
1678
|
}
|
|
1599
1679
|
|
|
1600
1680
|
const propsCode = props.length > 0 ? `{ ${props.join(', ')} }` : '{}';
|
|
1601
|
-
return { propsCode, childrenSetupLines };
|
|
1681
|
+
return { propsCode, reactiveProps, childrenSetupLines };
|
|
1602
1682
|
};
|
|
1603
1683
|
|
|
1604
1684
|
// --------------------------------------------------------------------------
|
|
@@ -1646,6 +1726,24 @@ export function installComponentSupport(CodeGenerator, Lexer) {
|
|
|
1646
1726
|
return false;
|
|
1647
1727
|
};
|
|
1648
1728
|
|
|
1729
|
+
// findRootReactiveMember — walk a nested access chain to find the root reactive member
|
|
1730
|
+
// e.g. (. ([] history 0) triglycerides) → 'history'
|
|
1731
|
+
// --------------------------------------------------------------------------
|
|
1732
|
+
|
|
1733
|
+
proto.findRootReactiveMember = function(sexpr) {
|
|
1734
|
+
if (typeof sexpr === 'string') {
|
|
1735
|
+
return this.reactiveMembers?.has(sexpr) ? sexpr : null;
|
|
1736
|
+
}
|
|
1737
|
+
if (!Array.isArray(sexpr)) return null;
|
|
1738
|
+
if (sexpr[0] === '.' && sexpr[1] === 'this' && typeof sexpr[2] === 'string') {
|
|
1739
|
+
return this.reactiveMembers?.has(sexpr[2]) ? sexpr[2] : null;
|
|
1740
|
+
}
|
|
1741
|
+
if (sexpr[0] === '.' || sexpr[0] === '[]') {
|
|
1742
|
+
return this.findRootReactiveMember(sexpr[1]);
|
|
1743
|
+
}
|
|
1744
|
+
return null;
|
|
1745
|
+
};
|
|
1746
|
+
|
|
1649
1747
|
// _rootsAtThis — check if a property-access chain is rooted at 'this'
|
|
1650
1748
|
// --------------------------------------------------------------------------
|
|
1651
1749
|
|