@jbpark/live-editor 4.1.1 → 4.3.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 (58) hide show
  1. package/README.ko.md +1 -1
  2. package/README.md +1 -1
  3. package/dist/{ast-jab6hQrT.js → ast-BFbDWO-l.js} +288 -229
  4. package/dist/ast-BFbDWO-l.js.map +1 -0
  5. package/dist/{boundary-D2IFja-3.js → boundary-B17cepvm.js} +12 -9
  6. package/dist/boundary-B17cepvm.js.map +1 -0
  7. package/dist/{compile-CBOAtQMz.js → compile-0Dvp8zp5.js} +37 -5
  8. package/dist/compile-0Dvp8zp5.js.map +1 -0
  9. package/dist/{constants-BD3FZKWE.js → constants-CKvdqZtO.js} +11 -4
  10. package/dist/constants-CKvdqZtO.js.map +1 -0
  11. package/dist/{context-DQ-UtoyS.js → context-93X3gyfJ.js} +2 -2
  12. package/dist/{context-DQ-UtoyS.js.map → context-93X3gyfJ.js.map} +1 -1
  13. package/dist/{core-DaXVtvH5.js → core-B3ruccKb.js} +2 -2
  14. package/dist/{core-DaXVtvH5.js.map → core-B3ruccKb.js.map} +1 -1
  15. package/dist/{detect-typescript-b0A751v2.js → detect-typescript-5MV4mCM7.js} +2 -2
  16. package/dist/{detect-typescript-b0A751v2.js.map → detect-typescript-5MV4mCM7.js.map} +1 -1
  17. package/dist/dnd/index.d.ts +2 -2
  18. package/dist/dnd/index.js +2 -2
  19. package/dist/{dnd-CMrXfD8O.js → dnd-Z1KS16Fy.js} +969 -322
  20. package/dist/dnd-Z1KS16Fy.js.map +1 -0
  21. package/dist/{document-J9Lo9p81.d.ts → document-Ct4jW78J.d.ts} +42 -22
  22. package/dist/{document-C5Dypv4_.js → document-cEEdFERz.js} +138 -46
  23. package/dist/document-cEEdFERz.js.map +1 -0
  24. package/dist/editor/index.js +2 -2
  25. package/dist/{editor-C3tQaMlU.js → editor-DvMruljw.js} +2 -2
  26. package/dist/{editor-C3tQaMlU.js.map → editor-DvMruljw.js.map} +1 -1
  27. package/dist/error/index.d.ts +1 -1
  28. package/dist/error/index.js +2 -2
  29. package/dist/{error-KW8XCcjH.js → error-DWhxQEom.js} +2 -2
  30. package/dist/{error-KW8XCcjH.js.map → error-DWhxQEom.js.map} +1 -1
  31. package/dist/{index-DNNj_0ba.d.ts → index-C4SGQ3Ci.d.ts} +4 -3
  32. package/dist/{index-C4t0OawE.d.ts → index-CtlUYnWq.d.ts} +131 -34
  33. package/dist/{index-B_p74BRM.d.ts → index-w3kLcCXl.d.ts} +29 -5
  34. package/dist/index.d.ts +5 -5
  35. package/dist/index.js +5 -5
  36. package/dist/index.js.map +1 -1
  37. package/dist/preview/index.js +2 -2
  38. package/dist/{preview-BwEfltgi.js → preview-C_UzpGWh.js} +3 -3
  39. package/dist/{preview-BwEfltgi.js.map → preview-C_UzpGWh.js.map} +1 -1
  40. package/dist/provider/index.js +1 -1
  41. package/dist/sections-GJQ63uEB.js +24 -0
  42. package/dist/sections-GJQ63uEB.js.map +1 -0
  43. package/dist/{use-dynamic-tailwind-DuGLeDR3.js → use-dynamic-tailwind-DpbjmATF.js} +20 -11
  44. package/dist/use-dynamic-tailwind-DpbjmATF.js.map +1 -0
  45. package/dist/utils/ast/index.d.ts +3 -3
  46. package/dist/utils/ast/index.js +3 -3
  47. package/dist/utils/index.d.ts +7 -6
  48. package/dist/utils/index.js +5 -5
  49. package/package.json +1 -1
  50. package/dist/ast-jab6hQrT.js.map +0 -1
  51. package/dist/boundary-D2IFja-3.js.map +0 -1
  52. package/dist/compile-CBOAtQMz.js.map +0 -1
  53. package/dist/constants-BD3FZKWE.js.map +0 -1
  54. package/dist/dnd-CMrXfD8O.js.map +0 -1
  55. package/dist/document-C5Dypv4_.js.map +0 -1
  56. package/dist/sections-B7dWoNVJ.js +0 -19
  57. package/dist/sections-B7dWoNVJ.js.map +0 -1
  58. package/dist/use-dynamic-tailwind-DuGLeDR3.js.map +0 -1
@@ -1,11 +1,11 @@
1
- import { d as nanoid, f as require_lib, h as __toESM, m as require_lib$1, p as require_lib$2, u as traverse } from "./document-C5Dypv4_.js";
2
- import { n as CONFIG, o as REGEX, r as DATA_ATTR, t as BINDING_PROP } from "./constants-BD3FZKWE.js";
1
+ import { C as require_lib, S as require_lib$1, _ as nanoid, b as unwrap, d as traverse, g as getJSXTagName, v as attrValue, w as __toESM, x as wrap, y as generateCode } from "./document-cEEdFERz.js";
2
+ import { c as RESERVED_BINDING_PROPERTIES, n as CONFIG, r as DATA_ATTR, s as REGEX, t as BINDING_PROP } from "./constants-CKvdqZtO.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";
6
6
  //#region src/utils/ast/types.ts
