@jbpark/live-editor 4.5.0 → 4.6.0

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 (70) hide show
  1. package/README.ko.md +4 -1
  2. package/README.md +5 -1
  3. package/dist/{boundary-DnjGgsK6.js → boundary-BLB80tyw.js} +2 -2
  4. package/dist/boundary-BLB80tyw.js.map +1 -0
  5. package/dist/cache-B0-XcIxJ.js.map +1 -1
  6. package/dist/{compile-DDfk5P25.js → compile-Dxas-D05.js} +3 -3
  7. package/dist/compile-Dxas-D05.js.map +1 -0
  8. package/dist/{constants-h1JAgOeW.js → constants-DU17Tdwo.js} +3 -3
  9. package/dist/constants-DU17Tdwo.js.map +1 -0
  10. package/dist/{context-DsEXJl4h.js → context-B8MzP7_p.js} +3 -3
  11. package/dist/context-B8MzP7_p.js.map +1 -0
  12. package/dist/{core-CRsAGpei.js → core-Bgfek364.js} +2 -2
  13. package/dist/core-Bgfek364.js.map +1 -0
  14. package/dist/{detect-typescript-CCj9ALXc.js → detect-typescript-Dr_oLniM.js} +2 -2
  15. package/dist/detect-typescript-Dr_oLniM.js.map +1 -0
  16. package/dist/dnd/index.d.ts +1 -1
  17. package/dist/dnd/index.js +1 -1
  18. package/dist/{dnd-DGNp20Nk.js → dnd-UoJILA75.js} +431 -408
  19. package/dist/dnd-UoJILA75.js.map +1 -0
  20. package/dist/{document-DGHTfrda.js → document-CGbe6bSV.js} +2 -2
  21. package/dist/{document-DGHTfrda.js.map → document-CGbe6bSV.js.map} +1 -1
  22. package/dist/editor/index.js +2 -2
  23. package/dist/{editor-DQ8Q--qR.js → editor-CMElfHer.js} +2 -2
  24. package/dist/editor-CMElfHer.js.map +1 -0
  25. package/dist/editor-caches-ClMvdcQF.js.map +1 -1
  26. package/dist/error/index.d.ts +1 -1
  27. package/dist/error/index.js +2 -2
  28. package/dist/{error-DwqwjJ2C.js → error-CN_GCnXB.js} +3 -3
  29. package/dist/{error-DwqwjJ2C.js.map → error-CN_GCnXB.js.map} +1 -1
  30. package/dist/{index-P9Aifaui.d.ts → index-C69Lv-jR.d.ts} +71 -69
  31. package/dist/{index-vtyggWy0.d.ts → index-CRwEhJ7w.d.ts} +2 -2
  32. package/dist/{index-CHknA6k1.d.ts → index-DKYUxi-E.d.ts} +10 -4
  33. package/dist/{index-WQgFy510.d.ts → index-DrWtSKXu.d.ts} +2 -2
  34. package/dist/index.d.ts +4 -4
  35. package/dist/index.js +6 -6
  36. package/dist/{items-DdrwGxJw.js → items-B6OXxcLG.js} +178 -259
  37. package/dist/items-B6OXxcLG.js.map +1 -0
  38. package/dist/{messages-CzUPVnzH.js → messages-CSrMI4Rm.js} +2 -1
  39. package/dist/messages-CSrMI4Rm.js.map +1 -0
  40. package/dist/{messages-Cp3g1mn1.d.ts → messages-IBPs4TkZ.d.ts} +2 -1
  41. package/dist/preview/index.js +2 -2
  42. package/dist/{preview-BKFgq_5u.js → preview-CtyG5UbH.js} +4 -4
  43. package/dist/{preview-BKFgq_5u.js.map → preview-CtyG5UbH.js.map} +1 -1
  44. package/dist/provider/index.d.ts +2 -2
  45. package/dist/provider/index.js +2 -2
  46. package/dist/{sections-BRH3KHYc.js → sections-BYWOBISr.js} +3 -3
  47. package/dist/sections-BYWOBISr.js.map +1 -0
  48. package/dist/states-Ci1AvoQ9.js.map +1 -1
  49. package/dist/{use-dynamic-tailwind-T9r9ExbR.js → use-dynamic-tailwind-BP1toJkW.js} +59 -39
  50. package/dist/use-dynamic-tailwind-BP1toJkW.js.map +1 -0
  51. package/dist/utils/ast/index.d.ts +1 -1
  52. package/dist/utils/ast/index.js +86 -2
  53. package/dist/utils/ast/index.js.map +1 -1
  54. package/dist/utils/index.js +4 -4
  55. package/dist/utils/index.js.map +1 -1
  56. package/dist/utils/tailwind/index.js.map +1 -1
  57. package/dist/validate-iLo8IONY.js.map +1 -1
  58. package/package.json +1 -1
  59. package/dist/boundary-DnjGgsK6.js.map +0 -1
  60. package/dist/compile-DDfk5P25.js.map +0 -1
  61. package/dist/constants-h1JAgOeW.js.map +0 -1
  62. package/dist/context-DsEXJl4h.js.map +0 -1
  63. package/dist/core-CRsAGpei.js.map +0 -1
  64. package/dist/detect-typescript-CCj9ALXc.js.map +0 -1
  65. package/dist/dnd-DGNp20Nk.js.map +0 -1
  66. package/dist/editor-DQ8Q--qR.js.map +0 -1
  67. package/dist/items-DdrwGxJw.js.map +0 -1
  68. package/dist/messages-CzUPVnzH.js.map +0 -1
  69. package/dist/sections-BRH3KHYc.js.map +0 -1
  70. package/dist/use-dynamic-tailwind-T9r9ExbR.js.map +0 -1
