@userflow-tech/react-native 0.3.0 → 0.3.1

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 (197) hide show
  1. package/README.md +325 -63
  2. package/docs/anchoring.md +58 -42
  3. package/docs/troubleshooting.md +63 -27
  4. package/expo-plugin/hostDependencyWarnings.d.ts +18 -0
  5. package/expo-plugin/hostDependencyWarnings.d.ts.map +1 -0
  6. package/expo-plugin/hostDependencyWarnings.js +91 -0
  7. package/expo-plugin/hostDependencyWarnings.js.map +1 -0
  8. package/expo-plugin/withUserflow.d.ts.map +1 -1
  9. package/expo-plugin/withUserflow.js +16 -0
  10. package/expo-plugin/withUserflow.js.map +1 -1
  11. package/lib/commonjs/anchors/AnchorRegistry.js +7 -0
  12. package/lib/commonjs/anchors/AnchorRegistry.js.map +1 -1
  13. package/lib/commonjs/anchors/elementConditionEvaluator.js +189 -55
  14. package/lib/commonjs/anchors/elementConditionEvaluator.js.map +1 -1
  15. package/lib/commonjs/anchors/elementTapMonitor.js +92 -0
  16. package/lib/commonjs/anchors/elementTapMonitor.js.map +1 -0
  17. package/lib/commonjs/anchors/elementTargetMatch.js +85 -0
  18. package/lib/commonjs/anchors/elementTargetMatch.js.map +1 -0
  19. package/lib/commonjs/anchors/fiber/findAnchorFiber.js +64 -39
  20. package/lib/commonjs/anchors/fiber/findAnchorFiber.js.map +1 -1
  21. package/lib/commonjs/anchors/fiber/touchTargetFiber.js +105 -0
  22. package/lib/commonjs/anchors/fiber/touchTargetFiber.js.map +1 -0
  23. package/lib/commonjs/anchors/resolveAnchorHost.js +2 -1
  24. package/lib/commonjs/anchors/resolveAnchorHost.js.map +1 -1
  25. package/lib/commonjs/anchors/resolveAutoAnchorHost.js +4 -2
  26. package/lib/commonjs/anchors/resolveAutoAnchorHost.js.map +1 -1
  27. package/lib/commonjs/anchors/resolveElementTargets.js +158 -0
  28. package/lib/commonjs/anchors/resolveElementTargets.js.map +1 -0
  29. package/lib/commonjs/anchors/targetPressMonitor.js +9 -3
  30. package/lib/commonjs/anchors/targetPressMonitor.js.map +1 -1
  31. package/lib/commonjs/anchors/useUserflowAnchor.js +1 -0
  32. package/lib/commonjs/anchors/useUserflowAnchor.js.map +1 -1
  33. package/lib/commonjs/anonymousId.js +16 -7
  34. package/lib/commonjs/anonymousId.js.map +1 -1
  35. package/lib/commonjs/index.js +5 -0
  36. package/lib/commonjs/index.js.map +1 -1
  37. package/lib/commonjs/installCheck.js +151 -0
  38. package/lib/commonjs/installCheck.js.map +1 -0
  39. package/lib/commonjs/pairing/deviceId.js +14 -11
  40. package/lib/commonjs/pairing/deviceId.js.map +1 -1
  41. package/lib/commonjs/runtime/TargetPressBridge.js +12 -1
  42. package/lib/commonjs/runtime/TargetPressBridge.js.map +1 -1
  43. package/lib/commonjs/runtime/UserflowProvider.js +6 -3
  44. package/lib/commonjs/runtime/UserflowProvider.js.map +1 -1
  45. package/lib/commonjs/storage/asyncStorage.js +67 -0
  46. package/lib/commonjs/storage/asyncStorage.js.map +1 -0
  47. package/lib/commonjs/surfaces/safeArea.js +68 -28
  48. package/lib/commonjs/surfaces/safeArea.js.map +1 -1
  49. package/lib/commonjs/version.js +1 -1
  50. package/lib/module/anchors/AnchorRegistry.js +7 -0
  51. package/lib/module/anchors/AnchorRegistry.js.map +1 -1
  52. package/lib/module/anchors/elementConditionEvaluator.js +189 -55
  53. package/lib/module/anchors/elementConditionEvaluator.js.map +1 -1
  54. package/lib/module/anchors/elementTapMonitor.js +87 -0
  55. package/lib/module/anchors/elementTapMonitor.js.map +1 -0
  56. package/lib/module/anchors/elementTargetMatch.js +78 -0
  57. package/lib/module/anchors/elementTargetMatch.js.map +1 -0
  58. package/lib/module/anchors/fiber/findAnchorFiber.js +62 -39
  59. package/lib/module/anchors/fiber/findAnchorFiber.js.map +1 -1
  60. package/lib/module/anchors/fiber/touchTargetFiber.js +100 -0
  61. package/lib/module/anchors/fiber/touchTargetFiber.js.map +1 -0
  62. package/lib/module/anchors/resolveAnchorHost.js +2 -1
  63. package/lib/module/anchors/resolveAnchorHost.js.map +1 -1
  64. package/lib/module/anchors/resolveAutoAnchorHost.js +3 -3
  65. package/lib/module/anchors/resolveAutoAnchorHost.js.map +1 -1
  66. package/lib/module/anchors/resolveElementTargets.js +152 -0
  67. package/lib/module/anchors/resolveElementTargets.js.map +1 -0
  68. package/lib/module/anchors/targetPressMonitor.js +8 -3
  69. package/lib/module/anchors/targetPressMonitor.js.map +1 -1
  70. package/lib/module/anchors/useUserflowAnchor.js +1 -0
  71. package/lib/module/anchors/useUserflowAnchor.js.map +1 -1
  72. package/lib/module/anonymousId.js +15 -5
  73. package/lib/module/anonymousId.js.map +1 -1
  74. package/lib/module/index.js +5 -0
  75. package/lib/module/index.js.map +1 -1
  76. package/lib/module/installCheck.js +139 -0
  77. package/lib/module/installCheck.js.map +1 -0
  78. package/lib/module/pairing/deviceId.js +14 -10
  79. package/lib/module/pairing/deviceId.js.map +1 -1
  80. package/lib/module/runtime/TargetPressBridge.js +12 -1
  81. package/lib/module/runtime/TargetPressBridge.js.map +1 -1
  82. package/lib/module/runtime/UserflowProvider.js +7 -4
  83. package/lib/module/runtime/UserflowProvider.js.map +1 -1
  84. package/lib/module/storage/asyncStorage.js +61 -0
  85. package/lib/module/storage/asyncStorage.js.map +1 -0
  86. package/lib/module/surfaces/safeArea.js +65 -28
  87. package/lib/module/surfaces/safeArea.js.map +1 -1
  88. package/lib/module/version.js +1 -1
  89. package/lib/typescript/commonjs/src/anchors/AnchorRegistry.d.ts +7 -0
  90. package/lib/typescript/commonjs/src/anchors/AnchorRegistry.d.ts.map +1 -1
  91. package/lib/typescript/commonjs/src/anchors/elementConditionEvaluator.d.ts +12 -16
  92. package/lib/typescript/commonjs/src/anchors/elementConditionEvaluator.d.ts.map +1 -1
  93. package/lib/typescript/commonjs/src/anchors/elementTapMonitor.d.ts +36 -0
  94. package/lib/typescript/commonjs/src/anchors/elementTapMonitor.d.ts.map +1 -0
  95. package/lib/typescript/commonjs/src/anchors/elementTargetMatch.d.ts +20 -0
  96. package/lib/typescript/commonjs/src/anchors/elementTargetMatch.d.ts.map +1 -0
  97. package/lib/typescript/commonjs/src/anchors/fiber/findAnchorFiber.d.ts +17 -5
  98. package/lib/typescript/commonjs/src/anchors/fiber/findAnchorFiber.d.ts.map +1 -1
  99. package/lib/typescript/commonjs/src/anchors/fiber/touchTargetFiber.d.ts +24 -0
  100. package/lib/typescript/commonjs/src/anchors/fiber/touchTargetFiber.d.ts.map +1 -0
  101. package/lib/typescript/commonjs/src/anchors/resolveAnchorHost.d.ts +2 -1
  102. package/lib/typescript/commonjs/src/anchors/resolveAnchorHost.d.ts.map +1 -1
  103. package/lib/typescript/commonjs/src/anchors/resolveAutoAnchorHost.d.ts +10 -1
  104. package/lib/typescript/commonjs/src/anchors/resolveAutoAnchorHost.d.ts.map +1 -1
  105. package/lib/typescript/commonjs/src/anchors/resolveElementTargets.d.ts +39 -0
  106. package/lib/typescript/commonjs/src/anchors/resolveElementTargets.d.ts.map +1 -0
  107. package/lib/typescript/commonjs/src/anchors/targetPressMonitor.d.ts +2 -0
  108. package/lib/typescript/commonjs/src/anchors/targetPressMonitor.d.ts.map +1 -1
  109. package/lib/typescript/commonjs/src/anchors/useUserflowAnchor.d.ts.map +1 -1
  110. package/lib/typescript/commonjs/src/anonymousId.d.ts +2 -0
  111. package/lib/typescript/commonjs/src/anonymousId.d.ts.map +1 -1
  112. package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
  113. package/lib/typescript/commonjs/src/installCheck.d.ts +33 -0
  114. package/lib/typescript/commonjs/src/installCheck.d.ts.map +1 -0
  115. package/lib/typescript/commonjs/src/pairing/deviceId.d.ts.map +1 -1
  116. package/lib/typescript/commonjs/src/runtime/TargetPressBridge.d.ts +2 -1
  117. package/lib/typescript/commonjs/src/runtime/TargetPressBridge.d.ts.map +1 -1
  118. package/lib/typescript/commonjs/src/runtime/UserflowProvider.d.ts.map +1 -1
  119. package/lib/typescript/commonjs/src/storage/asyncStorage.d.ts +15 -0
  120. package/lib/typescript/commonjs/src/storage/asyncStorage.d.ts.map +1 -0
  121. package/lib/typescript/commonjs/src/surfaces/safeArea.d.ts +4 -2
  122. package/lib/typescript/commonjs/src/surfaces/safeArea.d.ts.map +1 -1
  123. package/lib/typescript/commonjs/src/version.d.ts +1 -1
  124. package/lib/typescript/module/src/anchors/AnchorRegistry.d.ts +7 -0
  125. package/lib/typescript/module/src/anchors/AnchorRegistry.d.ts.map +1 -1
  126. package/lib/typescript/module/src/anchors/elementConditionEvaluator.d.ts +12 -16
  127. package/lib/typescript/module/src/anchors/elementConditionEvaluator.d.ts.map +1 -1
  128. package/lib/typescript/module/src/anchors/elementTapMonitor.d.ts +36 -0
  129. package/lib/typescript/module/src/anchors/elementTapMonitor.d.ts.map +1 -0
  130. package/lib/typescript/module/src/anchors/elementTargetMatch.d.ts +20 -0
  131. package/lib/typescript/module/src/anchors/elementTargetMatch.d.ts.map +1 -0
  132. package/lib/typescript/module/src/anchors/fiber/findAnchorFiber.d.ts +17 -5
  133. package/lib/typescript/module/src/anchors/fiber/findAnchorFiber.d.ts.map +1 -1
  134. package/lib/typescript/module/src/anchors/fiber/touchTargetFiber.d.ts +24 -0
  135. package/lib/typescript/module/src/anchors/fiber/touchTargetFiber.d.ts.map +1 -0
  136. package/lib/typescript/module/src/anchors/resolveAnchorHost.d.ts +2 -1
  137. package/lib/typescript/module/src/anchors/resolveAnchorHost.d.ts.map +1 -1
  138. package/lib/typescript/module/src/anchors/resolveAutoAnchorHost.d.ts +10 -1
  139. package/lib/typescript/module/src/anchors/resolveAutoAnchorHost.d.ts.map +1 -1
  140. package/lib/typescript/module/src/anchors/resolveElementTargets.d.ts +39 -0
  141. package/lib/typescript/module/src/anchors/resolveElementTargets.d.ts.map +1 -0
  142. package/lib/typescript/module/src/anchors/targetPressMonitor.d.ts +2 -0
  143. package/lib/typescript/module/src/anchors/targetPressMonitor.d.ts.map +1 -1
  144. package/lib/typescript/module/src/anchors/useUserflowAnchor.d.ts.map +1 -1
  145. package/lib/typescript/module/src/anonymousId.d.ts +2 -0
  146. package/lib/typescript/module/src/anonymousId.d.ts.map +1 -1
  147. package/lib/typescript/module/src/index.d.ts.map +1 -1
  148. package/lib/typescript/module/src/installCheck.d.ts +33 -0
  149. package/lib/typescript/module/src/installCheck.d.ts.map +1 -0
  150. package/lib/typescript/module/src/pairing/deviceId.d.ts.map +1 -1
  151. package/lib/typescript/module/src/runtime/TargetPressBridge.d.ts +2 -1
  152. package/lib/typescript/module/src/runtime/TargetPressBridge.d.ts.map +1 -1
  153. package/lib/typescript/module/src/runtime/UserflowProvider.d.ts.map +1 -1
  154. package/lib/typescript/module/src/storage/asyncStorage.d.ts +15 -0
  155. package/lib/typescript/module/src/storage/asyncStorage.d.ts.map +1 -0
  156. package/lib/typescript/module/src/surfaces/safeArea.d.ts +4 -2
  157. package/lib/typescript/module/src/surfaces/safeArea.d.ts.map +1 -1
  158. package/lib/typescript/module/src/version.d.ts +1 -1
  159. package/package.json +13 -1
  160. package/src/anchors/AnchorRegistry.ts +12 -0
  161. package/src/anchors/elementConditionEvaluator.ts +235 -70
  162. package/src/anchors/elementTapMonitor.ts +95 -0
  163. package/src/anchors/elementTargetMatch.ts +90 -0
  164. package/src/anchors/fiber/findAnchorFiber.ts +66 -35
  165. package/src/anchors/fiber/touchTargetFiber.ts +125 -0
  166. package/src/anchors/resolveAnchorHost.ts +2 -1
  167. package/src/anchors/resolveAutoAnchorHost.ts +3 -3
  168. package/src/anchors/resolveElementTargets.ts +165 -0
  169. package/src/anchors/targetPressMonitor.ts +12 -3
  170. package/src/anchors/useUserflowAnchor.ts +1 -0
  171. package/src/anonymousId.ts +19 -8
  172. package/src/index.ts +10 -0
  173. package/src/installCheck.ts +191 -0
  174. package/src/pairing/deviceId.ts +14 -11
  175. package/src/runtime/TargetPressBridge.tsx +17 -1
  176. package/src/runtime/UserflowProvider.tsx +11 -4
  177. package/src/storage/asyncStorage.ts +88 -0
  178. package/src/surfaces/safeArea.ts +80 -40
  179. package/src/version.ts +1 -1
  180. package/vendor/core/dist/constants.d.ts +2 -0
  181. package/vendor/core/dist/constants.d.ts.map +1 -1
  182. package/vendor/core/dist/constants.js +2 -0
  183. package/vendor/core/dist/constants.js.map +1 -1
  184. package/vendor/core/dist/engine/ClientConditionEngine.d.ts +20 -1
  185. package/vendor/core/dist/engine/ClientConditionEngine.d.ts.map +1 -1
  186. package/vendor/core/dist/engine/ClientConditionEngine.js +13 -10
  187. package/vendor/core/dist/engine/ClientConditionEngine.js.map +1 -1
  188. package/vendor/core/dist/engine/UserflowCore.d.ts.map +1 -1
  189. package/vendor/core/dist/engine/UserflowCore.js +21 -2
  190. package/vendor/core/dist/engine/UserflowCore.js.map +1 -1
  191. package/vendor/core/dist/index.d.ts +1 -1
  192. package/vendor/core/dist/index.d.ts.map +1 -1
  193. package/vendor/core/dist/index.js.map +1 -1
  194. package/vendor/core/dist/version.d.ts +1 -1
  195. package/vendor/core/dist/version.js +1 -1
  196. package/vendor/core/package.json +1 -1
  197. package/vendor/protocol/package.json +1 -1
