@unrulysystems/native-motion 0.1.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/LICENSE +21 -0
  3. package/README.md +55 -0
  4. package/android/build.gradle +24 -0
  5. package/android/src/main/AndroidManifest.xml +1 -0
  6. package/android/src/main/java/com/unrulysystems/nativemotion/GestureExclusionModule.kt +55 -0
  7. package/android/src/main/java/com/unrulysystems/nativemotion/NativeMotionPackage.kt +27 -0
  8. package/package.json +57 -0
  9. package/react-native.config.js +14 -0
  10. package/src/native/driver/instantWindow.ts +31 -0
  11. package/src/native/driver/strictModeReplay.ts +20 -0
  12. package/src/native/driver/uiLayoutEngine.ts +845 -0
  13. package/src/native/driver/uiLayoutGraph.ts +338 -0
  14. package/src/native/driver/uiValueChannel.ts +4640 -0
  15. package/src/native/driver/workletDriver.ts +3860 -0
  16. package/src/native/motion/AnimatePresence.tsx +1605 -0
  17. package/src/native/motion/LayoutGroup.tsx +163 -0
  18. package/src/native/motion/MotionConfig.tsx +400 -0
  19. package/src/native/motion/MotionRoot.tsx +250 -0
  20. package/src/native/motion/MotionView.tsx +6761 -0
  21. package/src/native/motion/addScaleCorrector.ts +97 -0
  22. package/src/native/motion/colorEndpointUiFeed.ts +32 -0
  23. package/src/native/motion/colorProjection.ts +39 -0
  24. package/src/native/motion/composeTransform.ts +271 -0
  25. package/src/native/motion/constraintMeasure.ts +157 -0
  26. package/src/native/motion/deferredPendingSnapshots.ts +25 -0
  27. package/src/native/motion/discreteProjection.ts +36 -0
  28. package/src/native/motion/dragAncestorPanContext.ts +28 -0
  29. package/src/native/motion/dragControls.ts +152 -0
  30. package/src/native/motion/dragGestureWiring.ts +1168 -0
  31. package/src/native/motion/dragHandoffBinding.ts +179 -0
  32. package/src/native/motion/dragHubStream.ts +756 -0
  33. package/src/native/motion/dragPropagationLock.ts +57 -0
  34. package/src/native/motion/driverValueChannel.ts +3288 -0
  35. package/src/native/motion/externalDragDriver.ts +214 -0
  36. package/src/native/motion/frameData.ts +31 -0
  37. package/src/native/motion/gestureBinding.ts +107 -0
  38. package/src/native/motion/gestureStateGate.ts +563 -0
  39. package/src/native/motion/gestureStateResolver.ts +286 -0
  40. package/src/native/motion/identityValueChannelControllerAdapter.ts +2043 -0
  41. package/src/native/motion/identityValueChannelControllerReconciliation.ts +176 -0
  42. package/src/native/motion/identityValueChannelLaneMarker.ts +14 -0
  43. package/src/native/motion/imperativeAnimate.ts +816 -0
  44. package/src/native/motion/keyframeTiming.ts +7 -0
  45. package/src/native/motion/layoutIdBinding.ts +261 -0
  46. package/src/native/motion/layoutIdFlightConfig.ts +51 -0
  47. package/src/native/motion/layoutProjection.ts +89 -0
  48. package/src/native/motion/layoutScroll.ts +204 -0
  49. package/src/native/motion/layoutTransition.ts +1302 -0
  50. package/src/native/motion/lengthLayoutContext.tsx +100 -0
  51. package/src/native/motion/lengthLayoutHost.ts +44 -0
  52. package/src/native/motion/mappedKeys.ts +184 -0
  53. package/src/native/motion/motionViewController.ts +3180 -0
  54. package/src/native/motion/nativeHostMarker.ts +22 -0
  55. package/src/native/motion/panSessionWiring.ts +127 -0
  56. package/src/native/motion/pathTransition.ts +101 -0
  57. package/src/native/motion/popLayout.ts +176 -0
  58. package/src/native/motion/presenceBinding.ts +382 -0
  59. package/src/native/motion/scaleCorrectorRegistry.ts +123 -0
  60. package/src/native/motion/scrollValues.ts +260 -0
  61. package/src/native/motion/serializablePayload.ts +151 -0
  62. package/src/native/motion/severity.ts +16 -0
  63. package/src/native/motion/shippedSurface.ts +843 -0
  64. package/src/native/motion/staticLengthGate.ts +86 -0
  65. package/src/native/motion/styleBaseGate.ts +72 -0
  66. package/src/native/motion/styleValueBinding.ts +657 -0
  67. package/src/native/motion/systemGestureExclusion.ts +61 -0
  68. package/src/native/motion/tapGestureWiring.ts +215 -0
  69. package/src/native/motion/transformOrder.ts +38 -0
  70. package/src/native/motion/transformStringBinding.ts +200 -0
  71. package/src/native/motion/transformTemplateGate.ts +45 -0
  72. package/src/native/motion/transitionGate.ts +435 -0
  73. package/src/native/motion/useAnimate.ts +52 -0
  74. package/src/native/motion/useCycle.ts +44 -0
  75. package/src/native/motion/useInstantTransition.ts +68 -0
  76. package/src/native/motion/useReducedMotion.ts +58 -0
  77. package/src/native/motion/useScroll.ts +162 -0
  78. package/src/native/motion/useViewportScroll.ts +29 -0
  79. package/src/native/motion/valueChannel.ts +7121 -0
  80. package/src/native/motion/valueHooks.ts +901 -0
  81. package/src/native/motion/variantChildRegistry.ts +67 -0
  82. package/src/native/motion/variantContext.tsx +172 -0
  83. package/src/native/motion/variantProps.ts +598 -0
  84. package/src/native.ts +159 -0
  85. package/src/verification/harnessMetrics.ts +78 -0
  86. package/src/verification/probe/LayoutIdentityWorkletProbe.tsx +251 -0
  87. package/src/verification/probe/WorkletParityProbe.tsx +162 -0
  88. package/src/verification/probe/layoutIdentityProbeEngine.ts +429 -0
  89. package/src/verification/screens/ArcPathChecksScreen.tsx +273 -0
  90. package/src/verification/screens/BooleanAnimateChecksScreen.tsx +358 -0
  91. package/src/verification/screens/ChoreographyGalleryScreen.tsx +1010 -0
  92. package/src/verification/screens/ColorBindingChecksScreen.tsx +568 -0
  93. package/src/verification/screens/CompletionChecksScreen.tsx +294 -0
  94. package/src/verification/screens/ConformanceScreen.tsx +573 -0
  95. package/src/verification/screens/ContentionProbeScreen.tsx +224 -0
  96. package/src/verification/screens/DriverSmokeScreen.tsx +99 -0
  97. package/src/verification/screens/DurationOnlyTweenChecksScreen.tsx +294 -0
  98. package/src/verification/screens/DynamicDragConfigChecksScreen.tsx +237 -0
  99. package/src/verification/screens/FrameDataChecksScreen.tsx +252 -0
  100. package/src/verification/screens/GestureChecksScreen.tsx +685 -0
  101. package/src/verification/screens/InstantTransitionChecksScreen.tsx +839 -0
  102. package/src/verification/screens/LayoutAnimationStartChecksScreen.tsx +648 -0
  103. package/src/verification/screens/LayoutChecksScreen.tsx +822 -0
  104. package/src/verification/screens/LayoutCommitSpikeScreen.tsx +142 -0
  105. package/src/verification/screens/MotionViewChecksScreen.tsx +930 -0
  106. package/src/verification/screens/PresenceChecksScreen.tsx +614 -0
  107. package/src/verification/screens/ReducedMotionChecksScreen.tsx +614 -0
  108. package/src/verification/screens/RestThresholdChecksScreen.tsx +634 -0
  109. package/src/verification/screens/ScaleCorrectorChecksScreen.tsx +425 -0
  110. package/src/verification/screens/SharedLayoutContinuityChecksScreen.tsx +338 -0
  111. package/src/verification/screens/SharedLayoutCrossfadeChecksScreen.tsx +425 -0
  112. package/src/verification/screens/TransitionDefaultSelectionChecksScreen.tsx +514 -0
  113. package/src/verification/screens/ViewportScrollAliasChecksScreen.tsx +303 -0
  114. package/src/verification/screens/conformanceBanner.ts +21 -0
  115. package/src/verification/screens/proofConsoleTap.ts +18 -0
  116. package/src/verification.ts +47 -0
  117. package/src/web.ts +98 -0
