@farm.js/react 0.1.0-beta.3 → 0.1.0-beta.4
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 +120 -37
- package/dist/compiler-runtime.cjs +1925 -156
- package/dist/compiler-runtime.cjs.map +1 -1
- package/dist/compiler-runtime.d.mts +76 -1
- package/dist/compiler-runtime.d.ts +76 -1
- package/dist/compiler-runtime.mjs +1925 -156
- package/dist/compiler-runtime.mjs.map +1 -1
- package/dist/index.cjs +5 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.mjs +5 -1
- package/dist/index.mjs.map +1 -1
- package/dist/list.cjs +18 -1
- package/dist/list.cjs.map +1 -1
- package/dist/list.mjs +18 -1
- package/dist/list.mjs.map +1 -1
- package/dist/vite.cjs +1168 -85
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.mjs +1168 -85
- package/dist/vite.mjs.map +1 -1
- package/package.json +4 -3
package/dist/vite.cjs
CHANGED
|
@@ -6,6 +6,62 @@ var promises = require('fs/promises');
|
|
|
6
6
|
var path = require('path');
|
|
7
7
|
|
|
8
8
|
// src/vite.ts
|
|
9
|
+
var DELEGATABLE_KEYED_ROW_EVENTS = /* @__PURE__ */ new Set([
|
|
10
|
+
"onBeforeInput",
|
|
11
|
+
"onBlur",
|
|
12
|
+
"onChange",
|
|
13
|
+
"onClick",
|
|
14
|
+
"onCompositionEnd",
|
|
15
|
+
"onCompositionStart",
|
|
16
|
+
"onCompositionUpdate",
|
|
17
|
+
"onContextMenu",
|
|
18
|
+
"onCopy",
|
|
19
|
+
"onCut",
|
|
20
|
+
"onDoubleClick",
|
|
21
|
+
"onDrag",
|
|
22
|
+
"onDragEnd",
|
|
23
|
+
"onDragEnter",
|
|
24
|
+
"onDragExit",
|
|
25
|
+
"onDragLeave",
|
|
26
|
+
"onDragOver",
|
|
27
|
+
"onDragStart",
|
|
28
|
+
"onDrop",
|
|
29
|
+
"onFocus",
|
|
30
|
+
"onInput",
|
|
31
|
+
"onKeyDown",
|
|
32
|
+
"onKeyPress",
|
|
33
|
+
"onKeyUp",
|
|
34
|
+
"onMouseDown",
|
|
35
|
+
"onMouseMove",
|
|
36
|
+
"onMouseOut",
|
|
37
|
+
"onMouseOver",
|
|
38
|
+
"onMouseUp",
|
|
39
|
+
"onPaste",
|
|
40
|
+
"onPointerCancel",
|
|
41
|
+
"onPointerDown",
|
|
42
|
+
"onPointerMove",
|
|
43
|
+
"onPointerOut",
|
|
44
|
+
"onPointerOver",
|
|
45
|
+
"onPointerUp",
|
|
46
|
+
"onReset",
|
|
47
|
+
"onSubmit",
|
|
48
|
+
"onTouchCancel",
|
|
49
|
+
"onTouchEnd",
|
|
50
|
+
"onTouchMove",
|
|
51
|
+
"onTouchStart",
|
|
52
|
+
"onWheel"
|
|
53
|
+
]);
|
|
54
|
+
function canDelegateKeyedRowEvents(plan) {
|
|
55
|
+
if (plan.events.length === 0 || plan.conditionals.length > 0) return false;
|
|
56
|
+
if (plan.source.openingElement.attributes.some(
|
|
57
|
+
(attribute) => core.types.isJSXAttribute(attribute) && core.types.isJSXIdentifier(attribute.name) && /^on[A-Z]/.test(attribute.name.name)
|
|
58
|
+
)) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
return plan.events.every(
|
|
62
|
+
(event) => DELEGATABLE_KEYED_ROW_EVENTS.has(event.name.replace(/Capture$/, ""))
|
|
63
|
+
);
|
|
64
|
+
}
|
|
9
65
|
var SAFE_GLOBAL_CALLS = /* @__PURE__ */ new Set(["Boolean", "Number", "String"]);
|
|
10
66
|
var SAFE_MATH_CALLS = /* @__PURE__ */ new Set(["abs", "ceil", "floor", "max", "min", "round", "sign", "trunc"]);
|
|
11
67
|
function isComponentName(name) {
|
|
@@ -90,6 +146,37 @@ function rewriteDestructuredPropAccess(expression, names, propsParameter) {
|
|
|
90
146
|
});
|
|
91
147
|
return file.program.body[0].expression;
|
|
92
148
|
}
|
|
149
|
+
function collectDestructuredPropNames(expression, names, propsParameter) {
|
|
150
|
+
const referenced = /* @__PURE__ */ new Set();
|
|
151
|
+
if (names.size === 0) return referenced;
|
|
152
|
+
core.traverse(expressionFile(cloneExpression(expression)), {
|
|
153
|
+
MemberExpression(path) {
|
|
154
|
+
const { object, property, computed } = path.node;
|
|
155
|
+
if (computed || !core.types.isIdentifier(object, { name: propsParameter.name }) || !core.types.isIdentifier(property) || !names.has(property.name)) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
referenced.add(property.name);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
return referenced;
|
|
162
|
+
}
|
|
163
|
+
function rewriteTrackedPropAccess(expression, propsParameter, bindingsByName) {
|
|
164
|
+
if (bindingsByName.size === 0) return cloneExpression(expression);
|
|
165
|
+
const file = expressionFile(cloneExpression(expression));
|
|
166
|
+
core.traverse(file, {
|
|
167
|
+
MemberExpression(path) {
|
|
168
|
+
const { object, property, computed } = path.node;
|
|
169
|
+
if (computed || !core.types.isIdentifier(object, { name: propsParameter.name }) || !core.types.isIdentifier(property)) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
const binding = bindingsByName.get(property.name);
|
|
173
|
+
if (!binding) return;
|
|
174
|
+
path.replaceWith(core.types.identifier(binding.valueName));
|
|
175
|
+
path.skip();
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
return file.program.body[0].expression;
|
|
179
|
+
}
|
|
93
180
|
function rewriteHandlerAccess(root, handlersByName) {
|
|
94
181
|
if (handlersByName.size === 0) return { root: core.types.cloneNode(root, true) };
|
|
95
182
|
const file = expressionFile(core.types.cloneNode(root, true));
|
|
@@ -769,7 +856,7 @@ function analyzeKeyedRowTree(row, renderCallback, safeGlobals, compilerSetters)
|
|
|
769
856
|
const reason = visit(row, []);
|
|
770
857
|
return reason ? { reason } : { bindings, events, conditionals };
|
|
771
858
|
}
|
|
772
|
-
function analyzeKeyedRowChild(child, statesByValue, safeGlobals, listNames) {
|
|
859
|
+
function analyzeKeyedRowChild(child, statesByValue, safeGlobals, listNames, acceptUnsupportedRow = false) {
|
|
773
860
|
let collection;
|
|
774
861
|
let keyCallback;
|
|
775
862
|
let renderCallback;
|
|
@@ -824,17 +911,29 @@ function analyzeKeyedRowChild(child, statesByValue, safeGlobals, listNames) {
|
|
|
824
911
|
safeGlobals,
|
|
825
912
|
new Set([...statesByValue.values()].map((state) => state.setterName))
|
|
826
913
|
);
|
|
827
|
-
if (rowAnalysis.reason) return void 0;
|
|
914
|
+
if (rowAnalysis.reason && !acceptUnsupportedRow) return void 0;
|
|
915
|
+
const keyExpression = returnedExpression(keyCallback);
|
|
916
|
+
const structureDependencies = new Set(collectStateDependencies(collection, statesByValue));
|
|
917
|
+
if (keyExpression) {
|
|
918
|
+
for (const dependency of collectStateDependencies(keyExpression, statesByValue)) {
|
|
919
|
+
structureDependencies.add(dependency);
|
|
920
|
+
}
|
|
921
|
+
}
|
|
828
922
|
return {
|
|
829
923
|
source,
|
|
830
924
|
collection,
|
|
925
|
+
structureDependencies: [...structureDependencies].sort((left, right) => left - right),
|
|
831
926
|
keyCallback,
|
|
832
927
|
renderCallback,
|
|
833
928
|
row,
|
|
834
929
|
dependencies,
|
|
835
|
-
bindings: rowAnalysis.bindings || []
|
|
930
|
+
bindings: (rowAnalysis.bindings || []).map((binding) => ({
|
|
931
|
+
...binding,
|
|
932
|
+
dependencies: collectStateDependencies(binding.value, statesByValue)
|
|
933
|
+
})),
|
|
836
934
|
events: rowAnalysis.events || [],
|
|
837
935
|
conditionals: rowAnalysis.conditionals || [],
|
|
936
|
+
rowReason: rowAnalysis.reason,
|
|
838
937
|
syntax
|
|
839
938
|
};
|
|
840
939
|
}
|
|
@@ -851,22 +950,7 @@ function analyzeKeyedRowsContainer(container, statesByValue, safeGlobals, listNa
|
|
|
851
950
|
}
|
|
852
951
|
const children = meaningfulJsxChildren(container);
|
|
853
952
|
if (children.length !== 1) return void 0;
|
|
854
|
-
return analyzeKeyedRowChild(children[0], statesByValue, safeGlobals, listNames);
|
|
855
|
-
}
|
|
856
|
-
function isStaticRangeSibling(element, statesByValue, safeGlobals) {
|
|
857
|
-
for (const child of meaningfulJsxChildren(element)) {
|
|
858
|
-
if (core.types.isJSXFragment(child)) return false;
|
|
859
|
-
if (core.types.isJSXElement(child)) {
|
|
860
|
-
if (!isHostElement(child) || !isStaticRangeSibling(child, statesByValue, safeGlobals)) {
|
|
861
|
-
return false;
|
|
862
|
-
}
|
|
863
|
-
continue;
|
|
864
|
-
}
|
|
865
|
-
if (core.types.isJSXExpressionContainer(child) && !core.types.isJSXEmptyExpression(child.expression) && !isTextExpression(child.expression, statesByValue, safeGlobals)) {
|
|
866
|
-
return false;
|
|
867
|
-
}
|
|
868
|
-
}
|
|
869
|
-
return true;
|
|
953
|
+
return analyzeKeyedRowChild(children[0], statesByValue, safeGlobals, listNames, true);
|
|
870
954
|
}
|
|
871
955
|
function analyzeKeyedRangesContainer(container, statesByValue, safeGlobals, listNames, allowSingleRange = false) {
|
|
872
956
|
if (container.openingElement.attributes.some(
|
|
@@ -878,6 +962,7 @@ function analyzeKeyedRangesContainer(container, statesByValue, safeGlobals, list
|
|
|
878
962
|
if (children.length < (allowSingleRange ? 1 : 2)) return void 0;
|
|
879
963
|
const ranges = [];
|
|
880
964
|
const dependencies = /* @__PURE__ */ new Set();
|
|
965
|
+
const staticBindings = [];
|
|
881
966
|
let staticBefore = 0;
|
|
882
967
|
for (const child of children) {
|
|
883
968
|
const range = analyzeKeyedRowChild(child, statesByValue, safeGlobals, listNames);
|
|
@@ -898,18 +983,31 @@ function analyzeKeyedRangesContainer(container, statesByValue, safeGlobals, list
|
|
|
898
983
|
continue;
|
|
899
984
|
}
|
|
900
985
|
if (!core.types.isJSXElement(child) || !isHostElement(child)) return void 0;
|
|
901
|
-
|
|
986
|
+
const analysis = analyzeHostConditionalTree(child, safeGlobals, true, statesByValue);
|
|
987
|
+
if (analysis.reason) return void 0;
|
|
988
|
+
for (const binding of analysis.bindings || []) {
|
|
989
|
+
staticBindings.push({
|
|
990
|
+
...binding,
|
|
991
|
+
segment: ranges.length,
|
|
992
|
+
sibling: staticBefore
|
|
993
|
+
});
|
|
994
|
+
for (const dependency of collectStateDependencies(binding.value, statesByValue)) {
|
|
995
|
+
dependencies.add(dependency);
|
|
996
|
+
}
|
|
997
|
+
}
|
|
902
998
|
staticBefore += 1;
|
|
903
999
|
}
|
|
904
1000
|
if (ranges.length === 0) return void 0;
|
|
905
1001
|
return {
|
|
906
1002
|
ranges,
|
|
907
1003
|
trailing: staticBefore,
|
|
908
|
-
dependencies: [...dependencies].sort((left, right) => left - right)
|
|
1004
|
+
dependencies: [...dependencies].sort((left, right) => left - right),
|
|
1005
|
+
staticBindings
|
|
909
1006
|
};
|
|
910
1007
|
}
|
|
911
|
-
function analyzeHostConditionalTree(branch, safeGlobals) {
|
|
1008
|
+
function analyzeHostConditionalTree(branch, safeGlobals, allowStaticEvents = false, statefulOnly) {
|
|
912
1009
|
const bindings = [];
|
|
1010
|
+
const needsStaticBinding = (expression) => !statefulOnly || collectStateDependencies(expression, statefulOnly).length > 0;
|
|
913
1011
|
const visit = (element, path) => {
|
|
914
1012
|
const tag = element.openingElement.name;
|
|
915
1013
|
if (!core.types.isJSXIdentifier(tag) || !/^[a-z]/.test(tag.name)) {
|
|
@@ -918,20 +1016,26 @@ function analyzeHostConditionalTree(branch, safeGlobals) {
|
|
|
918
1016
|
if (tag.name === "svg") return "compiler-owned conditionals do not support SVG yet";
|
|
919
1017
|
for (const attribute of element.openingElement.attributes) {
|
|
920
1018
|
if (core.types.isJSXSpreadAttribute(attribute)) {
|
|
1019
|
+
if (statefulOnly && !needsStaticBinding(attribute.argument)) continue;
|
|
921
1020
|
return "compiler-owned conditionals do not support JSX attribute spreads";
|
|
922
1021
|
}
|
|
923
1022
|
const name = jsxAttributeName(attribute);
|
|
924
1023
|
if (!name) return "compiler-owned conditionals do not support namespaced JSX attributes";
|
|
925
1024
|
if (name === "ref" || name === "dangerouslySetInnerHTML" || name === "key") {
|
|
1025
|
+
if (statefulOnly && (!core.types.isJSXExpressionContainer(attribute.value) || core.types.isJSXEmptyExpression(attribute.value.expression) || !needsStaticBinding(attribute.value.expression))) {
|
|
1026
|
+
continue;
|
|
1027
|
+
}
|
|
926
1028
|
return `compiler-owned conditional ${name} requires React ownership`;
|
|
927
1029
|
}
|
|
928
1030
|
if (/^on[A-Z]/.test(name)) {
|
|
1031
|
+
if (allowStaticEvents) continue;
|
|
929
1032
|
return "compiler-owned conditional events require React ownership";
|
|
930
1033
|
}
|
|
931
1034
|
if (!core.types.isJSXExpressionContainer(attribute.value) || core.types.isJSXEmptyExpression(attribute.value.expression)) {
|
|
932
1035
|
continue;
|
|
933
1036
|
}
|
|
934
1037
|
const expression = attribute.value.expression;
|
|
1038
|
+
if (!needsStaticBinding(expression)) continue;
|
|
935
1039
|
if (name === "style") {
|
|
936
1040
|
if (!core.types.isObjectExpression(expression)) {
|
|
937
1041
|
return "compiler-owned conditional styles must use one inline object literal";
|
|
@@ -944,6 +1048,7 @@ function analyzeHostConditionalTree(branch, safeGlobals) {
|
|
|
944
1048
|
if (!propertyName || propertyName.includes("-") && !propertyName.startsWith("--")) {
|
|
945
1049
|
return "compiler-owned conditional style names must use camelCase or a CSS custom property";
|
|
946
1050
|
}
|
|
1051
|
+
if (!needsStaticBinding(property.value)) continue;
|
|
947
1052
|
const unsupported2 = validateDerivedExpression(property.value, safeGlobals);
|
|
948
1053
|
if (unsupported2) {
|
|
949
1054
|
return `compiler-owned conditional style ${propertyName} cannot use ${unsupported2}`;
|
|
@@ -978,14 +1083,20 @@ function analyzeHostConditionalTree(branch, safeGlobals) {
|
|
|
978
1083
|
const expressions = element.children.filter(
|
|
979
1084
|
(child) => core.types.isJSXExpressionContainer(child) && !core.types.isJSXEmptyExpression(child.expression)
|
|
980
1085
|
);
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
1086
|
+
const boundExpressions = statefulOnly ? expressions.filter((child) => needsStaticBinding(child.expression)) : expressions;
|
|
1087
|
+
if (boundExpressions.length > 0) {
|
|
1088
|
+
for (const child of expressions) {
|
|
1089
|
+
const unsupported = validateDerivedExpression(
|
|
1090
|
+
child.expression,
|
|
1091
|
+
safeGlobals
|
|
1092
|
+
);
|
|
1093
|
+
if (unsupported) return `compiler-owned conditional text cannot use ${unsupported}`;
|
|
1094
|
+
}
|
|
984
1095
|
}
|
|
985
|
-
if (nestedElements.length > 0 &&
|
|
1096
|
+
if (nestedElements.length > 0 && boundExpressions.length > 0) {
|
|
986
1097
|
return "compiler-owned conditionals do not support dynamic text beside nested elements yet";
|
|
987
1098
|
}
|
|
988
|
-
if (nestedElements.length === 0 &&
|
|
1099
|
+
if (nestedElements.length === 0 && boundExpressions.length > 0) {
|
|
989
1100
|
const parts = [];
|
|
990
1101
|
for (const child of element.children) {
|
|
991
1102
|
if (core.types.isJSXText(child)) {
|
|
@@ -1009,7 +1120,369 @@ function analyzeHostConditionalTree(branch, safeGlobals) {
|
|
|
1009
1120
|
const reason = visit(branch, []);
|
|
1010
1121
|
return reason ? { reason } : { bindings };
|
|
1011
1122
|
}
|
|
1012
|
-
function
|
|
1123
|
+
function analyzeRecursiveHostTree(branch, statesByValue, safeGlobals, listNames, parent, allocateId) {
|
|
1124
|
+
const bindings = [];
|
|
1125
|
+
const plans = [];
|
|
1126
|
+
const blocks = /* @__PURE__ */ new Map();
|
|
1127
|
+
const visit = (element, path, owner) => {
|
|
1128
|
+
const tag = element.openingElement.name;
|
|
1129
|
+
if (!core.types.isJSXIdentifier(tag) || !/^[a-z]/.test(tag.name)) {
|
|
1130
|
+
return "recursive compiler-owned blocks support host elements only";
|
|
1131
|
+
}
|
|
1132
|
+
if (tag.name === "svg") return "recursive compiler-owned blocks do not support SVG yet";
|
|
1133
|
+
for (const attribute of element.openingElement.attributes) {
|
|
1134
|
+
if (core.types.isJSXSpreadAttribute(attribute)) {
|
|
1135
|
+
return "recursive compiler-owned blocks do not support JSX attribute spreads";
|
|
1136
|
+
}
|
|
1137
|
+
const name = jsxAttributeName(attribute);
|
|
1138
|
+
if (!name) return "recursive compiler-owned blocks do not support namespaced attributes";
|
|
1139
|
+
if (name === "ref" || name === "dangerouslySetInnerHTML" || name === "key") {
|
|
1140
|
+
return `recursive compiler-owned block ${name} requires React ownership`;
|
|
1141
|
+
}
|
|
1142
|
+
if (/^on[A-Z]/.test(name)) {
|
|
1143
|
+
return "recursive compiler-owned block events require React ownership";
|
|
1144
|
+
}
|
|
1145
|
+
if (!core.types.isJSXExpressionContainer(attribute.value) || core.types.isJSXEmptyExpression(attribute.value.expression)) {
|
|
1146
|
+
continue;
|
|
1147
|
+
}
|
|
1148
|
+
const expression = attribute.value.expression;
|
|
1149
|
+
if (name === "style") {
|
|
1150
|
+
if (!core.types.isObjectExpression(expression)) {
|
|
1151
|
+
return "recursive compiler-owned styles must use one inline object literal";
|
|
1152
|
+
}
|
|
1153
|
+
for (const property of expression.properties) {
|
|
1154
|
+
if (!core.types.isObjectProperty(property) || property.computed || !core.types.isExpression(property.value)) {
|
|
1155
|
+
return "recursive compiler-owned styles do not support spreads, methods, or computed properties";
|
|
1156
|
+
}
|
|
1157
|
+
const propertyName = core.types.isIdentifier(property.key) ? property.key.name : core.types.isStringLiteral(property.key) ? property.key.value : void 0;
|
|
1158
|
+
if (!propertyName || propertyName.includes("-") && !propertyName.startsWith("--")) {
|
|
1159
|
+
return "recursive compiler-owned style names must use camelCase or a CSS custom property";
|
|
1160
|
+
}
|
|
1161
|
+
const unsupported2 = validateDerivedExpression(property.value, safeGlobals);
|
|
1162
|
+
if (unsupported2) {
|
|
1163
|
+
return `recursive compiler-owned style ${propertyName} cannot use ${unsupported2}`;
|
|
1164
|
+
}
|
|
1165
|
+
bindings.push({
|
|
1166
|
+
kind: "style",
|
|
1167
|
+
path: [...path],
|
|
1168
|
+
name: propertyName,
|
|
1169
|
+
value: cloneExpression(property.value)
|
|
1170
|
+
});
|
|
1171
|
+
}
|
|
1172
|
+
continue;
|
|
1173
|
+
}
|
|
1174
|
+
if (name === "children") {
|
|
1175
|
+
return "recursive compiler-owned children props are not supported yet";
|
|
1176
|
+
}
|
|
1177
|
+
const unsupported = validateDerivedExpression(expression, safeGlobals);
|
|
1178
|
+
if (unsupported) return `recursive compiler-owned ${name} cannot use ${unsupported}`;
|
|
1179
|
+
bindings.push({
|
|
1180
|
+
kind: "attribute",
|
|
1181
|
+
path: [...path],
|
|
1182
|
+
name,
|
|
1183
|
+
value: cloneExpression(expression)
|
|
1184
|
+
});
|
|
1185
|
+
}
|
|
1186
|
+
const children = meaningfulJsxChildren(element);
|
|
1187
|
+
const hasConditionalRange = children.some(
|
|
1188
|
+
(child) => core.types.isJSXExpressionContainer(child) && !core.types.isJSXEmptyExpression(child.expression) && conditionalBlockShape(child.expression) !== null
|
|
1189
|
+
);
|
|
1190
|
+
const hasKeyedRange = children.some(
|
|
1191
|
+
(child) => analyzeKeyedRowChild(child, statesByValue, safeGlobals, listNames, true) !== void 0
|
|
1192
|
+
);
|
|
1193
|
+
if (hasConditionalRange && hasKeyedRange) {
|
|
1194
|
+
const id = allocateId();
|
|
1195
|
+
const mixed = analyzeMixedRangesContainer(
|
|
1196
|
+
element,
|
|
1197
|
+
statesByValue,
|
|
1198
|
+
safeGlobals,
|
|
1199
|
+
listNames,
|
|
1200
|
+
id,
|
|
1201
|
+
allocateId
|
|
1202
|
+
);
|
|
1203
|
+
if (mixed) {
|
|
1204
|
+
plans.push(...mixed.nestedPlans);
|
|
1205
|
+
for (const [nestedElement, plan2] of mixed.descriptorBlocks) {
|
|
1206
|
+
blocks.set(nestedElement, plan2);
|
|
1207
|
+
}
|
|
1208
|
+
const plan = {
|
|
1209
|
+
kind: "nested-host-mixed-ranges",
|
|
1210
|
+
id,
|
|
1211
|
+
parent: owner,
|
|
1212
|
+
dependencies: mixed.dependencies,
|
|
1213
|
+
source: element,
|
|
1214
|
+
ranges: mixed.ranges,
|
|
1215
|
+
trailing: mixed.trailing,
|
|
1216
|
+
staticBindings: mixed.staticBindings
|
|
1217
|
+
};
|
|
1218
|
+
plans.push(plan);
|
|
1219
|
+
blocks.set(element, plan);
|
|
1220
|
+
return void 0;
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
const conditionalChildren = /* @__PURE__ */ new Map();
|
|
1224
|
+
let conditionalContainer = children.length > 0;
|
|
1225
|
+
for (const child of children) {
|
|
1226
|
+
if (core.types.isJSXElement(child) && isHostElement(child)) continue;
|
|
1227
|
+
if (core.types.isJSXExpressionContainer(child) && !core.types.isJSXEmptyExpression(child.expression)) {
|
|
1228
|
+
const shape = conditionalBlockShape(child.expression);
|
|
1229
|
+
if (shape && !validateDerivedExpression(shape.test, safeGlobals)) {
|
|
1230
|
+
conditionalChildren.set(child.expression, shape);
|
|
1231
|
+
continue;
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
conditionalContainer = false;
|
|
1235
|
+
break;
|
|
1236
|
+
}
|
|
1237
|
+
if (conditionalContainer && conditionalChildren.size > 0) {
|
|
1238
|
+
const id = allocateId();
|
|
1239
|
+
const ranges = [];
|
|
1240
|
+
const staticBindings = [];
|
|
1241
|
+
const dependencies = /* @__PURE__ */ new Set();
|
|
1242
|
+
let staticBefore2 = 0;
|
|
1243
|
+
for (const child of children) {
|
|
1244
|
+
if (core.types.isJSXElement(child)) {
|
|
1245
|
+
const nested = analyzeRecursiveHostTree(
|
|
1246
|
+
child,
|
|
1247
|
+
statesByValue,
|
|
1248
|
+
safeGlobals,
|
|
1249
|
+
listNames,
|
|
1250
|
+
owner,
|
|
1251
|
+
allocateId
|
|
1252
|
+
);
|
|
1253
|
+
if (nested.reason) return nested.reason;
|
|
1254
|
+
plans.push(...nested.plans);
|
|
1255
|
+
for (const [nestedElement, plan2] of nested.blocks) blocks.set(nestedElement, plan2);
|
|
1256
|
+
for (const binding of nested.bindings) {
|
|
1257
|
+
staticBindings.push({
|
|
1258
|
+
...binding,
|
|
1259
|
+
segment: ranges.length,
|
|
1260
|
+
sibling: staticBefore2
|
|
1261
|
+
});
|
|
1262
|
+
for (const dependency of collectStateDependencies(binding.value, statesByValue)) {
|
|
1263
|
+
dependencies.add(dependency);
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
staticBefore2 += 1;
|
|
1267
|
+
continue;
|
|
1268
|
+
}
|
|
1269
|
+
if (!core.types.isJSXExpressionContainer(child) || core.types.isJSXEmptyExpression(child.expression)) {
|
|
1270
|
+
return "recursive conditional ranges contain an unsupported child";
|
|
1271
|
+
}
|
|
1272
|
+
const expression = child.expression;
|
|
1273
|
+
const shape = conditionalChildren.get(expression);
|
|
1274
|
+
const truthy = shape.truthy ? analyzeRecursiveHostTree(
|
|
1275
|
+
shape.truthy,
|
|
1276
|
+
statesByValue,
|
|
1277
|
+
safeGlobals,
|
|
1278
|
+
listNames,
|
|
1279
|
+
id,
|
|
1280
|
+
allocateId
|
|
1281
|
+
) : { bindings: [], plans: [], blocks: /* @__PURE__ */ new Map() };
|
|
1282
|
+
const falsy = shape.falsy ? analyzeRecursiveHostTree(
|
|
1283
|
+
shape.falsy,
|
|
1284
|
+
statesByValue,
|
|
1285
|
+
safeGlobals,
|
|
1286
|
+
listNames,
|
|
1287
|
+
id,
|
|
1288
|
+
allocateId
|
|
1289
|
+
) : { bindings: [], plans: [], blocks: /* @__PURE__ */ new Map() };
|
|
1290
|
+
if (truthy.reason) return truthy.reason;
|
|
1291
|
+
if (falsy.reason) return falsy.reason;
|
|
1292
|
+
plans.push(...truthy.plans, ...falsy.plans);
|
|
1293
|
+
for (const [nestedElement, plan2] of truthy.blocks) blocks.set(nestedElement, plan2);
|
|
1294
|
+
for (const [nestedElement, plan2] of falsy.blocks) blocks.set(nestedElement, plan2);
|
|
1295
|
+
for (const dependency of collectStateDependencies(shape.test, statesByValue)) {
|
|
1296
|
+
dependencies.add(dependency);
|
|
1297
|
+
}
|
|
1298
|
+
for (const binding of [...truthy.bindings, ...falsy.bindings]) {
|
|
1299
|
+
for (const dependency of collectStateDependencies(binding.value, statesByValue)) {
|
|
1300
|
+
dependencies.add(dependency);
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
ranges.push({
|
|
1304
|
+
before: staticBefore2,
|
|
1305
|
+
source: expression,
|
|
1306
|
+
test: cloneExpression(shape.test),
|
|
1307
|
+
logical: shape.logical,
|
|
1308
|
+
truthy: shape.truthy,
|
|
1309
|
+
falsy: shape.falsy,
|
|
1310
|
+
truthyBindings: truthy.bindings,
|
|
1311
|
+
falsyBindings: falsy.bindings
|
|
1312
|
+
});
|
|
1313
|
+
staticBefore2 = 0;
|
|
1314
|
+
}
|
|
1315
|
+
const plan = {
|
|
1316
|
+
kind: "nested-host-conditional-ranges",
|
|
1317
|
+
id,
|
|
1318
|
+
parent: owner,
|
|
1319
|
+
dependencies: [...dependencies].sort((left, right) => left - right),
|
|
1320
|
+
source: element,
|
|
1321
|
+
ranges,
|
|
1322
|
+
trailing: staticBefore2,
|
|
1323
|
+
staticBindings
|
|
1324
|
+
};
|
|
1325
|
+
plans.push(plan);
|
|
1326
|
+
blocks.set(element, plan);
|
|
1327
|
+
return void 0;
|
|
1328
|
+
}
|
|
1329
|
+
const keyedRows = [];
|
|
1330
|
+
let keyedContainer = children.length > 0;
|
|
1331
|
+
let staticBefore = 0;
|
|
1332
|
+
const staticChildren = [];
|
|
1333
|
+
for (const child of children) {
|
|
1334
|
+
const range = analyzeKeyedRowChild(child, statesByValue, safeGlobals, listNames, true);
|
|
1335
|
+
if (range) {
|
|
1336
|
+
keyedRows.push({ before: staticBefore, range });
|
|
1337
|
+
staticBefore = 0;
|
|
1338
|
+
} else if (core.types.isJSXElement(child) && isHostElement(child)) {
|
|
1339
|
+
staticChildren.push({
|
|
1340
|
+
element: child,
|
|
1341
|
+
segment: keyedRows.length,
|
|
1342
|
+
sibling: staticBefore
|
|
1343
|
+
});
|
|
1344
|
+
staticBefore += 1;
|
|
1345
|
+
} else {
|
|
1346
|
+
keyedContainer = false;
|
|
1347
|
+
break;
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
if (keyedContainer && keyedRows.length > 0) {
|
|
1351
|
+
const id = allocateId();
|
|
1352
|
+
const keyedRanges = [];
|
|
1353
|
+
const staticBindings = [];
|
|
1354
|
+
const keyedDependencies = /* @__PURE__ */ new Set();
|
|
1355
|
+
for (const { before, range } of keyedRows) {
|
|
1356
|
+
if (range.events.length > 0) {
|
|
1357
|
+
return "recursive compiler-owned keyed rows cannot contain events";
|
|
1358
|
+
}
|
|
1359
|
+
const row = core.types.cloneNode(range.row, true);
|
|
1360
|
+
row.openingElement.attributes = row.openingElement.attributes.filter(
|
|
1361
|
+
(attribute) => !core.types.isJSXAttribute(attribute) || jsxAttributeName(attribute) !== "key"
|
|
1362
|
+
);
|
|
1363
|
+
const rowAnalysis = analyzeRecursiveHostTree(
|
|
1364
|
+
row,
|
|
1365
|
+
statesByValue,
|
|
1366
|
+
safeGlobals,
|
|
1367
|
+
listNames,
|
|
1368
|
+
id,
|
|
1369
|
+
allocateId
|
|
1370
|
+
);
|
|
1371
|
+
if (rowAnalysis.reason) return rowAnalysis.reason;
|
|
1372
|
+
plans.push(...rowAnalysis.plans);
|
|
1373
|
+
for (const [nestedElement, nestedPlan] of rowAnalysis.blocks) {
|
|
1374
|
+
blocks.set(nestedElement, nestedPlan);
|
|
1375
|
+
}
|
|
1376
|
+
keyedRanges.push({
|
|
1377
|
+
before,
|
|
1378
|
+
source: range.source,
|
|
1379
|
+
collection: range.collection,
|
|
1380
|
+
keyCallback: range.keyCallback,
|
|
1381
|
+
renderCallback: range.renderCallback,
|
|
1382
|
+
row,
|
|
1383
|
+
bindings: rowAnalysis.bindings,
|
|
1384
|
+
syntax: range.syntax
|
|
1385
|
+
});
|
|
1386
|
+
for (const dependency of range.dependencies) keyedDependencies.add(dependency);
|
|
1387
|
+
}
|
|
1388
|
+
for (const { element: child, segment, sibling } of staticChildren) {
|
|
1389
|
+
const nested = analyzeRecursiveHostTree(
|
|
1390
|
+
child,
|
|
1391
|
+
statesByValue,
|
|
1392
|
+
safeGlobals,
|
|
1393
|
+
listNames,
|
|
1394
|
+
owner,
|
|
1395
|
+
allocateId
|
|
1396
|
+
);
|
|
1397
|
+
if (nested.reason) return nested.reason;
|
|
1398
|
+
plans.push(...nested.plans);
|
|
1399
|
+
for (const [nestedElement, plan2] of nested.blocks) blocks.set(nestedElement, plan2);
|
|
1400
|
+
for (const binding of nested.bindings) {
|
|
1401
|
+
staticBindings.push({ ...binding, segment, sibling });
|
|
1402
|
+
for (const dependency of collectStateDependencies(binding.value, statesByValue)) {
|
|
1403
|
+
keyedDependencies.add(dependency);
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1407
|
+
const plan = {
|
|
1408
|
+
kind: "nested-host-keyed-ranges",
|
|
1409
|
+
id,
|
|
1410
|
+
parent: owner,
|
|
1411
|
+
dependencies: [...keyedDependencies].sort((left, right) => left - right),
|
|
1412
|
+
source: element,
|
|
1413
|
+
ranges: keyedRanges,
|
|
1414
|
+
trailing: staticBefore,
|
|
1415
|
+
staticBindings
|
|
1416
|
+
};
|
|
1417
|
+
plans.push(plan);
|
|
1418
|
+
blocks.set(element, plan);
|
|
1419
|
+
return void 0;
|
|
1420
|
+
}
|
|
1421
|
+
if (element.children.some((child) => core.types.isJSXFragment(child))) {
|
|
1422
|
+
return "recursive compiler-owned blocks do not support fragments yet";
|
|
1423
|
+
}
|
|
1424
|
+
const nestedElements = element.children.filter(
|
|
1425
|
+
(child) => core.types.isJSXElement(child)
|
|
1426
|
+
);
|
|
1427
|
+
const expressions = element.children.filter(
|
|
1428
|
+
(child) => core.types.isJSXExpressionContainer(child) && !core.types.isJSXEmptyExpression(child.expression)
|
|
1429
|
+
);
|
|
1430
|
+
for (const child of expressions) {
|
|
1431
|
+
const unsupported = validateDerivedExpression(child.expression, safeGlobals);
|
|
1432
|
+
if (unsupported) return `recursive compiler-owned text cannot use ${unsupported}`;
|
|
1433
|
+
}
|
|
1434
|
+
if (nestedElements.length > 0 && expressions.length > 0) {
|
|
1435
|
+
return "recursive compiler-owned blocks do not support dynamic text beside nested elements";
|
|
1436
|
+
}
|
|
1437
|
+
if (nestedElements.length === 0 && expressions.length > 0) {
|
|
1438
|
+
const parts = [];
|
|
1439
|
+
for (const child of element.children) {
|
|
1440
|
+
if (core.types.isJSXText(child)) {
|
|
1441
|
+
const text = cleanJsxText(child.value);
|
|
1442
|
+
if (text) parts.push(core.types.stringLiteral(text));
|
|
1443
|
+
} else if (core.types.isJSXExpressionContainer(child) && !core.types.isJSXEmptyExpression(child.expression)) {
|
|
1444
|
+
parts.push(cloneExpression(child.expression));
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
bindings.push({ kind: "text", path: [...path], value: core.types.arrayExpression(parts) });
|
|
1448
|
+
}
|
|
1449
|
+
let elementIndex = 0;
|
|
1450
|
+
for (const child of element.children) {
|
|
1451
|
+
if (!core.types.isJSXElement(child)) continue;
|
|
1452
|
+
const reason2 = visit(child, [...path, elementIndex], owner);
|
|
1453
|
+
if (reason2) return reason2;
|
|
1454
|
+
elementIndex += 1;
|
|
1455
|
+
}
|
|
1456
|
+
return void 0;
|
|
1457
|
+
};
|
|
1458
|
+
const reason = visit(branch, [], parent);
|
|
1459
|
+
return { bindings, plans, blocks, reason };
|
|
1460
|
+
}
|
|
1461
|
+
function analyzeCompilerOwnedKeyedRowHostBlocks(shape, statesByValue, safeGlobals, listNames, parent, allocateId) {
|
|
1462
|
+
if (shape.events.length > 0) return void 0;
|
|
1463
|
+
const row = core.types.cloneNode(shape.row, true);
|
|
1464
|
+
row.openingElement.attributes = row.openingElement.attributes.filter(
|
|
1465
|
+
(attribute) => !core.types.isJSXAttribute(attribute) || jsxAttributeName(attribute) !== "key"
|
|
1466
|
+
);
|
|
1467
|
+
const analysis = analyzeRecursiveHostTree(
|
|
1468
|
+
row,
|
|
1469
|
+
statesByValue,
|
|
1470
|
+
safeGlobals,
|
|
1471
|
+
listNames,
|
|
1472
|
+
parent,
|
|
1473
|
+
allocateId
|
|
1474
|
+
);
|
|
1475
|
+
if (analysis.reason || analysis.plans.length === 0) {
|
|
1476
|
+
return void 0;
|
|
1477
|
+
}
|
|
1478
|
+
return {
|
|
1479
|
+
row,
|
|
1480
|
+
bindings: analysis.bindings,
|
|
1481
|
+
descriptorBlocks: analysis.blocks,
|
|
1482
|
+
nestedPlans: analysis.plans
|
|
1483
|
+
};
|
|
1484
|
+
}
|
|
1485
|
+
function analyzeHostConditionalContainer(container, statesByValue, safeGlobals, listNames, parent, allocateId) {
|
|
1013
1486
|
const containerName = container.openingElement.name;
|
|
1014
1487
|
if (!core.types.isJSXIdentifier(containerName) || !/^[a-z]/.test(containerName.name) || containerName.name === "svg") {
|
|
1015
1488
|
return void 0;
|
|
@@ -1031,8 +1504,22 @@ function analyzeHostConditionalContainer(container, statesByValue, safeGlobals)
|
|
|
1031
1504
|
}
|
|
1032
1505
|
const shape = conditionalBlockShape(children[0].expression);
|
|
1033
1506
|
if (!shape || validateDerivedExpression(shape.test, safeGlobals)) return void 0;
|
|
1034
|
-
const truthyAnalysis = shape.truthy ?
|
|
1035
|
-
|
|
1507
|
+
const truthyAnalysis = shape.truthy ? analyzeRecursiveHostTree(
|
|
1508
|
+
shape.truthy,
|
|
1509
|
+
statesByValue,
|
|
1510
|
+
safeGlobals,
|
|
1511
|
+
listNames,
|
|
1512
|
+
parent,
|
|
1513
|
+
allocateId
|
|
1514
|
+
) : { bindings: [], plans: [], blocks: /* @__PURE__ */ new Map() };
|
|
1515
|
+
const falsyAnalysis = shape.falsy ? analyzeRecursiveHostTree(
|
|
1516
|
+
shape.falsy,
|
|
1517
|
+
statesByValue,
|
|
1518
|
+
safeGlobals,
|
|
1519
|
+
listNames,
|
|
1520
|
+
parent,
|
|
1521
|
+
allocateId
|
|
1522
|
+
) : { bindings: [], plans: [], blocks: /* @__PURE__ */ new Map() };
|
|
1036
1523
|
if (truthyAnalysis.reason || falsyAnalysis.reason) return void 0;
|
|
1037
1524
|
const dependencies = new Set(collectStateDependencies(shape.test, statesByValue));
|
|
1038
1525
|
for (const binding of [...truthyAnalysis.bindings || [], ...falsyAnalysis.bindings || []]) {
|
|
@@ -1047,10 +1534,12 @@ function analyzeHostConditionalContainer(container, statesByValue, safeGlobals)
|
|
|
1047
1534
|
truthy: shape.truthy,
|
|
1048
1535
|
falsy: shape.falsy,
|
|
1049
1536
|
truthyBindings: truthyAnalysis.bindings || [],
|
|
1050
|
-
falsyBindings: falsyAnalysis.bindings || []
|
|
1537
|
+
falsyBindings: falsyAnalysis.bindings || [],
|
|
1538
|
+
descriptorBlocks: new Map([...truthyAnalysis.blocks, ...falsyAnalysis.blocks]),
|
|
1539
|
+
nestedPlans: [...truthyAnalysis.plans, ...falsyAnalysis.plans]
|
|
1051
1540
|
};
|
|
1052
1541
|
}
|
|
1053
|
-
function analyzeConditionalRangesContainer(container, statesByValue, safeGlobals, allowSingleRange
|
|
1542
|
+
function analyzeConditionalRangesContainer(container, statesByValue, safeGlobals, allowSingleRange, listNames, parent, allocateId) {
|
|
1054
1543
|
const containerName = container.openingElement.name;
|
|
1055
1544
|
if (!core.types.isJSXIdentifier(containerName) || !/^[a-z]/.test(containerName.name) || containerName.name === "svg" || container.openingElement.attributes.some(
|
|
1056
1545
|
(attribute) => core.types.isJSXSpreadAttribute(attribute) || core.types.isJSXAttribute(attribute) && core.types.isJSXIdentifier(attribute.name) && (attribute.name.name === "ref" || attribute.name.name === "dangerouslySetInnerHTML")
|
|
@@ -1061,14 +1550,34 @@ function analyzeConditionalRangesContainer(container, statesByValue, safeGlobals
|
|
|
1061
1550
|
if (children.length < (allowSingleRange ? 1 : 2)) return void 0;
|
|
1062
1551
|
const ranges = [];
|
|
1063
1552
|
const dependencies = /* @__PURE__ */ new Set();
|
|
1553
|
+
const descriptorBlocks = /* @__PURE__ */ new Map();
|
|
1554
|
+
const nestedPlans = [];
|
|
1555
|
+
const staticBindings = [];
|
|
1064
1556
|
let staticBefore = 0;
|
|
1065
1557
|
for (const child of children) {
|
|
1066
1558
|
if (core.types.isJSXExpressionContainer(child) && !core.types.isJSXEmptyExpression(child.expression)) {
|
|
1067
1559
|
const shape = conditionalBlockShape(child.expression);
|
|
1068
1560
|
if (shape && !validateDerivedExpression(shape.test, safeGlobals)) {
|
|
1069
|
-
const truthyAnalysis = shape.truthy ?
|
|
1070
|
-
|
|
1561
|
+
const truthyAnalysis = shape.truthy ? analyzeRecursiveHostTree(
|
|
1562
|
+
shape.truthy,
|
|
1563
|
+
statesByValue,
|
|
1564
|
+
safeGlobals,
|
|
1565
|
+
listNames,
|
|
1566
|
+
parent,
|
|
1567
|
+
allocateId
|
|
1568
|
+
) : { bindings: [], plans: [], blocks: /* @__PURE__ */ new Map() };
|
|
1569
|
+
const falsyAnalysis = shape.falsy ? analyzeRecursiveHostTree(
|
|
1570
|
+
shape.falsy,
|
|
1571
|
+
statesByValue,
|
|
1572
|
+
safeGlobals,
|
|
1573
|
+
listNames,
|
|
1574
|
+
parent,
|
|
1575
|
+
allocateId
|
|
1576
|
+
) : { bindings: [], plans: [], blocks: /* @__PURE__ */ new Map() };
|
|
1071
1577
|
if (truthyAnalysis.reason || falsyAnalysis.reason) return void 0;
|
|
1578
|
+
nestedPlans.push(...truthyAnalysis.plans, ...falsyAnalysis.plans);
|
|
1579
|
+
for (const [element, plan] of truthyAnalysis.blocks) descriptorBlocks.set(element, plan);
|
|
1580
|
+
for (const [element, plan] of falsyAnalysis.blocks) descriptorBlocks.set(element, plan);
|
|
1072
1581
|
const rangeDependencies = new Set(collectStateDependencies(shape.test, statesByValue));
|
|
1073
1582
|
for (const binding of [
|
|
1074
1583
|
...truthyAnalysis.bindings || [],
|
|
@@ -1094,14 +1603,158 @@ function analyzeConditionalRangesContainer(container, statesByValue, safeGlobals
|
|
|
1094
1603
|
}
|
|
1095
1604
|
}
|
|
1096
1605
|
if (!core.types.isJSXElement(child) || !isHostElement(child)) return void 0;
|
|
1097
|
-
|
|
1606
|
+
const staticAnalysis = analyzeHostConditionalTree(child, safeGlobals, true, statesByValue);
|
|
1607
|
+
if (staticAnalysis.reason) return void 0;
|
|
1608
|
+
for (const binding of staticAnalysis.bindings || []) {
|
|
1609
|
+
staticBindings.push({
|
|
1610
|
+
...binding,
|
|
1611
|
+
segment: ranges.length,
|
|
1612
|
+
sibling: staticBefore
|
|
1613
|
+
});
|
|
1614
|
+
for (const dependency of collectStateDependencies(binding.value, statesByValue)) {
|
|
1615
|
+
dependencies.add(dependency);
|
|
1616
|
+
}
|
|
1617
|
+
}
|
|
1098
1618
|
staticBefore += 1;
|
|
1099
1619
|
}
|
|
1100
1620
|
if (ranges.length === 0) return void 0;
|
|
1101
1621
|
return {
|
|
1102
1622
|
ranges,
|
|
1103
1623
|
trailing: staticBefore,
|
|
1104
|
-
dependencies: [...dependencies].sort((left, right) => left - right)
|
|
1624
|
+
dependencies: [...dependencies].sort((left, right) => left - right),
|
|
1625
|
+
staticBindings,
|
|
1626
|
+
descriptorBlocks,
|
|
1627
|
+
nestedPlans
|
|
1628
|
+
};
|
|
1629
|
+
}
|
|
1630
|
+
function analyzeMixedRangesContainer(container, statesByValue, safeGlobals, listNames, parent, allocateId) {
|
|
1631
|
+
const containerName = container.openingElement.name;
|
|
1632
|
+
if (!core.types.isJSXIdentifier(containerName) || !/^[a-z]/.test(containerName.name) || containerName.name === "svg" || container.openingElement.attributes.some(
|
|
1633
|
+
(attribute) => core.types.isJSXSpreadAttribute(attribute) || core.types.isJSXAttribute(attribute) && core.types.isJSXIdentifier(attribute.name) && (attribute.name.name === "ref" || attribute.name.name === "dangerouslySetInnerHTML")
|
|
1634
|
+
)) {
|
|
1635
|
+
return void 0;
|
|
1636
|
+
}
|
|
1637
|
+
const children = meaningfulJsxChildren(container);
|
|
1638
|
+
if (children.length < 2) return void 0;
|
|
1639
|
+
const ranges = [];
|
|
1640
|
+
const dependencies = /* @__PURE__ */ new Set();
|
|
1641
|
+
const descriptorBlocks = /* @__PURE__ */ new Map();
|
|
1642
|
+
const nestedPlans = [];
|
|
1643
|
+
const staticBindings = [];
|
|
1644
|
+
let conditionalCount = 0;
|
|
1645
|
+
let keyedCount = 0;
|
|
1646
|
+
let staticBefore = 0;
|
|
1647
|
+
const mergeAnalysis = (analysis) => {
|
|
1648
|
+
if (analysis.reason) return false;
|
|
1649
|
+
nestedPlans.push(...analysis.plans);
|
|
1650
|
+
for (const [element, plan] of analysis.blocks) descriptorBlocks.set(element, plan);
|
|
1651
|
+
for (const binding of analysis.bindings) {
|
|
1652
|
+
for (const dependency of collectStateDependencies(binding.value, statesByValue)) {
|
|
1653
|
+
dependencies.add(dependency);
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1656
|
+
return true;
|
|
1657
|
+
};
|
|
1658
|
+
for (const child of children) {
|
|
1659
|
+
if (core.types.isJSXExpressionContainer(child) && !core.types.isJSXEmptyExpression(child.expression)) {
|
|
1660
|
+
const shape = conditionalBlockShape(child.expression);
|
|
1661
|
+
if (shape && !validateDerivedExpression(shape.test, safeGlobals)) {
|
|
1662
|
+
const truthyAnalysis = shape.truthy ? analyzeRecursiveHostTree(
|
|
1663
|
+
shape.truthy,
|
|
1664
|
+
statesByValue,
|
|
1665
|
+
safeGlobals,
|
|
1666
|
+
listNames,
|
|
1667
|
+
parent,
|
|
1668
|
+
allocateId
|
|
1669
|
+
) : { bindings: [], plans: [], blocks: /* @__PURE__ */ new Map() };
|
|
1670
|
+
const falsyAnalysis = shape.falsy ? analyzeRecursiveHostTree(
|
|
1671
|
+
shape.falsy,
|
|
1672
|
+
statesByValue,
|
|
1673
|
+
safeGlobals,
|
|
1674
|
+
listNames,
|
|
1675
|
+
parent,
|
|
1676
|
+
allocateId
|
|
1677
|
+
) : { bindings: [], plans: [], blocks: /* @__PURE__ */ new Map() };
|
|
1678
|
+
if (!mergeAnalysis(truthyAnalysis) || !mergeAnalysis(falsyAnalysis)) return void 0;
|
|
1679
|
+
for (const dependency of collectStateDependencies(shape.test, statesByValue)) {
|
|
1680
|
+
dependencies.add(dependency);
|
|
1681
|
+
}
|
|
1682
|
+
ranges.push({
|
|
1683
|
+
rangeKind: "conditional",
|
|
1684
|
+
before: staticBefore,
|
|
1685
|
+
source: child.expression,
|
|
1686
|
+
test: cloneExpression(shape.test),
|
|
1687
|
+
logical: shape.logical,
|
|
1688
|
+
truthy: shape.truthy,
|
|
1689
|
+
falsy: shape.falsy,
|
|
1690
|
+
truthyBindings: truthyAnalysis.bindings,
|
|
1691
|
+
falsyBindings: falsyAnalysis.bindings
|
|
1692
|
+
});
|
|
1693
|
+
conditionalCount += 1;
|
|
1694
|
+
staticBefore = 0;
|
|
1695
|
+
continue;
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
const keyed = analyzeKeyedRowChild(child, statesByValue, safeGlobals, listNames, true);
|
|
1699
|
+
if (keyed) {
|
|
1700
|
+
if (keyed.events.length > 0) return void 0;
|
|
1701
|
+
const row = core.types.cloneNode(keyed.row, true);
|
|
1702
|
+
row.openingElement.attributes = row.openingElement.attributes.filter(
|
|
1703
|
+
(attribute) => !core.types.isJSXAttribute(attribute) || jsxAttributeName(attribute) !== "key"
|
|
1704
|
+
);
|
|
1705
|
+
const rowAnalysis = analyzeRecursiveHostTree(
|
|
1706
|
+
row,
|
|
1707
|
+
statesByValue,
|
|
1708
|
+
safeGlobals,
|
|
1709
|
+
listNames,
|
|
1710
|
+
parent,
|
|
1711
|
+
allocateId
|
|
1712
|
+
);
|
|
1713
|
+
if (!mergeAnalysis(rowAnalysis)) return void 0;
|
|
1714
|
+
for (const dependency of keyed.dependencies) dependencies.add(dependency);
|
|
1715
|
+
ranges.push({
|
|
1716
|
+
rangeKind: "keyed",
|
|
1717
|
+
before: staticBefore,
|
|
1718
|
+
source: keyed.source,
|
|
1719
|
+
collection: keyed.collection,
|
|
1720
|
+
keyCallback: keyed.keyCallback,
|
|
1721
|
+
renderCallback: keyed.renderCallback,
|
|
1722
|
+
row,
|
|
1723
|
+
bindings: rowAnalysis.bindings,
|
|
1724
|
+
syntax: keyed.syntax
|
|
1725
|
+
});
|
|
1726
|
+
keyedCount += 1;
|
|
1727
|
+
staticBefore = 0;
|
|
1728
|
+
continue;
|
|
1729
|
+
}
|
|
1730
|
+
if (!core.types.isJSXElement(child) || !isHostElement(child)) return void 0;
|
|
1731
|
+
const staticAnalysis = analyzeRecursiveHostTree(
|
|
1732
|
+
child,
|
|
1733
|
+
statesByValue,
|
|
1734
|
+
safeGlobals,
|
|
1735
|
+
listNames,
|
|
1736
|
+
parent,
|
|
1737
|
+
allocateId
|
|
1738
|
+
);
|
|
1739
|
+
if (staticAnalysis.reason) return void 0;
|
|
1740
|
+
for (const binding of staticAnalysis.bindings) {
|
|
1741
|
+
staticBindings.push({
|
|
1742
|
+
...binding,
|
|
1743
|
+
segment: ranges.length,
|
|
1744
|
+
sibling: staticBefore
|
|
1745
|
+
});
|
|
1746
|
+
}
|
|
1747
|
+
if (!mergeAnalysis(staticAnalysis)) return void 0;
|
|
1748
|
+
staticBefore += 1;
|
|
1749
|
+
}
|
|
1750
|
+
if (conditionalCount === 0 || keyedCount === 0) return void 0;
|
|
1751
|
+
return {
|
|
1752
|
+
ranges,
|
|
1753
|
+
trailing: staticBefore,
|
|
1754
|
+
dependencies: [...dependencies].sort((left, right) => left - right),
|
|
1755
|
+
staticBindings,
|
|
1756
|
+
descriptorBlocks,
|
|
1757
|
+
nestedPlans
|
|
1105
1758
|
};
|
|
1106
1759
|
}
|
|
1107
1760
|
function keyedListBoundary(blockRuntime, plan, source) {
|
|
@@ -1126,14 +1779,14 @@ function keyedListBoundary(blockRuntime, plan, source) {
|
|
|
1126
1779
|
true
|
|
1127
1780
|
);
|
|
1128
1781
|
}
|
|
1129
|
-
function hostElementDescriptor(element) {
|
|
1782
|
+
function hostElementDescriptor(element, descriptorBlocks = /* @__PURE__ */ new Map()) {
|
|
1130
1783
|
const tag = element.openingElement.name;
|
|
1131
1784
|
const attributes = [];
|
|
1132
1785
|
const styles = [];
|
|
1133
1786
|
for (const attribute of element.openingElement.attributes) {
|
|
1134
1787
|
if (!core.types.isJSXAttribute(attribute)) continue;
|
|
1135
1788
|
const name = jsxAttributeName(attribute);
|
|
1136
|
-
if (!name || name === "key" || /^on[A-Z]/.test(name)) continue;
|
|
1789
|
+
if (!name || name === "key" || name === "ref" || /^on[A-Z]/.test(name)) continue;
|
|
1137
1790
|
if (name === "style") {
|
|
1138
1791
|
if (core.types.isJSXExpressionContainer(attribute.value) && core.types.isObjectExpression(attribute.value.expression)) {
|
|
1139
1792
|
for (const property of attribute.value.expression.properties) {
|
|
@@ -1157,24 +1810,93 @@ function hostElementDescriptor(element) {
|
|
|
1157
1810
|
])
|
|
1158
1811
|
);
|
|
1159
1812
|
}
|
|
1813
|
+
const block = descriptorBlocks.get(element);
|
|
1814
|
+
const conditionalBySource = /* @__PURE__ */ new Map();
|
|
1815
|
+
const keyedBySource = /* @__PURE__ */ new Map();
|
|
1816
|
+
if (block?.kind === "nested-host-conditional-ranges") {
|
|
1817
|
+
for (const range of block.ranges) conditionalBySource.set(range.source, range);
|
|
1818
|
+
} else if (block?.kind === "nested-host-keyed-ranges") {
|
|
1819
|
+
for (const range of block.ranges) keyedBySource.set(range.source, range);
|
|
1820
|
+
} else if (block?.kind === "nested-host-mixed-ranges") {
|
|
1821
|
+
for (const range of block.ranges) {
|
|
1822
|
+
if (range.rangeKind === "conditional") conditionalBySource.set(range.source, range);
|
|
1823
|
+
else keyedBySource.set(range.source, range);
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1160
1826
|
const children = [];
|
|
1161
1827
|
for (const child of element.children) {
|
|
1162
1828
|
if (core.types.isJSXText(child)) {
|
|
1163
1829
|
const text = cleanJsxText(child.value);
|
|
1164
1830
|
if (text) children.push(core.types.stringLiteral(text));
|
|
1165
1831
|
} else if (core.types.isJSXElement(child)) {
|
|
1166
|
-
|
|
1832
|
+
const keyedRange = keyedBySource.get(child);
|
|
1833
|
+
if (keyedRange) {
|
|
1834
|
+
if (block?.kind !== "nested-host-keyed-ranges") {
|
|
1835
|
+
children.push(keyedRangeDescriptorChildren(keyedRange, descriptorBlocks));
|
|
1836
|
+
}
|
|
1837
|
+
} else {
|
|
1838
|
+
children.push(hostElementDescriptor(child, descriptorBlocks));
|
|
1839
|
+
}
|
|
1167
1840
|
} else if (core.types.isJSXExpressionContainer(child) && !core.types.isJSXEmptyExpression(child.expression)) {
|
|
1168
|
-
|
|
1841
|
+
const conditionalRange = conditionalBySource.get(child.expression);
|
|
1842
|
+
const keyedRange = keyedBySource.get(child.expression);
|
|
1843
|
+
if (conditionalRange) {
|
|
1844
|
+
children.push(conditionalRangeDescriptorChild(conditionalRange, descriptorBlocks));
|
|
1845
|
+
} else if (keyedRange) {
|
|
1846
|
+
if (block?.kind !== "nested-host-keyed-ranges") {
|
|
1847
|
+
children.push(keyedRangeDescriptorChildren(keyedRange, descriptorBlocks));
|
|
1848
|
+
}
|
|
1849
|
+
} else {
|
|
1850
|
+
children.push(cloneExpression(child.expression));
|
|
1851
|
+
}
|
|
1169
1852
|
}
|
|
1170
1853
|
}
|
|
1171
|
-
|
|
1854
|
+
const properties = [
|
|
1172
1855
|
core.types.objectProperty(core.types.identifier("kind"), core.types.stringLiteral("element")),
|
|
1173
1856
|
core.types.objectProperty(core.types.identifier("tag"), core.types.stringLiteral(tag.name)),
|
|
1174
1857
|
core.types.objectProperty(core.types.identifier("attributes"), core.types.arrayExpression(attributes)),
|
|
1175
1858
|
core.types.objectProperty(core.types.identifier("styles"), core.types.arrayExpression(styles)),
|
|
1176
1859
|
core.types.objectProperty(core.types.identifier("children"), core.types.arrayExpression(children))
|
|
1177
|
-
]
|
|
1860
|
+
];
|
|
1861
|
+
if (block) {
|
|
1862
|
+
properties.push(
|
|
1863
|
+
core.types.objectProperty(core.types.identifier("block"), nestedHostBlockObject(block, descriptorBlocks))
|
|
1864
|
+
);
|
|
1865
|
+
}
|
|
1866
|
+
return core.types.objectExpression(properties);
|
|
1867
|
+
}
|
|
1868
|
+
function conditionalRangeDescriptorChild(range, descriptorBlocks) {
|
|
1869
|
+
const truthy = range.truthy ? hostElementDescriptor(range.truthy, descriptorBlocks) : core.types.nullLiteral();
|
|
1870
|
+
if (range.logical) {
|
|
1871
|
+
return core.types.logicalExpression("&&", cloneExpression(range.test), truthy);
|
|
1872
|
+
}
|
|
1873
|
+
return core.types.conditionalExpression(
|
|
1874
|
+
cloneExpression(range.test),
|
|
1875
|
+
truthy,
|
|
1876
|
+
range.falsy ? hostElementDescriptor(range.falsy, descriptorBlocks) : core.types.nullLiteral()
|
|
1877
|
+
);
|
|
1878
|
+
}
|
|
1879
|
+
function keyedRangeDescriptorChildren(range, descriptorBlocks) {
|
|
1880
|
+
const parameters = range.renderCallback.params.map(
|
|
1881
|
+
(parameter) => core.types.cloneNode(parameter, true)
|
|
1882
|
+
);
|
|
1883
|
+
const callback = core.types.arrowFunctionExpression(
|
|
1884
|
+
parameters,
|
|
1885
|
+
hostElementDescriptor(range.row, descriptorBlocks)
|
|
1886
|
+
);
|
|
1887
|
+
const collection = cloneExpression(range.collection);
|
|
1888
|
+
if (range.syntax === "map") {
|
|
1889
|
+
return core.types.callExpression(core.types.memberExpression(collection, core.types.identifier("map")), [callback]);
|
|
1890
|
+
}
|
|
1891
|
+
return core.types.callExpression(
|
|
1892
|
+
core.types.memberExpression(
|
|
1893
|
+
core.types.callExpression(core.types.memberExpression(core.types.identifier("Array"), core.types.identifier("from")), [
|
|
1894
|
+
core.types.logicalExpression("||", collection, core.types.arrayExpression([]))
|
|
1895
|
+
]),
|
|
1896
|
+
core.types.identifier("map")
|
|
1897
|
+
),
|
|
1898
|
+
[callback]
|
|
1899
|
+
);
|
|
1178
1900
|
}
|
|
1179
1901
|
function keyedRowBindingObject(binding, parameters) {
|
|
1180
1902
|
const properties = [
|
|
@@ -1182,6 +1904,12 @@ function keyedRowBindingObject(binding, parameters) {
|
|
|
1182
1904
|
core.types.objectProperty(
|
|
1183
1905
|
core.types.identifier("path"),
|
|
1184
1906
|
core.types.arrayExpression(binding.path.map((part) => core.types.numericLiteral(part)))
|
|
1907
|
+
),
|
|
1908
|
+
core.types.objectProperty(
|
|
1909
|
+
core.types.identifier("dependencies"),
|
|
1910
|
+
core.types.arrayExpression(
|
|
1911
|
+
(binding.dependencies || []).map((dependency) => core.types.numericLiteral(dependency))
|
|
1912
|
+
)
|
|
1185
1913
|
)
|
|
1186
1914
|
];
|
|
1187
1915
|
if (binding.name) {
|
|
@@ -1198,6 +1926,16 @@ function keyedRowBindingObject(binding, parameters) {
|
|
|
1198
1926
|
);
|
|
1199
1927
|
return core.types.objectExpression(properties);
|
|
1200
1928
|
}
|
|
1929
|
+
function staticRangeBindingObject(binding) {
|
|
1930
|
+
const value = keyedRowBindingObject(binding, []);
|
|
1931
|
+
value.properties.splice(
|
|
1932
|
+
1,
|
|
1933
|
+
0,
|
|
1934
|
+
core.types.objectProperty(core.types.identifier("segment"), core.types.numericLiteral(binding.segment)),
|
|
1935
|
+
core.types.objectProperty(core.types.identifier("sibling"), core.types.numericLiteral(binding.sibling))
|
|
1936
|
+
);
|
|
1937
|
+
return value;
|
|
1938
|
+
}
|
|
1201
1939
|
function uniqueLocalIdentifier(base, nodes) {
|
|
1202
1940
|
const names = /* @__PURE__ */ new Set();
|
|
1203
1941
|
for (const node of nodes) {
|
|
@@ -1314,6 +2052,10 @@ function keyedRowEventObject(event, renderParameters) {
|
|
|
1314
2052
|
const parameters = [core.types.cloneNode(renderParameters[0], true), index, syntheticEvent];
|
|
1315
2053
|
return core.types.objectExpression([
|
|
1316
2054
|
core.types.objectProperty(core.types.identifier("name"), core.types.stringLiteral(event.name)),
|
|
2055
|
+
core.types.objectProperty(
|
|
2056
|
+
core.types.identifier("path"),
|
|
2057
|
+
core.types.arrayExpression(event.path.map((part) => core.types.numericLiteral(part)))
|
|
2058
|
+
),
|
|
1317
2059
|
core.types.objectProperty(
|
|
1318
2060
|
core.types.identifier("invoke"),
|
|
1319
2061
|
core.types.arrowFunctionExpression(
|
|
@@ -1383,6 +2125,7 @@ function keyedRowsBoundary(blockRuntime, plan) {
|
|
|
1383
2125
|
plan.source,
|
|
1384
2126
|
...plan.conditionals.map((conditional) => conditional.test)
|
|
1385
2127
|
]);
|
|
2128
|
+
const delegatedEvents = canDelegateKeyedRowEvents(plan);
|
|
1386
2129
|
const renderSource = keyedRowsRenderSource(plan, eventFactory, conditionalFactory);
|
|
1387
2130
|
const renderFactoryParameters = plan.conditionals.length > 0 ? [core.types.cloneNode(eventFactory), core.types.cloneNode(conditionalFactory)] : plan.events.length > 0 ? [core.types.cloneNode(eventFactory)] : [];
|
|
1388
2131
|
return core.types.jsxElement(
|
|
@@ -1400,6 +2143,14 @@ function keyedRowsBoundary(blockRuntime, plan) {
|
|
|
1400
2143
|
core.types.jsxIdentifier("items"),
|
|
1401
2144
|
core.types.jsxExpressionContainer(core.types.arrowFunctionExpression([], cloneExpression(plan.collection)))
|
|
1402
2145
|
),
|
|
2146
|
+
core.types.jsxAttribute(
|
|
2147
|
+
core.types.jsxIdentifier("structureDependencies"),
|
|
2148
|
+
core.types.jsxExpressionContainer(
|
|
2149
|
+
core.types.arrayExpression(
|
|
2150
|
+
plan.structureDependencies.map((dependency) => core.types.numericLiteral(dependency))
|
|
2151
|
+
)
|
|
2152
|
+
)
|
|
2153
|
+
),
|
|
1403
2154
|
core.types.jsxAttribute(
|
|
1404
2155
|
core.types.jsxIdentifier("rowKey"),
|
|
1405
2156
|
core.types.jsxExpressionContainer(core.types.cloneNode(plan.keyCallback, true))
|
|
@@ -1409,7 +2160,7 @@ function keyedRowsBoundary(blockRuntime, plan) {
|
|
|
1409
2160
|
core.types.jsxExpressionContainer(
|
|
1410
2161
|
core.types.arrowFunctionExpression(
|
|
1411
2162
|
parameters.map((parameter) => core.types.cloneNode(parameter, true)),
|
|
1412
|
-
hostElementDescriptor(plan.row)
|
|
2163
|
+
hostElementDescriptor(plan.row, plan.descriptorBlocks)
|
|
1413
2164
|
)
|
|
1414
2165
|
)
|
|
1415
2166
|
),
|
|
@@ -1429,7 +2180,13 @@ function keyedRowsBoundary(blockRuntime, plan) {
|
|
|
1429
2180
|
plan.events.map((event) => keyedRowEventObject(event, parameters))
|
|
1430
2181
|
)
|
|
1431
2182
|
)
|
|
1432
|
-
)
|
|
2183
|
+
),
|
|
2184
|
+
...delegatedEvents ? [
|
|
2185
|
+
core.types.jsxAttribute(
|
|
2186
|
+
core.types.jsxIdentifier("delegateEvents"),
|
|
2187
|
+
core.types.jsxExpressionContainer(core.types.booleanLiteral(true))
|
|
2188
|
+
)
|
|
2189
|
+
] : []
|
|
1433
2190
|
] : [],
|
|
1434
2191
|
...plan.conditionals.length > 0 ? [
|
|
1435
2192
|
core.types.jsxAttribute(
|
|
@@ -1442,6 +2199,12 @@ function keyedRowsBoundary(blockRuntime, plan) {
|
|
|
1442
2199
|
)
|
|
1443
2200
|
)
|
|
1444
2201
|
)
|
|
2202
|
+
] : [],
|
|
2203
|
+
...plan.descriptorBlocks?.size ? [
|
|
2204
|
+
core.types.jsxAttribute(
|
|
2205
|
+
core.types.jsxIdentifier("hostBlocks"),
|
|
2206
|
+
core.types.jsxExpressionContainer(core.types.booleanLiteral(true))
|
|
2207
|
+
)
|
|
1445
2208
|
] : []
|
|
1446
2209
|
],
|
|
1447
2210
|
true
|
|
@@ -1451,7 +2214,7 @@ function keyedRowsBoundary(blockRuntime, plan) {
|
|
|
1451
2214
|
true
|
|
1452
2215
|
);
|
|
1453
2216
|
}
|
|
1454
|
-
function keyedRangeObject(range) {
|
|
2217
|
+
function keyedRangeObject(range, descriptorBlocks = /* @__PURE__ */ new Map()) {
|
|
1455
2218
|
const parameters = range.renderCallback.params.map(
|
|
1456
2219
|
(parameter) => core.types.cloneNode(parameter, true)
|
|
1457
2220
|
);
|
|
@@ -1466,7 +2229,7 @@ function keyedRangeObject(range) {
|
|
|
1466
2229
|
core.types.identifier("create"),
|
|
1467
2230
|
core.types.arrowFunctionExpression(
|
|
1468
2231
|
parameters.map((parameter) => core.types.cloneNode(parameter, true)),
|
|
1469
|
-
hostElementDescriptor(range.row)
|
|
2232
|
+
hostElementDescriptor(range.row, descriptorBlocks)
|
|
1470
2233
|
)
|
|
1471
2234
|
),
|
|
1472
2235
|
core.types.objectProperty(
|
|
@@ -1510,6 +2273,12 @@ function keyedRangesBoundary(blockRuntime, plan) {
|
|
|
1510
2273
|
core.types.jsxAttribute(
|
|
1511
2274
|
core.types.jsxIdentifier("trailing"),
|
|
1512
2275
|
core.types.jsxExpressionContainer(core.types.numericLiteral(plan.trailing))
|
|
2276
|
+
),
|
|
2277
|
+
core.types.jsxAttribute(
|
|
2278
|
+
core.types.jsxIdentifier("bindings"),
|
|
2279
|
+
core.types.jsxExpressionContainer(
|
|
2280
|
+
core.types.arrayExpression(plan.staticBindings.map(staticRangeBindingObject))
|
|
2281
|
+
)
|
|
1513
2282
|
)
|
|
1514
2283
|
],
|
|
1515
2284
|
true
|
|
@@ -1519,11 +2288,11 @@ function keyedRangesBoundary(blockRuntime, plan) {
|
|
|
1519
2288
|
true
|
|
1520
2289
|
);
|
|
1521
2290
|
}
|
|
1522
|
-
function hostConditionalBranchObject(branch, bindings) {
|
|
2291
|
+
function hostConditionalBranchObject(branch, bindings, descriptorBlocks = /* @__PURE__ */ new Map()) {
|
|
1523
2292
|
return core.types.objectExpression([
|
|
1524
2293
|
core.types.objectProperty(
|
|
1525
2294
|
core.types.identifier("create"),
|
|
1526
|
-
core.types.arrowFunctionExpression([], hostElementDescriptor(branch))
|
|
2295
|
+
core.types.arrowFunctionExpression([], hostElementDescriptor(branch, descriptorBlocks))
|
|
1527
2296
|
),
|
|
1528
2297
|
core.types.objectProperty(
|
|
1529
2298
|
core.types.identifier("bindings"),
|
|
@@ -1552,7 +2321,9 @@ function hostConditionalBoundary(blockRuntime, plan) {
|
|
|
1552
2321
|
attributes.push(
|
|
1553
2322
|
core.types.jsxAttribute(
|
|
1554
2323
|
core.types.jsxIdentifier("truthy"),
|
|
1555
|
-
core.types.jsxExpressionContainer(
|
|
2324
|
+
core.types.jsxExpressionContainer(
|
|
2325
|
+
hostConditionalBranchObject(plan.truthy, plan.truthyBindings, plan.descriptorBlocks)
|
|
2326
|
+
)
|
|
1556
2327
|
)
|
|
1557
2328
|
);
|
|
1558
2329
|
}
|
|
@@ -1560,13 +2331,15 @@ function hostConditionalBoundary(blockRuntime, plan) {
|
|
|
1560
2331
|
attributes.push(
|
|
1561
2332
|
core.types.jsxAttribute(
|
|
1562
2333
|
core.types.jsxIdentifier("falsy"),
|
|
1563
|
-
core.types.jsxExpressionContainer(
|
|
2334
|
+
core.types.jsxExpressionContainer(
|
|
2335
|
+
hostConditionalBranchObject(plan.falsy, plan.falsyBindings, plan.descriptorBlocks)
|
|
2336
|
+
)
|
|
1564
2337
|
)
|
|
1565
2338
|
);
|
|
1566
2339
|
}
|
|
1567
2340
|
return core.types.jsxElement(core.types.jsxOpeningElement(name, attributes, true), null, [], true);
|
|
1568
2341
|
}
|
|
1569
|
-
function conditionalRangeObject(range) {
|
|
2342
|
+
function conditionalRangeObject(range, descriptorBlocks = /* @__PURE__ */ new Map()) {
|
|
1570
2343
|
const properties = [
|
|
1571
2344
|
core.types.objectProperty(core.types.identifier("before"), core.types.numericLiteral(range.before)),
|
|
1572
2345
|
core.types.objectProperty(
|
|
@@ -1581,7 +2354,7 @@ function conditionalRangeObject(range) {
|
|
|
1581
2354
|
properties.push(
|
|
1582
2355
|
core.types.objectProperty(
|
|
1583
2356
|
core.types.identifier("truthy"),
|
|
1584
|
-
hostConditionalBranchObject(range.truthy, range.truthyBindings)
|
|
2357
|
+
hostConditionalBranchObject(range.truthy, range.truthyBindings, descriptorBlocks)
|
|
1585
2358
|
)
|
|
1586
2359
|
);
|
|
1587
2360
|
}
|
|
@@ -1589,12 +2362,78 @@ function conditionalRangeObject(range) {
|
|
|
1589
2362
|
properties.push(
|
|
1590
2363
|
core.types.objectProperty(
|
|
1591
2364
|
core.types.identifier("falsy"),
|
|
1592
|
-
hostConditionalBranchObject(range.falsy, range.falsyBindings)
|
|
2365
|
+
hostConditionalBranchObject(range.falsy, range.falsyBindings, descriptorBlocks)
|
|
1593
2366
|
)
|
|
1594
2367
|
);
|
|
1595
2368
|
}
|
|
1596
2369
|
return core.types.objectExpression(properties);
|
|
1597
2370
|
}
|
|
2371
|
+
function nestedHostBlockObject(plan, descriptorBlocks) {
|
|
2372
|
+
const kind = plan.kind === "nested-host-conditional-ranges" ? "conditional-ranges" : plan.kind === "nested-host-keyed-ranges" ? "keyed-ranges" : "mixed-ranges";
|
|
2373
|
+
return core.types.objectExpression([
|
|
2374
|
+
core.types.objectProperty(core.types.identifier("kind"), core.types.stringLiteral(kind)),
|
|
2375
|
+
core.types.objectProperty(core.types.identifier("id"), core.types.numericLiteral(plan.id)),
|
|
2376
|
+
core.types.objectProperty(
|
|
2377
|
+
core.types.identifier("ranges"),
|
|
2378
|
+
core.types.arrayExpression(
|
|
2379
|
+
plan.kind === "nested-host-conditional-ranges" ? plan.ranges.map((range) => conditionalRangeObject(range, descriptorBlocks)) : plan.kind === "nested-host-keyed-ranges" ? plan.ranges.map((range) => keyedRangeObject(range, descriptorBlocks)) : plan.ranges.map((range) => mixedRangeObject(range, descriptorBlocks))
|
|
2380
|
+
)
|
|
2381
|
+
),
|
|
2382
|
+
core.types.objectProperty(core.types.identifier("trailing"), core.types.numericLiteral(plan.trailing)),
|
|
2383
|
+
core.types.objectProperty(
|
|
2384
|
+
core.types.identifier("bindings"),
|
|
2385
|
+
core.types.arrayExpression(plan.staticBindings.map(staticRangeBindingObject))
|
|
2386
|
+
),
|
|
2387
|
+
...plan.kind === "nested-host-keyed-ranges" ? [core.types.objectProperty(core.types.identifier("staticChildrenOnly"), core.types.booleanLiteral(true))] : []
|
|
2388
|
+
]);
|
|
2389
|
+
}
|
|
2390
|
+
function mixedRangeObject(range, descriptorBlocks) {
|
|
2391
|
+
const value = range.rangeKind === "conditional" ? conditionalRangeObject(range, descriptorBlocks) : keyedRangeObject(range, descriptorBlocks);
|
|
2392
|
+
value.properties.unshift(
|
|
2393
|
+
core.types.objectProperty(core.types.identifier("kind"), core.types.stringLiteral(range.rangeKind))
|
|
2394
|
+
);
|
|
2395
|
+
return value;
|
|
2396
|
+
}
|
|
2397
|
+
function mixedRangesBoundary(blockRuntime, plan) {
|
|
2398
|
+
const name = core.types.jsxMemberExpression(
|
|
2399
|
+
core.types.jsxIdentifier(blockRuntime.name),
|
|
2400
|
+
core.types.jsxIdentifier("MixedRanges")
|
|
2401
|
+
);
|
|
2402
|
+
const source = core.types.cloneNode(plan.source, true);
|
|
2403
|
+
const rootRefIndex = source.openingElement.attributes.findIndex(
|
|
2404
|
+
(attribute) => core.types.isJSXAttribute(attribute) && jsxAttributeName(attribute) === "ref"
|
|
2405
|
+
);
|
|
2406
|
+
const rootRef = rootRefIndex >= 0 ? source.openingElement.attributes.splice(rootRefIndex, 1)[0] : void 0;
|
|
2407
|
+
const nestedPlan = {
|
|
2408
|
+
kind: "nested-host-mixed-ranges",
|
|
2409
|
+
id: plan.id,
|
|
2410
|
+
parent: plan.parent,
|
|
2411
|
+
dependencies: plan.dependencies,
|
|
2412
|
+
source: plan.source,
|
|
2413
|
+
ranges: plan.ranges,
|
|
2414
|
+
trailing: plan.trailing,
|
|
2415
|
+
staticBindings: plan.staticBindings
|
|
2416
|
+
};
|
|
2417
|
+
const descriptorBlocks = new Map(plan.descriptorBlocks);
|
|
2418
|
+
descriptorBlocks.set(plan.source, nestedPlan);
|
|
2419
|
+
const attributes = [
|
|
2420
|
+
core.types.jsxAttribute(core.types.jsxIdentifier("id"), core.types.jsxExpressionContainer(core.types.numericLiteral(plan.id))),
|
|
2421
|
+
core.types.jsxAttribute(
|
|
2422
|
+
core.types.jsxIdentifier("render"),
|
|
2423
|
+
core.types.jsxExpressionContainer(core.types.arrowFunctionExpression([], source))
|
|
2424
|
+
),
|
|
2425
|
+
core.types.jsxAttribute(
|
|
2426
|
+
core.types.jsxIdentifier("create"),
|
|
2427
|
+
core.types.jsxExpressionContainer(
|
|
2428
|
+
core.types.arrowFunctionExpression([], hostElementDescriptor(plan.source, descriptorBlocks))
|
|
2429
|
+
)
|
|
2430
|
+
)
|
|
2431
|
+
];
|
|
2432
|
+
if (rootRef?.value) {
|
|
2433
|
+
attributes.push(core.types.jsxAttribute(core.types.jsxIdentifier("rootRef"), core.types.cloneNode(rootRef.value, true)));
|
|
2434
|
+
}
|
|
2435
|
+
return core.types.jsxElement(core.types.jsxOpeningElement(name, attributes, true), null, [], true);
|
|
2436
|
+
}
|
|
1598
2437
|
function conditionalRangesBoundary(blockRuntime, plan) {
|
|
1599
2438
|
const name = core.types.jsxMemberExpression(
|
|
1600
2439
|
core.types.jsxIdentifier(blockRuntime.name),
|
|
@@ -1614,12 +2453,20 @@ function conditionalRangesBoundary(blockRuntime, plan) {
|
|
|
1614
2453
|
core.types.jsxAttribute(
|
|
1615
2454
|
core.types.jsxIdentifier("ranges"),
|
|
1616
2455
|
core.types.jsxExpressionContainer(
|
|
1617
|
-
core.types.arrayExpression(
|
|
2456
|
+
core.types.arrayExpression(
|
|
2457
|
+
plan.ranges.map((range) => conditionalRangeObject(range, plan.descriptorBlocks))
|
|
2458
|
+
)
|
|
1618
2459
|
)
|
|
1619
2460
|
),
|
|
1620
2461
|
core.types.jsxAttribute(
|
|
1621
2462
|
core.types.jsxIdentifier("trailing"),
|
|
1622
2463
|
core.types.jsxExpressionContainer(core.types.numericLiteral(plan.trailing))
|
|
2464
|
+
),
|
|
2465
|
+
core.types.jsxAttribute(
|
|
2466
|
+
core.types.jsxIdentifier("bindings"),
|
|
2467
|
+
core.types.jsxExpressionContainer(
|
|
2468
|
+
core.types.arrayExpression(plan.staticBindings.map(staticRangeBindingObject))
|
|
2469
|
+
)
|
|
1623
2470
|
)
|
|
1624
2471
|
];
|
|
1625
2472
|
if (rootRef?.value) {
|
|
@@ -1792,6 +2639,41 @@ function analyzeComposableBlocks(root, statesByValue, safeGlobals, listNames, al
|
|
|
1792
2639
|
}
|
|
1793
2640
|
if (core.types.isJSXElement(child)) {
|
|
1794
2641
|
if (isHostElement(child)) {
|
|
2642
|
+
const mixedRangeStart = nextId;
|
|
2643
|
+
const mixedRangeId = nextId++;
|
|
2644
|
+
const mixedRanges = insideConditional ? void 0 : analyzeMixedRangesContainer(
|
|
2645
|
+
child,
|
|
2646
|
+
statesByValue,
|
|
2647
|
+
safeGlobals,
|
|
2648
|
+
listNames,
|
|
2649
|
+
mixedRangeId,
|
|
2650
|
+
() => nextId++
|
|
2651
|
+
);
|
|
2652
|
+
if (mixedRanges) {
|
|
2653
|
+
plans.push({
|
|
2654
|
+
kind: "mixed-ranges",
|
|
2655
|
+
id: mixedRangeId,
|
|
2656
|
+
parent,
|
|
2657
|
+
dependencies: mixedRanges.dependencies,
|
|
2658
|
+
source: child,
|
|
2659
|
+
ranges: mixedRanges.ranges,
|
|
2660
|
+
trailing: mixedRanges.trailing,
|
|
2661
|
+
staticBindings: mixedRanges.staticBindings,
|
|
2662
|
+
descriptorBlocks: mixedRanges.descriptorBlocks
|
|
2663
|
+
});
|
|
2664
|
+
plans.push(...mixedRanges.nestedPlans);
|
|
2665
|
+
for (const range of mixedRanges.ranges) {
|
|
2666
|
+
if (range.rangeKind === "conditional") {
|
|
2667
|
+
conditionalExpressions.add(range.source);
|
|
2668
|
+
} else if (core.types.isJSXElement(range.source)) {
|
|
2669
|
+
ownedElements.add(range.source);
|
|
2670
|
+
} else {
|
|
2671
|
+
keyedExpressions.add(range.source);
|
|
2672
|
+
}
|
|
2673
|
+
}
|
|
2674
|
+
continue;
|
|
2675
|
+
}
|
|
2676
|
+
nextId = mixedRangeStart;
|
|
1795
2677
|
const keyedRanges = insideConditional ? void 0 : analyzeKeyedRangesContainer(child, statesByValue, safeGlobals, listNames);
|
|
1796
2678
|
if (keyedRanges) {
|
|
1797
2679
|
plans.push({
|
|
@@ -1801,7 +2683,8 @@ function analyzeComposableBlocks(root, statesByValue, safeGlobals, listNames, al
|
|
|
1801
2683
|
dependencies: keyedRanges.dependencies,
|
|
1802
2684
|
source: child,
|
|
1803
2685
|
ranges: keyedRanges.ranges,
|
|
1804
|
-
trailing: keyedRanges.trailing
|
|
2686
|
+
trailing: keyedRanges.trailing,
|
|
2687
|
+
staticBindings: keyedRanges.staticBindings
|
|
1805
2688
|
});
|
|
1806
2689
|
for (const range of keyedRanges.ranges) {
|
|
1807
2690
|
if (core.types.isJSXElement(range.source)) ownedElements.add(range.source);
|
|
@@ -1809,58 +2692,102 @@ function analyzeComposableBlocks(root, statesByValue, safeGlobals, listNames, al
|
|
|
1809
2692
|
}
|
|
1810
2693
|
continue;
|
|
1811
2694
|
}
|
|
1812
|
-
const
|
|
2695
|
+
const conditionalRangeStart = nextId;
|
|
2696
|
+
const conditionalRangeId = nextId++;
|
|
2697
|
+
const conditionalRanges = insideConditional ? void 0 : analyzeConditionalRangesContainer(
|
|
2698
|
+
child,
|
|
2699
|
+
statesByValue,
|
|
2700
|
+
safeGlobals,
|
|
2701
|
+
false,
|
|
2702
|
+
listNames,
|
|
2703
|
+
conditionalRangeId,
|
|
2704
|
+
() => nextId++
|
|
2705
|
+
);
|
|
1813
2706
|
if (conditionalRanges) {
|
|
1814
2707
|
plans.push({
|
|
1815
2708
|
kind: "conditional-ranges",
|
|
1816
|
-
id:
|
|
2709
|
+
id: conditionalRangeId,
|
|
1817
2710
|
parent,
|
|
1818
2711
|
dependencies: conditionalRanges.dependencies,
|
|
1819
2712
|
source: child,
|
|
1820
2713
|
ranges: conditionalRanges.ranges,
|
|
1821
|
-
trailing: conditionalRanges.trailing
|
|
2714
|
+
trailing: conditionalRanges.trailing,
|
|
2715
|
+
staticBindings: conditionalRanges.staticBindings,
|
|
2716
|
+
descriptorBlocks: conditionalRanges.descriptorBlocks
|
|
1822
2717
|
});
|
|
2718
|
+
plans.push(...conditionalRanges.nestedPlans || []);
|
|
1823
2719
|
for (const range of conditionalRanges.ranges) {
|
|
1824
2720
|
conditionalExpressions.add(range.source);
|
|
1825
2721
|
}
|
|
1826
2722
|
continue;
|
|
1827
2723
|
}
|
|
2724
|
+
nextId = conditionalRangeStart;
|
|
2725
|
+
const hostConditionalStart = nextId;
|
|
2726
|
+
const hostConditionalId = nextId++;
|
|
1828
2727
|
const hostConditional = analyzeHostConditionalContainer(
|
|
1829
2728
|
child,
|
|
1830
2729
|
statesByValue,
|
|
1831
|
-
safeGlobals
|
|
2730
|
+
safeGlobals,
|
|
2731
|
+
listNames,
|
|
2732
|
+
hostConditionalId,
|
|
2733
|
+
() => nextId++
|
|
1832
2734
|
);
|
|
1833
2735
|
if (hostConditional) {
|
|
1834
2736
|
plans.push({
|
|
1835
2737
|
kind: "host-conditional",
|
|
1836
|
-
id:
|
|
2738
|
+
id: hostConditionalId,
|
|
1837
2739
|
parent,
|
|
1838
2740
|
source: child,
|
|
1839
2741
|
...hostConditional
|
|
1840
2742
|
});
|
|
2743
|
+
plans.push(...hostConditional.nestedPlans || []);
|
|
1841
2744
|
ownedElements.add(child);
|
|
1842
2745
|
continue;
|
|
1843
2746
|
}
|
|
2747
|
+
nextId = hostConditionalStart;
|
|
2748
|
+
const keyedRowsStart = nextId;
|
|
2749
|
+
const keyedRowsId = nextId++;
|
|
1844
2750
|
const keyedRows = analyzeKeyedRowsContainer(child, statesByValue, safeGlobals, listNames);
|
|
1845
2751
|
if (keyedRows) {
|
|
2752
|
+
const nestedStart = nextId;
|
|
2753
|
+
const hostBlocks = analyzeCompilerOwnedKeyedRowHostBlocks(
|
|
2754
|
+
keyedRows,
|
|
2755
|
+
statesByValue,
|
|
2756
|
+
safeGlobals,
|
|
2757
|
+
listNames,
|
|
2758
|
+
keyedRowsId,
|
|
2759
|
+
() => nextId++
|
|
2760
|
+
);
|
|
2761
|
+
if (!hostBlocks) nextId = nestedStart;
|
|
2762
|
+
if (keyedRows.rowReason && !hostBlocks) {
|
|
2763
|
+
nextId = keyedRowsStart;
|
|
2764
|
+
const nested2 = visitHost(child, parent, insideConditional);
|
|
2765
|
+
if (nested2.reason) return { dependencies, reason: nested2.reason };
|
|
2766
|
+
mergeDependencies(dependencies, nested2.dependencies);
|
|
2767
|
+
continue;
|
|
2768
|
+
}
|
|
1846
2769
|
plans.push({
|
|
1847
2770
|
kind: "keyed-rows",
|
|
1848
|
-
id:
|
|
2771
|
+
id: keyedRowsId,
|
|
1849
2772
|
parent,
|
|
1850
2773
|
dependencies: keyedRows.dependencies,
|
|
1851
2774
|
source: child,
|
|
1852
2775
|
collection: keyedRows.collection,
|
|
2776
|
+
structureDependencies: keyedRows.structureDependencies,
|
|
1853
2777
|
keyCallback: keyedRows.keyCallback,
|
|
1854
2778
|
renderCallback: keyedRows.renderCallback,
|
|
1855
|
-
row: keyedRows.row,
|
|
1856
|
-
bindings: keyedRows.bindings,
|
|
2779
|
+
row: hostBlocks?.row || keyedRows.row,
|
|
2780
|
+
bindings: hostBlocks?.bindings || keyedRows.bindings,
|
|
1857
2781
|
events: keyedRows.events,
|
|
1858
|
-
conditionals: keyedRows.conditionals,
|
|
2782
|
+
conditionals: hostBlocks ? [] : keyedRows.conditionals,
|
|
2783
|
+
descriptorBlocks: hostBlocks?.descriptorBlocks,
|
|
1859
2784
|
syntax: keyedRows.syntax
|
|
1860
2785
|
});
|
|
2786
|
+
plans.push(...hostBlocks?.nestedPlans || []);
|
|
1861
2787
|
ownedElements.add(child);
|
|
1862
2788
|
continue;
|
|
1863
2789
|
}
|
|
2790
|
+
nextId = keyedRowsStart;
|
|
1864
2791
|
const nested = visitHost(child, parent, insideConditional);
|
|
1865
2792
|
if (nested.reason) return { dependencies, reason: nested.reason };
|
|
1866
2793
|
mergeDependencies(dependencies, nested.dependencies);
|
|
@@ -1957,6 +2884,46 @@ function analyzeComposableBlocks(root, statesByValue, safeGlobals, listNames, al
|
|
|
1957
2884
|
}
|
|
1958
2885
|
return { dependencies };
|
|
1959
2886
|
};
|
|
2887
|
+
const rootMixedRangeStart = nextId;
|
|
2888
|
+
const rootMixedRangeId = nextId++;
|
|
2889
|
+
const rootMixedRanges = analyzeMixedRangesContainer(
|
|
2890
|
+
root,
|
|
2891
|
+
statesByValue,
|
|
2892
|
+
safeGlobals,
|
|
2893
|
+
listNames,
|
|
2894
|
+
rootMixedRangeId,
|
|
2895
|
+
() => nextId++
|
|
2896
|
+
);
|
|
2897
|
+
if (rootMixedRanges) {
|
|
2898
|
+
plans.push({
|
|
2899
|
+
kind: "mixed-ranges",
|
|
2900
|
+
id: rootMixedRangeId,
|
|
2901
|
+
dependencies: rootMixedRanges.dependencies,
|
|
2902
|
+
source: root,
|
|
2903
|
+
ranges: rootMixedRanges.ranges,
|
|
2904
|
+
trailing: rootMixedRanges.trailing,
|
|
2905
|
+
staticBindings: rootMixedRanges.staticBindings,
|
|
2906
|
+
descriptorBlocks: rootMixedRanges.descriptorBlocks
|
|
2907
|
+
});
|
|
2908
|
+
plans.push(...rootMixedRanges.nestedPlans);
|
|
2909
|
+
for (const range of rootMixedRanges.ranges) {
|
|
2910
|
+
if (range.rangeKind === "conditional") {
|
|
2911
|
+
conditionalExpressions.add(range.source);
|
|
2912
|
+
} else if (core.types.isJSXElement(range.source)) {
|
|
2913
|
+
ownedElements.add(range.source);
|
|
2914
|
+
} else {
|
|
2915
|
+
keyedExpressions.add(range.source);
|
|
2916
|
+
}
|
|
2917
|
+
}
|
|
2918
|
+
return {
|
|
2919
|
+
plans,
|
|
2920
|
+
componentElements,
|
|
2921
|
+
conditionalExpressions,
|
|
2922
|
+
ownedElements,
|
|
2923
|
+
keyedExpressions
|
|
2924
|
+
};
|
|
2925
|
+
}
|
|
2926
|
+
nextId = rootMixedRangeStart;
|
|
1960
2927
|
const rootRanges = analyzeKeyedRangesContainer(root, statesByValue, safeGlobals, listNames, true);
|
|
1961
2928
|
if (rootRanges) {
|
|
1962
2929
|
plans.push({
|
|
@@ -1965,7 +2932,8 @@ function analyzeComposableBlocks(root, statesByValue, safeGlobals, listNames, al
|
|
|
1965
2932
|
dependencies: rootRanges.dependencies,
|
|
1966
2933
|
source: root,
|
|
1967
2934
|
ranges: rootRanges.ranges,
|
|
1968
|
-
trailing: rootRanges.trailing
|
|
2935
|
+
trailing: rootRanges.trailing,
|
|
2936
|
+
staticBindings: rootRanges.staticBindings
|
|
1969
2937
|
});
|
|
1970
2938
|
for (const range of rootRanges.ranges) {
|
|
1971
2939
|
if (core.types.isJSXElement(range.source)) ownedElements.add(range.source);
|
|
@@ -1979,21 +2947,29 @@ function analyzeComposableBlocks(root, statesByValue, safeGlobals, listNames, al
|
|
|
1979
2947
|
keyedExpressions
|
|
1980
2948
|
};
|
|
1981
2949
|
}
|
|
2950
|
+
const rootConditionalRangeStart = nextId;
|
|
2951
|
+
const rootConditionalRangeId = nextId++;
|
|
1982
2952
|
const rootConditionalRanges = analyzeConditionalRangesContainer(
|
|
1983
2953
|
root,
|
|
1984
2954
|
statesByValue,
|
|
1985
2955
|
safeGlobals,
|
|
1986
|
-
true
|
|
2956
|
+
true,
|
|
2957
|
+
listNames,
|
|
2958
|
+
rootConditionalRangeId,
|
|
2959
|
+
() => nextId++
|
|
1987
2960
|
);
|
|
1988
2961
|
if (rootConditionalRanges) {
|
|
1989
2962
|
plans.push({
|
|
1990
2963
|
kind: "conditional-ranges",
|
|
1991
|
-
id:
|
|
2964
|
+
id: rootConditionalRangeId,
|
|
1992
2965
|
dependencies: rootConditionalRanges.dependencies,
|
|
1993
2966
|
source: root,
|
|
1994
2967
|
ranges: rootConditionalRanges.ranges,
|
|
1995
|
-
trailing: rootConditionalRanges.trailing
|
|
2968
|
+
trailing: rootConditionalRanges.trailing,
|
|
2969
|
+
staticBindings: rootConditionalRanges.staticBindings,
|
|
2970
|
+
descriptorBlocks: rootConditionalRanges.descriptorBlocks
|
|
1996
2971
|
});
|
|
2972
|
+
plans.push(...rootConditionalRanges.nestedPlans || []);
|
|
1997
2973
|
for (const range of rootConditionalRanges.ranges) {
|
|
1998
2974
|
conditionalExpressions.add(range.source);
|
|
1999
2975
|
}
|
|
@@ -2005,6 +2981,7 @@ function analyzeComposableBlocks(root, statesByValue, safeGlobals, listNames, al
|
|
|
2005
2981
|
keyedExpressions
|
|
2006
2982
|
};
|
|
2007
2983
|
}
|
|
2984
|
+
nextId = rootConditionalRangeStart;
|
|
2008
2985
|
const result = visitHost(root, void 0, false);
|
|
2009
2986
|
if (result.reason) return { reason: result.reason };
|
|
2010
2987
|
return {
|
|
@@ -2042,6 +3019,9 @@ function lowerComposableBlocks(root, plans, blockRuntime, listNames) {
|
|
|
2042
3019
|
plans.map((plan) => [plan.source, plan])
|
|
2043
3020
|
);
|
|
2044
3021
|
const rootPlan = planBySource.get(root);
|
|
3022
|
+
if (rootPlan?.kind === "mixed-ranges") {
|
|
3023
|
+
return mixedRangesBoundary(blockRuntime, rootPlan);
|
|
3024
|
+
}
|
|
2045
3025
|
if (rootPlan?.kind === "keyed-ranges") {
|
|
2046
3026
|
return keyedRangesBoundary(blockRuntime, rootPlan);
|
|
2047
3027
|
}
|
|
@@ -2055,6 +3035,9 @@ function lowerComposableBlocks(root, plans, blockRuntime, listNames) {
|
|
|
2055
3035
|
if (plan2?.kind === "host-conditional") {
|
|
2056
3036
|
return hostConditionalBoundary(blockRuntime, plan2);
|
|
2057
3037
|
}
|
|
3038
|
+
if (plan2?.kind === "mixed-ranges") {
|
|
3039
|
+
return mixedRangesBoundary(blockRuntime, plan2);
|
|
3040
|
+
}
|
|
2058
3041
|
if (plan2?.kind === "keyed-rows") {
|
|
2059
3042
|
return keyedRowsBoundary(blockRuntime, plan2);
|
|
2060
3043
|
}
|
|
@@ -2104,6 +3087,31 @@ function assignStableBindingTargets(bindings) {
|
|
|
2104
3087
|
binding.target = target;
|
|
2105
3088
|
}
|
|
2106
3089
|
}
|
|
3090
|
+
function markShortCircuitBindings(bindings) {
|
|
3091
|
+
for (const binding of bindings) {
|
|
3092
|
+
if (binding.kind === "block" || binding.dependencies.length < 2) continue;
|
|
3093
|
+
let shortCircuits = false;
|
|
3094
|
+
core.traverse(expressionFile(core.types.cloneNode(binding.value, true)), {
|
|
3095
|
+
ConditionalExpression(path) {
|
|
3096
|
+
shortCircuits = true;
|
|
3097
|
+
path.stop();
|
|
3098
|
+
},
|
|
3099
|
+
LogicalExpression(path) {
|
|
3100
|
+
shortCircuits = true;
|
|
3101
|
+
path.stop();
|
|
3102
|
+
},
|
|
3103
|
+
OptionalCallExpression(path) {
|
|
3104
|
+
shortCircuits = true;
|
|
3105
|
+
path.stop();
|
|
3106
|
+
},
|
|
3107
|
+
OptionalMemberExpression(path) {
|
|
3108
|
+
shortCircuits = true;
|
|
3109
|
+
path.stop();
|
|
3110
|
+
}
|
|
3111
|
+
});
|
|
3112
|
+
if (shortCircuits) binding.tracking = "dynamic";
|
|
3113
|
+
}
|
|
3114
|
+
}
|
|
2107
3115
|
function lowerStableBindingTargets(root, bindings, blockRuntime, ownedElements) {
|
|
2108
3116
|
const targetByPath = /* @__PURE__ */ new Map();
|
|
2109
3117
|
for (const binding of bindings) {
|
|
@@ -2373,6 +3381,9 @@ function bindingObject(binding, propsParameter, stateParameter, statesByValue, s
|
|
|
2373
3381
|
core.types.objectProperty(core.types.identifier("target"), core.types.numericLiteral(binding.target))
|
|
2374
3382
|
);
|
|
2375
3383
|
}
|
|
3384
|
+
if (binding.tracking) {
|
|
3385
|
+
properties.push(core.types.objectProperty(core.types.identifier("tracking"), core.types.stringLiteral(binding.tracking)));
|
|
3386
|
+
}
|
|
2376
3387
|
if (binding.name)
|
|
2377
3388
|
properties.push(core.types.objectProperty(core.types.identifier("name"), core.types.stringLiteral(binding.name)));
|
|
2378
3389
|
properties.push(
|
|
@@ -2391,7 +3402,7 @@ function wrapperElement(definitionIdentifier, props) {
|
|
|
2391
3402
|
const attributes = props ? [core.types.jsxSpreadAttribute(core.types.cloneNode(props))] : [];
|
|
2392
3403
|
return core.types.jsxElement(core.types.jsxOpeningElement(name, attributes, true), null, [], true);
|
|
2393
3404
|
}
|
|
2394
|
-
function compileCandidate(candidate, createComponentIdentifier, useStateNames, reactNames, listNames, moduleId) {
|
|
3405
|
+
function compileCandidate(candidate, createComponentIdentifier, useStateNames, reactNames, listNames, moduleId, reactivity) {
|
|
2395
3406
|
const { path, name, statementPath } = candidate;
|
|
2396
3407
|
if (path.node.async || path.node.generator)
|
|
2397
3408
|
return "async and generator components are not supported";
|
|
@@ -2508,8 +3519,34 @@ function compileCandidate(candidate, createComponentIdentifier, useStateNames, r
|
|
|
2508
3519
|
);
|
|
2509
3520
|
const setterReason = validateSetterUsage(expandedRoot, statesBySetter);
|
|
2510
3521
|
if (setterReason) return setterReason;
|
|
3522
|
+
const referencedPropNames = collectDestructuredPropNames(
|
|
3523
|
+
expandedRoot,
|
|
3524
|
+
propsPlan.destructuredNames,
|
|
3525
|
+
propsPlan.definitionParameter
|
|
3526
|
+
);
|
|
3527
|
+
let propBindings = referencedPropNames.has("children") ? [] : [...propsPlan.destructuredNames].filter((propName) => referencedPropNames.has(propName)).map(
|
|
3528
|
+
(localName, propIndex) => ({
|
|
3529
|
+
localName,
|
|
3530
|
+
valueName: path.scope.generateUidIdentifier(`farmProp${propIndex}`).name,
|
|
3531
|
+
index: states.length + propIndex
|
|
3532
|
+
})
|
|
3533
|
+
);
|
|
3534
|
+
const propBindingsByName = new Map(propBindings.map((binding) => [binding.localName, binding]));
|
|
3535
|
+
let reactiveByValue = new Map(statesByValue);
|
|
3536
|
+
for (const binding of propBindings) {
|
|
3537
|
+
reactiveByValue.set(binding.valueName, {
|
|
3538
|
+
valueName: binding.valueName,
|
|
3539
|
+
setterName: "",
|
|
3540
|
+
index: binding.index
|
|
3541
|
+
});
|
|
3542
|
+
}
|
|
3543
|
+
let expandedReactiveRoot = rewriteTrackedPropAccess(
|
|
3544
|
+
expandedRoot,
|
|
3545
|
+
propsPlan.definitionParameter,
|
|
3546
|
+
propBindingsByName
|
|
3547
|
+
);
|
|
2511
3548
|
const referencedComponentNames = /* @__PURE__ */ new Set();
|
|
2512
|
-
core.traverse(expressionFile(core.types.cloneNode(
|
|
3549
|
+
core.traverse(expressionFile(core.types.cloneNode(expandedReactiveRoot, true)), {
|
|
2513
3550
|
JSXOpeningElement(componentPath) {
|
|
2514
3551
|
const componentName = componentPath.node.name;
|
|
2515
3552
|
if (core.types.isJSXIdentifier(componentName) && isComponentName(componentName.name)) {
|
|
@@ -2526,32 +3563,54 @@ function compileCandidate(candidate, createComponentIdentifier, useStateNames, r
|
|
|
2526
3563
|
);
|
|
2527
3564
|
})
|
|
2528
3565
|
);
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
3566
|
+
let blockAnalysis = analyzeComposableBlocks(
|
|
3567
|
+
expandedReactiveRoot,
|
|
3568
|
+
reactiveByValue,
|
|
2532
3569
|
safeGlobals,
|
|
2533
3570
|
listNames,
|
|
2534
3571
|
allowedComponentNames
|
|
2535
3572
|
);
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
expandedRoot,
|
|
2540
|
-
statesByValue,
|
|
3573
|
+
let analysis = analyzeHostTree(
|
|
3574
|
+
expandedReactiveRoot,
|
|
3575
|
+
reactiveByValue,
|
|
2541
3576
|
safeGlobals,
|
|
2542
3577
|
blockAnalysis.conditionalExpressions || /* @__PURE__ */ new Set(),
|
|
2543
3578
|
blockAnalysis.keyedExpressions || /* @__PURE__ */ new Set(),
|
|
2544
3579
|
blockAnalysis.ownedElements || /* @__PURE__ */ new Set(),
|
|
2545
3580
|
blockAnalysis.componentElements || /* @__PURE__ */ new Set()
|
|
2546
3581
|
);
|
|
3582
|
+
if (propBindings.length > 0 && (blockAnalysis.reason || analysis.reason)) {
|
|
3583
|
+
propBindings = [];
|
|
3584
|
+
reactiveByValue = new Map(statesByValue);
|
|
3585
|
+
expandedReactiveRoot = core.types.cloneNode(expandedRoot, true);
|
|
3586
|
+
blockAnalysis = analyzeComposableBlocks(
|
|
3587
|
+
expandedReactiveRoot,
|
|
3588
|
+
reactiveByValue,
|
|
3589
|
+
safeGlobals,
|
|
3590
|
+
listNames,
|
|
3591
|
+
allowedComponentNames
|
|
3592
|
+
);
|
|
3593
|
+
analysis = analyzeHostTree(
|
|
3594
|
+
expandedReactiveRoot,
|
|
3595
|
+
reactiveByValue,
|
|
3596
|
+
safeGlobals,
|
|
3597
|
+
blockAnalysis.conditionalExpressions || /* @__PURE__ */ new Set(),
|
|
3598
|
+
blockAnalysis.keyedExpressions || /* @__PURE__ */ new Set(),
|
|
3599
|
+
blockAnalysis.ownedElements || /* @__PURE__ */ new Set(),
|
|
3600
|
+
blockAnalysis.componentElements || /* @__PURE__ */ new Set()
|
|
3601
|
+
);
|
|
3602
|
+
}
|
|
3603
|
+
if (blockAnalysis.reason) return blockAnalysis.reason;
|
|
2547
3604
|
if (analysis.reason) return analysis.reason;
|
|
3605
|
+
const blockPlans = blockAnalysis.plans || [];
|
|
3606
|
+
markShortCircuitBindings(analysis.bindings || []);
|
|
2548
3607
|
assignStableBindingTargets(analysis.bindings || []);
|
|
2549
3608
|
const stateParameter = path.scope.generateUidIdentifier("farmState");
|
|
2550
3609
|
const blockParameter = path.scope.generateUidIdentifier("farmBlocks");
|
|
2551
3610
|
const definitionIdentifier = path.scope.generateUidIdentifier(`${name}Compiled`);
|
|
2552
3611
|
const propsParameter = propsPlan.definitionParameter;
|
|
2553
3612
|
const rootWithTargets = lowerStableBindingTargets(
|
|
2554
|
-
|
|
3613
|
+
expandedReactiveRoot,
|
|
2555
3614
|
analysis.bindings || [],
|
|
2556
3615
|
blockParameter,
|
|
2557
3616
|
blockAnalysis.ownedElements || /* @__PURE__ */ new Set()
|
|
@@ -2565,12 +3624,13 @@ function compileCandidate(candidate, createComponentIdentifier, useStateNames, r
|
|
|
2565
3624
|
const rewrittenRoot = rewriteStateAccess(
|
|
2566
3625
|
rootWithBlocks,
|
|
2567
3626
|
stateParameter,
|
|
2568
|
-
|
|
3627
|
+
reactiveByValue,
|
|
2569
3628
|
statesBySetter
|
|
2570
3629
|
);
|
|
2571
3630
|
const definition = core.types.callExpression(core.types.cloneNode(createComponentIdentifier), [
|
|
2572
3631
|
core.types.objectExpression([
|
|
2573
3632
|
core.types.objectProperty(core.types.identifier("displayName"), core.types.stringLiteral(name)),
|
|
3633
|
+
core.types.objectProperty(core.types.identifier("reactivity"), core.types.stringLiteral(reactivity)),
|
|
2574
3634
|
core.types.spreadElement(
|
|
2575
3635
|
core.types.conditionalExpression(
|
|
2576
3636
|
core.types.memberExpression(
|
|
@@ -2581,7 +3641,9 @@ function compileCandidate(candidate, createComponentIdentifier, useStateNames, r
|
|
|
2581
3641
|
core.types.objectProperty(core.types.identifier("hmrId"), core.types.stringLiteral(`${moduleId}#${name}`)),
|
|
2582
3642
|
core.types.objectProperty(
|
|
2583
3643
|
core.types.identifier("stateSignature"),
|
|
2584
|
-
core.types.stringLiteral(
|
|
3644
|
+
core.types.stringLiteral(
|
|
3645
|
+
propBindings.length === 0 ? String(states.length) : `${states.length}:${propBindings.map((binding) => binding.localName).join(",")}`
|
|
3646
|
+
)
|
|
2585
3647
|
)
|
|
2586
3648
|
]),
|
|
2587
3649
|
core.types.objectExpression([])
|
|
@@ -2604,6 +3666,22 @@ function compileCandidate(candidate, createComponentIdentifier, useStateNames, r
|
|
|
2604
3666
|
)
|
|
2605
3667
|
)
|
|
2606
3668
|
),
|
|
3669
|
+
...propBindings.length > 0 ? [
|
|
3670
|
+
core.types.objectProperty(
|
|
3671
|
+
core.types.identifier("readProps"),
|
|
3672
|
+
core.types.arrowFunctionExpression(
|
|
3673
|
+
[core.types.cloneNode(propsParameter)],
|
|
3674
|
+
core.types.arrayExpression(
|
|
3675
|
+
propBindings.map(
|
|
3676
|
+
(binding) => core.types.memberExpression(
|
|
3677
|
+
core.types.cloneNode(propsParameter),
|
|
3678
|
+
core.types.identifier(binding.localName)
|
|
3679
|
+
)
|
|
3680
|
+
)
|
|
3681
|
+
)
|
|
3682
|
+
)
|
|
3683
|
+
)
|
|
3684
|
+
] : [],
|
|
2607
3685
|
core.types.objectProperty(
|
|
2608
3686
|
core.types.identifier("render"),
|
|
2609
3687
|
core.types.arrowFunctionExpression(
|
|
@@ -2623,7 +3701,7 @@ function compileCandidate(candidate, createComponentIdentifier, useStateNames, r
|
|
|
2623
3701
|
dependencies: block.dependencies
|
|
2624
3702
|
}))
|
|
2625
3703
|
].map(
|
|
2626
|
-
(binding) => bindingObject(binding, propsParameter, stateParameter,
|
|
3704
|
+
(binding) => bindingObject(binding, propsParameter, stateParameter, reactiveByValue, statesBySetter)
|
|
2627
3705
|
)
|
|
2628
3706
|
)
|
|
2629
3707
|
)
|
|
@@ -2717,7 +3795,8 @@ async function compileReactModule(code, id, options) {
|
|
|
2717
3795
|
useStateNames,
|
|
2718
3796
|
reactNames,
|
|
2719
3797
|
listNames,
|
|
2720
|
-
id
|
|
3798
|
+
id,
|
|
3799
|
+
options.reactivity
|
|
2721
3800
|
);
|
|
2722
3801
|
if (reason) {
|
|
2723
3802
|
diagnostics.push({
|
|
@@ -2844,6 +3923,10 @@ function normalizeReactCompilerOptions(value) {
|
|
|
2844
3923
|
if (!["fallback", "warn", "error"].includes(onUnsupported)) {
|
|
2845
3924
|
throw new TypeError(`Unknown unsupported-component behavior: ${String(onUnsupported)}`);
|
|
2846
3925
|
}
|
|
3926
|
+
const reactivity = options.reactivity || "hybrid";
|
|
3927
|
+
if (reactivity !== "static" && reactivity !== "hybrid") {
|
|
3928
|
+
throw new TypeError(`Unknown React compiler reactivity mode: ${String(reactivity)}`);
|
|
3929
|
+
}
|
|
2847
3930
|
if (options.report !== void 0 && typeof options.report !== "boolean") {
|
|
2848
3931
|
throw new TypeError("The React compiler report option must be a boolean.");
|
|
2849
3932
|
}
|
|
@@ -2854,7 +3937,7 @@ function normalizeReactCompilerOptions(value) {
|
|
|
2854
3937
|
}
|
|
2855
3938
|
const reportFile = normalizeCompilerReportFile(options.reportFile);
|
|
2856
3939
|
const report = options.report === true || options.reportFile !== void 0;
|
|
2857
|
-
return { mode, directive, onUnsupported, report, reportFile };
|
|
3940
|
+
return { mode, directive, onUnsupported, reactivity, report, reportFile };
|
|
2858
3941
|
}
|
|
2859
3942
|
|
|
2860
3943
|
// src/vite.ts
|
|
@@ -2870,7 +3953,7 @@ function readCompilerOptions(rendererOptions) {
|
|
|
2870
3953
|
);
|
|
2871
3954
|
}
|
|
2872
3955
|
const normalized = compiler;
|
|
2873
|
-
if ((normalized.mode === "infer" || normalized.mode === "annotation") && typeof normalized.directive === "string" && (normalized.onUnsupported === "fallback" || normalized.onUnsupported === "warn" || normalized.onUnsupported === "error")) {
|
|
3956
|
+
if ((normalized.mode === "infer" || normalized.mode === "annotation") && typeof normalized.directive === "string" && (normalized.reactivity === "static" || normalized.reactivity === "hybrid") && (normalized.onUnsupported === "fallback" || normalized.onUnsupported === "warn" || normalized.onUnsupported === "error")) {
|
|
2874
3957
|
return normalized;
|
|
2875
3958
|
}
|
|
2876
3959
|
return normalizeReactCompilerOptions(compiler);
|