@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,97 @@
|
|
|
1
|
+
// SPEC-COMPONENT §2 — the pure target-merge + base-resolution functions (REQ-API-002/010/011/012/017).
|
|
2
|
+
// Two responsibilities, two pure functions on the verifier seam:
|
|
3
|
+
// • resolveTarget(base, target) — REQ-API-012 overlay: apply a partial target onto the live value set.
|
|
4
|
+
// Keys in the target retarget; keys absent from the target retain their live value; a target NEVER
|
|
5
|
+
// resets an unlisted property. There is no "full visual state" the author must restate.
|
|
6
|
+
// • resolveStartValue / hostBaseValue — REQ-API-011 base resolution: the STARTING value of a property
|
|
7
|
+
// appearing in a target with no prior live value — the resolved `style` value if present, else the
|
|
8
|
+
// documented host base. Identical across engines (the base derives from the registry value type, not
|
|
9
|
+
// from any host), so no engine supplies a divergent implicit default.
|
|
10
|
+
// Both are pure and deterministic: same inputs → same result, independent of clock or host (REQ-API-017).
|
|
11
|
+
// Host-agnostic (REQ-CORE-003) — reads only the SUBSET registry (relative import).
|
|
12
|
+
import { UNIVERSAL_SUBSET } from "../subset/index.js";
|
|
13
|
+
import { captureBoundedArray, capturedArrayDescription } from "./boundedArray.js";
|
|
14
|
+
import { InvalidTargetError } from "./validate.js";
|
|
15
|
+
// Overlay `target` onto the live `base` value set (REQ-API-012). Returns a fresh, complete value set: every
|
|
16
|
+
// key present in either input appears once; a key in `target` takes the target value (retarget), a key only
|
|
17
|
+
// in `base` retains its live value (hold). Never mutates its inputs; never resets a property the target did
|
|
18
|
+
// not mention. A target value may be a keyframe array (ResolvedTargetValue), so the merge is typed to carry it.
|
|
19
|
+
export function resolveTarget(base, target) {
|
|
20
|
+
// Hold every unlisted base key, then overlay the target. A keyframe ARRAY value is CLONED (and frozen)
|
|
21
|
+
// as it is captured — a resolved snapshot (a presence exit target, a retarget origin) is resolved-once
|
|
22
|
+
// and held-immutable, so it must not alias a caller-owned array whose later mutation would change it in
|
|
23
|
+
// place (REQ-API-017; review major c8d4e61a705b). Keyframe elements are scalars, so a shallow clone is a
|
|
24
|
+
// full copy. A fresh object each call — the inputs stay immutable.
|
|
25
|
+
const merged = {};
|
|
26
|
+
for (const key of Object.keys(base))
|
|
27
|
+
merged[key] = captureValue(key, base[key]);
|
|
28
|
+
for (const key of Object.keys(target))
|
|
29
|
+
merged[key] = captureValue(key, target[key]);
|
|
30
|
+
return merged;
|
|
31
|
+
}
|
|
32
|
+
// Capture a resolved value independently of its caller: a keyframe array is cloned + frozen (so a later
|
|
33
|
+
// source mutation cannot reach the snapshot, and the snapshot itself cannot be mutated downstream); a
|
|
34
|
+
// scalar is already immutable and passes through.
|
|
35
|
+
function captureValue(key, value) {
|
|
36
|
+
if (!Array.isArray(value))
|
|
37
|
+
return value;
|
|
38
|
+
const capture = captureBoundedArray(value);
|
|
39
|
+
if (capture.kind !== 'captured') {
|
|
40
|
+
throw new InvalidTargetError(undefined, key, capturedArrayDescription(capture), 'keyframe arrays must have a safe bounded length (REQ-API-033)');
|
|
41
|
+
}
|
|
42
|
+
if (capture.values.length < 2) {
|
|
43
|
+
throw new InvalidTargetError(undefined, key, capture.values, 'a keyframe array must have at least two keyframes (REQ-API-033)');
|
|
44
|
+
}
|
|
45
|
+
for (let index = 0; index < capture.values.length; index++) {
|
|
46
|
+
if (!Object.hasOwn(capture.values, index)) {
|
|
47
|
+
throw new InvalidTargetError(undefined, key, capture.values, `keyframe array is missing index ${index} (REQ-API-033)`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return capture.values;
|
|
51
|
+
}
|
|
52
|
+
// REQ-API-011: the STARTING (from) value of a property that appears in a target with no prior live value.
|
|
53
|
+
// The resolved `style` value if the style prop specifies it, else the documented host base. Pure.
|
|
54
|
+
export function resolveStartValue(key, resolution) {
|
|
55
|
+
const styled = resolution?.style?.[key];
|
|
56
|
+
return styled !== undefined ? styled : hostBaseValue(key);
|
|
57
|
+
}
|
|
58
|
+
// T23 B2a2: the discrete-start refusal is TYPED so the component boundary can apply the
|
|
59
|
+
// severity law to exactly this case (production report + refuse the key) without message
|
|
60
|
+
// sniffing; unknown/complex host-base refusals stay plain loud errors on every severity.
|
|
61
|
+
export class DiscreteHostBaseError extends Error {
|
|
62
|
+
constructor(key) {
|
|
63
|
+
super(`no documented host base value for discrete '${key}': the host default diverges across ` +
|
|
64
|
+
'engines — provide the starting keyword via initial/style/variants.');
|
|
65
|
+
this.name = 'DiscreteHostBaseError';
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// The documented host base value for a universal property (REQ-API-011) — the value it animates FROM when
|
|
69
|
+
// neither a live value nor a `style` value exists. Derived from the registry value type so it is a SINGLE
|
|
70
|
+
// source of truth and identical across engines (no host parameter, no engine-divergent default): scale and
|
|
71
|
+
// opacity rest at 1; translations, dimensions, spacing, radii, border widths, and angles rest at 0; colors
|
|
72
|
+
// rest at fully-transparent black. complex/gesture capabilities have no scalar base and fail loud, as does
|
|
73
|
+
// an unknown property.
|
|
74
|
+
export function hostBaseValue(key) {
|
|
75
|
+
const entry = UNIVERSAL_SUBSET.get(key);
|
|
76
|
+
if (entry === undefined) {
|
|
77
|
+
throw new Error(`no documented host base value for unknown property '${key}': it is not a universal-subset property.`);
|
|
78
|
+
}
|
|
79
|
+
switch (entry.valueType) {
|
|
80
|
+
case 'unitless':
|
|
81
|
+
// opacity and scale/scaleX/scaleY are the only unitless universal properties; all rest at 1.
|
|
82
|
+
return 1;
|
|
83
|
+
case 'length':
|
|
84
|
+
case 'angle':
|
|
85
|
+
return 0;
|
|
86
|
+
case 'rgba':
|
|
87
|
+
return 'rgba(0, 0, 0, 0)';
|
|
88
|
+
case 'discrete':
|
|
89
|
+
// T23 B: the host default for a discrete keyword DIVERGES across engines (web block vs RN
|
|
90
|
+
// flex for display) — there is no engine-identical documented base, so the start value must
|
|
91
|
+
// come from `initial`/`style`/a variant, never a silent host default.
|
|
92
|
+
throw new DiscreteHostBaseError(key);
|
|
93
|
+
case 'complex':
|
|
94
|
+
case 'gesture':
|
|
95
|
+
throw new Error(`no documented host base value for '${key}' (valueType '${entry.valueType}'): it is not an animatable scalar/color property.`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// SPEC-COMPONENT §2 — the transition unit boundary (REQ-API-001). The public `Transition` (in ./types)
|
|
3
|
+
// speaks Motion's SECONDS convention; the internal SPRING (`SpringConfig`) and TIMING (`TimingConfig`)
|
|
4
|
+
// resolvers consume MILLISECONDS. These pure converters are the SINGLE crossing point, so the internal
|
|
5
|
+
// millisecond unit never leaks into the authored public surface and a Motion-idiomatic transition config
|
|
6
|
+
// resolves identically here. Host-agnostic (REQ-CORE-003) — relative imports only.
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.resolveTransitionForKey = resolveTransitionForKey;
|
|
9
|
+
exports.toSpringConfig = toSpringConfig;
|
|
10
|
+
exports.effectiveTransitionEase = effectiveTransitionEase;
|
|
11
|
+
exports.normalizeTransitionEaseAlias = normalizeTransitionEaseAlias;
|
|
12
|
+
exports.toRepeatFoldOptions = toRepeatFoldOptions;
|
|
13
|
+
exports.toDelayMs = toDelayMs;
|
|
14
|
+
exports.toTimingConfig = toTimingConfig;
|
|
15
|
+
exports.isTimingLaneTransition = isTimingLaneTransition;
|
|
16
|
+
exports.isDurationZeroInstantTransition = isDurationZeroInstantTransition;
|
|
17
|
+
exports.toTimingLaneConfig = toTimingLaneConfig;
|
|
18
|
+
exports.toKeyframesConfig = toKeyframesConfig;
|
|
19
|
+
const timing_1 = require("../timing.cjs");
|
|
20
|
+
const types_1 = require("./types.cjs");
|
|
21
|
+
// Motion authors durations in seconds; the SPRING/TIMING generators are seeded in milliseconds. This is the
|
|
22
|
+
// only conversion factor, named rather than inlined so the seconds↔ms boundary is explicit.
|
|
23
|
+
const MS_PER_SECOND = 1000;
|
|
24
|
+
const TRANSITION_MAP_KEYS = new Set(['default', 'layout', ...types_1.TARGET_PROPERTY_KEYS]);
|
|
25
|
+
function isTransitionMapKey(key) {
|
|
26
|
+
return TRANSITION_MAP_KEYS.has(key);
|
|
27
|
+
}
|
|
28
|
+
function flatTransitionSnapshot(source) {
|
|
29
|
+
const out = Object.create(null);
|
|
30
|
+
for (const key of Reflect.ownKeys(source)) {
|
|
31
|
+
if (typeof key !== 'string' || key === 'inherit' || isTransitionMapKey(key))
|
|
32
|
+
continue;
|
|
33
|
+
const descriptor = Object.getOwnPropertyDescriptor(source, key);
|
|
34
|
+
if (descriptor === undefined)
|
|
35
|
+
continue;
|
|
36
|
+
Object.defineProperty(out, key, {
|
|
37
|
+
value: source[key],
|
|
38
|
+
enumerable: descriptor.enumerable === true,
|
|
39
|
+
configurable: true,
|
|
40
|
+
writable: true,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return Object.freeze(out);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Resolve one Motion consumer against an authored transition map. The result is a detached flat
|
|
47
|
+
* bag: map entries never cross into a generator, and nested maps never recurse. Validation/capture
|
|
48
|
+
* owns malformed-shape refusal; this selector assumes that boundary has passed and preserves the
|
|
49
|
+
* pin's key → default → root precedence.
|
|
50
|
+
*/
|
|
51
|
+
function resolveTransitionForKey(transition, key) {
|
|
52
|
+
const source = transition;
|
|
53
|
+
const named = isTransitionMapKey(key) ? source[key] : undefined;
|
|
54
|
+
const fallback = source['default'];
|
|
55
|
+
const selected = named !== undefined && named !== null
|
|
56
|
+
? named
|
|
57
|
+
: fallback !== undefined && fallback !== null
|
|
58
|
+
? fallback
|
|
59
|
+
: transition;
|
|
60
|
+
if (selected === transition)
|
|
61
|
+
return flatTransitionSnapshot(source);
|
|
62
|
+
const root = flatTransitionSnapshot(source);
|
|
63
|
+
const nested = selected;
|
|
64
|
+
if (nested['inherit'] !== true) {
|
|
65
|
+
// Motion's getValueTransition returns a replacing child bag unchanged. The separate delay
|
|
66
|
+
// rebase in animateTarget supplies only its orchestration delay before spreading this bag, so
|
|
67
|
+
// an ordinary selected bag does not inherit the root transition's delay (motion-dom@12.42.2).
|
|
68
|
+
return flatTransitionSnapshot(nested);
|
|
69
|
+
}
|
|
70
|
+
const merged = Object.create(null);
|
|
71
|
+
for (const key of Reflect.ownKeys(root)) {
|
|
72
|
+
const descriptor = Object.getOwnPropertyDescriptor(root, key);
|
|
73
|
+
if (descriptor !== undefined)
|
|
74
|
+
Object.defineProperty(merged, key, { ...descriptor, configurable: true, writable: true });
|
|
75
|
+
}
|
|
76
|
+
const child = flatTransitionSnapshot(nested);
|
|
77
|
+
for (const key of Reflect.ownKeys(child)) {
|
|
78
|
+
const descriptor = Object.getOwnPropertyDescriptor(child, key);
|
|
79
|
+
if (descriptor !== undefined)
|
|
80
|
+
Object.defineProperty(merged, key, { ...descriptor, configurable: true, writable: true });
|
|
81
|
+
}
|
|
82
|
+
return Object.freeze(merged);
|
|
83
|
+
}
|
|
84
|
+
// Bridge the public `Transition` to the internal spring `SpringConfig`. `duration` crosses seconds→ms;
|
|
85
|
+
// `visualDuration` is already seconds in both surfaces (passthrough); the physics options are unit-
|
|
86
|
+
// consistent with Motion. Absent fields are omitted entirely (not written as `undefined`) so the result
|
|
87
|
+
// satisfies `exactOptionalPropertyTypes`.
|
|
88
|
+
function toSpringConfig(transition) {
|
|
89
|
+
const config = {};
|
|
90
|
+
if (transition.stiffness !== undefined)
|
|
91
|
+
config.stiffness = transition.stiffness;
|
|
92
|
+
if (transition.damping !== undefined)
|
|
93
|
+
config.damping = transition.damping;
|
|
94
|
+
if (transition.mass !== undefined)
|
|
95
|
+
config.mass = transition.mass;
|
|
96
|
+
if (transition.bounce !== undefined)
|
|
97
|
+
config.bounce = transition.bounce;
|
|
98
|
+
if (transition.velocity !== undefined)
|
|
99
|
+
config.velocity = transition.velocity;
|
|
100
|
+
// U7c (REQ-SPRING-014): the authored settle thresholds cross verbatim — unit-free passthroughs
|
|
101
|
+
// (the velocity precedent). An explicit 0 is forwarded as PRESENT; the `||=` quirk (0 ≡ absent,
|
|
102
|
+
// motion-dom@12.42.2 spring.ts:275-280) resolves in the solver's `||` read, never here.
|
|
103
|
+
if (transition.restDelta !== undefined)
|
|
104
|
+
config.restDelta = transition.restDelta;
|
|
105
|
+
if (transition.restSpeed !== undefined)
|
|
106
|
+
config.restSpeed = transition.restSpeed;
|
|
107
|
+
if (transition.visualDuration !== undefined)
|
|
108
|
+
config.visualDuration = transition.visualDuration;
|
|
109
|
+
if (transition.duration !== undefined)
|
|
110
|
+
config.duration = transition.duration * MS_PER_SECOND;
|
|
111
|
+
return config;
|
|
112
|
+
}
|
|
113
|
+
// Bridge the public `Transition` to the internal `TimingConfig` (tween path). `duration` crosses
|
|
114
|
+
// seconds→ms; `ease` passes through. Absent fields omitted (exactOptionalPropertyTypes).
|
|
115
|
+
// Family-2 / T20: `easings` and `easing` are Motion catalog aliases of `ease`.
|
|
116
|
+
// Dual authorship is refused at validate.
|
|
117
|
+
function effectiveTransitionEase(transition) {
|
|
118
|
+
if (transition.ease !== undefined)
|
|
119
|
+
return transition.ease;
|
|
120
|
+
if (transition.easings !== undefined)
|
|
121
|
+
return transition.easings;
|
|
122
|
+
return transition.easing;
|
|
123
|
+
}
|
|
124
|
+
// Rewrite `easings` → `ease` for host pass-through (web motion.div speaks `ease`). Identity when
|
|
125
|
+
// only `ease` is authored. Dual authorship never reaches here (validate refuses first).
|
|
126
|
+
// Preserve null-prototype + freeze + own descriptors from captureTransition (G-INV-8): object
|
|
127
|
+
// spread would re-open prototype pollution and drop non-enumerable own keys.
|
|
128
|
+
// Explicit `ease: undefined` / `easings: undefined` are ABSENT (same law, 00i0nt) — strip those
|
|
129
|
+
// own keys so nested config merge cannot treat them as present values that clobber a parent.
|
|
130
|
+
const EASE_ALIAS_KEYS = ['easings', 'easing'];
|
|
131
|
+
function normalizeFlatTransitionEaseAlias(transition) {
|
|
132
|
+
const source = transition;
|
|
133
|
+
const hasOwnEase = Object.hasOwn(transition, 'ease');
|
|
134
|
+
const easeIsExplicitUndefined = hasOwnEase && source['ease'] === undefined;
|
|
135
|
+
let aliasKey;
|
|
136
|
+
let aliasValue;
|
|
137
|
+
let aliasExplicitUndefined = false;
|
|
138
|
+
for (const key of EASE_ALIAS_KEYS) {
|
|
139
|
+
if (!Object.hasOwn(transition, key))
|
|
140
|
+
continue;
|
|
141
|
+
const value = source[key];
|
|
142
|
+
if (value === undefined) {
|
|
143
|
+
aliasExplicitUndefined = true;
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
if (aliasKey === undefined) {
|
|
147
|
+
aliasKey = key;
|
|
148
|
+
aliasValue = value;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (aliasKey === undefined) {
|
|
152
|
+
if (!easeIsExplicitUndefined && !aliasExplicitUndefined)
|
|
153
|
+
return transition;
|
|
154
|
+
const stripped = Object.create(null);
|
|
155
|
+
let changed = false;
|
|
156
|
+
for (const key of Reflect.ownKeys(transition)) {
|
|
157
|
+
if (key === 'ease' && source[key] === undefined) {
|
|
158
|
+
changed = true;
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
if ((key === 'easings' || key === 'easing') && source[key] === undefined) {
|
|
162
|
+
changed = true;
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
const descriptor = Object.getOwnPropertyDescriptor(transition, key);
|
|
166
|
+
if (descriptor === undefined)
|
|
167
|
+
continue;
|
|
168
|
+
Object.defineProperty(stripped, key, {
|
|
169
|
+
value: descriptor.value,
|
|
170
|
+
enumerable: descriptor.enumerable === true,
|
|
171
|
+
configurable: true,
|
|
172
|
+
writable: true,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
return changed ? Object.freeze(stripped) : transition;
|
|
176
|
+
}
|
|
177
|
+
const captured = Object.create(null);
|
|
178
|
+
for (const key of Reflect.ownKeys(transition)) {
|
|
179
|
+
if (key === 'easings' || key === 'easing')
|
|
180
|
+
continue;
|
|
181
|
+
if (key === 'ease' && source[key] === undefined)
|
|
182
|
+
continue;
|
|
183
|
+
const descriptor = Object.getOwnPropertyDescriptor(transition, key);
|
|
184
|
+
if (descriptor === undefined)
|
|
185
|
+
continue;
|
|
186
|
+
Object.defineProperty(captured, key, {
|
|
187
|
+
value: descriptor.value,
|
|
188
|
+
enumerable: descriptor.enumerable === true,
|
|
189
|
+
configurable: true,
|
|
190
|
+
writable: true,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
Object.defineProperty(captured, 'ease', {
|
|
194
|
+
value: aliasValue,
|
|
195
|
+
enumerable: true,
|
|
196
|
+
configurable: true,
|
|
197
|
+
writable: true,
|
|
198
|
+
});
|
|
199
|
+
return Object.freeze(captured);
|
|
200
|
+
}
|
|
201
|
+
const TRANSITION_MAP_KEYS_FOR_ALIAS = new Set([
|
|
202
|
+
'default',
|
|
203
|
+
'layout',
|
|
204
|
+
...types_1.TARGET_PROPERTY_KEYS,
|
|
205
|
+
]);
|
|
206
|
+
/**
|
|
207
|
+
* Canonicalize the public `easings` alias at both legal transition levels. The pin-facing web/native
|
|
208
|
+
* consumers never receive nested bags directly, but MotionConfig and variant inheritance can carry a
|
|
209
|
+
* captured map through several handoff boundaries before the consumer selector runs. Normalize exactly
|
|
210
|
+
* one nested bag level; recursive maps are a validation error, not an invitation to walk unbounded data.
|
|
211
|
+
*/
|
|
212
|
+
function normalizeTransitionEaseAlias(transition) {
|
|
213
|
+
const root = normalizeFlatTransitionEaseAlias(transition);
|
|
214
|
+
const source = transition;
|
|
215
|
+
let changed = root !== transition;
|
|
216
|
+
const replacements = new Map();
|
|
217
|
+
for (const key of Reflect.ownKeys(transition)) {
|
|
218
|
+
if (typeof key !== 'string' || !TRANSITION_MAP_KEYS_FOR_ALIAS.has(key))
|
|
219
|
+
continue;
|
|
220
|
+
const nested = source[key];
|
|
221
|
+
if (typeof nested !== 'object' ||
|
|
222
|
+
nested === null ||
|
|
223
|
+
Array.isArray(nested) ||
|
|
224
|
+
(Object.getPrototypeOf(nested) !== Object.prototype && Object.getPrototypeOf(nested) !== null))
|
|
225
|
+
continue;
|
|
226
|
+
const normalized = normalizeFlatTransitionEaseAlias(nested);
|
|
227
|
+
if (normalized !== nested) {
|
|
228
|
+
changed = true;
|
|
229
|
+
replacements.set(key, normalized);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
if (!changed)
|
|
233
|
+
return root;
|
|
234
|
+
const out = Object.create(null);
|
|
235
|
+
for (const key of Reflect.ownKeys(root)) {
|
|
236
|
+
const descriptor = Object.getOwnPropertyDescriptor(root, key);
|
|
237
|
+
if (descriptor === undefined)
|
|
238
|
+
continue;
|
|
239
|
+
Object.defineProperty(out, key, {
|
|
240
|
+
value: replacements.get(key) ?? descriptor.value,
|
|
241
|
+
enumerable: descriptor.enumerable === true,
|
|
242
|
+
configurable: true,
|
|
243
|
+
writable: true,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
return Object.freeze(out);
|
|
247
|
+
}
|
|
248
|
+
function toRepeatFoldOptions(transition) {
|
|
249
|
+
const repeat = transition.repeat;
|
|
250
|
+
if (repeat === undefined || repeat <= 0)
|
|
251
|
+
return null;
|
|
252
|
+
return {
|
|
253
|
+
repeat,
|
|
254
|
+
repeatType: transition.repeatType ?? 'loop',
|
|
255
|
+
repeatDelayMs: (transition.repeatDelay ?? 0) * MS_PER_SECOND,
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
// T18-b (REQ-TIMING-004 / REQ-API-050): the public `delay` crosses seconds→ms HERE, at the same
|
|
259
|
+
// boundary as every other public time (duration in toTimingConfig/toKeyframesConfig, repeatDelay
|
|
260
|
+
// above) — the rebase consumes milliseconds. Absent reads as 0, the pin's default.
|
|
261
|
+
function toDelayMs(transition) {
|
|
262
|
+
return (transition.delay ?? 0) * MS_PER_SECOND;
|
|
263
|
+
}
|
|
264
|
+
function toTimingConfig(transition) {
|
|
265
|
+
const config = {};
|
|
266
|
+
if (transition.duration !== undefined)
|
|
267
|
+
config.duration = transition.duration * MS_PER_SECOND;
|
|
268
|
+
// The scalar TWEEN path takes a SINGLE easing only. A per-segment `ease` LIST (R8 M2-B) is a
|
|
269
|
+
// keyframe-array param carried exclusively by `toKeyframesConfig`; passing a list here would break
|
|
270
|
+
// `resolveEasing` (it expects one easing). A list on a scalar target is a cross-field error caught
|
|
271
|
+
// by `keyframeTimingRefusal`, so dropping it here is safe and keeps the tween path total.
|
|
272
|
+
const ease = effectiveTransitionEase(transition);
|
|
273
|
+
if (ease !== undefined && !(0, timing_1.isEasingList)(ease))
|
|
274
|
+
config.ease = ease;
|
|
275
|
+
return config;
|
|
276
|
+
}
|
|
277
|
+
// transition-default-selection F6: the pin's timing LANE predicate, and the ONE rule both drivers
|
|
278
|
+
// and validation read. `isTransitionDefined` counts an authored duration AND the ease spellings
|
|
279
|
+
// (only the orchestration keys are exempt, is-transition-defined.ts:4-29), and a DEFINED-but-
|
|
280
|
+
// typeless bag resolves through the keyframes/timing generator at the 300ms default
|
|
281
|
+
// (motion-dom@12.42.2 JSAnimation.ts:106-116 `type = keyframesGenerator`,
|
|
282
|
+
// generators/keyframes.ts:25 `duration = 300`) — never the spring backstop. The lane is therefore:
|
|
283
|
+
// type omitted AND (an authored duration OR an authored ease spelling — `ease`/`easings`/`easing`,
|
|
284
|
+
// the 00i0nt alias law). Inertia narrows off by its literal `type`.
|
|
285
|
+
//
|
|
286
|
+
// The duration arm is REQ-TIMING-006's: the pin's `isTransitionDefined({ duration })` is TRUE, so
|
|
287
|
+
// `animateMotionValue` SKIPS the per-key `getDefaultTransition` (the spring, REQ-SPRING-012) and
|
|
288
|
+
// `JSAnimation.initAnimation` falls through `type = keyframesGenerator` (motion-value.ts:68-71,
|
|
289
|
+
// JSAnimation.ts:104,115-116) — an authored scalar transition with `duration` and no `type` runs
|
|
290
|
+
// the keyframes/timing generator, monotone, NEVER a duration-spring. This predicate SUBSUMES that
|
|
291
|
+
// arm; the narrower `isDurationOnlyTransition` it superseded at every call site was removed rather
|
|
292
|
+
// than left as dead exported surface, so do not reintroduce a duration-only predicate here.
|
|
293
|
+
//
|
|
294
|
+
// The ease-only arm is the F6 addition and is why an absent `duration` does NOT imply the spring
|
|
295
|
+
// backstop: `{ ease: 'linear' }` matches. It keeps its authored ease verbatim —
|
|
296
|
+
// `toTimingLaneConfig` injects easeOut ONLY when no spelling is authored, so no injection fires
|
|
297
|
+
// here. An orchestration-only bag matches NEITHER arm and keeps the spring backstop: unreachable
|
|
298
|
+
// on the component path (the controller's flat arm already merged the per-key default under it,
|
|
299
|
+
// REQ-SPRING-012) but held as the defensive default.
|
|
300
|
+
function isTimingLaneTransition(transition) {
|
|
301
|
+
if (transition.type !== undefined)
|
|
302
|
+
return false;
|
|
303
|
+
if (transition.duration !== undefined)
|
|
304
|
+
return true;
|
|
305
|
+
return effectiveTransitionEase(transition) !== undefined;
|
|
306
|
+
}
|
|
307
|
+
// transition-default-selection F5: the duration-zero half of the pin's `makeAnimationInstant`
|
|
308
|
+
// guard (motion-dom@12.42.2 animation/interfaces/motion-value.ts:89-98 —
|
|
309
|
+
// `(options as any).type === false || (options.duration === 0 && !options.repeatDelay)`; the
|
|
310
|
+
// `type === false` half is the U7a lane, which the drivers check beside this one). The routing is
|
|
311
|
+
// TYPE-INDEPENDENT — a typed spring with `duration: 0` instants too — and honors the pin's
|
|
312
|
+
// truthiness: an authored `repeatDelay: 0` reads as absent. A repeatDelay-bearing bag is EXEMPT:
|
|
313
|
+
// it keeps its normal generator (the pin builds a real animation whose zero-length plays are
|
|
314
|
+
// separated by the repeatDelay gaps).
|
|
315
|
+
function isDurationZeroInstantTransition(transition) {
|
|
316
|
+
if (transition.type === 'inertia')
|
|
317
|
+
return false;
|
|
318
|
+
return transition.duration === 0 && !transition.repeatDelay;
|
|
319
|
+
}
|
|
320
|
+
// REQ-TIMING-006 + transition-default-selection F1: the timing LANE's config — the ONE builder
|
|
321
|
+
// every timing-lane consumer reads (both drivers' scalar arms, the presence exit lane). The pin's
|
|
322
|
+
// `animateMotionValue` options base is `{ keyframes: [null, target], ease: "easeOut", ...valueTransition }`
|
|
323
|
+
// (motion-dom@12.42.2 motion-value.ts:45-49), so only an AUTHORED ease spelling overrides:
|
|
324
|
+
// whenever the timing lane is selected — a typed tween OR a duration-only untyped bag — and no
|
|
325
|
+
// ease spelling is authored, the ease is [0, 0, 0.58, 1], never the generator default
|
|
326
|
+
// [0.25, 0.1, 0.35, 1] (REQ-TIMING-002, whose default now governs only the pin's per-key default
|
|
327
|
+
// tween, default-transitions.ts:35-48). Any authored spelling (`ease`/`easings`/`easing`, the
|
|
328
|
+
// 00i0nt alias law) suppresses the injection. Mirrors the sealed layout-lane law (REQ-LAYOUT-023
|
|
329
|
+
// a, 7htzcf).
|
|
330
|
+
function toTimingLaneConfig(transition) {
|
|
331
|
+
const config = toTimingConfig(transition);
|
|
332
|
+
if (effectiveTransitionEase(transition) === undefined)
|
|
333
|
+
config.ease = 'easeOut';
|
|
334
|
+
return config;
|
|
335
|
+
}
|
|
336
|
+
// Bridge the public `Transition` to the internal `KeyframesConfig` (the multi-keyframe timing path,
|
|
337
|
+
// REQ-API-033). `duration` crosses seconds→ms; `ease` passes through — a single easing (applied to
|
|
338
|
+
// every segment) OR a per-SEGMENT list (R8 M2-B, law d); `times` (custom 0–1 offsets) passes through
|
|
339
|
+
// as-is (offsets are unitless, no seconds→ms crossing). Absent fields omitted
|
|
340
|
+
// (exactOptionalPropertyTypes). Shape validation happens before this bridge; target-count fallback is
|
|
341
|
+
// owned by the shared core/UI keyframe normalization seam.
|
|
342
|
+
function toKeyframesConfig(transition) {
|
|
343
|
+
const config = {};
|
|
344
|
+
if (transition.duration !== undefined)
|
|
345
|
+
config.duration = transition.duration * MS_PER_SECOND;
|
|
346
|
+
const ease = effectiveTransitionEase(transition);
|
|
347
|
+
if (ease !== undefined)
|
|
348
|
+
config.ease = ease;
|
|
349
|
+
if (transition.times !== undefined)
|
|
350
|
+
config.times = transition.times;
|
|
351
|
+
return config;
|
|
352
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { KeyframesConfig } from "../keyframes.cjs";
|
|
2
|
+
import type { RepeatType } from "../repeat.cjs";
|
|
3
|
+
import { type TimingConfig } from "../timing.cjs";
|
|
4
|
+
import type { InertiaTransition, SpringConfig } from "../transition.cjs";
|
|
5
|
+
import { type Transition } from "./types.cjs";
|
|
6
|
+
/**
|
|
7
|
+
* Resolve one Motion consumer against an authored transition map. The result is a detached flat
|
|
8
|
+
* bag: map entries never cross into a generator, and nested maps never recurse. Validation/capture
|
|
9
|
+
* owns malformed-shape refusal; this selector assumes that boundary has passed and preserves the
|
|
10
|
+
* pin's key → default → root precedence.
|
|
11
|
+
*/
|
|
12
|
+
export declare function resolveTransitionForKey(transition: Transition, key: string): Transition;
|
|
13
|
+
export declare function toSpringConfig(transition: Transition): SpringConfig;
|
|
14
|
+
export declare function effectiveTransitionEase(transition: Transition): Transition['ease'] | Transition['easings'] | Transition['easing'];
|
|
15
|
+
/**
|
|
16
|
+
* Canonicalize the public `easings` alias at both legal transition levels. The pin-facing web/native
|
|
17
|
+
* consumers never receive nested bags directly, but MotionConfig and variant inheritance can carry a
|
|
18
|
+
* captured map through several handoff boundaries before the consumer selector runs. Normalize exactly
|
|
19
|
+
* one nested bag level; recursive maps are a validation error, not an invitation to walk unbounded data.
|
|
20
|
+
*/
|
|
21
|
+
export declare function normalizeTransitionEaseAlias(transition: Transition): Transition;
|
|
22
|
+
export interface RepeatFoldOptions {
|
|
23
|
+
readonly repeat: number;
|
|
24
|
+
readonly repeatType: RepeatType;
|
|
25
|
+
readonly repeatDelayMs: number;
|
|
26
|
+
}
|
|
27
|
+
export declare function toRepeatFoldOptions(transition: Transition): RepeatFoldOptions | null;
|
|
28
|
+
export declare function toDelayMs(transition: Transition): number;
|
|
29
|
+
export declare function toTimingConfig(transition: Transition): TimingConfig;
|
|
30
|
+
export declare function isTimingLaneTransition(transition: Transition | InertiaTransition): boolean;
|
|
31
|
+
export declare function isDurationZeroInstantTransition(transition: Transition | InertiaTransition): boolean;
|
|
32
|
+
export declare function toTimingLaneConfig(transition: Transition): TimingConfig;
|
|
33
|
+
export declare function toKeyframesConfig(transition: Transition): KeyframesConfig;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { KeyframesConfig } from "../keyframes.js";
|
|
2
|
+
import type { RepeatType } from "../repeat.js";
|
|
3
|
+
import { type TimingConfig } from "../timing.js";
|
|
4
|
+
import type { InertiaTransition, SpringConfig } from "../transition.js";
|
|
5
|
+
import { type Transition } from "./types.js";
|
|
6
|
+
/**
|
|
7
|
+
* Resolve one Motion consumer against an authored transition map. The result is a detached flat
|
|
8
|
+
* bag: map entries never cross into a generator, and nested maps never recurse. Validation/capture
|
|
9
|
+
* owns malformed-shape refusal; this selector assumes that boundary has passed and preserves the
|
|
10
|
+
* pin's key → default → root precedence.
|
|
11
|
+
*/
|
|
12
|
+
export declare function resolveTransitionForKey(transition: Transition, key: string): Transition;
|
|
13
|
+
export declare function toSpringConfig(transition: Transition): SpringConfig;
|
|
14
|
+
export declare function effectiveTransitionEase(transition: Transition): Transition['ease'] | Transition['easings'] | Transition['easing'];
|
|
15
|
+
/**
|
|
16
|
+
* Canonicalize the public `easings` alias at both legal transition levels. The pin-facing web/native
|
|
17
|
+
* consumers never receive nested bags directly, but MotionConfig and variant inheritance can carry a
|
|
18
|
+
* captured map through several handoff boundaries before the consumer selector runs. Normalize exactly
|
|
19
|
+
* one nested bag level; recursive maps are a validation error, not an invitation to walk unbounded data.
|
|
20
|
+
*/
|
|
21
|
+
export declare function normalizeTransitionEaseAlias(transition: Transition): Transition;
|
|
22
|
+
export interface RepeatFoldOptions {
|
|
23
|
+
readonly repeat: number;
|
|
24
|
+
readonly repeatType: RepeatType;
|
|
25
|
+
readonly repeatDelayMs: number;
|
|
26
|
+
}
|
|
27
|
+
export declare function toRepeatFoldOptions(transition: Transition): RepeatFoldOptions | null;
|
|
28
|
+
export declare function toDelayMs(transition: Transition): number;
|
|
29
|
+
export declare function toTimingConfig(transition: Transition): TimingConfig;
|
|
30
|
+
export declare function isTimingLaneTransition(transition: Transition | InertiaTransition): boolean;
|
|
31
|
+
export declare function isDurationZeroInstantTransition(transition: Transition | InertiaTransition): boolean;
|
|
32
|
+
export declare function toTimingLaneConfig(transition: Transition): TimingConfig;
|
|
33
|
+
export declare function toKeyframesConfig(transition: Transition): KeyframesConfig;
|