@getforma/core 0.3.1 → 0.6.1
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/README.md +190 -16
- package/dist/{chunk-KX5WRZH7.js → chunk-DPSAVBCP.js} +3 -4
- package/dist/chunk-DPSAVBCP.js.map +1 -0
- package/dist/{chunk-FPSLC62A.cjs → chunk-KH3F5NRU.cjs} +2 -4
- package/dist/chunk-KH3F5NRU.cjs.map +1 -0
- package/dist/{chunk-5H52PKGF.js → chunk-TKGUHASG.js} +20 -10
- package/dist/chunk-TKGUHASG.js.map +1 -0
- package/dist/{chunk-TSQ7AKFT.cjs → chunk-YSKF3VRA.cjs} +27 -17
- package/dist/chunk-YSKF3VRA.cjs.map +1 -0
- package/dist/forma-runtime-csp.js +1 -1
- package/dist/forma-runtime.js +1 -1
- package/dist/formajs-runtime-hardened.global.js +1 -1
- package/dist/formajs-runtime-hardened.global.js.map +1 -1
- package/dist/formajs-runtime.global.js +1 -1
- package/dist/formajs-runtime.global.js.map +1 -1
- package/dist/formajs.global.js +1 -1
- package/dist/formajs.global.js.map +1 -1
- package/dist/index.cjs +102 -75
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +41 -9
- package/dist/index.d.ts +41 -9
- package/dist/index.js +46 -17
- package/dist/index.js.map +1 -1
- package/dist/runtime-hardened.cjs +61 -13
- package/dist/runtime-hardened.cjs.map +1 -1
- package/dist/runtime-hardened.js +62 -14
- package/dist/runtime-hardened.js.map +1 -1
- package/dist/runtime.cjs +85 -36
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.js +63 -14
- package/dist/runtime.js.map +1 -1
- package/dist/ssr/index.cjs +18 -10
- package/dist/ssr/index.cjs.map +1 -1
- package/dist/ssr/index.js +18 -10
- package/dist/ssr/index.js.map +1 -1
- package/dist/tc39-compat.cjs +3 -3
- package/dist/tc39-compat.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-5H52PKGF.js.map +0 -1
- package/dist/chunk-FPSLC62A.cjs.map +0 -1
- package/dist/chunk-KX5WRZH7.js.map +0 -1
- package/dist/chunk-TSQ7AKFT.cjs.map +0 -1
package/dist/runtime.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { internalEffect, reconcileList, batch } from './chunk-
|
|
2
|
-
import {
|
|
1
|
+
import { internalEffect, reconcileList, batch } from './chunk-TKGUHASG.js';
|
|
2
|
+
import { createSignal, createComputed } from './chunk-DPSAVBCP.js';
|
|
3
3
|
|
|
4
4
|
// src/dom/reconcile.ts
|
|
5
5
|
function getBindTargets(el) {
|
|
@@ -576,12 +576,11 @@ var RE_TOGGLE = /^(\w+)\s*=\s*!(\w+)$/;
|
|
|
576
576
|
var RE_ASSIGN = /^(\w+)\s*=\s*(.+)$/;
|
|
577
577
|
var RE_COMPOUND = /^(\w+)\s*(\+=|-=|\*=|\/=)\s*(.+)$/;
|
|
578
578
|
var RE_IF_PREFIX = /^if\b/;
|
|
579
|
-
var RE_UNQUOTED_KEYS = /(\w+)\s*:/g;
|
|
580
579
|
var RE_COMPUTED = /^(\w+)\s*=\s*(.+)$/;
|
|
581
580
|
var RE_FETCH = /^(.+?)(?:→|->)\s*(\S+)(.*)$/;
|
|
582
581
|
var RE_FETCH_METHOD = /^(GET|POST|PUT|PATCH|DELETE)\s+(.+)$/i;
|
|
583
582
|
var RE_STRIP_ITEM_BRACES = /^\{item\.?|\}$/g;
|
|
584
|
-
var RE_EVENT_REF = /\bevent\
|
|
583
|
+
var RE_EVENT_REF = /\bevent\s*[.([]|\$event\b/;
|
|
585
584
|
var RE_REFETCH_CALL = /^\$refetch\(\s*['"]([^'"]+)['"]\s*\)$/;
|
|
586
585
|
var TRANSITION_STATE_SYM = /* @__PURE__ */ Symbol.for("forma-transition-state");
|
|
587
586
|
var EXPRESSION_CACHE_MAX = 2048;
|
|
@@ -596,6 +595,14 @@ function cacheExpression(key, factory) {
|
|
|
596
595
|
var scopeExpressionCache = /* @__PURE__ */ new WeakMap();
|
|
597
596
|
var scopeHandlerCache = /* @__PURE__ */ new WeakMap();
|
|
598
597
|
var compiledTemplateCache = /* @__PURE__ */ new Map();
|
|
598
|
+
var COMPILED_TEMPLATE_CACHE_MAX = 2048;
|
|
599
|
+
function cacheCompiledTemplate(key, template) {
|
|
600
|
+
if (compiledTemplateCache.size >= COMPILED_TEMPLATE_CACHE_MAX) {
|
|
601
|
+
const first = compiledTemplateCache.keys().next().value;
|
|
602
|
+
if (first !== void 0) compiledTemplateCache.delete(first);
|
|
603
|
+
}
|
|
604
|
+
compiledTemplateCache.set(key, template);
|
|
605
|
+
}
|
|
599
606
|
var UNSAFE_METHOD_NAMES = /* @__PURE__ */ new Set([
|
|
600
607
|
"constructor",
|
|
601
608
|
"__proto__",
|
|
@@ -604,7 +611,8 @@ var UNSAFE_METHOD_NAMES = /* @__PURE__ */ new Set([
|
|
|
604
611
|
"__defineSetter__",
|
|
605
612
|
"__lookupGetter__",
|
|
606
613
|
"__lookupSetter__",
|
|
607
|
-
"eval"
|
|
614
|
+
"eval",
|
|
615
|
+
"Function"
|
|
608
616
|
]);
|
|
609
617
|
var BLOCKED_METHOD_REGEXES = (() => {
|
|
610
618
|
const result = [];
|
|
@@ -628,8 +636,36 @@ function findBlockedMethod(expr) {
|
|
|
628
636
|
if (dotRe.test(cleaned)) return name;
|
|
629
637
|
if (bracketRe.test(cleaned)) return name;
|
|
630
638
|
}
|
|
639
|
+
if (cleaned.includes("[")) {
|
|
640
|
+
const bracketContents = extractBracketContents(cleaned);
|
|
641
|
+
for (const content of bracketContents) {
|
|
642
|
+
if (!content.includes("+")) continue;
|
|
643
|
+
const fragments = content.match(/['"`]([^'"`]*?)['"`]/g);
|
|
644
|
+
if (!fragments) continue;
|
|
645
|
+
const joined = fragments.map((f) => f.slice(1, -1)).join("");
|
|
646
|
+
if (UNSAFE_METHOD_NAMES.has(joined)) return joined;
|
|
647
|
+
}
|
|
648
|
+
}
|
|
631
649
|
return null;
|
|
632
650
|
}
|
|
651
|
+
function extractBracketContents(expr) {
|
|
652
|
+
const results = [];
|
|
653
|
+
let depth = 0;
|
|
654
|
+
let start = -1;
|
|
655
|
+
for (let i = 0; i < expr.length; i++) {
|
|
656
|
+
if (expr[i] === "[") {
|
|
657
|
+
if (depth === 0) start = i + 1;
|
|
658
|
+
depth++;
|
|
659
|
+
} else if (expr[i] === "]") {
|
|
660
|
+
depth--;
|
|
661
|
+
if (depth === 0 && start >= 0) {
|
|
662
|
+
results.push(expr.slice(start, i));
|
|
663
|
+
start = -1;
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
return results;
|
|
668
|
+
}
|
|
633
669
|
var TEXT_BINDING_SYM = /* @__PURE__ */ Symbol.for("forma-text-binding-cache");
|
|
634
670
|
function toTextValue(value) {
|
|
635
671
|
if (value == null) return "";
|
|
@@ -965,7 +1001,7 @@ function compileTemplate(text) {
|
|
|
965
1001
|
dynamics,
|
|
966
1002
|
hasItemRef: dynamics.length > 0
|
|
967
1003
|
};
|
|
968
|
-
|
|
1004
|
+
cacheCompiledTemplate(text, result);
|
|
969
1005
|
return result;
|
|
970
1006
|
}
|
|
971
1007
|
var templateTexts = /* @__PURE__ */ new WeakMap();
|
|
@@ -1653,6 +1689,7 @@ function buildEvaluator(expr, scope) {
|
|
|
1653
1689
|
return key in scope.getters;
|
|
1654
1690
|
},
|
|
1655
1691
|
get(_, key) {
|
|
1692
|
+
if (UNSAFE_METHOD_NAMES.has(key)) return void 0;
|
|
1656
1693
|
const g = scope.getters[key];
|
|
1657
1694
|
return g ? g() : void 0;
|
|
1658
1695
|
}
|
|
@@ -1808,6 +1845,7 @@ function buildHandler(expr, scope) {
|
|
|
1808
1845
|
return key in scope.getters || key in scope.setters;
|
|
1809
1846
|
},
|
|
1810
1847
|
get(_, key) {
|
|
1848
|
+
if (UNSAFE_METHOD_NAMES.has(key)) return void 0;
|
|
1811
1849
|
const g = scope.getters[key];
|
|
1812
1850
|
return g ? g() : void 0;
|
|
1813
1851
|
},
|
|
@@ -1843,11 +1881,10 @@ function parseState(raw) {
|
|
|
1843
1881
|
try {
|
|
1844
1882
|
parsed = JSON.parse(raw);
|
|
1845
1883
|
} catch {
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
} catch {
|
|
1849
|
-
return {};
|
|
1884
|
+
if (_debug) {
|
|
1885
|
+
dbg("parseState: Invalid JSON in data-forma-state \u2014 use valid JSON with quoted keys. Got:", raw.slice(0, 200));
|
|
1850
1886
|
}
|
|
1887
|
+
return {};
|
|
1851
1888
|
}
|
|
1852
1889
|
for (const key of FORBIDDEN_STATE_KEYS) {
|
|
1853
1890
|
if (key in parsed) delete parsed[key];
|
|
@@ -1867,7 +1904,7 @@ function initScope(stateEl) {
|
|
|
1867
1904
|
const getters = {};
|
|
1868
1905
|
const setters = {};
|
|
1869
1906
|
for (const [key, initial] of Object.entries(state)) {
|
|
1870
|
-
const [get, set] =
|
|
1907
|
+
const [get, set] = createSignal(initial);
|
|
1871
1908
|
getters[key] = get;
|
|
1872
1909
|
setters[key] = set;
|
|
1873
1910
|
}
|
|
@@ -1875,6 +1912,18 @@ function initScope(stateEl) {
|
|
|
1875
1912
|
return { getters, setters };
|
|
1876
1913
|
}
|
|
1877
1914
|
function bindElement(el, scope, disposers) {
|
|
1915
|
+
const elMagics = {
|
|
1916
|
+
$el: el,
|
|
1917
|
+
$dispatch: (name, detail) => {
|
|
1918
|
+
el.dispatchEvent(new CustomEvent(name, {
|
|
1919
|
+
bubbles: true,
|
|
1920
|
+
composed: true,
|
|
1921
|
+
// crosses Shadow DOM boundaries (important for <forma-stage>)
|
|
1922
|
+
detail
|
|
1923
|
+
}));
|
|
1924
|
+
}
|
|
1925
|
+
};
|
|
1926
|
+
scope = createChildScope(scope, elMagics);
|
|
1878
1927
|
const known = getDirectives(el);
|
|
1879
1928
|
const computedAttr = !known || known.has("data-computed") ? el.getAttribute("data-computed") : null;
|
|
1880
1929
|
if (computedAttr) {
|
|
@@ -2254,16 +2303,16 @@ function bindElement(el, scope, disposers) {
|
|
|
2254
2303
|
else if (k === "error") errorTarget = v;
|
|
2255
2304
|
else if (k === "poll") interval = parseInt(v ?? "0", 10);
|
|
2256
2305
|
}
|
|
2257
|
-
const [getTarget, setTarget] =
|
|
2306
|
+
const [getTarget, setTarget] = createSignal(null);
|
|
2258
2307
|
scope.getters[target] = getTarget;
|
|
2259
2308
|
scope.setters[target] = setTarget;
|
|
2260
2309
|
if (loadingTarget) {
|
|
2261
|
-
const [gl, sl] =
|
|
2310
|
+
const [gl, sl] = createSignal(false);
|
|
2262
2311
|
scope.getters[loadingTarget] = gl;
|
|
2263
2312
|
scope.setters[loadingTarget] = sl;
|
|
2264
2313
|
}
|
|
2265
2314
|
if (errorTarget) {
|
|
2266
|
-
const [ge, se] =
|
|
2315
|
+
const [ge, se] = createSignal(null);
|
|
2267
2316
|
scope.getters[errorTarget] = ge;
|
|
2268
2317
|
scope.setters[errorTarget] = se;
|
|
2269
2318
|
}
|