@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.
Files changed (326) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/LICENSE +21 -0
  3. package/README.md +48 -0
  4. package/dist/clock.cjs +71 -0
  5. package/dist/clock.d.cts +23 -0
  6. package/dist/clock.d.ts +23 -0
  7. package/dist/clock.js +66 -0
  8. package/dist/collect-reads.cjs +68 -0
  9. package/dist/collect-reads.d.cts +23 -0
  10. package/dist/collect-reads.d.ts +23 -0
  11. package/dist/collect-reads.js +62 -0
  12. package/dist/component/boundedArray.cjs +74 -0
  13. package/dist/component/boundedArray.d.cts +25 -0
  14. package/dist/component/boundedArray.d.ts +25 -0
  15. package/dist/component/boundedArray.js +68 -0
  16. package/dist/component/index.cjs +57 -0
  17. package/dist/component/index.d.cts +12 -0
  18. package/dist/component/index.d.ts +12 -0
  19. package/dist/component/index.js +22 -0
  20. package/dist/component/orchestration.cjs +129 -0
  21. package/dist/component/orchestration.d.cts +66 -0
  22. package/dist/component/orchestration.d.ts +66 -0
  23. package/dist/component/orchestration.js +124 -0
  24. package/dist/component/resolve.cjs +104 -0
  25. package/dist/component/resolve.d.cts +11 -0
  26. package/dist/component/resolve.d.ts +11 -0
  27. package/dist/component/resolve.js +97 -0
  28. package/dist/component/transition.cjs +352 -0
  29. package/dist/component/transition.d.cts +33 -0
  30. package/dist/component/transition.d.ts +33 -0
  31. package/dist/component/transition.js +339 -0
  32. package/dist/component/types.cjs +114 -0
  33. package/dist/component/types.d.cts +60 -0
  34. package/dist/component/types.d.ts +60 -0
  35. package/dist/component/types.js +111 -0
  36. package/dist/component/validate.cjs +1015 -0
  37. package/dist/component/validate.d.cts +37 -0
  38. package/dist/component/validate.d.ts +37 -0
  39. package/dist/component/validate.js +1002 -0
  40. package/dist/component/variants.cjs +333 -0
  41. package/dist/component/variants.d.cts +106 -0
  42. package/dist/component/variants.d.ts +106 -0
  43. package/dist/component/variants.js +321 -0
  44. package/dist/config/constants.cjs +41 -0
  45. package/dist/config/constants.d.cts +29 -0
  46. package/dist/config/constants.d.ts +29 -0
  47. package/dist/config/constants.js +38 -0
  48. package/dist/delay.cjs +72 -0
  49. package/dist/delay.d.cts +26 -0
  50. package/dist/delay.d.ts +26 -0
  51. package/dist/delay.js +70 -0
  52. package/dist/derived.cjs +143 -0
  53. package/dist/derived.d.cts +41 -0
  54. package/dist/derived.d.ts +41 -0
  55. package/dist/derived.js +139 -0
  56. package/dist/driver/index.cjs +22 -0
  57. package/dist/driver/index.d.cts +7 -0
  58. package/dist/driver/index.d.ts +7 -0
  59. package/dist/driver/index.js +14 -0
  60. package/dist/driver/keyframeTiming.cjs +130 -0
  61. package/dist/driver/keyframeTiming.d.cts +18 -0
  62. package/dist/driver/keyframeTiming.d.ts +18 -0
  63. package/dist/driver/keyframeTiming.js +124 -0
  64. package/dist/driver/keyframeTimingConfig.cjs +24 -0
  65. package/dist/driver/keyframeTimingConfig.d.cts +5 -0
  66. package/dist/driver/keyframeTimingConfig.d.ts +5 -0
  67. package/dist/driver/keyframeTimingConfig.js +22 -0
  68. package/dist/driver/prepare.cjs +459 -0
  69. package/dist/driver/prepare.d.cts +4 -0
  70. package/dist/driver/prepare.d.ts +4 -0
  71. package/dist/driver/prepare.js +454 -0
  72. package/dist/driver/reference.cjs +762 -0
  73. package/dist/driver/reference.d.cts +53 -0
  74. package/dist/driver/reference.d.ts +53 -0
  75. package/dist/driver/reference.js +757 -0
  76. package/dist/driver/step.cjs +55 -0
  77. package/dist/driver/step.d.cts +9 -0
  78. package/dist/driver/step.d.ts +9 -0
  79. package/dist/driver/step.js +52 -0
  80. package/dist/driver/tiers.cjs +40 -0
  81. package/dist/driver/tiers.d.cts +2 -0
  82. package/dist/driver/tiers.d.ts +2 -0
  83. package/dist/driver/tiers.js +37 -0
  84. package/dist/driver/types.cjs +9 -0
  85. package/dist/driver/types.d.cts +68 -0
  86. package/dist/driver/types.d.ts +68 -0
  87. package/dist/driver/types.js +8 -0
  88. package/dist/external-animation-ledger.cjs +1250 -0
  89. package/dist/external-animation-ledger.d.cts +416 -0
  90. package/dist/external-animation-ledger.d.ts +416 -0
  91. package/dist/external-animation-ledger.js +1243 -0
  92. package/dist/gesture/directionLock.cjs +25 -0
  93. package/dist/gesture/directionLock.d.cts +8 -0
  94. package/dist/gesture/directionLock.d.ts +8 -0
  95. package/dist/gesture/directionLock.js +21 -0
  96. package/dist/gesture/dragConfig.cjs +634 -0
  97. package/dist/gesture/dragConfig.d.cts +298 -0
  98. package/dist/gesture/dragConfig.d.ts +298 -0
  99. package/dist/gesture/dragConfig.js +624 -0
  100. package/dist/gesture/elastic.cjs +44 -0
  101. package/dist/gesture/elastic.d.cts +4 -0
  102. package/dist/gesture/elastic.d.ts +4 -0
  103. package/dist/gesture/elastic.js +39 -0
  104. package/dist/gesture/handoffSession.cjs +161 -0
  105. package/dist/gesture/handoffSession.d.cts +35 -0
  106. package/dist/gesture/handoffSession.d.ts +35 -0
  107. package/dist/gesture/handoffSession.js +158 -0
  108. package/dist/gesture/index.cjs +37 -0
  109. package/dist/gesture/index.d.cts +12 -0
  110. package/dist/gesture/index.d.ts +12 -0
  111. package/dist/gesture/index.js +11 -0
  112. package/dist/gesture/projection.cjs +95 -0
  113. package/dist/gesture/projection.d.cts +7 -0
  114. package/dist/gesture/projection.d.ts +7 -0
  115. package/dist/gesture/projection.js +87 -0
  116. package/dist/gesture/session.cjs +162 -0
  117. package/dist/gesture/session.d.cts +29 -0
  118. package/dist/gesture/session.d.ts +29 -0
  119. package/dist/gesture/session.js +158 -0
  120. package/dist/gesture/types.cjs +5 -0
  121. package/dist/gesture/types.d.cts +13 -0
  122. package/dist/gesture/types.d.ts +13 -0
  123. package/dist/gesture/types.js +4 -0
  124. package/dist/gesture/viewportConstraints.cjs +38 -0
  125. package/dist/gesture/viewportConstraints.d.cts +6 -0
  126. package/dist/gesture/viewportConstraints.d.ts +6 -0
  127. package/dist/gesture/viewportConstraints.js +34 -0
  128. package/dist/graph.cjs +226 -0
  129. package/dist/graph.d.cts +2 -0
  130. package/dist/graph.d.ts +2 -0
  131. package/dist/graph.js +223 -0
  132. package/dist/index.cjs +140 -0
  133. package/dist/index.d.cts +33 -0
  134. package/dist/index.d.ts +33 -0
  135. package/dist/index.js +70 -0
  136. package/dist/inertia.cjs +214 -0
  137. package/dist/inertia.d.cts +53 -0
  138. package/dist/inertia.d.ts +53 -0
  139. package/dist/inertia.js +212 -0
  140. package/dist/instant.cjs +66 -0
  141. package/dist/instant.d.cts +16 -0
  142. package/dist/instant.d.ts +16 -0
  143. package/dist/instant.js +63 -0
  144. package/dist/internal-driver.cjs +81 -0
  145. package/dist/internal-driver.d.cts +19 -0
  146. package/dist/internal-driver.d.ts +19 -0
  147. package/dist/internal-driver.js +35 -0
  148. package/dist/keyframes.cjs +191 -0
  149. package/dist/keyframes.d.cts +13 -0
  150. package/dist/keyframes.d.ts +13 -0
  151. package/dist/keyframes.js +188 -0
  152. package/dist/layout/commitDetector.cjs +67 -0
  153. package/dist/layout/commitDetector.d.cts +21 -0
  154. package/dist/layout/commitDetector.d.ts +21 -0
  155. package/dist/layout/commitDetector.js +64 -0
  156. package/dist/layout/compose.cjs +67 -0
  157. package/dist/layout/compose.d.cts +30 -0
  158. package/dist/layout/compose.d.ts +30 -0
  159. package/dist/layout/compose.js +65 -0
  160. package/dist/layout/constants.cjs +13 -0
  161. package/dist/layout/constants.d.cts +6 -0
  162. package/dist/layout/constants.d.ts +6 -0
  163. package/dist/layout/constants.js +10 -0
  164. package/dist/layout/identity.cjs +700 -0
  165. package/dist/layout/identity.d.cts +67 -0
  166. package/dist/layout/identity.d.ts +67 -0
  167. package/dist/layout/identity.js +698 -0
  168. package/dist/layout/index.cjs +36 -0
  169. package/dist/layout/index.d.cts +18 -0
  170. package/dist/layout/index.d.ts +18 -0
  171. package/dist/layout/index.js +13 -0
  172. package/dist/layout/measure.cjs +81 -0
  173. package/dist/layout/measure.d.cts +43 -0
  174. package/dist/layout/measure.d.ts +43 -0
  175. package/dist/layout/measure.js +78 -0
  176. package/dist/layout/projection.cjs +99 -0
  177. package/dist/layout/projection.d.cts +23 -0
  178. package/dist/layout/projection.d.ts +23 -0
  179. package/dist/layout/projection.js +97 -0
  180. package/dist/layout/scroll.cjs +27 -0
  181. package/dist/layout/scroll.d.cts +13 -0
  182. package/dist/layout/scroll.d.ts +13 -0
  183. package/dist/layout/scroll.js +24 -0
  184. package/dist/layout/session.cjs +207 -0
  185. package/dist/layout/session.d.cts +73 -0
  186. package/dist/layout/session.d.ts +73 -0
  187. package/dist/layout/session.js +205 -0
  188. package/dist/layout/tree.cjs +826 -0
  189. package/dist/layout/tree.d.cts +70 -0
  190. package/dist/layout/tree.d.ts +70 -0
  191. package/dist/layout/tree.js +823 -0
  192. package/dist/layout/types.cjs +36 -0
  193. package/dist/layout/types.d.cts +31 -0
  194. package/dist/layout/types.d.ts +31 -0
  195. package/dist/layout/types.js +35 -0
  196. package/dist/motion-arc.cjs +184 -0
  197. package/dist/motion-arc.d.cts +78 -0
  198. package/dist/motion-arc.d.ts +78 -0
  199. package/dist/motion-arc.js +183 -0
  200. package/dist/motion-mix.cjs +205 -0
  201. package/dist/motion-mix.d.cts +3 -0
  202. package/dist/motion-mix.d.ts +3 -0
  203. package/dist/motion-mix.js +202 -0
  204. package/dist/motion-value-driver-port.cjs +636 -0
  205. package/dist/motion-value-driver-port.d.cts +406 -0
  206. package/dist/motion-value-driver-port.d.ts +406 -0
  207. package/dist/motion-value-driver-port.js +627 -0
  208. package/dist/motion-value.cjs +189 -0
  209. package/dist/motion-value.d.cts +51 -0
  210. package/dist/motion-value.d.ts +51 -0
  211. package/dist/motion-value.js +185 -0
  212. package/dist/presence/controller.cjs +657 -0
  213. package/dist/presence/controller.d.cts +6 -0
  214. package/dist/presence/controller.d.ts +6 -0
  215. package/dist/presence/controller.js +652 -0
  216. package/dist/presence/index.cjs +19 -0
  217. package/dist/presence/index.d.cts +4 -0
  218. package/dist/presence/index.d.ts +4 -0
  219. package/dist/presence/index.js +12 -0
  220. package/dist/presence/machine.cjs +50 -0
  221. package/dist/presence/machine.d.cts +10 -0
  222. package/dist/presence/machine.d.ts +10 -0
  223. package/dist/presence/machine.js +46 -0
  224. package/dist/presence/types.cjs +6 -0
  225. package/dist/presence/types.d.cts +32 -0
  226. package/dist/presence/types.d.ts +32 -0
  227. package/dist/presence/types.js +5 -0
  228. package/dist/repeat.cjs +311 -0
  229. package/dist/repeat.d.cts +174 -0
  230. package/dist/repeat.d.ts +174 -0
  231. package/dist/repeat.js +300 -0
  232. package/dist/spring.cjs +128 -0
  233. package/dist/spring.d.cts +18 -0
  234. package/dist/spring.d.ts +18 -0
  235. package/dist/spring.js +125 -0
  236. package/dist/subscriptions.cjs +74 -0
  237. package/dist/subscriptions.d.cts +19 -0
  238. package/dist/subscriptions.d.ts +19 -0
  239. package/dist/subscriptions.js +69 -0
  240. package/dist/subset/index.cjs +23 -0
  241. package/dist/subset/index.d.cts +6 -0
  242. package/dist/subset/index.d.ts +6 -0
  243. package/dist/subset/index.js +13 -0
  244. package/dist/subset/normalize.cjs +90 -0
  245. package/dist/subset/normalize.d.cts +10 -0
  246. package/dist/subset/normalize.d.ts +10 -0
  247. package/dist/subset/normalize.js +85 -0
  248. package/dist/subset/registry.cjs +259 -0
  249. package/dist/subset/registry.d.cts +25 -0
  250. package/dist/subset/registry.d.ts +25 -0
  251. package/dist/subset/registry.js +256 -0
  252. package/dist/subset/resolve.cjs +98 -0
  253. package/dist/subset/resolve.d.cts +24 -0
  254. package/dist/subset/resolve.d.ts +24 -0
  255. package/dist/subset/resolve.js +90 -0
  256. package/dist/timing.cjs +206 -0
  257. package/dist/timing.d.cts +17 -0
  258. package/dist/timing.d.ts +17 -0
  259. package/dist/timing.js +201 -0
  260. package/dist/transformTemplate.cjs +219 -0
  261. package/dist/transformTemplate.d.cts +29 -0
  262. package/dist/transformTemplate.d.ts +29 -0
  263. package/dist/transformTemplate.js +215 -0
  264. package/dist/transition.cjs +231 -0
  265. package/dist/transition.d.cts +89 -0
  266. package/dist/transition.d.ts +89 -0
  267. package/dist/transition.js +223 -0
  268. package/dist/types.cjs +4 -0
  269. package/dist/types.d.cts +175 -0
  270. package/dist/types.d.ts +175 -0
  271. package/dist/types.js +3 -0
  272. package/dist/value-types/color.cjs +220 -0
  273. package/dist/value-types/color.d.cts +19 -0
  274. package/dist/value-types/color.d.ts +19 -0
  275. package/dist/value-types/color.js +218 -0
  276. package/dist/value-types/complex.cjs +160 -0
  277. package/dist/value-types/complex.d.cts +19 -0
  278. package/dist/value-types/complex.d.ts +19 -0
  279. package/dist/value-types/complex.js +155 -0
  280. package/dist/value-types/constants.cjs +15 -0
  281. package/dist/value-types/constants.d.cts +6 -0
  282. package/dist/value-types/constants.d.ts +6 -0
  283. package/dist/value-types/constants.js +12 -0
  284. package/dist/value-types/discrete.cjs +62 -0
  285. package/dist/value-types/discrete.d.cts +4 -0
  286. package/dist/value-types/discrete.d.ts +4 -0
  287. package/dist/value-types/discrete.js +56 -0
  288. package/dist/value-types/index.cjs +59 -0
  289. package/dist/value-types/index.d.cts +14 -0
  290. package/dist/value-types/index.d.ts +14 -0
  291. package/dist/value-types/index.js +24 -0
  292. package/dist/value-types/measure-resolve.cjs +325 -0
  293. package/dist/value-types/measure-resolve.d.cts +91 -0
  294. package/dist/value-types/measure-resolve.d.ts +91 -0
  295. package/dist/value-types/measure-resolve.js +313 -0
  296. package/dist/value-types/mix.cjs +90 -0
  297. package/dist/value-types/mix.d.cts +27 -0
  298. package/dist/value-types/mix.d.ts +27 -0
  299. package/dist/value-types/mix.js +85 -0
  300. package/dist/value-types/named-colors.cjs +61 -0
  301. package/dist/value-types/named-colors.d.cts +2 -0
  302. package/dist/value-types/named-colors.d.ts +2 -0
  303. package/dist/value-types/named-colors.js +58 -0
  304. package/dist/value-types/numeric.cjs +86 -0
  305. package/dist/value-types/numeric.d.cts +16 -0
  306. package/dist/value-types/numeric.d.ts +16 -0
  307. package/dist/value-types/numeric.js +79 -0
  308. package/dist/worklet-layout/config/constants.js +39 -0
  309. package/dist/worklet-layout/layout/constants.js +11 -0
  310. package/dist/worklet-layout/layout/identity.js +699 -0
  311. package/dist/worklet-layout/layout/projection.js +98 -0
  312. package/dist/worklet-layout/layout/session.js +206 -0
  313. package/dist/worklet-layout/layout/tree.js +824 -0
  314. package/dist/worklet-layout/layout/types.js +36 -0
  315. package/dist/worklet-layout/spring.js +125 -0
  316. package/dist/worklet-layout/timing.js +201 -0
  317. package/dist/worklet-layout/transition.js +223 -0
  318. package/dist/worklet-layout.cjs +47 -0
  319. package/dist/worklet-layout.d.cts +15 -0
  320. package/dist/worklet-layout.d.ts +15 -0
  321. package/dist/worklet-layout.js +28 -0
  322. package/dist/wrap.cjs +7 -0
  323. package/dist/wrap.d.cts +1 -0
  324. package/dist/wrap.d.ts +1 -0
  325. package/dist/wrap.js +4 -0
  326. package/package.json +45 -0
