@rafaelaugusto/jolt 0.1.0-beta.9 → 0.1.0-rc.2

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 (576) hide show
  1. package/README.md +167 -21
  2. package/dist/animate.d.ts +25 -4
  3. package/dist/animate.d.ts.map +1 -1
  4. package/dist/animate.js +67 -26
  5. package/dist/animate.js.map +1 -1
  6. package/dist/blur/index.d.ts +6 -0
  7. package/dist/blur/index.d.ts.map +1 -0
  8. package/dist/blur/index.js +196 -0
  9. package/dist/blur/index.js.map +1 -0
  10. package/dist/blur/native.d.ts +17 -0
  11. package/dist/blur/native.d.ts.map +1 -0
  12. package/dist/blur/native.js +44 -0
  13. package/dist/blur/native.js.map +1 -0
  14. package/dist/blur/types.d.ts +32 -0
  15. package/dist/blur/types.d.ts.map +1 -0
  16. package/dist/blur/types.js +2 -0
  17. package/dist/blur/types.js.map +1 -0
  18. package/dist/bottom-sheet/geometry.d.ts +18 -0
  19. package/dist/bottom-sheet/geometry.d.ts.map +1 -0
  20. package/dist/bottom-sheet/geometry.js +51 -0
  21. package/dist/bottom-sheet/geometry.js.map +1 -0
  22. package/dist/bottom-sheet/index.d.ts +56 -0
  23. package/dist/bottom-sheet/index.d.ts.map +1 -0
  24. package/dist/bottom-sheet/index.js +462 -0
  25. package/dist/bottom-sheet/index.js.map +1 -0
  26. package/dist/bottom-sheet/native.d.ts +11 -0
  27. package/dist/bottom-sheet/native.d.ts.map +1 -0
  28. package/dist/bottom-sheet/native.js +173 -0
  29. package/dist/bottom-sheet/native.js.map +1 -0
  30. package/dist/config.d.ts +9 -0
  31. package/dist/config.d.ts.map +1 -1
  32. package/dist/config.js +40 -1
  33. package/dist/config.js.map +1 -1
  34. package/dist/decay.d.ts +1 -0
  35. package/dist/decay.d.ts.map +1 -1
  36. package/dist/decay.js +7 -0
  37. package/dist/decay.js.map +1 -1
  38. package/dist/drag-physics.d.ts +6 -1
  39. package/dist/drag-physics.d.ts.map +1 -1
  40. package/dist/drag.d.ts +17 -3
  41. package/dist/drag.d.ts.map +1 -1
  42. package/dist/drag.js +34 -11
  43. package/dist/drag.js.map +1 -1
  44. package/dist/driver/android-gradient.d.ts +5 -0
  45. package/dist/driver/android-gradient.d.ts.map +1 -0
  46. package/dist/driver/android-gradient.js +99 -0
  47. package/dist/driver/android-gradient.js.map +1 -0
  48. package/dist/driver/android-particles.d.ts +6 -0
  49. package/dist/driver/android-particles.d.ts.map +1 -0
  50. package/dist/driver/android-particles.js +93 -0
  51. package/dist/driver/android-particles.js.map +1 -0
  52. package/dist/driver/android.d.ts.map +1 -1
  53. package/dist/driver/android.js +27 -1
  54. package/dist/driver/android.js.map +1 -1
  55. package/dist/driver/frame.d.ts +3 -0
  56. package/dist/driver/frame.d.ts.map +1 -0
  57. package/dist/driver/frame.js +7 -0
  58. package/dist/driver/frame.js.map +1 -0
  59. package/dist/driver/index.d.ts +4 -0
  60. package/dist/driver/index.d.ts.map +1 -1
  61. package/dist/driver/index.js.map +1 -1
  62. package/dist/driver/ios-gradient.d.ts +5 -0
  63. package/dist/driver/ios-gradient.d.ts.map +1 -0
  64. package/dist/driver/ios-gradient.js +131 -0
  65. package/dist/driver/ios-gradient.js.map +1 -0
  66. package/dist/driver/ios-scroll-delegate.d.ts +4 -0
  67. package/dist/driver/ios-scroll-delegate.d.ts.map +1 -0
  68. package/dist/driver/ios-scroll-delegate.js +26 -0
  69. package/dist/driver/ios-scroll-delegate.js.map +1 -0
  70. package/dist/driver/ios.d.ts.map +1 -1
  71. package/dist/driver/ios.js +9 -0
  72. package/dist/driver/ios.js.map +1 -1
  73. package/dist/easing.d.ts +3 -1
  74. package/dist/easing.d.ts.map +1 -1
  75. package/dist/easing.js +18 -1
  76. package/dist/easing.js.map +1 -1
  77. package/dist/engine.d.ts +31 -2
  78. package/dist/engine.d.ts.map +1 -1
  79. package/dist/engine.js +194 -42
  80. package/dist/engine.js.map +1 -1
  81. package/dist/gesture-native.d.ts +28 -0
  82. package/dist/gesture-native.d.ts.map +1 -0
  83. package/dist/gesture-native.js +61 -0
  84. package/dist/gesture-native.js.map +1 -0
  85. package/dist/gestures/index.d.ts +69 -0
  86. package/dist/gestures/index.d.ts.map +1 -0
  87. package/dist/gestures/index.js +262 -0
  88. package/dist/gestures/index.js.map +1 -0
  89. package/dist/glass/index.d.ts +55 -0
  90. package/dist/glass/index.d.ts.map +1 -0
  91. package/dist/glass/index.js +205 -0
  92. package/dist/glass/index.js.map +1 -0
  93. package/dist/gradient-binding.d.ts +38 -0
  94. package/dist/gradient-binding.d.ts.map +1 -0
  95. package/dist/gradient-binding.js +128 -0
  96. package/dist/gradient-binding.js.map +1 -0
  97. package/dist/gradient.d.ts +105 -0
  98. package/dist/gradient.d.ts.map +1 -0
  99. package/dist/gradient.js +514 -0
  100. package/dist/gradient.js.map +1 -0
  101. package/dist/gravity.d.ts +13 -0
  102. package/dist/gravity.d.ts.map +1 -0
  103. package/dist/gravity.js +84 -0
  104. package/dist/gravity.js.map +1 -0
  105. package/dist/haptics.d.ts.map +1 -1
  106. package/dist/haptics.js +101 -28
  107. package/dist/haptics.js.map +1 -1
  108. package/dist/image-effect.d.ts +1 -0
  109. package/dist/image-effect.d.ts.map +1 -1
  110. package/dist/image-effect.js +10 -2
  111. package/dist/image-effect.js.map +1 -1
  112. package/dist/index.d.ts +19 -7
  113. package/dist/index.d.ts.map +1 -1
  114. package/dist/index.js +10 -4
  115. package/dist/index.js.map +1 -1
  116. package/dist/inspector/index.d.ts +86 -0
  117. package/dist/inspector/index.d.ts.map +1 -0
  118. package/dist/inspector/index.js +419 -0
  119. package/dist/inspector/index.js.map +1 -0
  120. package/dist/inspector/plot.d.ts +4 -0
  121. package/dist/inspector/plot.d.ts.map +1 -0
  122. package/dist/inspector/plot.js +23 -0
  123. package/dist/inspector/plot.js.map +1 -0
  124. package/dist/inspector/probe.d.ts +19 -0
  125. package/dist/inspector/probe.d.ts.map +1 -0
  126. package/dist/inspector/probe.js +37 -0
  127. package/dist/inspector/probe.js.map +1 -0
  128. package/dist/inspector/tuning.d.ts +19 -0
  129. package/dist/inspector/tuning.d.ts.map +1 -0
  130. package/dist/inspector/tuning.js +37 -0
  131. package/dist/inspector/tuning.js.map +1 -0
  132. package/dist/interactive-navigation/index.d.ts +44 -0
  133. package/dist/interactive-navigation/index.d.ts.map +1 -0
  134. package/dist/interactive-navigation/index.js +350 -0
  135. package/dist/interactive-navigation/index.js.map +1 -0
  136. package/dist/keyboard.d.ts +24 -0
  137. package/dist/keyboard.d.ts.map +1 -1
  138. package/dist/keyboard.js +199 -6
  139. package/dist/keyboard.js.map +1 -1
  140. package/dist/live-spring-driver.d.ts +52 -0
  141. package/dist/live-spring-driver.d.ts.map +1 -0
  142. package/dist/live-spring-driver.js +104 -0
  143. package/dist/live-spring-driver.js.map +1 -0
  144. package/dist/mixer.d.ts +55 -0
  145. package/dist/mixer.d.ts.map +1 -0
  146. package/dist/mixer.js +286 -0
  147. package/dist/mixer.js.map +1 -0
  148. package/dist/motion-scope.d.ts +8 -2
  149. package/dist/motion-scope.d.ts.map +1 -1
  150. package/dist/motion-scope.js +24 -3
  151. package/dist/motion-scope.js.map +1 -1
  152. package/dist/motion-states.d.ts +19 -7
  153. package/dist/motion-states.d.ts.map +1 -1
  154. package/dist/motion-states.js +116 -26
  155. package/dist/motion-states.js.map +1 -1
  156. package/dist/motion-value.d.ts +227 -0
  157. package/dist/motion-value.d.ts.map +1 -0
  158. package/dist/motion-value.js +1074 -0
  159. package/dist/motion-value.js.map +1 -0
  160. package/dist/native/index.d.ts +10 -0
  161. package/dist/native/index.d.ts.map +1 -0
  162. package/dist/native/index.js +6 -0
  163. package/dist/native/index.js.map +1 -0
  164. package/dist/native-properties.d.ts +28 -0
  165. package/dist/native-properties.d.ts.map +1 -0
  166. package/dist/native-properties.js +154 -0
  167. package/dist/native-properties.js.map +1 -0
  168. package/dist/native-property-driver.d.ts +19 -0
  169. package/dist/native-property-driver.d.ts.map +1 -0
  170. package/dist/native-property-driver.js +69 -0
  171. package/dist/native-property-driver.js.map +1 -0
  172. package/dist/native-property.d.ts +37 -0
  173. package/dist/native-property.d.ts.map +1 -0
  174. package/dist/native-property.js +285 -0
  175. package/dist/native-property.js.map +1 -0
  176. package/dist/particles.d.ts +5 -2
  177. package/dist/particles.d.ts.map +1 -1
  178. package/dist/particles.js +16 -10
  179. package/dist/particles.js.map +1 -1
  180. package/dist/path.d.ts.map +1 -1
  181. package/dist/path.js +2 -2
  182. package/dist/path.js.map +1 -1
  183. package/dist/physics/index.d.ts +139 -0
  184. package/dist/physics/index.d.ts.map +1 -0
  185. package/dist/physics/index.js +316 -0
  186. package/dist/physics/index.js.map +1 -0
  187. package/dist/physics/native.d.ts +54 -0
  188. package/dist/physics/native.d.ts.map +1 -0
  189. package/dist/physics/native.js +64 -0
  190. package/dist/physics/native.js.map +1 -0
  191. package/dist/playback-group.d.ts.map +1 -1
  192. package/dist/playback-group.js +17 -1
  193. package/dist/playback-group.js.map +1 -1
  194. package/dist/playback.d.ts +15 -0
  195. package/dist/playback.d.ts.map +1 -1
  196. package/dist/playback.js +23 -0
  197. package/dist/playback.js.map +1 -1
  198. package/dist/predictive-back/index.d.ts +45 -0
  199. package/dist/predictive-back/index.d.ts.map +1 -0
  200. package/dist/predictive-back/index.js +220 -0
  201. package/dist/predictive-back/index.js.map +1 -0
  202. package/dist/predictive-back/presentation.d.ts +4 -0
  203. package/dist/predictive-back/presentation.d.ts.map +1 -0
  204. package/dist/predictive-back/presentation.js +3 -0
  205. package/dist/predictive-back/presentation.js.map +1 -0
  206. package/dist/press.d.ts.map +1 -1
  207. package/dist/press.js +11 -2
  208. package/dist/press.js.map +1 -1
  209. package/dist/reorder/handle.d.ts +6 -0
  210. package/dist/reorder/handle.d.ts.map +1 -0
  211. package/dist/reorder/handle.js +10 -0
  212. package/dist/reorder/handle.js.map +1 -0
  213. package/dist/reorder/index.d.ts +10 -0
  214. package/dist/reorder/index.d.ts.map +1 -0
  215. package/dist/reorder/index.js +233 -0
  216. package/dist/reorder/index.js.map +1 -0
  217. package/dist/reorder/list-view.d.ts +5 -0
  218. package/dist/reorder/list-view.d.ts.map +1 -0
  219. package/dist/reorder/list-view.js +238 -0
  220. package/dist/reorder/list-view.js.map +1 -0
  221. package/dist/reorder/model.d.ts +6 -0
  222. package/dist/reorder/model.d.ts.map +1 -0
  223. package/dist/reorder/model.js +30 -0
  224. package/dist/reorder/model.js.map +1 -0
  225. package/dist/reorder/surface.d.ts +6 -0
  226. package/dist/reorder/surface.d.ts.map +1 -0
  227. package/dist/reorder/surface.js +10 -0
  228. package/dist/reorder/surface.js.map +1 -0
  229. package/dist/reorder/types.d.ts +92 -0
  230. package/dist/reorder/types.d.ts.map +1 -0
  231. package/dist/reorder/types.js +2 -0
  232. package/dist/reorder/types.js.map +1 -0
  233. package/dist/sampling.d.ts +35 -0
  234. package/dist/sampling.d.ts.map +1 -0
  235. package/dist/sampling.js +123 -0
  236. package/dist/sampling.js.map +1 -0
  237. package/dist/scene-appearance.d.ts +14 -0
  238. package/dist/scene-appearance.d.ts.map +1 -0
  239. package/dist/scene-appearance.js +68 -0
  240. package/dist/scene-appearance.js.map +1 -0
  241. package/dist/scene-camera.d.ts +5 -0
  242. package/dist/scene-camera.d.ts.map +1 -0
  243. package/dist/scene-camera.js +23 -0
  244. package/dist/scene-camera.js.map +1 -0
  245. package/dist/scene-shader.d.ts +18 -0
  246. package/dist/scene-shader.d.ts.map +1 -0
  247. package/dist/scene-shader.js +76 -0
  248. package/dist/scene-shader.js.map +1 -0
  249. package/dist/scroll-header/geometry.d.ts +18 -0
  250. package/dist/scroll-header/geometry.d.ts.map +1 -0
  251. package/dist/scroll-header/geometry.js +46 -0
  252. package/dist/scroll-header/geometry.js.map +1 -0
  253. package/dist/scroll-header/index.d.ts +48 -0
  254. package/dist/scroll-header/index.d.ts.map +1 -0
  255. package/dist/scroll-header/index.js +399 -0
  256. package/dist/scroll-header/index.js.map +1 -0
  257. package/dist/scroll-header/native.d.ts +28 -0
  258. package/dist/scroll-header/native.d.ts.map +1 -0
  259. package/dist/scroll-header/native.js +43 -0
  260. package/dist/scroll-header/native.js.map +1 -0
  261. package/dist/sensors/index.d.ts +69 -0
  262. package/dist/sensors/index.d.ts.map +1 -0
  263. package/dist/sensors/index.js +149 -0
  264. package/dist/sensors/index.js.map +1 -0
  265. package/dist/sensors/native.d.ts +20 -0
  266. package/dist/sensors/native.d.ts.map +1 -0
  267. package/dist/sensors/native.js +48 -0
  268. package/dist/sensors/native.js.map +1 -0
  269. package/dist/sequence.d.ts +24 -0
  270. package/dist/sequence.d.ts.map +1 -1
  271. package/dist/sequence.js +181 -19
  272. package/dist/sequence.js.map +1 -1
  273. package/dist/shapes/android.d.ts +3 -0
  274. package/dist/shapes/android.d.ts.map +1 -0
  275. package/dist/shapes/android.js +51 -0
  276. package/dist/shapes/android.js.map +1 -0
  277. package/dist/shapes/index.d.ts +6 -0
  278. package/dist/shapes/index.d.ts.map +1 -0
  279. package/dist/shapes/index.js +238 -0
  280. package/dist/shapes/index.js.map +1 -0
  281. package/dist/shapes/ios.d.ts +3 -0
  282. package/dist/shapes/ios.d.ts.map +1 -0
  283. package/dist/shapes/ios.js +164 -0
  284. package/dist/shapes/ios.js.map +1 -0
  285. package/dist/shapes/native.d.ts +18 -0
  286. package/dist/shapes/native.d.ts.map +1 -0
  287. package/dist/shapes/native.js +10 -0
  288. package/dist/shapes/native.js.map +1 -0
  289. package/dist/shapes/path.d.ts +10 -0
  290. package/dist/shapes/path.d.ts.map +1 -0
  291. package/dist/shapes/path.js +106 -0
  292. package/dist/shapes/path.js.map +1 -0
  293. package/dist/shapes/types.d.ts +55 -0
  294. package/dist/shapes/types.d.ts.map +1 -0
  295. package/dist/shapes/types.js +11 -0
  296. package/dist/shapes/types.js.map +1 -0
  297. package/dist/shared-layout/index.d.ts +40 -0
  298. package/dist/shared-layout/index.d.ts.map +1 -0
  299. package/dist/shared-layout/index.js +267 -0
  300. package/dist/shared-layout/index.js.map +1 -0
  301. package/dist/shared-layout/native.d.ts +15 -0
  302. package/dist/shared-layout/native.d.ts.map +1 -0
  303. package/dist/shared-layout/native.js +79 -0
  304. package/dist/shared-layout/native.js.map +1 -0
  305. package/dist/shared-layout/timing.d.ts +9 -0
  306. package/dist/shared-layout/timing.d.ts.map +1 -0
  307. package/dist/shared-layout/timing.js +68 -0
  308. package/dist/shared-layout/timing.js.map +1 -0
  309. package/dist/shared-navigation/entry.d.ts +51 -0
  310. package/dist/shared-navigation/entry.d.ts.map +1 -0
  311. package/dist/shared-navigation/entry.js +619 -0
  312. package/dist/shared-navigation/entry.js.map +1 -0
  313. package/dist/shared-navigation/index.d.ts +58 -0
  314. package/dist/shared-navigation/index.d.ts.map +1 -0
  315. package/dist/shared-navigation/index.js +318 -0
  316. package/dist/shared-navigation/index.js.map +1 -0
  317. package/dist/shared-navigation/return-signal.d.ts +16 -0
  318. package/dist/shared-navigation/return-signal.d.ts.map +1 -0
  319. package/dist/shared-navigation/return-signal.js +35 -0
  320. package/dist/shared-navigation/return-signal.js.map +1 -0
  321. package/dist/shared-navigation/return-target.d.ts +32 -0
  322. package/dist/shared-navigation/return-target.d.ts.map +1 -0
  323. package/dist/shared-navigation/return-target.js +168 -0
  324. package/dist/shared-navigation/return-target.js.map +1 -0
  325. package/dist/shared-navigation/scope.d.ts +4 -0
  326. package/dist/shared-navigation/scope.d.ts.map +1 -0
  327. package/dist/shared-navigation/scope.js +2 -0
  328. package/dist/shared-navigation/scope.js.map +1 -0
  329. package/dist/shared-navigation/targets.d.ts +6 -0
  330. package/dist/shared-navigation/targets.d.ts.map +1 -0
  331. package/dist/shared-navigation/targets.js +36 -0
  332. package/dist/shared-navigation/targets.js.map +1 -0
  333. package/dist/size-layout.d.ts +19 -0
  334. package/dist/size-layout.d.ts.map +1 -0
  335. package/dist/size-layout.js +216 -0
  336. package/dist/size-layout.js.map +1 -0
  337. package/dist/size.d.ts +19 -0
  338. package/dist/size.d.ts.map +1 -0
  339. package/dist/size.js +251 -0
  340. package/dist/size.js.map +1 -0
  341. package/dist/spring.d.ts +2 -0
  342. package/dist/spring.d.ts.map +1 -1
  343. package/dist/spring.js +11 -0
  344. package/dist/spring.js.map +1 -1
  345. package/dist/svg-path.d.ts +18 -0
  346. package/dist/svg-path.d.ts.map +1 -1
  347. package/dist/svg-path.js +3 -2
  348. package/dist/svg-path.js.map +1 -1
  349. package/dist/testing/clock.d.ts +40 -0
  350. package/dist/testing/clock.d.ts.map +1 -0
  351. package/dist/testing/clock.js +116 -0
  352. package/dist/testing/clock.js.map +1 -0
  353. package/dist/testing/handoff-recorder.d.ts +8 -0
  354. package/dist/testing/handoff-recorder.d.ts.map +1 -0
  355. package/dist/testing/handoff-recorder.js +77 -0
  356. package/dist/testing/handoff-recorder.js.map +1 -0
  357. package/dist/testing/index.d.ts +5 -0
  358. package/dist/testing/index.d.ts.map +1 -0
  359. package/dist/testing/index.js +5 -0
  360. package/dist/testing/index.js.map +1 -0
  361. package/dist/testing/native.d.ts +46 -0
  362. package/dist/testing/native.d.ts.map +1 -0
  363. package/dist/testing/native.js +313 -0
  364. package/dist/testing/native.js.map +1 -0
  365. package/dist/testing/presentation.d.ts +11 -0
  366. package/dist/testing/presentation.d.ts.map +1 -0
  367. package/dist/testing/presentation.js +45 -0
  368. package/dist/testing/presentation.js.map +1 -0
  369. package/dist/testing/replay.d.ts +39 -0
  370. package/dist/testing/replay.d.ts.map +1 -0
  371. package/dist/testing/replay.js +99 -0
  372. package/dist/testing/replay.js.map +1 -0
  373. package/dist/testing/scroll-handoff-native.d.ts +10 -0
  374. package/dist/testing/scroll-handoff-native.d.ts.map +1 -0
  375. package/dist/testing/scroll-handoff-native.js +151 -0
  376. package/dist/testing/scroll-handoff-native.js.map +1 -0
  377. package/dist/testing/scroll-handoff.d.ts +25 -0
  378. package/dist/testing/scroll-handoff.d.ts.map +1 -0
  379. package/dist/testing/scroll-handoff.js +127 -0
  380. package/dist/testing/scroll-handoff.js.map +1 -0
  381. package/dist/testing/sensors.d.ts +13 -0
  382. package/dist/testing/sensors.d.ts.map +1 -0
  383. package/dist/testing/sensors.js +26 -0
  384. package/dist/testing/sensors.js.map +1 -0
  385. package/dist/testing/trace.d.ts +101 -0
  386. package/dist/testing/trace.d.ts.map +1 -0
  387. package/dist/testing/trace.js +263 -0
  388. package/dist/testing/trace.js.map +1 -0
  389. package/dist/timed-animation.d.ts +38 -0
  390. package/dist/timed-animation.d.ts.map +1 -0
  391. package/dist/timed-animation.js +177 -0
  392. package/dist/timed-animation.js.map +1 -0
  393. package/dist/track.d.ts +3 -0
  394. package/dist/track.d.ts.map +1 -1
  395. package/dist/track.js +281 -40
  396. package/dist/track.js.map +1 -1
  397. package/dist/transition.d.ts +54 -2
  398. package/dist/transition.d.ts.map +1 -1
  399. package/dist/transition.js +128 -8
  400. package/dist/transition.js.map +1 -1
  401. package/dist/types.d.ts +10 -1
  402. package/dist/types.d.ts.map +1 -1
  403. package/dist/value-observers.d.ts +22 -0
  404. package/dist/value-observers.d.ts.map +1 -0
  405. package/dist/value-observers.js +122 -0
  406. package/dist/value-observers.js.map +1 -0
  407. package/dist/value-track.d.ts +13 -0
  408. package/dist/value-track.d.ts.map +1 -0
  409. package/dist/value-track.js +59 -0
  410. package/dist/value-track.js.map +1 -0
  411. package/dist/vue/index.d.ts +33 -3
  412. package/dist/vue/index.d.ts.map +1 -1
  413. package/dist/vue/index.js +118 -3
  414. package/dist/vue/index.js.map +1 -1
  415. package/dist/zoomable.d.ts +1 -1
  416. package/dist/zoomable.d.ts.map +1 -1
  417. package/package.json +68 -3
  418. package/platforms/android/include.gradle +10 -0
  419. package/platforms/android/java/org/rafaelaugusto/jolt/BlurEffect.java +89 -0
  420. package/platforms/android/java/org/rafaelaugusto/jolt/CircleMath.java +158 -0
  421. package/platforms/android/java/org/rafaelaugusto/jolt/CircleWorld.java +221 -0
  422. package/platforms/android/java/org/rafaelaugusto/jolt/GestureSession.java +227 -0
  423. package/platforms/android/java/org/rafaelaugusto/jolt/GestureSurface.java +54 -0
  424. package/platforms/android/java/org/rafaelaugusto/jolt/GradientLayer.java +224 -0
  425. package/platforms/android/java/org/rafaelaugusto/jolt/KeyboardFrame.java +53 -0
  426. package/platforms/android/java/org/rafaelaugusto/jolt/KeyboardFrameFollower.java +57 -0
  427. package/platforms/android/java/org/rafaelaugusto/jolt/KeyboardObserver.java +97 -0
  428. package/platforms/android/java/org/rafaelaugusto/jolt/LiveSpring.java +277 -0
  429. package/platforms/android/java/org/rafaelaugusto/jolt/MotionProbe.java +70 -0
  430. package/platforms/android/java/org/rafaelaugusto/jolt/ParticleEmitter.java +192 -0
  431. package/platforms/android/java/org/rafaelaugusto/jolt/ParticleSimulation.java +114 -0
  432. package/platforms/android/java/org/rafaelaugusto/jolt/PredictiveBackSession.java +212 -0
  433. package/platforms/android/java/org/rafaelaugusto/jolt/ReorderHandle.java +25 -0
  434. package/platforms/android/java/org/rafaelaugusto/jolt/ReorderSession.java +213 -0
  435. package/platforms/android/java/org/rafaelaugusto/jolt/ReorderSurface.java +27 -0
  436. package/platforms/android/java/org/rafaelaugusto/jolt/ScrollHeader.java +84 -0
  437. package/platforms/android/java/org/rafaelaugusto/jolt/SensorMath.java +28 -0
  438. package/platforms/android/java/org/rafaelaugusto/jolt/SensorSource.java +217 -0
  439. package/platforms/android/java/org/rafaelaugusto/jolt/ShapeLayer.java +120 -0
  440. package/platforms/android/java/org/rafaelaugusto/jolt/SharedLayoutFlight.java +287 -0
  441. package/platforms/android/java/org/rafaelaugusto/jolt/SharedNavigationScene.java +115 -0
  442. package/platforms/android/java/org/rafaelaugusto/jolt/SpringState.java +39 -0
  443. package/platforms/android/proguard-rules.pro +20 -0
  444. package/platforms/ios/build.xcconfig +1 -1
  445. package/platforms/ios/src/JoltBlur.h +14 -0
  446. package/platforms/ios/src/JoltBlur.m +86 -0
  447. package/platforms/ios/src/JoltCircleMath.h +191 -0
  448. package/platforms/ios/src/JoltCircleWorld.h +18 -0
  449. package/platforms/ios/src/JoltCircleWorld.m +218 -0
  450. package/platforms/ios/src/JoltGestureSession.h +23 -0
  451. package/platforms/ios/src/JoltGestureSession.m +251 -0
  452. package/platforms/ios/src/JoltInteractiveNavigation.h +23 -0
  453. package/platforms/ios/src/JoltInteractiveNavigation.m +255 -0
  454. package/platforms/ios/src/JoltLiveSpring.h +29 -0
  455. package/platforms/ios/src/JoltLiveSpring.m +243 -0
  456. package/platforms/ios/src/JoltMotionProbe.h +9 -0
  457. package/platforms/ios/src/JoltMotionProbe.m +72 -0
  458. package/platforms/ios/src/JoltReorderSession.h +15 -0
  459. package/platforms/ios/src/JoltReorderSession.m +205 -0
  460. package/platforms/ios/src/JoltScrollHeader.h +13 -0
  461. package/platforms/ios/src/JoltScrollHeader.m +101 -0
  462. package/platforms/ios/src/JoltSensorMath.h +39 -0
  463. package/platforms/ios/src/JoltSensorSource.h +13 -0
  464. package/platforms/ios/src/JoltSensorSource.m +201 -0
  465. package/platforms/ios/src/JoltSharedLayoutFlight.h +19 -0
  466. package/platforms/ios/src/JoltSharedLayoutFlight.m +250 -0
  467. package/platforms/ios/src/JoltSpringState.h +35 -0
  468. package/platforms/ios/src/module.modulemap +10 -0
  469. package/src/android-plugin.d.ts +464 -0
  470. package/src/animate.ts +129 -15
  471. package/src/blur/index.ts +195 -0
  472. package/src/blur/native.ts +70 -0
  473. package/src/blur/types.ts +32 -0
  474. package/src/bottom-sheet/geometry.ts +84 -0
  475. package/src/bottom-sheet/index.ts +536 -0
  476. package/src/bottom-sheet/native.ts +214 -0
  477. package/src/config.ts +39 -1
  478. package/src/decay.ts +9 -0
  479. package/src/drag.ts +67 -21
  480. package/src/driver/android-gradient.ts +116 -0
  481. package/src/driver/android-particles.ts +118 -0
  482. package/src/driver/android.ts +31 -1
  483. package/src/driver/frame.ts +10 -0
  484. package/src/driver/index.ts +4 -0
  485. package/src/driver/ios-gradient.ts +136 -0
  486. package/src/driver/ios-scroll-delegate.ts +23 -0
  487. package/src/driver/ios.ts +10 -0
  488. package/src/easing.ts +21 -1
  489. package/src/engine.ts +209 -60
  490. package/src/gesture-native.ts +139 -0
  491. package/src/gestures/index.ts +365 -0
  492. package/src/glass/index.ts +218 -0
  493. package/src/gradient-binding.ts +158 -0
  494. package/src/gradient.ts +663 -0
  495. package/src/gravity.ts +107 -0
  496. package/src/haptics.ts +106 -28
  497. package/src/image-effect.ts +10 -2
  498. package/src/index.ts +56 -7
  499. package/src/inspector/index.ts +523 -0
  500. package/src/inspector/plot.ts +27 -0
  501. package/src/inspector/probe.ts +50 -0
  502. package/src/inspector/tuning.ts +51 -0
  503. package/src/interactive-navigation/index.ts +427 -0
  504. package/src/ios-plugin.d.ts +280 -0
  505. package/src/keyboard.ts +231 -7
  506. package/src/live-spring-driver.ts +181 -0
  507. package/src/mixer.ts +312 -0
  508. package/src/motion-scope.ts +39 -6
  509. package/src/motion-states.ts +149 -42
  510. package/src/motion-value.ts +1289 -0
  511. package/src/native/index.ts +30 -0
  512. package/src/native-properties.ts +188 -0
  513. package/src/native-property-driver.ts +123 -0
  514. package/src/native-property.ts +366 -0
  515. package/src/particles.ts +18 -17
  516. package/src/path.ts +2 -1
  517. package/src/physics/index.ts +476 -0
  518. package/src/physics/native.ts +121 -0
  519. package/src/playback-group.ts +17 -1
  520. package/src/playback.ts +41 -0
  521. package/src/predictive-back/index.ts +280 -0
  522. package/src/predictive-back/presentation.ts +6 -0
  523. package/src/press.ts +10 -2
  524. package/src/reorder/handle.ts +9 -0
  525. package/src/reorder/index.ts +243 -0
  526. package/src/reorder/list-view.ts +262 -0
  527. package/src/reorder/model.ts +47 -0
  528. package/src/reorder/surface.ts +10 -0
  529. package/src/reorder/types.ts +87 -0
  530. package/src/sampling.ts +173 -0
  531. package/src/scene-appearance.ts +92 -0
  532. package/src/scene-camera.ts +30 -0
  533. package/src/scene-shader.ts +139 -0
  534. package/src/scroll-header/geometry.ts +88 -0
  535. package/src/scroll-header/index.ts +530 -0
  536. package/src/scroll-header/native.ts +89 -0
  537. package/src/sensors/index.ts +246 -0
  538. package/src/sensors/native.ts +72 -0
  539. package/src/sequence.ts +209 -20
  540. package/src/shapes/android.ts +63 -0
  541. package/src/shapes/index.ts +267 -0
  542. package/src/shapes/ios.ts +194 -0
  543. package/src/shapes/native.ts +27 -0
  544. package/src/shapes/path.ts +127 -0
  545. package/src/shapes/types.ts +63 -0
  546. package/src/shared-layout/index.ts +343 -0
  547. package/src/shared-layout/native.ts +138 -0
  548. package/src/shared-layout/timing.ts +87 -0
  549. package/src/shared-navigation/entry.ts +695 -0
  550. package/src/shared-navigation/index.ts +414 -0
  551. package/src/shared-navigation/return-signal.ts +41 -0
  552. package/src/shared-navigation/return-target.ts +197 -0
  553. package/src/shared-navigation/scope.ts +3 -0
  554. package/src/shared-navigation/targets.ts +38 -0
  555. package/src/size-layout.ts +237 -0
  556. package/src/size.ts +302 -0
  557. package/src/spring.ts +18 -0
  558. package/src/svg-path.ts +8 -3
  559. package/src/testing/clock.ts +128 -0
  560. package/src/testing/handoff-recorder.ts +98 -0
  561. package/src/testing/index.ts +4 -0
  562. package/src/testing/native.ts +386 -0
  563. package/src/testing/presentation.ts +46 -0
  564. package/src/testing/replay.ts +149 -0
  565. package/src/testing/scroll-handoff-native.ts +201 -0
  566. package/src/testing/scroll-handoff.ts +140 -0
  567. package/src/testing/sensors.ts +41 -0
  568. package/src/testing/trace.ts +340 -0
  569. package/src/timed-animation.ts +192 -0
  570. package/src/track.ts +334 -38
  571. package/src/transition.ts +197 -9
  572. package/src/types.ts +11 -1
  573. package/src/value-observers.ts +147 -0
  574. package/src/value-track.ts +71 -0
  575. package/src/vue/index.ts +147 -1
  576. package/src/zoomable.ts +1 -1