@@ -0,0 +1,176 @@
1
+ import type { BoundStyleValue } from './styleValueBinding'
2
+
3
+ export const IDENTITY_VALUE_CHANNEL_CONTROLLER_RECONCILIATION_INVARIANT =
4
+ 'NATIVE_MOTION_IDENTITY_VALUE_CHANNEL_CONTROLLER_RECONCILIATION_INVARIANT' as const
5
+
6
+ export class IdentityValueChannelControllerReconciliationInvariantError extends Error {
7
+ readonly code = IDENTITY_VALUE_CHANNEL_CONTROLLER_RECONCILIATION_INVARIANT
8
+ readonly reason = 'replacement-snapshot-missing' as const
9
+ readonly key: string
10
+
11
+ constructor(key: string) {
12
+ super(
13
+ `native-motion: identity value-channel replacement '${key}' has no captured scalar snapshot`,
14
+ )
15
+ this.name = 'IdentityValueChannelControllerReconciliationInvariantError'
16
+ this.key = key
17
+ }
18
+ }
19
+
20
+ export interface IdentityValueChannelControllerDetachBoundValueEdge {
21
+ readonly kind: 'DETACH_BOUND_VALUE'
22
+ readonly key: string
23
+ readonly value: BoundStyleValue
24
+ readonly identityEligible: boolean
25
+ }
26
+
27
+ export interface IdentityValueChannelControllerAttachBoundValueEdge {
28
+ readonly kind: 'ATTACH_BOUND_VALUE'
29
+ readonly key: string
30
+ readonly value: BoundStyleValue
31
+ readonly resolvedValue: number | string
32
+ readonly identityEligible: boolean
33
+ }
34
+
35
+ export type IdentityValueChannelControllerElementReconciliationChange =
36
+ | {
37
+ readonly kind: 'REPLACE_BOUND_VALUE'
38
+ readonly key: string
39
+ readonly previousValue: BoundStyleValue
40
+ readonly replacementValue: BoundStyleValue
41
+ readonly replacementResolvedValue: number | string
42
+ readonly previousIdentityEligible: boolean
43
+ readonly replacementIdentityEligible: boolean
44
+ readonly orderedEdges: readonly [
45
+ IdentityValueChannelControllerDetachBoundValueEdge,
46
+ IdentityValueChannelControllerAttachBoundValueEdge,
47
+ ]
48
+ }
49
+ | {
50
+ readonly kind: 'REMOVE_BOUND_VALUE'
51
+ readonly key: string
52
+ readonly previousValue: BoundStyleValue
53
+ readonly previousIdentityEligible: true
54
+ readonly orderedEdges: readonly [IdentityValueChannelControllerDetachBoundValueEdge]
55
+ }
56
+ | {
57
+ readonly kind: 'ATTACH_BOUND_VALUE'
58
+ readonly key: string
59
+ readonly replacementValue: BoundStyleValue
60
+ readonly replacementResolvedValue: number | string
61
+ readonly replacementIdentityEligible: true
62
+ readonly orderedEdges: readonly [IdentityValueChannelControllerAttachBoundValueEdge]
63
+ }
64
+
65
+ export interface IdentityValueChannelControllerElementReconciliationPlan {
66
+ readonly changes: readonly IdentityValueChannelControllerElementReconciliationChange[]
67
+ }
68
+
69
+ export interface PlanIdentityValueChannelControllerElementReconciliationOptions {
70
+ readonly previousBoundStyleValues: Readonly<Record<string, BoundStyleValue>>
71
+ readonly previousIdentityEligibleBoundKeys: readonly string[]
72
+ readonly nextBoundStyleValues: Readonly<Record<string, BoundStyleValue>>
73
+ readonly nextIdentityEligibleBoundKeys: readonly string[]
74
+ /** One-read snapshots for new or replaced values only; unchanged identities are deliberately absent. */
75
+ readonly resolvedReplacementStyleValues: Readonly<Record<string, number | string>>
76
+ }
77
+
78
+ function capturedReplacementValue(
79
+ key: string,
80
+ resolvedReplacementStyleValues: Readonly<Record<string, number | string>>,
81
+ ): number | string {
82
+ if (!Object.prototype.hasOwnProperty.call(resolvedReplacementStyleValues, key)) {
83
+ throw new IdentityValueChannelControllerReconciliationInvariantError(key)
84
+ }
85
+ return resolvedReplacementStyleValues[key]!
86
+ }
87
+
88
+ /**
89
+ * Produces the exact-reference commit plan consumed by the controller adapter. Previous authored
90
+ * key order owns replacements/removals; genuinely new eligible keys follow next-style order.
91
+ */
92
+ export function planIdentityValueChannelControllerElementReconciliation(
93
+ options: PlanIdentityValueChannelControllerElementReconciliationOptions,
94
+ ): IdentityValueChannelControllerElementReconciliationPlan {
95
+ const changes: IdentityValueChannelControllerElementReconciliationChange[] = []
96
+ const previousKeys = Object.keys(options.previousBoundStyleValues)
97
+ const nextKeys = Object.keys(options.nextBoundStyleValues)
98
+ const orderedKeys = [
99
+ ...previousKeys,
100
+ ...nextKeys.filter(
101
+ (key) => !Object.prototype.hasOwnProperty.call(options.previousBoundStyleValues, key),
102
+ ),
103
+ ]
104
+
105
+ for (const key of orderedKeys) {
106
+ const previousValue = options.previousBoundStyleValues[key]
107
+ const replacementValue = options.nextBoundStyleValues[key]
108
+ if (previousValue === replacementValue) continue
109
+
110
+ const previousIdentityEligible = options.previousIdentityEligibleBoundKeys.includes(key)
111
+ const replacementIdentityEligible = options.nextIdentityEligibleBoundKeys.includes(key)
112
+ if (!previousIdentityEligible && !replacementIdentityEligible) continue
113
+
114
+ if (previousValue !== undefined && replacementValue === undefined) {
115
+ if (!previousIdentityEligible) continue
116
+ const detach = {
117
+ kind: 'DETACH_BOUND_VALUE',
118
+ key,
119
+ value: previousValue,
120
+ identityEligible: true,
121
+ } as const
122
+ changes.push({
123
+ kind: 'REMOVE_BOUND_VALUE',
124
+ key,
125
+ previousValue,
126
+ previousIdentityEligible: true,
127
+ orderedEdges: [detach],
128
+ })
129
+ continue
130
+ }
131
+
132
+ if (replacementValue === undefined) continue
133
+ const replacementResolvedValue = capturedReplacementValue(
134
+ key,
135
+ options.resolvedReplacementStyleValues,
136
+ )
137
+ const attach = {
138
+ kind: 'ATTACH_BOUND_VALUE',
139
+ key,
140
+ value: replacementValue,
141
+ resolvedValue: replacementResolvedValue,
142
+ identityEligible: replacementIdentityEligible,
143
+ } as const
144
+ if (previousValue === undefined) {
145
+ if (!replacementIdentityEligible) continue
146
+ changes.push({
147
+ kind: 'ATTACH_BOUND_VALUE',
148
+ key,
149
+ replacementValue,
150
+ replacementResolvedValue,
151
+ replacementIdentityEligible: true,
152
+ orderedEdges: [attach],
153
+ })
154
+ continue
155
+ }
156
+
157
+ const detach = {
158
+ kind: 'DETACH_BOUND_VALUE',
159
+ key,
160
+ value: previousValue,
161
+ identityEligible: previousIdentityEligible,
162
+ } as const
163
+ changes.push({
164
+ kind: 'REPLACE_BOUND_VALUE',
165
+ key,
166
+ previousValue,
167
+ replacementValue,
168
+ replacementResolvedValue,
169
+ previousIdentityEligible,
170
+ replacementIdentityEligible,
171
+ orderedEdges: [detach, attach],
172
+ })
173
+ }
174
+
175
+ return { changes }
176
+ }
@@ -0,0 +1,14 @@
1
+ // The identity-channel lane marker shared by the controller and the adapter binding (REQ-API-061).
2
+ // Kept dependency-free on purpose: every consumer of the controller can load it without pulling
3
+ // the adapter's driver graph (several suites resolve no react-native-worklets at all).
4
+
5
+ /**
6
+ * Command-level lane marker the controller stamps on declarative animate updates (its
7
+ * `animateScope`-carrying update lane). A top-level symbol never crosses into the prepared driver
8
+ * protocol and never serializes, so the delegate and every command trace stay oblivious; the
9
+ * identity adapter alone reads it to keep the declarative lane on a timed trajectory while a
10
+ * gesture-state/presence retarget of the same shape takes the host-resolved carrier commit.
11
+ */
12
+ export const IDENTITY_DECLARATIVE_LANE_COMMAND: unique symbol = Symbol(
13
+ 'native-motion.identity-value-channel.declarative-lane-command',
14
+ )