@unrulysystems/native-motion-core 0.1.0-alpha.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/CHANGELOG.md +9 -0
- package/LICENSE +21 -0
- package/README.md +48 -0
- package/dist/clock.cjs +71 -0
- package/dist/clock.d.cts +23 -0
- package/dist/clock.d.ts +23 -0
- package/dist/clock.js +66 -0
- package/dist/collect-reads.cjs +68 -0
- package/dist/collect-reads.d.cts +23 -0
- package/dist/collect-reads.d.ts +23 -0
- package/dist/collect-reads.js +62 -0
- package/dist/component/boundedArray.cjs +74 -0
- package/dist/component/boundedArray.d.cts +25 -0
- package/dist/component/boundedArray.d.ts +25 -0
- package/dist/component/boundedArray.js +68 -0
- package/dist/component/index.cjs +57 -0
- package/dist/component/index.d.cts +12 -0
- package/dist/component/index.d.ts +12 -0
- package/dist/component/index.js +22 -0
- package/dist/component/orchestration.cjs +129 -0
- package/dist/component/orchestration.d.cts +66 -0
- package/dist/component/orchestration.d.ts +66 -0
- package/dist/component/orchestration.js +124 -0
- package/dist/component/resolve.cjs +104 -0
- package/dist/component/resolve.d.cts +11 -0
- package/dist/component/resolve.d.ts +11 -0
- package/dist/component/resolve.js +97 -0
- package/dist/component/transition.cjs +352 -0
- package/dist/component/transition.d.cts +33 -0
- package/dist/component/transition.d.ts +33 -0
- package/dist/component/transition.js +339 -0
- package/dist/component/types.cjs +114 -0
- package/dist/component/types.d.cts +60 -0
- package/dist/component/types.d.ts +60 -0
- package/dist/component/types.js +111 -0
- package/dist/component/validate.cjs +1015 -0
- package/dist/component/validate.d.cts +37 -0
- package/dist/component/validate.d.ts +37 -0
- package/dist/component/validate.js +1002 -0
- package/dist/component/variants.cjs +333 -0
- package/dist/component/variants.d.cts +106 -0
- package/dist/component/variants.d.ts +106 -0
- package/dist/component/variants.js +321 -0
- package/dist/config/constants.cjs +41 -0
- package/dist/config/constants.d.cts +29 -0
- package/dist/config/constants.d.ts +29 -0
- package/dist/config/constants.js +38 -0
- package/dist/delay.cjs +72 -0
- package/dist/delay.d.cts +26 -0
- package/dist/delay.d.ts +26 -0
- package/dist/delay.js +70 -0
- package/dist/derived.cjs +143 -0
- package/dist/derived.d.cts +41 -0
- package/dist/derived.d.ts +41 -0
- package/dist/derived.js +139 -0
- package/dist/driver/index.cjs +22 -0
- package/dist/driver/index.d.cts +7 -0
- package/dist/driver/index.d.ts +7 -0
- package/dist/driver/index.js +14 -0
- package/dist/driver/keyframeTiming.cjs +130 -0
- package/dist/driver/keyframeTiming.d.cts +18 -0
- package/dist/driver/keyframeTiming.d.ts +18 -0
- package/dist/driver/keyframeTiming.js +124 -0
- package/dist/driver/keyframeTimingConfig.cjs +24 -0
- package/dist/driver/keyframeTimingConfig.d.cts +5 -0
- package/dist/driver/keyframeTimingConfig.d.ts +5 -0
- package/dist/driver/keyframeTimingConfig.js +22 -0
- package/dist/driver/prepare.cjs +459 -0
- package/dist/driver/prepare.d.cts +4 -0
- package/dist/driver/prepare.d.ts +4 -0
- package/dist/driver/prepare.js +454 -0
- package/dist/driver/reference.cjs +762 -0
- package/dist/driver/reference.d.cts +53 -0
- package/dist/driver/reference.d.ts +53 -0
- package/dist/driver/reference.js +757 -0
- package/dist/driver/step.cjs +55 -0
- package/dist/driver/step.d.cts +9 -0
- package/dist/driver/step.d.ts +9 -0
- package/dist/driver/step.js +52 -0
- package/dist/driver/tiers.cjs +40 -0
- package/dist/driver/tiers.d.cts +2 -0
- package/dist/driver/tiers.d.ts +2 -0
- package/dist/driver/tiers.js +37 -0
- package/dist/driver/types.cjs +9 -0
- package/dist/driver/types.d.cts +68 -0
- package/dist/driver/types.d.ts +68 -0
- package/dist/driver/types.js +8 -0
- package/dist/external-animation-ledger.cjs +1250 -0
- package/dist/external-animation-ledger.d.cts +416 -0
- package/dist/external-animation-ledger.d.ts +416 -0
- package/dist/external-animation-ledger.js +1243 -0
- package/dist/gesture/directionLock.cjs +25 -0
- package/dist/gesture/directionLock.d.cts +8 -0
- package/dist/gesture/directionLock.d.ts +8 -0
- package/dist/gesture/directionLock.js +21 -0
- package/dist/gesture/dragConfig.cjs +634 -0
- package/dist/gesture/dragConfig.d.cts +298 -0
- package/dist/gesture/dragConfig.d.ts +298 -0
- package/dist/gesture/dragConfig.js +624 -0
- package/dist/gesture/elastic.cjs +44 -0
- package/dist/gesture/elastic.d.cts +4 -0
- package/dist/gesture/elastic.d.ts +4 -0
- package/dist/gesture/elastic.js +39 -0
- package/dist/gesture/handoffSession.cjs +161 -0
- package/dist/gesture/handoffSession.d.cts +35 -0
- package/dist/gesture/handoffSession.d.ts +35 -0
- package/dist/gesture/handoffSession.js +158 -0
- package/dist/gesture/index.cjs +37 -0
- package/dist/gesture/index.d.cts +12 -0
- package/dist/gesture/index.d.ts +12 -0
- package/dist/gesture/index.js +11 -0
- package/dist/gesture/projection.cjs +95 -0
- package/dist/gesture/projection.d.cts +7 -0
- package/dist/gesture/projection.d.ts +7 -0
- package/dist/gesture/projection.js +87 -0
- package/dist/gesture/session.cjs +162 -0
- package/dist/gesture/session.d.cts +29 -0
- package/dist/gesture/session.d.ts +29 -0
- package/dist/gesture/session.js +158 -0
- package/dist/gesture/types.cjs +5 -0
- package/dist/gesture/types.d.cts +13 -0
- package/dist/gesture/types.d.ts +13 -0
- package/dist/gesture/types.js +4 -0
- package/dist/gesture/viewportConstraints.cjs +38 -0
- package/dist/gesture/viewportConstraints.d.cts +6 -0
- package/dist/gesture/viewportConstraints.d.ts +6 -0
- package/dist/gesture/viewportConstraints.js +34 -0
- package/dist/graph.cjs +226 -0
- package/dist/graph.d.cts +2 -0
- package/dist/graph.d.ts +2 -0
- package/dist/graph.js +223 -0
- package/dist/index.cjs +140 -0
- package/dist/index.d.cts +33 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +70 -0
- package/dist/inertia.cjs +214 -0
- package/dist/inertia.d.cts +53 -0
- package/dist/inertia.d.ts +53 -0
- package/dist/inertia.js +212 -0
- package/dist/instant.cjs +66 -0
- package/dist/instant.d.cts +16 -0
- package/dist/instant.d.ts +16 -0
- package/dist/instant.js +63 -0
- package/dist/internal-driver.cjs +81 -0
- package/dist/internal-driver.d.cts +19 -0
- package/dist/internal-driver.d.ts +19 -0
- package/dist/internal-driver.js +35 -0
- package/dist/keyframes.cjs +191 -0
- package/dist/keyframes.d.cts +13 -0
- package/dist/keyframes.d.ts +13 -0
- package/dist/keyframes.js +188 -0
- package/dist/layout/commitDetector.cjs +67 -0
- package/dist/layout/commitDetector.d.cts +21 -0
- package/dist/layout/commitDetector.d.ts +21 -0
- package/dist/layout/commitDetector.js +64 -0
- package/dist/layout/compose.cjs +67 -0
- package/dist/layout/compose.d.cts +30 -0
- package/dist/layout/compose.d.ts +30 -0
- package/dist/layout/compose.js +65 -0
- package/dist/layout/constants.cjs +13 -0
- package/dist/layout/constants.d.cts +6 -0
- package/dist/layout/constants.d.ts +6 -0
- package/dist/layout/constants.js +10 -0
- package/dist/layout/identity.cjs +700 -0
- package/dist/layout/identity.d.cts +67 -0
- package/dist/layout/identity.d.ts +67 -0
- package/dist/layout/identity.js +698 -0
- package/dist/layout/index.cjs +36 -0
- package/dist/layout/index.d.cts +18 -0
- package/dist/layout/index.d.ts +18 -0
- package/dist/layout/index.js +13 -0
- package/dist/layout/measure.cjs +81 -0
- package/dist/layout/measure.d.cts +43 -0
- package/dist/layout/measure.d.ts +43 -0
- package/dist/layout/measure.js +78 -0
- package/dist/layout/projection.cjs +99 -0
- package/dist/layout/projection.d.cts +23 -0
- package/dist/layout/projection.d.ts +23 -0
- package/dist/layout/projection.js +97 -0
- package/dist/layout/scroll.cjs +27 -0
- package/dist/layout/scroll.d.cts +13 -0
- package/dist/layout/scroll.d.ts +13 -0
- package/dist/layout/scroll.js +24 -0
- package/dist/layout/session.cjs +207 -0
- package/dist/layout/session.d.cts +73 -0
- package/dist/layout/session.d.ts +73 -0
- package/dist/layout/session.js +205 -0
- package/dist/layout/tree.cjs +826 -0
- package/dist/layout/tree.d.cts +70 -0
- package/dist/layout/tree.d.ts +70 -0
- package/dist/layout/tree.js +823 -0
- package/dist/layout/types.cjs +36 -0
- package/dist/layout/types.d.cts +31 -0
- package/dist/layout/types.d.ts +31 -0
- package/dist/layout/types.js +35 -0
- package/dist/motion-arc.cjs +184 -0
- package/dist/motion-arc.d.cts +78 -0
- package/dist/motion-arc.d.ts +78 -0
- package/dist/motion-arc.js +183 -0
- package/dist/motion-mix.cjs +205 -0
- package/dist/motion-mix.d.cts +3 -0
- package/dist/motion-mix.d.ts +3 -0
- package/dist/motion-mix.js +202 -0
- package/dist/motion-value-driver-port.cjs +636 -0
- package/dist/motion-value-driver-port.d.cts +406 -0
- package/dist/motion-value-driver-port.d.ts +406 -0
- package/dist/motion-value-driver-port.js +627 -0
- package/dist/motion-value.cjs +189 -0
- package/dist/motion-value.d.cts +51 -0
- package/dist/motion-value.d.ts +51 -0
- package/dist/motion-value.js +185 -0
- package/dist/presence/controller.cjs +657 -0
- package/dist/presence/controller.d.cts +6 -0
- package/dist/presence/controller.d.ts +6 -0
- package/dist/presence/controller.js +652 -0
- package/dist/presence/index.cjs +19 -0
- package/dist/presence/index.d.cts +4 -0
- package/dist/presence/index.d.ts +4 -0
- package/dist/presence/index.js +12 -0
- package/dist/presence/machine.cjs +50 -0
- package/dist/presence/machine.d.cts +10 -0
- package/dist/presence/machine.d.ts +10 -0
- package/dist/presence/machine.js +46 -0
- package/dist/presence/types.cjs +6 -0
- package/dist/presence/types.d.cts +32 -0
- package/dist/presence/types.d.ts +32 -0
- package/dist/presence/types.js +5 -0
- package/dist/repeat.cjs +311 -0
- package/dist/repeat.d.cts +174 -0
- package/dist/repeat.d.ts +174 -0
- package/dist/repeat.js +300 -0
- package/dist/spring.cjs +128 -0
- package/dist/spring.d.cts +18 -0
- package/dist/spring.d.ts +18 -0
- package/dist/spring.js +125 -0
- package/dist/subscriptions.cjs +74 -0
- package/dist/subscriptions.d.cts +19 -0
- package/dist/subscriptions.d.ts +19 -0
- package/dist/subscriptions.js +69 -0
- package/dist/subset/index.cjs +23 -0
- package/dist/subset/index.d.cts +6 -0
- package/dist/subset/index.d.ts +6 -0
- package/dist/subset/index.js +13 -0
- package/dist/subset/normalize.cjs +90 -0
- package/dist/subset/normalize.d.cts +10 -0
- package/dist/subset/normalize.d.ts +10 -0
- package/dist/subset/normalize.js +85 -0
- package/dist/subset/registry.cjs +259 -0
- package/dist/subset/registry.d.cts +25 -0
- package/dist/subset/registry.d.ts +25 -0
- package/dist/subset/registry.js +256 -0
- package/dist/subset/resolve.cjs +98 -0
- package/dist/subset/resolve.d.cts +24 -0
- package/dist/subset/resolve.d.ts +24 -0
- package/dist/subset/resolve.js +90 -0
- package/dist/timing.cjs +206 -0
- package/dist/timing.d.cts +17 -0
- package/dist/timing.d.ts +17 -0
- package/dist/timing.js +201 -0
- package/dist/transformTemplate.cjs +219 -0
- package/dist/transformTemplate.d.cts +29 -0
- package/dist/transformTemplate.d.ts +29 -0
- package/dist/transformTemplate.js +215 -0
- package/dist/transition.cjs +231 -0
- package/dist/transition.d.cts +89 -0
- package/dist/transition.d.ts +89 -0
- package/dist/transition.js +223 -0
- package/dist/types.cjs +4 -0
- package/dist/types.d.cts +175 -0
- package/dist/types.d.ts +175 -0
- package/dist/types.js +3 -0
- package/dist/value-types/color.cjs +220 -0
- package/dist/value-types/color.d.cts +19 -0
- package/dist/value-types/color.d.ts +19 -0
- package/dist/value-types/color.js +218 -0
- package/dist/value-types/complex.cjs +160 -0
- package/dist/value-types/complex.d.cts +19 -0
- package/dist/value-types/complex.d.ts +19 -0
- package/dist/value-types/complex.js +155 -0
- package/dist/value-types/constants.cjs +15 -0
- package/dist/value-types/constants.d.cts +6 -0
- package/dist/value-types/constants.d.ts +6 -0
- package/dist/value-types/constants.js +12 -0
- package/dist/value-types/discrete.cjs +62 -0
- package/dist/value-types/discrete.d.cts +4 -0
- package/dist/value-types/discrete.d.ts +4 -0
- package/dist/value-types/discrete.js +56 -0
- package/dist/value-types/index.cjs +59 -0
- package/dist/value-types/index.d.cts +14 -0
- package/dist/value-types/index.d.ts +14 -0
- package/dist/value-types/index.js +24 -0
- package/dist/value-types/measure-resolve.cjs +325 -0
- package/dist/value-types/measure-resolve.d.cts +91 -0
- package/dist/value-types/measure-resolve.d.ts +91 -0
- package/dist/value-types/measure-resolve.js +313 -0
- package/dist/value-types/mix.cjs +90 -0
- package/dist/value-types/mix.d.cts +27 -0
- package/dist/value-types/mix.d.ts +27 -0
- package/dist/value-types/mix.js +85 -0
- package/dist/value-types/named-colors.cjs +61 -0
- package/dist/value-types/named-colors.d.cts +2 -0
- package/dist/value-types/named-colors.d.ts +2 -0
- package/dist/value-types/named-colors.js +58 -0
- package/dist/value-types/numeric.cjs +86 -0
- package/dist/value-types/numeric.d.cts +16 -0
- package/dist/value-types/numeric.d.ts +16 -0
- package/dist/value-types/numeric.js +79 -0
- package/dist/worklet-layout/config/constants.js +39 -0
- package/dist/worklet-layout/layout/constants.js +11 -0
- package/dist/worklet-layout/layout/identity.js +699 -0
- package/dist/worklet-layout/layout/projection.js +98 -0
- package/dist/worklet-layout/layout/session.js +206 -0
- package/dist/worklet-layout/layout/tree.js +824 -0
- package/dist/worklet-layout/layout/types.js +36 -0
- package/dist/worklet-layout/spring.js +125 -0
- package/dist/worklet-layout/timing.js +201 -0
- package/dist/worklet-layout/transition.js +223 -0
- package/dist/worklet-layout.cjs +47 -0
- package/dist/worklet-layout.d.cts +15 -0
- package/dist/worklet-layout.d.ts +15 -0
- package/dist/worklet-layout.js +28 -0
- package/dist/wrap.cjs +7 -0
- package/dist/wrap.d.cts +1 -0
- package/dist/wrap.d.ts +1 -0
- package/dist/wrap.js +4 -0
- package/package.json +45 -0
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// SPEC-COMPONENT §2 — REQ-API-032: the variants resolution core (R7). Pure, host-agnostic,
|
|
3
|
+
// deterministic over (definition, dictionary, live state) — the pinned `resolveVariantFromProps`
|
|
4
|
+
// chain including its runtime-only direct function form. Law (a): a local dictionary miss is the pinned
|
|
5
|
+
// NO-OP (the propagation-source shape), never an error. Law (b): animation-time arrays
|
|
6
|
+
// resolve to ORDERED per-label applications, each preserving its own embedded transition.
|
|
7
|
+
// Law (c): initial labels overlay synchronously into one first-paint state, transitions
|
|
8
|
+
// discarded. Law (f): the eager shape + entry validation — outer shapes typed as a unit,
|
|
9
|
+
// per-entry validation through the SAME target/transition boundaries the animate lane
|
|
10
|
+
// rides. The FUNCTION form (T24 B2, dynamic variants) is accepted at the boundary by
|
|
11
|
+
// identity and validated at RESOLUTION, where its result exists.
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.InvalidVariantError = void 0;
|
|
14
|
+
exports.variantsShapeRefusal = variantsShapeRefusal;
|
|
15
|
+
exports.assertVariantsShape = assertVariantsShape;
|
|
16
|
+
exports.validateVariantEntry = validateVariantEntry;
|
|
17
|
+
exports.validateVariantEntrySnapshot = validateVariantEntrySnapshot;
|
|
18
|
+
exports.resolveVariantDefinition = resolveVariantDefinition;
|
|
19
|
+
exports.resolveVariantDefinitionResult = resolveVariantDefinitionResult;
|
|
20
|
+
exports.flattenVariantApplications = flattenVariantApplications;
|
|
21
|
+
exports.resolveInitialOverlay = resolveInitialOverlay;
|
|
22
|
+
const validate_1 = require("./validate.cjs");
|
|
23
|
+
const keyframeTiming_1 = require("../driver/keyframeTiming.cjs");
|
|
24
|
+
const prepare_1 = require("../driver/prepare.cjs");
|
|
25
|
+
const boundedArray_1 = require("./boundedArray.cjs");
|
|
26
|
+
const transition_1 = require("./transition.cjs");
|
|
27
|
+
// Thrown for malformed variants SHAPES (REQ-API-014's structured pattern): the key names the
|
|
28
|
+
// offending unit ('(variants)' for the outer shape, the label for an entry).
|
|
29
|
+
class InvalidVariantError extends Error {
|
|
30
|
+
key;
|
|
31
|
+
value;
|
|
32
|
+
constructor(key, value, reason, cause) {
|
|
33
|
+
super(`invalid variants ${key === '(variants)' ? 'prop' : `entry '${key}'`} — ${reason}`, cause !== undefined ? { cause } : undefined);
|
|
34
|
+
this.name = 'InvalidVariantError';
|
|
35
|
+
this.key = key;
|
|
36
|
+
this.value = value;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
exports.InvalidVariantError = InvalidVariantError;
|
|
40
|
+
function isPlainObject(value) {
|
|
41
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value))
|
|
42
|
+
return false;
|
|
43
|
+
const proto = Object.getPrototypeOf(value);
|
|
44
|
+
return proto === Object.prototype || proto === null;
|
|
45
|
+
}
|
|
46
|
+
// Hostile-input architecture (M3 r3 majors 1b53e9337aec/13af48a64530): severity gates never
|
|
47
|
+
// CATCH around code that can run foreign traps/getters — any durable "ownership" mark on an
|
|
48
|
+
// error object is forgeable or replayable, and trusting exported classes launders authentic
|
|
49
|
+
// sentinels. Instead every boundary primitive is RETURN-shaped with PHASE-SEPARATED reads:
|
|
50
|
+
// foreign code (prototype probes, getters, enumeration traps) runs UNGUARDED first — its
|
|
51
|
+
// faults propagate untouched by construction — and validation then operates on plain
|
|
52
|
+
// snapshots, so a returned refusal is boundary-made by construction and nothing else is
|
|
53
|
+
// ever classified.
|
|
54
|
+
/**
|
|
55
|
+
* Law (f), outer shape, RETURN-shaped: the typed refusal, or null when `variants` is a
|
|
56
|
+
* plain object. The probe itself may throw on hostile values (a getPrototypeOf trap, a
|
|
57
|
+
* revoked proxy) — those faults propagate untouched; only the RETURNED refusal is input
|
|
58
|
+
* refusal.
|
|
59
|
+
*/
|
|
60
|
+
function variantsShapeRefusal(value) {
|
|
61
|
+
if (isPlainObject(value))
|
|
62
|
+
return null;
|
|
63
|
+
return new InvalidVariantError('(variants)', value, 'the dictionary must be a plain object of label → target entries (REQ-API-032 law f; ' +
|
|
64
|
+
'a malformed shape fails loud, never coerces to the empty dictionary)');
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Law (f), outer shape: `variants` must be a plain object — null, arrays, and
|
|
68
|
+
* prototype-carrying objects refuse AS A UNIT (typed), never coerce to an empty dictionary.
|
|
69
|
+
*/
|
|
70
|
+
function assertVariantsShape(value) {
|
|
71
|
+
const refusal = variantsShapeRefusal(value);
|
|
72
|
+
if (refusal !== null)
|
|
73
|
+
throw refusal;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Law (f), per entry: an entry must be a plain object whose members validate through the
|
|
77
|
+
* SAME boundaries the animate lane rides — core validateTarget for the target members and
|
|
78
|
+
* the REQ-API-031 transition law for the embedded transition — or a RESOLVER (T24 B2),
|
|
79
|
+
* accepted uninvoked and validated at resolution.
|
|
80
|
+
*/
|
|
81
|
+
function validateVariantEntry(label, entry, host, opts) {
|
|
82
|
+
const { refusal } = validateVariantEntrySnapshot(label, entry, host, opts);
|
|
83
|
+
if (refusal !== null)
|
|
84
|
+
throw refusal;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Law (f), per entry, RETURN-shaped + SNAPSHOT-accepting (M3 r3 majors 13af48a64530 +
|
|
88
|
+
* 5cb2381e272c; hardened r4 majors 4db96de50131 + 93bab4ecf757): the READ phase runs first
|
|
89
|
+
* and UNGUARDED — the entry's getters and every level of a transition's enumeration traps
|
|
90
|
+
* fire here, so their faults (including authentic same-class sentinels) propagate
|
|
91
|
+
* untouched. Validation then runs on DEEP-plain snapshots, and the SNAPSHOT is what the
|
|
92
|
+
* caller accepts: a stateful proxy cannot show the validators one value and the engine
|
|
93
|
+
* another (one read, one truth). Residual bound, stated honestly: hostile LEAF objects
|
|
94
|
+
* (non-array, non-plain) stay by reference and are refused by the validators' trap-free
|
|
95
|
+
* type checks — they are never enumerated inside the trusted region.
|
|
96
|
+
*/
|
|
97
|
+
function validateVariantEntrySnapshot(label, entry, host, opts) {
|
|
98
|
+
if (typeof entry === 'function') {
|
|
99
|
+
// T24 B2: the dynamic form is ACCEPTED at the boundary, by identity and UNINVOKED — its
|
|
100
|
+
// keys do not exist until resolution, so entry validation applies to its RESULT at the
|
|
101
|
+
// resolution seam (resolveVariantDefinition), never here.
|
|
102
|
+
return { refusal: null, entry: entry };
|
|
103
|
+
}
|
|
104
|
+
if (!isPlainObject(entry)) {
|
|
105
|
+
return {
|
|
106
|
+
refusal: new InvalidVariantError(label, entry, `variants.${label} must be a plain target entry (REQ-API-032 law f)`),
|
|
107
|
+
entry: null,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
// READ phase — every getter and enumeration trap fires HERE, outside any try.
|
|
111
|
+
const { transition: rawTransition, ...rawTarget } = entry;
|
|
112
|
+
// Materialize each ARRAY member ONCE, before validation (R8, review major 18): a shallow snapshot let
|
|
113
|
+
// the validators read a member's elements and the accepted clone read them AGAIN, so a hostile
|
|
114
|
+
// accessor-backed array (100 then null) could pass validation yet land the unvalidated null in the
|
|
115
|
+
// snapshot. The bounded capture reads each own index exactly once; the frozen copy is the SINGLE truth both the
|
|
116
|
+
// validators and the accepted entry see. Non-array members pass through unchanged. The accumulator is
|
|
117
|
+
// NULL-PROTOTYPE (review major 24): a SCALAR own '__proto__' member assigned onto an ordinary object
|
|
118
|
+
// is a silent no-op setter (the key vanishes yet the snapshot stays plain and passes the shape gate) —
|
|
119
|
+
// a null-prototype object makes it an own data property so the capability gate refuses it, loudly.
|
|
120
|
+
const targetSnapshot = Object.create(null);
|
|
121
|
+
for (const [key, member] of Object.entries(rawTarget)) {
|
|
122
|
+
if (!Array.isArray(member)) {
|
|
123
|
+
targetSnapshot[key] = member;
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
const captured = (0, boundedArray_1.captureBoundedArray)(member);
|
|
127
|
+
if (captured.kind !== 'captured') {
|
|
128
|
+
return {
|
|
129
|
+
refusal: new InvalidVariantError(label, (0, boundedArray_1.capturedArrayDescription)(captured), `variants.${label} keyframe arrays must have a safe length between 0 and 100000 (REQ-API-033)`),
|
|
130
|
+
entry: null,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
targetSnapshot[key] = captured.values;
|
|
134
|
+
}
|
|
135
|
+
let transitionSnapshot;
|
|
136
|
+
if (rawTransition === undefined) {
|
|
137
|
+
transitionSnapshot = undefined;
|
|
138
|
+
}
|
|
139
|
+
else if (isPlainObject(rawTransition)) {
|
|
140
|
+
// Reuse the value-preserving transition capture used by every raw/supplying boundary. It keeps
|
|
141
|
+
// symbols, unknown strings, and non-enumerable known fields for validateTransitionRefusal while
|
|
142
|
+
// deeply snapshotting only legal timing arrays.
|
|
143
|
+
transitionSnapshot = (0, prepare_1.captureTransition)(rawTransition);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
// A non-plain transition cannot be faithfully snapshotted — spreading a Date/Map/array
|
|
147
|
+
// yields the EMPTY object, silently laundering the malformed shape into a valid empty
|
|
148
|
+
// transition (M3 r4 major 4db96de50131). The refusal is constructed HERE, return-shaped,
|
|
149
|
+
// mirroring validateTransition's own shape law verbatim (message + category parity);
|
|
150
|
+
// the value is never probed again.
|
|
151
|
+
const shapeCause = new validate_1.InvalidTransitionError(opts?.componentId, '(transition)', rawTransition, 'a transition must be a plain object of transition options (G-INV-8 — a malformed config ' +
|
|
152
|
+
'fails loud, never coerces to the default transition)');
|
|
153
|
+
return {
|
|
154
|
+
refusal: new InvalidVariantError(label, entry, `variants.${label}: ${shapeCause.message}`, shapeCause),
|
|
155
|
+
entry: null,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
// RETURN-shaped validators, NO catch (M3 r6 major 30a9c21bf960): a returned refusal is
|
|
159
|
+
// validator-made by construction; anything THROWN — including an authentic same-class
|
|
160
|
+
// sentinel from a polluted dependency (Set.prototype.has) — propagates untouched because
|
|
161
|
+
// nothing here catches it.
|
|
162
|
+
const transitionRefusal = (0, validate_1.validateTransitionRefusal)(transitionSnapshot, opts);
|
|
163
|
+
if (transitionRefusal === null && transitionSnapshot !== undefined) {
|
|
164
|
+
// Family-2: web pin consumes `ease`; rewrite catalog `easings` on the accepted snapshot so
|
|
165
|
+
// every supplier (variant embed, element, MotionConfig) hands the same normalized shape.
|
|
166
|
+
transitionSnapshot = (0, transition_1.normalizeTransitionEaseAlias)(transitionSnapshot);
|
|
167
|
+
}
|
|
168
|
+
if (transitionRefusal !== null) {
|
|
169
|
+
return {
|
|
170
|
+
refusal: new InvalidVariantError(label, entry, `variants.${label}: ${transitionRefusal.message}`, transitionRefusal),
|
|
171
|
+
entry: null,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
const targetRefusal = (0, validate_1.validateTargetRefusal)(targetSnapshot, host, opts);
|
|
175
|
+
if (targetRefusal !== null) {
|
|
176
|
+
return {
|
|
177
|
+
refusal: new InvalidVariantError(label, entry, `variants.${label}: ${targetRefusal.message}`, targetRefusal),
|
|
178
|
+
entry: null,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
for (const [key, value] of Object.entries(targetSnapshot)) {
|
|
182
|
+
const effectiveTransition = transitionSnapshot === undefined
|
|
183
|
+
? undefined
|
|
184
|
+
: (0, transition_1.resolveTransitionForKey)(transitionSnapshot, key);
|
|
185
|
+
const timingRefusal = (0, keyframeTiming_1.keyframeTransitionRefusal)(opts?.componentId, key, value, effectiveTransition);
|
|
186
|
+
if (timingRefusal !== null) {
|
|
187
|
+
return {
|
|
188
|
+
refusal: new InvalidVariantError(label, entry, `variants.${label}: ${timingRefusal.message}`, timingRefusal),
|
|
189
|
+
entry: null,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
// The accepted ENTRY is null-prototype too (M3 r6 major 5d48ad691b96): absent must MEAN
|
|
194
|
+
// absent — a consumer reading `.transition` off an Object.prototype-backed entry would
|
|
195
|
+
// see a polluted inherited value when none is own.
|
|
196
|
+
const acceptedEntry = Object.create(null);
|
|
197
|
+
for (const [key, member] of Object.entries(targetSnapshot)) {
|
|
198
|
+
// `targetSnapshot` array members are ALREADY the read-once frozen copies the validators saw, so the
|
|
199
|
+
// accepted entry references that single truth directly — no second read of the caller's array
|
|
200
|
+
// (reviews major 91f7a2c43bd0 immutability + major 18 one-read). Keyframe elements are scalars.
|
|
201
|
+
acceptedEntry[key] = member;
|
|
202
|
+
}
|
|
203
|
+
if (transitionSnapshot !== undefined) {
|
|
204
|
+
acceptedEntry['transition'] = transitionSnapshot;
|
|
205
|
+
}
|
|
206
|
+
return { refusal: null, entry: acceptedEntry };
|
|
207
|
+
}
|
|
208
|
+
/** Split one entry into its application (the bare target + its own transition). */
|
|
209
|
+
function applicationOf(entry) {
|
|
210
|
+
const { transition, ...target } = entry;
|
|
211
|
+
return { target: target, transition };
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Laws (a)/(b): resolve a label or label array to the ORDERED application list. A local
|
|
215
|
+
* miss contributes nothing (the pinned no-op); each hit preserves its own transition.
|
|
216
|
+
*/
|
|
217
|
+
function resolveVariantDefinition(definition, dictionary, context) {
|
|
218
|
+
const result = resolveVariantDefinitionResult(definition, dictionary, context);
|
|
219
|
+
if (result.refusal !== null)
|
|
220
|
+
throw result.refusal;
|
|
221
|
+
return result.applications;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Internal severity seam: boundary-made validation failures are returned, while value-state reads
|
|
225
|
+
* and user resolver invocations remain outside every catch and preserve their exact thrown value.
|
|
226
|
+
*/
|
|
227
|
+
function resolveVariantDefinitionResult(definition, dictionary, context) {
|
|
228
|
+
if (typeof definition === 'function') {
|
|
229
|
+
const invocation = invokeResolver('(definition)', definition, context);
|
|
230
|
+
if (invocation.refusal !== null)
|
|
231
|
+
return { applications: [], refusal: invocation.refusal };
|
|
232
|
+
const produced = invocation.value;
|
|
233
|
+
if (typeof produced !== 'string') {
|
|
234
|
+
const resolution = resolveProducedTarget('(definition)', produced, context);
|
|
235
|
+
return resolution.refusal === null
|
|
236
|
+
? { applications: [resolution.application], refusal: null }
|
|
237
|
+
: { applications: [], refusal: resolution.refusal };
|
|
238
|
+
}
|
|
239
|
+
return resolveSingleLabel(produced, dictionary, context);
|
|
240
|
+
}
|
|
241
|
+
const labels = typeof definition === 'string' ? [definition] : definition;
|
|
242
|
+
const applications = [];
|
|
243
|
+
for (const label of labels) {
|
|
244
|
+
const resolution = resolveSingleLabel(label, dictionary, context);
|
|
245
|
+
if (resolution.refusal !== null)
|
|
246
|
+
return { applications: [], refusal: resolution.refusal };
|
|
247
|
+
applications.push(...resolution.applications);
|
|
248
|
+
}
|
|
249
|
+
return { applications, refusal: null };
|
|
250
|
+
}
|
|
251
|
+
function resolutionContextRefusal(label, context) {
|
|
252
|
+
return context === undefined
|
|
253
|
+
? new InvalidVariantError(label, undefined, `variants.${label} is a RESOLVER but the resolution site supplied no ` +
|
|
254
|
+
'resolution context — the site is not wired for dynamic variants (T24 B2)')
|
|
255
|
+
: null;
|
|
256
|
+
}
|
|
257
|
+
// Each call performs its own pin-shaped `getValueState` read. The invocation is deliberately
|
|
258
|
+
// unguarded: user faults preserve identity and host severity routes only our typed refusals.
|
|
259
|
+
function invokeResolver(label, entry, context) {
|
|
260
|
+
const refusal = resolutionContextRefusal(label, context);
|
|
261
|
+
if (refusal !== null)
|
|
262
|
+
return { refusal };
|
|
263
|
+
const wired = context;
|
|
264
|
+
const { current, velocity } = wired.readValueState();
|
|
265
|
+
return { value: entry(wired.custom, current, velocity), refusal: null };
|
|
266
|
+
}
|
|
267
|
+
function resolveProducedTarget(label, produced, context) {
|
|
268
|
+
const contextRefusal = resolutionContextRefusal(label, context);
|
|
269
|
+
if (contextRefusal !== null)
|
|
270
|
+
return { refusal: contextRefusal };
|
|
271
|
+
const wired = context;
|
|
272
|
+
if (typeof produced === 'function') {
|
|
273
|
+
return {
|
|
274
|
+
refusal: new InvalidVariantError(label, produced, `variants.${label}: the resolver returned another resolver — a dictionary resolver ` +
|
|
275
|
+
'must return a target object exactly once (the pin two-step bound)'),
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
const { refusal, entry: accepted } = validateVariantEntrySnapshot(label, produced, wired.host, wired.componentId === undefined ? undefined : { componentId: wired.componentId });
|
|
279
|
+
if (refusal !== null)
|
|
280
|
+
return { refusal };
|
|
281
|
+
return { application: applicationOf(accepted), refusal: null };
|
|
282
|
+
}
|
|
283
|
+
function resolveSingleLabel(label, dictionary, context) {
|
|
284
|
+
// OWN properties only (M1 review major 1): prototype-chain names are local misses.
|
|
285
|
+
if (dictionary === undefined || !Object.hasOwn(dictionary, label)) {
|
|
286
|
+
return { applications: [], refusal: null };
|
|
287
|
+
}
|
|
288
|
+
const entry = dictionary[label];
|
|
289
|
+
if (typeof entry !== 'function') {
|
|
290
|
+
return { applications: [applicationOf(entry)], refusal: null };
|
|
291
|
+
}
|
|
292
|
+
const invocation = invokeResolver(label, entry, context);
|
|
293
|
+
if (invocation.refusal !== null)
|
|
294
|
+
return { applications: [], refusal: invocation.refusal };
|
|
295
|
+
// This is the bounded second function arm. Its result is final and cannot name another label.
|
|
296
|
+
const resolution = resolveProducedTarget(label, invocation.value, context);
|
|
297
|
+
return resolution.refusal === null
|
|
298
|
+
? { applications: [resolution.application], refusal: null }
|
|
299
|
+
: { applications: [], refusal: resolution.refusal };
|
|
300
|
+
}
|
|
301
|
+
function flattenVariantApplications(applications) {
|
|
302
|
+
const target = {};
|
|
303
|
+
const transitions = {};
|
|
304
|
+
for (const application of applications) {
|
|
305
|
+
for (const key of Object.keys(application.target)) {
|
|
306
|
+
target[key] = application.target[key];
|
|
307
|
+
if (application.transition === undefined)
|
|
308
|
+
delete transitions[key];
|
|
309
|
+
else
|
|
310
|
+
transitions[key] = application.transition;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
return { target: target, transitions };
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Law (c): the synchronous initial overlay — all labels merge in order into ONE first-paint
|
|
317
|
+
* state, transitions DISCARDED (REQ-API-010's no-entrance law is untouched).
|
|
318
|
+
*/
|
|
319
|
+
function resolveInitialOverlay(definition, dictionary, context) {
|
|
320
|
+
const overlay = {};
|
|
321
|
+
for (const application of resolveVariantDefinition(definition, dictionary, context)) {
|
|
322
|
+
// T23 B3c: an initial application applies its transitionEnd INSTANTLY (the pin's
|
|
323
|
+
// nothing-animates arm) — the carrier's sub-values fold into the first-paint state,
|
|
324
|
+
// winning over the same application's target key; the carrier member itself never
|
|
325
|
+
// rides the overlay.
|
|
326
|
+
const { transitionEnd: carrier, ...plain } = application.target;
|
|
327
|
+
Object.assign(overlay, plain);
|
|
328
|
+
if (typeof carrier === 'object' && carrier !== null && !Array.isArray(carrier)) {
|
|
329
|
+
Object.assign(overlay, carrier);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
return overlay;
|
|
333
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type { HostCapabilities } from "../subset/index.cjs";
|
|
2
|
+
import type { Target, Transition } from "./types.cjs";
|
|
3
|
+
export type VariantEntry = Target & {
|
|
4
|
+
readonly transition?: Transition;
|
|
5
|
+
};
|
|
6
|
+
export type VariantResolver = (custom: unknown, current: Readonly<Record<string, unknown>>, velocity: Readonly<Record<string, number>>) => unknown;
|
|
7
|
+
export interface VariantValueState {
|
|
8
|
+
readonly current: Readonly<Record<string, unknown>>;
|
|
9
|
+
readonly velocity: Readonly<Record<string, number>>;
|
|
10
|
+
}
|
|
11
|
+
export type VariantsDictionary = Readonly<Record<string, VariantEntry | VariantResolver>>;
|
|
12
|
+
/**
|
|
13
|
+
* The live inputs a RESOLVER entry is invoked with (pin `getValueState`: the element's
|
|
14
|
+
* current values and their velocities; `custom` per the pin's exit-vs-props precedence),
|
|
15
|
+
* plus the validation host its RESULT is validated against. A value-less element's reader
|
|
16
|
+
* returns empty maps, matching the pin.
|
|
17
|
+
*/
|
|
18
|
+
export interface VariantResolutionContext {
|
|
19
|
+
readonly custom: unknown;
|
|
20
|
+
/**
|
|
21
|
+
* Pin `getValueState` is read at each function arm, not captured when the definition is
|
|
22
|
+
* discovered. Keeping this lazy also makes static labels a zero-read path.
|
|
23
|
+
*/
|
|
24
|
+
readonly readValueState: () => VariantValueState;
|
|
25
|
+
readonly host: HostCapabilities;
|
|
26
|
+
readonly componentId?: string;
|
|
27
|
+
}
|
|
28
|
+
/** One resolved label's application: the bare target + the label's OWN transition (law b). */
|
|
29
|
+
export interface VariantApplication {
|
|
30
|
+
readonly target: Target;
|
|
31
|
+
readonly transition: Transition | undefined;
|
|
32
|
+
}
|
|
33
|
+
export declare class InvalidVariantError extends Error {
|
|
34
|
+
readonly key: string;
|
|
35
|
+
readonly value: unknown;
|
|
36
|
+
constructor(key: string, value: unknown, reason: string, cause?: unknown);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Law (f), outer shape, RETURN-shaped: the typed refusal, or null when `variants` is a
|
|
40
|
+
* plain object. The probe itself may throw on hostile values (a getPrototypeOf trap, a
|
|
41
|
+
* revoked proxy) — those faults propagate untouched; only the RETURNED refusal is input
|
|
42
|
+
* refusal.
|
|
43
|
+
*/
|
|
44
|
+
export declare function variantsShapeRefusal(value: unknown): InvalidVariantError | null;
|
|
45
|
+
/**
|
|
46
|
+
* Law (f), outer shape: `variants` must be a plain object — null, arrays, and
|
|
47
|
+
* prototype-carrying objects refuse AS A UNIT (typed), never coerce to an empty dictionary.
|
|
48
|
+
*/
|
|
49
|
+
export declare function assertVariantsShape(value: unknown): asserts value is VariantsDictionary;
|
|
50
|
+
/**
|
|
51
|
+
* Law (f), per entry: an entry must be a plain object whose members validate through the
|
|
52
|
+
* SAME boundaries the animate lane rides — core validateTarget for the target members and
|
|
53
|
+
* the REQ-API-031 transition law for the embedded transition — or a RESOLVER (T24 B2),
|
|
54
|
+
* accepted uninvoked and validated at resolution.
|
|
55
|
+
*/
|
|
56
|
+
export declare function validateVariantEntry(label: string, entry: unknown, host: HostCapabilities, opts?: {
|
|
57
|
+
readonly componentId?: string;
|
|
58
|
+
}): void;
|
|
59
|
+
/**
|
|
60
|
+
* Law (f), per entry, RETURN-shaped + SNAPSHOT-accepting (M3 r3 majors 13af48a64530 +
|
|
61
|
+
* 5cb2381e272c; hardened r4 majors 4db96de50131 + 93bab4ecf757): the READ phase runs first
|
|
62
|
+
* and UNGUARDED — the entry's getters and every level of a transition's enumeration traps
|
|
63
|
+
* fire here, so their faults (including authentic same-class sentinels) propagate
|
|
64
|
+
* untouched. Validation then runs on DEEP-plain snapshots, and the SNAPSHOT is what the
|
|
65
|
+
* caller accepts: a stateful proxy cannot show the validators one value and the engine
|
|
66
|
+
* another (one read, one truth). Residual bound, stated honestly: hostile LEAF objects
|
|
67
|
+
* (non-array, non-plain) stay by reference and are refused by the validators' trap-free
|
|
68
|
+
* type checks — they are never enumerated inside the trusted region.
|
|
69
|
+
*/
|
|
70
|
+
export declare function validateVariantEntrySnapshot(label: string, entry: unknown, host: HostCapabilities, opts?: {
|
|
71
|
+
readonly componentId?: string;
|
|
72
|
+
}): {
|
|
73
|
+
readonly refusal: InvalidVariantError | null;
|
|
74
|
+
readonly entry: VariantEntry | VariantResolver | null;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Laws (a)/(b): resolve a label or label array to the ORDERED application list. A local
|
|
78
|
+
* miss contributes nothing (the pinned no-op); each hit preserves its own transition.
|
|
79
|
+
*/
|
|
80
|
+
export declare function resolveVariantDefinition(definition: string | readonly string[] | VariantResolver, dictionary: VariantsDictionary | undefined, context?: VariantResolutionContext): readonly VariantApplication[];
|
|
81
|
+
/**
|
|
82
|
+
* Internal severity seam: boundary-made validation failures are returned, while value-state reads
|
|
83
|
+
* and user resolver invocations remain outside every catch and preserve their exact thrown value.
|
|
84
|
+
*/
|
|
85
|
+
export declare function resolveVariantDefinitionResult(definition: string | readonly string[] | VariantResolver, dictionary: VariantsDictionary | undefined, context?: VariantResolutionContext): {
|
|
86
|
+
readonly applications: readonly VariantApplication[];
|
|
87
|
+
readonly refusal: InvalidVariantError | null;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* The per-key projection of an ordered application list — law (b) for LAYER consumers
|
|
91
|
+
* (gesture-state layers hold one flattened target): each key carries the value AND the
|
|
92
|
+
* transition of the application that LAST named it. A transition-less winner clears an
|
|
93
|
+
* earlier attribution so the key falls back exactly as executing that label alone would
|
|
94
|
+
* (the R6-F1 chain: layer transition, else element transition).
|
|
95
|
+
*/
|
|
96
|
+
export interface FlattenedVariantApplications {
|
|
97
|
+
readonly target: Target;
|
|
98
|
+
/** Attribution holds ONLY labeled transitions — absence (not undefined) means fallback. */
|
|
99
|
+
readonly transitions: Readonly<Record<string, Transition>>;
|
|
100
|
+
}
|
|
101
|
+
export declare function flattenVariantApplications(applications: readonly VariantApplication[]): FlattenedVariantApplications;
|
|
102
|
+
/**
|
|
103
|
+
* Law (c): the synchronous initial overlay — all labels merge in order into ONE first-paint
|
|
104
|
+
* state, transitions DISCARDED (REQ-API-010's no-entrance law is untouched).
|
|
105
|
+
*/
|
|
106
|
+
export declare function resolveInitialOverlay(definition: string | readonly string[], dictionary: VariantsDictionary | undefined, context?: VariantResolutionContext): Target;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type { HostCapabilities } from "../subset/index.js";
|
|
2
|
+
import type { Target, Transition } from "./types.js";
|
|
3
|
+
export type VariantEntry = Target & {
|
|
4
|
+
readonly transition?: Transition;
|
|
5
|
+
};
|
|
6
|
+
export type VariantResolver = (custom: unknown, current: Readonly<Record<string, unknown>>, velocity: Readonly<Record<string, number>>) => unknown;
|
|
7
|
+
export interface VariantValueState {
|
|
8
|
+
readonly current: Readonly<Record<string, unknown>>;
|
|
9
|
+
readonly velocity: Readonly<Record<string, number>>;
|
|
10
|
+
}
|
|
11
|
+
export type VariantsDictionary = Readonly<Record<string, VariantEntry | VariantResolver>>;
|
|
12
|
+
/**
|
|
13
|
+
* The live inputs a RESOLVER entry is invoked with (pin `getValueState`: the element's
|
|
14
|
+
* current values and their velocities; `custom` per the pin's exit-vs-props precedence),
|
|
15
|
+
* plus the validation host its RESULT is validated against. A value-less element's reader
|
|
16
|
+
* returns empty maps, matching the pin.
|
|
17
|
+
*/
|
|
18
|
+
export interface VariantResolutionContext {
|
|
19
|
+
readonly custom: unknown;
|
|
20
|
+
/**
|
|
21
|
+
* Pin `getValueState` is read at each function arm, not captured when the definition is
|
|
22
|
+
* discovered. Keeping this lazy also makes static labels a zero-read path.
|
|
23
|
+
*/
|
|
24
|
+
readonly readValueState: () => VariantValueState;
|
|
25
|
+
readonly host: HostCapabilities;
|
|
26
|
+
readonly componentId?: string;
|
|
27
|
+
}
|
|
28
|
+
/** One resolved label's application: the bare target + the label's OWN transition (law b). */
|
|
29
|
+
export interface VariantApplication {
|
|
30
|
+
readonly target: Target;
|
|
31
|
+
readonly transition: Transition | undefined;
|
|
32
|
+
}
|
|
33
|
+
export declare class InvalidVariantError extends Error {
|
|
34
|
+
readonly key: string;
|
|
35
|
+
readonly value: unknown;
|
|
36
|
+
constructor(key: string, value: unknown, reason: string, cause?: unknown);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Law (f), outer shape, RETURN-shaped: the typed refusal, or null when `variants` is a
|
|
40
|
+
* plain object. The probe itself may throw on hostile values (a getPrototypeOf trap, a
|
|
41
|
+
* revoked proxy) — those faults propagate untouched; only the RETURNED refusal is input
|
|
42
|
+
* refusal.
|
|
43
|
+
*/
|
|
44
|
+
export declare function variantsShapeRefusal(value: unknown): InvalidVariantError | null;
|
|
45
|
+
/**
|
|
46
|
+
* Law (f), outer shape: `variants` must be a plain object — null, arrays, and
|
|
47
|
+
* prototype-carrying objects refuse AS A UNIT (typed), never coerce to an empty dictionary.
|
|
48
|
+
*/
|
|
49
|
+
export declare function assertVariantsShape(value: unknown): asserts value is VariantsDictionary;
|
|
50
|
+
/**
|
|
51
|
+
* Law (f), per entry: an entry must be a plain object whose members validate through the
|
|
52
|
+
* SAME boundaries the animate lane rides — core validateTarget for the target members and
|
|
53
|
+
* the REQ-API-031 transition law for the embedded transition — or a RESOLVER (T24 B2),
|
|
54
|
+
* accepted uninvoked and validated at resolution.
|
|
55
|
+
*/
|
|
56
|
+
export declare function validateVariantEntry(label: string, entry: unknown, host: HostCapabilities, opts?: {
|
|
57
|
+
readonly componentId?: string;
|
|
58
|
+
}): void;
|
|
59
|
+
/**
|
|
60
|
+
* Law (f), per entry, RETURN-shaped + SNAPSHOT-accepting (M3 r3 majors 13af48a64530 +
|
|
61
|
+
* 5cb2381e272c; hardened r4 majors 4db96de50131 + 93bab4ecf757): the READ phase runs first
|
|
62
|
+
* and UNGUARDED — the entry's getters and every level of a transition's enumeration traps
|
|
63
|
+
* fire here, so their faults (including authentic same-class sentinels) propagate
|
|
64
|
+
* untouched. Validation then runs on DEEP-plain snapshots, and the SNAPSHOT is what the
|
|
65
|
+
* caller accepts: a stateful proxy cannot show the validators one value and the engine
|
|
66
|
+
* another (one read, one truth). Residual bound, stated honestly: hostile LEAF objects
|
|
67
|
+
* (non-array, non-plain) stay by reference and are refused by the validators' trap-free
|
|
68
|
+
* type checks — they are never enumerated inside the trusted region.
|
|
69
|
+
*/
|
|
70
|
+
export declare function validateVariantEntrySnapshot(label: string, entry: unknown, host: HostCapabilities, opts?: {
|
|
71
|
+
readonly componentId?: string;
|
|
72
|
+
}): {
|
|
73
|
+
readonly refusal: InvalidVariantError | null;
|
|
74
|
+
readonly entry: VariantEntry | VariantResolver | null;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Laws (a)/(b): resolve a label or label array to the ORDERED application list. A local
|
|
78
|
+
* miss contributes nothing (the pinned no-op); each hit preserves its own transition.
|
|
79
|
+
*/
|
|
80
|
+
export declare function resolveVariantDefinition(definition: string | readonly string[] | VariantResolver, dictionary: VariantsDictionary | undefined, context?: VariantResolutionContext): readonly VariantApplication[];
|
|
81
|
+
/**
|
|
82
|
+
* Internal severity seam: boundary-made validation failures are returned, while value-state reads
|
|
83
|
+
* and user resolver invocations remain outside every catch and preserve their exact thrown value.
|
|
84
|
+
*/
|
|
85
|
+
export declare function resolveVariantDefinitionResult(definition: string | readonly string[] | VariantResolver, dictionary: VariantsDictionary | undefined, context?: VariantResolutionContext): {
|
|
86
|
+
readonly applications: readonly VariantApplication[];
|
|
87
|
+
readonly refusal: InvalidVariantError | null;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* The per-key projection of an ordered application list — law (b) for LAYER consumers
|
|
91
|
+
* (gesture-state layers hold one flattened target): each key carries the value AND the
|
|
92
|
+
* transition of the application that LAST named it. A transition-less winner clears an
|
|
93
|
+
* earlier attribution so the key falls back exactly as executing that label alone would
|
|
94
|
+
* (the R6-F1 chain: layer transition, else element transition).
|
|
95
|
+
*/
|
|
96
|
+
export interface FlattenedVariantApplications {
|
|
97
|
+
readonly target: Target;
|
|
98
|
+
/** Attribution holds ONLY labeled transitions — absence (not undefined) means fallback. */
|
|
99
|
+
readonly transitions: Readonly<Record<string, Transition>>;
|
|
100
|
+
}
|
|
101
|
+
export declare function flattenVariantApplications(applications: readonly VariantApplication[]): FlattenedVariantApplications;
|
|
102
|
+
/**
|
|
103
|
+
* Law (c): the synchronous initial overlay — all labels merge in order into ONE first-paint
|
|
104
|
+
* state, transitions DISCARDED (REQ-API-010's no-entrance law is untouched).
|
|
105
|
+
*/
|
|
106
|
+
export declare function resolveInitialOverlay(definition: string | readonly string[], dictionary: VariantsDictionary | undefined, context?: VariantResolutionContext): Target;
|