7
- var import_lib$1 = require_lib$1();
8
- var import_lib$2 = /* @__PURE__ */ __toESM(require_lib$2(), 1);
7
+ var import_lib = require_lib();
8
+ var import_lib$1 = /* @__PURE__ */ __toESM(require_lib$1(), 1);
9
9
  const BINDING_TYPES = [
10
10
  "array",
11
11
  "object",
@@ -19,35 +19,6 @@ const BINDING_TYPES = [
19
19
  "url"
20
20
  ];
21
21
  //#endregion
22
- //#region src/utils/ast/helpers.ts
23
- var import_lib = /* @__PURE__ */ __toESM(require_lib(), 1);
24
- const generate = typeof import_lib.default === "function" ? import_lib.default : import_lib.default.default;
25
- const wrap = (code) => {
26
- return `<>${code}</>`;
27
- };
28
- const unwrap = (generated) => {
29
- return generated.replace(/^<>\s*/g, "").replace(/\s*<\/>\s*;?\s*$/g, "").trim();
30
- };
31
- const attrValue = ({ value, isStringLiteral }) => {
32
- if (value === null) return null;
33
- if (isStringLiteral) return import_lib$2.stringLiteral(value);
34
- const trimmed = value.trim();
35
- if (REGEX.NUMBER.test(trimmed)) return import_lib$2.jsxExpressionContainer(import_lib$2.numericLiteral(parseFloat(trimmed)));
36
- if (REGEX.BOOLEAN_OR_NULL.test(trimmed)) {
37
- const expr = (0, import_lib$1.parseExpression)(trimmed, { plugins: ["jsx", "typescript"] });
38
- return import_lib$2.jsxExpressionContainer(expr);
39
- }
40
- try {
41
- const expr = (0, import_lib$1.parseExpression)(trimmed, { plugins: ["jsx", "typescript"] });
42
- return import_lib$2.jsxExpressionContainer(expr);
43
- } catch {
44
- return import_lib$2.stringLiteral(trimmed);
45
- }
46
- };
47
- const generateCode = (node) => {
48
- return generate(node, { jsescOption: { minimal: true } }).code;
49
- };
50
- //#endregion
51
22
  //#region src/utils/ast/value.ts
52
23
  const dedent = (str) => {
53
24
  const lines = str.replace(/^\n/, "").replace(/\n\s*$/, "").split("\n");
@@ -60,44 +31,44 @@ const dedent = (str) => {
60
31
  };
61
32
  const unwrapExpression = (node) => {
62
33
  let current = node;
63
- while (import_lib$2.isTSAsExpression(current) || import_lib$2.isTSSatisfiesExpression(current) || import_lib$2.isTSNonNullExpression(current) || import_lib$2.isTSTypeAssertion(current) || import_lib$2.isParenthesizedExpression(current)) current = current.expression;
34
+ while (import_lib$1.isTSAsExpression(current) || import_lib$1.isTSSatisfiesExpression(current) || import_lib$1.isTSNonNullExpression(current) || import_lib$1.isTSTypeAssertion(current) || import_lib$1.isParenthesizedExpression(current)) current = current.expression;
64
35
  return current;
65
36
  };
66
37
  const isLosslesslyEvaluable = (node) => {
67
38
  const value = unwrapExpression(node);
68
- if (import_lib$2.isStringLiteral(value) || import_lib$2.isNumericLiteral(value) || import_lib$2.isBooleanLiteral(value) || import_lib$2.isNullLiteral(value)) return true;
69
- if (import_lib$2.isUnaryExpression(value) && value.operator === "-" && import_lib$2.isNumericLiteral(value.argument)) return true;
70
- if (import_lib$2.isTemplateLiteral(value)) return value.expressions.length === 0;
71
- if (import_lib$2.isArrayExpression(value)) return value.elements.every((element) => element !== null && isLosslesslyEvaluable(element));
72
- if (import_lib$2.isObjectExpression(value)) return value.properties.every((property) => import_lib$2.isObjectProperty(property) && !property.computed && (import_lib$2.isIdentifier(property.key) || import_lib$2.isStringLiteral(property.key) || import_lib$2.isNumericLiteral(property.key)) && isLosslesslyEvaluable(property.value));
39
+ if (import_lib$1.isStringLiteral(value) || import_lib$1.isNumericLiteral(value) || import_lib$1.isBooleanLiteral(value) || import_lib$1.isNullLiteral(value)) return true;
40
+ if (import_lib$1.isUnaryExpression(value) && value.operator === "-" && import_lib$1.isNumericLiteral(value.argument)) return true;
41
+ if (import_lib$1.isTemplateLiteral(value)) return value.expressions.length === 0;
42
+ if (import_lib$1.isArrayExpression(value)) return value.elements.every((element) => element !== null && isLosslesslyEvaluable(element));
43
+ if (import_lib$1.isObjectExpression(value)) return value.properties.every((property) => import_lib$1.isObjectProperty(property) && !property.computed && (import_lib$1.isIdentifier(property.key) || import_lib$1.isStringLiteral(property.key) || import_lib$1.isNumericLiteral(property.key)) && isLosslesslyEvaluable(property.value));
73
44
  return false;
74
45
  };
75
46
  const canLosslesslyEvaluateSource = (source) => {
76
47
  try {
77
- return isLosslesslyEvaluable((0, import_lib$1.parseExpression)(source, { plugins: ["jsx", "typescript"] }));
48
+ return isLosslesslyEvaluable((0, import_lib.parseExpression)(source, { plugins: ["jsx", "typescript"] }));
78
49
  } catch {
79
50
  return false;
80
51
  }
81
52
  };
82
53
  const evaluateLiteral = (rawNode) => {
83
54
  const node = unwrapExpression(rawNode);
84
- if (import_lib$2.isStringLiteral(node)) return node.value;
85
- if (import_lib$2.isNumericLiteral(node)) return node.value;
86
- if (import_lib$2.isBooleanLiteral(node)) return node.value;
87
- if (import_lib$2.isNullLiteral(node)) return null;
88
- if (import_lib$2.isIdentifier(node) && node.name === "undefined") return;
89
- if (import_lib$2.isUnaryExpression(node) && node.operator === "-" && import_lib$2.isNumericLiteral(node.argument)) return -node.argument.value;
90
- if (import_lib$2.isTemplateLiteral(node) && node.expressions.length === 0) return node.quasis[0]?.value.cooked ?? node.quasis[0]?.value.raw ?? "";
91
- if (import_lib$2.isJSXElement(node) || import_lib$2.isJSXFragment(node)) return generateCode(node);
92
- if (import_lib$2.isArrayExpression(node)) return node.elements.map((element) => element ? evaluateLiteral(element) : null);
93
- if (import_lib$2.isObjectExpression(node)) {
55
+ if (import_lib$1.isStringLiteral(node)) return node.value;
56
+ if (import_lib$1.isNumericLiteral(node)) return node.value;
57
+ if (import_lib$1.isBooleanLiteral(node)) return node.value;
58
+ if (import_lib$1.isNullLiteral(node)) return null;
59
+ if (import_lib$1.isIdentifier(node) && node.name === "undefined") return;
60
+ if (import_lib$1.isUnaryExpression(node) && node.operator === "-" && import_lib$1.isNumericLiteral(node.argument)) return -node.argument.value;
61
+ if (import_lib$1.isTemplateLiteral(node) && node.expressions.length === 0) return node.quasis[0]?.value.cooked ?? node.quasis[0]?.value.raw ?? "";
62
+ if (import_lib$1.isJSXElement(node) || import_lib$1.isJSXFragment(node)) return generateCode(node);
63
+ if (import_lib$1.isArrayExpression(node)) return node.elements.map((element) => element ? evaluateLiteral(element) : null);
64
+ if (import_lib$1.isObjectExpression(node)) {
94
65
  const result = {};
95
66
  for (const prop of node.properties) {
96
- if (!import_lib$2.isObjectProperty(prop)) continue;
67
+ if (!import_lib$1.isObjectProperty(prop)) continue;
97
68
  let key = null;
98
- if (import_lib$2.isIdentifier(prop.key)) key = prop.key.name;
99
- else if (import_lib$2.isStringLiteral(prop.key)) key = prop.key.value;
100
- else if (import_lib$2.isNumericLiteral(prop.key)) key = String(prop.key.value);
69
+ if (import_lib$1.isIdentifier(prop.key)) key = prop.key.name;
70
+ else if (import_lib$1.isStringLiteral(prop.key)) key = prop.key.value;
71
+ else if (import_lib$1.isNumericLiteral(prop.key)) key = String(prop.key.value);
101
72
  if (key === null) continue;
102
73
  result[key] = evaluateLiteral(prop.value);
103
74
  }
@@ -117,8 +88,8 @@ const parseValue = (value) => {
117
88
  }
118
89
  if (trimmed.startsWith("{") && trimmed.endsWith("}") || trimmed.startsWith("[") && trimmed.endsWith("]")) {
119
90
  try {
120
- const ast = (0, import_lib$1.parseExpression)(trimmed, { plugins: ["jsx", "typescript"] });
121
- if (import_lib$2.isObjectExpression(ast) || import_lib$2.isArrayExpression(ast)) return evaluateLiteral(ast);
91
+ const ast = (0, import_lib.parseExpression)(trimmed, { plugins: ["jsx", "typescript"] });
92
+ if (import_lib$1.isObjectExpression(ast) || import_lib$1.isArrayExpression(ast)) return evaluateLiteral(ast);
122
93
  } catch {}
123
94
  return value;
124
95
  }
@@ -148,43 +119,80 @@ const flattenEditableValue = (value) => {
148
119
  walk(parsed, [], 0);
149
120
  return entries.length ? entries : null;
150
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
+ };
151
167
  const setEditableValue = (value, path, next) => {
152
168
  if (!path.length) return value;
153
- const parsed = parseValue(value);
154
- if (typeof parsed !== "object" || parsed === null) return value;
155
- const root = Array.isArray(parsed) ? [...parsed] : { ...parsed };
156
- let cursor = root;
157
- for (let i = 0; i < path.length - 1; i++) {
158
- const key = path[i];
159
- const child = cursor[key];
160
- if (typeof child !== "object" || child === null) return value;
161
- const clonedChild = Array.isArray(child) ? [...child] : { ...child };
162
- cursor[key] = clonedChild;
163
- cursor = clonedChild;
169
+ let leaf;
170
+ try {
171
+ leaf = findEditableLeaf((0, import_lib.parseExpression)(value, { plugins: ["jsx", "typescript"] }), path);
172
+ } catch {
173
+ return value;
164
174
  }
165
- const lastKey = path[path.length - 1];
166
- if (!(lastKey in cursor)) return value;
167
- cursor[lastKey] = next;
168
- return JSON.stringify(root);
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)}`;
169
177
  };
170
178
  const extractNodeValue = (node) => {
171
- if (import_lib$2.isBooleanLiteral(node)) return {
179
+ if (import_lib$1.isBooleanLiteral(node)) return {
172
180
  type: "boolean",
173
181
  value: node.value
174
182
  };
175
- if (import_lib$2.isNumericLiteral(node)) return {
183
+ if (import_lib$1.isNumericLiteral(node)) return {
176
184
  type: "number",
177
185
  value: node.value
178
186
  };
179
- if (import_lib$2.isUnaryExpression(node) && node.operator === "-" && import_lib$2.isNumericLiteral(node.argument)) return {
187
+ if (import_lib$1.isUnaryExpression(node) && node.operator === "-" && import_lib$1.isNumericLiteral(node.argument)) return {
180
188
  type: "number",
181
189
  value: -node.argument.value
182
190
  };
183
- if (import_lib$2.isStringLiteral(node)) return {
191
+ if (import_lib$1.isStringLiteral(node)) return {
184
192
  type: "string",
185
193
  value: node.value
186
194
  };
187
- if (import_lib$2.isTemplateLiteral(node)) {
195
+ if (import_lib$1.isTemplateLiteral(node)) {
188
196
  if (node.expressions.length === 0 && node.quasis.length === 1) return {
189
197
  type: "string",
190
198
  value: dedent(node.quasis[0].value.cooked ?? node.quasis[0].value.raw)
@@ -194,19 +202,19 @@ const extractNodeValue = (node) => {
194
202
  value: generateCode(node)
195
203
  };
196
204
  }
197
- if (import_lib$2.isNullLiteral(node)) return {
205
+ if (import_lib$1.isNullLiteral(node)) return {
198
206
  type: "null",
199
207
  value: null
200
208
  };
201
- if (import_lib$2.isArrayExpression(node)) return {
209
+ if (import_lib$1.isArrayExpression(node)) return {
202
210
  type: "array",
203
211
  value: generateCode(node)
204
212
  };
205
- if (import_lib$2.isObjectExpression(node)) return {
213
+ if (import_lib$1.isObjectExpression(node)) return {
206
214
  type: "object",
207
215
  value: generateCode(node)
208
216
  };
209
- if (import_lib$2.isJSXElement(node) || import_lib$2.isJSXFragment(node)) return {
217
+ if (import_lib$1.isJSXElement(node) || import_lib$1.isJSXFragment(node)) return {
210
218
  type: "string",
211
219
  value: generateCode(node)
212
220
  };
@@ -217,10 +225,10 @@ const extractNodeValue = (node) => {
217
225
  };
218
226
  const createNodeFromValue = (type, value) => {
219
227
  switch (type) {
220
- case "boolean": return import_lib$2.booleanLiteral(value === true);
221
- case "number": return import_lib$2.numericLiteral(Number(value));
222
- case "string": return import_lib$2.stringLiteral(String(value));
223
- case "null": return import_lib$2.nullLiteral();
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();
224
232
  case "array":
225
233
  case "object":
226
234
  case "unknown": return null;
@@ -228,26 +236,26 @@ const createNodeFromValue = (type, value) => {
228
236
  }
229
237
  };
230
238
  const valueToExpression = (value) => {
231
- if (typeof value === "string") return import_lib$2.stringLiteral(value);
232
- if (typeof value === "number") return value < 0 ? import_lib$2.unaryExpression("-", import_lib$2.numericLiteral(-value)) : import_lib$2.numericLiteral(value);
233
- if (typeof value === "boolean") return import_lib$2.booleanLiteral(value);
234
- if (value === null) return import_lib$2.nullLiteral();
235
- if (Array.isArray(value)) return import_lib$2.arrayExpression(value.map((item) => valueToExpression(item) ?? import_lib$2.nullLiteral()));
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()));
236
244
  if (typeof value === "object") {
237
245
  const properties = [];
238
246
  for (const [key, item] of Object.entries(value)) {
239
247
  const expr = valueToExpression(item);
240
248
  if (expr === null) continue;
241
- properties.push(import_lib$2.objectProperty(import_lib$2.stringLiteral(key), expr));
249
+ properties.push(import_lib$1.objectProperty(import_lib$1.stringLiteral(key), expr));
242
250
  }
243
- return import_lib$2.objectExpression(properties);
251
+ return import_lib$1.objectExpression(properties);
244
252
  }
245
253
  return null;
246
254
  };
247
255
  const parseArrayExpression = (value) => {
248
256
  try {
249
- const ast = unwrapExpression((0, import_lib$1.parseExpression)(value, { plugins: ["jsx", "typescript"] }));
250
- if (!import_lib$2.isArrayExpression(ast)) return null;
257
+ const ast = unwrapExpression((0, import_lib.parseExpression)(value, { plugins: ["jsx", "typescript"] }));
258
+ if (!import_lib$1.isArrayExpression(ast)) return null;
251
259
  return ast;
252
260
  } catch (error) {
253
261
  console.error("❌ Array parsing error:", error);
@@ -257,9 +265,9 @@ const parseArrayExpression = (value) => {
257
265
  const extractObjectProperties = (element) => {
258
266
  const properties = {};
259
267
  element.properties.forEach((prop) => {
260
- if (import_lib$2.isObjectProperty(prop) && import_lib$2.isIdentifier(prop.key)) {
268
+ if (import_lib$1.isObjectProperty(prop) && import_lib$1.isIdentifier(prop.key)) {
261
269
  const key = prop.key.name;
262
- if (key === "children" || import_lib$2.isJSXElement(prop.value) || import_lib$2.isJSXFragment(prop.value)) return;
270
+ if (key === "children" || import_lib$1.isJSXElement(prop.value) || import_lib$1.isJSXFragment(prop.value)) return;
263
271
  const extracted = extractNodeValue(prop.value);
264
272
  properties[key] = {
265
273
  ...extracted,
@@ -270,7 +278,7 @@ const extractObjectProperties = (element) => {
270
278
  return properties;
271
279
  };
272
280
  const arrayExpressionToCode = (elements) => {
273
- const nextAst = import_lib$2.arrayExpression(elements);
281
+ const nextAst = import_lib$1.arrayExpression(elements);
274
282
  return generateCode(nextAst);
275
283
  };
276
284
  //#endregion
@@ -377,12 +385,12 @@ const getCurrentValue = (node, property) => {
377
385
  case BINDING_PROP.INNER_HTML: {
378
386
  const dsiAttr = node.attributes.find((a) => a.name === "dangerouslySetInnerHTML");
379
387
  if (dsiAttr?.value) try {
380
- const expr = (0, import_lib$1.parseExpression)(dsiAttr.value, { plugins: ["jsx", "typescript"] });
381
- if (import_lib$2.isObjectExpression(expr)) {
382
- const htmlProp = expr.properties.find((p) => import_lib$2.isObjectProperty(p) && import_lib$2.isIdentifier(p.key) && p.key.name === "__html");
388
+ const expr = (0, import_lib.parseExpression)(dsiAttr.value, { plugins: ["jsx", "typescript"] });
389
+ if (import_lib$1.isObjectExpression(expr)) {
390
+ const htmlProp = expr.properties.find((p) => import_lib$1.isObjectProperty(p) && import_lib$1.isIdentifier(p.key) && p.key.name === "__html");
383
391
  if (htmlProp) {
384
- if (import_lib$2.isStringLiteral(htmlProp.value)) return htmlProp.value.value;
385
- if (import_lib$2.isTemplateLiteral(htmlProp.value) && htmlProp.value.expressions.length === 0) return htmlProp.value.quasis[0]?.value.cooked ?? htmlProp.value.quasis[0]?.value.raw ?? "";
392
+ if (import_lib$1.isStringLiteral(htmlProp.value)) return htmlProp.value.value;
393
+ if (import_lib$1.isTemplateLiteral(htmlProp.value) && htmlProp.value.expressions.length === 0) return htmlProp.value.quasis[0]?.value.cooked ?? htmlProp.value.quasis[0]?.value.raw ?? "";
386
394
  }
387
395
  }
388
396
  } catch {}
@@ -549,7 +557,7 @@ const commaIn = (source, start, end) => {
549
557
  };
550
558
  const denseArraySource = (source) => {
551
559
  const array = parseArrayExpression(source);
552
- if (!array || array.elements.some((node) => !import_lib$2.isExpression(node) || node.extra?.parenthesized)) return null;
560
+ if (!array || array.elements.some((node) => !import_lib$1.isExpression(node) || node.extra?.parenthesized)) return null;
553
561
  const elements = array.elements;
554
562
  const commas = elements.slice(0, -1).map((node, index) => commaIn(source, node.end, elements[index + 1].start));
555
563
  if (commas.some((comma) => comma === null)) return null;
@@ -609,9 +617,9 @@ const appendArraySource = (source, data, copies) => {
609
617
  //#endregion
610
618
  //#region src/utils/ast/items.ts
611
619
  const elementsOf = (code) => parseArrayExpression(code)?.elements ?? null;
612
- const kindOf = (element) => import_lib$2.isObjectExpression(element) ? "object" : "primitive";
620
+ const kindOf = (element) => import_lib$1.isObjectExpression(element) ? "object" : "primitive";
613
621
  const parseItems = (code) => {
614
- return elementsOf(code)?.flatMap((node, index) => import_lib$2.isExpression(node) ? [{
622
+ return elementsOf(code)?.flatMap((node, index) => import_lib$1.isExpression(node) ? [{
615
623
  index,
616
624
  kind: kindOf(node),
617
625
  node
@@ -627,23 +635,23 @@ const toTemplateRaw = (value) => {
627
635
  const buildPropertyValue = (value, declaredType, renderLeaf, current) => {
628
636
  if (renderLeaf?.property === BINDING_PROP.INNER_HTML) {
629
637
  const raw = String(value);
630
- return import_lib$2.templateLiteral([import_lib$2.templateElement({
638
+ return import_lib$1.templateLiteral([import_lib$1.templateElement({
631
639
  raw: toTemplateRaw(raw),
632
640
  cooked: raw
633
641
  }, true)], []);
634
642
  }
635
- if (renderLeaf?.type === "jsx" || import_lib$2.isJSXElement(current) || import_lib$2.isJSXFragment(current)) {
643
+ if (renderLeaf?.type === "jsx" || import_lib$1.isJSXElement(current) || import_lib$1.isJSXFragment(current)) {
636
644
  const trimmed = String(value).trim();
637
- if (!trimmed.startsWith("<")) return import_lib$2.stringLiteral(trimmed);
645
+ if (!trimmed.startsWith("<")) return import_lib$1.stringLiteral(trimmed);
638
646
  try {
639
- return (0, import_lib$1.parseExpression)(trimmed, { plugins: ["jsx", "typescript"] });
647
+ return (0, import_lib.parseExpression)(trimmed, { plugins: ["jsx", "typescript"] });
640
648
  } catch {
641
649
  return;
642
650
  }
643
651
  }
644
652
  if (declaredType === "array" || declaredType === "object") {
645
653
  if (typeof value === "string") try {
646
- return (0, import_lib$1.parseExpression)(value, { plugins: ["jsx", "typescript"] });
654
+ return (0, import_lib.parseExpression)(value, { plugins: ["jsx", "typescript"] });
647
655
  } catch {
648
656
  return;
649
657
  }
@@ -655,13 +663,13 @@ const buildPropertyValue = (value, declaredType, renderLeaf, current) => {
655
663
  const updateArrayItemProperty = (code, index, key, value, render) => {
656
664
  const elements = elementsOf(code);
657
665
  const element = elements?.[index];
658
- if (!elements || !import_lib$2.isObjectExpression(element)) return null;
659
- const target = element.properties.find((property) => import_lib$2.isObjectProperty(property) && import_lib$2.isIdentifier(property.key) && property.key.name === key);
666
+ if (!elements || !import_lib$1.isObjectExpression(element)) return null;
667
+ const target = element.properties.find((property) => import_lib$1.isObjectProperty(property) && import_lib$1.isIdentifier(property.key) && property.key.name === key);
660
668
  if (!target) return null;
661
669
  const declaredType = extractObjectProperties(element)[key]?.type ?? "string";
662
670
  const nextValue = buildPropertyValue(value, declaredType, resolveRenderLeaf(render, key), target.value);
663
671
  if (!nextValue) return null;
664
- let serialized = typeof value === "string" && (declaredType === "array" || declaredType === "object" || import_lib$2.isJSXElement(nextValue) || import_lib$2.isJSXFragment(nextValue)) ? value.trim() : generateCode(nextValue);
672
+ let serialized = typeof value === "string" && (declaredType === "array" || declaredType === "object" || import_lib$1.isJSXElement(nextValue) || import_lib$1.isJSXFragment(nextValue)) ? value.trim() : generateCode(nextValue);
665
673
  if (nextValue.trailingComments?.some((comment) => comment.type === "CommentLine")) serialized += "\n";
666
674
  const content = target.shorthand ? `${key}: ${serialized}` : serialized;
667
675
  return applyEdits(code, [{
@@ -673,7 +681,7 @@ const updateArrayItemProperty = (code, index, key, value, render) => {
673
681
  const updateArrayItemValue = (code, index, value) => {
674
682
  const elements = elementsOf(code);
675
683
  const element = elements?.[index];
676
- if (!elements || !import_lib$2.isExpression(element)) return null;
684
+ if (!elements || !import_lib$1.isExpression(element)) return null;
677
685
  const nextValue = createNodeFromValue(extractNodeValue(element).type, parseValue(value));
678
686
  if (!nextValue) return null;
679
687
  return applyEdits(code, [{
@@ -714,25 +722,25 @@ const copyItem = (code, element, generateId, usedIds) => {
714
722
  usedIds.add(id);
715
723
  return JSON.stringify(id);
716
724
  };
717
- import_lib$2.traverseFast(element, (node) => {
718
- if (!import_lib$2.isJSXOpeningElement(node)) return;
719
- const ids = node.attributes.filter((attr) => import_lib$2.isJSXAttribute(attr) && import_lib$2.isJSXIdentifier(attr.name, { name: "data-id" }));
725
+ import_lib$1.traverseFast(element, (node) => {
726
+ if (!import_lib$1.isJSXOpeningElement(node)) return;
727
+ const ids = node.attributes.filter((attr) => import_lib$1.isJSXAttribute(attr) && import_lib$1.isJSXIdentifier(attr.name, { name: "data-id" }));
720
728
  const attr = ids[0];
721
- if (ids.length > 1 || attr && (!import_lib$2.isStringLiteral(attr.value) || node.attributes.slice(node.attributes.indexOf(attr) + 1).some((a) => import_lib$2.isJSXSpreadAttribute(a)))) {
729
+ if (ids.length > 1 || attr && (!import_lib$1.isStringLiteral(attr.value) || node.attributes.slice(node.attributes.indexOf(attr) + 1).some((a) => import_lib$1.isJSXSpreadAttribute(a)))) {
722
730
  unsupported = true;
723
731
  return;
724
732
  }
725
- if (attr && import_lib$2.isStringLiteral(attr.value)) edits.push({
733
+ if (attr && import_lib$1.isStringLiteral(attr.value)) edits.push({
726
734
  start: attr.value.start,
727
735
  end: attr.value.end,
728
736
  content: reserveId(generateId())
729
737
  });
730
738
  });
731
- if (import_lib$2.isObjectExpression(element)) {
732
- const keys = element.properties.filter((prop) => import_lib$2.isObjectProperty(prop) && !prop.computed && (import_lib$2.isIdentifier(prop.key, { name: "key" }) || import_lib$2.isStringLiteral(prop.key, { value: "key" })));
739
+ if (import_lib$1.isObjectExpression(element)) {
740
+ const keys = element.properties.filter((prop) => import_lib$1.isObjectProperty(prop) && !prop.computed && (import_lib$1.isIdentifier(prop.key, { name: "key" }) || import_lib$1.isStringLiteral(prop.key, { value: "key" })));
733
741
  const key = keys[0];
734
- if (keys.length > 1 || key && (!import_lib$2.isStringLiteral(key.value) || element.properties.slice(element.properties.indexOf(key) + 1).some((prop) => import_lib$2.isSpreadElement(prop) || "computed" in prop && prop.computed))) return null;
735
- if (key && import_lib$2.isStringLiteral(key.value)) edits.push({
742
+ if (keys.length > 1 || key && (!import_lib$1.isStringLiteral(key.value) || element.properties.slice(element.properties.indexOf(key) + 1).some((prop) => import_lib$1.isSpreadElement(prop) || "computed" in prop && prop.computed))) return null;
743
+ if (key && import_lib$1.isStringLiteral(key.value)) edits.push({
736
744
  start: key.value.start,
737
745
  end: key.value.end,
738
746
  content: reserveId(`${key.value.value}-${generateId()}`)
@@ -749,9 +757,9 @@ const duplicateArrayItems = (code, indices, generateId = () => nanoid(6)) => {
749
757
  const data = denseArraySource(code);
750
758
  if (!data || !indices.size || !validArrayIndices(indices, data.elements.length)) return null;
751
759
  const usedIds = /* @__PURE__ */ new Set();
752
- import_lib$2.traverseFast(data.array, (node) => {
753
- if (import_lib$2.isJSXAttribute(node) && import_lib$2.isJSXIdentifier(node.name, { name: "data-id" }) && import_lib$2.isStringLiteral(node.value)) usedIds.add(node.value.value);
754
- else if (import_lib$2.isObjectProperty(node) && !node.computed && (import_lib$2.isIdentifier(node.key, { name: "key" }) || import_lib$2.isStringLiteral(node.key, { value: "key" })) && import_lib$2.isStringLiteral(node.value)) usedIds.add(node.value.value);
760
+ import_lib$1.traverseFast(data.array, (node) => {
761
+ if (import_lib$1.isJSXAttribute(node) && import_lib$1.isJSXIdentifier(node.name, { name: "data-id" }) && import_lib$1.isStringLiteral(node.value)) usedIds.add(node.value.value);
762
+ else if (import_lib$1.isObjectProperty(node) && !node.computed && (import_lib$1.isIdentifier(node.key, { name: "key" }) || import_lib$1.isStringLiteral(node.key, { value: "key" })) && import_lib$1.isStringLiteral(node.value)) usedIds.add(node.value.value);
755
763
  });
756
764
  const copies = [...indices].sort((a, b) => a - b).map((index) => copyItem(code, data.elements[index], generateId, usedIds));
757
765
  return copies.every((copy) => copy !== null) ? appendArraySource(code, data, copies) : null;
@@ -763,31 +771,13 @@ const appendArrayItem = (code, kind, generateId = () => nanoid(6)) => {
763
771
  //#endregion
764
772
  //#region src/utils/ast/extract.ts
765
773
  const collectText = (children) => {
766
- return children.filter((c) => import_lib$2.isJSXText(c)).map((c) => c.value.trim()).filter((v) => v.length).join(" ");
767
- };
768
- const getTagName = (opening) => {
769
- if (import_lib$2.isJSXIdentifier(opening.name)) return opening.name.name;
770
- if (import_lib$2.isJSXMemberExpression(opening.name)) return resolveMemberName(opening.name);
771
- return "";
772
- };
773
- const resolveMemberName = (expr) => {
774
- const parts = [];
775
- const collectMemberParts = (node) => {
776
- if (import_lib$2.isJSXIdentifier(node)) parts.push(node.name);
777
- else if (import_lib$2.isJSXMemberExpression(node)) {
778
- collectMemberParts(node.object);
779
- if (import_lib$2.isJSXIdentifier(node.property)) parts.push(node.property.name);
780
- }
781
- };
782
- collectMemberParts(expr.object);
783
- if (import_lib$2.isJSXIdentifier(expr.property)) parts.push(expr.property.name);
784
- return parts.join(".");
774
+ return children.filter((c) => import_lib$1.isJSXText(c)).map((c) => c.value.trim()).filter((v) => v.length).join(" ");
785
775
  };
786
776
  const parseJSXName = (tagName) => {
787
777
  const parts = tagName.split(".");
788
- if (parts.length === 1) return import_lib$2.jsxIdentifier(parts[0]);
789
- let expr = import_lib$2.jsxIdentifier(parts[0]);
790
- for (let i = 1; i < parts.length; i++) expr = import_lib$2.jsxMemberExpression(expr, import_lib$2.jsxIdentifier(parts[i]));
778
+ if (parts.length === 1) return import_lib$1.jsxIdentifier(parts[0]);
779
+ let expr = import_lib$1.jsxIdentifier(parts[0]);
780
+ for (let i = 1; i < parts.length; i++) expr = import_lib$1.jsxMemberExpression(expr, import_lib$1.jsxIdentifier(parts[i]));
791
781
  return expr;
792
782
  };
793
783
  const extractCache = createBoundedCache(CONFIG.CACHE_LIMIT);
@@ -795,17 +785,17 @@ const extractAttributes = (attributes, source) => {
795
785
  const allAttrs = [];
796
786
  const dataAttrs = [];
797
787
  for (const attr of attributes) {
798
- if (!import_lib$2.isJSXAttribute(attr) || !import_lib$2.isJSXIdentifier(attr.name)) continue;
788
+ if (!import_lib$1.isJSXAttribute(attr) || !import_lib$1.isJSXIdentifier(attr.name)) continue;
799
789
  const name = attr.name.name;
800
790
  let value = null;
801
791
  let isStringLiteral = false;
802
792
  if (attr.value) {
803
- if (import_lib$2.isStringLiteral(attr.value)) {
793
+ if (import_lib$1.isStringLiteral(attr.value)) {
804
794
  value = attr.value.value;
805
795
  isStringLiteral = true;
806
- } else if (import_lib$2.isJSXExpressionContainer(attr.value)) try {
796
+ } else if (import_lib$1.isJSXExpressionContainer(attr.value)) try {
807
797
  const expression = attr.value.expression;
808
- const structural = import_lib$2.isArrayExpression(unwrapExpression(expression)) || import_lib$2.isObjectExpression(unwrapExpression(expression));
798
+ const structural = import_lib$1.isArrayExpression(unwrapExpression(expression)) || import_lib$1.isObjectExpression(unwrapExpression(expression));
809
799
  value = source && structural && expression.start != null && expression.end != null ? source.slice(expression.start, expression.end) : generateCode(expression);
810
800
  isStringLiteral = false;
811
801
  } catch {
@@ -827,7 +817,7 @@ const extractAttributes = (attributes, source) => {
827
817
  };
828
818
  const buildChildElements = (node) => {
829
819
  const childElements = [];
830
- if (node.textContent) childElements.push(import_lib$2.jsxText(node.textContent));
820
+ if (node.textContent) childElements.push(import_lib$1.jsxText(node.textContent));
831
821
  node.children?.forEach((child) => {
832
822
  const childJSX = nodeToJSX(child);
833
823
  if (childJSX) childElements.push(childJSX);
@@ -838,22 +828,22 @@ const nodeToJSX = (node) => {
838
828
  try {
839
829
  if (node.isFragment) {
840
830
  const childElements = buildChildElements(node);
841
- return import_lib$2.jsxFragment(import_lib$2.jsxOpeningFragment(), import_lib$2.jsxClosingFragment(), childElements);
831
+ return import_lib$1.jsxFragment(import_lib$1.jsxOpeningFragment(), import_lib$1.jsxClosingFragment(), childElements);
842
832
  }
843
833
  if (node.tagName === "div" && node.dataAttributes.some((attr) => attr.name === "data-item")) {
844
834
  if (node.children) return nodeToJSX(node.children[0]);
845
835
  return null;
846
836
  }
847
837
  const attributes = node.attributes.map((attr) => {
848
- const attrName = import_lib$2.jsxIdentifier(attr.name);
849
- if (!attr.value) return import_lib$2.jsxAttribute(attrName, null);
850
- return import_lib$2.jsxAttribute(attrName, attrValue(attr));
838
+ const attrName = import_lib$1.jsxIdentifier(attr.name);
839
+ if (!attr.value) return import_lib$1.jsxAttribute(attrName, null);
840
+ return import_lib$1.jsxAttribute(attrName, attrValue(attr));
851
841
  });
852
842
  const elementName = parseJSXName(node.tagName);
853
- const openingElement = import_lib$2.jsxOpeningElement(elementName, attributes);
854
- const closingElement = import_lib$2.jsxClosingElement(elementName);
843
+ const openingElement = import_lib$1.jsxOpeningElement(elementName, attributes);
844
+ const closingElement = import_lib$1.jsxClosingElement(elementName);
855
845
  const children = buildChildElements(node);
856
- return import_lib$2.jsxElement(openingElement, closingElement, children, false);
846
+ return import_lib$1.jsxElement(openingElement, closingElement, children, false);
857
847
  } catch (error) {
858
848
  console.error("❌ DataAttrNode to JSX conversion error:", error);
859
849
  return null;
@@ -883,11 +873,11 @@ const createFragmentNode = (textContent, children) => ({
883
873
  isFragment: true
884
874
  });
885
875
  const processChildrenBinding = (jsxElement, processedNodes, shouldWrap = true, source) => {
886
- const jsxChildren = jsxElement.children.filter((child) => import_lib$2.isJSXElement(child) || import_lib$2.isJSXFragment(child));
876
+ const jsxChildren = jsxElement.children.filter((child) => import_lib$1.isJSXElement(child) || import_lib$1.isJSXFragment(child));
887
877
  if (!jsxChildren.length) return;
888
878
  const childrenNodes = [];
889
879
  jsxChildren.forEach((child) => {
890
- if (import_lib$2.isJSXElement(child)) {
880
+ if (import_lib$1.isJSXElement(child)) {
891
881
  const childResults = extractFromNode(child, processedNodes, source);
892
882
  if (shouldWrap) {
893
883
  const wrapperNode = createWrapperNode(collectText(child.children), childResults);
@@ -896,11 +886,11 @@ const processChildrenBinding = (jsxElement, processedNodes, shouldWrap = true, s
896
886
  if (dataId) wrapperNode.id = `child:${dataId}`;
897
887
  childrenNodes.push(wrapperNode);
898
888
  } else childrenNodes.push(...childResults);
899
- } else if (import_lib$2.isJSXFragment(child)) {
889
+ } else if (import_lib$1.isJSXFragment(child)) {
900
890
  processedNodes?.add(child);
901
891
  const fragmentChildren = [];
902
892
  child.children.forEach((fragmentChild) => {
903
- if (import_lib$2.isJSXElement(fragmentChild)) {
893
+ if (import_lib$1.isJSXElement(fragmentChild)) {
904
894
  const childResults = extractFromNode(fragmentChild, processedNodes, source);
905
895
  fragmentChildren.push(...childResults);
906
896
  }
@@ -915,32 +905,32 @@ const processChildrenBinding = (jsxElement, processedNodes, shouldWrap = true, s
915
905
  return childrenNodes.length ? childrenNodes : void 0;
916
906
  };
917
907
  const skipItemsChildren = (jsxElement, processedNodes, propertyName = "items") => {
918
- const itemsAttr = jsxElement.openingElement.attributes.find((attr) => import_lib$2.isJSXAttribute(attr) && import_lib$2.isJSXIdentifier(attr.name) && attr.name.name === propertyName);
919
- if (!itemsAttr || !import_lib$2.isJSXAttribute(itemsAttr)) return;
920
- if (itemsAttr.value && import_lib$2.isJSXExpressionContainer(itemsAttr.value) && import_lib$2.isArrayExpression(itemsAttr.value.expression)) itemsAttr.value.expression.elements.forEach((element) => {
921
- if (import_lib$2.isObjectExpression(element)) element.properties.forEach((prop) => {
922
- if (import_lib$2.isObjectProperty(prop) && import_lib$2.isIdentifier(prop.key) && import_lib$2.isJSXElement(prop.value)) markProcessedJSX(prop.value, processedNodes);
908
+ const itemsAttr = jsxElement.openingElement.attributes.find((attr) => import_lib$1.isJSXAttribute(attr) && import_lib$1.isJSXIdentifier(attr.name) && attr.name.name === propertyName);
909
+ if (!itemsAttr || !import_lib$1.isJSXAttribute(itemsAttr)) return;
910
+ if (itemsAttr.value && import_lib$1.isJSXExpressionContainer(itemsAttr.value) && import_lib$1.isArrayExpression(itemsAttr.value.expression)) itemsAttr.value.expression.elements.forEach((element) => {
911
+ if (import_lib$1.isObjectExpression(element)) element.properties.forEach((prop) => {
912
+ if (import_lib$1.isObjectProperty(prop) && import_lib$1.isIdentifier(prop.key) && import_lib$1.isJSXElement(prop.value)) markProcessedJSX(prop.value, processedNodes);
923
913
  });
924
914
  });
925
915
  };
926
916
  const markProcessedJSX = (node, processedNodes) => {
927
- if (import_lib$2.isJSXElement(node) || import_lib$2.isJSXFragment(node)) {
917
+ if (import_lib$1.isJSXElement(node) || import_lib$1.isJSXFragment(node)) {
928
918
  processedNodes.add(node);
929
919
  node.children.forEach((child) => markProcessedJSX(child, processedNodes));
930
920
  return;
931
921
  }
932
- if (import_lib$2.isJSXExpressionContainer(node) || import_lib$2.isParenthesizedExpression(node)) markProcessedJSX(node.expression, processedNodes);
922
+ if (import_lib$1.isJSXExpressionContainer(node) || import_lib$1.isParenthesizedExpression(node)) markProcessedJSX(node.expression, processedNodes);
933
923
  };
934
924
  const getBindingExpression = (opening) => {
935
- for (const attr of opening.attributes) if (import_lib$2.isJSXAttribute(attr) && import_lib$2.isJSXIdentifier(attr.name) && attr.name.name === DATA_ATTR.BINDING && attr.value && import_lib$2.isJSXExpressionContainer(attr.value)) {
925
+ for (const attr of opening.attributes) if (import_lib$1.isJSXAttribute(attr) && import_lib$1.isJSXIdentifier(attr.name) && attr.name.name === DATA_ATTR.BINDING && attr.value && import_lib$1.isJSXExpressionContainer(attr.value)) {
936
926
  const expression = unwrapExpression(attr.value.expression);
937
- if (import_lib$2.isArrayExpression(expression)) return expression;
927
+ if (import_lib$1.isArrayExpression(expression)) return expression;
938
928
  }
939
929
  return null;
940
930
  };
941
931
  const readNodeBindingInfo = (node, source) => {
942
932
  const opening = node.openingElement;
943
- const tagName = getTagName(opening);
933
+ const tagName = getJSXTagName(opening);
944
934
  const { allAttrs, dataAttrs } = extractAttributes(opening.attributes, source);
945
935
  const bindingAttr = dataAttrs.find((attr) => attr.name === DATA_ATTR.BINDING);
946
936
  const bindingExpr = getBindingExpression(opening);
@@ -962,7 +952,7 @@ const readNodeBindingInfo = (node, source) => {
962
952
  };
963
953
  const parseToNodes = (raw) => {
964
954
  const wrapped = wrap(raw);
965
- const ast = (0, import_lib$1.parse)(wrapped, {
955
+ const ast = (0, import_lib.parse)(wrapped, {
966
956
  sourceType: "module",
967
957
  plugins: ["jsx", "typescript"],
968
958
  errorRecovery: true
@@ -1037,7 +1027,7 @@ const getChildrenSignatures = (nodes) => {
1037
1027
  };
1038
1028
  const indicesAreValid = (indices, count) => Array.isArray(indices) && new Set(indices).size === indices.length && indices.every((index) => Number.isInteger(index) && index >= 0 && index < count);
1039
1029
  const copySource = (source, usedIds) => {
1040
- const node = (0, import_lib$1.parseExpression)(source, { plugins: ["jsx", "typescript"] });
1030
+ const node = (0, import_lib.parseExpression)(source, { plugins: ["jsx", "typescript"] });
1041
1031
  const edits = [];
1042
1032
  const newId = () => {
1043
1033
  let id = nanoid(12);
@@ -1045,15 +1035,15 @@ const copySource = (source, usedIds) => {
1045
1035
  usedIds.add(id);
1046
1036
  return id;
1047
1037
  };
1048
- import_lib$2.traverseFast(node, (child) => {
1049
- if (!import_lib$2.isJSXOpeningElement(child)) return;
1050
- const ids = child.attributes.filter((attr) => import_lib$2.isJSXAttribute(attr) && import_lib$2.isJSXIdentifier(attr.name, { name: "data-id" }));
1038
+ import_lib$1.traverseFast(node, (child) => {
1039
+ if (!import_lib$1.isJSXOpeningElement(child)) return;
1040
+ const ids = child.attributes.filter((attr) => import_lib$1.isJSXAttribute(attr) && import_lib$1.isJSXIdentifier(attr.name, { name: "data-id" }));
1051
1041
  if (ids.length > 1) throw new Error("Duplicate data-id attributes");
1052
1042
  const attr = ids[0];
1053
- if (attr && child.attributes.slice(child.attributes.indexOf(attr) + 1).some((attribute) => import_lib$2.isJSXSpreadAttribute(attribute))) throw new Error("A spread may override the copied data-id");
1043
+ if (attr && child.attributes.slice(child.attributes.indexOf(attr) + 1).some((attribute) => import_lib$1.isJSXSpreadAttribute(attribute))) throw new Error("A spread may override the copied data-id");
1054
1044
  if (attr) {
1055
1045
  const value = attr.value;
1056
- if (!import_lib$2.isStringLiteral(value) || value.start == null || value.end == null) throw new Error("Cannot copy a dynamic data-id");
1046
+ if (!import_lib$1.isStringLiteral(value) || value.start == null || value.end == null) throw new Error("Cannot copy a dynamic data-id");
1057
1047
  edits.push({
1058
1048
  start: value.start,
1059
1049
  end: value.end,
@@ -1075,7 +1065,7 @@ const editChildrenSource = (source, parent, input) => {
1075
1065
  try {
1076
1066
  if (!parent.closingElement || parent.start == null || parent.end == null) return null;
1077
1067
  const value = typeof input === "string" ? JSON.parse(input) : input;
1078
- const children = parent.children.filter((child) => import_lib$2.isJSXElement(child) || import_lib$2.isJSXFragment(child));
1068
+ const children = parent.children.filter((child) => import_lib$1.isJSXElement(child) || import_lib$1.isJSXFragment(child));
1079
1069
  const raw = children.map((child) => source.slice(child.start, child.end));
1080
1070
  const models = extract(source.slice(parent.start, parent.end))[0]?.children ?? [];
1081
1071
  if (models.length !== children.length) return null;
@@ -1098,7 +1088,7 @@ const editChildrenSource = (source, parent, input) => {
1098
1088
  };
1099
1089
  if (Array.isArray(value)) {
1100
1090
  const desired = modeledSignatures(value);
1101
- const lossless = raw.every((text, index) => generateCode((0, import_lib$1.parseExpression)(text, { plugins: ["jsx", "typescript"] })) === signatures[index]);
1091
+ const lossless = raw.every((text, index) => generateCode((0, import_lib.parseExpression)(text, { plugins: ["jsx", "typescript"] })) === signatures[index]);
1102
1092
  const consumed = /* @__PURE__ */ new Set();
1103
1093
  const next = desired.map((signature, position) => {
1104
1094
  const index = signatures.findIndex((candidate, i) => candidate === signature && !consumed.has(i) && (value[position].source === void 0 || value[position].source === raw[i]));
@@ -1111,8 +1101,8 @@ const editChildrenSource = (source, parent, input) => {
1111
1101
  });
1112
1102
  const countIds = (text) => {
1113
1103
  const counts = /* @__PURE__ */ new Map();
1114
- import_lib$2.traverseFast((0, import_lib$1.parseExpression)(text, { plugins: ["jsx", "typescript"] }), (node) => {
1115
- if (import_lib$2.isJSXAttribute(node) && import_lib$2.isJSXIdentifier(node.name, { name: "data-id" }) && import_lib$2.isStringLiteral(node.value)) counts.set(node.value.value, (counts.get(node.value.value) ?? 0) + 1);
1104
+ import_lib$1.traverseFast((0, import_lib.parseExpression)(text, { plugins: ["jsx", "typescript"] }), (node) => {
1105
+ if (import_lib$1.isJSXAttribute(node) && import_lib$1.isJSXIdentifier(node.name, { name: "data-id" }) && import_lib$1.isStringLiteral(node.value)) counts.set(node.value.value, (counts.get(node.value.value) ?? 0) + 1);
1116
1106
  });
1117
1107
  return counts;
1118
1108
  };
@@ -1124,8 +1114,8 @@ const editChildrenSource = (source, parent, input) => {
1124
1114
  if (request?.kind !== "children-edit" || !Array.isArray(request.expected) || request.expected.length !== signatures.length || !getChildrenSignatures(models).every((signature, index) => signature === request.expected[index]) || !request.action) return null;
1125
1115
  const { action } = request;
1126
1116
  const usedIds = /* @__PURE__ */ new Set();
1127
- import_lib$2.traverseFast(parent, (node) => {
1128
- if (import_lib$2.isJSXAttribute(node) && import_lib$2.isJSXIdentifier(node.name, { name: "data-id" }) && import_lib$2.isStringLiteral(node.value)) usedIds.add(node.value.value);
1117
+ import_lib$1.traverseFast(parent, (node) => {
1118
+ if (import_lib$1.isJSXAttribute(node) && import_lib$1.isJSXIdentifier(node.name, { name: "data-id" }) && import_lib$1.isStringLiteral(node.value)) usedIds.add(node.value.value);
1129
1119
  });
1130
1120
  switch (action.type) {
1131
1121
  case "move": {
@@ -1181,7 +1171,7 @@ const childrenRange = (element) => {
1181
1171
  };
1182
1172
  };
1183
1173
  const findAttribute = (opening, propertyName) => {
1184
- return opening.attributes.find((attr) => import_lib$2.isJSXAttribute(attr) && import_lib$2.isJSXIdentifier(attr.name) && attr.name.name === propertyName);
1174
+ return opening.attributes.find((attr) => import_lib$1.isJSXAttribute(attr) && import_lib$1.isJSXIdentifier(attr.name) && attr.name.name === propertyName);
1185
1175
  };
1186
1176
  const attributeInsertPoint = (opening) => {
1187
1177
  return opening.attributes[opening.attributes.length - 1]?.end ?? opening.name.end ?? null;
@@ -1190,7 +1180,7 @@ const editInnerText = (source, element, value) => {
1190
1180
  const range = childrenRange(element);
1191
1181
  if (!range) return [];
1192
1182
  const [only] = element.children;
1193
- if (element.children.length === 1 && import_lib$2.isJSXText(only) && only.start != null && only.end != null) {
1183
+ if (element.children.length === 1 && import_lib$1.isJSXText(only) && only.start != null && only.end != null) {
1194
1184
  const raw = source.slice(only.start, only.end);
1195
1185
  if (raw.trim() !== "") {
1196
1186
  const leading = raw.length - raw.trimStart().length;
@@ -1203,7 +1193,7 @@ const editInnerText = (source, element, value) => {
1203
1193
  }
1204
1194
  }
1205
1195
  const edits = [];
1206
- for (const child of element.children) if (import_lib$2.isJSXText(child) && child.start != null && child.end != null) edits.push({
1196
+ for (const child of element.children) if (import_lib$1.isJSXText(child) && child.start != null && child.end != null) edits.push({
1207
1197
  start: child.start,
1208
1198
  end: child.end,
1209
1199
  content: ""
@@ -1233,7 +1223,7 @@ const editRichtext = (element, value) => {
1233
1223
  content: ""
1234
1224
  });
1235
1225
  const opening = element.openingElement;
1236
- const attribute = import_lib$2.jsxAttribute(import_lib$2.jsxIdentifier("dangerouslySetInnerHTML"), import_lib$2.jsxExpressionContainer(import_lib$2.objectExpression([import_lib$2.objectProperty(import_lib$2.identifier("__html"), import_lib$2.stringLiteral(value))])));
1226
+ const attribute = import_lib$1.jsxAttribute(import_lib$1.jsxIdentifier("dangerouslySetInnerHTML"), import_lib$1.jsxExpressionContainer(import_lib$1.objectExpression([import_lib$1.objectProperty(import_lib$1.identifier("__html"), import_lib$1.stringLiteral(value))])));
1237
1227
  const content = generateCode(attribute);
1238
1228
  const existing = findAttribute(opening, "dangerouslySetInnerHTML");
1239
1229
  if (existing && existing.start != null && existing.end != null) {
@@ -1272,11 +1262,11 @@ const editJsxAttribute = (opening, propertyName, value) => {
1272
1262
  content: `=${content}`
1273
1263
  }];
1274
1264
  };
1275
- const holdsStructuralExpression = (value) => import_lib$2.isJSXExpressionContainer(value) && (import_lib$2.isArrayExpression(unwrapExpression(value.expression)) || import_lib$2.isObjectExpression(unwrapExpression(value.expression)));
1265
+ const holdsStructuralExpression = (value) => import_lib$1.isJSXExpressionContainer(value) && (import_lib$1.isArrayExpression(unwrapExpression(value.expression)) || import_lib$1.isObjectExpression(unwrapExpression(value.expression)));
1276
1266
  const structuralSource = (value) => {
1277
1267
  try {
1278
- const expression = (0, import_lib$1.parseExpression)(value.trim(), { plugins: ["jsx", "typescript"] });
1279
- return import_lib$2.isArrayExpression(unwrapExpression(expression)) || import_lib$2.isObjectExpression(unwrapExpression(expression)) ? expression : null;
1268
+ const expression = (0, import_lib.parseExpression)(value.trim(), { plugins: ["jsx", "typescript"] });
1269
+ return import_lib$1.isArrayExpression(unwrapExpression(expression)) || import_lib$1.isObjectExpression(unwrapExpression(expression)) ? expression : null;
1280
1270
  } catch {
1281
1271
  return null;
1282
1272
  }
@@ -1284,29 +1274,29 @@ const structuralSource = (value) => {
1284
1274
  const buildAttributeValue = (value, type, current) => {
1285
1275
  if (type === "array" || type === "object") {
1286
1276
  if (typeof value === "string") try {
1287
- return import_lib$2.jsxExpressionContainer((0, import_lib$1.parseExpression)(value.trim(), { plugins: ["jsx", "typescript"] }));
1277
+ return import_lib$1.jsxExpressionContainer((0, import_lib.parseExpression)(value.trim(), { plugins: ["jsx", "typescript"] }));
1288
1278
  } catch {
1289
- return import_lib$2.stringLiteral(value);
1279
+ return import_lib$1.stringLiteral(value);
1290
1280
  }
1291
1281
  const expr = valueToExpression(value);
1292
- return expr ? import_lib$2.jsxExpressionContainer(expr) : import_lib$2.stringLiteral("");
1282
+ return expr ? import_lib$1.jsxExpressionContainer(expr) : import_lib$1.stringLiteral("");
1293
1283
  }
1294
1284
  if (typeof value === "string") {
1295
1285
  if (holdsStructuralExpression(current) && !(type && STRING_VALUED_TYPES.has(type))) {
1296
1286
  const structural = structuralSource(value);
1297
- if (structural) return import_lib$2.jsxExpressionContainer(structural);
1287
+ if (structural) return import_lib$1.jsxExpressionContainer(structural);
1298
1288
  }
1299
- return import_lib$2.stringLiteral(value);
1289
+ return import_lib$1.stringLiteral(value);
1300
1290
  }
1301
1291
  const expr = valueToExpression(value);
1302
- return expr ? import_lib$2.jsxExpressionContainer(expr) : import_lib$2.stringLiteral(String(value));
1292
+ return expr ? import_lib$1.jsxExpressionContainer(expr) : import_lib$1.stringLiteral(String(value));
1303
1293
  };
1304
1294
  const editAttribute = (opening, propertyName, value, type) => {
1305
1295
  const attribute = findAttribute(opening, propertyName);
1306
1296
  if (!attribute || attribute.start == null || attribute.end == null) return null;
1307
1297
  if (typeof value === "string" && (type === "array" || type === "object" || holdsStructuralExpression(attribute.value) && !(type && STRING_VALUED_TYPES.has(type)))) {
1308
1298
  const expression = structuralSource(value);
1309
- if (expression && import_lib$2.isJSXExpressionContainer(attribute.value)) {
1299
+ if (expression && import_lib$1.isJSXExpressionContainer(attribute.value)) {
1310
1300
  const text = value.trim();
1311
1301
  const lineComment = expression.trailingComments?.some((comment) => comment.type === "CommentLine");
1312
1302
  return [{
@@ -1316,7 +1306,7 @@ const editAttribute = (opening, propertyName, value, type) => {
1316
1306
  }];
1317
1307
  }
1318
1308
  }
1319
- const content = generateCode(import_lib$2.jsxAttribute(attribute.name, buildAttributeValue(value, type, attribute.value)));
1309
+ const content = generateCode(import_lib$1.jsxAttribute(attribute.name, buildAttributeValue(value, type, attribute.value)));
1320
1310
  return [{
1321
1311
  start: attribute.start,
1322
1312
  end: attribute.end,
@@ -1324,14 +1314,36 @@ const editAttribute = (opening, propertyName, value, type) => {
1324
1314
  indent: true
1325
1315
  }];
1326
1316
  };
1317
+ const removeAttribute = (source, attribute) => {
1318
+ if (attribute.start == null || attribute.end == null) return null;
1319
+ let start = attribute.start;
1320
+ while (start > 0 && /\s/.test(source[start - 1])) start -= 1;
1321
+ return [{
1322
+ start,
1323
+ end: attribute.end,
1324
+ content: ""
1325
+ }];
1326
+ };
1327
+ const addAttribute = (source, opening, propertyName, value, type) => {
1328
+ const insertAt = attributeInsertPoint(opening);
1329
+ if (insertAt == null) return null;
1330
+ const lastStart = opening.attributes[opening.attributes.length - 1]?.start;
1331
+ const lineStart = lastStart == null ? -1 : source.lastIndexOf("\n", lastStart - 1) + 1;
1332
+ return [{
1333
+ start: insertAt,
1334
+ end: insertAt,
1335
+ content: `${lastStart != null && lineStart > 0 && /^\s*$/.test(source.slice(lineStart, lastStart)) ? "\n" : " "}${type === "jsx" ? `${propertyName}={${String(value).trim()}}` : generateCode(import_lib$1.jsxAttribute(import_lib$1.jsxIdentifier(propertyName), buildAttributeValue(value, type)))}`,
1336
+ indent: true
1337
+ }];
1338
+ };
1327
1339
  const canEditAttributeValue = (attribute, value, type) => {
1328
- if (!import_lib$2.isJSXExpressionContainer(attribute.value) || import_lib$2.isJSXEmptyExpression(attribute.value.expression) || isLosslesslyEvaluable(attribute.value.expression)) return true;
1340
+ if (!import_lib$1.isJSXExpressionContainer(attribute.value) || import_lib$1.isJSXEmptyExpression(attribute.value.expression) || isLosslesslyEvaluable(attribute.value.expression)) return true;
1329
1341
  return typeof value === "string" && holdsStructuralExpression(attribute.value) && !(type && STRING_VALUED_TYPES.has(type)) && structuralSource(value) !== null;
1330
1342
  };
1331
1343
  const update = (code, dataId, label, value, property) => {
1332
1344
  try {
1333
1345
  const wrapped = wrap(code);
1334
- const ast = (0, import_lib$1.parse)(wrapped, {
1346
+ const ast = (0, import_lib.parse)(wrapped, {
1335
1347
  sourceType: "module",
1336
1348
  plugins: ["jsx", "typescript"]
1337
1349
  });
@@ -1349,9 +1361,9 @@ const update = (code, dataId, label, value, property) => {
1349
1361
  traverse(ast, { JSXElement(path) {
1350
1362
  const opening = path.node.openingElement;
1351
1363
  if (!opening.attributes.find((attr) => {
1352
- return import_lib$2.isJSXAttribute(attr) && import_lib$2.isJSXIdentifier(attr.name) && attr.name.name === DATA_ATTR.ID && attr.value && import_lib$2.isStringLiteral(attr.value) && attr.value.value === dataId;
1364
+ 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;
1353
1365
  })) return;
1354
- const bindingAttr = opening.attributes.find((attr) => import_lib$2.isJSXAttribute(attr) && import_lib$2.isJSXIdentifier(attr.name) && attr.name.name === DATA_ATTR.BINDING);
1366
+ const bindingAttr = opening.attributes.find((attr) => import_lib$1.isJSXAttribute(attr) && import_lib$1.isJSXIdentifier(attr.name) && attr.name.name === DATA_ATTR.BINDING);
1355
1367
  if (!bindingAttr?.value) {
1356
1368
  failure = {
1357
1369
  reason: "no-binding",
@@ -1360,8 +1372,8 @@ const update = (code, dataId, label, value, property) => {
1360
1372
  return;
1361
1373
  }
1362
1374
  let bindingValue = "";
1363
- if (import_lib$2.isStringLiteral(bindingAttr.value)) bindingValue = bindingAttr.value.value;
1364
- else if (import_lib$2.isJSXExpressionContainer(bindingAttr.value)) try {
1375
+ if (import_lib$1.isStringLiteral(bindingAttr.value)) bindingValue = bindingAttr.value.value;
1376
+ else if (import_lib$1.isJSXExpressionContainer(bindingAttr.value)) try {
1365
1377
  bindingValue = generateCode(bindingAttr.value.expression);
1366
1378
  } catch (error) {
1367
1379
  failure = {
@@ -1392,20 +1404,45 @@ const update = (code, dataId, label, value, property) => {
1392
1404
  }
1393
1405
  const propertyBinding = matches[0];
1394
1406
  const prop = propertyBinding.property;
1407
+ if (RESERVED_BINDING_PROPERTIES.includes(prop)) {
1408
+ failure = {
1409
+ reason: "reserved-property",
1410
+ dataId,
1411
+ property: prop
1412
+ };
1413
+ return;
1414
+ }
1415
+ const unset = value === void 0;
1416
+ if (unset && propertyBinding.required) {
1417
+ failure = {
1418
+ reason: "required-property",
1419
+ dataId,
1420
+ property: prop
1421
+ };
1422
+ return;
1423
+ }
1395
1424
  switch (prop) {
1396
1425
  case BINDING_PROP.INNER_TEXT:
1397
- collect(editInnerText(wrapped, path.node, String(value)), () => ({
1426
+ collect(editInnerText(wrapped, path.node, unset ? "" : String(value)), () => ({
1398
1427
  reason: "parse-error",
1399
1428
  error: /* @__PURE__ */ new Error(`could not update "${prop}"`)
1400
1429
  }));
1401
1430
  break;
1402
1431
  case BINDING_PROP.INNER_HTML:
1403
- collect(propertyBinding.type === "richtext" ? editRichtext(path.node, String(value)) : editInnerHTML(path.node, String(value)), () => ({
1432
+ collect(propertyBinding.type === "richtext" ? editRichtext(path.node, unset ? "" : String(value)) : editInnerHTML(path.node, unset ? "" : String(value)), () => ({
1404
1433
  reason: "parse-error",
1405
1434
  error: /* @__PURE__ */ new Error(`could not update "${prop}"`)
1406
1435
  }));
1407
1436
  break;
1408
1437
  case BINDING_PROP.CHILDREN:
1438
+ if (unset) {
1439
+ failure = {
1440
+ reason: "unsupported-syntax",
1441
+ dataId,
1442
+ property: prop
1443
+ };
1444
+ break;
1445
+ }
1409
1446
  collect(editChildrenSource(wrapped, path.node, value), () => ({
1410
1447
  reason: "parse-error",
1411
1448
  error: /* @__PURE__ */ new Error("Unsupported or stale children edit; source was preserved")
@@ -1413,6 +1450,21 @@ const update = (code, dataId, label, value, property) => {
1413
1450
  break;
1414
1451
  default: {
1415
1452
  const attribute = findAttribute(opening, prop);
1453
+ if (unset) {
1454
+ collect(attribute ? removeAttribute(wrapped, attribute) : [], () => ({
1455
+ reason: "parse-error",
1456
+ error: /* @__PURE__ */ new Error(`could not remove "${prop}"`)
1457
+ }));
1458
+ break;
1459
+ }
1460
+ if (!attribute) {
1461
+ collect(value === "" ? [] : addAttribute(wrapped, opening, prop, value, propertyBinding.type), () => ({
1462
+ reason: "attribute-not-found",
1463
+ dataId,
1464
+ property: prop
1465
+ }));
1466
+ break;
1467
+ }
1416
1468
  if (attribute && propertyBinding.type !== "jsx" && !canEditAttributeValue(attribute, value, propertyBinding.type)) {
1417
1469
  failure = {
1418
1470
  reason: "unsupported-syntax",
@@ -1454,6 +1506,31 @@ const update = (code, dataId, label, value, property) => {
1454
1506
  };
1455
1507
  }
1456
1508
  };
1509
+ const updateAll = (raw, entries) => {
1510
+ let current = raw;
1511
+ for (const [index, entry] of entries.entries()) {
1512
+ const result = update(current, entry.dataId, entry.label, entry.value, entry.property);
1513
+ if (!result.success) return {
1514
+ success: false,
1515
+ code: raw,
1516
+ failure: result.failure ?? {
1517
+ reason: "element-not-found",
1518
+ dataId: entry.dataId
1519
+ },
1520
+ index
1521
+ };
1522
+ current = result.code;
1523
+ }
1524
+ return {
1525
+ success: true,
1526
+ code: current
1527
+ };
1528
+ };
1529
+ /**
1530
+ * @deprecated Not atomic: when an entry fails, the ones before and after it
1531
+ * are still applied, and the returned `code` carries them. Use `updateAll`,
1532
+ * which applies every entry or none. Will be removed in the next major.
1533
+ */
1457
1534
  const bulkUpdate = (raw, entries) => {
1458
1535
  let current = raw;
1459
1536
  const failures = [];
@@ -1472,24 +1549,6 @@ const bulkUpdate = (raw, entries) => {
1472
1549
  };
1473
1550
  };
1474
1551
  //#endregion
1475
- //#region src/utils/ast/tree.ts
1476
- const replaceIds = (code, generateId = () => nanoid(6)) => {
1477
- return code.replace(new RegExp(`${DATA_ATTR.ID}="[^"]*"`, "g"), () => {
1478
- return `${DATA_ATTR.ID}="${generateId()}"`;
1479
- });
1480
- };
1481
- const fillIds = (code, generateId = () => nanoid(6)) => {
1482
- return code.replace(new RegExp(`${DATA_ATTR.ID}=""`, "g"), () => {
1483
- return `${DATA_ATTR.ID}="${generateId()}"`;
1484
- });
1485
- };
1486
- const clone = (element, generateId = () => nanoid(6)) => {
1487
- const cloned = import_lib$2.cloneNode(element, true);
1488
- const generatedCode = generateCode(cloned);
1489
- const code = replaceIds(generatedCode, generateId);
1490
- return (0, import_lib$1.parseExpression)(code, { plugins: ["jsx", "typescript"] });
1491
- };
1492
- //#endregion
1493
1552
  //#region src/utils/ast/validate.ts
1494
1553
  const VALID = { valid: true };
1495
1554
  const validateBindingValue = (binding, value) => {
@@ -1539,6 +1598,6 @@ const validateBindingValue = (binding, value) => {
1539
1598
  return VALID;
1540
1599
  };
1541
1600
  //#endregion
1542
- export { flattenEditableValue as A, parseBinding as C, createNodeFromValue as D, canLosslesslyEvaluateSource as E, parseValue as M, setEditableValue as N, extractNodeValue as O, generateCode as P, getStructuredValue as S, arrayExpressionToCode as T, updateArrayItemValue as _, bulkUpdate as a, findEditableChildren as b, clearExtractCache as c, duplicateArrayItems as d, moveArrayItem as f, updateArrayItemProperty as g, removeArrayItems as h, replaceIds as i, parseArrayExpression as j, extractObjectProperties as k, extract as l, parseItems as m, clone as n, update as o, moveArrayItems as p, fillIds as r, getChildrenSignatures as s, validateBindingValue as t, appendArrayItem as u, canStructurallyEditArray as v, parseBindingExpression as w, getCurrentValue as x, moveSelectedIndices as y };
1601
+ export { parseValue as A, arrayExpressionToCode as C, extractObjectProperties as D, extractNodeValue as E, flattenEditableValue as O, parseBindingExpression as S, createNodeFromValue as T, moveSelectedIndices as _, getChildrenSignatures as a, getStructuredValue as b, appendArrayItem as c, moveArrayItems as d, parseItems as f, canStructurallyEditArray as g, updateArrayItemValue as h, updateAll as i, setEditableValue as j, parseArrayExpression as k, duplicateArrayItems as l, updateArrayItemProperty as m, bulkUpdate as n, clearExtractCache as o, removeArrayItems as p, update as r, extract as s, validateBindingValue as t, moveArrayItem as u, findEditableChildren as v, canLosslesslyEvaluateSource as w, parseBinding as x, getCurrentValue as y };
1543
1602
 
1544
- //# sourceMappingURL=ast-jab6hQrT.js.map
1603
+ //# sourceMappingURL=ast-BFbDWO-l.js.map