@@ -1,5 +1,5 @@
1
- import { C as require_lib, S as require_lib$1, _ as generateCode, b as getJSXTagName, d as traverse, g as attrValue, v as unwrap, w as __toESM, x as nanoid, y as wrap } from "./document-DGHTfrda.js";
2
- import { c as RESERVED_BINDING_PROPERTIES, n as CONFIG, r as DATA_ATTR, s as REGEX, t as BINDING_PROP } from "./constants-h1JAgOeW.js";
1
+ import { C as require_lib, S as require_lib$1, _ as generateCode, b as getJSXTagName, d as traverse, g as attrValue, v as unwrap, w as __toESM, x as nanoid, y as wrap } from "./document-CGbe6bSV.js";
2
+ import { c as RESERVED_BINDING_PROPERTIES, n as CONFIG, r as DATA_ATTR, s as REGEX, t as BINDING_PROP } from "./constants-DU17Tdwo.js";
3
3
  import { n as registerEditorCache } from "./editor-caches-ClMvdcQF.js";
4
4
  import { t as createBoundedCache } from "./cache-B0-XcIxJ.js";
5
5
  import { z } from "zod";
@@ -95,86 +95,6 @@ const parseValue = (value) => {
95
95
  }
96
96
  return value;
97
97
  };
98
- const MAX_FLATTEN_DEPTH = 20;
99
- const isEditablePrimitive = (value) => typeof value === "string" || typeof value === "number" || typeof value === "boolean";
100
- const flattenEditableValue = (value) => {
101
- const parsed = parseValue(value);
102
- if (typeof parsed !== "object" || parsed === null || Object.keys(parsed).length === 0) return null;
103
- const entries = [];
104
- const walk = (node, path, depth) => {
105
- if (depth > MAX_FLATTEN_DEPTH) return;
106
- if (isEditablePrimitive(node)) {
107
- entries.push({
108
- path,
109
- value: node
110
- });
111
- return;
112
- }
113
- if (Array.isArray(node)) {
114
- node.forEach((item, index) => walk(item, [...path, index], depth + 1));
115
- return;
116
- }
117
- if (typeof node === "object" && node !== null) Object.entries(node).forEach(([key, item]) => walk(item, [...path, key], depth + 1));
118
- };
119
- walk(parsed, [], 0);
120
- return entries.length ? entries : null;
121
- };
122
- const findEditableLeaf = (root, path) => {
123
- let node = unwrapExpression(root);
124
- for (const segment of path) {
125
- if (import_lib$1.isArrayExpression(node)) {
126
- if (typeof segment !== "number") return null;
127
- const elements = node.elements.slice(0, segment + 1);
128
- const element = node.elements[segment];
129
- if (!element || elements.some((item) => import_lib$1.isSpreadElement(item))) return null;
130
- node = unwrapExpression(element);
131
- continue;
132
- }
133
- if (import_lib$1.isObjectExpression(node)) {
134
- const key = String(segment);
135
- const matches = (property) => import_lib$1.isObjectProperty(property) && !property.computed && (import_lib$1.isIdentifier(property.key) && property.key.name === key || import_lib$1.isStringLiteral(property.key) && property.key.value === key || import_lib$1.isNumericLiteral(property.key) && String(property.key.value) === key);
136
- let index = node.properties.length - 1;
137
- while (index >= 0 && !matches(node.properties[index])) index--;
138
- const property = node.properties[index];
139
- if (!property || !import_lib$1.isObjectProperty(property) || node.properties.slice(index + 1).some((item) => import_lib$1.isSpreadElement(item))) return null;
140
- node = unwrapExpression(property.value);
141
- continue;
142
- }
143
- return null;
144
- }
145
- return node;
146
- };
147
- const isEditableLeaf = (node) => import_lib$1.isStringLiteral(node) || import_lib$1.isNumericLiteral(node) || import_lib$1.isBooleanLiteral(node) || import_lib$1.isUnaryExpression(node) && node.operator === "-" && import_lib$1.isNumericLiteral(node.argument) || import_lib$1.isTemplateLiteral(node) && node.expressions.length === 0 || import_lib$1.isJSXElement(node) || import_lib$1.isJSXFragment(node);
148
- const quoteString = (text, quote) => {
149
- if (quote === "`") return `\`${text.replace(/[\\`]|\$\{/g, (match) => `\\${match}`)}\``;
150
- const escaped = JSON.stringify(text).slice(1, -1);
151
- return quote === "\"" ? `"${escaped}"` : `'${escaped.replace(/\\"/g, "\"").replace(/'/g, "\\'")}'`;
152
- };
153
- const isJSXSource = (text) => {
154
- try {
155
- const expression = (0, import_lib.parseExpression)(text, { plugins: ["jsx"] });
156
- return import_lib$1.isJSXElement(expression) || import_lib$1.isJSXFragment(expression);
157
- } catch {
158
- return false;
159
- }
160
- };
161
- const leafSource = (value, leaf, next) => {
162
- if (typeof next !== "string") return String(next);
163
- if ((import_lib$1.isJSXElement(leaf) || import_lib$1.isJSXFragment(leaf)) && isJSXSource(next)) return next.trim();
164
- const quote = import_lib$1.isStringLiteral(leaf) || import_lib$1.isTemplateLiteral(leaf) ? value[leaf.start] : "'";
165
- return quoteString(next, quote);
166
- };
167
- const setEditableValue = (value, path, next) => {
168
- if (!path.length) return value;
169
- let leaf;
170
- try {
171
- leaf = findEditableLeaf((0, import_lib.parseExpression)(value, { plugins: ["jsx", "typescript"] }), path);
172
- } catch {
173
- return value;
174
- }
175
- if (!leaf || !isEditableLeaf(leaf) || leaf.start == null || leaf.end == null) return value;
176
- return `${value.slice(0, leaf.start)}${leafSource(value, leaf, next)}${value.slice(leaf.end)}`;
177
- };
178
98
  const extractNodeValue = (node) => {
179
99
  if (import_lib$1.isBooleanLiteral(node)) return {
180
100
  type: "boolean",
@@ -223,35 +143,6 @@ const extractNodeValue = (node) => {
223
143
  value: null
224
144
  };
225
145
  };
226
- const createNodeFromValue = (type, value) => {
227
- switch (type) {
228
- case "boolean": return import_lib$1.booleanLiteral(value === true);
229
- case "number": return import_lib$1.numericLiteral(Number(value));
230
- case "string": return import_lib$1.stringLiteral(String(value));
231
- case "null": return import_lib$1.nullLiteral();
232
- case "array":
233
- case "object":
234
- case "unknown": return null;
235
- default: return null;
236
- }
237
- };
238
- const valueToExpression = (value) => {
239
- if (typeof value === "string") return import_lib$1.stringLiteral(value);
240
- if (typeof value === "number") return value < 0 ? import_lib$1.unaryExpression("-", import_lib$1.numericLiteral(-value)) : import_lib$1.numericLiteral(value);
241
- if (typeof value === "boolean") return import_lib$1.booleanLiteral(value);
242
- if (value === null) return import_lib$1.nullLiteral();
243
- if (Array.isArray(value)) return import_lib$1.arrayExpression(value.map((item) => valueToExpression(item) ?? import_lib$1.nullLiteral()));
244
- if (typeof value === "object") {
245
- const properties = [];
246
- for (const [key, item] of Object.entries(value)) {
247
- const expr = valueToExpression(item);
248
- if (expr === null) continue;
249
- properties.push(import_lib$1.objectProperty(import_lib$1.stringLiteral(key), expr));
250
- }
251
- return import_lib$1.objectExpression(properties);
252
- }
253
- return null;
254
- };
255
146
  const parseArrayExpression = (value) => {
256
147
  try {
257
148
  const ast = unwrapExpression((0, import_lib.parseExpression)(value, { plugins: ["jsx", "typescript"] }));
@@ -277,10 +168,6 @@ const extractObjectProperties = (element) => {
277
168
  });
278
169
  return properties;
279
170
  };
280
- const arrayExpressionToCode = (elements) => {
281
- const nextAst = import_lib$1.arrayExpression(elements);
282
- return generateCode(nextAst);
283
- };
284
171
  //#endregion
285
172
  //#region src/utils/ast/binding.ts
286
173
  const bindingTypeSchema = z.enum(BINDING_TYPES);
@@ -1007,7 +894,42 @@ const editChildrenSource = (source, parent, input, options) => {
1007
894
  }
1008
895
  };