@@ -0,0 +1,414 @@
1
+ import { ReturnScope } from './return-signal.js'
2
+ import { Application, Image, type Frame, type Page } from '@nativescript/core'
3
+ import { find, radius, supportedImage } from './targets.js'
4
+ import { reducedMotion, onReducedMotion } from '../config.js'
5
+ import { getDriver } from '../driver/index.js'
6
+ import { capture, captureNavigationImage, type Flight } from '../shared-layout/native.js'
7
+ import {
8
+ resolveReturnTarget,
9
+ validateReturnTarget,
10
+ focusReturnTarget,
11
+ type SharedReturnTarget,
12
+ } from './return-target.js'
13
+ export { resolveListTarget } from './return-target.js'
14
+ export type { SharedReturnSignal } from './return-signal.js'
15
+ export type { SharedReturnContext, SharedReturnTarget } from './return-target.js'
16
+ import { timing, tracks } from '../shared-layout/timing.js'
17
+ import type {
18
+ SharedLayoutOptions,
19
+ SharedLayoutTransition,
20
+ } from '../shared-layout/index.js'
21
+
22
+ export type SharedNavigationStatus = 'completed' | 'cancelled' | 'unavailable' | 'failed'
23
+ export interface SharedNavigationResult {
24
+ status: SharedNavigationStatus
25
+ reason?: string
26
+ /** The Frame committed a different page. Cancelling motion never rolls a route back. */
27
+ navigated: boolean
28
+ error?: unknown
29
+ }
30
+ export interface SharedNavigationOptions extends SharedLayoutOptions {
31
+ /** Bound route guards/page creation. Default 3000 ms; maximum 10000 ms. */
32
+ navigationTimeout?: number
33
+ }
34
+ export interface SharedNavigationRequest {
35
+ /** Capture a dragged static image with its current viewport clipping. */
36
+ allowClippedSource?: boolean
37
+ /** Current window-space translation velocity, in DIPs per second. Spring flights only. */
38
+ velocity?: Readonly<{ x: number; y: number }>
39
+ /** Resolve the current return view after the destination page has been mounted. */
40
+ returnTarget?: SharedReturnTarget
41
+ /** Retain the visible source page while the return target is realized (within the pixel budget). */
42
+ holdSource?: boolean
43
+ /** Called after native capture, before route mutation; useful for releasing a held viewer pose. */
44
+ onCaptured?: () => void
45
+ /** Optional lower per-flight budget when another native presentation retains pixels. */
46
+ maxSnapshotPixels?: number
47
+ /** Match exactly one sharedTransitionTag on each page in this Frame. */
48
+ tag: string
49
+ /** Called once, after capture. Pass these options to Frame.navigate/router.push/back. */
50
+ navigate(options: Readonly<{ animated: false }>): unknown
51
+ transition?: SharedLayoutTransition
52
+ }
53
+ export interface SharedNavigationAnimation {
54
+ finished: Promise<SharedNavigationResult>
55
+ /** Ends only the visual overlay. The route belongs to the Frame/router. */
56
+ cancel(): void
57
+ }
58
+ export interface SharedNavigation {
59
+ readonly state: 'idle' | 'preparing' | 'running' | 'disposed'
60
+ /** Single flight: a concurrent request returns unavailable/busy without invoking its route. */
61
+ navigate(request: SharedNavigationRequest): SharedNavigationAnimation
62
+ dispose(): void
63
+ }
64
+ import { navigationScopes as scopes } from './scope.js'
65
+ export { sharedNavigationEntry } from './entry.js'
66
+ export type {
67
+ SharedNavigationEntry,
68
+ SharedNavigationEntryOptions,
69
+ SharedNavigationEntryEvent,
70
+ SharedNavigationRouteOptions,
71
+ } from './entry.js'
72
+ const routeOptions = Object.freeze({ animated: false as const })
73
+
74
+ /** Programmatic, same-Frame navigation. Core owns routes; Jolt owns a bounded native overlay. */
75
+ export function sharedNavigation(
76
+ frame: Frame,
77
+ options: SharedNavigationOptions = {},
78
+ ): SharedNavigation {
79
+ if (scopes.has(frame))
80
+ throw new Error('This Frame already has a shared navigation owner.')
81
+ const defaultTiming = timing(options.transition)
82
+ const navigationTimeout = options.navigationTimeout ?? 3000
83
+ const layoutTimeout = options.layoutTimeout ?? 500
84
+ const budget = options.maxSnapshotPixels ?? 8_000_000
85
+ for (const [key, value] of Object.entries({ navigationTimeout, layoutTimeout }))
86
+ if (!Number.isFinite(value) || value <= 0 || value > 10_000)
87
+ throw new RangeError(`${key} must be positive and at most 10000 ms.`)
88
+ if (!Number.isSafeInteger(budget) || budget <= 0 || budget > 32_000_000)
89
+ throw new RangeError('maxSnapshotPixels must be a positive integer at most 32000000.')
90
+ let state: SharedNavigation['state'] = 'idle'
91
+ let cancel: ((reason: string) => void) | undefined
92
+ const suspend = () => cancel?.('suspended')
93
+ const unload = () => control.dispose()
94
+ const releaseMotion = onReducedMotion((value) => {
95
+ if (value) cancel?.('reduced-motion')
96
+ })
97
+ const control: SharedNavigation = {
98
+ get state() {
99
+ return state
100
+ },
101
+ navigate(request) {
102
+ if (typeof request.tag !== 'string' || !request.tag.trim())
103
+ throw new TypeError('A nonempty sharedTransitionTag is required.')
104
+ if (typeof request.navigate !== 'function')
105
+ throw new TypeError('A navigation callback is required.')
106
+ validateReturnTarget(request.returnTarget)
107
+ if (
108
+ request.velocity &&
109
+ (!Number.isFinite(request.velocity.x) || !Number.isFinite(request.velocity.y))
110
+ )
111
+ throw new RangeError('Navigation velocity must contain finite x and y values.')
112
+ for (const key of ['holdSource', 'allowClippedSource'] as const)
113
+ if (request[key] !== undefined && typeof request[key] !== 'boolean')
114
+ throw new TypeError(`${key} must be boolean.`)
115
+ if (request.onCaptured !== undefined && typeof request.onCaptured !== 'function')
116
+ throw new TypeError('onCaptured must be a function.')
117
+ const requestedBudget = request.maxSnapshotPixels ?? budget
118
+ if (
119
+ !Number.isSafeInteger(requestedBudget) ||
120
+ requestedBudget <= 0 ||
121
+ requestedBudget > 32_000_000
122
+ )
123
+ throw new RangeError(
124
+ 'maxSnapshotPixels must be a positive integer at most 32000000.',
125
+ )
126
+ const flightBudget = Math.min(budget, requestedBudget)
127
+ const transition = timing(request.transition ?? defaultTiming)
128
+ if (state !== 'idle')
129
+ return {
130
+ finished: Promise.resolve({
131
+ status: 'unavailable',
132
+ reason: state === 'disposed' ? 'disposed' : 'busy',
133
+ navigated: false,
134
+ }),
135
+ cancel() {},
136
+ }
137
+ state = 'preparing'
138
+ let settle!: (result: SharedNavigationResult) => void
139
+ const finished = new Promise<SharedNavigationResult>((resolve) => {
140
+ settle = resolve
141
+ })
142
+ const targetScope = new ReturnScope()
143
+ let resolvedTarget: import('@nativescript/core').View | undefined
144
+ let fallbackRunning = false
145
+ let ended = false,
146
+ navigated = false,
147
+ navigationStarted = false
148
+ let detachIdentity: (() => void) | undefined
149
+ let flight: Flight | undefined, detach: (() => void) | undefined
150
+ let timer: ReturnType<typeof setTimeout> | undefined
151
+ let destination: Page | undefined
152
+ let unavailable: string | undefined
153
+ const sourcePage = frame.currentPage
154
+ const finish = (
155
+ status: SharedNavigationStatus,
156
+ reason?: string,
157
+ error?: unknown,
158
+ ) => {
159
+ if (ended) return
160
+ if (
161
+ !fallbackRunning &&
162
+ flight?.fade &&
163
+ navigated &&
164
+ status === 'unavailable' &&
165
+ request.returnTarget &&
166
+ !targetScope.signal.aborted &&
167
+ !reducedMotion()
168
+ ) {
169
+ fallbackRunning = true
170
+ targetScope.abort()
171
+ detach?.()
172
+ detach = undefined
173
+ if (timer !== undefined) clearTimeout(timer)
174
+ timer = setTimeout(() => finish(status, reason, error), 500)
175
+ flight.fade(180, () => finish(status, reason, error))
176
+ return
177
+ }
178
+ ended = true
179
+ targetScope.abort()
180
+ if (timer !== undefined) clearTimeout(timer)
181
+ detach?.()
182
+ detachIdentity?.()
183
+ frame.off('navigatingTo', navigating)
184
+ frame.off('navigatedTo', arrived)
185
+ destination?.off('unloaded', targetUnloaded)
186
+ flight?.dispose()
187
+ flight = undefined
188
+ cancel = undefined
189
+ if (state !== 'disposed') state = 'idle'
190
+ if (navigated && destination && request.returnTarget) {
191
+ let target = resolvedTarget
192
+ if (!target)
193
+ try {
194
+ target = request.returnTarget.fallbackFocus?.(destination)
195
+ } catch {}
196
+ focusReturnTarget(destination, target)
197
+ }
198
+ settle({
199
+ status,
200
+ navigated,
201
+ ...(reason ? { reason } : {}),
202
+ ...(error !== undefined ? { error } : {}),
203
+ })
204
+ }
205
+ const bound = (
206
+ milliseconds: number,
207
+ status: SharedNavigationStatus,
208
+ reason: string,
209
+ ) => {
210
+ if (timer !== undefined) clearTimeout(timer)
211
+ timer = setTimeout(() => finish(status, reason), milliseconds)
212
+ }
213
+ const targetUnloaded = () => finish('cancelled', 'target-unloaded')
214
+ const navigating = () => {
215
+ if (navigationStarted) finish('cancelled', 'navigation-interrupted')
216
+ navigationStarted = true
217
+ }
218
+ const sources = find(sourcePage, request.tag, true)
219
+ const source = sources[0]
220
+ const image = source instanceof Image
221
+ const imageSrc = image ? source.src : undefined
222
+ const imageSource = image ? source.imageSource : undefined
223
+ const arrived = () => {
224
+ if (ended) return
225
+ destination = frame.currentPage
226
+ navigated = !!destination && destination !== sourcePage
227
+ if (!navigated) {
228
+ finish('unavailable', 'route-unchanged')
229
+ return
230
+ }
231
+ if (unavailable && !request.returnTarget) {
232
+ finish('unavailable', unavailable)
233
+ return
234
+ }
235
+ if (!destination || (!flight && !request.returnTarget)) {
236
+ finish('unavailable', 'missing-target')
237
+ return
238
+ }
239
+ destination.on('unloaded', targetUnloaded)
240
+ bound(
241
+ request.returnTarget
242
+ ? (request.returnTarget.timeout ?? 1500) + 100
243
+ : layoutTimeout,
244
+ 'unavailable',
245
+ 'layout-timeout',
246
+ )
247
+ // Vue can mount the returning page's contents in its navigatedTo hook.
248
+ void Promise.resolve().then(async () => {
249
+ if (ended || !destination) return
250
+ if (request.returnTarget) {
251
+ const result = await resolveReturnTarget(
252
+ request.returnTarget,
253
+ request.tag,
254
+ destination,
255
+ targetScope.signal,
256
+ )
257
+ if (ended || targetScope.signal.aborted) return
258
+ resolvedTarget = result.view
259
+ if (result.reason) {
260
+ finish('unavailable', result.reason)
261
+ return
262
+ }
263
+ if (unavailable || !flight) {
264
+ finish('unavailable', unavailable ?? 'unsupported-source')
265
+ return
266
+ }
267
+ }
268
+ try {
269
+ const driver = getDriver()
270
+ if (!driver.afterLayout) {
271
+ finish('unavailable', 'unsupported-layout')
272
+ return
273
+ }
274
+ detach = driver.afterLayout(destination, () => {
275
+ if (ended || !flight) return
276
+ try {
277
+ const targets = find(destination, request.tag, true)
278
+ if (targets.length !== 1) {
279
+ finish(
280
+ 'unavailable',
281
+ targets.length ? 'duplicate-target' : 'missing-target',
282
+ )
283
+ return
284
+ }
285
+ const target = targets[0]!
286
+ if (request.returnTarget && target !== resolvedTarget) {
287
+ finish('unavailable', 'stale-target')
288
+ return
289
+ }
290
+ if (
291
+ image &&
292
+ (!supportedImage(target) ||
293
+ (imageSrc !== target.src && imageSource !== target.imageSource))
294
+ ) {
295
+ finish('unavailable', 'unsupported-image')
296
+ return
297
+ }
298
+ if (!image && target instanceof Image) {
299
+ finish('unavailable', 'content-mismatch')
300
+ return
301
+ }
302
+ const identityChanged = () =>
303
+ finish('cancelled', 'target-identity-changed')
304
+ const identityEvents = [
305
+ 'bindingContextChange',
306
+ 'sharedTransitionTagChange',
307
+ 'imageSourceChange',
308
+ 'unloaded',
309
+ ]
310
+ for (const event of identityEvents) target.on(event, identityChanged)
311
+ detachIdentity = () => {
312
+ for (const event of identityEvents) target.off(event, identityChanged)
313
+ }
314
+ const geometry = flight.prepare(
315
+ target,
316
+ image,
317
+ radius(target),
318
+ flightBudget,
319
+ )
320
+ if (!geometry) {
321
+ finish('unavailable', 'unsupported-target')
322
+ return
323
+ }
324
+ const json = tracks(
325
+ flight,
326
+ JSON.parse(geometry) as number[],
327
+ transition,
328
+ request.velocity,
329
+ )
330
+ const duration = Math.max(
331
+ ...(JSON.parse(json).tracks as { times: number[] }[]).map((track) =>
332
+ track.times.at(-1)!,
333
+ ),
334
+ )
335
+ state = 'running'
336
+ bound(duration + 500, 'cancelled', 'playback-timeout')
337
+ flight.play(json, (completed) =>
338
+ finish(
339
+ completed ? 'completed' : 'cancelled',
340
+ completed ? undefined : 'geometry-changed',
341
+ ),
342
+ )
343
+ } catch (error) {
344
+ finish('failed', 'preparation-failed', error)
345
+ }
346
+ })
347
+ destination.requestLayout()
348
+ } catch (error) {
349
+ finish('failed', 'preparation-failed', error)
350
+ }
351
+ })
352
+ }
353
+ cancel = (reason) => finish('cancelled', reason)
354
+ const handle = { finished, cancel: () => finish('cancelled', 'cancelled') }
355
+ try {
356
+ if (reducedMotion()) unavailable = 'reduced-motion'
357
+ else if (!frame.isLoaded || !sourcePage?.isLoaded) unavailable = 'unloaded'
358
+ else if (sources.length !== 1)
359
+ unavailable = sources.length ? 'duplicate-source' : 'missing-source'
360
+ else if (image && !supportedImage(source!)) unavailable = 'unsupported-image'
361
+ else {
362
+ try {
363
+ flight = image
364
+ ? request.allowClippedSource
365
+ ? captureNavigationImage(source!, radius(source!), flightBudget, true)
366
+ : captureNavigationImage(source!, radius(source!), flightBudget)
367
+ : capture(source!, false, radius(source!), flightBudget)
368
+ if (!flight) unavailable = 'unsupported-source'
369
+ else if (
370
+ request.holdSource &&
371
+ !flight.holdPage?.(sourcePage!, flightBudget)
372
+ ) {
373
+ flight.dispose()
374
+ flight = undefined
375
+ unavailable = 'unsupported-source-page'
376
+ }
377
+ } catch {
378
+ unavailable = 'native-unavailable'
379
+ }
380
+ }
381
+ if (flight) request.onCaptured?.()
382
+ frame.on('navigatingTo', navigating)
383
+ frame.on('navigatedTo', arrived)
384
+ bound(navigationTimeout, 'unavailable', 'navigation-timeout')
385
+ const result = request.navigate(routeOptions)
386
+ if (result && typeof (result as PromiseLike<unknown>).then === 'function') {
387
+ void Promise.resolve(result).then(
388
+ () => {
389
+ if (!ended && !navigated && frame.currentPage === sourcePage)
390
+ finish('unavailable', 'route-unchanged')
391
+ },
392
+ (error) => finish('failed', 'navigation-failed', error),
393
+ )
394
+ }
395
+ } catch (error) {
396
+ finish('failed', 'navigation-failed', error)
397
+ }
398
+ return handle
399
+ },
400
+ dispose() {
401
+ if (state === 'disposed') return
402
+ state = 'disposed'
403
+ cancel?.('disposed')
404
+ releaseMotion()
405
+ frame.off('unloaded', unload)
406
+ Application.off(Application.suspendEvent, suspend)
407
+ scopes.delete(frame)
408
+ },
409
+ }
410
+ scopes.set(frame, control)
411
+ frame.on('unloaded', unload)
412
+ Application.on(Application.suspendEvent, suspend)
413
+ return control
414
+ }
@@ -0,0 +1,41 @@
1
+ /** Small cancellation contract that works without browser globals in NativeScript. */
2
+ export interface SharedReturnSignal {
3
+ readonly aborted: boolean
4
+ addEventListener(
5
+ type: 'abort',
6
+ listener: () => void,
7
+ options?: { once?: boolean },
8
+ ): void
9
+ removeEventListener(type: 'abort', listener: () => void): void
10
+ }
11
+ export class ReturnScope {
12
+ private cancelled = false
13
+ private listeners = new Set<() => void>()
14
+ readonly signal: SharedReturnSignal
15
+ constructor() {
16
+ const scope = this
17
+ this.signal = {
18
+ get aborted() {
19
+ return scope.cancelled
20
+ },
21
+ addEventListener(_type, listener) {
22
+ if (!scope.cancelled) scope.listeners.add(listener)
23
+ },
24
+ removeEventListener(_type, listener) {
25
+ scope.listeners.delete(listener)
26
+ },
27
+ }
28
+ }
29
+ abort() {
30
+ if (this.cancelled) return
31
+ this.cancelled = true
32
+ const listeners = [...this.listeners]
33
+ this.listeners.clear()
34
+ for (const listener of listeners)
35
+ try {
36
+ listener()
37
+ } catch {
38
+ /* Observers cannot prevent cleanup. */
39
+ }
40
+ }
41
+ }
@@ -0,0 +1,197 @@
1
+ import { ReturnScope, type SharedReturnSignal } from './return-signal.js'
2
+ import {
3
+ Application,
4
+ isIOS,
5
+ type ListView,
6
+ type Page,
7
+ type View,
8
+ } from '@nativescript/core'
9
+ import { getDriver } from '../driver/index.js'
10
+ import { find } from './targets.js'
11
+
12
+ export interface SharedReturnContext {
13
+ readonly key: string
14
+ readonly tag: string
15
+ readonly page: Page
16
+ readonly signal: SharedReturnSignal
17
+ }
18
+ export interface SharedReturnTarget {
19
+ /** Stable item identity, independent of its current list position or native cell. */
20
+ key: string
21
+ resolve(
22
+ context: SharedReturnContext,
23
+ ): View | undefined | null | Promise<View | undefined | null>
24
+ /** Includes realization, scrolling and final layout. Default 1500 ms; maximum 5000. */
25
+ timeout?: number
26
+ /** Accessible fallback when the original item was deleted. Must belong to the returned page. */
27
+ fallbackFocus?: (page: Page) => View | undefined
28
+ }
29
+ export type ReturnResolution = { view?: View; reason?: string }
30
+ export function validateReturnTarget(target: SharedReturnTarget | undefined) {
31
+ if (!target) return
32
+ if (
33
+ typeof target.key !== 'string' ||
34
+ !target.key.trim() ||
35
+ typeof target.resolve !== 'function'
36
+ )
37
+ throw new TypeError('A return target needs a stable nonempty key and resolver.')
38
+ const timeout = target.timeout ?? 1500
39
+ if (!Number.isFinite(timeout) || timeout <= 0 || timeout > 5000)
40
+ throw new RangeError('Return target timeout must be positive and at most 5000 ms.')
41
+ if (target.fallbackFocus !== undefined && typeof target.fallbackFocus !== 'function')
42
+ throw new TypeError('fallbackFocus must be a function.')
43
+ }
44
+ export function afterReturnLayout(view: View, signal: SharedReturnSignal): Promise<void> {
45
+ return new Promise<void>((resolve, reject) => {
46
+ let detach: (() => void) | undefined,
47
+ done = false
48
+ const finish = (error?: Error) => {
49
+ if (done) return
50
+ done = true
51
+ detach?.()
52
+ signal.removeEventListener('abort', abort)
53
+ error ? reject(error) : resolve()
54
+ }
55
+ const abort = () => finish(new Error('return-cancelled'))
56
+ if (signal.aborted) {
57
+ abort()
58
+ return
59
+ }
60
+ signal.addEventListener('abort', abort, { once: true })
61
+ const driver = getDriver()
62
+ if (!driver.afterLayout) {
63
+ finish(new Error('unsupported-layout'))
64
+ return
65
+ }
66
+ try {
67
+ detach = driver.afterLayout(view, () => finish())
68
+ if (done) detach?.()
69
+ else view.requestLayout()
70
+ } catch (error) {
71
+ finish(error instanceof Error ? error : new Error(String(error)))
72
+ }
73
+ }).then(() => {
74
+ if (signal.aborted) throw new Error('return-cancelled')
75
+ // Core's measure/layout and UIKit's deferred table-cell realization are
76
+ // separate boundaries. Flush the latter while JS-backed delegates can run,
77
+ // including a deleted-item return where no scrollToIndex call will follow.
78
+ if (isIOS) view.nativeViewProtected?.layoutIfNeeded?.()
79
+ })
80
+ }
81
+ export async function resolveReturnTarget(
82
+ target: SharedReturnTarget,
83
+ tag: string,
84
+ page: Page,
85
+ signal: SharedReturnSignal,
86
+ ): Promise<ReturnResolution> {
87
+ const scope = new ReturnScope()
88
+ const abort = () => scope.abort()
89
+ signal.addEventListener('abort', abort, { once: true })
90
+ if (signal.aborted) scope.abort()
91
+ let timer: ReturnType<typeof setTimeout> | undefined
92
+ try {
93
+ const cancelled = new Promise<ReturnResolution>((resolve) => {
94
+ const end = () => resolve({ reason: 'target-cancelled' })
95
+ scope.signal.addEventListener('abort', end, { once: true })
96
+ if (scope.signal.aborted) end()
97
+ })
98
+ const expired = new Promise<ReturnResolution>((resolve) => {
99
+ timer = setTimeout(() => {
100
+ resolve({ reason: 'target-timeout' })
101
+ scope.abort()
102
+ }, target.timeout ?? 1500)
103
+ })
104
+ const run = async (): Promise<ReturnResolution> => {
105
+ await afterReturnLayout(page, scope.signal)
106
+ const view = await target.resolve({
107
+ key: target.key,
108
+ tag,
109
+ page,
110
+ signal: scope.signal,
111
+ })
112
+ if (scope.signal.aborted) return { reason: 'target-cancelled' }
113
+ if (!view) return { reason: 'missing-target' }
114
+ await afterReturnLayout(page, scope.signal)
115
+ const matches = find(page, tag, true)
116
+ if (matches.length !== 1)
117
+ return { reason: matches.length ? 'duplicate-target' : 'missing-target' }
118
+ if (matches[0] !== view || !view.isLoaded) return { reason: 'stale-target' }
119
+ return { view }
120
+ }
121
+ return await Promise.race([
122
+ run().catch(() => ({
123
+ reason: scope.signal.aborted ? 'target-cancelled' : 'target-resolution-failed',
124
+ })),
125
+ expired,
126
+ cancelled,
127
+ ])
128
+ } finally {
129
+ if (timer !== undefined) clearTimeout(timer)
130
+ signal.removeEventListener('abort', abort)
131
+ scope.abort()
132
+ }
133
+ }
134
+
135
+ /** Resolve a Core ListView cell after scrolling by the current key, never a saved native view/index. */
136
+ export async function resolveListTarget(
137
+ context: SharedReturnContext,
138
+ options: {
139
+ list: ListView
140
+ indexOf(key: string): number
141
+ viewForKey(key: string): View | undefined
142
+ },
143
+ ): Promise<View | undefined> {
144
+ const { list, indexOf, viewForKey } = options
145
+ let previous: { view: View; box: number[] } | undefined
146
+ for (let attempt = 0; attempt < 4 && !context.signal.aborted; attempt++) {
147
+ const index = indexOf(context.key)
148
+ if (!Number.isSafeInteger(index) || index < 0) return
149
+ list.scrollToIndex(index)
150
+ await afterReturnLayout(list, context.signal)
151
+ if (indexOf(context.key) !== index) {
152
+ previous = undefined
153
+ continue
154
+ }
155
+ const view = viewForKey(context.key)
156
+ if (view?.sharedTransitionTag !== context.tag) {
157
+ previous = undefined
158
+ continue
159
+ }
160
+ const point = view.getLocationInWindow()
161
+ const size = view?.getActualSize()
162
+ if (!point || !size || size.width <= 0 || size.height <= 0) {
163
+ previous = undefined
164
+ continue
165
+ }
166
+ const box = [point.x, point.y, size.width, size.height]
167
+ // Estimated row heights can adjust contentOffset after the first realization.
168
+ // Require the same live cell/rectangle across layout passes before handing it off.
169
+ if (
170
+ previous?.view === view &&
171
+ box.every((v, i) => Number.isFinite(v) && Math.abs(v - previous!.box[i]!) < 0.5)
172
+ )
173
+ return view
174
+ previous = { view, box }
175
+ }
176
+ }
177
+ export function focusReturnTarget(page: Page, view: View | undefined) {
178
+ if (!view || !view.isLoaded || view.page !== page) return
179
+ try {
180
+ const native = view.nativeViewProtected
181
+ if (isIOS) {
182
+ if (UIAccessibilityIsVoiceOverRunning())
183
+ UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, native)
184
+ } else {
185
+ const manager = Application.android.context?.getSystemService(
186
+ android.content.Context.ACCESSIBILITY_SERVICE,
187
+ ) as android.view.accessibility.AccessibilityManager | undefined
188
+ if (manager?.isTouchExplorationEnabled())
189
+ native?.performAccessibilityAction(
190
+ android.view.accessibility.AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS,
191
+ null,
192
+ )
193
+ }
194
+ } catch {
195
+ /* Focus cannot change the navigation outcome. */
196
+ }
197
+ }
@@ -0,0 +1,3 @@
1
+ import type { Frame } from '@nativescript/core'
2
+ import type { SharedNavigation } from './index.js'
3
+ export const navigationScopes = new WeakMap<Frame, SharedNavigation>()
@@ -0,0 +1,38 @@
1
+ import { Image, type Page, type View } from '@nativescript/core'
2
+
3
+ export function attached(view: View): boolean {
4
+ if (!view.nativeViewProtected) return false
5
+ return typeof view.getLocationInWindow === 'function'
6
+ ? view.getLocationInWindow() !== undefined
7
+ : view.isLoaded
8
+ }
9
+ export function find(page: Page | undefined, tag: string, attachedOnly = false): View[] {
10
+ const matches: View[] = []
11
+ const visit = (view: View) => {
12
+ // Nested Frames own their own identities and navigation.
13
+ if (view !== page && (view.typeName === 'Frame' || view.typeName === 'Page')) return
14
+ if (
15
+ view.sharedTransitionTag === tag &&
16
+ !view.sharedTransitionIgnore &&
17
+ (!attachedOnly || attached(view))
18
+ )
19
+ matches.push(view)
20
+ view.eachChildView((child) => {
21
+ visit(child)
22
+ return true
23
+ })
24
+ }
25
+ if (page) visit(page)
26
+ return matches
27
+ }
28
+ export const radius = (view: View) =>
29
+ typeof view.borderRadius === 'number' ? view.borderRadius : 0
30
+ export function supportedImage(view: View): view is Image {
31
+ return (
32
+ view instanceof Image &&
33
+ !!view.imageSource &&
34
+ !view.isLoading &&
35
+ (view.stretch === 'aspectFill' || view.stretch === 'aspectFit') &&
36
+ !view.tintColor
37
+ )
38
+ }