praxis-kit 5.0.0 → 6.1.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-SKAY22CZ.js → chunk-VUULGK5M.js} +161 -72
- package/dist/contract/index.d.ts +27 -1
- package/dist/lit/index.d.ts +27 -1
- package/dist/lit/index.js +158 -76
- package/dist/preact/index.d.ts +27 -1
- package/dist/preact/index.js +147 -70
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +1 -1
- package/dist/react/legacy.d.ts +2 -2
- package/dist/react/legacy.js +1 -1
- package/dist/{react-options-D6rRB2gJ.d.ts → react-options-AitAOrje.d.ts} +27 -1
- package/dist/solid/index.d.ts +27 -1
- package/dist/solid/index.js +138 -67
- package/dist/svelte/Polymorphic.svelte +1 -1
- package/dist/svelte/index.d.ts +32 -2
- package/dist/svelte/index.js +134 -66
- package/dist/tailwind/index.d.ts +89 -54
- package/dist/tailwind/index.js +128 -66
- package/dist/vite-plugin/index.js +14 -2
- package/dist/vue/index.d.ts +27 -1
- package/dist/vue/index.js +136 -67
- package/dist/web/index.d.ts +27 -1
- package/dist/web/index.js +158 -81
- package/package.json +4 -4
|
@@ -420,6 +420,19 @@ function makeResolveTag(defaultTag) {
|
|
|
420
420
|
};
|
|
421
421
|
}
|
|
422
422
|
|
|
423
|
+
// ../../lib/primitive/src/rule/rule-brand.ts
|
|
424
|
+
var RULE_BRAND = /* @__PURE__ */ Symbol("praxis-kit/dynamic-rule");
|
|
425
|
+
|
|
426
|
+
// ../../lib/primitive/src/rule/is-dynamic-rule.ts
|
|
427
|
+
function isDynamicRule(rule) {
|
|
428
|
+
return isObject(rule, true) && rule[RULE_BRAND] === true;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// ../../lib/primitive/src/rule/resolve-rule.ts
|
|
432
|
+
function resolveRule(rule, context) {
|
|
433
|
+
return isDynamicRule(rule) ? rule.resolve(context) : rule;
|
|
434
|
+
}
|
|
435
|
+
|
|
423
436
|
// ../../lib/primitive/src/utils/assert-never.ts
|
|
424
437
|
function assertNever(value) {
|
|
425
438
|
throw new Error(`Unexpected value: ${String(value)}`);
|
|
@@ -601,6 +614,58 @@ var iterate = Object.freeze({
|
|
|
601
614
|
values
|
|
602
615
|
});
|
|
603
616
|
|
|
617
|
+
// ../../lib/primitive/src/utils/lazy.ts
|
|
618
|
+
function lazy(factory) {
|
|
619
|
+
let initialized = false;
|
|
620
|
+
let value;
|
|
621
|
+
return () => {
|
|
622
|
+
if (!initialized) {
|
|
623
|
+
value = factory();
|
|
624
|
+
initialized = true;
|
|
625
|
+
}
|
|
626
|
+
return value;
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
// ../../lib/primitive/src/utils/lru-cache.ts
|
|
631
|
+
var LRUCache = class {
|
|
632
|
+
#maxSize;
|
|
633
|
+
#store = /* @__PURE__ */ new Map();
|
|
634
|
+
constructor(maxSize) {
|
|
635
|
+
if (!Number.isInteger(maxSize) || maxSize < 1) {
|
|
636
|
+
throw new RangeError("LRUCache maxSize must be a positive integer.");
|
|
637
|
+
}
|
|
638
|
+
this.#maxSize = maxSize;
|
|
639
|
+
}
|
|
640
|
+
get(key) {
|
|
641
|
+
if (!this.#store.has(key)) return void 0;
|
|
642
|
+
const value = this.#store.get(key);
|
|
643
|
+
this.#store.delete(key);
|
|
644
|
+
this.#store.set(key, value);
|
|
645
|
+
return value;
|
|
646
|
+
}
|
|
647
|
+
set(key, value) {
|
|
648
|
+
this.#store.delete(key);
|
|
649
|
+
this.#store.set(key, value);
|
|
650
|
+
if (this.#store.size > this.#maxSize) {
|
|
651
|
+
const lru = this.#store.keys().next().value;
|
|
652
|
+
if (lru !== void 0) this.#store.delete(lru);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
has(key) {
|
|
656
|
+
return this.#store.has(key);
|
|
657
|
+
}
|
|
658
|
+
delete(key) {
|
|
659
|
+
return this.#store.delete(key);
|
|
660
|
+
}
|
|
661
|
+
get size() {
|
|
662
|
+
return this.#store.size;
|
|
663
|
+
}
|
|
664
|
+
clear() {
|
|
665
|
+
this.#store.clear();
|
|
666
|
+
}
|
|
667
|
+
};
|
|
668
|
+
|
|
604
669
|
// ../../lib/primitive/src/utils/merge-refs.ts
|
|
605
670
|
function mergeRefsCore(...refs) {
|
|
606
671
|
const active = refs.filter((r) => r != null);
|
|
@@ -662,28 +727,6 @@ function isTag(...args) {
|
|
|
662
727
|
return tag !== void 0 && set2.has(tag);
|
|
663
728
|
}
|
|
664
729
|
|
|
665
|
-
// ../../lib/contract/src/strict/invariant-base.ts
|
|
666
|
-
var InvariantBase = class {
|
|
667
|
-
diagnostics;
|
|
668
|
-
constructor(diagnostics) {
|
|
669
|
-
this.diagnostics = diagnostics;
|
|
670
|
-
}
|
|
671
|
-
get active() {
|
|
672
|
-
return this.diagnostics.active;
|
|
673
|
-
}
|
|
674
|
-
violate(input) {
|
|
675
|
-
this.diagnostics.error(input);
|
|
676
|
-
}
|
|
677
|
-
// Always caps at warn — never throws. ARIA 'warning' violations route here
|
|
678
|
-
// so they surface even in strict='throw' mode without aborting a render.
|
|
679
|
-
warn(input) {
|
|
680
|
-
this.diagnostics.warn(input);
|
|
681
|
-
}
|
|
682
|
-
invariant(condition, input) {
|
|
683
|
-
if (!condition) this.violate(input);
|
|
684
|
-
}
|
|
685
|
-
};
|
|
686
|
-
|
|
687
730
|
// ../../lib/contract/src/diagnostics/aria.ts
|
|
688
731
|
import { DiagnosticCategory, DiagnosticCode } from "./_shared/diagnostics.js";
|
|
689
732
|
var AriaDiagnostics = {
|
|
@@ -1040,6 +1083,28 @@ var SlotDiagnostics = {
|
|
|
1040
1083
|
}
|
|
1041
1084
|
};
|
|
1042
1085
|
|
|
1086
|
+
// ../../lib/contract/src/strict/invariant-base.ts
|
|
1087
|
+
var InvariantBase = class {
|
|
1088
|
+
diagnostics;
|
|
1089
|
+
constructor(diagnostics) {
|
|
1090
|
+
this.diagnostics = diagnostics;
|
|
1091
|
+
}
|
|
1092
|
+
get active() {
|
|
1093
|
+
return this.diagnostics.active;
|
|
1094
|
+
}
|
|
1095
|
+
violate(input) {
|
|
1096
|
+
this.diagnostics.error(input);
|
|
1097
|
+
}
|
|
1098
|
+
// Always caps at warn — never throws. ARIA 'warning' violations route here
|
|
1099
|
+
// so they surface even in strict='throw' mode without aborting a render.
|
|
1100
|
+
warn(input) {
|
|
1101
|
+
this.diagnostics.warn(input);
|
|
1102
|
+
}
|
|
1103
|
+
invariant(condition, input) {
|
|
1104
|
+
if (!condition) this.violate(input);
|
|
1105
|
+
}
|
|
1106
|
+
};
|
|
1107
|
+
|
|
1043
1108
|
// ../../lib/contract/src/aria/polymorphic-validator.ts
|
|
1044
1109
|
var VALID = [{ valid: true }];
|
|
1045
1110
|
function isIntrinsicTag(tag) {
|
|
@@ -1051,8 +1116,7 @@ function omitProp(obj, key) {
|
|
|
1051
1116
|
}
|
|
1052
1117
|
var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
1053
1118
|
#extraRules;
|
|
1054
|
-
#planCache =
|
|
1055
|
-
static #MAX_CACHE = 100;
|
|
1119
|
+
#planCache = new LRUCache(100);
|
|
1056
1120
|
// Memoized AriaFix objects keyed by attribute name — the ARIA attribute set is
|
|
1057
1121
|
// finite so this Map is bounded and avoids recreating closures on every cache miss.
|
|
1058
1122
|
static #removeAttributeFixCache = /* @__PURE__ */ new Map();
|
|
@@ -1208,8 +1272,6 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1208
1272
|
if (!isNull(key)) {
|
|
1209
1273
|
const cached = this.#planCache.get(key);
|
|
1210
1274
|
if (cached !== void 0) {
|
|
1211
|
-
this.#planCache.delete(key);
|
|
1212
|
-
this.#planCache.set(key, cached);
|
|
1213
1275
|
if (cached.violations.length > 0) this.report(cached.violations);
|
|
1214
1276
|
return {
|
|
1215
1277
|
props: _AriaPolicyEngine.#applyPlan(props, cached.removals, cached.updates),
|
|
@@ -1226,10 +1288,6 @@ var AriaPolicyEngine = class _AriaPolicyEngine extends InvariantBase {
|
|
|
1226
1288
|
);
|
|
1227
1289
|
const plan = { removals, updates, violations: result.violations };
|
|
1228
1290
|
this.#planCache.set(key, plan);
|
|
1229
|
-
if (this.#planCache.size > _AriaPolicyEngine.#MAX_CACHE) {
|
|
1230
|
-
const lru = this.#planCache.keys().next().value;
|
|
1231
|
-
if (lru !== void 0) this.#planCache.delete(lru);
|
|
1232
|
-
}
|
|
1233
1291
|
}
|
|
1234
1292
|
return result;
|
|
1235
1293
|
}
|
|
@@ -1885,10 +1943,22 @@ var RuleValidator = class _RuleValidator extends InvariantBase {
|
|
|
1885
1943
|
|
|
1886
1944
|
// ../../lib/contract/src/children/children-evaluator.ts
|
|
1887
1945
|
var isTextLike = (child) => isString(child) || isNumber(child);
|
|
1946
|
+
function checkPositionCardinalityInvariant(rules, context) {
|
|
1947
|
+
iterate.forEach(rules, (rule) => {
|
|
1948
|
+
const { name, position, cardinality } = rule;
|
|
1949
|
+
if ((position === "first" || position === "last") && (cardinality.kind === "unbounded" || cardinality.max > 1)) {
|
|
1950
|
+
throw new RangeError(
|
|
1951
|
+
`ChildrenEvaluator [${context}]: rule "${name}" sets position="${position}" with an unbound or >1 max. position="first|last" implies max=1.`
|
|
1952
|
+
);
|
|
1953
|
+
}
|
|
1954
|
+
});
|
|
1955
|
+
}
|
|
1888
1956
|
var ChildrenEvaluator = class extends InvariantBase {
|
|
1889
1957
|
#context;
|
|
1890
|
-
|
|
1891
|
-
#
|
|
1958
|
+
/** Rules with a static cardinality — normalized once, reused on every evaluate() call. */
|
|
1959
|
+
#staticRules;
|
|
1960
|
+
/** Rules whose cardinality is `dynamic(...)` — re-resolved against a ChildRuleContext per call. */
|
|
1961
|
+
#dynamicRuleInputs;
|
|
1892
1962
|
#matcher;
|
|
1893
1963
|
#ruleValidator;
|
|
1894
1964
|
#exclusiveChildren;
|
|
@@ -1896,29 +1966,39 @@ var ChildrenEvaluator = class extends InvariantBase {
|
|
|
1896
1966
|
constructor(rules, diagnostics, context = "Component", options = {}) {
|
|
1897
1967
|
super(diagnostics);
|
|
1898
1968
|
this.#context = context;
|
|
1899
|
-
this.#rules = rules.map((r) => normalizeChildRule(r));
|
|
1900
|
-
this.#ruleNames = this.#rules.map((r) => r.name);
|
|
1901
1969
|
this.#exclusiveChildren = options.exclusiveChildren ?? false;
|
|
1902
1970
|
this.#allowText = options.allowText ?? true;
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
);
|
|
1909
|
-
}
|
|
1971
|
+
const staticRuleInputs = [];
|
|
1972
|
+
const dynamicRuleInputs = [];
|
|
1973
|
+
iterate.forEach(rules, (rule) => {
|
|
1974
|
+
if (isDynamicRule(rule.cardinality)) dynamicRuleInputs.push(rule);
|
|
1975
|
+
else staticRuleInputs.push(rule);
|
|
1910
1976
|
});
|
|
1911
|
-
this.#
|
|
1977
|
+
this.#dynamicRuleInputs = dynamicRuleInputs;
|
|
1978
|
+
this.#staticRules = staticRuleInputs.map(
|
|
1979
|
+
(r) => normalizeChildRule(r)
|
|
1980
|
+
);
|
|
1912
1981
|
this.#ruleValidator = new RuleValidator(context, diagnostics);
|
|
1982
|
+
if (this.#dynamicRuleInputs.length === 0) {
|
|
1983
|
+
checkPositionCardinalityInvariant(this.#staticRules, context);
|
|
1984
|
+
this.#matcher = new RuleMatcher(this.#staticRules);
|
|
1985
|
+
} else {
|
|
1986
|
+
this.#matcher = void 0;
|
|
1987
|
+
}
|
|
1913
1988
|
}
|
|
1914
|
-
|
|
1989
|
+
/**
|
|
1990
|
+
* @param context Required when any rule has a `dynamic(...)` cardinality —
|
|
1991
|
+
* supplies the resolved tag/props those rules are evaluated against.
|
|
1992
|
+
*/
|
|
1993
|
+
evaluate(children, context) {
|
|
1915
1994
|
if (!this.active) return;
|
|
1995
|
+
const { rules, matcher } = this.#resolveRules(context);
|
|
1916
1996
|
const {
|
|
1917
1997
|
matrix,
|
|
1918
1998
|
unexpectedIndices: rawUnexpectedIndices,
|
|
1919
1999
|
ambiguousIndices
|
|
1920
|
-
} =
|
|
1921
|
-
this.#ruleValidator.validate(
|
|
2000
|
+
} = matcher.match(children);
|
|
2001
|
+
this.#ruleValidator.validate(rules, matrix, children.length);
|
|
1922
2002
|
const unexpectedIndices = new Set(
|
|
1923
2003
|
[...rawUnexpectedIndices].filter(
|
|
1924
2004
|
(ci) => isTextLike(children[ci]) ? this.#allowText === false : this.#exclusiveChildren
|
|
@@ -1932,11 +2012,28 @@ var ChildrenEvaluator = class extends InvariantBase {
|
|
|
1932
2012
|
this.violate(ContractDiagnostics.unexpectedChild(typeName, ci, this.#context));
|
|
1933
2013
|
} else {
|
|
1934
2014
|
const matches = matrix.childToRules.forward.get(ci);
|
|
1935
|
-
const names = [...matches].map((ri) =>
|
|
2015
|
+
const names = [...matches].map((ri) => rules[ri]?.name ?? `#${ri}`);
|
|
1936
2016
|
this.violate(ContractDiagnostics.ambiguousChild(typeName, ci, names, this.#context));
|
|
1937
2017
|
}
|
|
1938
2018
|
});
|
|
1939
2019
|
}
|
|
2020
|
+
#resolveRules(context) {
|
|
2021
|
+
if (this.#dynamicRuleInputs.length === 0) {
|
|
2022
|
+
return { rules: this.#staticRules, matcher: this.#matcher };
|
|
2023
|
+
}
|
|
2024
|
+
if (context === void 0) {
|
|
2025
|
+
throw new RangeError(
|
|
2026
|
+
`ChildrenEvaluator [${this.#context}]: rule(s) have a dynamic(...) cardinality \u2014 evaluate() requires a context argument to resolve them.`
|
|
2027
|
+
);
|
|
2028
|
+
}
|
|
2029
|
+
const resolvedDynamicRules = this.#dynamicRuleInputs.map((r) => {
|
|
2030
|
+
const cardinality = resolveRule(r.cardinality, context);
|
|
2031
|
+
return normalizeChildRule({ ...r, cardinality });
|
|
2032
|
+
});
|
|
2033
|
+
checkPositionCardinalityInvariant(resolvedDynamicRules, this.#context);
|
|
2034
|
+
const rules = [...this.#staticRules, ...resolvedDynamicRules];
|
|
2035
|
+
return { rules, matcher: new RuleMatcher(rules) };
|
|
2036
|
+
}
|
|
1940
2037
|
};
|
|
1941
2038
|
|
|
1942
2039
|
// ../../lib/contract/src/props/get-disabled-props.ts
|
|
@@ -2265,7 +2362,7 @@ function cva2(base, config) {
|
|
|
2265
2362
|
// ../../lib/styling/src/static-class-resolver.ts
|
|
2266
2363
|
var StaticClassResolver = class {
|
|
2267
2364
|
#baseClass;
|
|
2268
|
-
#cache =
|
|
2365
|
+
#cache = new LRUCache(200);
|
|
2269
2366
|
#resolveTag;
|
|
2270
2367
|
constructor(baseClass, tagMap) {
|
|
2271
2368
|
this.#baseClass = Array.isArray(baseClass) ? baseClass.join(" ") : baseClass;
|
|
@@ -2279,17 +2376,9 @@ var StaticClassResolver = class {
|
|
|
2279
2376
|
resolve(tag, skipTagMap = false) {
|
|
2280
2377
|
if (typeof tag !== "string" || skipTagMap) return this.#baseClass;
|
|
2281
2378
|
const cached = this.#cache.get(tag);
|
|
2282
|
-
if (cached !== void 0)
|
|
2283
|
-
this.#cache.delete(tag);
|
|
2284
|
-
this.#cache.set(tag, cached);
|
|
2285
|
-
return cached;
|
|
2286
|
-
}
|
|
2379
|
+
if (cached !== void 0) return cached;
|
|
2287
2380
|
const result = this.#resolveTag(tag);
|
|
2288
2381
|
this.#cache.set(tag, result);
|
|
2289
|
-
if (this.#cache.size > 200) {
|
|
2290
|
-
const lru = this.#cache.keys().next().value;
|
|
2291
|
-
if (lru !== void 0) this.#cache.delete(lru);
|
|
2292
|
-
}
|
|
2293
2382
|
return result;
|
|
2294
2383
|
}
|
|
2295
2384
|
};
|
|
@@ -2300,7 +2389,7 @@ var VariantClassResolver = class _VariantClassResolver {
|
|
|
2300
2389
|
#recipeMap;
|
|
2301
2390
|
#variantKeys;
|
|
2302
2391
|
#precomputedClasses;
|
|
2303
|
-
#cache =
|
|
2392
|
+
#cache = new LRUCache(1e3);
|
|
2304
2393
|
constructor(cvaFn, recipeMap, variantKeys, precomputedClasses) {
|
|
2305
2394
|
this.#cvaFn = cvaFn ?? null;
|
|
2306
2395
|
this.#recipeMap = Object.freeze(recipeMap ?? {});
|
|
@@ -2315,17 +2404,9 @@ var VariantClassResolver = class _VariantClassResolver {
|
|
|
2315
2404
|
if (precomputed !== void 0) return precomputed;
|
|
2316
2405
|
}
|
|
2317
2406
|
const cached = this.#cache.get(cacheKey);
|
|
2318
|
-
if (cached !== void 0)
|
|
2319
|
-
this.#cache.delete(cacheKey);
|
|
2320
|
-
this.#cache.set(cacheKey, cached);
|
|
2321
|
-
return cached;
|
|
2322
|
-
}
|
|
2407
|
+
if (cached !== void 0) return cached;
|
|
2323
2408
|
const result = this.#compute(props, recipe);
|
|
2324
2409
|
this.#cache.set(cacheKey, result);
|
|
2325
|
-
if (this.#cache.size > 1e3) {
|
|
2326
|
-
const lru = this.#cache.keys().next().value;
|
|
2327
|
-
if (lru !== void 0) this.#cache.delete(lru);
|
|
2328
|
-
}
|
|
2329
2410
|
return result;
|
|
2330
2411
|
}
|
|
2331
2412
|
#compute(props, recipe) {
|
|
@@ -2846,8 +2927,14 @@ function applyDisplayName(component, name) {
|
|
|
2846
2927
|
// ../../adapters/react/src/shared/render.ts
|
|
2847
2928
|
import { createElement as createElement2 } from "react";
|
|
2848
2929
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
2849
|
-
function buildRenderState(tag, directives, props, className, children) {
|
|
2850
|
-
const state = {
|
|
2930
|
+
function buildRenderState(tag, directives, props, normalizedProps, className, children) {
|
|
2931
|
+
const state = {
|
|
2932
|
+
tag,
|
|
2933
|
+
directives,
|
|
2934
|
+
props,
|
|
2935
|
+
normalizedProps,
|
|
2936
|
+
className
|
|
2937
|
+
};
|
|
2851
2938
|
if (children !== void 0) state.children = children;
|
|
2852
2939
|
return state;
|
|
2853
2940
|
}
|
|
@@ -2872,7 +2959,7 @@ function prepareRenderState(runtime, props, filterProps) {
|
|
|
2872
2959
|
...as !== void 0 && { as },
|
|
2873
2960
|
...asChild !== void 0 && { asChild }
|
|
2874
2961
|
};
|
|
2875
|
-
return buildRenderState(tag, directives, filteredProps, resolvedClass, children);
|
|
2962
|
+
return buildRenderState(tag, directives, filteredProps, normalizedProps, resolvedClass, children);
|
|
2876
2963
|
}
|
|
2877
2964
|
function warnDiscardedChildren(originalChildren, normalizedChildren, validator) {
|
|
2878
2965
|
if (!Array.isArray(originalChildren)) return;
|
|
@@ -2947,10 +3034,12 @@ function render({
|
|
|
2947
3034
|
childrenEvaluator
|
|
2948
3035
|
}) {
|
|
2949
3036
|
const state = prepareRenderState(runtime, props, filterProps);
|
|
2950
|
-
|
|
2951
|
-
const getNormalizedChildren = () => cached ??= normalizeChildren(state.children);
|
|
3037
|
+
const getNormalizedChildren = lazy(() => normalizeChildren(state.children));
|
|
2952
3038
|
if (process.env.NODE_ENV !== "production") {
|
|
2953
|
-
childrenEvaluator?.evaluate(getNormalizedChildren()
|
|
3039
|
+
childrenEvaluator?.evaluate(getNormalizedChildren(), {
|
|
3040
|
+
tag: state.tag,
|
|
3041
|
+
props: state.normalizedProps
|
|
3042
|
+
});
|
|
2954
3043
|
runtime.options.htmlChildrenEvaluatorFn?.(state.tag)?.evaluate(getNormalizedChildren());
|
|
2955
3044
|
}
|
|
2956
3045
|
if (typeof props.render === "function") {
|
package/dist/contract/index.d.ts
CHANGED
|
@@ -29,6 +29,26 @@ type MinMax = {
|
|
|
29
29
|
};
|
|
30
30
|
type CardinalityInput = Partial<MinMax>;
|
|
31
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Resolved per-instance state available to a dynamic (`dynamic(...)`) child
|
|
34
|
+
* rule field — the same tag/props every adapter already computes before
|
|
35
|
+
* evaluating children, exposed so a rule can vary by them (e.g. cardinality
|
|
36
|
+
* that depends on the resolved `as` tag).
|
|
37
|
+
*/
|
|
38
|
+
type ChildRuleContext = {
|
|
39
|
+
readonly tag: unknown;
|
|
40
|
+
readonly props: Readonly<AnyRecord>;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
declare const RULE_BRAND: unique symbol;
|
|
44
|
+
|
|
45
|
+
type DynamicRule<T, C = unknown> = {
|
|
46
|
+
readonly [RULE_BRAND]: true;
|
|
47
|
+
resolve(context: C): T;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
type Rule<T, C = unknown> = T | DynamicRule<T, C>;
|
|
51
|
+
|
|
32
52
|
type ChildRuleMatch<T, U extends T = T> = (child: T) => child is U;
|
|
33
53
|
|
|
34
54
|
type ChildRulePosition = 'first' | 'last' | 'any';
|
|
@@ -36,7 +56,13 @@ type ChildRulePosition = 'first' | 'last' | 'any';
|
|
|
36
56
|
type ChildRuleInput<T = unknown, U extends T = T> = {
|
|
37
57
|
name: string;
|
|
38
58
|
match: ChildRuleMatch<T, U>;
|
|
39
|
-
|
|
59
|
+
/**
|
|
60
|
+
* Either a static cardinality, or `dynamic((ctx) => ...)` to derive it from
|
|
61
|
+
* the resolved tag/props (e.g. a different max depending on `as`). `match`
|
|
62
|
+
* stays static-only — it's already a function, so a dynamic wrapper would
|
|
63
|
+
* be indistinguishable from the predicate itself without one.
|
|
64
|
+
*/
|
|
65
|
+
cardinality?: Rule<CardinalityInput, ChildRuleContext>;
|
|
40
66
|
position?: ChildRulePosition;
|
|
41
67
|
/**
|
|
42
68
|
* Optional component-type reference for O(1) dispatch index.
|
package/dist/lit/index.d.ts
CHANGED
|
@@ -30,6 +30,26 @@ type MinMax = {
|
|
|
30
30
|
};
|
|
31
31
|
type CardinalityInput = Partial<MinMax>;
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Resolved per-instance state available to a dynamic (`dynamic(...)`) child
|
|
35
|
+
* rule field — the same tag/props every adapter already computes before
|
|
36
|
+
* evaluating children, exposed so a rule can vary by them (e.g. cardinality
|
|
37
|
+
* that depends on the resolved `as` tag).
|
|
38
|
+
*/
|
|
39
|
+
type ChildRuleContext = {
|
|
40
|
+
readonly tag: unknown;
|
|
41
|
+
readonly props: Readonly<AnyRecord>;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
declare const RULE_BRAND: unique symbol;
|
|
45
|
+
|
|
46
|
+
type DynamicRule<T, C = unknown> = {
|
|
47
|
+
readonly [RULE_BRAND]: true;
|
|
48
|
+
resolve(context: C): T;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
type Rule<T, C = unknown> = T | DynamicRule<T, C>;
|
|
52
|
+
|
|
33
53
|
type ChildRuleMatch<T, U extends T = T> = (child: T) => child is U;
|
|
34
54
|
|
|
35
55
|
type ChildRulePosition = 'first' | 'last' | 'any';
|
|
@@ -37,7 +57,13 @@ type ChildRulePosition = 'first' | 'last' | 'any';
|
|
|
37
57
|
type ChildRuleInput<T = unknown, U extends T = T> = {
|
|
38
58
|
name: string;
|
|
39
59
|
match: ChildRuleMatch<T, U>;
|
|
40
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Either a static cardinality, or `dynamic((ctx) => ...)` to derive it from
|
|
62
|
+
* the resolved tag/props (e.g. a different max depending on `as`). `match`
|
|
63
|
+
* stays static-only — it's already a function, so a dynamic wrapper would
|
|
64
|
+
* be indistinguishable from the predicate itself without one.
|
|
65
|
+
*/
|
|
66
|
+
cardinality?: Rule<CardinalityInput, ChildRuleContext>;
|
|
41
67
|
position?: ChildRulePosition;
|
|
42
68
|
/**
|
|
43
69
|
* Optional component-type reference for O(1) dispatch index.
|