@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.
- package/CHANGELOG.md +16 -0
- package/LICENSE +21 -0
- package/README.md +55 -0
- package/android/build.gradle +24 -0
- package/android/src/main/AndroidManifest.xml +1 -0
- package/android/src/main/java/com/unrulysystems/nativemotion/GestureExclusionModule.kt +55 -0
- package/android/src/main/java/com/unrulysystems/nativemotion/NativeMotionPackage.kt +27 -0
- package/package.json +57 -0
- package/react-native.config.js +14 -0
- package/src/native/driver/instantWindow.ts +31 -0
- package/src/native/driver/strictModeReplay.ts +20 -0
- package/src/native/driver/uiLayoutEngine.ts +845 -0
- package/src/native/driver/uiLayoutGraph.ts +338 -0
- package/src/native/driver/uiValueChannel.ts +4640 -0
- package/src/native/driver/workletDriver.ts +3860 -0
- package/src/native/motion/AnimatePresence.tsx +1605 -0
- package/src/native/motion/LayoutGroup.tsx +163 -0
- package/src/native/motion/MotionConfig.tsx +400 -0
- package/src/native/motion/MotionRoot.tsx +250 -0
- package/src/native/motion/MotionView.tsx +6761 -0
- package/src/native/motion/addScaleCorrector.ts +97 -0
- package/src/native/motion/colorEndpointUiFeed.ts +32 -0
- package/src/native/motion/colorProjection.ts +39 -0
- package/src/native/motion/composeTransform.ts +271 -0
- package/src/native/motion/constraintMeasure.ts +157 -0
- package/src/native/motion/deferredPendingSnapshots.ts +25 -0
- package/src/native/motion/discreteProjection.ts +36 -0
- package/src/native/motion/dragAncestorPanContext.ts +28 -0
- package/src/native/motion/dragControls.ts +152 -0
- package/src/native/motion/dragGestureWiring.ts +1168 -0
- package/src/native/motion/dragHandoffBinding.ts +179 -0
- package/src/native/motion/dragHubStream.ts +756 -0
- package/src/native/motion/dragPropagationLock.ts +57 -0
- package/src/native/motion/driverValueChannel.ts +3288 -0
- package/src/native/motion/externalDragDriver.ts +214 -0
- package/src/native/motion/frameData.ts +31 -0
- package/src/native/motion/gestureBinding.ts +107 -0
- package/src/native/motion/gestureStateGate.ts +563 -0
- package/src/native/motion/gestureStateResolver.ts +286 -0
- package/src/native/motion/identityValueChannelControllerAdapter.ts +2043 -0
- package/src/native/motion/identityValueChannelControllerReconciliation.ts +176 -0
- package/src/native/motion/identityValueChannelLaneMarker.ts +14 -0
- package/src/native/motion/imperativeAnimate.ts +816 -0
- package/src/native/motion/keyframeTiming.ts +7 -0
- package/src/native/motion/layoutIdBinding.ts +261 -0
- package/src/native/motion/layoutIdFlightConfig.ts +51 -0
- package/src/native/motion/layoutProjection.ts +89 -0
- package/src/native/motion/layoutScroll.ts +204 -0
- package/src/native/motion/layoutTransition.ts +1302 -0
- package/src/native/motion/lengthLayoutContext.tsx +100 -0
- package/src/native/motion/lengthLayoutHost.ts +44 -0
- package/src/native/motion/mappedKeys.ts +184 -0
- package/src/native/motion/motionViewController.ts +3180 -0
- package/src/native/motion/nativeHostMarker.ts +22 -0
- package/src/native/motion/panSessionWiring.ts +127 -0
- package/src/native/motion/pathTransition.ts +101 -0
- package/src/native/motion/popLayout.ts +176 -0
- package/src/native/motion/presenceBinding.ts +382 -0
- package/src/native/motion/scaleCorrectorRegistry.ts +123 -0
- package/src/native/motion/scrollValues.ts +260 -0
- package/src/native/motion/serializablePayload.ts +151 -0
- package/src/native/motion/severity.ts +16 -0
- package/src/native/motion/shippedSurface.ts +843 -0
- package/src/native/motion/staticLengthGate.ts +86 -0
- package/src/native/motion/styleBaseGate.ts +72 -0
- package/src/native/motion/styleValueBinding.ts +657 -0
- package/src/native/motion/systemGestureExclusion.ts +61 -0
- package/src/native/motion/tapGestureWiring.ts +215 -0
- package/src/native/motion/transformOrder.ts +38 -0
- package/src/native/motion/transformStringBinding.ts +200 -0
- package/src/native/motion/transformTemplateGate.ts +45 -0
- package/src/native/motion/transitionGate.ts +435 -0
- package/src/native/motion/useAnimate.ts +52 -0
- package/src/native/motion/useCycle.ts +44 -0
- package/src/native/motion/useInstantTransition.ts +68 -0
- package/src/native/motion/useReducedMotion.ts +58 -0
- package/src/native/motion/useScroll.ts +162 -0
- package/src/native/motion/useViewportScroll.ts +29 -0
- package/src/native/motion/valueChannel.ts +7121 -0
- package/src/native/motion/valueHooks.ts +901 -0
- package/src/native/motion/variantChildRegistry.ts +67 -0
- package/src/native/motion/variantContext.tsx +172 -0
- package/src/native/motion/variantProps.ts +598 -0
- package/src/native.ts +159 -0
- package/src/verification/harnessMetrics.ts +78 -0
- package/src/verification/probe/LayoutIdentityWorkletProbe.tsx +251 -0
- package/src/verification/probe/WorkletParityProbe.tsx +162 -0
- package/src/verification/probe/layoutIdentityProbeEngine.ts +429 -0
- package/src/verification/screens/ArcPathChecksScreen.tsx +273 -0
- package/src/verification/screens/BooleanAnimateChecksScreen.tsx +358 -0
- package/src/verification/screens/ChoreographyGalleryScreen.tsx +1010 -0
- package/src/verification/screens/ColorBindingChecksScreen.tsx +568 -0
- package/src/verification/screens/CompletionChecksScreen.tsx +294 -0
- package/src/verification/screens/ConformanceScreen.tsx +573 -0
- package/src/verification/screens/ContentionProbeScreen.tsx +224 -0
- package/src/verification/screens/DriverSmokeScreen.tsx +99 -0
- package/src/verification/screens/DurationOnlyTweenChecksScreen.tsx +294 -0
- package/src/verification/screens/DynamicDragConfigChecksScreen.tsx +237 -0
- package/src/verification/screens/FrameDataChecksScreen.tsx +252 -0
- package/src/verification/screens/GestureChecksScreen.tsx +685 -0
- package/src/verification/screens/InstantTransitionChecksScreen.tsx +839 -0
- package/src/verification/screens/LayoutAnimationStartChecksScreen.tsx +648 -0
- package/src/verification/screens/LayoutChecksScreen.tsx +822 -0
- package/src/verification/screens/LayoutCommitSpikeScreen.tsx +142 -0
- package/src/verification/screens/MotionViewChecksScreen.tsx +930 -0
- package/src/verification/screens/PresenceChecksScreen.tsx +614 -0
- package/src/verification/screens/ReducedMotionChecksScreen.tsx +614 -0
- package/src/verification/screens/RestThresholdChecksScreen.tsx +634 -0
- package/src/verification/screens/ScaleCorrectorChecksScreen.tsx +425 -0
- package/src/verification/screens/SharedLayoutContinuityChecksScreen.tsx +338 -0
- package/src/verification/screens/SharedLayoutCrossfadeChecksScreen.tsx +425 -0
- package/src/verification/screens/TransitionDefaultSelectionChecksScreen.tsx +514 -0
- package/src/verification/screens/ViewportScrollAliasChecksScreen.tsx +303 -0
- package/src/verification/screens/conformanceBanner.ts +21 -0
- package/src/verification/screens/proofConsoleTap.ts +18 -0
- package/src/verification.ts +47 -0
- 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
|
+
)
|