@getforma/core 1.1.0 → 1.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 (45) hide show
  1. package/dist/{chunk-MIOMT2CB.js → chunk-AJP4OVCN.js} +29 -9
  2. package/dist/chunk-AJP4OVCN.js.map +1 -0
  3. package/dist/{chunk-XLVBYXOU.js → chunk-ETPJTPYD.js} +6 -3
  4. package/dist/chunk-ETPJTPYD.js.map +1 -0
  5. package/dist/{chunk-JRQNDXX7.cjs → chunk-FBM7V4NE.cjs} +68 -47
  6. package/dist/chunk-FBM7V4NE.cjs.map +1 -0
  7. package/dist/{chunk-W7OUWVRA.cjs → chunk-H7MDUHS5.cjs} +6 -2
  8. package/dist/chunk-H7MDUHS5.cjs.map +1 -0
  9. package/dist/{chunk-2Y5US35K.cjs → chunk-KUXNZ5MG.cjs} +12 -12
  10. package/dist/{chunk-2Y5US35K.cjs.map → chunk-KUXNZ5MG.cjs.map} +1 -1
  11. package/dist/{chunk-INNOI6TG.js → chunk-Y3A2EVVS.js} +3 -3
  12. package/dist/{chunk-INNOI6TG.js.map → chunk-Y3A2EVVS.js.map} +1 -1
  13. package/dist/forma-runtime-csp.js +178 -79
  14. package/dist/forma-runtime.js +178 -79
  15. package/dist/formajs-runtime-hardened.global.js +178 -79
  16. package/dist/formajs-runtime-hardened.global.js.map +1 -1
  17. package/dist/formajs-runtime.global.js +178 -79
  18. package/dist/formajs-runtime.global.js.map +1 -1
  19. package/dist/formajs.global.js +245 -61
  20. package/dist/formajs.global.js.map +1 -1
  21. package/dist/http.cjs +11 -11
  22. package/dist/http.js +2 -2
  23. package/dist/index.cjs +307 -143
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.cts +34 -2
  26. package/dist/index.d.ts +34 -2
  27. package/dist/index.js +248 -88
  28. package/dist/index.js.map +1 -1
  29. package/dist/runtime-hardened.cjs +178 -79
  30. package/dist/runtime-hardened.cjs.map +1 -1
  31. package/dist/runtime-hardened.js +178 -79
  32. package/dist/runtime-hardened.js.map +1 -1
  33. package/dist/runtime.cjs +198 -103
  34. package/dist/runtime.cjs.map +1 -1
  35. package/dist/runtime.js +174 -79
  36. package/dist/runtime.js.map +1 -1
  37. package/dist/server.cjs +7 -7
  38. package/dist/server.js +2 -2
  39. package/dist/tc39-compat.cjs +3 -3
  40. package/dist/tc39-compat.js +1 -1
  41. package/package.json +1 -1
  42. package/dist/chunk-JRQNDXX7.cjs.map +0 -1
  43. package/dist/chunk-MIOMT2CB.js.map +0 -1
  44. package/dist/chunk-W7OUWVRA.cjs.map +0 -1
  45. package/dist/chunk-XLVBYXOU.js.map +0 -1
package/dist/runtime.cjs CHANGED
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
- var chunkJRQNDXX7_cjs = require('./chunk-JRQNDXX7.cjs');
3
+ var chunkFBM7V4NE_cjs = require('./chunk-FBM7V4NE.cjs');
4
4
  var chunk263HW3KN_cjs = require('./chunk-263HW3KN.cjs');
5
- var chunk2Y5US35K_cjs = require('./chunk-2Y5US35K.cjs');
6
- var chunkW7OUWVRA_cjs = require('./chunk-W7OUWVRA.cjs');
5
+ var chunkKUXNZ5MG_cjs = require('./chunk-KUXNZ5MG.cjs');
6
+ var chunkH7MDUHS5_cjs = require('./chunk-H7MDUHS5.cjs');
7
7
 
8
8
  // src/dom/reconcile.ts