1009
896
  //#endregion
1010
- //#region src/utils/ast/update.ts
897
+ //#region src/utils/ast/value-expression.ts
898
+ const createNodeFromValue = (type, value) => {
899
+ switch (type) {
900
+ case "boolean": return import_lib$1.booleanLiteral(value === true);
901
+ case "number": return import_lib$1.numericLiteral(Number(value));
902
+ case "string": return import_lib$1.stringLiteral(String(value));
903
+ case "null": return import_lib$1.nullLiteral();
904
+ case "array":
905
+ case "object":
906
+ case "unknown": return null;
907
+ default: return null;
908
+ }
909
+ };
910
+ const valueToExpression = (value) => {
911
+ if (typeof value === "string") return import_lib$1.stringLiteral(value);
912
+ if (typeof value === "number") return value < 0 ? import_lib$1.unaryExpression("-", import_lib$1.numericLiteral(-value)) : import_lib$1.numericLiteral(value);
913
+ if (typeof value === "boolean") return import_lib$1.booleanLiteral(value);
914
+ if (value === null) return import_lib$1.nullLiteral();
915
+ if (Array.isArray(value)) return import_lib$1.arrayExpression(value.map((item) => valueToExpression(item) ?? import_lib$1.nullLiteral()));
916
+ if (typeof value === "object") {
917
+ const properties = [];
918
+ for (const [key, item] of Object.entries(value)) {
919
+ const expr = valueToExpression(item);
920
+ if (expr === null) continue;
921
+ properties.push(import_lib$1.objectProperty(import_lib$1.stringLiteral(key), expr));
922
+ }
923
+ return import_lib$1.objectExpression(properties);
924
+ }
925
+ return null;
926
+ };
927
+ const arrayExpressionToCode = (elements) => {
928
+ const nextAst = import_lib$1.arrayExpression(elements);
929
+ return generateCode(nextAst);
930
+ };
931
+ //#endregion
932
+ //#region src/utils/ast/edit-source.ts
1011
933
  const childrenRange = (element) => {
1012
934
  const { openingElement, closingElement } = element;
1013
935
  if (!closingElement || openingElement.end == null || closingElement.start == null) return null;
@@ -1186,7 +1108,139 @@ const canEditAttributeValue = (attribute, value, type) => {
1186
1108
  if (!import_lib$1.isJSXExpressionContainer(attribute.value) || import_lib$1.isJSXEmptyExpression(attribute.value.expression) || isLosslesslyEvaluable(attribute.value.expression)) return true;
1187
1109
  return typeof value === "string" && holdsStructuralExpression(attribute.value) && !(type && STRING_VALUED_TYPES.has(type)) && structuralSource(value) !== null;
1188
1110
  };
1111
+ //#endregion
1112
+ //#region src/utils/ast/update.ts
1113
+ const hasDataId = (opening, dataId) => opening.attributes.some((attr) => import_lib$1.isJSXAttribute(attr) && import_lib$1.isJSXIdentifier(attr.name) && attr.name.name === DATA_ATTR.ID && attr.value && import_lib$1.isStringLiteral(attr.value) && attr.value.value === dataId);
1114
+ const findJSXAttribute = (opening, name) => opening.attributes.find((attr) => import_lib$1.isJSXAttribute(attr) && import_lib$1.isJSXIdentifier(attr.name) && attr.name.name === name);
1115
+ const findBinding = (opening, { dataId, label, property, options }) => {
1116
+ const bindingAttr = findJSXAttribute(opening, DATA_ATTR.BINDING);
1117
+ if (bindingAttr && !bindingAttr.value) return { failure: {
1118
+ reason: "no-binding",
1119
+ dataId
1120
+ } };
1121
+ let own;
1122
+ if (bindingAttr?.value) {
1123
+ let bindingValue = "";
1124
+ if (import_lib$1.isStringLiteral(bindingAttr.value)) bindingValue = bindingAttr.value.value;
1125
+ else if (import_lib$1.isJSXExpressionContainer(bindingAttr.value)) try {
1126
+ bindingValue = generateCode(bindingAttr.value.expression);
1127
+ } catch (error) {
1128
+ return { failure: {
1129
+ reason: "parse-error",
1130
+ error
1131
+ } };
1132
+ }
1133
+ own = parseBinding(bindingValue);
1134
+ }
1135
+ const keyAttr = findJSXAttribute(opening, DATA_ATTR.BINDING_KEY);
1136
+ const bindings = resolveBindings(own, keyAttr && (keyAttr.value && import_lib$1.isStringLiteral(keyAttr.value) ? keyAttr.value.value : null), getJSXTagName(opening), options);
1137
+ if (!own && bindings.length === 0) return { failure: {
1138
+ reason: "no-binding",
1139
+ dataId
1140
+ } };
1141
+ const matches = bindings.filter((binding) => property !== void 0 ? binding.property === property : binding.label === label);
1142
+ if (matches.length === 0) return { failure: {
1143
+ reason: "binding-not-declared",
1144
+ dataId,
1145
+ label,
1146
+ property
1147
+ } };
1148
+ if (matches.length > 1) return { failure: {
1149
+ reason: "duplicate-binding",
1150
+ dataId,
1151
+ label,
1152
+ property,
1153
+ count: matches.length
1154
+ } };
1155
+ return { binding: matches[0] };
1156
+ };
1157
+ const checkEdit = (binding, { dataId, value }) => {
1158
+ const property = binding.property;
1159
+ if (RESERVED_BINDING_PROPERTIES.includes(property)) return {
1160
+ reason: "reserved-property",
1161
+ dataId,
1162
+ property
1163
+ };
1164
+ if (value === void 0 && binding.required) return {
1165
+ reason: "required-property",
1166
+ dataId,
1167
+ property
1168
+ };
1169
+ };
1170
+ const toElementEdit = (result, onNull) => result ? { edits: result } : { failure: onNull() };
1171
+ const editProperty = (source, element, binding, { dataId, value, options }) => {
1172
+ const opening = element.openingElement;
1173
+ const prop = binding.property;
1174
+ const unset = value === void 0;
1175
+ const couldNotUpdate = () => ({
1176
+ reason: "parse-error",
1177
+ error: /* @__PURE__ */ new Error(`could not update "${prop}"`)
1178
+ });
1179
+ const contentWithoutSlot = !unset && String(value) !== "" && !childrenRange(element);
1180
+ switch (prop) {
1181
+ case BINDING_PROP.INNER_TEXT:
1182
+ if (contentWithoutSlot) return { failure: {
1183
+ reason: "self-closing",
1184
+ dataId,
1185
+ property: prop
1186
+ } };
1187
+ return toElementEdit(editInnerText(source, element, unset ? "" : String(value)), couldNotUpdate);
1188
+ case BINDING_PROP.INNER_HTML:
1189
+ if (contentWithoutSlot && binding.type !== "richtext") return { failure: {
1190
+ reason: "self-closing",
1191
+ dataId,
1192
+ property: prop
1193
+ } };
1194
+ return toElementEdit(binding.type === "richtext" ? editRichtext(element, unset ? "" : String(value)) : editInnerHTML(element, unset ? "" : String(value)), couldNotUpdate);
1195
+ case BINDING_PROP.CHILDREN:
1196
+ if (unset) return { failure: {
1197
+ reason: "unsupported-syntax",
1198
+ dataId,
1199
+ property: prop
1200
+ } };
1201
+ return toElementEdit(editChildrenSource(source, element, value, options), () => ({
1202
+ reason: "parse-error",
1203
+ error: /* @__PURE__ */ new Error("Unsupported or stale children edit; source was preserved")
1204
+ }));
1205
+ default: {
1206
+ const attribute = findAttribute(opening, prop);
1207
+ if (unset) return toElementEdit(attribute ? removeAttribute(source, attribute) : [], () => ({
1208
+ reason: "parse-error",
1209
+ error: /* @__PURE__ */ new Error(`could not remove "${prop}"`)
1210
+ }));
1211
+ if (!attribute) return toElementEdit(value === "" ? [] : addAttribute(source, opening, prop, value, binding.type), () => ({
1212
+ reason: "attribute-not-found",
1213
+ dataId,
1214
+ property: prop
1215
+ }));
1216
+ if (binding.type !== "jsx" && !canEditAttributeValue(attribute, value, binding.type)) return { failure: {
1217
+ reason: "unsupported-syntax",
1218
+ dataId,
1219
+ property: prop
1220
+ } };
1221
+ return toElementEdit(binding.type === "jsx" ? editJsxAttribute(opening, prop, value) : editAttribute(opening, prop, value, binding.type), () => ({
1222
+ reason: "attribute-not-found",
1223
+ dataId,
1224
+ property: prop
1225
+ }));
1226
+ }
1227
+ }
1228
+ };
1229
+ const editElement = (source, element, request) => {
1230
+ const found = findBinding(element.openingElement, request);
1231
+ if ("failure" in found) return found;
1232
+ const refused = checkEdit(found.binding, request);
1233
+ if (refused) return { failure: refused };
1234
+ return editProperty(source, element, found.binding, request);
1235
+ };
1189
1236
  const update = (code, dataId, label, value, property, options = {}) => {
1237
+ const request = {
1238
+ dataId,
1239
+ label,
1240
+ value,
1241
+ property,
1242
+ options
1243
+ };
1190
1244
  try {
1191
1245
  const wrapped = wrap(code);
1192
1246
  const ast = (0, import_lib.parse)(wrapped, {
@@ -1196,150 +1250,15 @@ const update = (code, dataId, label, value, property, options = {}) => {
1196
1250
  let changed = false;
1197
1251
  let failure;
1198
1252
  const edits = [];
1199
- const collect = (result, onNull) => {
1200
- if (!result) {
1201
- failure = onNull();
1202
- return;
1203
- }
1204
- edits.push(...result);
1205
- changed = true;
1206
- };
1207
1253
  traverse(ast, { JSXElement(path) {
1208
- const opening = path.node.openingElement;
1209
- if (!opening.attributes.find((attr) => {
1210
- return import_lib$1.isJSXAttribute(attr) && import_lib$1.isJSXIdentifier(attr.name) && attr.name.name === DATA_ATTR.ID && attr.value && import_lib$1.isStringLiteral(attr.value) && attr.value.value === dataId;
1211
- })) return;
1212
- const bindingAttr = opening.attributes.find((attr) => import_lib$1.isJSXAttribute(attr) && import_lib$1.isJSXIdentifier(attr.name) && attr.name.name === DATA_ATTR.BINDING);
1213
- if (bindingAttr && !bindingAttr.value) {
1214
- failure = {
1215
- reason: "no-binding",
1216
- dataId
1217
- };
1254
+ if (!hasDataId(path.node.openingElement, dataId)) return;
1255
+ const result = editElement(wrapped, path.node, request);
1256
+ if ("failure" in result) {
1257
+ failure = result.failure;
1218
1258
  return;
1219
1259
  }
1220
- let own;
1221
- if (bindingAttr?.value) {
1222
- let bindingValue = "";
1223
- if (import_lib$1.isStringLiteral(bindingAttr.value)) bindingValue = bindingAttr.value.value;
1224
- else if (import_lib$1.isJSXExpressionContainer(bindingAttr.value)) try {
1225
- bindingValue = generateCode(bindingAttr.value.expression);
1226
- } catch (error) {
1227
- failure = {
1228
- reason: "parse-error",
1229
- error
1230
- };
1231
- return;
1232
- }
1233
- own = parseBinding(bindingValue);
1234
- }
1235
- const keyAttr = opening.attributes.find((attr) => import_lib$1.isJSXAttribute(attr) && import_lib$1.isJSXIdentifier(attr.name) && attr.name.name === DATA_ATTR.BINDING_KEY);
1236
- const bindings = resolveBindings(own, keyAttr && (keyAttr.value && import_lib$1.isStringLiteral(keyAttr.value) ? keyAttr.value.value : null), getJSXTagName(opening), options);
1237
- if (!own && bindings.length === 0) {
1238
- failure = {
1239
- reason: "no-binding",
1240
- dataId
1241
- };
1242
- return;
1243
- }
1244
- const matches = bindings.filter((binding) => property !== void 0 ? binding.property === property : binding.label === label);
1245
- if (matches.length === 0) {
1246
- failure = {
1247
- reason: "binding-not-declared",
1248
- dataId,
1249
- label,
1250
- property
1251
- };
1252
- return;
1253
- }
1254
- if (matches.length > 1) {
1255
- failure = {
1256
- reason: "duplicate-binding",
1257
- dataId,
1258
- label,
1259
- property,
1260
- count: matches.length
1261
- };
1262
- return;
1263
- }
1264
- const propertyBinding = matches[0];
1265
- const prop = propertyBinding.property;
1266
- if (RESERVED_BINDING_PROPERTIES.includes(prop)) {
1267
- failure = {
1268
- reason: "reserved-property",
1269
- dataId,
1270
- property: prop
1271
- };
1272
- return;
1273
- }
1274
- const unset = value === void 0;
1275
- if (unset && propertyBinding.required) {
1276
- failure = {
1277
- reason: "required-property",
1278
- dataId,
1279
- property: prop
1280
- };
1281
- return;
1282
- }
1283
- switch (prop) {
1284
- case BINDING_PROP.INNER_TEXT:
1285
- collect(editInnerText(wrapped, path.node, unset ? "" : String(value)), () => ({
1286
- reason: "parse-error",
1287
- error: /* @__PURE__ */ new Error(`could not update "${prop}"`)
1288
- }));
1289
- break;
1290
- case BINDING_PROP.INNER_HTML:
1291
- collect(propertyBinding.type === "richtext" ? editRichtext(path.node, unset ? "" : String(value)) : editInnerHTML(path.node, unset ? "" : String(value)), () => ({
1292
- reason: "parse-error",
1293
- error: /* @__PURE__ */ new Error(`could not update "${prop}"`)
1294
- }));
1295
- break;
1296
- case BINDING_PROP.CHILDREN:
1297
- if (unset) {
1298
- failure = {
1299
- reason: "unsupported-syntax",
1300
- dataId,
1301
- property: prop
1302
- };
1303
- break;
1304
- }
1305
- collect(editChildrenSource(wrapped, path.node, value, options), () => ({
1306
- reason: "parse-error",
1307
- error: /* @__PURE__ */ new Error("Unsupported or stale children edit; source was preserved")
1308
- }));
1309
- break;
1310
- default: {
1311
- const attribute = findAttribute(opening, prop);
1312
- if (unset) {
1313
- collect(attribute ? removeAttribute(wrapped, attribute) : [], () => ({
1314
- reason: "parse-error",
1315
- error: /* @__PURE__ */ new Error(`could not remove "${prop}"`)
1316
- }));
1317
- break;
1318
- }
1319
- if (!attribute) {
1320
- collect(value === "" ? [] : addAttribute(wrapped, opening, prop, value, propertyBinding.type), () => ({
1321
- reason: "attribute-not-found",
1322
- dataId,
1323
- property: prop
1324
- }));
1325
- break;
1326
- }
1327
- if (attribute && propertyBinding.type !== "jsx" && !canEditAttributeValue(attribute, value, propertyBinding.type)) {
1328
- failure = {
1329
- reason: "unsupported-syntax",
1330
- dataId,
1331
- property: prop
1332
- };
1333
- break;
1334
- }
1335
- collect(propertyBinding.type === "jsx" ? editJsxAttribute(opening, prop, value) : editAttribute(opening, prop, value, propertyBinding.type), () => ({
1336
- reason: "attribute-not-found",
1337
- dataId,
1338
- property: prop
1339
- }));
1340
- break;
1341
- }
1342
- }
1260
+ edits.push(...result.edits);
1261
+ changed = true;
1343
1262
  } });
1344
1263
  if (!changed) return {
1345
1264
  code,
@@ -1639,6 +1558,6 @@ const appendArrayItem = (code, kind, generateId = () => nanoid(6)) => {
1639
1558
  return index < 0 ? null : duplicateArrayItems(code, /* @__PURE__ */ new Set([index]), generateId);
1640
1559
  };
1641
1560
  //#endregion
1642
- export { extractNodeValue as A, parseBinding as C, arrayExpressionToCode as D, resolveBindings as E, setEditableValue as F, flattenEditableValue as M, parseArrayExpression as N, canLosslesslyEvaluateSource as O, parseValue as P, isComponentTagName as S, readNodeBindings as T, findEditableChildren as _, parseItems as a, getRegistryBindings as b, updateArrayItemValue as c, update as d, updateAll as f, extract as g, clearExtractCache as h, moveArrayItems as i, extractObjectProperties as j, createNodeFromValue as k, canStructurallyEditArray as l, moveSelectedIndices as m, duplicateArrayItems as n, removeArrayItems as o, getChildrenSignatures as p, moveArrayItem as r, updateArrayItemProperty as s, appendArrayItem as t, bulkUpdate as u, getCurrentValue as v, parseBindingExpression as w, getStructuredValue as x, getKeyBindings as y };
1561
+ export { extractNodeValue as A, getStructuredValue as C, readNodeBindings as D, parseBindingExpression as E, parseArrayExpression as M, parseValue as N, resolveBindings as O, unwrapExpression as P, getRegistryBindings as S, parseBinding as T, clearExtractCache as _, parseItems as a, getCurrentValue as b, updateArrayItemValue as c, update as d, updateAll as f, moveSelectedIndices as g, getChildrenSignatures as h, moveArrayItems as i, extractObjectProperties as j, canLosslesslyEvaluateSource as k, canStructurallyEditArray as l, createNodeFromValue as m, duplicateArrayItems as n, removeArrayItems as o, arrayExpressionToCode as p, moveArrayItem as r, updateArrayItemProperty as s, appendArrayItem as t, bulkUpdate as u, extract as v, isComponentTagName as w, getKeyBindings as x, findEditableChildren as y };
1643
1562
 
1644
- //# sourceMappingURL=items-DdrwGxJw.js.map
1563
+ //# sourceMappingURL=items-B6OXxcLG.js.map