@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.
- package/README.md +167 -21
- package/dist/animate.d.ts +25 -4
- package/dist/animate.d.ts.map +1 -1
- package/dist/animate.js +67 -26
- package/dist/animate.js.map +1 -1
- package/dist/blur/index.d.ts +6 -0
- package/dist/blur/index.d.ts.map +1 -0
- package/dist/blur/index.js +196 -0
- package/dist/blur/index.js.map +1 -0
- package/dist/blur/native.d.ts +17 -0
- package/dist/blur/native.d.ts.map +1 -0
- package/dist/blur/native.js +44 -0
- package/dist/blur/native.js.map +1 -0
- package/dist/blur/types.d.ts +32 -0
- package/dist/blur/types.d.ts.map +1 -0
- package/dist/blur/types.js +2 -0
- package/dist/blur/types.js.map +1 -0
- package/dist/bottom-sheet/geometry.d.ts +18 -0
- package/dist/bottom-sheet/geometry.d.ts.map +1 -0
- package/dist/bottom-sheet/geometry.js +51 -0
- package/dist/bottom-sheet/geometry.js.map +1 -0
- package/dist/bottom-sheet/index.d.ts +56 -0
- package/dist/bottom-sheet/index.d.ts.map +1 -0
- package/dist/bottom-sheet/index.js +462 -0
- package/dist/bottom-sheet/index.js.map +1 -0
- package/dist/bottom-sheet/native.d.ts +11 -0
- package/dist/bottom-sheet/native.d.ts.map +1 -0
- package/dist/bottom-sheet/native.js +173 -0
- package/dist/bottom-sheet/native.js.map +1 -0
- package/dist/config.d.ts +9 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +40 -1
- package/dist/config.js.map +1 -1
- package/dist/decay.d.ts +1 -0
- package/dist/decay.d.ts.map +1 -1
- package/dist/decay.js +7 -0
- package/dist/decay.js.map +1 -1
- package/dist/drag-physics.d.ts +6 -1
- package/dist/drag-physics.d.ts.map +1 -1
- package/dist/drag.d.ts +17 -3
- package/dist/drag.d.ts.map +1 -1
- package/dist/drag.js +34 -11
- package/dist/drag.js.map +1 -1
- package/dist/driver/android-gradient.d.ts +5 -0
- package/dist/driver/android-gradient.d.ts.map +1 -0
- package/dist/driver/android-gradient.js +99 -0
- package/dist/driver/android-gradient.js.map +1 -0
- package/dist/driver/android-particles.d.ts +6 -0
- package/dist/driver/android-particles.d.ts.map +1 -0
- package/dist/driver/android-particles.js +93 -0
- package/dist/driver/android-particles.js.map +1 -0
- package/dist/driver/android.d.ts.map +1 -1
- package/dist/driver/android.js +27 -1
- package/dist/driver/android.js.map +1 -1
- package/dist/driver/frame.d.ts +3 -0
- package/dist/driver/frame.d.ts.map +1 -0
- package/dist/driver/frame.js +7 -0
- package/dist/driver/frame.js.map +1 -0
- package/dist/driver/index.d.ts +4 -0
- package/dist/driver/index.d.ts.map +1 -1
- package/dist/driver/index.js.map +1 -1
- package/dist/driver/ios-gradient.d.ts +5 -0
- package/dist/driver/ios-gradient.d.ts.map +1 -0
- package/dist/driver/ios-gradient.js +131 -0
- package/dist/driver/ios-gradient.js.map +1 -0
- package/dist/driver/ios-scroll-delegate.d.ts +4 -0
- package/dist/driver/ios-scroll-delegate.d.ts.map +1 -0
- package/dist/driver/ios-scroll-delegate.js +26 -0
- package/dist/driver/ios-scroll-delegate.js.map +1 -0
- package/dist/driver/ios.d.ts.map +1 -1
- package/dist/driver/ios.js +9 -0
- package/dist/driver/ios.js.map +1 -1
- package/dist/easing.d.ts +3 -1
- package/dist/easing.d.ts.map +1 -1
- package/dist/easing.js +18 -1
- package/dist/easing.js.map +1 -1
- package/dist/engine.d.ts +31 -2
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +194 -42
- package/dist/engine.js.map +1 -1
- package/dist/gesture-native.d.ts +28 -0
- package/dist/gesture-native.d.ts.map +1 -0
- package/dist/gesture-native.js +61 -0
- package/dist/gesture-native.js.map +1 -0
- package/dist/gestures/index.d.ts +69 -0
- package/dist/gestures/index.d.ts.map +1 -0
- package/dist/gestures/index.js +262 -0
- package/dist/gestures/index.js.map +1 -0
- package/dist/glass/index.d.ts +55 -0
- package/dist/glass/index.d.ts.map +1 -0
- package/dist/glass/index.js +205 -0
- package/dist/glass/index.js.map +1 -0
- package/dist/gradient-binding.d.ts +38 -0
- package/dist/gradient-binding.d.ts.map +1 -0
- package/dist/gradient-binding.js +128 -0
- package/dist/gradient-binding.js.map +1 -0
- package/dist/gradient.d.ts +105 -0
- package/dist/gradient.d.ts.map +1 -0
- package/dist/gradient.js +514 -0
- package/dist/gradient.js.map +1 -0
- package/dist/gravity.d.ts +13 -0
- package/dist/gravity.d.ts.map +1 -0
- package/dist/gravity.js +84 -0
- package/dist/gravity.js.map +1 -0
- package/dist/haptics.d.ts.map +1 -1
- package/dist/haptics.js +101 -28
- package/dist/haptics.js.map +1 -1
- package/dist/image-effect.d.ts +1 -0
- package/dist/image-effect.d.ts.map +1 -1
- package/dist/image-effect.js +10 -2
- package/dist/image-effect.js.map +1 -1
- package/dist/index.d.ts +19 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -4
- package/dist/index.js.map +1 -1
- package/dist/inspector/index.d.ts +86 -0
- package/dist/inspector/index.d.ts.map +1 -0
- package/dist/inspector/index.js +419 -0
- package/dist/inspector/index.js.map +1 -0
- package/dist/inspector/plot.d.ts +4 -0
- package/dist/inspector/plot.d.ts.map +1 -0
- package/dist/inspector/plot.js +23 -0
- package/dist/inspector/plot.js.map +1 -0
- package/dist/inspector/probe.d.ts +19 -0
- package/dist/inspector/probe.d.ts.map +1 -0
- package/dist/inspector/probe.js +37 -0
- package/dist/inspector/probe.js.map +1 -0
- package/dist/inspector/tuning.d.ts +19 -0
- package/dist/inspector/tuning.d.ts.map +1 -0
- package/dist/inspector/tuning.js +37 -0
- package/dist/inspector/tuning.js.map +1 -0
- package/dist/interactive-navigation/index.d.ts +44 -0
- package/dist/interactive-navigation/index.d.ts.map +1 -0
- package/dist/interactive-navigation/index.js +350 -0
- package/dist/interactive-navigation/index.js.map +1 -0
- package/dist/keyboard.d.ts +24 -0
- package/dist/keyboard.d.ts.map +1 -1
- package/dist/keyboard.js +199 -6
- package/dist/keyboard.js.map +1 -1
- package/dist/live-spring-driver.d.ts +52 -0
- package/dist/live-spring-driver.d.ts.map +1 -0
- package/dist/live-spring-driver.js +104 -0
- package/dist/live-spring-driver.js.map +1 -0
- package/dist/mixer.d.ts +55 -0
- package/dist/mixer.d.ts.map +1 -0
- package/dist/mixer.js +286 -0
- package/dist/mixer.js.map +1 -0
- package/dist/motion-scope.d.ts +8 -2
- package/dist/motion-scope.d.ts.map +1 -1
- package/dist/motion-scope.js +24 -3
- package/dist/motion-scope.js.map +1 -1
- package/dist/motion-states.d.ts +19 -7
- package/dist/motion-states.d.ts.map +1 -1
- package/dist/motion-states.js +116 -26
- package/dist/motion-states.js.map +1 -1
- package/dist/motion-value.d.ts +227 -0
- package/dist/motion-value.d.ts.map +1 -0
- package/dist/motion-value.js +1074 -0
- package/dist/motion-value.js.map +1 -0
- package/dist/native/index.d.ts +10 -0
- package/dist/native/index.d.ts.map +1 -0
- package/dist/native/index.js +6 -0
- package/dist/native/index.js.map +1 -0
- package/dist/native-properties.d.ts +28 -0
- package/dist/native-properties.d.ts.map +1 -0
- package/dist/native-properties.js +154 -0
- package/dist/native-properties.js.map +1 -0
- package/dist/native-property-driver.d.ts +19 -0
- package/dist/native-property-driver.d.ts.map +1 -0
- package/dist/native-property-driver.js +69 -0
- package/dist/native-property-driver.js.map +1 -0
- package/dist/native-property.d.ts +37 -0
- package/dist/native-property.d.ts.map +1 -0
- package/dist/native-property.js +285 -0
- package/dist/native-property.js.map +1 -0
- package/dist/particles.d.ts +5 -2
- package/dist/particles.d.ts.map +1 -1
- package/dist/particles.js +16 -10
- package/dist/particles.js.map +1 -1
- package/dist/path.d.ts.map +1 -1
- package/dist/path.js +2 -2
- package/dist/path.js.map +1 -1
- package/dist/physics/index.d.ts +139 -0
- package/dist/physics/index.d.ts.map +1 -0
- package/dist/physics/index.js +316 -0
- package/dist/physics/index.js.map +1 -0
- package/dist/physics/native.d.ts +54 -0
- package/dist/physics/native.d.ts.map +1 -0
- package/dist/physics/native.js +64 -0
- package/dist/physics/native.js.map +1 -0
- package/dist/playback-group.d.ts.map +1 -1
- package/dist/playback-group.js +17 -1
- package/dist/playback-group.js.map +1 -1
- package/dist/playback.d.ts +15 -0
- package/dist/playback.d.ts.map +1 -1
- package/dist/playback.js +23 -0
- package/dist/playback.js.map +1 -1
- package/dist/predictive-back/index.d.ts +45 -0
- package/dist/predictive-back/index.d.ts.map +1 -0
- package/dist/predictive-back/index.js +220 -0
- package/dist/predictive-back/index.js.map +1 -0
- package/dist/predictive-back/presentation.d.ts +4 -0
- package/dist/predictive-back/presentation.d.ts.map +1 -0
- package/dist/predictive-back/presentation.js +3 -0
- package/dist/predictive-back/presentation.js.map +1 -0
- package/dist/press.d.ts.map +1 -1
- package/dist/press.js +11 -2
- package/dist/press.js.map +1 -1
- package/dist/reorder/handle.d.ts +6 -0
- package/dist/reorder/handle.d.ts.map +1 -0
- package/dist/reorder/handle.js +10 -0
- package/dist/reorder/handle.js.map +1 -0
- package/dist/reorder/index.d.ts +10 -0
- package/dist/reorder/index.d.ts.map +1 -0
- package/dist/reorder/index.js +233 -0
- package/dist/reorder/index.js.map +1 -0
- package/dist/reorder/list-view.d.ts +5 -0
- package/dist/reorder/list-view.d.ts.map +1 -0
- package/dist/reorder/list-view.js +238 -0
- package/dist/reorder/list-view.js.map +1 -0
- package/dist/reorder/model.d.ts +6 -0
- package/dist/reorder/model.d.ts.map +1 -0
- package/dist/reorder/model.js +30 -0
- package/dist/reorder/model.js.map +1 -0
- package/dist/reorder/surface.d.ts +6 -0
- package/dist/reorder/surface.d.ts.map +1 -0
- package/dist/reorder/surface.js +10 -0
- package/dist/reorder/surface.js.map +1 -0
- package/dist/reorder/types.d.ts +92 -0
- package/dist/reorder/types.d.ts.map +1 -0
- package/dist/reorder/types.js +2 -0
- package/dist/reorder/types.js.map +1 -0
- package/dist/sampling.d.ts +35 -0
- package/dist/sampling.d.ts.map +1 -0
- package/dist/sampling.js +123 -0
- package/dist/sampling.js.map +1 -0
- package/dist/scene-appearance.d.ts +14 -0
- package/dist/scene-appearance.d.ts.map +1 -0
- package/dist/scene-appearance.js +68 -0
- package/dist/scene-appearance.js.map +1 -0
- package/dist/scene-camera.d.ts +5 -0
- package/dist/scene-camera.d.ts.map +1 -0
- package/dist/scene-camera.js +23 -0
- package/dist/scene-camera.js.map +1 -0
- package/dist/scene-shader.d.ts +18 -0
- package/dist/scene-shader.d.ts.map +1 -0
- package/dist/scene-shader.js +76 -0
- package/dist/scene-shader.js.map +1 -0
- package/dist/scroll-header/geometry.d.ts +18 -0
- package/dist/scroll-header/geometry.d.ts.map +1 -0
- package/dist/scroll-header/geometry.js +46 -0
- package/dist/scroll-header/geometry.js.map +1 -0
- package/dist/scroll-header/index.d.ts +48 -0
- package/dist/scroll-header/index.d.ts.map +1 -0
- package/dist/scroll-header/index.js +399 -0
- package/dist/scroll-header/index.js.map +1 -0
- package/dist/scroll-header/native.d.ts +28 -0
- package/dist/scroll-header/native.d.ts.map +1 -0
- package/dist/scroll-header/native.js +43 -0
- package/dist/scroll-header/native.js.map +1 -0
- package/dist/sensors/index.d.ts +69 -0
- package/dist/sensors/index.d.ts.map +1 -0
- package/dist/sensors/index.js +149 -0
- package/dist/sensors/index.js.map +1 -0
- package/dist/sensors/native.d.ts +20 -0
- package/dist/sensors/native.d.ts.map +1 -0
- package/dist/sensors/native.js +48 -0
- package/dist/sensors/native.js.map +1 -0
- package/dist/sequence.d.ts +24 -0
- package/dist/sequence.d.ts.map +1 -1
- package/dist/sequence.js +181 -19
- package/dist/sequence.js.map +1 -1
- package/dist/shapes/android.d.ts +3 -0
- package/dist/shapes/android.d.ts.map +1 -0
- package/dist/shapes/android.js +51 -0
- package/dist/shapes/android.js.map +1 -0
- package/dist/shapes/index.d.ts +6 -0
- package/dist/shapes/index.d.ts.map +1 -0
- package/dist/shapes/index.js +238 -0
- package/dist/shapes/index.js.map +1 -0
- package/dist/shapes/ios.d.ts +3 -0
- package/dist/shapes/ios.d.ts.map +1 -0
- package/dist/shapes/ios.js +164 -0
- package/dist/shapes/ios.js.map +1 -0
- package/dist/shapes/native.d.ts +18 -0
- package/dist/shapes/native.d.ts.map +1 -0
- package/dist/shapes/native.js +10 -0
- package/dist/shapes/native.js.map +1 -0
- package/dist/shapes/path.d.ts +10 -0
- package/dist/shapes/path.d.ts.map +1 -0
- package/dist/shapes/path.js +106 -0
- package/dist/shapes/path.js.map +1 -0
- package/dist/shapes/types.d.ts +55 -0
- package/dist/shapes/types.d.ts.map +1 -0
- package/dist/shapes/types.js +11 -0
- package/dist/shapes/types.js.map +1 -0
- package/dist/shared-layout/index.d.ts +40 -0
- package/dist/shared-layout/index.d.ts.map +1 -0
- package/dist/shared-layout/index.js +267 -0
- package/dist/shared-layout/index.js.map +1 -0
- package/dist/shared-layout/native.d.ts +15 -0
- package/dist/shared-layout/native.d.ts.map +1 -0
- package/dist/shared-layout/native.js +79 -0
- package/dist/shared-layout/native.js.map +1 -0
- package/dist/shared-layout/timing.d.ts +9 -0
- package/dist/shared-layout/timing.d.ts.map +1 -0
- package/dist/shared-layout/timing.js +68 -0
- package/dist/shared-layout/timing.js.map +1 -0
- package/dist/shared-navigation/entry.d.ts +51 -0
- package/dist/shared-navigation/entry.d.ts.map +1 -0
- package/dist/shared-navigation/entry.js +619 -0
- package/dist/shared-navigation/entry.js.map +1 -0
- package/dist/shared-navigation/index.d.ts +58 -0
- package/dist/shared-navigation/index.d.ts.map +1 -0
- package/dist/shared-navigation/index.js +318 -0
- package/dist/shared-navigation/index.js.map +1 -0
- package/dist/shared-navigation/return-signal.d.ts +16 -0
- package/dist/shared-navigation/return-signal.d.ts.map +1 -0
- package/dist/shared-navigation/return-signal.js +35 -0
- package/dist/shared-navigation/return-signal.js.map +1 -0
- package/dist/shared-navigation/return-target.d.ts +32 -0
- package/dist/shared-navigation/return-target.d.ts.map +1 -0
- package/dist/shared-navigation/return-target.js +168 -0
- package/dist/shared-navigation/return-target.js.map +1 -0
- package/dist/shared-navigation/scope.d.ts +4 -0
- package/dist/shared-navigation/scope.d.ts.map +1 -0
- package/dist/shared-navigation/scope.js +2 -0
- package/dist/shared-navigation/scope.js.map +1 -0
- package/dist/shared-navigation/targets.d.ts +6 -0
- package/dist/shared-navigation/targets.d.ts.map +1 -0
- package/dist/shared-navigation/targets.js +36 -0
- package/dist/shared-navigation/targets.js.map +1 -0
- package/dist/size-layout.d.ts +19 -0
- package/dist/size-layout.d.ts.map +1 -0
- package/dist/size-layout.js +216 -0
- package/dist/size-layout.js.map +1 -0
- package/dist/size.d.ts +19 -0
- package/dist/size.d.ts.map +1 -0
- package/dist/size.js +251 -0
- package/dist/size.js.map +1 -0
- package/dist/spring.d.ts +2 -0
- package/dist/spring.d.ts.map +1 -1
- package/dist/spring.js +11 -0
- package/dist/spring.js.map +1 -1
- package/dist/svg-path.d.ts +18 -0
- package/dist/svg-path.d.ts.map +1 -1
- package/dist/svg-path.js +3 -2
- package/dist/svg-path.js.map +1 -1
- package/dist/testing/clock.d.ts +40 -0
- package/dist/testing/clock.d.ts.map +1 -0
- package/dist/testing/clock.js +116 -0
- package/dist/testing/clock.js.map +1 -0
- package/dist/testing/handoff-recorder.d.ts +8 -0
- package/dist/testing/handoff-recorder.d.ts.map +1 -0
- package/dist/testing/handoff-recorder.js +77 -0
- package/dist/testing/handoff-recorder.js.map +1 -0
- package/dist/testing/index.d.ts +5 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +5 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/native.d.ts +46 -0
- package/dist/testing/native.d.ts.map +1 -0
- package/dist/testing/native.js +313 -0
- package/dist/testing/native.js.map +1 -0
- package/dist/testing/presentation.d.ts +11 -0
- package/dist/testing/presentation.d.ts.map +1 -0
- package/dist/testing/presentation.js +45 -0
- package/dist/testing/presentation.js.map +1 -0
- package/dist/testing/replay.d.ts +39 -0
- package/dist/testing/replay.d.ts.map +1 -0
- package/dist/testing/replay.js +99 -0
- package/dist/testing/replay.js.map +1 -0
- package/dist/testing/scroll-handoff-native.d.ts +10 -0
- package/dist/testing/scroll-handoff-native.d.ts.map +1 -0
- package/dist/testing/scroll-handoff-native.js +151 -0
- package/dist/testing/scroll-handoff-native.js.map +1 -0
- package/dist/testing/scroll-handoff.d.ts +25 -0
- package/dist/testing/scroll-handoff.d.ts.map +1 -0
- package/dist/testing/scroll-handoff.js +127 -0
- package/dist/testing/scroll-handoff.js.map +1 -0
- package/dist/testing/sensors.d.ts +13 -0
- package/dist/testing/sensors.d.ts.map +1 -0
- package/dist/testing/sensors.js +26 -0
- package/dist/testing/sensors.js.map +1 -0
- package/dist/testing/trace.d.ts +101 -0
- package/dist/testing/trace.d.ts.map +1 -0
- package/dist/testing/trace.js +263 -0
- package/dist/testing/trace.js.map +1 -0
- package/dist/timed-animation.d.ts +38 -0
- package/dist/timed-animation.d.ts.map +1 -0
- package/dist/timed-animation.js +177 -0
- package/dist/timed-animation.js.map +1 -0
- package/dist/track.d.ts +3 -0
- package/dist/track.d.ts.map +1 -1
- package/dist/track.js +281 -40
- package/dist/track.js.map +1 -1
- package/dist/transition.d.ts +54 -2
- package/dist/transition.d.ts.map +1 -1
- package/dist/transition.js +128 -8
- package/dist/transition.js.map +1 -1
- package/dist/types.d.ts +10 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/value-observers.d.ts +22 -0
- package/dist/value-observers.d.ts.map +1 -0
- package/dist/value-observers.js +122 -0
- package/dist/value-observers.js.map +1 -0
- package/dist/value-track.d.ts +13 -0
- package/dist/value-track.d.ts.map +1 -0
- package/dist/value-track.js +59 -0
- package/dist/value-track.js.map +1 -0
- package/dist/vue/index.d.ts +33 -3
- package/dist/vue/index.d.ts.map +1 -1
- package/dist/vue/index.js +118 -3
- package/dist/vue/index.js.map +1 -1
- package/dist/zoomable.d.ts +1 -1
- package/dist/zoomable.d.ts.map +1 -1
- package/package.json +68 -3
- package/platforms/android/include.gradle +10 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/BlurEffect.java +89 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/CircleMath.java +158 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/CircleWorld.java +221 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/GestureSession.java +227 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/GestureSurface.java +54 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/GradientLayer.java +224 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/KeyboardFrame.java +53 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/KeyboardFrameFollower.java +57 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/KeyboardObserver.java +97 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/LiveSpring.java +277 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/MotionProbe.java +70 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/ParticleEmitter.java +192 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/ParticleSimulation.java +114 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/PredictiveBackSession.java +212 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/ReorderHandle.java +25 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/ReorderSession.java +213 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/ReorderSurface.java +27 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/ScrollHeader.java +84 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/SensorMath.java +28 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/SensorSource.java +217 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/ShapeLayer.java +120 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/SharedLayoutFlight.java +287 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/SharedNavigationScene.java +115 -0
- package/platforms/android/java/org/rafaelaugusto/jolt/SpringState.java +39 -0
- package/platforms/android/proguard-rules.pro +20 -0
- package/platforms/ios/build.xcconfig +1 -1
- package/platforms/ios/src/JoltBlur.h +14 -0
- package/platforms/ios/src/JoltBlur.m +86 -0
- package/platforms/ios/src/JoltCircleMath.h +191 -0
- package/platforms/ios/src/JoltCircleWorld.h +18 -0
- package/platforms/ios/src/JoltCircleWorld.m +218 -0
- package/platforms/ios/src/JoltGestureSession.h +23 -0
- package/platforms/ios/src/JoltGestureSession.m +251 -0
- package/platforms/ios/src/JoltInteractiveNavigation.h +23 -0
- package/platforms/ios/src/JoltInteractiveNavigation.m +255 -0
- package/platforms/ios/src/JoltLiveSpring.h +29 -0
- package/platforms/ios/src/JoltLiveSpring.m +243 -0
- package/platforms/ios/src/JoltMotionProbe.h +9 -0
- package/platforms/ios/src/JoltMotionProbe.m +72 -0
- package/platforms/ios/src/JoltReorderSession.h +15 -0
- package/platforms/ios/src/JoltReorderSession.m +205 -0
- package/platforms/ios/src/JoltScrollHeader.h +13 -0
- package/platforms/ios/src/JoltScrollHeader.m +101 -0
- package/platforms/ios/src/JoltSensorMath.h +39 -0
- package/platforms/ios/src/JoltSensorSource.h +13 -0
- package/platforms/ios/src/JoltSensorSource.m +201 -0
- package/platforms/ios/src/JoltSharedLayoutFlight.h +19 -0
- package/platforms/ios/src/JoltSharedLayoutFlight.m +250 -0
- package/platforms/ios/src/JoltSpringState.h +35 -0
- package/platforms/ios/src/module.modulemap +10 -0
- package/src/android-plugin.d.ts +464 -0
- package/src/animate.ts +129 -15
- package/src/blur/index.ts +195 -0
- package/src/blur/native.ts +70 -0
- package/src/blur/types.ts +32 -0
- package/src/bottom-sheet/geometry.ts +84 -0
- package/src/bottom-sheet/index.ts +536 -0
- package/src/bottom-sheet/native.ts +214 -0
- package/src/config.ts +39 -1
- package/src/decay.ts +9 -0
- package/src/drag.ts +67 -21
- package/src/driver/android-gradient.ts +116 -0
- package/src/driver/android-particles.ts +118 -0
- package/src/driver/android.ts +31 -1
- package/src/driver/frame.ts +10 -0
- package/src/driver/index.ts +4 -0
- package/src/driver/ios-gradient.ts +136 -0
- package/src/driver/ios-scroll-delegate.ts +23 -0
- package/src/driver/ios.ts +10 -0
- package/src/easing.ts +21 -1
- package/src/engine.ts +209 -60
- package/src/gesture-native.ts +139 -0
- package/src/gestures/index.ts +365 -0
- package/src/glass/index.ts +218 -0
- package/src/gradient-binding.ts +158 -0
- package/src/gradient.ts +663 -0
- package/src/gravity.ts +107 -0
- package/src/haptics.ts +106 -28
- package/src/image-effect.ts +10 -2
- package/src/index.ts +56 -7
- package/src/inspector/index.ts +523 -0
- package/src/inspector/plot.ts +27 -0
- package/src/inspector/probe.ts +50 -0
- package/src/inspector/tuning.ts +51 -0
- package/src/interactive-navigation/index.ts +427 -0
- package/src/ios-plugin.d.ts +280 -0
- package/src/keyboard.ts +231 -7
- package/src/live-spring-driver.ts +181 -0
- package/src/mixer.ts +312 -0
- package/src/motion-scope.ts +39 -6
- package/src/motion-states.ts +149 -42
- package/src/motion-value.ts +1289 -0
- package/src/native/index.ts +30 -0
- package/src/native-properties.ts +188 -0
- package/src/native-property-driver.ts +123 -0
- package/src/native-property.ts +366 -0
- package/src/particles.ts +18 -17
- package/src/path.ts +2 -1
- package/src/physics/index.ts +476 -0
- package/src/physics/native.ts +121 -0
- package/src/playback-group.ts +17 -1
- package/src/playback.ts +41 -0
- package/src/predictive-back/index.ts +280 -0
- package/src/predictive-back/presentation.ts +6 -0
- package/src/press.ts +10 -2
- package/src/reorder/handle.ts +9 -0
- package/src/reorder/index.ts +243 -0
- package/src/reorder/list-view.ts +262 -0
- package/src/reorder/model.ts +47 -0
- package/src/reorder/surface.ts +10 -0
- package/src/reorder/types.ts +87 -0
- package/src/sampling.ts +173 -0
- package/src/scene-appearance.ts +92 -0
- package/src/scene-camera.ts +30 -0
- package/src/scene-shader.ts +139 -0
- package/src/scroll-header/geometry.ts +88 -0
- package/src/scroll-header/index.ts +530 -0
- package/src/scroll-header/native.ts +89 -0
- package/src/sensors/index.ts +246 -0
- package/src/sensors/native.ts +72 -0
- package/src/sequence.ts +209 -20
- package/src/shapes/android.ts +63 -0
- package/src/shapes/index.ts +267 -0
- package/src/shapes/ios.ts +194 -0
- package/src/shapes/native.ts +27 -0
- package/src/shapes/path.ts +127 -0
- package/src/shapes/types.ts +63 -0
- package/src/shared-layout/index.ts +343 -0
- package/src/shared-layout/native.ts +138 -0
- package/src/shared-layout/timing.ts +87 -0
- package/src/shared-navigation/entry.ts +695 -0
- package/src/shared-navigation/index.ts +414 -0
- package/src/shared-navigation/return-signal.ts +41 -0
- package/src/shared-navigation/return-target.ts +197 -0
- package/src/shared-navigation/scope.ts +3 -0
- package/src/shared-navigation/targets.ts +38 -0
- package/src/size-layout.ts +237 -0
- package/src/size.ts +302 -0
- package/src/spring.ts +18 -0
- package/src/svg-path.ts +8 -3
- package/src/testing/clock.ts +128 -0
- package/src/testing/handoff-recorder.ts +98 -0
- package/src/testing/index.ts +4 -0
- package/src/testing/native.ts +386 -0
- package/src/testing/presentation.ts +46 -0
- package/src/testing/replay.ts +149 -0
- package/src/testing/scroll-handoff-native.ts +201 -0
- package/src/testing/scroll-handoff.ts +140 -0
- package/src/testing/sensors.ts +41 -0
- package/src/testing/trace.ts +340 -0
- package/src/timed-animation.ts +192 -0
- package/src/track.ts +334 -38
- package/src/transition.ts +197 -9
- package/src/types.ts +11 -1
- package/src/value-observers.ts +147 -0
- package/src/value-track.ts +71 -0
- package/src/vue/index.ts +147 -1
- package/src/zoomable.ts +1 -1
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import {
|
|
2
|
+
parseTrace,
|
|
3
|
+
traceRandom,
|
|
4
|
+
type InteractionTrace,
|
|
5
|
+
type TraceInput,
|
|
6
|
+
type TraceState,
|
|
7
|
+
} from './trace.js'
|
|
8
|
+
|
|
9
|
+
export interface ReplayAdapter {
|
|
10
|
+
input(event: TraceInput): void | Promise<void>
|
|
11
|
+
read(id: string): TraceState
|
|
12
|
+
dispose(): void | Promise<void>
|
|
13
|
+
/** Owned subscriptions/handles remaining after dispose; must be zero. */
|
|
14
|
+
resources(): number
|
|
15
|
+
}
|
|
16
|
+
export interface ReplayObservation {
|
|
17
|
+
at: number
|
|
18
|
+
id: string
|
|
19
|
+
expected: TraceState
|
|
20
|
+
observed: TraceState
|
|
21
|
+
positionError: number
|
|
22
|
+
velocityError: number
|
|
23
|
+
passed: boolean
|
|
24
|
+
}
|
|
25
|
+
export interface ReplayReport {
|
|
26
|
+
passed: boolean
|
|
27
|
+
observations: ReplayObservation[]
|
|
28
|
+
errors: string[]
|
|
29
|
+
remainingResources: number
|
|
30
|
+
trace: InteractionTrace
|
|
31
|
+
/** A compact expected/observed SVG, useful as a failure artifact. */
|
|
32
|
+
plot: string
|
|
33
|
+
}
|
|
34
|
+
export interface ReplayOptions {
|
|
35
|
+
advanceTo(at: number): void | Promise<void>
|
|
36
|
+
/** Construct fresh state for each replay. Include the supplied seed in random effects. */
|
|
37
|
+
create(trace: InteractionTrace, random: () => number): ReplayAdapter
|
|
38
|
+
signal?: { readonly aborted: boolean }
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Ordered replay at original timestamps. A 250 ms gap advances once, never fifteen fake frames. */
|
|
42
|
+
export async function replayInteraction(
|
|
43
|
+
value: InteractionTrace | string,
|
|
44
|
+
options: ReplayOptions,
|
|
45
|
+
): Promise<ReplayReport> {
|
|
46
|
+
const trace = parseTrace(value)
|
|
47
|
+
const observations: ReplayObservation[] = [],
|
|
48
|
+
errors: string[] = []
|
|
49
|
+
let adapter: ReplayAdapter | undefined,
|
|
50
|
+
remainingResources = 0
|
|
51
|
+
try {
|
|
52
|
+
if (!trace.entries.some((entry) => 'expected' in entry))
|
|
53
|
+
throw new Error('A regression trace needs at least one checkpoint.')
|
|
54
|
+
adapter = options.create(trace, traceRandom(trace.seed))
|
|
55
|
+
let previous = -1
|
|
56
|
+
for (const entry of trace.entries) {
|
|
57
|
+
if (options.signal?.aborted) throw new Error('Replay cancelled.')
|
|
58
|
+
if (entry.at !== previous) {
|
|
59
|
+
await options.advanceTo(entry.at)
|
|
60
|
+
previous = entry.at
|
|
61
|
+
}
|
|
62
|
+
if ('input' in entry) await adapter.input(entry.input)
|
|
63
|
+
else {
|
|
64
|
+
const value = adapter.read(entry.id)
|
|
65
|
+
const observed = {
|
|
66
|
+
position: value.position,
|
|
67
|
+
velocity: value.velocity,
|
|
68
|
+
settled: value.settled,
|
|
69
|
+
}
|
|
70
|
+
const positionError = Math.abs(observed.position - entry.expected.position)
|
|
71
|
+
const velocityError = Math.abs(observed.velocity - entry.expected.velocity)
|
|
72
|
+
const passed =
|
|
73
|
+
typeof observed.position === 'number' &&
|
|
74
|
+
typeof observed.velocity === 'number' &&
|
|
75
|
+
typeof observed.settled === 'boolean' &&
|
|
76
|
+
Number.isFinite(positionError) &&
|
|
77
|
+
Number.isFinite(velocityError) &&
|
|
78
|
+
positionError <= entry.tolerance.position &&
|
|
79
|
+
velocityError <= entry.tolerance.velocity &&
|
|
80
|
+
observed.settled === entry.expected.settled
|
|
81
|
+
observations.push({
|
|
82
|
+
at: entry.at,
|
|
83
|
+
id: entry.id,
|
|
84
|
+
expected: entry.expected,
|
|
85
|
+
observed: { ...observed },
|
|
86
|
+
positionError,
|
|
87
|
+
velocityError,
|
|
88
|
+
passed,
|
|
89
|
+
})
|
|
90
|
+
if (!passed)
|
|
91
|
+
errors.push(
|
|
92
|
+
`${entry.id} at ${entry.at} ms: position error ${positionError}, velocity error ${velocityError}, settled ${observed.settled} (expected ${entry.expected.settled}).`,
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
} catch (error) {
|
|
97
|
+
errors.push(error instanceof Error ? error.message : 'Replay adapter failed.')
|
|
98
|
+
} finally {
|
|
99
|
+
if (adapter) {
|
|
100
|
+
try {
|
|
101
|
+
await adapter.dispose()
|
|
102
|
+
} catch {
|
|
103
|
+
errors.push('Replay adapter disposal failed.')
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
remainingResources = adapter.resources()
|
|
107
|
+
if (!Number.isSafeInteger(remainingResources) || remainingResources !== 0)
|
|
108
|
+
errors.push('Replay left owned subscriptions or handles alive.')
|
|
109
|
+
} catch {
|
|
110
|
+
remainingResources = -1
|
|
111
|
+
errors.push('Replay resource audit failed.')
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
passed: errors.length === 0,
|
|
117
|
+
observations,
|
|
118
|
+
errors,
|
|
119
|
+
remainingResources,
|
|
120
|
+
trace,
|
|
121
|
+
plot: replayPlot(observations),
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** IDs are validated by parseTrace; plotted values must be finite before entering SVG. */
|
|
126
|
+
export function replayPlot(samples: readonly ReplayObservation[]): string {
|
|
127
|
+
const finite = samples.filter((s) =>
|
|
128
|
+
[s.at, s.expected.position, s.observed.position].every(Number.isFinite),
|
|
129
|
+
)
|
|
130
|
+
const end = Math.max(1, ...finite.map((s) => s.at))
|
|
131
|
+
const min = Math.min(
|
|
132
|
+
0,
|
|
133
|
+
...finite.flatMap((s) => [s.expected.position, s.observed.position]),
|
|
134
|
+
)
|
|
135
|
+
const max = Math.max(
|
|
136
|
+
min + 1,
|
|
137
|
+
...finite.flatMap((s) => [s.expected.position, s.observed.position]),
|
|
138
|
+
)
|
|
139
|
+
const point = (at: number, y: number) =>
|
|
140
|
+
`${(40 + (at / end) * 560).toFixed(2)},${(180 - ((y - min) / (max - min)) * 140).toFixed(2)}`
|
|
141
|
+
const ids = [...new Set(finite.map((s) => s.id))]
|
|
142
|
+
const lines = ids
|
|
143
|
+
.map((id) => {
|
|
144
|
+
const rows = finite.filter((s) => s.id === id)
|
|
145
|
+
return `<polyline fill="none" stroke="#176b5b" stroke-width="2" points="${rows.map((s) => point(s.at, s.expected.position)).join(' ')}"/><polyline fill="none" stroke="#b7355f" stroke-width="2" stroke-dasharray="4 3" points="${rows.map((s) => point(s.at, s.observed.position)).join(' ')}"/>`
|
|
146
|
+
})
|
|
147
|
+
.join('')
|
|
148
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="640" height="220" viewBox="0 0 640 220"><rect width="640" height="220" fill="#faf8f1"/><g font-family="sans-serif" font-size="12" fill="#202630"><text x="20" y="20">Presentation position (DIP): green expected / pink observed</text><text x="40" y="205">0 ms</text><text x="540" y="205">${end.toFixed(0)} ms</text><text x="8" y="45">${max.toFixed(0)}</text><text x="8" y="180">${min.toFixed(0)}</text></g><path d="M40 35 V180 H605" fill="none" stroke="#bfc5be"/>${lines}</svg>`
|
|
149
|
+
}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { isIOS, ScrollView, Utils, type View } from '@nativescript/core'
|
|
2
|
+
import { GestureSurface } from '../gestures/index.js'
|
|
3
|
+
import {
|
|
4
|
+
liveSpringDriver,
|
|
5
|
+
nativeLiveNode,
|
|
6
|
+
type LiveNode,
|
|
7
|
+
type LiveBinding,
|
|
8
|
+
} from '../live-spring-driver.js'
|
|
9
|
+
import { retainScrollDelegate } from '../driver/ios-scroll-delegate.js'
|
|
10
|
+
import { nativeTracePosition } from './native.js'
|
|
11
|
+
import {
|
|
12
|
+
handoffIds,
|
|
13
|
+
handoffInput,
|
|
14
|
+
handoffMotions,
|
|
15
|
+
type HandoffIds,
|
|
16
|
+
} from './scroll-handoff.js'
|
|
17
|
+
import type { TraceMotion } from './trace.js'
|
|
18
|
+
import type { ReplayAdapter } from './replay.js'
|
|
19
|
+
|
|
20
|
+
/** Isolated native contact replay. Uses the production gesture session's consumption code.
|
|
21
|
+
* It holds the sheet at release; free spring settling and OS recognition are separate tests.
|
|
22
|
+
*/
|
|
23
|
+
export function nativeScrollHandoffTraceGraph(
|
|
24
|
+
motions: readonly TraceMotion[],
|
|
25
|
+
surface: GestureSurface,
|
|
26
|
+
scroll: ScrollView,
|
|
27
|
+
ids: HandoffIds = handoffIds,
|
|
28
|
+
): ReplayAdapter {
|
|
29
|
+
const config = handoffMotions(motions, ids)
|
|
30
|
+
let parent: View | undefined = scroll.parent as View | undefined
|
|
31
|
+
while (parent && parent !== surface) parent = parent.parent as View | undefined
|
|
32
|
+
if (
|
|
33
|
+
!(surface instanceof GestureSurface) ||
|
|
34
|
+
!(scroll instanceof ScrollView) ||
|
|
35
|
+
scroll.orientation !== 'vertical' ||
|
|
36
|
+
parent !== surface ||
|
|
37
|
+
!surface.isLoaded ||
|
|
38
|
+
!scroll.isLoaded
|
|
39
|
+
)
|
|
40
|
+
throw new TypeError(
|
|
41
|
+
'Handoff replay requires a loaded GestureSurface and descendant vertical ScrollView.',
|
|
42
|
+
)
|
|
43
|
+
if (
|
|
44
|
+
isIOS
|
|
45
|
+
? typeof JoltGestureSession === 'undefined' ||
|
|
46
|
+
!JoltGestureSession.supportsScrollReplay?.()
|
|
47
|
+
: typeof org === 'undefined' ||
|
|
48
|
+
!org.rafaelaugusto.jolt.GestureSession.supportsScrollReplay?.()
|
|
49
|
+
)
|
|
50
|
+
throw new Error('Rebuild the native app to use scroll handoff replay.')
|
|
51
|
+
if (Math.abs(scroll.scrollableHeight - config.scroll.max) > 1)
|
|
52
|
+
throw new RangeError('The loaded scroll range differs from the recorded geometry.')
|
|
53
|
+
if (
|
|
54
|
+
isIOS
|
|
55
|
+
? JoltGestureSession.hasSession(surface.nativeViewProtected)
|
|
56
|
+
: (
|
|
57
|
+
surface.nativeViewProtected as org.rafaelaugusto.jolt.GestureSurface
|
|
58
|
+
).hasSession()
|
|
59
|
+
)
|
|
60
|
+
throw new Error('Replay requires an unowned gesture surface.')
|
|
61
|
+
const count = () =>
|
|
62
|
+
isIOS ? JoltLiveSpring.nodeCount() : org.rafaelaugusto.jolt.LiveSpring.nodeCount()
|
|
63
|
+
const baseline = count(),
|
|
64
|
+
nodes: LiveNode[] = []
|
|
65
|
+
const surfaceInput = surface.isUserInteractionEnabled,
|
|
66
|
+
scrollInput = scroll.isUserInteractionEnabled
|
|
67
|
+
let claimedInput = false
|
|
68
|
+
let binding: LiveBinding | undefined,
|
|
69
|
+
releaseDelegate = () => {},
|
|
70
|
+
disposed = false,
|
|
71
|
+
ownsVelocity = false
|
|
72
|
+
let session:
|
|
73
|
+
| {
|
|
74
|
+
input(phase: number, delta: number, velocity: number): void
|
|
75
|
+
offset(value: number): void
|
|
76
|
+
dispose(): void
|
|
77
|
+
}
|
|
78
|
+
| undefined
|
|
79
|
+
const dispose = () => {
|
|
80
|
+
if (disposed) return
|
|
81
|
+
disposed = true
|
|
82
|
+
try {
|
|
83
|
+
session?.dispose()
|
|
84
|
+
} finally {
|
|
85
|
+
releaseDelegate()
|
|
86
|
+
binding?.cancel()
|
|
87
|
+
nodes.forEach((node) => node.dispose())
|
|
88
|
+
if (claimedInput) {
|
|
89
|
+
surface.isUserInteractionEnabled = surfaceInput
|
|
90
|
+
scroll.isUserInteractionEnabled = scrollInput
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
const physics = {
|
|
96
|
+
stiffness: config.sheet.stiffness,
|
|
97
|
+
damping: config.sheet.damping,
|
|
98
|
+
mass: config.sheet.mass,
|
|
99
|
+
restDelta: 0.001,
|
|
100
|
+
restSpeed: 0.01,
|
|
101
|
+
}
|
|
102
|
+
for (const initial of [0, config.sheet.initial, 1, 0])
|
|
103
|
+
nodes.push(liveSpringDriver().create(initial, physics, false))
|
|
104
|
+
const options = JSON.stringify({
|
|
105
|
+
replay: true,
|
|
106
|
+
axis: 2,
|
|
107
|
+
threshold: 8,
|
|
108
|
+
failOffset: 12,
|
|
109
|
+
minX: 0,
|
|
110
|
+
maxX: 0,
|
|
111
|
+
minY: config.sheet.min,
|
|
112
|
+
maxY: config.sheet.max,
|
|
113
|
+
minScale: 1,
|
|
114
|
+
maxScale: 1,
|
|
115
|
+
pinch: false,
|
|
116
|
+
rotate: false,
|
|
117
|
+
tap: false,
|
|
118
|
+
doubleTap: false,
|
|
119
|
+
})
|
|
120
|
+
if (isIOS) {
|
|
121
|
+
const n = nodes.map(nativeLiveNode) as JoltLiveSpring[]
|
|
122
|
+
const native = JoltGestureSession.attachScrollXYScaleRotationOptionsOnState(
|
|
123
|
+
surface.nativeViewProtected,
|
|
124
|
+
scroll.nativeViewProtected,
|
|
125
|
+
n[0]!,
|
|
126
|
+
n[1]!,
|
|
127
|
+
n[2]!,
|
|
128
|
+
n[3]!,
|
|
129
|
+
options,
|
|
130
|
+
() => {},
|
|
131
|
+
)
|
|
132
|
+
session = {
|
|
133
|
+
input: (phase, delta, velocity) =>
|
|
134
|
+
native.replayScrollDeltaVelocity(phase, delta, velocity),
|
|
135
|
+
offset: (value) => native.replayScrollOffset(value),
|
|
136
|
+
dispose: () => native.dispose(),
|
|
137
|
+
}
|
|
138
|
+
releaseDelegate = retainScrollDelegate(scroll, () => native.refreshScrollDelegate())
|
|
139
|
+
} else {
|
|
140
|
+
const n = nodes.map(nativeLiveNode) as org.rafaelaugusto.jolt.LiveSpring[]
|
|
141
|
+
const native = new org.rafaelaugusto.jolt.GestureSession(
|
|
142
|
+
surface.nativeViewProtected,
|
|
143
|
+
scroll.nativeViewProtected,
|
|
144
|
+
n[0]!,
|
|
145
|
+
n[1]!,
|
|
146
|
+
n[2]!,
|
|
147
|
+
n[3]!,
|
|
148
|
+
options,
|
|
149
|
+
new org.rafaelaugusto.jolt.GestureSession.Listener({ onState() {} }),
|
|
150
|
+
)
|
|
151
|
+
session = {
|
|
152
|
+
input: (phase, delta, velocity) => native.replayScroll(phase, delta, velocity),
|
|
153
|
+
offset: (value) => native.replayScrollOffset(value),
|
|
154
|
+
dispose: () => native.dispose(),
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// Claim input and bind only after native ownership validation succeeds.
|
|
158
|
+
claimedInput = true
|
|
159
|
+
surface.isUserInteractionEnabled = false
|
|
160
|
+
scroll.isUserInteractionEnabled = false
|
|
161
|
+
binding = nodes[1]!.bind(surface, 'y', [])
|
|
162
|
+
session.offset(config.scroll.initial)
|
|
163
|
+
} catch (error) {
|
|
164
|
+
dispose()
|
|
165
|
+
throw error
|
|
166
|
+
}
|
|
167
|
+
const input = handoffInput((phase, delta, velocity) => {
|
|
168
|
+
const before = nodes[1]!.position()
|
|
169
|
+
session!.input(phase, delta, velocity)
|
|
170
|
+
ownsVelocity = phase === 2 && nodes[1]!.position() !== before
|
|
171
|
+
})
|
|
172
|
+
return {
|
|
173
|
+
input(event) {
|
|
174
|
+
if (disposed) throw new Error('Handoff graph is disposed.')
|
|
175
|
+
if (event.type === 'gesture' && event.id === ids.sheet) input.gesture(event)
|
|
176
|
+
else if (event.type === 'scroll' && event.id === ids.scroll) {
|
|
177
|
+
if (event.offset < 0 || event.offset > config.scroll.max)
|
|
178
|
+
throw new RangeError('Scroll offset is outside the recorded bounds.')
|
|
179
|
+
session!.offset(event.offset)
|
|
180
|
+
} else if (event.type === 'lifecycle') input.lifecycle(event.state)
|
|
181
|
+
else throw new Error(`Handoff has no adapter for ${event.type}.`)
|
|
182
|
+
},
|
|
183
|
+
read(id) {
|
|
184
|
+
if (id !== ids.sheet && id !== ids.scroll)
|
|
185
|
+
throw new Error('Unknown handoff view ID.')
|
|
186
|
+
const offset = isIOS
|
|
187
|
+
? (scroll.nativeViewProtected as UIScrollView).contentOffset.y +
|
|
188
|
+
(scroll.nativeViewProtected as UIScrollView).adjustedContentInset.top
|
|
189
|
+
: Utils.layout.toDeviceIndependentPixels(
|
|
190
|
+
(scroll.nativeViewProtected as android.view.View).getScrollY(),
|
|
191
|
+
)
|
|
192
|
+
return {
|
|
193
|
+
position: id === ids.sheet ? nativeTracePosition(surface, 'y') : offset,
|
|
194
|
+
velocity: id === ids.sheet && ownsVelocity ? nodes[1]!.velocity() : 0,
|
|
195
|
+
settled: !input.contact && !nodes[1]!.moving(),
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
dispose,
|
|
199
|
+
resources: () => (disposed ? Math.max(0, count() - baseline) : nodes.length + 2),
|
|
200
|
+
}
|
|
201
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import type { ReplayAdapter } from './replay.js'
|
|
2
|
+
import { parseTrace, type TraceInput, type TraceMotion } from './trace.js'
|
|
3
|
+
|
|
4
|
+
export interface HandoffIds {
|
|
5
|
+
sheet: string
|
|
6
|
+
scroll: string
|
|
7
|
+
}
|
|
8
|
+
export const handoffIds: HandoffIds = { sheet: 'sheet', scroll: 'scroll' }
|
|
9
|
+
|
|
10
|
+
/** Both entries describe bounded y positions; no free-running spring is part of this adapter. */
|
|
11
|
+
export function handoffMotions(motions: readonly TraceMotion[], ids = handoffIds) {
|
|
12
|
+
// Reuse the trace schema rather than trusting a cast from a file or consumer.
|
|
13
|
+
const validated = parseTrace({
|
|
14
|
+
version: 1,
|
|
15
|
+
seed: 0,
|
|
16
|
+
settings: { timeScale: 1, reducedMotion: false },
|
|
17
|
+
metadata: {
|
|
18
|
+
platform: 'test',
|
|
19
|
+
os: 'test',
|
|
20
|
+
model: 'test',
|
|
21
|
+
refreshRate: 60,
|
|
22
|
+
density: 1,
|
|
23
|
+
width: 1,
|
|
24
|
+
height: 1,
|
|
25
|
+
},
|
|
26
|
+
motions,
|
|
27
|
+
entries: [],
|
|
28
|
+
}).motions
|
|
29
|
+
const sheet = validated.find((m) => m.id === ids.sheet),
|
|
30
|
+
scroll = validated.find((m) => m.id === ids.scroll)
|
|
31
|
+
if (
|
|
32
|
+
validated.length !== 2 ||
|
|
33
|
+
!sheet ||
|
|
34
|
+
!scroll ||
|
|
35
|
+
sheet === scroll ||
|
|
36
|
+
validated.some((m) => m.kind !== 'drag' || m.axis !== 'y' || m.snap.length) ||
|
|
37
|
+
scroll.min !== 0
|
|
38
|
+
)
|
|
39
|
+
throw new TypeError(
|
|
40
|
+
'Handoff needs two distinct y drag motions, no snap, and scroll min 0.',
|
|
41
|
+
)
|
|
42
|
+
return { sheet, scroll }
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Normalize cumulative contact positions once; membership changes rebase without a delta. */
|
|
46
|
+
export function handoffInput(
|
|
47
|
+
send: (phase: number, delta: number, velocity: number) => void,
|
|
48
|
+
) {
|
|
49
|
+
let contact = false,
|
|
50
|
+
suspended = false,
|
|
51
|
+
previous = 0,
|
|
52
|
+
pointers = ''
|
|
53
|
+
return {
|
|
54
|
+
get contact() {
|
|
55
|
+
return contact
|
|
56
|
+
},
|
|
57
|
+
gesture(event: Extract<TraceInput, { type: 'gesture' }>) {
|
|
58
|
+
if (suspended) return
|
|
59
|
+
if (event.phase === 'begin') {
|
|
60
|
+
contact = true
|
|
61
|
+
previous = event.y
|
|
62
|
+
pointers = event.pointers.join(',')
|
|
63
|
+
send(1, 0, 0)
|
|
64
|
+
} else if (contact && event.phase === 'move') {
|
|
65
|
+
const next = event.pointers.join(',')
|
|
66
|
+
const changed = pointers !== next
|
|
67
|
+
const delta = changed ? 0 : event.y - previous
|
|
68
|
+
previous = event.y
|
|
69
|
+
pointers = next
|
|
70
|
+
send(2, delta, changed ? 0 : event.velocityY)
|
|
71
|
+
} else if (contact) {
|
|
72
|
+
contact = false
|
|
73
|
+
send(event.phase === 'cancel' ? 4 : 3, 0, 0)
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
lifecycle(state: string) {
|
|
77
|
+
if (state === 'suspend' || state === 'unload') {
|
|
78
|
+
suspended = true
|
|
79
|
+
contact = false
|
|
80
|
+
send(4, 0, 0)
|
|
81
|
+
} else suspended = false
|
|
82
|
+
},
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Independent headless contract: scroll to its top before pulling the sheet down;
|
|
87
|
+
* expand the sheet before scrolling content up. Native replay exercises the production policy.
|
|
88
|
+
*/
|
|
89
|
+
export function scrollHandoffTraceGraph(
|
|
90
|
+
motions: readonly TraceMotion[],
|
|
91
|
+
ids: HandoffIds = handoffIds,
|
|
92
|
+
): ReplayAdapter {
|
|
93
|
+
const config = handoffMotions(motions, ids)
|
|
94
|
+
let y = config.sheet.initial,
|
|
95
|
+
offset = config.scroll.initial,
|
|
96
|
+
velocity = 0,
|
|
97
|
+
disposed = false
|
|
98
|
+
const input = handoffInput((phase, delta, speed) => {
|
|
99
|
+
if (phase !== 2) {
|
|
100
|
+
velocity = 0
|
|
101
|
+
return
|
|
102
|
+
}
|
|
103
|
+
const before = y
|
|
104
|
+
if (delta > 0) {
|
|
105
|
+
const content = Math.min(offset, delta)
|
|
106
|
+
offset -= content
|
|
107
|
+
y = Math.min(config.sheet.max, y + delta - content)
|
|
108
|
+
} else {
|
|
109
|
+
const panel = Math.min(y - config.sheet.min, -delta)
|
|
110
|
+
y -= panel
|
|
111
|
+
offset = Math.min(config.scroll.max, offset - delta - panel)
|
|
112
|
+
}
|
|
113
|
+
velocity = y === before ? 0 : speed
|
|
114
|
+
})
|
|
115
|
+
return {
|
|
116
|
+
input(event) {
|
|
117
|
+
if (disposed) throw new Error('Handoff graph is disposed.')
|
|
118
|
+
if (event.type === 'gesture' && event.id === ids.sheet) input.gesture(event)
|
|
119
|
+
else if (event.type === 'scroll' && event.id === ids.scroll) {
|
|
120
|
+
if (event.offset < 0 || event.offset > config.scroll.max)
|
|
121
|
+
throw new RangeError('Scroll offset is outside the recorded bounds.')
|
|
122
|
+
offset = event.offset
|
|
123
|
+
} else if (event.type === 'lifecycle') input.lifecycle(event.state)
|
|
124
|
+
else throw new Error(`Handoff has no adapter for ${event.type}.`)
|
|
125
|
+
},
|
|
126
|
+
read(id) {
|
|
127
|
+
if (id !== ids.sheet && id !== ids.scroll)
|
|
128
|
+
throw new Error('Unknown handoff view ID.')
|
|
129
|
+
return {
|
|
130
|
+
position: id === ids.sheet ? y : offset,
|
|
131
|
+
velocity: id === ids.sheet ? velocity : 0,
|
|
132
|
+
settled: !input.contact,
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
dispose() {
|
|
136
|
+
disposed = true
|
|
137
|
+
},
|
|
138
|
+
resources: () => (disposed ? 0 : 1),
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Sensor } from '../sensors/index.js'
|
|
2
|
+
import { sensorDriver } from '../sensors/native.js'
|
|
3
|
+
/** Explicit canonical test inputs. These are synthetic samples, never evidence from device hardware. */
|
|
4
|
+
export interface SensorSample {
|
|
5
|
+
/** Relative milliseconds from the start of playback. */
|
|
6
|
+
time: number
|
|
7
|
+
/** Device-coordinate quaternion xyzw for rotation; downward m/s² xyz for gravity. */
|
|
8
|
+
values: readonly number[]
|
|
9
|
+
/** Interface clockwise basis angle from device coordinates, in degrees. */
|
|
10
|
+
orientation?: 0 | 90 | 180 | 270
|
|
11
|
+
}
|
|
12
|
+
/** Play finite test inputs through the native sensor pipeline; hardware is detached during playback. */
|
|
13
|
+
export function replaySensor(source: Sensor, samples: readonly SensorSample[]): void {
|
|
14
|
+
if (!Array.isArray(samples) || samples.length < 2 || samples.length > 10000)
|
|
15
|
+
throw new RangeError('Use 2–10000 sensor samples.')
|
|
16
|
+
let previous = -1
|
|
17
|
+
for (const sample of samples) {
|
|
18
|
+
if (
|
|
19
|
+
!Number.isFinite(sample.time) ||
|
|
20
|
+
sample.time <= previous ||
|
|
21
|
+
sample.time > 60000 ||
|
|
22
|
+
sample.time < 0
|
|
23
|
+
)
|
|
24
|
+
throw new RangeError('Sensor times must increase within 0–60000 milliseconds.')
|
|
25
|
+
previous = sample.time
|
|
26
|
+
if (
|
|
27
|
+
!Array.isArray(sample.values) ||
|
|
28
|
+
sample.values.length !== (source.kind === 'rotation' ? 4 : 3) ||
|
|
29
|
+
sample.values.some((value: number) => !Number.isFinite(value))
|
|
30
|
+
)
|
|
31
|
+
throw new TypeError('Invalid canonical sensor sample.')
|
|
32
|
+
if (source.kind === 'rotation' && Math.hypot(...sample.values) < 1e-8)
|
|
33
|
+
throw new RangeError('A quaternion cannot be zero.')
|
|
34
|
+
if (
|
|
35
|
+
sample.orientation !== undefined &&
|
|
36
|
+
![0, 90, 180, 270].includes(sample.orientation)
|
|
37
|
+
)
|
|
38
|
+
throw new RangeError('Invalid interface orientation.')
|
|
39
|
+
}
|
|
40
|
+
sensorDriver(source).replay(JSON.stringify(samples))
|
|
41
|
+
}
|