@getforma/core 1.2.0 → 1.4.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.
- package/dist/{chunk-YRNYOZF3.js → chunk-AJP4OVCN.js} +27 -7
- package/dist/chunk-AJP4OVCN.js.map +1 -0
- package/dist/{chunk-E3FV2VSU.cjs → chunk-FBM7V4NE.cjs} +27 -6
- package/dist/chunk-FBM7V4NE.cjs.map +1 -0
- package/dist/forma-runtime-csp.js +178 -79
- package/dist/forma-runtime.js +178 -79
- package/dist/formajs-runtime-hardened.global.js +178 -79
- package/dist/formajs-runtime-hardened.global.js.map +1 -1
- package/dist/formajs-runtime.global.js +178 -79
- package/dist/formajs-runtime.global.js.map +1 -1
- package/dist/formajs.global.js +69 -9
- package/dist/formajs.global.js.map +1 -1
- package/dist/index.cjs +59 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -1
- package/dist/index.d.ts +14 -1
- package/dist/index.js +46 -7
- package/dist/index.js.map +1 -1
- package/dist/runtime-hardened.cjs +178 -79
- package/dist/runtime-hardened.cjs.map +1 -1
- package/dist/runtime-hardened.js +178 -79
- package/dist/runtime-hardened.js.map +1 -1
- package/dist/runtime.cjs +172 -77
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.js +172 -77
- package/dist/runtime.js.map +1 -1
- package/dist/server.cjs +62 -9
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +29 -3
- package/dist/server.d.ts +29 -3
- package/dist/server.js +62 -10
- package/dist/server.js.map +1 -1
- package/dist/ssr/index.cjs +22 -4
- package/dist/ssr/index.cjs.map +1 -1
- package/dist/ssr/index.d.cts +7 -0
- package/dist/ssr/index.d.ts +7 -0
- package/dist/ssr/index.js +22 -4
- package/dist/ssr/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-E3FV2VSU.cjs.map +0 -1
- package/dist/chunk-YRNYOZF3.js.map +0 -1
package/dist/runtime-hardened.js
CHANGED
|
@@ -239,14 +239,18 @@ function reconcileList(parent, oldItems, newItems, oldNodes, keyFn, createFn, up
|
|
|
239
239
|
}
|
|
240
240
|
const oldKeyMap = /* @__PURE__ */ new Map();
|
|
241
241
|
for (let i = 0; i < oldLen; i++) {
|
|
242
|
-
|
|
242
|
+
const k = keyFn(oldItems[i]);
|
|
243
|
+
const bucket = oldKeyMap.get(k);
|
|
244
|
+
if (bucket) bucket.push(i);
|
|
245
|
+
else oldKeyMap.set(k, [i]);
|
|
243
246
|
}
|
|
244
247
|
const oldIndices = new Array(newLen);
|
|
245
248
|
const oldUsed = new Uint8Array(oldLen);
|
|
246
249
|
for (let i = 0; i < newLen; i++) {
|
|
247
250
|
const key = keyFn(newItems[i]);
|
|
248
|
-
const
|
|
249
|
-
if (
|
|
251
|
+
const bucket = oldKeyMap.get(key);
|
|
252
|
+
if (bucket && bucket.length > 0) {
|
|
253
|
+
const oldIdx = bucket.shift();
|
|
250
254
|
oldIndices[i] = oldIdx;
|
|
251
255
|
oldUsed[oldIdx] = 1;
|
|
252
256
|
} else {
|
|
@@ -595,12 +599,12 @@ function findInsertionPoint(parent, newChild, newChildren) {
|
|
|
595
599
|
return null;
|
|
596
600
|
}
|
|
597
601
|
function createReconciler(config) {
|
|
598
|
-
|
|
602
|
+
const lastHtmlByContainer = /* @__PURE__ */ new WeakMap();
|
|
599
603
|
return function reconcile2(container, html) {
|
|
600
604
|
const trimmed = html.trim();
|
|
601
605
|
if (!trimmed) return;
|
|
602
|
-
if (
|
|
603
|
-
|
|
606
|
+
if (lastHtmlByContainer.get(container) === trimmed && container.hasChildNodes()) return;
|
|
607
|
+
lastHtmlByContainer.set(container, trimmed);
|
|
604
608
|
config.disconnectObserver();
|
|
605
609
|
try {
|
|
606
610
|
if (!container.hasChildNodes() || container.children.length === 0) {
|
|
@@ -914,9 +918,97 @@ var RE_TERNARY = /^(.+?)\s*\?\s*(.+?)\s*:\s*(.+)$/;
|
|
|
914
918
|
var RE_NULLISH = /^(.+?)\s*\?\?\s*(.+)$/;
|
|
915
919
|
var RE_AND = /^(.+?)\s*&&\s*(.+)$/;
|
|
916
920
|
var RE_OR = /^(.+?)\s*\|\|\s*(.+)$/;
|
|
917
|
-
var
|
|
918
|
-
|
|
919
|
-
|
|
921
|
+
var UNARY_PRECEDERS = "+-*/%<>=!&|^~(,[{?:";
|
|
922
|
+
function matchBinaryOp(expr, ops) {
|
|
923
|
+
const SQ = String.fromCharCode(39);
|
|
924
|
+
const DQ = String.fromCharCode(34);
|
|
925
|
+
const BT = String.fromCharCode(96);
|
|
926
|
+
const BS = String.fromCharCode(92);
|
|
927
|
+
let depth = 0;
|
|
928
|
+
let inSingle = false, inDouble = false, inTemplate = false, escaped = false;
|
|
929
|
+
let prevSig = "";
|
|
930
|
+
let bestIdx = -1;
|
|
931
|
+
let bestOp = "";
|
|
932
|
+
for (let i = 0; i < expr.length; i++) {
|
|
933
|
+
const ch = expr[i];
|
|
934
|
+
if (escaped) {
|
|
935
|
+
escaped = false;
|
|
936
|
+
continue;
|
|
937
|
+
}
|
|
938
|
+
if (ch === BS && (inSingle || inDouble || inTemplate)) {
|
|
939
|
+
escaped = true;
|
|
940
|
+
continue;
|
|
941
|
+
}
|
|
942
|
+
if (inSingle) {
|
|
943
|
+
if (ch === SQ) {
|
|
944
|
+
inSingle = false;
|
|
945
|
+
prevSig = DQ;
|
|
946
|
+
}
|
|
947
|
+
continue;
|
|
948
|
+
}
|
|
949
|
+
if (inDouble) {
|
|
950
|
+
if (ch === DQ) {
|
|
951
|
+
inDouble = false;
|
|
952
|
+
prevSig = DQ;
|
|
953
|
+
}
|
|
954
|
+
continue;
|
|
955
|
+
}
|
|
956
|
+
if (inTemplate) {
|
|
957
|
+
if (ch === BT) {
|
|
958
|
+
inTemplate = false;
|
|
959
|
+
prevSig = DQ;
|
|
960
|
+
}
|
|
961
|
+
continue;
|
|
962
|
+
}
|
|
963
|
+
if (ch === SQ) {
|
|
964
|
+
inSingle = true;
|
|
965
|
+
continue;
|
|
966
|
+
}
|
|
967
|
+
if (ch === DQ) {
|
|
968
|
+
inDouble = true;
|
|
969
|
+
continue;
|
|
970
|
+
}
|
|
971
|
+
if (ch === BT) {
|
|
972
|
+
inTemplate = true;
|
|
973
|
+
continue;
|
|
974
|
+
}
|
|
975
|
+
if (ch === "(" || ch === "[" || ch === "{") {
|
|
976
|
+
depth++;
|
|
977
|
+
prevSig = ch;
|
|
978
|
+
continue;
|
|
979
|
+
}
|
|
980
|
+
if (ch === ")" || ch === "]" || ch === "}") {
|
|
981
|
+
if (depth > 0) depth--;
|
|
982
|
+
prevSig = ch;
|
|
983
|
+
continue;
|
|
984
|
+
}
|
|
985
|
+
if (depth !== 0) continue;
|
|
986
|
+
if (ch === " " || ch === " " || ch === "\n") continue;
|
|
987
|
+
if (i > 0) {
|
|
988
|
+
let matchedOp = "";
|
|
989
|
+
for (const op of ops) {
|
|
990
|
+
if (expr.startsWith(op, i)) {
|
|
991
|
+
matchedOp = op;
|
|
992
|
+
break;
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
if (matchedOp) {
|
|
996
|
+
const isPlusMinus = matchedOp === "+" || matchedOp === "-";
|
|
997
|
+
const unary = isPlusMinus && (prevSig === "" || UNARY_PRECEDERS.includes(prevSig));
|
|
998
|
+
if (!unary) {
|
|
999
|
+
bestIdx = i;
|
|
1000
|
+
bestOp = matchedOp;
|
|
1001
|
+
}
|
|
1002
|
+
i += matchedOp.length - 1;
|
|
1003
|
+
prevSig = matchedOp[matchedOp.length - 1];
|
|
1004
|
+
continue;
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
prevSig = ch;
|
|
1008
|
+
}
|
|
1009
|
+
if (bestIdx === -1) return null;
|
|
1010
|
+
return { left: expr.slice(0, bestIdx).trim(), op: bestOp, right: expr.slice(bestIdx + bestOp.length).trim() };
|
|
1011
|
+
}
|
|
920
1012
|
var RE_TEMPLATE_LIT = /^`([^`]*)`$/;
|
|
921
1013
|
var RE_TEMPLATE_INTERP = /\$\{([^}]+)\}/g;
|
|
922
1014
|
var RE_GROUP_METHOD_CALL = /^\((.+)\)\.(\w+)\((.*)\)$/;
|
|
@@ -1873,12 +1965,12 @@ function parseExpressionUncached(expr, scope) {
|
|
|
1873
1965
|
return () => left() && right();
|
|
1874
1966
|
}
|
|
1875
1967
|
}
|
|
1876
|
-
const compMatch = expr
|
|
1968
|
+
const compMatch = matchBinaryOp(expr, ["===", "!==", "==", "!=", ">=", "<=", ">", "<"]);
|
|
1877
1969
|
if (compMatch) {
|
|
1878
|
-
const left = parseExpression(compMatch
|
|
1879
|
-
const right = parseExpression(compMatch
|
|
1970
|
+
const left = parseExpression(compMatch.left, scope);
|
|
1971
|
+
const right = parseExpression(compMatch.right, scope);
|
|
1880
1972
|
if (left && right) {
|
|
1881
|
-
const op = compMatch
|
|
1973
|
+
const op = compMatch.op;
|
|
1882
1974
|
return () => {
|
|
1883
1975
|
const l = left(), r = right();
|
|
1884
1976
|
switch (op) {
|
|
@@ -1902,12 +1994,12 @@ function parseExpressionUncached(expr, scope) {
|
|
|
1902
1994
|
};
|
|
1903
1995
|
}
|
|
1904
1996
|
}
|
|
1905
|
-
const addMatch = expr
|
|
1997
|
+
const addMatch = matchBinaryOp(expr, ["+", "-"]);
|
|
1906
1998
|
if (addMatch) {
|
|
1907
|
-
const left = parseExpression(addMatch
|
|
1908
|
-
const right = parseExpression(addMatch
|
|
1999
|
+
const left = parseExpression(addMatch.left, scope);
|
|
2000
|
+
const right = parseExpression(addMatch.right, scope);
|
|
1909
2001
|
if (left && right) {
|
|
1910
|
-
const op = addMatch
|
|
2002
|
+
const op = addMatch.op;
|
|
1911
2003
|
return () => {
|
|
1912
2004
|
const l = left(), r = right();
|
|
1913
2005
|
if (op === "+") return l + r;
|
|
@@ -1915,12 +2007,12 @@ function parseExpressionUncached(expr, scope) {
|
|
|
1915
2007
|
};
|
|
1916
2008
|
}
|
|
1917
2009
|
}
|
|
1918
|
-
const mulMatch = expr
|
|
2010
|
+
const mulMatch = matchBinaryOp(expr, ["*", "/", "%"]);
|
|
1919
2011
|
if (mulMatch) {
|
|
1920
|
-
const left = parseExpression(mulMatch
|
|
1921
|
-
const right = parseExpression(mulMatch
|
|
2012
|
+
const left = parseExpression(mulMatch.left, scope);
|
|
2013
|
+
const right = parseExpression(mulMatch.right, scope);
|
|
1922
2014
|
if (left && right) {
|
|
1923
|
-
const op = mulMatch
|
|
2015
|
+
const op = mulMatch.op;
|
|
1924
2016
|
return () => {
|
|
1925
2017
|
const l = left(), r = right();
|
|
1926
2018
|
switch (op) {
|
|
@@ -2345,25 +2437,61 @@ function bindElement(el, scope, disposers) {
|
|
|
2345
2437
|
const modelExpr = !known || known.has("data-model") ? el.getAttribute("data-model") : null;
|
|
2346
2438
|
if (modelExpr) {
|
|
2347
2439
|
const prop = modelExpr.replace(RE_STRIP_BRACES, "").trim();
|
|
2348
|
-
|
|
2349
|
-
|
|
2440
|
+
let getter = scope.getters[prop];
|
|
2441
|
+
let setter = scope.setters[prop];
|
|
2442
|
+
if ((!getter || !setter) && prop.includes(".")) {
|
|
2443
|
+
getter = buildEvaluator(prop, scope);
|
|
2444
|
+
const lastDot = prop.lastIndexOf(".");
|
|
2445
|
+
const basePath = prop.slice(0, lastDot);
|
|
2446
|
+
const key = prop.slice(lastDot + 1);
|
|
2447
|
+
const baseGet = buildEvaluator(basePath, scope);
|
|
2448
|
+
setter = (v) => {
|
|
2449
|
+
const base = baseGet();
|
|
2450
|
+
if (base != null && typeof base === "object") base[key] = v;
|
|
2451
|
+
};
|
|
2452
|
+
}
|
|
2350
2453
|
if (getter && setter) {
|
|
2351
2454
|
const input = el;
|
|
2455
|
+
const tag = input.tagName;
|
|
2352
2456
|
const dispose = internalEffect(() => {
|
|
2353
2457
|
const val = getter();
|
|
2354
|
-
|
|
2458
|
+
const type = input.type;
|
|
2459
|
+
if (type === "checkbox") {
|
|
2355
2460
|
input.checked = !!val;
|
|
2461
|
+
const indetExpr = el.getAttribute("data-model-indeterminate");
|
|
2462
|
+
if (indetExpr) {
|
|
2463
|
+
const indetGetter = scope.getters[indetExpr.replace(RE_STRIP_BRACES, "").trim()];
|
|
2464
|
+
if (indetGetter) input.indeterminate = !!indetGetter();
|
|
2465
|
+
}
|
|
2466
|
+
} else if (type === "radio") {
|
|
2467
|
+
input.checked = String(val) === input.value;
|
|
2468
|
+
} else if (tag === "SELECT" && input.multiple) {
|
|
2469
|
+
const sel = input;
|
|
2470
|
+
const arr = Array.isArray(val) ? val.map(String) : [];
|
|
2471
|
+
for (const opt of Array.from(sel.options)) opt.selected = arr.includes(opt.value);
|
|
2356
2472
|
} else {
|
|
2357
2473
|
input.value = String(val ?? "");
|
|
2358
2474
|
}
|
|
2359
2475
|
});
|
|
2360
2476
|
disposers.push(dispose);
|
|
2361
|
-
const event = input.type === "checkbox" ? "change" : "input";
|
|
2477
|
+
const event = input.type === "checkbox" || input.type === "radio" || tag === "SELECT" ? "change" : "input";
|
|
2362
2478
|
const onModelInput = () => {
|
|
2363
|
-
|
|
2479
|
+
const type = input.type;
|
|
2480
|
+
if (type === "checkbox") {
|
|
2364
2481
|
setter(input.checked);
|
|
2365
|
-
} else if (
|
|
2366
|
-
setter(
|
|
2482
|
+
} else if (type === "radio") {
|
|
2483
|
+
if (input.checked) setter(input.value);
|
|
2484
|
+
} else if (tag === "SELECT" && input.multiple) {
|
|
2485
|
+
const sel = input;
|
|
2486
|
+
setter(Array.from(sel.selectedOptions).map((o) => o.value));
|
|
2487
|
+
} else if (type === "number" || type === "range") {
|
|
2488
|
+
const raw = input.value;
|
|
2489
|
+
if (raw === "") {
|
|
2490
|
+
setter(null);
|
|
2491
|
+
} else {
|
|
2492
|
+
const n = Number(raw);
|
|
2493
|
+
if (!Number.isNaN(n)) setter(n);
|
|
2494
|
+
}
|
|
2367
2495
|
} else {
|
|
2368
2496
|
setter(input.value);
|
|
2369
2497
|
}
|
|
@@ -2555,59 +2683,30 @@ function bindElement(el, scope, disposers) {
|
|
|
2555
2683
|
}
|
|
2556
2684
|
}
|
|
2557
2685
|
const prevNodes = new Set(oldNodes);
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
for (const n of prevNodes) {
|
|
2579
|
-
if (!nextNodes.has(n)) {
|
|
2580
|
-
if (n.hasAttribute?.("data-forma-leaving")) continue;
|
|
2581
|
-
disposeCloneBindings2(n);
|
|
2582
|
-
}
|
|
2583
|
-
}
|
|
2584
|
-
oldItems = result.items;
|
|
2585
|
-
oldNodes = result.nodes;
|
|
2586
|
-
} else {
|
|
2587
|
-
const wrapped = rawItems.map((item, i) => ({ __idx: i, __item: item }));
|
|
2588
|
-
const oldWrapped = oldItems;
|
|
2589
|
-
const result = reconcileList(
|
|
2590
|
-
el,
|
|
2591
|
-
oldWrapped,
|
|
2592
|
-
wrapped,
|
|
2593
|
-
oldNodes,
|
|
2594
|
-
(w) => w.__idx,
|
|
2595
|
-
(w) => createBoundClone2(w.__item, w.__idx),
|
|
2596
|
-
(node, w) => updateBoundClone2(node, w.__item, w.__idx),
|
|
2597
|
-
void 0,
|
|
2598
|
-
// beforeNode
|
|
2599
|
-
listHooks
|
|
2600
|
-
);
|
|
2601
|
-
const nextNodes = new Set(result.nodes);
|
|
2602
|
-
for (const n of prevNodes) {
|
|
2603
|
-
if (!nextNodes.has(n)) {
|
|
2604
|
-
if (n.hasAttribute?.("data-forma-leaving")) continue;
|
|
2605
|
-
disposeCloneBindings2(n);
|
|
2606
|
-
}
|
|
2686
|
+
const wrapped = rawItems.map((item, i) => ({ __idx: i, __item: item }));
|
|
2687
|
+
const oldWrapped = oldItems;
|
|
2688
|
+
const keyFn = keyProp ? (w) => String(w.__item?.[keyProp] ?? "") : (w) => w.__idx;
|
|
2689
|
+
const result = reconcileList(
|
|
2690
|
+
el,
|
|
2691
|
+
oldWrapped,
|
|
2692
|
+
wrapped,
|
|
2693
|
+
oldNodes,
|
|
2694
|
+
keyFn,
|
|
2695
|
+
(w) => createBoundClone2(w.__item, w.__idx),
|
|
2696
|
+
(node, w) => updateBoundClone2(node, w.__item, w.__idx),
|
|
2697
|
+
void 0,
|
|
2698
|
+
// beforeNode
|
|
2699
|
+
listHooks
|
|
2700
|
+
);
|
|
2701
|
+
const nextNodes = new Set(result.nodes);
|
|
2702
|
+
for (const n of prevNodes) {
|
|
2703
|
+
if (!nextNodes.has(n)) {
|
|
2704
|
+
if (n.hasAttribute?.("data-forma-leaving")) continue;
|
|
2705
|
+
disposeCloneBindings2(n);
|
|
2607
2706
|
}
|
|
2608
|
-
oldItems = result.items;
|
|
2609
|
-
oldNodes = result.nodes;
|
|
2610
2707
|
}
|
|
2708
|
+
oldItems = result.items;
|
|
2709
|
+
oldNodes = result.nodes;
|
|
2611
2710
|
});
|
|
2612
2711
|
disposers.push(dispose);
|
|
2613
2712
|
}
|