9
9
  function getBindTargets(el) {
@@ -275,12 +275,12 @@ function findInsertionPoint(parent, newChild, newChildren) {
275
275
  return null;
276
276
  }
277
277
  function createReconciler(config) {
278
- let _lastHtml = "";
278
+ const lastHtmlByContainer = /* @__PURE__ */ new WeakMap();
279
279
  return function reconcile2(container, html) {
280
280
  const trimmed = html.trim();
281
281
  if (!trimmed) return;
282
- if (trimmed === _lastHtml && container.hasChildNodes()) return;
283
- _lastHtml = trimmed;
282
+ if (lastHtmlByContainer.get(container) === trimmed && container.hasChildNodes()) return;
283
+ lastHtmlByContainer.set(container, trimmed);
284
284
  config.disconnectObserver();
285
285
  try {
286
286
  if (!container.hasChildNodes() || container.children.length === 0) {
@@ -571,9 +571,97 @@ var RE_TERNARY = /^(.+?)\s*\?\s*(.+?)\s*:\s*(.+)$/;
571
571
  var RE_NULLISH = /^(.+?)\s*\?\?\s*(.+)$/;
572
572
  var RE_AND = /^(.+?)\s*&&\s*(.+)$/;
573
573
  var RE_OR = /^(.+?)\s*\|\|\s*(.+)$/;
574
- var RE_COMPARISON = /^(.+?)\s*(===|!==|==|!=|>=|<=|>|<)\s*(.+)$/;
575
- var RE_MUL = /^(.+?)\s*([*/%])\s*(.+)$/;
576
- var RE_ADD = /^(.+?)\s*([+-])\s*(.+)$/;
574
+ var UNARY_PRECEDERS = "+-*/%<>=!&|^~(,[{?:";
575
+ function matchBinaryOp(expr, ops) {
576
+ const SQ = String.fromCharCode(39);
577
+ const DQ = String.fromCharCode(34);
578
+ const BT = String.fromCharCode(96);
579
+ const BS = String.fromCharCode(92);
580
+ let depth = 0;
581
+ let inSingle = false, inDouble = false, inTemplate = false, escaped = false;
582
+ let prevSig = "";
583
+ let bestIdx = -1;
584
+ let bestOp = "";
585
+ for (let i = 0; i < expr.length; i++) {
586
+ const ch = expr[i];
587
+ if (escaped) {
588
+ escaped = false;
589
+ continue;
590
+ }
591
+ if (ch === BS && (inSingle || inDouble || inTemplate)) {
592
+ escaped = true;
593
+ continue;
594
+ }
595
+ if (inSingle) {
596
+ if (ch === SQ) {
597
+ inSingle = false;
598
+ prevSig = DQ;
599
+ }
600
+ continue;
601
+ }
602
+ if (inDouble) {
603
+ if (ch === DQ) {
604
+ inDouble = false;
605
+ prevSig = DQ;
606
+ }
607
+ continue;
608
+ }
609
+ if (inTemplate) {
610
+ if (ch === BT) {
611
+ inTemplate = false;
612
+ prevSig = DQ;
613
+ }
614
+ continue;
615
+ }
616
+ if (ch === SQ) {
617
+ inSingle = true;
618
+ continue;
619
+ }
620
+ if (ch === DQ) {
621
+ inDouble = true;
622
+ continue;
623
+ }
624
+ if (ch === BT) {
625
+ inTemplate = true;
626
+ continue;
627
+ }
628
+ if (ch === "(" || ch === "[" || ch === "{") {
629
+ depth++;
630
+ prevSig = ch;
631
+ continue;
632
+ }
633
+ if (ch === ")" || ch === "]" || ch === "}") {
634
+ if (depth > 0) depth--;
635
+ prevSig = ch;
636
+ continue;
637
+ }
638
+ if (depth !== 0) continue;
639
+ if (ch === " " || ch === " " || ch === "\n") continue;
640
+ if (i > 0) {
641
+ let matchedOp = "";
642
+ for (const op of ops) {
643
+ if (expr.startsWith(op, i)) {
644
+ matchedOp = op;
645
+ break;
646
+ }
647
+ }
648
+ if (matchedOp) {
649
+ const isPlusMinus = matchedOp === "+" || matchedOp === "-";
650
+ const unary = isPlusMinus && (prevSig === "" || UNARY_PRECEDERS.includes(prevSig));
651
+ if (!unary) {
652
+ bestIdx = i;
653
+ bestOp = matchedOp;
654
+ }
655
+ i += matchedOp.length - 1;
656
+ prevSig = matchedOp[matchedOp.length - 1];
657
+ continue;
658
+ }
659
+ }
660
+ prevSig = ch;
661
+ }
662
+ if (bestIdx === -1) return null;
663
+ return { left: expr.slice(0, bestIdx).trim(), op: bestOp, right: expr.slice(bestIdx + bestOp.length).trim() };
664
+ }
577
665
  var RE_TEMPLATE_LIT = /^`([^`]*)`$/;
578
666
  var RE_TEMPLATE_INTERP = /\$\{([^}]+)\}/g;
579
667
  var RE_GROUP_METHOD_CALL = /^\((.+)\)\.(\w+)\((.*)\)$/;
@@ -974,7 +1062,7 @@ function parseIfHandler(expr, scope) {
974
1062
  }
975
1063
  if (rest.length > 0) return null;
976
1064
  return (e) => {
977
- chunk2Y5US35K_cjs.batch(() => {
1065
+ chunkKUXNZ5MG_cjs.batch(() => {
978
1066
  if (condExpr()) thenHandler(e);
979
1067
  else elseHandler?.(e);
980
1068
  });
@@ -1568,12 +1656,12 @@ function parseExpressionUncached(expr, scope) {
1568
1656
  return () => left() && right();
1569
1657
  }
1570
1658
  }
1571
- const compMatch = expr.match(RE_COMPARISON);
1659
+ const compMatch = matchBinaryOp(expr, ["===", "!==", "==", "!=", ">=", "<=", ">", "<"]);
1572
1660
  if (compMatch) {
1573
- const left = parseExpression(compMatch[1].trim(), scope);
1574
- const right = parseExpression(compMatch[3].trim(), scope);
1661
+ const left = parseExpression(compMatch.left, scope);
1662
+ const right = parseExpression(compMatch.right, scope);
1575
1663
  if (left && right) {
1576
- const op = compMatch[2];
1664
+ const op = compMatch.op;
1577
1665
  return () => {
1578
1666
  const l = left(), r = right();
1579
1667
  switch (op) {
@@ -1597,12 +1685,12 @@ function parseExpressionUncached(expr, scope) {
1597
1685
  };
1598
1686
  }
1599
1687
  }
1600
- const addMatch = expr.match(RE_ADD);
1688
+ const addMatch = matchBinaryOp(expr, ["+", "-"]);
1601
1689
  if (addMatch) {
1602
- const left = parseExpression(addMatch[1].trim(), scope);
1603
- const right = parseExpression(addMatch[3].trim(), scope);
1690
+ const left = parseExpression(addMatch.left, scope);
1691
+ const right = parseExpression(addMatch.right, scope);
1604
1692
  if (left && right) {
1605
- const op = addMatch[2];
1693
+ const op = addMatch.op;
1606
1694
  return () => {
1607
1695
  const l = left(), r = right();
1608
1696
  if (op === "+") return l + r;
@@ -1610,12 +1698,12 @@ function parseExpressionUncached(expr, scope) {
1610
1698
  };
1611
1699
  }
1612
1700
  }
1613
- const mulMatch = expr.match(RE_MUL);
1701
+ const mulMatch = matchBinaryOp(expr, ["*", "/", "%"]);
1614
1702
  if (mulMatch) {
1615
- const left = parseExpression(mulMatch[1].trim(), scope);
1616
- const right = parseExpression(mulMatch[3].trim(), scope);
1703
+ const left = parseExpression(mulMatch.left, scope);
1704
+ const right = parseExpression(mulMatch.right, scope);
1617
1705
  if (left && right) {
1618
- const op = mulMatch[2];
1706
+ const op = mulMatch.op;
1619
1707
  return () => {
1620
1708
  const l = left(), r = right();
1621
1709
  switch (op) {
@@ -1728,7 +1816,7 @@ function parseHandler(expr, scope) {
1728
1816
  const handlers = stmts.map((s) => parseHandler(s, scope));
1729
1817
  if (handlers.every((h) => h !== null)) {
1730
1818
  return (e) => {
1731
- chunk2Y5US35K_cjs.batch(() => {
1819
+ chunkKUXNZ5MG_cjs.batch(() => {
1732
1820
  for (const h of handlers) h(e);
1733
1821
  });
1734
1822
  };
@@ -1741,7 +1829,7 @@ function parseHandler(expr, scope) {
1741
1829
  const name = incrMatch[1];
1742
1830
  const op = incrMatch[2];
1743
1831
  return () => {
1744
- chunk2Y5US35K_cjs.batch(() => {
1832
+ chunkKUXNZ5MG_cjs.batch(() => {
1745
1833
  const val = scope.getters[name]?.() ?? 0;
1746
1834
  scope.setters[name]?.(op === "++" ? val + 1 : val - 1);
1747
1835
  });
@@ -1752,7 +1840,7 @@ function parseHandler(expr, scope) {
1752
1840
  const op = preIncrMatch[1];
1753
1841
  const name = preIncrMatch[2];
1754
1842
  return () => {
1755
- chunk2Y5US35K_cjs.batch(() => {
1843
+ chunkKUXNZ5MG_cjs.batch(() => {
1756
1844
  const val = scope.getters[name]?.() ?? 0;
1757
1845
  scope.setters[name]?.(op === "++" ? val + 1 : val - 1);
1758
1846
  });
@@ -1762,7 +1850,7 @@ function parseHandler(expr, scope) {
1762
1850
  if (toggleMatch && toggleMatch[1] === toggleMatch[2]) {
1763
1851
  const name = toggleMatch[1];
1764
1852
  return () => {
1765
- chunk2Y5US35K_cjs.batch(() => {
1853
+ chunkKUXNZ5MG_cjs.batch(() => {
1766
1854
  scope.setters[name]?.(!scope.getters[name]?.());
1767
1855
  });
1768
1856
  };
@@ -1774,7 +1862,7 @@ function parseHandler(expr, scope) {
1774
1862
  if (valExpr) {
1775
1863
  if (_debug) dbg(`parseHandler: assignment "${name} = ..." \u2014 setter exists:`, !!scope.setters[name], ", getter exists:", !!scope.getters[name]);
1776
1864
  return () => {
1777
- chunk2Y5US35K_cjs.batch(() => {
1865
+ chunkKUXNZ5MG_cjs.batch(() => {
1778
1866
  const val = valExpr();
1779
1867
  if (_debug) dbg(`SETTER: ${name} = ${val} (was: ${scope.getters[name]?.()})`);
1780
1868
  scope.setters[name]?.(val);
@@ -1789,7 +1877,7 @@ function parseHandler(expr, scope) {
1789
1877
  const valExpr = parseExpression(compoundMatch[3].trim(), scope);
1790
1878
  if (valExpr) {
1791
1879
  return () => {
1792
- chunk2Y5US35K_cjs.batch(() => {
1880
+ chunkKUXNZ5MG_cjs.batch(() => {
1793
1881
  const current = scope.getters[name]?.() ?? 0;
1794
1882
  const val = valExpr();
1795
1883
  switch (op) {
@@ -1870,7 +1958,7 @@ function buildHandler(expr, scope) {
1870
1958
  }
1871
1959
  });
1872
1960
  const unsafeHandler = (e) => {
1873
- chunk2Y5US35K_cjs.batch(() => fn(proxy, e, e));
1961
+ chunkKUXNZ5MG_cjs.batch(() => fn(proxy, e, e));
1874
1962
  };
1875
1963
  const result = {
1876
1964
  handler: unsafeHandler,
@@ -1918,7 +2006,7 @@ function initScope(stateEl) {
1918
2006
  const getters = {};
1919
2007
  const setters = {};
1920
2008
  for (const [key, initial] of Object.entries(state)) {
1921
- const [get, set] = chunkW7OUWVRA_cjs.createSignal(initial);
2009
+ const [get, set] = chunkH7MDUHS5_cjs.createSignal(initial);
1922
2010
  getters[key] = get;
1923
2011
  setters[key] = set;
1924
2012
  }
@@ -2030,7 +2118,7 @@ function bindElement(el, scope, disposers) {
2030
2118
  const prevGetter = scope.getters[name];
2031
2119
  delete scope.getters[name];
2032
2120
  const evaluate = buildEvaluator(`{${expr}}`, scope);
2033
- const getter = chunkW7OUWVRA_cjs.createComputed(evaluate);
2121
+ const getter = chunkH7MDUHS5_cjs.createComputed(evaluate);
2034
2122
  scope.getters[name] = getter;
2035
2123
  if (!prevGetter) {
2036
2124
  delete scope.setters[name];
@@ -2041,7 +2129,7 @@ function bindElement(el, scope, disposers) {
2041
2129
  const textExpr = !known || known.has("data-text") ? el.getAttribute("data-text") : null;
2042
2130
  if (textExpr) {
2043
2131
  const evaluate = buildEvaluator(textExpr, scope);
2044
- const dispose = chunk2Y5US35K_cjs.internalEffect(() => {
2132
+ const dispose = chunkKUXNZ5MG_cjs.internalEffect(() => {
2045
2133
  setElementTextFast(el, toTextValue(evaluate()));
2046
2134
  });
2047
2135
  disposers.push(dispose);
@@ -2056,7 +2144,7 @@ function bindElement(el, scope, disposers) {
2056
2144
  dbg(`bindElement: data-show="${showExpr}" on <${tag}${cls}>`);
2057
2145
  }
2058
2146
  let initialized = false;
2059
- const dispose = chunk2Y5US35K_cjs.internalEffect(() => {
2147
+ const dispose = chunkKUXNZ5MG_cjs.internalEffect(() => {
2060
2148
  const visible = !!evaluate();
2061
2149
  if (_debug) dbg(`data-show effect: "${showExpr}" \u2192 ${visible}`);
2062
2150
  applyShowVisibility(el, visible, transition, !initialized);
@@ -2075,7 +2163,7 @@ function bindElement(el, scope, disposers) {
2075
2163
  const parent = el.parentNode;
2076
2164
  let inserted = true;
2077
2165
  let initialized = false;
2078
- const dispose = chunk2Y5US35K_cjs.internalEffect(() => {
2166
+ const dispose = chunkKUXNZ5MG_cjs.internalEffect(() => {
2079
2167
  const show = !!evaluate();
2080
2168
  if (show && !inserted) {
2081
2169
  clearTransitionState(el);
@@ -2110,25 +2198,61 @@ function bindElement(el, scope, disposers) {
2110
2198
  const modelExpr = !known || known.has("data-model") ? el.getAttribute("data-model") : null;
2111
2199
  if (modelExpr) {
2112
2200
  const prop = modelExpr.replace(RE_STRIP_BRACES, "").trim();
2113
- const getter = scope.getters[prop];
2114
- const setter = scope.setters[prop];
2201
+ let getter = scope.getters[prop];
2202
+ let setter = scope.setters[prop];
2203
+ if ((!getter || !setter) && prop.includes(".")) {
2204
+ getter = buildEvaluator(prop, scope);
2205
+ const lastDot = prop.lastIndexOf(".");
2206
+ const basePath = prop.slice(0, lastDot);
2207
+ const key = prop.slice(lastDot + 1);
2208
+ const baseGet = buildEvaluator(basePath, scope);
2209
+ setter = (v) => {
2210
+ const base = baseGet();
2211
+ if (base != null && typeof base === "object") base[key] = v;
2212
+ };
2213
+ }
2115
2214
  if (getter && setter) {
2116
2215
  const input = el;
2117
- const dispose = chunk2Y5US35K_cjs.internalEffect(() => {
2216
+ const tag = input.tagName;
2217
+ const dispose = chunkKUXNZ5MG_cjs.internalEffect(() => {
2118
2218
  const val = getter();
2119
- if (input.type === "checkbox") {
2219
+ const type = input.type;
2220
+ if (type === "checkbox") {
2120
2221
  input.checked = !!val;
2222
+ const indetExpr = el.getAttribute("data-model-indeterminate");
2223
+ if (indetExpr) {
2224
+ const indetGetter = scope.getters[indetExpr.replace(RE_STRIP_BRACES, "").trim()];
2225
+ if (indetGetter) input.indeterminate = !!indetGetter();
2226
+ }
2227
+ } else if (type === "radio") {
2228
+ input.checked = String(val) === input.value;
2229
+ } else if (tag === "SELECT" && input.multiple) {
2230
+ const sel = input;
2231
+ const arr = Array.isArray(val) ? val.map(String) : [];
2232
+ for (const opt of Array.from(sel.options)) opt.selected = arr.includes(opt.value);
2121
2233
  } else {
2122
2234
  input.value = String(val ?? "");
2123
2235
  }
2124
2236
  });
2125
2237
  disposers.push(dispose);
2126
- const event = input.type === "checkbox" ? "change" : "input";
2238
+ const event = input.type === "checkbox" || input.type === "radio" || tag === "SELECT" ? "change" : "input";
2127
2239
  const onModelInput = () => {
2128
- if (input.type === "checkbox") {
2240
+ const type = input.type;
2241
+ if (type === "checkbox") {
2129
2242
  setter(input.checked);
2130
- } else if (input.type === "number" || input.type === "range") {
2131
- setter(Number(input.value));
2243
+ } else if (type === "radio") {
2244
+ if (input.checked) setter(input.value);
2245
+ } else if (tag === "SELECT" && input.multiple) {
2246
+ const sel = input;
2247
+ setter(Array.from(sel.selectedOptions).map((o) => o.value));
2248
+ } else if (type === "number" || type === "range") {
2249
+ const raw = input.value;
2250
+ if (raw === "") {
2251
+ setter(null);
2252
+ } else {
2253
+ const n = Number(raw);
2254
+ if (!Number.isNaN(n)) setter(n);
2255
+ }
2132
2256
  } else {
2133
2257
  setter(input.value);
2134
2258
  }
@@ -2178,14 +2302,14 @@ function bindElement(el, scope, disposers) {
2178
2302
  } else if (name.startsWith("data-class:")) {
2179
2303
  const cls = name.slice(11);
2180
2304
  const evaluate = buildEvaluator(attr.value, scope);
2181
- const dispose = chunk2Y5US35K_cjs.internalEffect(() => {
2305
+ const dispose = chunkKUXNZ5MG_cjs.internalEffect(() => {
2182
2306
  el.classList.toggle(cls, !!evaluate());
2183
2307
  });
2184
2308
  disposers.push(dispose);
2185
2309
  } else if (name.startsWith("data-bind:")) {
2186
2310
  const attrName = name.slice(10);
2187
2311
  const evaluate = buildEvaluator(attr.value, scope);
2188
- const dispose = chunk2Y5US35K_cjs.internalEffect(() => {
2312
+ const dispose = chunkKUXNZ5MG_cjs.internalEffect(() => {
2189
2313
  const val = evaluate();
2190
2314
  if (val == null || val === false) {
2191
2315
  el.removeAttribute(attrName);
@@ -2213,7 +2337,7 @@ function bindElement(el, scope, disposers) {
2213
2337
  if (saved !== null) setter(JSON.parse(saved));
2214
2338
  } catch {
2215
2339
  }
2216
- const dispose = chunk2Y5US35K_cjs.internalEffect(() => {
2340
+ const dispose = chunkKUXNZ5MG_cjs.internalEffect(() => {
2217
2341
  try {
2218
2342
  localStorage.setItem(key, JSON.stringify(getter()));
2219
2343
  } catch {
@@ -2300,7 +2424,7 @@ function bindElement(el, scope, disposers) {
2300
2424
  });
2301
2425
  }
2302
2426
  } : void 0;
2303
- const dispose = chunk2Y5US35K_cjs.internalEffect(() => {
2427
+ const dispose = chunkKUXNZ5MG_cjs.internalEffect(() => {
2304
2428
  const rawItems = evaluate();
2305
2429
  if (!Array.isArray(rawItems)) {
2306
2430
  for (const n of oldNodes) {
@@ -2320,59 +2444,30 @@ function bindElement(el, scope, disposers) {
2320
2444
  }
2321
2445
  }
2322
2446
  const prevNodes = new Set(oldNodes);
2323
- if (keyProp) {
2324
- const result = chunkJRQNDXX7_cjs.reconcileList(
2325
- el,
2326
- oldItems,
2327
- rawItems,
2328
- oldNodes,
2329
- (item) => String(item?.[keyProp] ?? ""),
2330
- (item) => {
2331
- const idx = rawItems.indexOf(item);
2332
- return createBoundClone2(item, idx);
2333
- },
2334
- (node, item) => {
2335
- const idx = rawItems.indexOf(item);
2336
- updateBoundClone2(node, item, idx);
2337
- },
2338
- void 0,
2339
- // beforeNode
2340
- listHooks
2341
- );
2342
- const nextNodes = new Set(result.nodes);
2343
- for (const n of prevNodes) {
2344
- if (!nextNodes.has(n)) {
2345
- if (n.hasAttribute?.("data-forma-leaving")) continue;
2346
- disposeCloneBindings2(n);
2347
- }
2348
- }
2349
- oldItems = result.items;
2350
- oldNodes = result.nodes;
2351
- } else {
2352
- const wrapped = rawItems.map((item, i) => ({ __idx: i, __item: item }));
2353
- const oldWrapped = oldItems;
2354
- const result = chunkJRQNDXX7_cjs.reconcileList(
2355
- el,
2356
- oldWrapped,
2357
- wrapped,
2358
- oldNodes,
2359
- (w) => w.__idx,
2360
- (w) => createBoundClone2(w.__item, w.__idx),
2361
- (node, w) => updateBoundClone2(node, w.__item, w.__idx),
2362
- void 0,
2363
- // beforeNode
2364
- listHooks
2365
- );
2366
- const nextNodes = new Set(result.nodes);
2367
- for (const n of prevNodes) {
2368
- if (!nextNodes.has(n)) {
2369
- if (n.hasAttribute?.("data-forma-leaving")) continue;
2370
- disposeCloneBindings2(n);
2371
- }
2447
+ const wrapped = rawItems.map((item, i) => ({ __idx: i, __item: item }));
2448
+ const oldWrapped = oldItems;
2449
+ const keyFn = keyProp ? (w) => String(w.__item?.[keyProp] ?? "") : (w) => w.__idx;
2450
+ const result = chunkFBM7V4NE_cjs.reconcileList(
2451
+ el,
2452
+ oldWrapped,
2453
+ wrapped,
2454
+ oldNodes,
2455
+ keyFn,
2456
+ (w) => createBoundClone2(w.__item, w.__idx),
2457
+ (node, w) => updateBoundClone2(node, w.__item, w.__idx),
2458
+ void 0,
2459
+ // beforeNode
2460
+ listHooks
2461
+ );
2462
+ const nextNodes = new Set(result.nodes);
2463
+ for (const n of prevNodes) {
2464
+ if (!nextNodes.has(n)) {
2465
+ if (n.hasAttribute?.("data-forma-leaving")) continue;
2466
+ disposeCloneBindings2(n);
2372
2467
  }
2373
- oldItems = result.items;
2374
- oldNodes = result.nodes;
2375
2468
  }
2469
+ oldItems = result.items;
2470
+ oldNodes = result.nodes;
2376
2471
  });
2377
2472
  disposers.push(dispose);
2378
2473
  }
@@ -2400,16 +2495,16 @@ function bindElement(el, scope, disposers) {
2400
2495
  else if (k === "error") errorTarget = v;
2401
2496
  else if (k === "poll") interval = parseInt(v ?? "0", 10);
2402
2497
  }
2403
- const [getTarget, setTarget] = chunkW7OUWVRA_cjs.createSignal(null);
2498
+ const [getTarget, setTarget] = chunkH7MDUHS5_cjs.createSignal(null);
2404
2499
  scope.getters[target] = getTarget;
2405
2500
  scope.setters[target] = setTarget;
2406
2501
  if (loadingTarget) {
2407
- const [gl, sl] = chunkW7OUWVRA_cjs.createSignal(false);
2502
+ const [gl, sl] = chunkH7MDUHS5_cjs.createSignal(false);
2408
2503
  scope.getters[loadingTarget] = gl;
2409
2504
  scope.setters[loadingTarget] = sl;
2410
2505
  }
2411
2506
  if (errorTarget) {
2412
- const [ge, se] = chunkW7OUWVRA_cjs.createSignal(null);
2507
+ const [ge, se] = chunkH7MDUHS5_cjs.createSignal(null);
2413
2508
  scope.getters[errorTarget] = ge;
2414
2509
  scope.setters[errorTarget] = se;
2415
2510
  }
@@ -2738,7 +2833,7 @@ function getScopes() {
2738
2833
  function setScopeValue(element, key, value) {
2739
2834
  const scope = element.__formaScope;
2740
2835
  if (!scope?.setters[key]) return;
2741
- chunk2Y5US35K_cjs.batch(() => {
2836
+ chunkKUXNZ5MG_cjs.batch(() => {
2742
2837
  scope.setters[key](value);
2743
2838
  });
2744
2839
  }
@@ -2747,7 +2842,7 @@ function resetScope(element) {
2747
2842
  const initialJSON = element.__formaInitialState;
2748
2843
  if (!scope || !initialJSON) return;
2749
2844
  const initial = parseState(initialJSON);
2750
- chunk2Y5US35K_cjs.batch(() => {
2845
+ chunkKUXNZ5MG_cjs.batch(() => {
2751
2846
  for (const [key, val] of Object.entries(initial)) {
2752
2847
  scope.setters[key]?.(val);
2753
2848
  }
@@ -2777,7 +2872,7 @@ function getReconciler() {
2777
2872
  }
2778
2873
  }
2779
2874
  },
2780
- batch: chunk2Y5US35K_cjs.batch
2875
+ batch: chunkKUXNZ5MG_cjs.batch
2781
2876
  });
2782
2877
  }
2783
2878
  return _reconciler;