@@ -4,34 +4,35 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.createElementConditionEvaluator = createElementConditionEvaluator;
7
+ var _protocol = require("@userflow-tech/protocol");
7
8
  var _anchorChangeTicker = require("./anchorChangeTicker.js");
8
- var _resolveAnchorHost = require("./resolveAnchorHost.js");
9
- var _resolveAutoAnchorHost = require("./resolveAutoAnchorHost.js");
9
+ var _elementTapMonitor = require("./elementTapMonitor.js");
10
+ var _elementTargetMatch = require("./elementTargetMatch.js");
11
+ var _resolveElementTargets = require("./resolveElementTargets.js");
10
12
  var _resolveManualAnchorId = require("./resolveManualAnchorId.js");
11
- /** ELEMENT states the mobile SDK can evaluate today. */
12
- const SUPPORTED_ELEMENT_STATES = new Set(['PRESENT', 'NOT_PRESENT']);
13
+ /** How many hosts to measure before giving up on a crowded duplicate id. */
14
+ const MAX_MEASURED_HOSTS = 8;
15
+
16
+ /** Same bound tooltip measurement uses. A host that never calls back is unknown. */
17
+ const MEASURE_TIMEOUT_MS = 400;
13
18
 
14
19
  /**
15
20
  * Evaluate ELEMENT client conditions against manual anchors, fiber-resolved
16
- * `testID` / `nativeID` / `accessibilityLabel` targets, and AUTO (codeless)
17
- * selectors.
21
+ * `userflowId` / `testID` / `nativeID` / `accessibilityLabel` targets, and AUTO
22
+ * (codeless) selectors.
18
23
  *
19
- * Supports PRESENT / NOT_PRESENT for MANUAL selectors (`css` → anchor id) and
20
- * AUTO selectors (`autoData` → {@link resolveAutoAnchorHost}). AUTO fails
21
- * closed: `unknown` / `ambiguous` stay `null` so a gated flow never starts
22
- * just because the auto-anchor registry is empty. Web-interaction states
23
- * (CLICK, DISABLED, …) still report unknown.
24
+ * PRESENT / NOT_PRESENT: any uniquely-or-not host on a visible navigator screen
25
+ * counts (web parity — duplicates are present). A measured 0×0 host counts as
26
+ * absent. AUTO `unknown` / `ambiguous` stay `null`.
24
27
  *
25
- * "Present" means a unique host on a **visible** navigator screen. MANUAL
26
- * goes through `resolveAnchorHost`; AUTO through `resolveAutoAnchorHost`.
27
- * Both skip screens covered by another navigator screen, so an id on a
28
- * pushed-under screen counts as absent. Pixel visibility (off-screen inside a
29
- * ScrollView, opacity 0, etc.) would need async `measureInWindow` and is out
30
- * of scope.
28
+ * CLICK / NOT_CLICK: latch from the first matching tap, including a tap on a
29
+ * descendant. The latch survives re-attach via `previousIsTrue` and is cleared
30
+ * when the server untracks. Disabled hosts are ignored. Until it latches, an
31
+ * AUTO selector that does not resolve reports `null`, like presence.
31
32
  *
32
- * Note: compares string literals rather than importing protocol enums so Jest
33
- * (which cannot resolve the ESM-only `@userflow-tech/protocol` package) stays
34
- * hermetic. Wire values match `FlowConditionElementState` / `FlowSelectorType`.
33
+ * Element states are compared as string literals rather than protocol enums so
34
+ * the wire values stay obvious next to the branches. They match
35
+ * `FlowConditionElementState`.
35
36
  */
