@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
|
@@ -19,7 +19,6 @@ function createSignal(initialValue) {
|
|
|
19
19
|
const setter = (v) => applySignalSet(s, v);
|
|
20
20
|
return [getter, setter];
|
|
21
21
|
}
|
|
22
|
-
var createValueSignal = createSignal;
|
|
23
22
|
function internalEffect(fn) {
|
|
24
23
|
const dispose = alienSignals.effect(fn);
|
|
25
24
|
return dispose;
|
|
@@ -852,12 +851,11 @@ var RE_TOGGLE = /^(\w+)\s*=\s*!(\w+)$/;
|
|
|
852
851
|
var RE_ASSIGN = /^(\w+)\s*=\s*(.+)$/;
|
|
853
852
|
var RE_COMPOUND = /^(\w+)\s*(\+=|-=|\*=|\/=)\s*(.+)$/;
|
|
854
853
|
var RE_IF_PREFIX = /^if\b/;
|
|
855
|
-
var RE_UNQUOTED_KEYS = /(\w+)\s*:/g;
|
|
856
854
|
var RE_COMPUTED = /^(\w+)\s*=\s*(.+)$/;
|
|
857
855
|
var RE_FETCH = /^(.+?)(?:→|->)\s*(\S+)(.*)$/;
|
|
858
856
|
var RE_FETCH_METHOD = /^(GET|POST|PUT|PATCH|DELETE)\s+(.+)$/i;
|
|
859
857
|
var RE_STRIP_ITEM_BRACES = /^\{item\.?|\}$/g;
|
|
860
|
-
var RE_EVENT_REF = /\bevent\
|
|
858
|
+
var RE_EVENT_REF = /\bevent\s*[.([]|\$event\b/;
|
|
861
859
|
var RE_REFETCH_CALL = /^\$refetch\(\s*['"]([^'"]+)['"]\s*\)$/;
|
|
862
860
|
var TRANSITION_STATE_SYM = /* @__PURE__ */ Symbol.for("forma-transition-state");
|
|
863
861
|
var EXPRESSION_CACHE_MAX = 2048;
|
|
@@ -872,6 +870,14 @@ function cacheExpression(key, factory) {
|
|
|
872
870
|
var scopeExpressionCache = /* @__PURE__ */ new WeakMap();
|
|
873
871
|
var scopeHandlerCache = /* @__PURE__ */ new WeakMap();
|
|
874
872
|
var compiledTemplateCache = /* @__PURE__ */ new Map();
|
|
873
|
+
var COMPILED_TEMPLATE_CACHE_MAX = 2048;
|
|
874
|
+
function cacheCompiledTemplate(key, template) {
|
|
875
|
+
if (compiledTemplateCache.size >= COMPILED_TEMPLATE_CACHE_MAX) {
|
|
876
|
+
const first = compiledTemplateCache.keys().next().value;
|
|
877
|
+
if (first !== void 0) compiledTemplateCache.delete(first);
|
|
878
|
+
}
|
|
879
|
+
compiledTemplateCache.set(key, template);
|
|
880
|
+
}
|
|
875
881
|
var UNSAFE_METHOD_NAMES = /* @__PURE__ */ new Set([
|
|
876
882
|
"constructor",
|
|
877
883
|
"__proto__",
|
|
@@ -880,7 +886,8 @@ var UNSAFE_METHOD_NAMES = /* @__PURE__ */ new Set([
|
|
|
880
886
|
"__defineSetter__",
|
|
881
887
|
"__lookupGetter__",
|
|
882
888
|
"__lookupSetter__",
|
|
883
|
-
"eval"
|
|
889
|
+
"eval",
|
|
890
|
+
"Function"
|
|
884
891
|
]);
|
|
885
892
|
var BLOCKED_METHOD_REGEXES = (() => {
|
|
886
893
|
const result = [];
|
|
@@ -904,8 +911,36 @@ function findBlockedMethod(expr) {
|
|
|
904
911
|
if (dotRe.test(cleaned)) return name;
|
|
905
912
|
if (bracketRe.test(cleaned)) return name;
|
|
906
913
|
}
|
|
914
|
+
if (cleaned.includes("[")) {
|
|
915
|
+
const bracketContents = extractBracketContents(cleaned);
|
|
916
|
+
for (const content of bracketContents) {
|
|
917
|
+
if (!content.includes("+")) continue;
|
|
918
|
+
const fragments = content.match(/['"`]([^'"`]*?)['"`]/g);
|
|
919
|
+
if (!fragments) continue;
|
|
920
|
+
const joined = fragments.map((f) => f.slice(1, -1)).join("");
|
|
921
|
+
if (UNSAFE_METHOD_NAMES.has(joined)) return joined;
|
|
922
|
+
}
|
|
923
|
+
}
|
|
907
924
|
return null;
|
|
908
925
|
}
|
|
926
|
+
function extractBracketContents(expr) {
|
|
927
|
+
const results = [];
|
|
928
|
+
let depth = 0;
|
|
929
|
+
let start = -1;
|
|
930
|
+
for (let i = 0; i < expr.length; i++) {
|
|
931
|
+
if (expr[i] === "[") {
|
|
932
|
+
if (depth === 0) start = i + 1;
|
|
933
|
+
depth++;
|
|
934
|
+
} else if (expr[i] === "]") {
|
|
935
|
+
depth--;
|
|
936
|
+
if (depth === 0 && start >= 0) {
|
|
937
|
+
results.push(expr.slice(start, i));
|
|
938
|
+
start = -1;
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
return results;
|
|
943
|
+
}
|
|
909
944
|
var TEXT_BINDING_SYM = /* @__PURE__ */ Symbol.for("forma-text-binding-cache");
|
|
910
945
|
function toTextValue(value2) {
|
|
911
946
|
if (value2 == null) return "";
|
|
@@ -1241,7 +1276,7 @@ function compileTemplate(text) {
|
|
|
1241
1276
|
dynamics,
|
|
1242
1277
|
hasItemRef: dynamics.length > 0
|
|
1243
1278
|
};
|
|
1244
|
-
|
|
1279
|
+
cacheCompiledTemplate(text, result);
|
|
1245
1280
|
return result;
|
|
1246
1281
|
}
|
|
1247
1282
|
var templateTexts = /* @__PURE__ */ new WeakMap();
|
|
@@ -1929,6 +1964,7 @@ function buildEvaluator(expr, scope) {
|
|
|
1929
1964
|
return key in scope.getters;
|
|
1930
1965
|
},
|
|
1931
1966
|
get(_, key) {
|
|
1967
|
+
if (UNSAFE_METHOD_NAMES.has(key)) return void 0;
|
|
1932
1968
|
const g = scope.getters[key];
|
|
1933
1969
|
return g ? g() : void 0;
|
|
1934
1970
|
}
|
|
@@ -2084,6 +2120,7 @@ function buildHandler(expr, scope) {
|
|
|
2084
2120
|
return key in scope.getters || key in scope.setters;
|
|
2085
2121
|
},
|
|
2086
2122
|
get(_, key) {
|
|
2123
|
+
if (UNSAFE_METHOD_NAMES.has(key)) return void 0;
|
|
2087
2124
|
const g = scope.getters[key];
|
|
2088
2125
|
return g ? g() : void 0;
|
|
2089
2126
|
},
|
|
@@ -2119,11 +2156,10 @@ function parseState(raw) {
|
|
|
2119
2156
|
try {
|
|
2120
2157
|
parsed = JSON.parse(raw);
|
|
2121
2158
|
} catch {
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
} catch {
|
|
2125
|
-
return {};
|
|
2159
|
+
if (_debug) {
|
|
2160
|
+
dbg("parseState: Invalid JSON in data-forma-state \u2014 use valid JSON with quoted keys. Got:", raw.slice(0, 200));
|
|
2126
2161
|
}
|
|
2162
|
+
return {};
|
|
2127
2163
|
}
|
|
2128
2164
|
for (const key of FORBIDDEN_STATE_KEYS) {
|
|
2129
2165
|
if (key in parsed) delete parsed[key];
|
|
@@ -2143,7 +2179,7 @@ function initScope(stateEl) {
|
|
|
2143
2179
|
const getters = {};
|
|
2144
2180
|
const setters = {};
|
|
2145
2181
|
for (const [key, initial] of Object.entries(state)) {
|
|
2146
|
-
const [get, set] =
|
|
2182
|
+
const [get, set] = createSignal(initial);
|
|
2147
2183
|
getters[key] = get;
|
|
2148
2184
|
setters[key] = set;
|
|
2149
2185
|
}
|
|
@@ -2151,6 +2187,18 @@ function initScope(stateEl) {
|
|
|
2151
2187
|
return { getters, setters };
|
|
2152
2188
|
}
|
|
2153
2189
|
function bindElement(el, scope, disposers) {
|
|
2190
|
+
const elMagics = {
|
|
2191
|
+
$el: el,
|
|
2192
|
+
$dispatch: (name, detail) => {
|
|
2193
|
+
el.dispatchEvent(new CustomEvent(name, {
|
|
2194
|
+
bubbles: true,
|
|
2195
|
+
composed: true,
|
|
2196
|
+
// crosses Shadow DOM boundaries (important for <forma-stage>)
|
|
2197
|
+
detail
|
|
2198
|
+
}));
|
|
2199
|
+
}
|
|
2200
|
+
};
|
|
2201
|
+
scope = createChildScope(scope, elMagics);
|
|
2154
2202
|
const known = getDirectives(el);
|
|
2155
2203
|
const computedAttr = !known || known.has("data-computed") ? el.getAttribute("data-computed") : null;
|
|
2156
2204
|
if (computedAttr) {
|
|
@@ -2530,16 +2578,16 @@ function bindElement(el, scope, disposers) {
|
|
|
2530
2578
|
else if (k === "error") errorTarget = v;
|
|
2531
2579
|
else if (k === "poll") interval = parseInt(v ?? "0", 10);
|
|
2532
2580
|
}
|
|
2533
|
-
const [getTarget, setTarget] =
|
|
2581
|
+
const [getTarget, setTarget] = createSignal(null);
|
|
2534
2582
|
scope.getters[target] = getTarget;
|
|
2535
2583
|
scope.setters[target] = setTarget;
|
|
2536
2584
|
if (loadingTarget) {
|
|
2537
|
-
const [gl, sl] =
|
|
2585
|
+
const [gl, sl] = createSignal(false);
|
|
2538
2586
|
scope.getters[loadingTarget] = gl;
|
|
2539
2587
|
scope.setters[loadingTarget] = sl;
|
|
2540
2588
|
}
|
|
2541
2589
|
if (errorTarget) {
|
|
2542
|
-
const [ge, se] =
|
|
2590
|
+
const [ge, se] = createSignal(null);
|
|
2543
2591
|
scope.getters[errorTarget] = ge;
|
|
2544
2592
|
scope.setters[errorTarget] = se;
|
|
2545
2593
|
}
|