@@ -0,0 +1,215 @@
1
+ 'worklet';
2
+ // @frame-path — executes inside the UI-runtime frame step; allocation-gated (REQ-DRIVER-021).
3
+ // Bounded transform-template support (T17 packet, specs/T17-TRANSFORM-TEMPLATE-BUILD-PACKET.md):
4
+ // the canonical generated-string builder (pin `motion-dom buildTransform` format and value
5
+ // typing) and the bounded parser that turns a template's RETURN string into the RN transform
6
+ // array. Grammar is exactly the canonical builder's function set; anything off-grammar fails
7
+ // loud naming the offending token — never a silent partial parse (the R13 law). Host-agnostic
8
+ // (REQ-CORE-003): no host imports.
9
+ //
10
+ // alloc-ok: frame — template composition is string-valued by pin design (motion-dom
11
+ // buildTransform allocates the composed string per frame); the parser allocates only the small
12
+ // output entry list, proportional to the entry count.
13
+ // Canonical key order (pin `transformPropOrder` restricted to the shipped transform keys — the
14
+ // same list composeTransform commits, so template and non-template composition agree).
15
+ const TEMPLATE_KEY_ORDER = [
16
+ 'perspective',
17
+ 'x',
18
+ 'y',
19
+ 'scale',
20
+ 'scaleX',
21
+ 'scaleY',
22
+ 'rotate',
23
+ 'rotateX',
24
+ 'rotateY',
25
+ 'skewX',
26
+ 'skewY',
27
+ ];
28
+ // Function name in the generated string per key (pin: translateAlias x→translateX, y→translateY).
29
+ const KEY_FUNCTION = {
30
+ perspective: 'perspective',
31
+ x: 'translateX',
32
+ y: 'translateY',
33
+ scale: 'scale',
34
+ scaleX: 'scaleX',
35
+ scaleY: 'scaleY',
36
+ rotate: 'rotate',
37
+ rotateX: 'rotateX',
38
+ rotateY: 'rotateY',
39
+ skewX: 'skewX',
40
+ skewY: 'skewY',
41
+ };
42
+ // Plain-object lookups, never Sets: worklet captures stay in the most conservative shareable
43
+ // shape — records of primitives (the composeTransform.ts law) — so serialization can never be
44
+ // the failure mode on the UI runtime.
45
+ const DEGREE_KEYS = Object.freeze({
46
+ rotate: 1,
47
+ rotateX: 1,
48
+ rotateY: 1,
49
+ skewX: 1,
50
+ skewY: 1,
51
+ });
52
+ const LENGTH_KEYS = Object.freeze({ perspective: 1, x: 1, y: 1 });
53
+ // Pin build-transform's default law: `value === (key.startsWith("scale") ? 1 : 0)`.
54
+ const SCALE_KEYS = Object.freeze({ scale: 1, scaleX: 1, scaleY: 1 });
55
+ // The values-map key name per canonical key (pin latestValues naming: transformPerspective).
56
+ const VALUES_MAP_KEY = {
57
+ perspective: 'transformPerspective',
58
+ x: 'x',
59
+ y: 'y',
60
+ scale: 'scale',
61
+ scaleX: 'scaleX',
62
+ scaleY: 'scaleY',
63
+ rotate: 'rotate',
64
+ rotateX: 'rotateX',
65
+ rotateY: 'rotateY',
66
+ skewX: 'skewX',
67
+ skewY: 'skewY',
68
+ };
69
+ function typedValueFor(key, value) {
70
+ const unit = DEGREE_KEYS[key] === 1 ? 'deg' : LENGTH_KEYS[key] === 1 ? 'px' : '';
71
+ return `${value}${unit}`;
72
+ }
73
+ function assertFiniteTemplateValue(key, value) {
74
+ if (typeof value !== 'number' || !Number.isFinite(value)) {
75
+ throw new Error(`transformTemplate values: key '${key}' must be a finite number, got ${String(value)} (T17).`);
76
+ }
77
+ }
78
+ /**
79
+ * The canonical generated string (pin `buildTransform`): `${fn}(${valueWithUnit})` joined by
80
+ * spaces in canonical order. A non-finite value fails loud naming the key.
81
+ */
82
+ export function buildTransformString(values) {
83
+ let out = '';
84
+ for (const key of TEMPLATE_KEY_ORDER) {
85
+ const value = values[key];
86
+ if (value === undefined)
87
+ continue;
88
+ assertFiniteTemplateValue(key, value);
89
+ out += `${out === '' ? '' : ' '}${KEY_FUNCTION[key]}(${typedValueFor(key, value)})`;
90
+ }
91
+ return out;
92
+ }
93
+ /**
94
+ * The pin's template call args (motion-dom build-transform, verbatim loop): the values map
95
+ * carries every PRESENT key typed (defaults INCLUDED — `!valueIsDefault || transformTemplate`);
96
+ * the generated string carries only NON-DEFAULT values in canonical order, so an all-default
97
+ * transform hands the template '' (pin `transformIsDefault ? "" : transformString`).
98
+ */
99
+ export function buildTransformTemplateArgs(values) {
100
+ const typed = {};
101
+ let generated = '';
102
+ for (const key of TEMPLATE_KEY_ORDER) {
103
+ const value = values[key];
104
+ if (value === undefined)
105
+ continue;
106
+ assertFiniteTemplateValue(key, value);
107
+ const typedValue = typedValueFor(key, value);
108
+ typed[VALUES_MAP_KEY[key]] = typedValue;
109
+ const isDefault = SCALE_KEYS[key] === 1 ? value === 1 : value === 0;
110
+ if (!isDefault) {
111
+ generated += `${generated === '' ? '' : ' '}${KEY_FUNCTION[key]}(${typedValue})`;
112
+ }
113
+ }
114
+ return { values: typed, generated };
115
+ }
116
+ // Per-function unit law: translate* take px|%; scale* are unitless; rotate*/skew* take
117
+ // deg|unitless; perspective takes px|unitless. Anything else is a named refusal.
118
+ const FUNCTION_UNITS = {
119
+ perspective: ['px', ''],
120
+ translate: ['px', '%'],
121
+ translateX: ['px', '%'],
122
+ translateY: ['px', '%'],
123
+ scale: [''],
124
+ scaleX: [''],
125
+ scaleY: [''],
126
+ rotate: ['deg', ''],
127
+ rotateX: ['deg', ''],
128
+ rotateY: ['deg', ''],
129
+ skewX: ['deg', ''],
130
+ skewY: ['deg', ''],
131
+ };
132
+ const ENTRY_NAME = {
133
+ perspective: 'perspective',
134
+ translateX: 'translateX',
135
+ translateY: 'translateY',
136
+ scale: 'scale',
137
+ scaleX: 'scaleX',
138
+ scaleY: 'scaleY',
139
+ rotate: 'rotate',
140
+ rotateX: 'rotateX',
141
+ rotateY: 'rotateY',
142
+ skewX: 'skewX',
143
+ skewY: 'skewY',
144
+ };
145
+ const VALUE_RE = /^(-?(?:\d+(?:\.\d+)?|\.\d+))(px|%|deg)?$/;
146
+ function fail(templateOutput, reason) {
147
+ throw new Error(`transformTemplate output '${templateOutput}': ${reason} (T17 bounded grammar).`);
148
+ }
149
+ function parseValue(templateOutput, fn, raw) {
150
+ const m = VALUE_RE.exec(raw.trim());
151
+ if (m === null) {
152
+ fail(templateOutput, `unparseable value '${raw}' for ${fn}`);
153
+ }
154
+ const [, numeral, rawUnit] = m;
155
+ const unit = (rawUnit ?? '');
156
+ const allowed = FUNCTION_UNITS[fn];
157
+ if (!allowed.includes(unit)) {
158
+ fail(templateOutput, `unit '${unit || '(none)'}' is not valid for ${fn}`);
159
+ }
160
+ // Percent translate entries ride RN's percent-string form. Angle entries commit as RN degree
161
+ // STRINGS — the shipped composeTransform output shape (RN types the rotate/skew family
162
+ // string-typed; a bare number is not a valid entry). A unitless angle is degrees by the pin's
163
+ // getValueAsType law. Everything else commits numeric.
164
+ if (unit === '%')
165
+ return `${numeral}%`;
166
+ if (allowed.includes('deg'))
167
+ return `${numeral}deg`;
168
+ return Number(numeral);
169
+ }
170
+ /**
171
+ * Parse a template's RETURN string into the ordered RN transform array. The grammar is the
172
+ * canonical builder's function set with px/%/deg/unitless values; `translate` takes 1-2 args
173
+ * (comma or space separated). Anything else throws naming the offending token.
174
+ */
175
+ export function parseTransformTemplateOutput(templateOutput) {
176
+ const out = [];
177
+ let rest = templateOutput.trim();
178
+ while (rest.length > 0) {
179
+ const open = rest.indexOf('(');
180
+ const fn = open === -1 ? rest.trim() : rest.slice(0, open).trim();
181
+ if (open === -1 || fn === '' || /\s/.test(fn)) {
182
+ fail(templateOutput, `malformed token '${fn}' — expected fn(args)`);
183
+ }
184
+ if (!(fn in FUNCTION_UNITS) && fn !== 'translate') {
185
+ fail(templateOutput, `transform function '${fn}' is outside the bounded grammar`);
186
+ }
187
+ const close = rest.indexOf(')', open);
188
+ if (close === -1) {
189
+ fail(templateOutput, `unbalanced parens near '${fn}('`);
190
+ }
191
+ const argsRaw = rest.slice(open + 1, close);
192
+ const args = argsRaw.includes(',')
193
+ ? argsRaw.split(',').map((a) => a.trim())
194
+ : argsRaw.trim() === ''
195
+ ? []
196
+ : argsRaw.trim().split(/\s+/);
197
+ if (fn === 'translate') {
198
+ if (args.length === 0 || args.length > 2) {
199
+ fail(templateOutput, `translate takes 1 or 2 args, got ${args.length}`);
200
+ }
201
+ out.push({ translateX: parseValue(templateOutput, 'translate', args[0]) });
202
+ if (args.length === 2) {
203
+ out.push({ translateY: parseValue(templateOutput, 'translate', args[1]) });
204
+ }
205
+ }
206
+ else {
207
+ if (args.length !== 1) {
208
+ fail(templateOutput, `${fn} takes exactly 1 arg, got ${args.length}`);
209
+ }
210
+ out.push({ [ENTRY_NAME[fn]]: parseValue(templateOutput, fn, args[0]) });
211
+ }
212
+ rest = rest.slice(close + 1).trim();
213
+ }
214
+ return out;
215
+ }
@@ -0,0 +1,231 @@
1
+ "use strict";
2
+ // @frame-path — executes inside the UI-runtime frame step; allocation-gated (REQ-DRIVER-021).
3
+ // Transition-config resolution (SPEC-SPRING REQ-SPRING-004/005/006/007/012). Turns a user transition
4
+ // config into concrete spring physics + the flags the generator/settle layers need. Host-agnostic
5
+ // (REQ-CORE-003): imports nothing from motion/react. Numerics are pinned to motion@12.42.2 and proven
6
+ // by resolution parity in transition.test.ts.
7
+ //
8
+ // findSpring (REQ-SPRING-004) uses the DETERMINISTIC closed form, not motion's 12-iteration
9
+ // Newton-Raphson: for velocity-free duration springs the closed form is the exact analytic root of
10
+ // motion's envelope, so it reproduces motion's resolution (proven to ~5e-5 relative in the tests) with
11
+ // no iteration.
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.DRAG_INERTIA_DEFAULTS = void 0;
14
+ exports.resolveSpring = resolveSpring;
15
+ exports.resolveSpringGenerator = resolveSpringGenerator;
16
+ exports.retargetSpring = retargetSpring;
17
+ exports.springKeyframeCountRefusal = springKeyframeCountRefusal;
18
+ exports.getDefaultTransition = getDefaultTransition;
19
+ exports.dragInertiaBounce = dragInertiaBounce;
20
+ const spring_1 = require("./spring.cjs");
21
+ // Pinned defaults (REQ-SPRING-003 springDefaults).
22
+ const DEFAULT_PHYSICS = { stiffness: 100, damping: 10, mass: 1 };
23
+ const DEFAULT_DURATION_MS = 800;
24
+ const DEFAULT_BOUNCE = 0.3;
25
+ const SAFE_MIN = 0.001;
26
+ const clamp = (lo, hi, v) => Math.max(lo, Math.min(hi, v));
27
+ // REQ-SPRING-004 critical-root constant: the u solving e^(−u)·(u+1) = SAFE_MIN. Derived from SAFE_MIN
28
+ // by Newton (NOT hard-copied 9.2334…) so it stays consistent if SAFE_MIN changes.
29
+ const CRITICAL_ROOT = (() => {
30
+ let u = 9;
31
+ for (let i = 0; i < 40; i++)
32
+ u -= (Math.exp(-u) * (u + 1) - SAFE_MIN) / (-u * Math.exp(-u));
33
+ return u;
34
+ })();
35
+ // REQ-SPRING-004: duration+bounce → physics via the closed-form undamped frequency (velocity = 0).
36
+ // alloc-ok: lifecycle-edge — duration→physics resolution at command time.
37
+ function findSpring(durationMs, bounce, mass) {
38
+ const z = clamp(0.05, 1, 1 - bounce);
39
+ const tSec = clamp(0.01, 10, durationMs / 1000);
40
+ const omega = z < 1 ? Math.log(z / (SAFE_MIN * Math.sqrt(1 - z * z))) / (z * tSec) : CRITICAL_ROOT / tSec;
41
+ if (Number.isNaN(omega)) {
42
+ return { ...DEFAULT_PHYSICS, mass, durationMs: tSec * 1000 };
43
+ }
44
+ const stiffness = omega * omega * mass;
45
+ return { stiffness, damping: z * 2 * Math.sqrt(mass * stiffness), mass, durationMs: tSec * 1000 };
46
+ }
47
+ // REQ-SPRING-005: visualDuration+bounce → the DISTINCT path (no findSpring). bounce defaults to 0 here
48
+ // (intentional asymmetry with REQ-SPRING-004's 0.3). The 1.2 factor is load-bearing.
49
+ // alloc-ok: lifecycle-edge — visualDuration→physics resolution at command time.
50
+ function visualDurationSpring(visualDuration, bounce, mass) {
51
+ const root = (2 * Math.PI) / (visualDuration * 1.2);
52
+ const stiffness = root * root;
53
+ const damping = 2 * clamp(0.05, 1, 1 - (bounce ?? 0)) * Math.sqrt(stiffness);
54
+ return { stiffness, damping, mass };
55
+ }
56
+ const hasPhysicsKey = (c) => c.stiffness !== undefined || c.damping !== undefined || c.mass !== undefined;
57
+ /**
58
+ * Resolve a spring transition config to concrete physics + carry/settle flags (REQ-SPRING-006
59
+ * precedence). Presence is tested on `!== undefined`.
60
+ */
61
+ // alloc-ok: lifecycle-edge — config resolution at command time (REQ-SPRING-006 precedence).
62
+ function resolveSpring(config) {
63
+ const mass = config.mass ?? DEFAULT_PHYSICS.mass;
64
+ // Any physics key ⇒ physics used directly; the entire duration family is ignored; velocity carries.
65
+ if (hasPhysicsKey(config)) {
66
+ return {
67
+ physics: {
68
+ stiffness: config.stiffness ?? DEFAULT_PHYSICS.stiffness,
69
+ damping: config.damping ?? DEFAULT_PHYSICS.damping,
70
+ mass,
71
+ },
72
+ carryVelocity: true,
73
+ isResolvedFromDuration: false,
74
+ calculatedDuration: null,
75
+ };
76
+ }
77
+ // Duration family — velocity is ZEROED (REQ-SPRING-007). visualDuration wins over duration, and a
78
+ // visualDuration-only config still takes the vd path (REQ-SPRING-006, post-plan-030); it MUST NOT
79
+ // fall back to default physics.
80
+ if (config.visualDuration !== undefined) {
81
+ return {
82
+ physics: visualDurationSpring(config.visualDuration, config.bounce, mass),
83
+ carryVelocity: false,
84
+ isResolvedFromDuration: false, // vd does NOT set the duration flag (REQ-SPRING-011)
85
+ calculatedDuration: null,
86
+ };
87
+ }
88
+ if (config.duration !== undefined || config.bounce !== undefined) {
89
+ const fs = findSpring(config.duration ?? DEFAULT_DURATION_MS, config.bounce ?? DEFAULT_BOUNCE, mass);
90
+ return {
91
+ physics: { stiffness: fs.stiffness, damping: fs.damping, mass: fs.mass },
92
+ carryVelocity: false,
93
+ isResolvedFromDuration: true,
94
+ calculatedDuration: fs.durationMs,
95
+ };
96
+ }
97
+ // Bare `{type:'spring'}` / empty ⇒ REQ-SPRING-003 defaults (100/10/1); a physics spring (carries).
98
+ return {
99
+ physics: { ...DEFAULT_PHYSICS },
100
+ carryVelocity: true,
101
+ isResolvedFromDuration: false,
102
+ calculatedDuration: null,
103
+ };
104
+ }
105
+ /**
106
+ * Build a `GeneratorFactory` from a target + config, honoring velocity carry/zero (REQ-SPRING-007).
107
+ * Duration/visualDuration springs drop the seed's incoming velocity; physics springs keep it —
108
+ * unless the config carries an AUTHORED `velocity`, which replaces it (REQ-API-053, T21): the pin's
109
+ * animateMotionValue spreads the authored transition over the live-velocity default
110
+ * (motion-dom@12.42.2 motion-value.ts:45-50), so the authored number wins on every start.
111
+ */
112
+ // alloc-ok: lifecycle-edge — factory construction at command time; sampling stays allocation-free.
113
+ function resolveSpringGenerator(target, config) {
114
+ const resolved = resolveSpring(config);
115
+ // findSpring (duration) springs settle at t ≥ calculatedDuration; physics/visualDuration settle by
116
+ // threshold (settleDuration null). (REQ-SPRING-011)
117
+ const factory = (0, spring_1.springGenerator)(target, resolved.physics, {
118
+ settleDuration: resolved.calculatedDuration,
119
+ ...(config.restSpeed !== undefined ? { restSpeed: config.restSpeed } : {}),
120
+ ...(config.restDelta !== undefined ? { restDelta: config.restDelta } : {}),
121
+ });
122
+ if (resolved.carryVelocity) {
123
+ const authoredVelocity = config.velocity;
124
+ if (authoredVelocity === undefined)
125
+ return factory;
126
+ // alloc-ok: lifecycle-edge — the authored-velocity reseed wrapper runs at generator construction.
127
+ return (seed) => factory({ from: seed.from, velocity: authoredVelocity });
128
+ }
129
+ // alloc-ok: lifecycle-edge — the zero-velocity reseed wrapper runs at generator construction.
130
+ return (seed) => factory({ from: seed.from, velocity: 0 });
131
+ }
132
+ /**
133
+ * Interrupt/retarget (REQ-SPRING-009): build a new generator for `newTarget` from the OUTGOING
134
+ * generator's analytic state at `atMs` — its exact value and analytic velocity (preferred over any
135
+ * finite-diff, which avoids systematic velocity loss at high frame rates). Whether that incoming
136
+ * velocity carries (physics), is replaced by an authored config `velocity` (REQ-API-053), or is
137
+ * zeroed (duration/visualDuration) is decided by
138
+ * `resolveSpringGenerator` (REQ-SPRING-007). The result's `value(0)` equals the outgoing `value(atMs)`
139
+ * exactly — no teleport, no velocity reset. The graph's own interruption seam does the equivalent via
140
+ * `motionValue.getVelocity()`; this is the explicit spring-layer helper for consumers driving
141
+ * generators directly (e.g. the Reanimated driver).
142
+ */
143
+ // alloc-ok: lifecycle-edge — interruption/retarget construction; samples the outgoing generator
144
+ // once, then builds the successor.
145
+ function retargetSpring(outgoing, atMs, newTarget, config) {
146
+ const at = outgoing.sample(atMs);
147
+ return resolveSpringGenerator(newTarget, config)({ from: at.value, velocity: at.velocity });
148
+ }
149
+ // REQ-SPRING-012 getDefaultTransition selection table. transformProps mirrors motion's set.
150
+ const TRANSFORM_PROPS = new Set([
151
+ 'transformPerspective',
152
+ 'x',
153
+ 'y',
154
+ 'z',
155
+ 'translateX',
156
+ 'translateY',
157
+ 'translateZ',
158
+ 'scale',
159
+ 'scaleX',
160
+ 'scaleY',
161
+ 'rotate',
162
+ 'rotateX',
163
+ 'rotateY',
164
+ 'rotateZ',
165
+ 'skew',
166
+ 'skewX',
167
+ 'skewY',
168
+ 'pathRotation',
169
+ ]);
170
+ // R8-F1: a spring interpolates EXACTLY two keyframes (origin → target); the pinned Motion throws
171
+ // `spring-two-frames` for any other count. The ONE predicate the reference driver's
172
+ // springKeyframeGenerator throws from AND the native controller PRE-VALIDATES with before issuing any
173
+ // driver command (so a rejected multi-command mount/update mutates nothing — atomicity, review major
174
+ // 36). The worklet driver mirrors the SAME message inline on its 'worklet' path. Returns the loud
175
+ // refusal for a non-two count, else null.
176
+ // alloc-ok: lifecycle-edge — a refusal built at command/pre-validation time, never per frame.
177
+ function springKeyframeCountRefusal(count) {
178
+ if (count === 2)
179
+ return null;
180
+ return new Error(`a spring transition cannot interpolate through ${count} keyframes — a spring animates exactly ` +
181
+ 'two (origin → target). Keyframe index 2 (the successor) is unreachable; use a tween for a ' +
182
+ 'multi-keyframe array (REQ-API-033, R8-F1).');
183
+ }
184
+ /**
185
+ * Default transition per property when none is specified (REQ-SPRING-012), keyframe-count-aware to
186
+ * match the pinned `motion-dom` `getDefaultTransition(valueKey, { keyframes })`
187
+ * (default-transitions.ts): MORE than two keyframes → an 800ms keyframes transition (regardless of
188
+ * property); otherwise a transform prop gets an underdamped spring (scale: critically-damped 550,
189
+ * damping 30 for a non-zero target and 2√550 at exactly 0; other transforms: 500/25), and every
190
+ * other property gets the 300ms shallow-browser tween. A scalar animation is the two-keyframe case
191
+ * (`[from, target]`); the last keyframe drives the scale-at-zero branch (Motion reads `keyframes[1]`).
192
+ */
193
+ // alloc-ok: lifecycle-edge — per-property default selection at command time.
194
+ function getDefaultTransition(valueKey, keyframes) {
195
+ if (keyframes.length > 2) {
196
+ return { type: 'keyframes', duration: 0.8 };
197
+ }
198
+ if (TRANSFORM_PROPS.has(valueKey)) {
199
+ if (valueKey.startsWith('scale')) {
200
+ const last = keyframes[keyframes.length - 1];
201
+ const target = typeof last === 'number' ? last : 0;
202
+ return {
203
+ type: 'spring',
204
+ stiffness: 550,
205
+ damping: target === 0 ? 2 * Math.sqrt(550) : 30,
206
+ restSpeed: 10,
207
+ };
208
+ }
209
+ return { type: 'spring', stiffness: 500, damping: 25, restSpeed: 10 };
210
+ }
211
+ return { type: 'keyframes', ease: [0.25, 0.1, 0.35, 1], duration: 0.3 };
212
+ }
213
+ // Pinned drag-layer physics (startAnimation spread: timeConstant 750, restDelta 1, restSpeed 10;
214
+ // motion-dom inertia `power` default 0.8 — single-sourced with PROJECTION_POWER's pin note).
215
+ exports.DRAG_INERTIA_DEFAULTS = {
216
+ power: 0.8,
217
+ timeConstant: 750,
218
+ restDelta: 1,
219
+ restSpeed: 10,
220
+ };
221
+ // The pin's elastic-conditional boundary-spring pairs (VisualElementDragControls: dragElastic
222
+ // truthy → 200/40, falsy → 1e6/1e7 "overdamp the boundary spring"). dragTransition overrides.
223
+ // Shared frozen constants (never a per-call literal — the frame-path allocation law, REQ-DRIVER-021).
224
+ const ELASTIC_BOUNDARY_BOUNCE = Object.freeze({ bounceStiffness: 200, bounceDamping: 40 });
225
+ const RIGID_BOUNDARY_BOUNCE = Object.freeze({
226
+ bounceStiffness: 1000000,
227
+ bounceDamping: 10000000,
228
+ });
229
+ function dragInertiaBounce(elastic) {
230
+ return elastic !== undefined && elastic > 0 ? ELASTIC_BOUNDARY_BOUNCE : RIGID_BOUNDARY_BOUNCE;
231
+ }
@@ -0,0 +1,89 @@
1
+ import type { SpringPhysics } from "./spring.cjs";
2
+ import type { Generator, GeneratorFactory } from "./types.cjs";
3
+ import type { Transition } from "./component/types.cjs";
4
+ export interface SpringConfig {
5
+ stiffness?: number;
6
+ damping?: number;
7
+ mass?: number;
8
+ duration?: number;
9
+ bounce?: number;
10
+ visualDuration?: number;
11
+ velocity?: number;
12
+ restSpeed?: number;
13
+ restDelta?: number;
14
+ }
15
+ export interface ResolvedSpring {
16
+ physics: SpringPhysics;
17
+ carryVelocity: boolean;
18
+ isResolvedFromDuration: boolean;
19
+ calculatedDuration: number | null;
20
+ }
21
+ /**
22
+ * Resolve a spring transition config to concrete physics + carry/settle flags (REQ-SPRING-006
23
+ * precedence). Presence is tested on `!== undefined`.
24
+ */
25
+ export declare function resolveSpring(config: SpringConfig): ResolvedSpring;
26
+ /**
27
+ * Build a `GeneratorFactory` from a target + config, honoring velocity carry/zero (REQ-SPRING-007).
28
+ * Duration/visualDuration springs drop the seed's incoming velocity; physics springs keep it —
29
+ * unless the config carries an AUTHORED `velocity`, which replaces it (REQ-API-053, T21): the pin's
30
+ * animateMotionValue spreads the authored transition over the live-velocity default
31
+ * (motion-dom@12.42.2 motion-value.ts:45-50), so the authored number wins on every start.
32
+ */
33
+ export declare function resolveSpringGenerator(target: number, config: SpringConfig): GeneratorFactory;
34
+ /**
35
+ * Interrupt/retarget (REQ-SPRING-009): build a new generator for `newTarget` from the OUTGOING
36
+ * generator's analytic state at `atMs` — its exact value and analytic velocity (preferred over any
37
+ * finite-diff, which avoids systematic velocity loss at high frame rates). Whether that incoming
38
+ * velocity carries (physics), is replaced by an authored config `velocity` (REQ-API-053), or is
39
+ * zeroed (duration/visualDuration) is decided by
40
+ * `resolveSpringGenerator` (REQ-SPRING-007). The result's `value(0)` equals the outgoing `value(atMs)`
41
+ * exactly — no teleport, no velocity reset. The graph's own interruption seam does the equivalent via
42
+ * `motionValue.getVelocity()`; this is the explicit spring-layer helper for consumers driving
43
+ * generators directly (e.g. the Reanimated driver).
44
+ */
45
+ export declare function retargetSpring(outgoing: Generator, atMs: number, newTarget: number, config: SpringConfig): Generator;
46
+ export declare function springKeyframeCountRefusal(count: number): Error | null;
47
+ export type DefaultTransition = ({
48
+ type: 'spring';
49
+ stiffness: number;
50
+ damping: number;
51
+ restSpeed: number;
52
+ } & Pick<Transition, 'delay' | 'repeat' | 'repeatType' | 'repeatDelay'>) | ({
53
+ type: 'keyframes';
54
+ ease?: readonly [number, number, number, number];
55
+ duration: number;
56
+ } & Pick<Transition, 'delay' | 'repeat' | 'repeatType' | 'repeatDelay'>);
57
+ /**
58
+ * Default transition per property when none is specified (REQ-SPRING-012), keyframe-count-aware to
59
+ * match the pinned `motion-dom` `getDefaultTransition(valueKey, { keyframes })`
60
+ * (default-transitions.ts): MORE than two keyframes → an 800ms keyframes transition (regardless of
61
+ * property); otherwise a transform prop gets an underdamped spring (scale: critically-damped 550,
62
+ * damping 30 for a non-zero target and 2√550 at exactly 0; other transforms: 500/25), and every
63
+ * other property gets the 300ms shallow-browser tween. A scalar animation is the two-keyframe case
64
+ * (`[from, target]`); the last keyframe drives the scale-at-zero branch (Motion reads `keyframes[1]`).
65
+ */
66
+ export declare function getDefaultTransition(valueKey: string, keyframes: readonly (number | null)[]): DefaultTransition;
67
+ export interface InertiaTransition {
68
+ readonly type: 'inertia';
69
+ /** Pinned drag-layer defaults (VisualElementDragControls.startAnimation); all fields resolved */
70
+ readonly power: number;
71
+ readonly timeConstant: number;
72
+ readonly bounceStiffness: number;
73
+ readonly bounceDamping: number;
74
+ readonly restDelta: number;
75
+ readonly restSpeed: number;
76
+ /** Constraint bounds for the boundary spring; ±Infinity sentinels are legal (open sides). */
77
+ readonly min?: number;
78
+ readonly max?: number;
79
+ }
80
+ export declare const DRAG_INERTIA_DEFAULTS: {
81
+ readonly power: 0.8;
82
+ readonly timeConstant: 750;
83
+ readonly restDelta: 1;
84
+ readonly restSpeed: 10;
85
+ };
86
+ export declare function dragInertiaBounce(elastic: number | undefined): {
87
+ readonly bounceStiffness: number;
88
+ readonly bounceDamping: number;
89
+ };
@@ -0,0 +1,89 @@
1
+ import type { SpringPhysics } from "./spring.js";
2
+ import type { Generator, GeneratorFactory } from "./types.js";
3
+ import type { Transition } from "./component/types.js";
4
+ export interface SpringConfig {
5
+ stiffness?: number;
6
+ damping?: number;
7
+ mass?: number;
8
+ duration?: number;
9
+ bounce?: number;
10
+ visualDuration?: number;
11
+ velocity?: number;
12
+ restSpeed?: number;
13
+ restDelta?: number;
14
+ }
15
+ export interface ResolvedSpring {
16
+ physics: SpringPhysics;
17
+ carryVelocity: boolean;
18
+ isResolvedFromDuration: boolean;
19
+ calculatedDuration: number | null;
20
+ }
21
+ /**
22
+ * Resolve a spring transition config to concrete physics + carry/settle flags (REQ-SPRING-006
23
+ * precedence). Presence is tested on `!== undefined`.
24
+ */
25
+ export declare function resolveSpring(config: SpringConfig): ResolvedSpring;
26
+ /**
27
+ * Build a `GeneratorFactory` from a target + config, honoring velocity carry/zero (REQ-SPRING-007).
28
+ * Duration/visualDuration springs drop the seed's incoming velocity; physics springs keep it —
29
+ * unless the config carries an AUTHORED `velocity`, which replaces it (REQ-API-053, T21): the pin's
30
+ * animateMotionValue spreads the authored transition over the live-velocity default
31
+ * (motion-dom@12.42.2 motion-value.ts:45-50), so the authored number wins on every start.
32
+ */
33
+ export declare function resolveSpringGenerator(target: number, config: SpringConfig): GeneratorFactory;
34
+ /**
35
+ * Interrupt/retarget (REQ-SPRING-009): build a new generator for `newTarget` from the OUTGOING
36
+ * generator's analytic state at `atMs` — its exact value and analytic velocity (preferred over any
37
+ * finite-diff, which avoids systematic velocity loss at high frame rates). Whether that incoming
38
+ * velocity carries (physics), is replaced by an authored config `velocity` (REQ-API-053), or is
39
+ * zeroed (duration/visualDuration) is decided by
40
+ * `resolveSpringGenerator` (REQ-SPRING-007). The result's `value(0)` equals the outgoing `value(atMs)`
41
+ * exactly — no teleport, no velocity reset. The graph's own interruption seam does the equivalent via
42
+ * `motionValue.getVelocity()`; this is the explicit spring-layer helper for consumers driving
43
+ * generators directly (e.g. the Reanimated driver).
44
+ */
45
+ export declare function retargetSpring(outgoing: Generator, atMs: number, newTarget: number, config: SpringConfig): Generator;
46
+ export declare function springKeyframeCountRefusal(count: number): Error | null;
47
+ export type DefaultTransition = ({
48
+ type: 'spring';
49
+ stiffness: number;
50
+ damping: number;
51
+ restSpeed: number;
52
+ } & Pick<Transition, 'delay' | 'repeat' | 'repeatType' | 'repeatDelay'>) | ({
53
+ type: 'keyframes';
54
+ ease?: readonly [number, number, number, number];
55
+ duration: number;
56
+ } & Pick<Transition, 'delay' | 'repeat' | 'repeatType' | 'repeatDelay'>);
57
+ /**
58
+ * Default transition per property when none is specified (REQ-SPRING-012), keyframe-count-aware to
59
+ * match the pinned `motion-dom` `getDefaultTransition(valueKey, { keyframes })`
60
+ * (default-transitions.ts): MORE than two keyframes → an 800ms keyframes transition (regardless of
61
+ * property); otherwise a transform prop gets an underdamped spring (scale: critically-damped 550,
62
+ * damping 30 for a non-zero target and 2√550 at exactly 0; other transforms: 500/25), and every
63
+ * other property gets the 300ms shallow-browser tween. A scalar animation is the two-keyframe case
64
+ * (`[from, target]`); the last keyframe drives the scale-at-zero branch (Motion reads `keyframes[1]`).
65
+ */
66
+ export declare function getDefaultTransition(valueKey: string, keyframes: readonly (number | null)[]): DefaultTransition;
67
+ export interface InertiaTransition {
68
+ readonly type: 'inertia';
69
+ /** Pinned drag-layer defaults (VisualElementDragControls.startAnimation); all fields resolved */
70
+ readonly power: number;
71
+ readonly timeConstant: number;
72
+ readonly bounceStiffness: number;
73
+ readonly bounceDamping: number;
74
+ readonly restDelta: number;
75
+ readonly restSpeed: number;
76
+ /** Constraint bounds for the boundary spring; ±Infinity sentinels are legal (open sides). */
77
+ readonly min?: number;
78
+ readonly max?: number;
79
+ }
80
+ export declare const DRAG_INERTIA_DEFAULTS: {
81
+ readonly power: 0.8;
82
+ readonly timeConstant: 750;
83
+ readonly restDelta: 1;
84
+ readonly restSpeed: 10;
85
+ };
86
+ export declare function dragInertiaBounce(elastic: number | undefined): {
87
+ readonly bounceStiffness: number;
88
+ readonly bounceDamping: number;
89
+ };