36
37
  function createElementConditionEvaluator(warn = message => {
37
38
  if (__DEV__) {
@@ -45,51 +46,184 @@ function createElementConditionEvaluator(warn = message => {
45
46
  warnedConditionIds.add(conditionId);
46
47
  warn(message);
47
48
  };
48
- return (condition, report) => {
49
- const evaluate = () => {
50
- const result = evaluateElementCondition(condition, warnOnce);
51
- report(result);
49
+ return (condition, report, context) => {
50
+ const elementState = condition.elementState;
51
+ if (elementState === 'PRESENT' || elementState === 'NOT_PRESENT') {
52
+ return trackPresence(condition, elementState, report, warnOnce);
53
+ }
54
+ if (elementState === 'CLICK' || elementState === 'NOT_CLICK') {
55
+ return trackClick(condition, elementState, report, context, warnOnce);
56
+ }
57
+ warnOnce(condition.id, `[Userflow] ELEMENT condition ${condition.id} uses unsupported elementState ` + `"${elementState ?? 'null'}" (supported: PRESENT, NOT_PRESENT, CLICK, NOT_CLICK); ` + 'leaving unknown');
58
+ report(null);
59
+ return () => {};
60
+ };
61
+ }
62
+ function trackPresence(condition, elementState, report, warnOnce) {
63
+ // A synchronous result supersedes any older measurement. Only one
64
+ // measurement runs at a time, and a change during it re-runs once it settles
65
+ // instead of discarding it, so steady anchor churn cannot hold the condition
66
+ // at unknown.
67
+ let generation = 0;
68
+ let reportedGeneration = 0;
69
+ let measuring = false;
70
+ let changedWhileMeasuring = false;
71
+ let disposed = false;
72
+ const evaluate = () => {
73
+ if (disposed) return;
74
+ const gen = ++generation;
75
+ const resolution = (0, _resolveElementTargets.resolveElementTargets)(condition.selector);
76
+ if (resolution.status === 'unknown') {
77
+ if (!resolution.silent) warnUnknown(condition, warnOnce);
78
+ reportedGeneration = gen;
79
+ report(null);
80
+ return;
81
+ }
82
+ if (resolution.status === 'absent') {
83
+ reportedGeneration = gen;
84
+ report(elementState === 'PRESENT' ? false : true);
85
+ return;
86
+ }
87
+ if (measuring) {
88
+ changedWhileMeasuring = true;
89
+ return;
90
+ }
91
+ measuring = true;
92
+ void measureVisibility(resolution.targets).catch(() => 'unknown').then(visibility => {
93
+ measuring = false;
94
+ if (disposed) return;
95
+ if (gen > reportedGeneration) {
96
+ reportedGeneration = gen;
97
+ if (visibility === 'unknown') {
98
+ report(null);
99
+ } else {
100
+ const present = visibility === 'present';
101
+ report(elementState === 'PRESENT' ? present : !present);
102
+ }
103
+ }
104
+ if (changedWhileMeasuring) {
105
+ changedWhileMeasuring = false;
106
+ evaluate();
107
+ }
108
+ });
109
+ };
110
+ evaluate();
111
+ const unsubscribe = _anchorChangeTicker.anchorChangeTicker.subscribe(evaluate);
112
+ return () => {
113
+ disposed = true;
114
+ unsubscribe();
115
+ };
116
+ }
117
+ function trackClick(condition, elementState, report, context, warnOnce) {
118
+ if (!clickSelectorUsable(condition)) {
119
+ warnUnknown(condition, warnOnce);
120
+ report(null);
121
+ return () => {};
122
+ }
123
+
124
+ // CLICK starts false and latches true. NOT_CLICK starts true and latches false.
125
+ const valueWhenOccurred = elementState === 'CLICK';
126
+ if (context?.previousIsTrue === valueWhenOccurred) {
127
+ report(valueWhenOccurred);
128
+ return () => {};
129
+ }
130
+ let latched = false;
131
+ let stopWatchingResolution = () => {};
132
+ if (condition.selector?.type === 'AUTO') {
133
+ // An AUTO selector can stay unresolvable (empty auto-anchor registry, a
134
+ // tie between look-alikes), and then no tap can latch. Report unknown
135
+ // until it resolves, as presence does, rather than an unclicked value
136
+ // nothing could clear.
137
+ const reportUnclickedOnceResolvable = () => {
138
+ if (latched) return;
139
+ const resolution = (0, _resolveElementTargets.resolveElementTargets)(condition.selector);
140
+ if (resolution.status === 'unknown') {
141
+ if (!resolution.silent) warnUnknown(condition, warnOnce);
142
+ report(null);
143
+ return;
144
+ }
145
+ report(!valueWhenOccurred);
52
146
  };
53
- evaluate();
54
- return _anchorChangeTicker.anchorChangeTicker.subscribe(evaluate);
147
+ reportUnclickedOnceResolvable();
148
+ stopWatchingResolution = _anchorChangeTicker.anchorChangeTicker.subscribe(reportUnclickedOnceResolvable);
149
+ } else {
150
+ report(!valueWhenOccurred);
151
+ }
152
+ const subscription = {
153
+ unsubscribe: () => {}
154
+ };
155
+ subscription.unsubscribe = _elementTapMonitor.elementTapMonitor.subscribe(tap => {
156
+ if (latched) return;
157
+ if (!(0, _resolveElementTargets.tapMayHitSelector)(condition.selector, tap)) return;
158
+ const resolution = (0, _resolveElementTargets.resolveElementTargets)(condition.selector);
159
+ if (resolution.status !== 'found') return;
160
+ const matched = resolution.targets.find(target => target.fiber != null && (0, _elementTargetMatch.fiberIsUnder)(tap.targetFiber, target.fiber));
161
+ if (!matched?.fiber) return;
162
+ if ((0, _elementTargetMatch.tapPathDisabled)(tap.targetFiber, matched.fiber)) return;
163
+ latched = true;
164
+ report(valueWhenOccurred, {
165
+ immediate: true
166
+ });
167
+ subscription.unsubscribe();
168
+ stopWatchingResolution();
169
+ });
170
+ return () => {
171
+ subscription.unsubscribe();
172
+ stopWatchingResolution();
55
173
  };
56
174
  }
57
- function evaluateElementCondition(condition, warnOnce) {
58
- const elementState = condition.elementState;
59
- if (elementState == null || !SUPPORTED_ELEMENT_STATES.has(elementState)) {
60
- warnOnce(condition.id, `[Userflow] ELEMENT condition ${condition.id} uses unsupported elementState ` + `"${elementState ?? 'null'}" (only PRESENT / NOT_PRESENT are supported); ` + 'leaving unknown');
61
- return null;
175
+ function clickSelectorUsable(condition) {
176
+ const selector = condition.selector;
177
+ if (selector == null) return false;
178
+ if (selector.type === 'AUTO') {
179
+ // Without a fingerprint the selector can never resolve, so a definite
180
+ // NOT_CLICK true would start the flow on a target nobody can tap.
181
+ return (0, _protocol.decodeMobileAutoData)(selector.autoData)?.fingerprint != null;
62
182
  }
183
+ return (0, _resolveManualAnchorId.resolveManualAnchorId)(selector.css) != null;
184
+ }
185
+ function warnUnknown(condition, warnOnce) {
63
186
  const selector = condition.selector;
64
187
  if (selector == null) {
65
188
  warnOnce(condition.id, `[Userflow] ELEMENT condition ${condition.id} has no selector; leaving unknown`);
66
- return null;
189
+ return;
67
190
  }
68
191
  if (selector.type === 'AUTO') {
69
- const resolution = (0, _resolveAutoAnchorHost.resolveAutoAnchorHost)(selector.autoData);
70
- if (resolution.status === 'unknown') {
71
- warnOnce(condition.id, `[Userflow] ELEMENT condition ${condition.id} uses an AUTO (codeless) selector ` + 'that could not be resolved; leaving unknown');
72
- return null;
73
- }
74
- if (resolution.status === 'ambiguous') {
75
- return null;
76
- }
77
- const present = resolution.status === 'found';
78
- return elementState === 'PRESENT' ? present : !present;
192
+ warnOnce(condition.id, `[Userflow] ELEMENT condition ${condition.id} uses an AUTO (codeless) selector ` + 'that could not be resolved; leaving unknown');
193
+ return;
79
194
  }
80
- const anchorId = (0, _resolveManualAnchorId.resolveManualAnchorId)(selector.css);
81
- if (anchorId == null) {
82
- warnOnce(condition.id, `[Userflow] ELEMENT condition ${condition.id} has no resolvable manual anchor id; ` + 'leaving unknown');
83
- return null;
84
- }
85
- const resolution = (0, _resolveAnchorHost.resolveAnchorHost)(anchorId);
86
- // Ambiguous counts as not present for PRESENT (fail closed) and as "present"
87
- // for NOT_PRESENT would be wrong — treat ambiguous as unknown so gated flows
88
- // stay blocked rather than inventing a truth value.
89
- if (resolution.status === 'ambiguous') {
90
- return null;
195
+ warnOnce(condition.id, `[Userflow] ELEMENT condition ${condition.id} has no resolvable manual anchor id; ` + 'leaving unknown');
196
+ }
197
+ /** Measures hosts in parallel so duplicates cost one timeout, not one each. */
198
+ async function measureVisibility(targets) {
199
+ const slice = targets.slice(0, MAX_MEASURED_HOSTS);
200
+ const measured = await Promise.all(slice.map(measureHost));
201
+ if (measured.some(size => size !== 'timeout' && size.width > 0 && size.height > 0)) {
202
+ return 'present';
91
203
  }
92
- const present = resolution.status === 'found';
93
- return elementState === 'PRESENT' ? present : !present;
204
+ if (measured.includes('timeout') || targets.length > slice.length) return 'unknown';
205
+ return 'absent';
206
+ }
207
+ function measureHost(target) {
208
+ return new Promise(resolve => {
209
+ let settled = false;
210
+ const finish = value => {
211
+ if (settled) return;
212
+ settled = true;
213
+ clearTimeout(timer);
214
+ resolve(value);
215
+ };
216
+ const timer = setTimeout(() => finish('timeout'), MEASURE_TIMEOUT_MS);
217
+ try {
218
+ target.host.measureInWindow((_x, _y, width, height) => {
219
+ finish({
220
+ width,
221
+ height
222
+ });
223
+ });
224
+ } catch {
225
+ finish('timeout');
226
+ }
227
+ });
94
228
  }
95
229
  //# sourceMappingURL=elementConditionEvaluator.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_anchorChangeTicker","require","_resolveAnchorHost","_resolveAutoAnchorHost","_resolveManualAnchorId","SUPPORTED_ELEMENT_STATES","Set","createElementConditionEvaluator","warn","message","__DEV__","console","warnedConditionIds","warnOnce","conditionId","has","add","condition","report","evaluate","result","evaluateElementCondition","anchorChangeTicker","subscribe","elementState","id","selector","type","resolution","resolveAutoAnchorHost","autoData","status","present","anchorId","resolveManualAnchorId","css","resolveAnchorHost"],"sourceRoot":"../../../src","sources":["anchors/elementConditionEvaluator.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_protocol","require","_anchorChangeTicker","_elementTapMonitor","_elementTargetMatch","_resolveElementTargets","_resolveManualAnchorId","MAX_MEASURED_HOSTS","MEASURE_TIMEOUT_MS","createElementConditionEvaluator","warn","message","__DEV__","console","warnedConditionIds","Set","warnOnce","conditionId","has","add","condition","report","context","elementState","trackPresence","trackClick","id","generation","reportedGeneration","measuring","changedWhileMeasuring","disposed","evaluate","gen","resolution","resolveElementTargets","selector","status","silent","warnUnknown","measureVisibility","targets","catch","then","visibility","present","unsubscribe","anchorChangeTicker","subscribe","clickSelectorUsable","valueWhenOccurred","previousIsTrue","latched","stopWatchingResolution","type","reportUnclickedOnceResolvable","subscription","elementTapMonitor","tap","tapMayHitSelector","matched","find","target","fiber","fiberIsUnder","targetFiber","tapPathDisabled","immediate","decodeMobileAutoData","autoData","fingerprint","resolveManualAnchorId","css","slice","measured","Promise","all","map","measureHost","some","size","width","height","includes","length","resolve","settled","finish","value","clearTimeout","timer","setTimeout","host","measureInWindow","_x","_y"],"sourceRoot":"../../../src","sources":["anchors/elementConditionEvaluator.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.elementTapMonitor = exports.ElementTapMonitor = void 0;
7
+ var _targetPressMonitor = require("./targetPressMonitor.js");
8
+ /**
9
+ * Pass-through tap observation for ELEMENT CLICK / NOT_CLICK conditions.
10
+ *
11
+ * Many conditions can subscribe at once. Touch start/end are paired per finger
12
+ * and a tap is emitted only when movement stays within the same slop the
13
+ * tooltip target-press monitor uses. The host fiber is the one captured at
14
+ * touch start, before the press's setState commits a new tree.
15
+ *
16
+ * With no subscribers the monitor stores nothing, so the bridge can skip the
17
+ * fiber lookup entirely.
18
+ */
19
+
20
+ class ElementTapMonitor {
21
+ listeners = new Set();
22
+ touchStarts = new Map();
23
+ get subscriberCount() {
24
+ return this.listeners.size;
25
+ }
26
+ subscribe(listener) {
27
+ this.listeners.add(listener);
28
+ return () => {
29
+ this.listeners.delete(listener);
30
+ if (this.listeners.size === 0) {
31
+ this.touchStarts.clear();
32
+ }
33
+ };
34
+ }
35
+ handleTouchStart(identifier, pageX, pageY, targetFiber) {
36
+ if (this.listeners.size === 0) {
37
+ this.touchStarts.clear();
38
+ return;
39
+ }
40
+ this.touchStarts.set(identifier, {
41
+ pageX,
42
+ pageY,
43
+ targetFiber
44
+ });
45
+ }
46
+
47
+ /**
48
+ * Emit a tap when this finger started and ended within slop on a resolved
49
+ * host. Never claims the responder.
50
+ */
51
+ handleTouchEnd(identifier, pageX, pageY) {
52
+ const start = this.touchStarts.get(identifier) ?? null;
53
+ this.touchStarts.delete(identifier);
54
+ if (!start || this.listeners.size === 0 || !start.targetFiber) return;
55
+ if (!(0, _targetPressMonitor.withinTapSlop)(start, {
56
+ pageX,
57
+ pageY
58
+ })) return;
59
+ const tap = {
60
+ targetFiber: start.targetFiber
61
+ };
62
+ for (const listener of this.listeners) {
63
+ // One condition's failure must not cost the others this tap, or abort
64
+ // the bridge's handling of the event's remaining touches.
65
+ try {
66
+ listener(tap);
67
+ } catch {
68
+ // The condition stays at its current value.
69
+ }
70
+ }
71
+ }
72
+
73
+ /** Drop in-progress gesture(s). Omit `identifier` to clear every finger. */
74
+ cancelTouch(identifier) {
75
+ if (identifier == null) {
76
+ this.touchStarts.clear();
77
+ return;
78
+ }
79
+ this.touchStarts.delete(identifier);
80
+ }
81
+
82
+ /** Test helper. */
83
+ resetForTests() {
84
+ this.listeners.clear();
85
+ this.touchStarts.clear();
86
+ }
87
+ }
88
+
89
+ /** Shared singleton used by TargetPressBridge and the element-condition evaluator. */
90
+ exports.ElementTapMonitor = ElementTapMonitor;
91
+ const elementTapMonitor = exports.elementTapMonitor = new ElementTapMonitor();
92
+ //# sourceMappingURL=elementTapMonitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_targetPressMonitor","require","ElementTapMonitor","listeners","Set","touchStarts","Map","subscriberCount","size","subscribe","listener","add","delete","clear","handleTouchStart","identifier","pageX","pageY","targetFiber","set","handleTouchEnd","start","get","withinTapSlop","tap","cancelTouch","resetForTests","exports","elementTapMonitor"],"sourceRoot":"../../../src","sources":["anchors/elementTapMonitor.ts"],"mappings":";;;;;;AAYA,IAAAA,mBAAA,GAAAC,OAAA;AAZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAcO,MAAMC,iBAAiB,CAAC;EACZC,SAAS,GAAG,IAAIC,GAAG,CAAqB,CAAC;EACzCC,WAAW,GAAG,IAAIC,GAAG,CAA8B,CAAC;EAErE,IAAIC,eAAeA,CAAA,EAAW;IAC5B,OAAO,IAAI,CAACJ,SAAS,CAACK,IAAI;EAC5B;EAEAC,SAASA,CAACC,QAA4B,EAAc;IAClD,IAAI,CAACP,SAAS,CAACQ,GAAG,CAACD,QAAQ,CAAC;IAC5B,OAAO,MAAM;MACX,IAAI,CAACP,SAAS,CAACS,MAAM,CAACF,QAAQ,CAAC;MAC/B,IAAI,IAAI,CAACP,SAAS,CAACK,IAAI,KAAK,CAAC,EAAE;QAC7B,IAAI,CAACH,WAAW,CAACQ,KAAK,CAAC,CAAC;MAC1B;IACF,CAAC;EACH;EAEAC,gBAAgBA,CACdC,UAA2B,EAC3BC,KAAa,EACbC,KAAa,EACbC,WAA4B,EACtB;IACN,IAAI,IAAI,CAACf,SAAS,CAACK,IAAI,KAAK,CAAC,EAAE;MAC7B,IAAI,CAACH,WAAW,CAACQ,KAAK,CAAC,CAAC;MACxB;IACF;IACA,IAAI,CAACR,WAAW,CAACc,GAAG,CAACJ,UAAU,EAAE;MAAEC,KAAK;MAAEC,KAAK;MAAEC;IAAY,CAAC,CAAC;EACjE;;EAEA;AACF;AACA;AACA;EACEE,cAAcA,CAACL,UAA2B,EAAEC,KAAa,EAAEC,KAAa,EAAQ;IAC9E,MAAMI,KAAK,GAAG,IAAI,CAAChB,WAAW,CAACiB,GAAG,CAACP,UAAU,CAAC,IAAI,IAAI;IACtD,IAAI,CAACV,WAAW,CAACO,MAAM,CAACG,UAAU,CAAC;IACnC,IAAI,CAACM,KAAK,IAAI,IAAI,CAAClB,SAAS,CAACK,IAAI,KAAK,CAAC,IAAI,CAACa,KAAK,CAACH,WAAW,EAAE;IAC/D,IAAI,CAAC,IAAAK,iCAAa,EAACF,KAAK,EAAE;MAAEL,KAAK;MAAEC;IAAM,CAAC,CAAC,EAAE;IAE7C,MAAMO,GAAe,GAAG;MAAEN,WAAW,EAAEG,KAAK,CAACH;IAAY,CAAC;IAC1D,KAAK,MAAMR,QAAQ,IAAI,IAAI,CAACP,SAAS,EAAE;MACrC;MACA;MACA,IAAI;QACFO,QAAQ,CAACc,GAAG,CAAC;MACf,CAAC,CAAC,MAAM;QACN;MAAA;IAEJ;EACF;;EAEA;EACAC,WAAWA,CAACV,UAA4B,EAAQ;IAC9C,IAAIA,UAAU,IAAI,IAAI,EAAE;MACtB,IAAI,CAACV,WAAW,CAACQ,KAAK,CAAC,CAAC;MACxB;IACF;IACA,IAAI,CAACR,WAAW,CAACO,MAAM,CAACG,UAAU,CAAC;EACrC;;EAEA;EACAW,aAAaA,CAAA,EAAS;IACpB,IAAI,CAACvB,SAAS,CAACU,KAAK,CAAC,CAAC;IACtB,IAAI,CAACR,WAAW,CAACQ,KAAK,CAAC,CAAC;EAC1B;AACF;;AAEA;AAAAc,OAAA,CAAAzB,iBAAA,GAAAA,iBAAA;AACO,MAAM0B,iBAAiB,GAAAD,OAAA,CAAAC,iBAAA,GAAG,IAAI1B,iBAAiB,CAAC,CAAC","ignoreList":[]}
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.anchorIdsAboveTap = anchorIdsAboveTap;
7
+ exports.fiberIsUnder = fiberIsUnder;
8
+ exports.sameFiber = sameFiber;
9
+ exports.tapPathDisabled = tapPathDisabled;
10
+ var _fiberInternals = require("./fiber/fiberInternals.js");
11
+ var _findAnchorFiber = require("./fiber/findAnchorFiber.js");
12
+ /**
13
+ * Compare a touch-start fiber with a host resolved later, tolerating the
14
+ * alternate swap a Pressable `pressed` re-render does mid-gesture.
15
+ */
16
+
17
+ const anchorIdsByTap = new WeakMap();
18
+
19
+ /**
20
+ * Anchor ids on the tapped fiber and its ancestors, built once per tap and
21
+ * shared by every click condition it is delivered to.
22
+ */
23
+ function anchorIdsAboveTap(tap) {
24
+ const cached = anchorIdsByTap.get(tap);
25
+ if (cached) return cached;
26
+ const ids = new Set();
27
+ let current = tap.targetFiber;
28
+ for (let depth = 0; current && depth < _fiberInternals.MAX_ANCESTOR_WALK; depth += 1) {
29
+ const props = (0, _fiberInternals.getMemoizedProps)(current);
30
+ if (props) {
31
+ for (const tier of _findAnchorFiber.ANCHOR_PROP_TIERS) {
32
+ const value = props[tier];
33
+ if (typeof value === 'string') ids.add(value);
34
+ }
35
+ }
36
+ current = (0, _fiberInternals.getReturn)(current);
37
+ }
38
+ anchorIdsByTap.set(tap, ids);
39
+ return ids;
40
+ }
41
+ function sameFiber(a, b) {
42
+ if (a == null || b == null) return false;
43
+ if (a === b) return true;
44
+ const aAlt = (0, _fiberInternals.getAlternate)(a);
45
+ const bAlt = (0, _fiberInternals.getAlternate)(b);
46
+ return a === bAlt || aAlt === b || aAlt != null && aAlt === bAlt;
47
+ }
48
+
49
+ /** True when `node` is `host` or a descendant of it. */
50
+ function fiberIsUnder(node, host) {
51
+ let current = node;
52
+ for (let depth = 0; current && depth < _fiberInternals.MAX_ANCESTOR_WALK; depth += 1) {
53
+ if (sameFiber(current, host)) return true;
54
+ current = (0, _fiberInternals.getReturn)(current);
55
+ }
56
+ return false;
57
+ }
58
+ function fiberDisabled(fiber) {
59
+ let props;
60
+ try {
61
+ props = (0, _fiberInternals.getLiveHostProps)(fiber);
62
+ } catch {
63
+ return false;
64
+ }
65
+ if (!props) return false;
66
+ if (props.disabled === true) return true;
67
+ if (props['aria-disabled'] === true) return true;
68
+ const state = props.accessibilityState;
69
+ return typeof state === 'object' && state !== null && state.disabled === true;
70
+ }
71
+
72
+ /**
73
+ * True when the tapped fiber, the matched host, or a fiber between them is
74
+ * disabled. Browsers do not fire `click` on a disabled control.
75
+ */
76
+ function tapPathDisabled(tapped, host) {
77
+ let current = tapped;
78
+ for (let depth = 0; current && depth < _fiberInternals.MAX_ANCESTOR_WALK; depth += 1) {
79
+ if (fiberDisabled(current)) return true;
80
+ if (sameFiber(current, host)) return false;
81
+ current = (0, _fiberInternals.getReturn)(current);
82
+ }
83
+ return fiberDisabled(host);
84
+ }
85
+ //# sourceMappingURL=elementTargetMatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_fiberInternals","require","_findAnchorFiber","anchorIdsByTap","WeakMap","anchorIdsAboveTap","tap","cached","get","ids","Set","current","targetFiber","depth","MAX_ANCESTOR_WALK","props","getMemoizedProps","tier","ANCHOR_PROP_TIERS","value","add","getReturn","set","sameFiber","a","b","aAlt","getAlternate","bAlt","fiberIsUnder","node","host","fiberDisabled","fiber","getLiveHostProps","disabled","state","accessibilityState","tapPathDisabled","tapped"],"sourceRoot":"../../../src","sources":["anchors/elementTargetMatch.ts"],"mappings":"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","ignoreList":[]}