@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,36 @@
1
+ "use strict";
2
+ // @frame-path — executes inside the UI-runtime frame step; allocation-gated (REQ-DRIVER-021).
3
+ // SPEC-LAYOUT §2 — the plain geometric data the projection engine operates on. Host-agnostic: a `Rect` is a
4
+ // bounding box in its projection frame, fed in by the host measurement adapter as plain numbers; `core` never
5
+ // imports a Fabric measure API (REQ-CORE-003). Projection sessions may operate in any caller-chosen coherent
6
+ // frame; layout identity is stricter and accepts only branded common/window-space rects so cross-container
7
+ // FLIP cannot accidentally compare parent-relative coordinates (REQ-LAYOUT-020). A `Transform` is the
8
+ // transform-ONLY correction the substrate executes — translate + scale, no rotation/skew at M1 (the FLIP
9
+ // correction never mutates layout-authoritative style, REQ-LAYOUT-001).
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.toWindowSpaceRect = toWindowSpaceRect;
12
+ const WINDOW_SPACE_RECT = Symbol('WindowSpaceRect');
13
+ function requireFiniteWindowSpaceField(rect, field) {
14
+ const value = rect[field];
15
+ if (!Number.isFinite(value)) {
16
+ throw new Error(`layout identity: window-space rect field '${field}' is ${JSON.stringify(value)}; ` +
17
+ 'a finite number is required before entering the projection registry.');
18
+ }
19
+ return value;
20
+ }
21
+ /**
22
+ * Brand a host-validated common-space measurement for the layoutId registry. Host bindings own the
23
+ * measurement primitive; core owns the unrepresentable-if-raw registry contract.
24
+ */
25
+ // alloc-ok: js-thread — measure-commit conversion on the JS side (onLayout path), never per frame.
26
+ function toWindowSpaceRect(rect) {
27
+ const x = requireFiniteWindowSpaceField(rect, 'x');
28
+ const y = requireFiniteWindowSpaceField(rect, 'y');
29
+ const width = requireFiniteWindowSpaceField(rect, 'width');
30
+ const height = requireFiniteWindowSpaceField(rect, 'height');
31
+ if (width <= 0 || height <= 0) {
32
+ throw new Error(`layout identity: window-space rect dimensions must be positive before projection ` +
33
+ `(width=${width}, height=${height}).`);
34
+ }
35
+ return { x, y, width, height };
36
+ }
@@ -0,0 +1,31 @@
1
+ declare const WINDOW_SPACE_RECT: unique symbol;
2
+ /** A host bounding rect (top-left origin) in its projection frame. All units are px. */
3
+ export interface Rect {
4
+ readonly x: number;
5
+ readonly y: number;
6
+ readonly width: number;
7
+ readonly height: number;
8
+ }
9
+ /** A rect already converted into the common layoutId projection frame. */
10
+ export type WindowSpaceRect = Rect & {
11
+ readonly [WINDOW_SPACE_RECT]: true;
12
+ };
13
+ /**
14
+ * Brand a host-validated common-space measurement for the layoutId registry. Host bindings own the
15
+ * measurement primitive; core owns the unrepresentable-if-raw registry contract.
16
+ */
17
+ export declare function toWindowSpaceRect(rect: Rect): WindowSpaceRect;
18
+ /** A transform-only layout correction (translate + scale about the rect's top-left). No rotation/skew (M1). */
19
+ export interface Transform {
20
+ readonly translateX: number;
21
+ readonly translateY: number;
22
+ readonly scaleX: number;
23
+ readonly scaleY: number;
24
+ }
25
+ /**
26
+ * A stable layout-identity token — the binding key for a measurement (REQ-LAYOUT-016). NOT a raw host view
27
+ * tag: Fabric recycles and reuses tags, so identity is carried by this token and re-validated immediately
28
+ * before a transform applies. Opaque string at M1.
29
+ */
30
+ export type LayoutIdToken = string;
31
+ export {};
@@ -0,0 +1,31 @@
1
+ declare const WINDOW_SPACE_RECT: unique symbol;
2
+ /** A host bounding rect (top-left origin) in its projection frame. All units are px. */
3
+ export interface Rect {
4
+ readonly x: number;
5
+ readonly y: number;
6
+ readonly width: number;
7
+ readonly height: number;
8
+ }
9
+ /** A rect already converted into the common layoutId projection frame. */
10
+ export type WindowSpaceRect = Rect & {
11
+ readonly [WINDOW_SPACE_RECT]: true;
12
+ };
13
+ /**
14
+ * Brand a host-validated common-space measurement for the layoutId registry. Host bindings own the
15
+ * measurement primitive; core owns the unrepresentable-if-raw registry contract.
16
+ */
17
+ export declare function toWindowSpaceRect(rect: Rect): WindowSpaceRect;
18
+ /** A transform-only layout correction (translate + scale about the rect's top-left). No rotation/skew (M1). */
19
+ export interface Transform {
20
+ readonly translateX: number;
21
+ readonly translateY: number;
22
+ readonly scaleX: number;
23
+ readonly scaleY: number;
24
+ }
25
+ /**
26
+ * A stable layout-identity token — the binding key for a measurement (REQ-LAYOUT-016). NOT a raw host view
27
+ * tag: Fabric recycles and reuses tags, so identity is carried by this token and re-validated immediately
28
+ * before a transform applies. Opaque string at M1.
29
+ */
30
+ export type LayoutIdToken = string;
31
+ export {};
@@ -0,0 +1,35 @@
1
+ // @frame-path — executes inside the UI-runtime frame step; allocation-gated (REQ-DRIVER-021).
2
+ // SPEC-LAYOUT §2 — the plain geometric data the projection engine operates on. Host-agnostic: a `Rect` is a
3
+ // bounding box in its projection frame, fed in by the host measurement adapter as plain numbers; `core` never
4
+ // imports a Fabric measure API (REQ-CORE-003). Projection sessions may operate in any caller-chosen coherent
5
+ // frame; layout identity is stricter and accepts only branded common/window-space rects so cross-container
6
+ // FLIP cannot accidentally compare parent-relative coordinates (REQ-LAYOUT-020). A `Transform` is the
7
+ // transform-ONLY correction the substrate executes — translate + scale, no rotation/skew at M1 (the FLIP
8
+ // correction never mutates layout-authoritative style, REQ-LAYOUT-001).
9
+ const WINDOW_SPACE_RECT = Symbol('WindowSpaceRect');
10
+ function requireFiniteWindowSpaceField(rect, field) {
11
+ 'worklet';
12
+ const value = rect[field];
13
+ if (!Number.isFinite(value)) {
14
+ throw new Error(`layout identity: window-space rect field '${field}' is ${JSON.stringify(value)}; ` +
15
+ 'a finite number is required before entering the projection registry.');
16
+ }
17
+ return value;
18
+ }
19
+ /**
20
+ * Brand a host-validated common-space measurement for the layoutId registry. Host bindings own the
21
+ * measurement primitive; core owns the unrepresentable-if-raw registry contract.
22
+ */
23
+ // alloc-ok: js-thread — measure-commit conversion on the JS side (onLayout path), never per frame.
24
+ export function toWindowSpaceRect(rect) {
25
+ 'worklet';
26
+ const x = requireFiniteWindowSpaceField(rect, 'x');
27
+ const y = requireFiniteWindowSpaceField(rect, 'y');
28
+ const width = requireFiniteWindowSpaceField(rect, 'width');
29
+ const height = requireFiniteWindowSpaceField(rect, 'height');
30
+ if (width <= 0 || height <= 0) {
31
+ throw new Error(`layout identity: window-space rect dimensions must be positive before projection ` +
32
+ `(width=${width}, height=${height}).`);
33
+ }
34
+ return { x, y, width, height };
35
+ }
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+ // REQ-API-059 — pin-faithful parametric arc (motion-dom animation/utils/arc.ts at 12.42.2).
3
+ // Host-agnostic: atan2 + wrap only. `sampleArcPoint` is the UI-runtime sampler (resolved
4
+ // geometry, no sticky closure). `arc()` holds the auto-direction continuity closure JS-side.
5
+ // `transition.layout.path` is NOT this module (packet F3).
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.NATIVE_ARC_BRAND = void 0;
8
+ exports.computeArcControlPointInto = computeArcControlPointInto;
9
+ exports.sampleArcPointInto = sampleArcPointInto;
10
+ exports.sampleArcPoint = sampleArcPoint;
11
+ exports.applyPathProgressInto = applyPathProgressInto;
12
+ exports.applyPathProgress = applyPathProgress;
13
+ exports.isNativeArcPath = isNativeArcPath;
14
+ exports.arc = arc;
15
+ exports.NATIVE_ARC_BRAND = '$$nativeMotionArc';
16
+ function wrap180(v) {
17
+ 'worklet';
18
+ const rangeSize = 360;
19
+ return ((((v + 180) % rangeSize) + rangeSize) % rangeSize) - 180;
20
+ }
21
+ function bezierPoint(t, origin, control, target) {
22
+ 'worklet';
23
+ const inv = 1 - t;
24
+ return inv * inv * origin + 2 * inv * t * control + t * t * target;
25
+ }
26
+ function bezierTangentAngle(t, originX, controlX, targetX, originY, controlY, targetY) {
27
+ 'worklet';
28
+ const dx = 2 * (1 - t) * (controlX - originX) + 2 * t * (targetX - controlX);
29
+ const dy = 2 * (1 - t) * (controlY - originY) + 2 * t * (targetY - controlY);
30
+ return Math.atan2(dy, dx) * (180 / Math.PI);
31
+ }
32
+ /** Frame-path control point: writes the caller-owned `out` slot, allocates nothing. */
33
+ function computeArcControlPointInto(fromX, fromY, toX, toY, strength, peak, out) {
34
+ 'worklet';
35
+ const deltaX = toX - fromX;
36
+ const deltaY = toY - fromY;
37
+ const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
38
+ if (distance > 0) {
39
+ const normalPerpX = -deltaY / distance;
40
+ const normalPerpY = deltaX / distance;
41
+ const desiredHeight = strength * distance;
42
+ out.x = fromX + deltaX * peak + normalPerpX * desiredHeight;
43
+ out.y = fromY + deltaY * peak + normalPerpY * desiredHeight;
44
+ return;
45
+ }
46
+ out.x = fromX;
47
+ out.y = fromY;
48
+ }
49
+ function computeArcControlPoint(fromX, fromY, toX, toY, strength, peak) {
50
+ 'worklet';
51
+ const out = { x: 0, y: 0 };
52
+ computeArcControlPointInto(fromX, fromY, toX, toY, strength, peak, out);
53
+ return out;
54
+ }
55
+ /**
56
+ * Frame-path sampler: `t` is progress/1000 and MAY exceed [0, 1] (spring overshoot). Writes the
57
+ * caller-owned `out`/`scratch` slots, allocating nothing (REQ-DRIVER-021).
58
+ */
59
+ function sampleArcPointInto(t, geometry, out, scratch) {
60
+ 'worklet';
61
+ const control = scratch.control;
62
+ computeArcControlPointInto(geometry.fromX, geometry.fromY, geometry.toX, geometry.toY, geometry.signedStrength, geometry.peak, control);
63
+ const x = bezierPoint(t, geometry.fromX, control.x, geometry.toX);
64
+ const y = bezierPoint(t, geometry.fromY, control.y, geometry.toY);
65
+ if (!geometry.rotationScale) {
66
+ out.x = x;
67
+ out.y = y;
68
+ out.rotate = 0;
69
+ return;
70
+ }
71
+ const tangent0 = bezierTangentAngle(0, geometry.fromX, control.x, geometry.toX, geometry.fromY, control.y, geometry.toY);
72
+ const tangent1 = bezierTangentAngle(1, geometry.fromX, control.x, geometry.toX, geometry.fromY, control.y, geometry.toY);
73
+ const tangentDelta = wrap180(tangent1 - tangent0);
74
+ const raw = bezierTangentAngle(t, geometry.fromX, control.x, geometry.toX, geometry.fromY, control.y, geometry.toY);
75
+ const baseline = tangent0 + tangentDelta * t;
76
+ out.x = x;
77
+ out.y = y;
78
+ out.rotate = wrap180(raw - baseline) * geometry.rotationScale;
79
+ }
80
+ /**
81
+ * UI-runtime sampler. `t` is progress/1000 and MAY exceed [0, 1] (spring overshoot).
82
+ * Dual-use: tests + worklet frame step. Function-level worklet tag (JS callers stay valid).
83
+ * Allocating public twin of `sampleArcPointInto` — off-frame callers only (REQ-DRIVER-021).
84
+ */
85
+ function sampleArcPoint(t, fromX, fromY, toX, toY, peak, signedStrength, rotationScale) {
86
+ 'worklet';
87
+ const scratch = { control: { x: 0, y: 0 }, sample: { x: 0, y: 0, rotate: 0 } };
88
+ const out = { x: 0, y: 0, rotate: 0 };
89
+ sampleArcPointInto(t, { fromX, fromY, toX, toY, peak, signedStrength, rotationScale }, out, scratch);
90
+ return out;
91
+ }
92
+ /**
93
+ * Pin onComplete: snap x/y to target and zero pathRotation. Progress is 0→1000. Frame-path
94
+ * form: writes the caller-owned `out`/`scratch` slots, allocating nothing (REQ-DRIVER-021).
95
+ */
96
+ function applyPathProgressInto(progressValue, geometry, done, out, scratch) {
97
+ 'worklet';
98
+ if (done) {
99
+ out.x = geometry.toX;
100
+ out.y = geometry.toY;
101
+ out.pathRotation = 0;
102
+ return;
103
+ }
104
+ const point = scratch.sample;
105
+ sampleArcPointInto(progressValue / 1000, geometry, point, scratch);
106
+ out.x = point.x;
107
+ out.y = point.y;
108
+ out.pathRotation = point.rotate;
109
+ }
110
+ /**
111
+ * Allocating public twin of `applyPathProgressInto` — off-frame callers only (REQ-DRIVER-021);
112
+ * the UI frame step uses the caller-owned-slot form above.
113
+ */
114
+ function applyPathProgress(progressValue, geometry, done) {
115
+ 'worklet';
116
+ const out = { x: 0, y: 0, pathRotation: 0 };
117
+ const scratch = { control: { x: 0, y: 0 }, sample: { x: 0, y: 0, rotate: 0 } };
118
+ applyPathProgressInto(progressValue, geometry, done, out, scratch);
119
+ return out;
120
+ }
121
+ function isNativeArcPath(value) {
122
+ return (typeof value === 'object' &&
123
+ value !== null &&
124
+ value[exports.NATIVE_ARC_BRAND] === true &&
125
+ typeof value.resolve === 'function');
126
+ }
127
+ function rotationScaleOf(rotate) {
128
+ if (rotate === true)
129
+ return 1;
130
+ if (typeof rotate === 'number')
131
+ return rotate;
132
+ return 0;
133
+ }
134
+ /**
135
+ * Public `arc(options)` — reuse the returned value (useMemo / module scope) so the
136
+ * auto-direction sticky closure survives re-renders, matching the pin.
137
+ */
138
+ function arc(options = {}) {
139
+ const strength = options.strength ?? 0.5;
140
+ const peak = options.peak ?? 0.5;
141
+ const direction = options.direction;
142
+ const rotationScale = rotationScaleOf(options.rotate);
143
+ let prevBulgeSign;
144
+ const path = {
145
+ [exports.NATIVE_ARC_BRAND]: true,
146
+ resolve(from, to) {
147
+ const dx = to.x - from.x;
148
+ const dy = to.y - from.y;
149
+ let signed;
150
+ if (direction === 'cw')
151
+ signed = -strength;
152
+ else if (direction === 'ccw')
153
+ signed = strength;
154
+ else {
155
+ const dom = Math.abs(dx) >= Math.abs(dy) ? dx : dy;
156
+ signed = dom < 0 ? -strength : strength;
157
+ }
158
+ let control = computeArcControlPoint(from.x, from.y, to.x, to.y, signed, peak);
159
+ if (direction === undefined) {
160
+ const isVertical = Math.abs(dx) < Math.abs(dy);
161
+ const midX = from.x + dx * peak;
162
+ const midY = from.y + dy * peak;
163
+ const bulgeSign = isVertical ? Math.sign(control.x - midX) : Math.sign(control.y - midY);
164
+ if (prevBulgeSign !== undefined && bulgeSign !== 0 && bulgeSign !== prevBulgeSign) {
165
+ signed = -signed;
166
+ control = computeArcControlPoint(from.x, from.y, to.x, to.y, signed, peak);
167
+ }
168
+ else if (bulgeSign !== 0) {
169
+ prevBulgeSign = bulgeSign;
170
+ }
171
+ }
172
+ return {
173
+ fromX: from.x,
174
+ fromY: from.y,
175
+ toX: to.x,
176
+ toY: to.y,
177
+ peak,
178
+ signedStrength: signed,
179
+ rotationScale,
180
+ };
181
+ },
182
+ };
183
+ return path;
184
+ }
@@ -0,0 +1,78 @@
1
+ export interface ArcOptions {
2
+ readonly strength?: number;
3
+ readonly peak?: number;
4
+ readonly direction?: 'cw' | 'ccw';
5
+ readonly rotate?: boolean | number;
6
+ }
7
+ export interface ArcPoint {
8
+ x: number;
9
+ y: number;
10
+ }
11
+ export interface ArcSample {
12
+ x: number;
13
+ y: number;
14
+ rotate: number;
15
+ }
16
+ export interface PathChannelGeometry {
17
+ readonly fromX: number;
18
+ readonly fromY: number;
19
+ readonly toX: number;
20
+ readonly toY: number;
21
+ readonly peak: number;
22
+ readonly signedStrength: number;
23
+ readonly rotationScale: number;
24
+ }
25
+ export declare const NATIVE_ARC_BRAND: "$$nativeMotionArc";
26
+ export interface NativeArcPath {
27
+ readonly [NATIVE_ARC_BRAND]: true;
28
+ resolve(from: ArcPoint, to: ArcPoint): PathChannelGeometry;
29
+ }
30
+ /**
31
+ * Caller-owned scratch for the frame-path arc samplers (REQ-DRIVER-021, packet §6
32
+ * arc-return-records repair): allocated once at the command edge alongside the path record,
33
+ * reused every frame. `control` carries the quadratic control point; `sample` carries the
34
+ * intermediate ArcSample between `sampleArcPointInto` and `applyPathProgressInto`.
35
+ */
36
+ export interface ArcScratch {
37
+ control: ArcPoint;
38
+ sample: ArcSample;
39
+ }
40
+ /** The frame-path path-progress output slot — written in place, never returned fresh per frame. */
41
+ export interface PathProgressSample {
42
+ x: number;
43
+ y: number;
44
+ pathRotation: number;
45
+ }
46
+ /** Frame-path control point: writes the caller-owned `out` slot, allocates nothing. */
47
+ export declare function computeArcControlPointInto(fromX: number, fromY: number, toX: number, toY: number, strength: number, peak: number, out: ArcPoint): void;
48
+ /**
49
+ * Frame-path sampler: `t` is progress/1000 and MAY exceed [0, 1] (spring overshoot). Writes the
50
+ * caller-owned `out`/`scratch` slots, allocating nothing (REQ-DRIVER-021).
51
+ */
52
+ export declare function sampleArcPointInto(t: number, geometry: PathChannelGeometry, out: ArcSample, scratch: ArcScratch): void;
53
+ /**
54
+ * UI-runtime sampler. `t` is progress/1000 and MAY exceed [0, 1] (spring overshoot).
55
+ * Dual-use: tests + worklet frame step. Function-level worklet tag (JS callers stay valid).
56
+ * Allocating public twin of `sampleArcPointInto` — off-frame callers only (REQ-DRIVER-021).
57
+ */
58
+ export declare function sampleArcPoint(t: number, fromX: number, fromY: number, toX: number, toY: number, peak: number, signedStrength: number, rotationScale: number): ArcSample;
59
+ /**
60
+ * Pin onComplete: snap x/y to target and zero pathRotation. Progress is 0→1000. Frame-path
61
+ * form: writes the caller-owned `out`/`scratch` slots, allocating nothing (REQ-DRIVER-021).
62
+ */
63
+ export declare function applyPathProgressInto(progressValue: number, geometry: PathChannelGeometry, done: boolean, out: PathProgressSample, scratch: ArcScratch): void;
64
+ /**
65
+ * Allocating public twin of `applyPathProgressInto` — off-frame callers only (REQ-DRIVER-021);
66
+ * the UI frame step uses the caller-owned-slot form above.
67
+ */
68
+ export declare function applyPathProgress(progressValue: number, geometry: PathChannelGeometry, done: boolean): {
69
+ x: number;
70
+ y: number;
71
+ pathRotation: number;
72
+ };
73
+ export declare function isNativeArcPath(value: unknown): value is NativeArcPath;
74
+ /**
75
+ * Public `arc(options)` — reuse the returned value (useMemo / module scope) so the
76
+ * auto-direction sticky closure survives re-renders, matching the pin.
77
+ */
78
+ export declare function arc(options?: ArcOptions): NativeArcPath;
@@ -0,0 +1,78 @@
1
+ export interface ArcOptions {
2
+ readonly strength?: number;
3
+ readonly peak?: number;
4
+ readonly direction?: 'cw' | 'ccw';
5
+ readonly rotate?: boolean | number;
6
+ }
7
+ export interface ArcPoint {
8
+ x: number;
9
+ y: number;
10
+ }
11
+ export interface ArcSample {
12
+ x: number;
13
+ y: number;
14
+ rotate: number;
15
+ }
16
+ export interface PathChannelGeometry {
17
+ readonly fromX: number;
18
+ readonly fromY: number;
19
+ readonly toX: number;
20
+ readonly toY: number;
21
+ readonly peak: number;
22
+ readonly signedStrength: number;
23
+ readonly rotationScale: number;
24
+ }
25
+ export declare const NATIVE_ARC_BRAND: "$$nativeMotionArc";
26
+ export interface NativeArcPath {
27
+ readonly [NATIVE_ARC_BRAND]: true;
28
+ resolve(from: ArcPoint, to: ArcPoint): PathChannelGeometry;
29
+ }
30
+ /**
31
+ * Caller-owned scratch for the frame-path arc samplers (REQ-DRIVER-021, packet §6
32
+ * arc-return-records repair): allocated once at the command edge alongside the path record,
33
+ * reused every frame. `control` carries the quadratic control point; `sample` carries the
34
+ * intermediate ArcSample between `sampleArcPointInto` and `applyPathProgressInto`.
35
+ */
36
+ export interface ArcScratch {
37
+ control: ArcPoint;
38
+ sample: ArcSample;
39
+ }
40
+ /** The frame-path path-progress output slot — written in place, never returned fresh per frame. */
41
+ export interface PathProgressSample {
42
+ x: number;
43
+ y: number;
44
+ pathRotation: number;
45
+ }
46
+ /** Frame-path control point: writes the caller-owned `out` slot, allocates nothing. */
47
+ export declare function computeArcControlPointInto(fromX: number, fromY: number, toX: number, toY: number, strength: number, peak: number, out: ArcPoint): void;
48
+ /**
49
+ * Frame-path sampler: `t` is progress/1000 and MAY exceed [0, 1] (spring overshoot). Writes the
50
+ * caller-owned `out`/`scratch` slots, allocating nothing (REQ-DRIVER-021).
51
+ */
52
+ export declare function sampleArcPointInto(t: number, geometry: PathChannelGeometry, out: ArcSample, scratch: ArcScratch): void;
53
+ /**
54
+ * UI-runtime sampler. `t` is progress/1000 and MAY exceed [0, 1] (spring overshoot).
55
+ * Dual-use: tests + worklet frame step. Function-level worklet tag (JS callers stay valid).
56
+ * Allocating public twin of `sampleArcPointInto` — off-frame callers only (REQ-DRIVER-021).
57
+ */
58
+ export declare function sampleArcPoint(t: number, fromX: number, fromY: number, toX: number, toY: number, peak: number, signedStrength: number, rotationScale: number): ArcSample;
59
+ /**
60
+ * Pin onComplete: snap x/y to target and zero pathRotation. Progress is 0→1000. Frame-path
61
+ * form: writes the caller-owned `out`/`scratch` slots, allocating nothing (REQ-DRIVER-021).
62
+ */
63
+ export declare function applyPathProgressInto(progressValue: number, geometry: PathChannelGeometry, done: boolean, out: PathProgressSample, scratch: ArcScratch): void;
64
+ /**
65
+ * Allocating public twin of `applyPathProgressInto` — off-frame callers only (REQ-DRIVER-021);
66
+ * the UI frame step uses the caller-owned-slot form above.
67
+ */
68
+ export declare function applyPathProgress(progressValue: number, geometry: PathChannelGeometry, done: boolean): {
69
+ x: number;
70
+ y: number;
71
+ pathRotation: number;
72
+ };
73
+ export declare function isNativeArcPath(value: unknown): value is NativeArcPath;
74
+ /**
75
+ * Public `arc(options)` — reuse the returned value (useMemo / module scope) so the
76
+ * auto-direction sticky closure survives re-renders, matching the pin.
77
+ */
78
+ export declare function arc(options?: ArcOptions): NativeArcPath;
@@ -0,0 +1,183 @@
1
+ // REQ-API-059 — pin-faithful parametric arc (motion-dom animation/utils/arc.ts at 12.42.2).
2
+ // Host-agnostic: atan2 + wrap only. `sampleArcPoint` is the UI-runtime sampler (resolved
3
+ // geometry, no sticky closure). `arc()` holds the auto-direction continuity closure JS-side.
4
+ // `transition.layout.path` is NOT this module (packet F3).
5
+ export const NATIVE_ARC_BRAND = '$$nativeMotionArc';
6
+ function wrap180(v) {
7
+ 'worklet';
8
+ 'worklet';
9
+ const rangeSize = 360;
10
+ return ((((v + 180) % rangeSize) + rangeSize) % rangeSize) - 180;
11
+ }
12
+ function bezierPoint(t, origin, control, target) {
13
+ 'worklet';
14
+ 'worklet';
15
+ const inv = 1 - t;
16
+ return inv * inv * origin + 2 * inv * t * control + t * t * target;
17
+ }
18
+ function bezierTangentAngle(t, originX, controlX, targetX, originY, controlY, targetY) {
19
+ 'worklet';
20
+ 'worklet';
21
+ const dx = 2 * (1 - t) * (controlX - originX) + 2 * t * (targetX - controlX);
22
+ const dy = 2 * (1 - t) * (controlY - originY) + 2 * t * (targetY - controlY);
23
+ return Math.atan2(dy, dx) * (180 / Math.PI);
24
+ }
25
+ /** Frame-path control point: writes the caller-owned `out` slot, allocates nothing. */
26
+ export function computeArcControlPointInto(fromX, fromY, toX, toY, strength, peak, out) {
27
+ 'worklet';
28
+ 'worklet';
29
+ const deltaX = toX - fromX;
30
+ const deltaY = toY - fromY;
31
+ const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
32
+ if (distance > 0) {
33
+ const normalPerpX = -deltaY / distance;
34
+ const normalPerpY = deltaX / distance;
35
+ const desiredHeight = strength * distance;
36
+ out.x = fromX + deltaX * peak + normalPerpX * desiredHeight;
37
+ out.y = fromY + deltaY * peak + normalPerpY * desiredHeight;
38
+ return;
39
+ }
40
+ out.x = fromX;
41
+ out.y = fromY;
42
+ }
43
+ function computeArcControlPoint(fromX, fromY, toX, toY, strength, peak) {
44
+ 'worklet';
45
+ 'worklet';
46
+ const out = { x: 0, y: 0 };
47
+ computeArcControlPointInto(fromX, fromY, toX, toY, strength, peak, out);
48
+ return out;
49
+ }
50
+ /**
51
+ * Frame-path sampler: `t` is progress/1000 and MAY exceed [0, 1] (spring overshoot). Writes the
52
+ * caller-owned `out`/`scratch` slots, allocating nothing (REQ-DRIVER-021).
53
+ */
54
+ export function sampleArcPointInto(t, geometry, out, scratch) {
55
+ 'worklet';
56
+ 'worklet';
57
+ const control = scratch.control;
58
+ computeArcControlPointInto(geometry.fromX, geometry.fromY, geometry.toX, geometry.toY, geometry.signedStrength, geometry.peak, control);
59
+ const x = bezierPoint(t, geometry.fromX, control.x, geometry.toX);
60
+ const y = bezierPoint(t, geometry.fromY, control.y, geometry.toY);
61
+ if (!geometry.rotationScale) {
62
+ out.x = x;
63
+ out.y = y;
64
+ out.rotate = 0;
65
+ return;
66
+ }
67
+ const tangent0 = bezierTangentAngle(0, geometry.fromX, control.x, geometry.toX, geometry.fromY, control.y, geometry.toY);
68
+ const tangent1 = bezierTangentAngle(1, geometry.fromX, control.x, geometry.toX, geometry.fromY, control.y, geometry.toY);
69
+ const tangentDelta = wrap180(tangent1 - tangent0);
70
+ const raw = bezierTangentAngle(t, geometry.fromX, control.x, geometry.toX, geometry.fromY, control.y, geometry.toY);
71
+ const baseline = tangent0 + tangentDelta * t;
72
+ out.x = x;
73
+ out.y = y;
74
+ out.rotate = wrap180(raw - baseline) * geometry.rotationScale;
75
+ }
76
+ /**
77
+ * UI-runtime sampler. `t` is progress/1000 and MAY exceed [0, 1] (spring overshoot).
78
+ * Dual-use: tests + worklet frame step. Function-level worklet tag (JS callers stay valid).
79
+ * Allocating public twin of `sampleArcPointInto` — off-frame callers only (REQ-DRIVER-021).
80
+ */
81
+ export function sampleArcPoint(t, fromX, fromY, toX, toY, peak, signedStrength, rotationScale) {
82
+ 'worklet';
83
+ 'worklet';
84
+ const scratch = { control: { x: 0, y: 0 }, sample: { x: 0, y: 0, rotate: 0 } };
85
+ const out = { x: 0, y: 0, rotate: 0 };
86
+ sampleArcPointInto(t, { fromX, fromY, toX, toY, peak, signedStrength, rotationScale }, out, scratch);
87
+ return out;
88
+ }
89
+ /**
90
+ * Pin onComplete: snap x/y to target and zero pathRotation. Progress is 0→1000. Frame-path
91
+ * form: writes the caller-owned `out`/`scratch` slots, allocating nothing (REQ-DRIVER-021).
92
+ */
93
+ export function applyPathProgressInto(progressValue, geometry, done, out, scratch) {
94
+ 'worklet';
95
+ 'worklet';
96
+ if (done) {
97
+ out.x = geometry.toX;
98
+ out.y = geometry.toY;
99
+ out.pathRotation = 0;
100
+ return;
101
+ }
102
+ const point = scratch.sample;
103
+ sampleArcPointInto(progressValue / 1000, geometry, point, scratch);
104
+ out.x = point.x;
105
+ out.y = point.y;
106
+ out.pathRotation = point.rotate;
107
+ }
108
+ /**
109
+ * Allocating public twin of `applyPathProgressInto` — off-frame callers only (REQ-DRIVER-021);
110
+ * the UI frame step uses the caller-owned-slot form above.
111
+ */
112
+ export function applyPathProgress(progressValue, geometry, done) {
113
+ 'worklet';
114
+ 'worklet';
115
+ const out = { x: 0, y: 0, pathRotation: 0 };
116
+ const scratch = { control: { x: 0, y: 0 }, sample: { x: 0, y: 0, rotate: 0 } };
117
+ applyPathProgressInto(progressValue, geometry, done, out, scratch);
118
+ return out;
119
+ }
120
+ export function isNativeArcPath(value) {
121
+ return (typeof value === 'object' &&
122
+ value !== null &&
123
+ value[NATIVE_ARC_BRAND] === true &&
124
+ typeof value.resolve === 'function');
125
+ }
126
+ function rotationScaleOf(rotate) {
127
+ if (rotate === true)
128
+ return 1;
129
+ if (typeof rotate === 'number')
130
+ return rotate;
131
+ return 0;
132
+ }
133
+ /**
134
+ * Public `arc(options)` — reuse the returned value (useMemo / module scope) so the
135
+ * auto-direction sticky closure survives re-renders, matching the pin.
136
+ */
137
+ export function arc(options = {}) {
138
+ const strength = options.strength ?? 0.5;
139
+ const peak = options.peak ?? 0.5;
140
+ const direction = options.direction;
141
+ const rotationScale = rotationScaleOf(options.rotate);
142
+ let prevBulgeSign;
143
+ const path = {
144
+ [NATIVE_ARC_BRAND]: true,
145
+ resolve(from, to) {
146
+ const dx = to.x - from.x;
147
+ const dy = to.y - from.y;
148
+ let signed;
149
+ if (direction === 'cw')
150
+ signed = -strength;
151
+ else if (direction === 'ccw')
152
+ signed = strength;
153
+ else {
154
+ const dom = Math.abs(dx) >= Math.abs(dy) ? dx : dy;
155
+ signed = dom < 0 ? -strength : strength;
156
+ }
157
+ let control = computeArcControlPoint(from.x, from.y, to.x, to.y, signed, peak);
158
+ if (direction === undefined) {
159
+ const isVertical = Math.abs(dx) < Math.abs(dy);
160
+ const midX = from.x + dx * peak;
161
+ const midY = from.y + dy * peak;
162
+ const bulgeSign = isVertical ? Math.sign(control.x - midX) : Math.sign(control.y - midY);
163
+ if (prevBulgeSign !== undefined && bulgeSign !== 0 && bulgeSign !== prevBulgeSign) {
164
+ signed = -signed;
165
+ control = computeArcControlPoint(from.x, from.y, to.x, to.y, signed, peak);
166
+ }
167
+ else if (bulgeSign !== 0) {
168
+ prevBulgeSign = bulgeSign;
169
+ }
170
+ }
171
+ return {
172
+ fromX: from.x,
173
+ fromY: from.y,
174
+ toX: to.x,
175
+ toY: to.y,
176
+ peak,
177
+ signedStrength: signed,
178
+ rotationScale,
179
+ };
180
+ },
181
+ };
182
+ return path;
183
+ }