babel-plugin-essor 0.0.16 → 0.0.17-beta.2

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.
Files changed (3) hide show
  1. package/dist/index.cjs +407 -225
  2. package/dist/index.js +407 -225
  3. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -59,7 +59,6 @@ var IMPORTS_MAPS = [
59
59
  "reactive",
60
60
  "memoEffect",
61
61
  "omitProps",
62
- "resolveDefaultProps",
63
62
  // component
64
63
  "createComponent",
65
64
  "Fragment",
@@ -81,9 +80,7 @@ var IMPORTS_MAPS = [
81
80
  "addEventListener",
82
81
  // rendering related
83
82
  "render",
84
- "toRawHtmlString",
85
- "toEscapedHtmlString",
86
- "markAsRawHtml",
83
+ "escape",
87
84
  "escapeHTML",
88
85
  "getHydrationKey",
89
86
  "hydrationAnchor",
@@ -111,31 +108,13 @@ var HYDRATE_IMPORT_REMAPS = {
111
108
  patchAttr: "patchAttrHydrate",
112
109
  patchStyle: "patchStyleHydrate"
113
110
  };
114
- var SERVER_ONLY_NAMES = [
115
- "render",
116
- "toRawHtmlString",
117
- "toEscapedHtmlString",
118
- "markAsRawHtml",
119
- "escapeHTML",
120
- "Fragment",
121
- "Portal",
122
- "Suspense",
123
- "getHydrationKey",
124
- "ssrAttr",
125
- "ssrBind",
126
- "ssrClass",
127
- "ssrSelected",
128
- "ssrStyle",
129
- "ssrSpread",
130
- "ssrTextValue",
131
- "createComponent",
132
- "patchAttr"
133
- ];
134
- var _remaps = SERVER_IMPORT_REMAPS;
135
- var SERVER_EXPORTS = new Set(SERVER_ONLY_NAMES.map((name) => {
136
- var _a;
137
- return (_a = _remaps[name]) != null ? _a : name;
138
- }));
111
+ var UNIVERSAL_IMPORTS = /* @__PURE__ */ new Set([
112
+ "signal",
113
+ "computed",
114
+ "reactive",
115
+ "memoEffect",
116
+ "omitProps"
117
+ ]);
139
118
  var importMap = Object.fromEntries(IMPORTS_MAPS.map((name) => [name, name]));
140
119
  var TRANSFORM_PROPERTY_NAME = "__props";
141
120
  var FRAGMENT_NAME = "Fragment";
@@ -222,7 +201,7 @@ function computeDeclarationCacheKey(expression) {
222
201
  const parts = [];
223
202
  for (const el of expression.elements) {
224
203
  if (el == null) {
225
- parts.push("\0null");
204
+ parts.push(" null");
226
205
  continue;
227
206
  }
228
207
  if (types.isStringLiteral(el)) {
@@ -255,23 +234,26 @@ function createImport(path) {
255
234
  const ctx = getCompileContext();
256
235
  if (!ctx.imports.size) return;
257
236
  const { mode } = ctx.options;
258
- const serverSpecifiers = [];
259
- const clientSpecifiers = [];
260
- for (const name of ctx.imports) {
261
- const local = ctx.importIdentifiers[name];
262
- const importedName = resolveImportedName(name, mode);
263
- const specifier = types.importSpecifier(local, types.identifier(importedName));
264
- if (mode === "server" /* SERVER */ && SERVER_EXPORTS.has(importedName)) {
265
- serverSpecifiers.push(specifier);
266
- } else {
267
- clientSpecifiers.push(specifier);
268
- }
269
- }
270
- if (serverSpecifiers.length > 0) {
271
- path.node.body.unshift(types.importDeclaration(serverSpecifiers, types.stringLiteral("essor/server")));
272
- }
273
- if (clientSpecifiers.length > 0) {
274
- path.node.body.unshift(types.importDeclaration(clientSpecifiers, types.stringLiteral("essor")));
237
+ const emit = (names, source) => {
238
+ if (!names.length) return;
239
+ const specifiers = names.map(
240
+ (name) => types.importSpecifier(
241
+ ctx.importIdentifiers[name],
242
+ types.identifier(resolveImportedName(name, mode))
243
+ )
244
+ );
245
+ path.node.body.unshift(types.importDeclaration(specifiers, types.stringLiteral(source)));
246
+ };
247
+ if (mode === "server" /* SERVER */) {
248
+ const universal = [];
249
+ const server = [];
250
+ for (const name of ctx.imports) {
251
+ (UNIVERSAL_IMPORTS.has(name) ? universal : server).push(name);
252
+ }
253
+ emit(server, "essor/server");
254
+ emit(universal, "essor");
255
+ } else {
256
+ emit([...ctx.imports], "essor");
275
257
  }
276
258
  }
277
259
 
@@ -819,29 +801,55 @@ function applyHmr(programPath, ctx) {
819
801
  ])
820
802
  );
821
803
  }
822
- function isMemberAccessingProperty(node, propertyName) {
823
- if (!node.computed && types.isIdentifier(node.property) && node.property.name === propertyName) {
824
- return true;
825
- }
826
- if (node.computed && types.isStringLiteral(node.property) && node.property.value === propertyName) {
827
- return true;
804
+ var DEFAULT_PREFIX = "$";
805
+ var cachedContext = null;
806
+ var cachedPrefix = DEFAULT_PREFIX;
807
+ function getSignalPrefix() {
808
+ var _a;
809
+ const ctx = getCompileContext();
810
+ if (ctx !== cachedContext) {
811
+ cachedContext = ctx;
812
+ cachedPrefix = (_a = ctx.options.signalPrefix) != null ? _a : DEFAULT_PREFIX;
828
813
  }
829
- return false;
814
+ return cachedPrefix;
830
815
  }
831
816
  function isSignal(name) {
832
- var _a;
833
- const prefix = (_a = getCompileContext().options.signalPrefix) != null ? _a : "$";
834
- return !!name && x(name, prefix);
817
+ return !!name && x(name, getSignalPrefix());
818
+ }
819
+ function stripSignalPrefix(name) {
820
+ const prefix = getSignalPrefix();
821
+ return x(name, prefix) ? name.slice(prefix.length) : name;
822
+ }
823
+ function isMemberLike(node) {
824
+ return types.isMemberExpression(node) || types.isOptionalMemberExpression(node);
825
+ }
826
+ function isMemberAccessingProperty(node, propertyName) {
827
+ if (node.computed) {
828
+ return types.isStringLiteral(node.property) && node.property.value === propertyName;
829
+ }
830
+ return types.isIdentifier(node.property) && node.property.name === propertyName;
831
+ }
832
+ function clone(node) {
833
+ return types.cloneNode(node, true);
834
+ }
835
+ function valueAccess(object) {
836
+ return types.memberExpression(object, types.identifier("value"));
837
+ }
838
+ function makeComputed(access) {
839
+ return types.callExpression(useImport("computed"), [types.arrowFunctionExpression([], access)]);
835
840
  }
836
841
  function replaceSymbol(path) {
837
842
  const { init, id } = path.node;
838
- if (!types.isIdentifier(id)) return;
839
- if (!isSignal(id.name)) return;
840
- if (isAlreadySignalCall(init)) return;
843
+ if (types.isObjectPattern(id) || types.isArrayPattern(id)) {
844
+ transformDestructuring(path);
845
+ return;
846
+ }
847
+ if (!types.isIdentifier(id) || !isSignal(id.name) || isAlreadySignalCall(init)) return;
841
848
  const isComputed = isFunctionLikeExpression(init) && path.parent.kind === "const";
842
- const importName = isComputed ? "computed" : "signal";
843
- const args = init ? [init] : [];
844
- path.node.init = types.callExpression(useImport(importName), args);
849
+ path.node.init = types.callExpression(
850
+ useImport(isComputed ? "computed" : "signal"),
851
+ init ? [init] : []
852
+ );
845
853
  }
846
854
  function isAlreadySignalCall(init) {
847
855
  if (!init || !types.isCallExpression(init) || !types.isIdentifier(init.callee)) return false;
@@ -850,24 +858,151 @@ function isAlreadySignalCall(init) {
850
858
  const { importIdentifiers } = getCompileContext();
851
859
  return calleeName === importIdentifiers.signal.name || calleeName === importIdentifiers.computed.name;
852
860
  }
861
+ function transformDestructuring(path) {
862
+ var _a;
863
+ const { init, id } = path.node;
864
+ const pattern = id;
865
+ if (!init) {
866
+ if (patternHasSignalBinding(pattern)) path.skip();
867
+ return;
868
+ }
869
+ if (!isSignalSource(init) && !patternHasSignalBinding(pattern)) return;
870
+ const declPath = path.parentPath;
871
+ if (!declPath || !declPath.isVariableDeclaration()) return;
872
+ if ((_a = declPath.parentPath) == null ? void 0 : _a.isForStatement()) {
873
+ path.skip();
874
+ return;
875
+ }
876
+ const declarators = bindPattern(pattern, signalSourceBase(init));
877
+ const declaration = declPath.node;
878
+ const index = declaration.declarations.indexOf(path.node);
879
+ declaration.declarations.splice(index, 1, ...declarators);
880
+ path.skip();
881
+ }
882
+ function isSignalSource(init) {
883
+ if (types.isIdentifier(init)) return isSignal(init.name);
884
+ if (isMemberLike(init) && types.isIdentifier(init.object) && isSignal(init.object.name)) {
885
+ return isMemberAccessingProperty(init, "value");
886
+ }
887
+ return false;
888
+ }
889
+ function signalSourceBase(init) {
890
+ if (types.isIdentifier(init) && isSignal(init.name)) {
891
+ return valueAccess(types.identifier(init.name));
892
+ }
893
+ return clone(init);
894
+ }
895
+ function patternHasSignalBinding(node) {
896
+ if (types.isIdentifier(node)) return isSignal(node.name);
897
+ if (types.isObjectPattern(node)) {
898
+ return node.properties.some(
899
+ (p2) => types.isRestElement(p2) ? patternHasSignalBinding(p2.argument) : patternHasSignalBinding(p2.value)
900
+ );
901
+ }
902
+ if (types.isArrayPattern(node)) {
903
+ return node.elements.some((el) => el != null && patternHasSignalBinding(el));
904
+ }
905
+ if (types.isAssignmentPattern(node)) return patternHasSignalBinding(node.left);
906
+ if (types.isRestElement(node)) return patternHasSignalBinding(node.argument);
907
+ return false;
908
+ }
909
+ function bindPattern(pattern, base) {
910
+ return types.isObjectPattern(pattern) ? bindObjectPattern(pattern, base) : bindArrayPattern(pattern, base);
911
+ }
912
+ function bindObjectPattern(pattern, base) {
913
+ const out = [];
914
+ const handledKeys = [];
915
+ for (const prop of pattern.properties) {
916
+ if (types.isRestElement(prop)) {
917
+ out.push(buildObjectRest(prop, base, handledKeys));
918
+ continue;
919
+ }
920
+ const { keyExpr, computed, target } = resolveObjectProp(prop);
921
+ handledKeys.push({ key: clone(keyExpr), computed });
922
+ out.push(...bindTarget(target, types.memberExpression(clone(base), keyExpr, computed)));
923
+ }
924
+ return out;
925
+ }
926
+ function resolveObjectProp(prop) {
927
+ const target = prop.value;
928
+ const shorthandId = types.isAssignmentPattern(target) ? target.left : target;
929
+ if (prop.shorthand && types.isIdentifier(shorthandId) && isSignal(shorthandId.name)) {
930
+ return { keyExpr: types.identifier(stripSignalPrefix(shorthandId.name)), computed: false, target };
931
+ }
932
+ if (prop.computed) {
933
+ return { keyExpr: prop.key, computed: true, target };
934
+ }
935
+ return { keyExpr: prop.key, computed: !types.isIdentifier(prop.key), target };
936
+ }
937
+ function bindArrayPattern(pattern, base) {
938
+ const out = [];
939
+ pattern.elements.forEach((el, i2) => {
940
+ if (el == null) return;
941
+ if (types.isRestElement(el)) {
942
+ const slice = types.callExpression(types.memberExpression(clone(base), types.identifier("slice")), [
943
+ types.numericLiteral(i2)
944
+ ]);
945
+ out.push(...bindTarget(el.argument, slice));
946
+ return;
947
+ }
948
+ out.push(...bindTarget(el, types.memberExpression(clone(base), types.numericLiteral(i2), true)));
949
+ });
950
+ return out;
951
+ }
952
+ function bindTarget(target, access) {
953
+ if (types.isAssignmentPattern(target)) {
954
+ return bindTarget(target.left, applyDefault(access, target.right));
955
+ }
956
+ if (types.isIdentifier(target)) {
957
+ const value = isSignal(target.name) ? makeComputed(access) : access;
958
+ return [types.variableDeclarator(types.identifier(target.name), value)];
959
+ }
960
+ if (types.isObjectPattern(target)) return bindObjectPattern(target, access);
961
+ if (types.isArrayPattern(target)) return bindArrayPattern(target, access);
962
+ return [types.variableDeclarator(target, access)];
963
+ }
964
+ function applyDefault(access, def) {
965
+ return types.conditionalExpression(
966
+ types.binaryExpression("===", clone(access), types.identifier("undefined")),
967
+ def,
968
+ clone(access)
969
+ );
970
+ }
971
+ function buildObjectRest(rest, base, handledKeys) {
972
+ const omits = (target) => types.objectPattern([
973
+ ...handledKeys.map(({ key, computed }) => types.objectProperty(key, genUid("_omit$"), computed)),
974
+ types.restElement(target)
975
+ ]);
976
+ const arg = rest.argument;
977
+ if (types.isIdentifier(arg) && isSignal(arg.name)) {
978
+ const inner = genUid("_rest$");
979
+ const body = types.blockStatement([
980
+ types.variableDeclaration("const", [types.variableDeclarator(omits(inner), clone(base))]),
981
+ types.returnStatement(clone(inner))
982
+ ]);
983
+ return types.variableDeclarator(types.identifier(arg.name), makeComputed(body));
984
+ }
985
+ return types.variableDeclarator(omits(arg), clone(base));
986
+ }
853
987
  function symbolIdentifier(path) {
854
- const name = path.node.name;
988
+ const { name } = path.node;
855
989
  if (!isSignal(name)) return;
856
- if (!shouldProcessIdentifier(path, path.parentPath)) return;
990
+ if (!shouldProcessIdentifier(path)) return;
857
991
  if (isAlreadyValueAccess(path)) return;
858
992
  const parent = path.parent;
859
- if (types.isMemberExpression(parent) && parent.property === path.node) return;
860
- path.replaceWith(types.memberExpression(types.identifier(name), types.identifier("value")));
993
+ if (isMemberLike(parent) && parent.property === path.node && !parent.computed) return;
994
+ path.replaceWith(valueAccess(types.identifier(name)));
861
995
  path.skip();
862
996
  }
863
- function shouldProcessIdentifier(path, parentPath) {
997
+ function shouldProcessIdentifier(path) {
998
+ const parentPath = path.parentPath;
864
999
  if (!parentPath) return false;
865
1000
  const parent = parentPath.node;
866
1001
  const node = path.node;
867
- if (types.isVariableDeclarator(parent) || types.isArrayPattern(parent) || types.isObjectPattern(parent)) {
1002
+ if (types.isVariableDeclarator(parent) || types.isArrayPattern(parent) || types.isObjectPattern(parent) || types.isRestElement(parent)) {
868
1003
  return false;
869
1004
  }
870
- if (types.isImportSpecifier(parent) || types.isImportDefaultSpecifier(parent) || types.isImportNamespaceSpecifier(parent)) {
1005
+ if (types.isImportSpecifier(parent) || types.isImportDefaultSpecifier(parent) || types.isImportNamespaceSpecifier(parent) || types.isExportSpecifier(parent)) {
871
1006
  return false;
872
1007
  }
873
1008
  if (types.isFunctionDeclaration(parent) || types.isFunctionExpression(parent)) {
@@ -878,7 +1013,7 @@ function shouldProcessIdentifier(path, parentPath) {
878
1013
  }
879
1014
  if (types.isClassDeclaration(parent) && parent.id === node) return false;
880
1015
  if (types.isObjectMethod(parent) || types.isClassMethod(parent)) return false;
881
- if (types.isObjectProperty(parent) && parent.key === node) return false;
1016
+ if (types.isObjectProperty(parent) && parent.key === node && !parent.computed) return false;
882
1017
  if (types.isLabeledStatement(parent) && parent.label === node) return false;
883
1018
  if ((types.isBreakStatement(parent) || types.isContinueStatement(parent)) && parent.label === node) {
884
1019
  return false;
@@ -887,38 +1022,27 @@ function shouldProcessIdentifier(path, parentPath) {
887
1022
  }
888
1023
  function isAlreadyValueAccess(path) {
889
1024
  const parent = path.parent;
890
- if (types.isMemberExpression(parent) && parent.object === path.node) {
1025
+ if (isMemberLike(parent) && parent.object === path.node) {
891
1026
  return isMemberAccessingProperty(parent, "value");
892
1027
  }
893
1028
  if (!types.isParenthesizedExpression(parent) && !types.isTSAsExpression(parent) && !types.isTSNonNullExpression(parent)) {
894
1029
  return false;
895
1030
  }
896
1031
  const ancestor = path.findParent((p2) => {
897
- if (!p2.isMemberExpression()) return false;
898
- const m = p2.node;
899
- return m.object === path.node && isMemberAccessingProperty(m, "value");
1032
+ if (!isMemberLike(p2.node)) return false;
1033
+ return isMemberAccessingProperty(p2.node, "value");
900
1034
  });
901
1035
  return !!ancestor;
902
1036
  }
903
1037
  function symbolAssignment(path) {
904
1038
  const { left } = path.node;
905
- if (!types.isIdentifier(left)) return;
906
- if (!isSignal(left.name)) return;
907
- if (isAlreadyValueAssignment(left)) return;
908
- path.node.left = types.memberExpression(types.identifier(left.name), types.identifier("value"));
909
- }
910
- function isAlreadyValueAssignment(left) {
911
- return types.isMemberExpression(left) && isMemberAccessingProperty(left, "value");
1039
+ if (!types.isIdentifier(left) || !isSignal(left.name)) return;
1040
+ path.node.left = valueAccess(types.identifier(left.name));
912
1041
  }
913
1042
  function symbolUpdate(path) {
914
1043
  const { argument } = path.node;
915
- if (!types.isIdentifier(argument)) return;
916
- if (!isSignal(argument.name)) return;
917
- if (isAlreadyValueUpdate(argument)) return;
918
- path.node.argument = types.memberExpression(types.identifier(argument.name), types.identifier("value"));
919
- }
920
- function isAlreadyValueUpdate(argument) {
921
- return types.isMemberExpression(argument) && isMemberAccessingProperty(argument, "value");
1044
+ if (!types.isIdentifier(argument) || !isSignal(argument.name)) return;
1045
+ path.node.argument = valueAccess(types.identifier(argument.name));
922
1046
  }
923
1047
  var symbolVisitors = {
924
1048
  VariableDeclarator: replaceSymbol,
@@ -926,114 +1050,174 @@ var symbolVisitors = {
926
1050
  AssignmentExpression: symbolAssignment,
927
1051
  UpdateExpression: symbolUpdate
928
1052
  };
929
- function transformProperty(path, properties, parentPath, defaults = {}) {
930
- for (const property of properties) {
931
- if (!types.isObjectProperty(property)) continue;
932
- const key = property.key;
933
- const keyName = types.isIdentifier(key) ? key.name : types.isStringLiteral(key) ? key.value : "";
934
- if (!keyName) continue;
935
- const value = property.value;
936
- const childPath = `${parentPath}.${keyName}`;
937
- if (types.isAssignmentPattern(value)) {
938
- const left = value.left;
939
- if (types.isIdentifier(left)) {
940
- defaults[keyName] = value.right;
941
- path.scope.rename(left.name, childPath);
942
- } else if (types.isObjectPattern(left)) {
943
- transformProperty(path, left.properties, childPath, defaults);
944
- defaults[keyName] = value.right;
945
- }
946
- } else if (types.isIdentifier(value)) {
947
- path.scope.rename(value.name, childPath);
948
- } else if (types.isObjectPattern(value)) {
949
- const nested = {};
950
- transformProperty(path, value.properties, childPath, nested);
951
- if (Object.keys(nested).length > 0) defaults[keyName] = nested;
952
- }
953
- }
954
- return defaults;
955
- }
956
- function buildRestVariableDeclaration(restName, parentPath, excludeProps) {
957
- const validExcludeProps = excludeProps.filter(Boolean);
958
- const pathParts = parentPath.split(".").filter(Boolean);
959
- let sourceObject = types.identifier(pathParts[0] || "__props");
960
- for (let i2 = 1; i2 < pathParts.length; i2++) {
961
- sourceObject = types.memberExpression(sourceObject, types.identifier(pathParts[i2]));
962
- }
963
- const init = validExcludeProps.length === 0 ? sourceObject : types.callExpression(useImport(importMap.omitProps), [
964
- sourceObject,
965
- types.arrayExpression(validExcludeProps.map((name) => types.stringLiteral(name)))
1053
+ function clone2(node) {
1054
+ return types.cloneNode(node, true);
1055
+ }
1056
+ function applyDefault2(access, def) {
1057
+ return types.conditionalExpression(
1058
+ types.binaryExpression("===", clone2(access), types.identifier("undefined")),
1059
+ def,
1060
+ clone2(access)
1061
+ );
1062
+ }
1063
+ function resolveKey(prop) {
1064
+ const key = prop.key;
1065
+ if (prop.computed) {
1066
+ return { keyExpr: key, computed: true, excludeKey: key };
1067
+ }
1068
+ if (types.isIdentifier(key)) {
1069
+ return {
1070
+ keyExpr: types.identifier(key.name),
1071
+ computed: false,
1072
+ excludeKey: types.stringLiteral(key.name)
1073
+ };
1074
+ }
1075
+ if (types.isStringLiteral(key)) {
1076
+ return {
1077
+ keyExpr: types.stringLiteral(key.value),
1078
+ computed: true,
1079
+ excludeKey: types.stringLiteral(key.value)
1080
+ };
1081
+ }
1082
+ if (types.isNumericLiteral(key)) {
1083
+ return {
1084
+ keyExpr: types.numericLiteral(key.value),
1085
+ computed: true,
1086
+ excludeKey: types.stringLiteral(String(key.value))
1087
+ };
1088
+ }
1089
+ return { keyExpr: key, computed: true, excludeKey: null };
1090
+ }
1091
+ function restName(argument) {
1092
+ return types.isIdentifier(argument) ? argument.name : null;
1093
+ }
1094
+ function buildObjectRestInit(base, excludeKeys) {
1095
+ if (excludeKeys.length === 0) return clone2(base);
1096
+ return types.callExpression(useImport(importMap.omitProps), [
1097
+ clone2(base),
1098
+ types.arrayExpression(excludeKeys.map((key) => clone2(key)))
966
1099
  ]);
967
- return types.variableDeclaration("const", [types.variableDeclarator(types.identifier(restName), init)]);
968
1100
  }
969
- function transformRestProperties(path, restProperties, notRestNames = []) {
970
- if (!types.isIdentifier(restProperties.argument)) return;
971
- const restName = restProperties.argument.name;
972
- if (notRestNames.length === 0) {
973
- path.node.params[0] = types.identifier(restName);
1101
+ function collectTarget(target, access, leaves, rests) {
1102
+ if (types.isAssignmentPattern(target)) {
1103
+ collectTarget(target.left, applyDefault2(access, target.right), leaves, rests);
974
1104
  return;
975
1105
  }
976
- const declaration = buildRestVariableDeclaration(restName, TRANSFORM_PROPERTY_NAME, notRestNames);
977
- const body = path.node.body;
978
- body.body.unshift(declaration);
979
- }
980
- function buildDefaultValueObject(defaults) {
981
- if (!P(defaults)) return types.objectExpression([]);
982
- const properties = [];
983
- for (const [key, value] of Object.entries(defaults)) {
984
- if (!key) continue;
985
- let propertyValue;
986
- if (P(value) && !types.isNode(value)) {
987
- propertyValue = buildDefaultValueObject(value);
988
- } else if (types.isExpression(value)) {
989
- propertyValue = value;
990
- } else {
1106
+ if (types.isIdentifier(target)) {
1107
+ leaves.push({ name: target.name, accessor: access });
1108
+ return;
1109
+ }
1110
+ if (types.isObjectPattern(target)) {
1111
+ collectObjectPattern(target, access, leaves, rests);
1112
+ return;
1113
+ }
1114
+ if (types.isArrayPattern(target)) {
1115
+ collectArrayPattern(target, access, leaves, rests);
1116
+ return;
1117
+ }
1118
+ }
1119
+ function collectObjectPattern(pattern, base, leaves, rests) {
1120
+ const excludeKeys = [];
1121
+ for (const prop of pattern.properties) {
1122
+ if (types.isRestElement(prop)) {
1123
+ const name = restName(prop.argument);
1124
+ if (name) rests.push({ name, init: buildObjectRestInit(base, excludeKeys) });
991
1125
  continue;
992
1126
  }
993
- properties.push(types.objectProperty(types.identifier(key), propertyValue));
994
- }
995
- return types.objectExpression(properties);
1127
+ const { keyExpr, computed, excludeKey } = resolveKey(prop);
1128
+ if (excludeKey !== null) excludeKeys.push(excludeKey);
1129
+ const access = types.memberExpression(clone2(base), keyExpr, computed);
1130
+ collectTarget(prop.value, access, leaves, rests);
1131
+ }
1132
+ }
1133
+ function spreadOf(base) {
1134
+ return types.arrayExpression([types.spreadElement(clone2(base))]);
1135
+ }
1136
+ function collectArrayPattern(pattern, base, leaves, rests) {
1137
+ pattern.elements.forEach((element, index) => {
1138
+ if (element == null) return;
1139
+ if (types.isRestElement(element)) {
1140
+ const name = restName(element.argument);
1141
+ if (name) {
1142
+ const init = types.callExpression(types.memberExpression(spreadOf(base), types.identifier("slice")), [
1143
+ types.numericLiteral(index)
1144
+ ]);
1145
+ rests.push({ name, init });
1146
+ }
1147
+ return;
1148
+ }
1149
+ const access = types.memberExpression(spreadOf(base), types.numericLiteral(index), true);
1150
+ collectTarget(element, access, leaves, rests);
1151
+ });
996
1152
  }
997
- function buildDefaultValue(path, defaults) {
998
- path.node.params[0] = types.identifier(TRANSFORM_PROPERTY_NAME);
999
- if (Object.keys(defaults).length === 0) return;
1000
- const resolveDefaultProps = useImport(importMap.resolveDefaultProps);
1001
- const body = types.isBlockStatement(path.node.body) ? path.node.body : types.blockStatement([types.returnStatement(path.node.body)]);
1002
- path.node.body = body;
1003
- body.body.unshift(
1004
- types.expressionStatement(
1005
- types.assignmentExpression(
1006
- "=",
1007
- types.identifier(TRANSFORM_PROPERTY_NAME),
1008
- types.callExpression(resolveDefaultProps, [
1009
- types.identifier(TRANSFORM_PROPERTY_NAME),
1010
- buildDefaultValueObject(defaults)
1011
- ])
1012
- )
1013
- )
1014
- );
1153
+ function ensureBlockBody(path) {
1154
+ if (types.isBlockStatement(path.node.body)) return path.node.body;
1155
+ const block = types.blockStatement([types.returnStatement(path.node.body)]);
1156
+ path.node.body = block;
1157
+ return block;
1158
+ }
1159
+ function isInsidePattern(ref, pattern) {
1160
+ return !!ref.findParent((p2) => p2.node === pattern);
1161
+ }
1162
+ function accessorFor(pattern, base, name) {
1163
+ var _a;
1164
+ const leaves = [];
1165
+ collectObjectPattern(pattern, base, leaves, []);
1166
+ return (_a = leaves.find((leaf) => leaf.name === name)) == null ? void 0 : _a.accessor;
1015
1167
  }
1016
1168
  function transformFnProps(path) {
1169
+ var _a, _b;
1017
1170
  const firstParam = path.node.params[0];
1018
1171
  if (!firstParam || !types.isObjectPattern(firstParam) || !checkHasJSXReturn(path)) return;
1019
1172
  const ctx = getCompileContext();
1020
- const properties = firstParam.properties;
1021
1173
  const signalPrefix = ctx.options.signalPrefix || "$";
1022
- const notRestProperties = properties.filter((prop) => !types.isRestElement(prop));
1023
- const restProperties = properties.find((prop) => types.isRestElement(prop));
1024
- const notRestNames = notRestProperties.map((prop) => types.isIdentifier(prop.key) ? prop.key.name : null).filter((name) => name !== null);
1025
- const signalConflicts = notRestNames.filter((name) => x(name, signalPrefix));
1026
- if (signalConflicts.length > 0) {
1027
- re("transformProps", "Property names cannot start with signal prefix", signalConflicts);
1028
- }
1029
- if (notRestProperties.length > 0) {
1030
- const defaults = transformProperty(path, notRestProperties, TRANSFORM_PROPERTY_NAME);
1031
- if (restProperties) transformRestProperties(path, restProperties, notRestNames);
1032
- buildDefaultValue(path, defaults);
1174
+ const base = types.identifier(TRANSFORM_PROPERTY_NAME);
1175
+ const initLeaves = [];
1176
+ const initRests = [];
1177
+ collectObjectPattern(firstParam, base, initLeaves, initRests);
1178
+ const conflicts = [...initLeaves, ...initRests].map((b2) => b2.name).filter((name) => x(name, signalPrefix));
1179
+ if (conflicts.length > 0) {
1180
+ re("transformProps", "Property names cannot start with signal prefix", conflicts);
1181
+ }
1182
+ if (initLeaves.length === 0 && initRests.length === 1 && firstParam.properties.length === 1 && types.isRestElement(firstParam.properties[0])) {
1183
+ path.node.params[0] = types.identifier(initRests[0].name);
1033
1184
  return;
1034
1185
  }
1035
- buildDefaultValue(path, {});
1036
- if (restProperties) transformRestProperties(path, restProperties, notRestNames);
1186
+ const inPatternRefs = /* @__PURE__ */ new Map();
1187
+ const bodyRefs = /* @__PURE__ */ new Map();
1188
+ for (const leaf of initLeaves) {
1189
+ const inside = [];
1190
+ const outside = [];
1191
+ for (const ref of (_b = (_a = path.scope.getBinding(leaf.name)) == null ? void 0 : _a.referencePaths) != null ? _b : []) {
1192
+ (isInsidePattern(ref, firstParam) ? inside : outside).push(ref);
1193
+ }
1194
+ if (inside.length > 0) inPatternRefs.set(leaf.name, inside);
1195
+ bodyRefs.set(leaf.name, outside);
1196
+ }
1197
+ for (const leaf of initLeaves) {
1198
+ const refs = inPatternRefs.get(leaf.name);
1199
+ if (!refs) continue;
1200
+ const accessor = accessorFor(firstParam, base, leaf.name);
1201
+ if (!accessor) continue;
1202
+ for (const ref of refs) ref.replaceWith(clone2(accessor));
1203
+ }
1204
+ const leaves = [];
1205
+ const rests = [];
1206
+ collectObjectPattern(firstParam, base, leaves, rests);
1207
+ const accessorByName = new Map(leaves.map((leaf) => [leaf.name, leaf.accessor]));
1208
+ path.node.params[0] = types.identifier(TRANSFORM_PROPERTY_NAME);
1209
+ for (const [name, refs] of bodyRefs) {
1210
+ const accessor = accessorByName.get(name);
1211
+ if (!accessor) continue;
1212
+ for (const ref of refs) ref.replaceWith(clone2(accessor));
1213
+ }
1214
+ if (rests.length > 0) {
1215
+ const body = ensureBlockBody(path);
1216
+ const declarations = rests.map(
1217
+ (rest) => types.variableDeclaration("const", [types.variableDeclarator(types.identifier(rest.name), rest.init)])
1218
+ );
1219
+ body.body.unshift(...declarations);
1220
+ }
1037
1221
  }
1038
1222
  var propsVisitors = {
1039
1223
  FunctionDeclaration: transformFnProps,
@@ -1449,8 +1633,8 @@ function setNodeText(path, text) {
1449
1633
  function createComponentPropKey(name, forceStringLiteralKeys = false) {
1450
1634
  return forceStringLiteralKeys || !types.isValidIdentifier(name) ? types.stringLiteral(name) : types.identifier(name);
1451
1635
  }
1452
- function cloneValue(value, clone = false) {
1453
- return clone ? types.cloneNode(value, true) : value;
1636
+ function cloneValue(value, clone3 = false) {
1637
+ return clone3 ? types.cloneNode(value, true) : value;
1454
1638
  }
1455
1639
  function createPropNode(name, value, kind, options) {
1456
1640
  const key = createComponentPropKey(name, options.forceStringLiteralKeys);
@@ -1596,44 +1780,6 @@ var SERVER_TEXT_ESCAPES = {
1596
1780
  ">": "&gt;"
1597
1781
  };
1598
1782
  var serverTextEscapeRE = /[&<>]/g;
1599
- function markSafeHtmlCall(expression) {
1600
- return types.callExpression(useImport("markAsRawHtml"), [expression]);
1601
- }
1602
- function isGeneratedServerHtmlCall(expression) {
1603
- const { importIdentifiers } = getCompileContext();
1604
- const renderId = importIdentifiers.render;
1605
- const componentId = importIdentifiers.createComponent;
1606
- return types.isIdentifier(expression.callee) && (expression.callee.name === renderId.name || expression.callee.name === componentId.name);
1607
- }
1608
- function visitServerHtmlSubexpressions(node) {
1609
- var _a;
1610
- if (!node) return node;
1611
- if (types.isJSXElement(node) || types.isJSXFragment(node)) {
1612
- return markSafeHtmlCall(node);
1613
- }
1614
- if (types.isCallExpression(node) && isGeneratedServerHtmlCall(node)) {
1615
- return markSafeHtmlCall(node);
1616
- }
1617
- const keys = (_a = types.VISITOR_KEYS[node.type]) != null ? _a : [];
1618
- for (const key of keys) {
1619
- const record = node;
1620
- const value = record[key];
1621
- if (Array.isArray(value)) {
1622
- for (let i2 = 0; i2 < value.length; i2++) {
1623
- const child = value[i2];
1624
- if (child && typeof child === "object" && "type" in child) {
1625
- value[i2] = visitServerHtmlSubexpressions(child);
1626
- }
1627
- }
1628
- } else if (value && typeof value === "object" && "type" in value) {
1629
- record[key] = visitServerHtmlSubexpressions(value);
1630
- }
1631
- }
1632
- return node;
1633
- }
1634
- function markServerHtmlSubexpressions(expression) {
1635
- return visitServerHtmlSubexpressions(expression);
1636
- }
1637
1783
  function escapeServerTemplateText(value) {
1638
1784
  return value.replaceAll(serverTextEscapeRE, (char) => {
1639
1785
  var _a;
@@ -1718,14 +1864,50 @@ function createSSRSelectedExpression(selectValue, optionValue) {
1718
1864
  types.cloneNode(optionValue, true)
1719
1865
  ]);
1720
1866
  }
1867
+ function isSafeServerHtml(expr) {
1868
+ if (types.isJSXElement(expr) || types.isJSXFragment(expr)) return true;
1869
+ if (!types.isCallExpression(expr) || !types.isIdentifier(expr.callee)) return false;
1870
+ const { importIdentifiers } = getCompileContext();
1871
+ return expr.callee.name === importIdentifiers.render.name || expr.callee.name === importIdentifiers.createComponent.name;
1872
+ }
1873
+ function escapeChildExpression(expr) {
1874
+ if (isSafeServerHtml(expr)) {
1875
+ return expr;
1876
+ }
1877
+ if (types.isParenthesizedExpression(expr)) {
1878
+ expr.expression = escapeChildExpression(expr.expression);
1879
+ return expr;
1880
+ }
1881
+ if (types.isLogicalExpression(expr)) {
1882
+ if (expr.operator === "&&") {
1883
+ expr.right = escapeChildExpression(expr.right);
1884
+ } else {
1885
+ expr.left = escapeChildExpression(expr.left);
1886
+ expr.right = escapeChildExpression(expr.right);
1887
+ }
1888
+ return expr;
1889
+ }
1890
+ if (types.isConditionalExpression(expr)) {
1891
+ expr.consequent = escapeChildExpression(expr.consequent);
1892
+ expr.alternate = escapeChildExpression(expr.alternate);
1893
+ return expr;
1894
+ }
1895
+ if (types.isSequenceExpression(expr) && expr.expressions.length > 0) {
1896
+ const last = expr.expressions.length - 1;
1897
+ expr.expressions[last] = escapeChildExpression(expr.expressions[last]);
1898
+ return expr;
1899
+ }
1900
+ return types.callExpression(useImport("escape"), [expr]);
1901
+ }
1721
1902
  function generateServerNode(node, ctx, withHydrationKey = true) {
1722
1903
  switch (node.type) {
1723
1904
  case 2 /* TEXT */:
1724
1905
  return types.stringLiteral(node.value);
1725
1906
  case 3 /* EXPRESSION */: {
1726
- const expression = node.asRawChildren ? types.cloneNode(node.value, true) : markServerHtmlSubexpressions(types.cloneNode(node.value, true));
1727
- const converter = node.asRawChildren ? "toRawHtmlString" : "toEscapedHtmlString";
1728
- return types.callExpression(useImport(converter), [expression]);
1907
+ if (node.asRawChildren) {
1908
+ return types.cloneNode(node.value, true);
1909
+ }
1910
+ return escapeChildExpression(types.cloneNode(node.value, true));
1729
1911
  }
1730
1912
  case 1 /* COMPONENT */:
1731
1913
  return generateServerComponent(node, ctx);