@dynatrace/react-native-plugin 2.333.1 → 2.335.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.
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.TabButton = exports.LabelClaimScope = exports.AnalyticsRoot = exports.PathPrefix = exports.Segment = exports.AnalyticsProvider = exports._an_flat = exports.buildUiEventShape = exports.compactify = exports.FORCED_TOUCHABLES = exports.CfgCtx = void 0;
3
+ exports.AnalyticsRoot = exports._an_flat = exports.buildUiEventShape = exports.compactify = void 0;
4
4
  const React = require("react");
5
5
  const react_1 = require("react");
6
6
  const react_native_1 = require("react-native");
@@ -9,292 +9,117 @@ const EventTimestamp_1 = require("../../../lib/next/events/EventTimestamp");
9
9
  const ConsoleLogger_1 = require("../../../lib/core/logging/ConsoleLogger");
10
10
  const IUserInteractionEvent_1 = require("./IUserInteractionEvent");
11
11
  const ConfigurationHandler_1 = require("../../../lib/core/configuration/ConfigurationHandler");
12
+ const RuntimeConfigurationObserver_1 = require("../../../lib/next/configuration/RuntimeConfigurationObserver");
13
+ const TouchMetaResolver_1 = require("./TouchMetaResolver");
12
14
  class TimestampProvider {
13
15
  constructor() {
14
16
  this.getCurrentTimestamp = () => Date.now();
15
17
  }
16
18
  }
17
19
  const logger = new ConsoleLogger_1.ConsoleLogger('DyntraceUserInteraction');
18
- const NodeCtx = (0, react_1.createContext)(null);
19
- const LogCtx = (0, react_1.createContext)(null);
20
- exports.CfgCtx = (0, react_1.createContext)({});
21
- const TouchCtx = (0, react_1.createContext)(null);
20
+ function isUiDebugEnabled() {
21
+ return (globalThis
22
+ .__DT_UII_DEBUG === true);
23
+ }
24
+ function uiDebugLog(message, data) {
25
+ if (!isUiDebugEnabled())
26
+ return;
27
+ if (data) {
28
+ console.log(`[DT UI DEBUG] ${message}`, data);
29
+ return;
30
+ }
31
+ console.log(`[DT UI DEBUG] ${message}`);
32
+ }
22
33
  let LAST_EMIT_KEY = null;
23
34
  let LAST_EMIT_TS = 0;
24
35
  let LAST_PRESS_ID = null;
25
36
  let LAST_PRESS_TS = 0;
26
- const RE_FORWARD_REF = Symbol.for('react.forward_ref');
27
- const RE_MEMO = Symbol.for('react.memo');
28
- const RE_FRAGMENT = Symbol.for('react.fragment');
29
- const HANDLE_REG = new Map();
30
- exports.FORCED_TOUCHABLES = new Set([
31
- 'TouchableOpacity',
32
- 'TouchableHighlight',
33
- 'TouchableWithoutFeedback',
34
- 'TouchableNativeFeedback',
35
- 'Pressable',
36
- 'TouchableOpacity_GH',
37
- 'TouchableHighlight_GH',
38
- 'TouchableWithoutFeedback_GH',
39
- 'RectButton',
40
- 'BorderlessButton',
41
- 'HeaderBackButton',
42
- 'HeaderTitle',
43
- 'DrawerItem',
44
- 'DrawerToggleButton',
45
- 'TabBarItem',
46
- ]);
47
- const PRESS_KEYS = new Set([
48
- 'onPress',
49
- 'onLongPress',
50
- 'onTap',
51
- 'onClick',
52
- 'onTouchStart',
53
- ]);
54
- const TEXTINPUT_KEYS = new Set([
55
- 'onFocus',
56
- 'onBlur',
57
- 'onSubmitEditing',
58
- 'onEndEditing',
59
- 'onChangeText',
60
- ]);
61
- const DEFAULT_ROLE_HEURISTICS = {
62
- nav: [/nav/i, /stack/i, /tab/i, /drawer/i, /navigator/i, /screen$/i],
63
- theme: [/theme/i],
64
- provider: [/provider/i, /context/i],
65
- list: [/list/i, /flatlist/i, /sectionlist/i, /virtualizedlist/i],
66
- view: [/^view$/i, /^text$/i, /^image$/i, /scrollview/i, /pressable/i],
67
- };
68
- const isReactNodeIterable = (node) => typeof node === 'object' && node !== null && Symbol.iterator in node;
69
- const SiblingCtx = (0, react_1.createContext)(null);
70
37
  function getDtLastTouch() {
38
+ var _a;
71
39
  const g = globalThis;
72
- if (!g.__DT_LAST_TOUCH)
73
- g.__DT_LAST_TOUCH = { ts: 0, x: 0, y: 0 };
40
+ (_a = g.__DT_LAST_TOUCH) !== null && _a !== void 0 ? _a : (g.__DT_LAST_TOUCH = { ts: 0, x: 0, y: 0 });
74
41
  return g.__DT_LAST_TOUCH;
75
42
  }
76
- function isExpoRuntime() {
77
- const g = globalThis;
78
- return !!((g === null || g === void 0 ? void 0 : g.expo) || (g === null || g === void 0 ? void 0 : g.__expo) || (g === null || g === void 0 ? void 0 : g.Expo));
79
- }
80
- function isNativeTextInputViewTarget(t) {
81
- var _a;
82
- const cls = (_a = t === null || t === void 0 ? void 0 : t._viewConfig) === null || _a === void 0 ? void 0 : _a.uiViewClassName;
83
- if (typeof cls !== 'string')
84
- return false;
85
- return (cls === 'RCTSinglelineTextInputView' ||
86
- cls === 'RCTMultilineTextInputView' ||
87
- cls === 'AndroidTextInput' ||
88
- cls.toLowerCase().includes('textinput'));
89
- }
90
- function makePreIndexedRegistry(children) {
91
- var _a, _b;
92
- const table = new Map();
93
- const counts = new Map();
94
- const arr = react_1.Children.toArray(children);
95
- for (let i = 0; i < arr.length; i++) {
96
- const el = arr[i];
97
- if (!(0, react_1.isValidElement)(el))
98
- continue;
99
- const name = getElTypeName(el);
100
- const key = String((_a = el.key) !== null && _a !== void 0 ? _a : `__pos:${i}`);
101
- const cur = ((_b = counts.get(name)) !== null && _b !== void 0 ? _b : 0) + 1;
102
- counts.set(name, cur);
103
- let bucket = table.get(name);
104
- if (!bucket) {
105
- bucket = new Map();
106
- table.set(name, bucket);
107
- }
108
- bucket.set(key, cur);
43
+ function flattenTextChildren(children) {
44
+ if (Array.isArray(children)) {
45
+ return children.map((child) => flattenTextChildren(child)).join('');
109
46
  }
110
- return {
111
- getIndex(name, key) {
112
- var _a;
113
- const bucket = table.get(name);
114
- if (!bucket)
115
- return 1;
116
- return (_a = bucket.get(key)) !== null && _a !== void 0 ? _a : 1;
117
- },
118
- };
119
- }
120
- function shortSid(s) {
121
- if (!s)
47
+ if (children === null || children === undefined || children === false)
122
48
  return '';
123
- const str = String(s);
124
- let h = 5381;
125
- for (let i = 0; i < str.length; i++) {
126
- h = ((h << 5) + h) ^ str.codePointAt(i);
127
- }
128
- const base = Math.abs(h >>> 0).toString(36);
129
- return base.slice(-6);
49
+ return String(children);
130
50
  }
131
- function toPathString(n, cfg) {
132
- var _a, _b, _c, _d, _e;
133
- const parts = [];
134
- const exNames = new Set((_a = cfg === null || cfg === void 0 ? void 0 : cfg.excludeNames) !== null && _a !== void 0 ? _a : []);
135
- const exRoles = new Set((_b = cfg === null || cfg === void 0 ? void 0 : cfg.excludeRoles) !== null && _b !== void 0 ? _b : []);
136
- const segs = [];
137
- let cur = n;
138
- while (cur) {
139
- segs.push(cur);
140
- cur = cur.parent;
141
- }
142
- segs.reverse();
143
- const needGlobal = ((_c = cfg === null || cfg === void 0 ? void 0 : cfg.indexMode) !== null && _c !== void 0 ? _c : 'sibling') !== 'sibling';
144
- const gCounts = new Map();
145
- for (const seg of segs) {
146
- if (exNames.has(seg.name) || (seg.role && exRoles.has(seg.role)))
147
- continue;
148
- let gIdx;
149
- if (needGlobal) {
150
- const c = ((_d = gCounts.get(seg.name)) !== null && _d !== void 0 ? _d : 0) + 1;
151
- gCounts.set(seg.name, c);
152
- gIdx = c;
51
+ function findRCTTextChild(fiber) {
52
+ let node = fiber === null || fiber === void 0 ? void 0 : fiber.child;
53
+ while (node) {
54
+ if (node.type === 'RCTText') {
55
+ return node;
153
56
  }
154
- parts.push(formatSegEx(seg, cfg, gIdx));
57
+ const found = findRCTTextChild(node);
58
+ if (found)
59
+ return found;
60
+ node = node.sibling;
155
61
  }
156
- const sep = (_e = cfg === null || cfg === void 0 ? void 0 : cfg.separator) !== null && _e !== void 0 ? _e : '->';
157
- return parts.join(sep);
62
+ return null;
158
63
  }
159
- function formatSegIndex(seg, mode, style, gIdx) {
160
- const siblingIndex = typeof seg.idx === 'number' ? String(seg.idx) : '';
161
- const globalIndex = typeof gIdx === 'number' ? String(gIdx) : '';
162
- if (mode === 'sibling') {
163
- if (!siblingIndex)
164
- return '';
165
- return style === 'bracket' ? `[${siblingIndex}]` : `#${siblingIndex}`;
166
- }
167
- if (mode === 'global') {
168
- if (!globalIndex)
169
- return '';
170
- return style === 'bracket' ? `[${globalIndex}]` : `^g${globalIndex}`;
171
- }
172
- if (style === 'bracket') {
173
- return `[${siblingIndex}|${globalIndex}]`;
64
+ function getAnyParentMasked(fiber) {
65
+ var _a;
66
+ let cursor = fiber;
67
+ while (cursor) {
68
+ if ((_a = cursor.memoizedProps) === null || _a === void 0 ? void 0 : _a.dtMask)
69
+ return true;
70
+ cursor = cursor.return;
174
71
  }
175
- const siblingPart = siblingIndex ? `#${siblingIndex}` : '';
176
- const globalPart = globalIndex ? `^g${globalIndex}` : '';
177
- return `${siblingPart}${globalPart}`;
178
- }
179
- function formatSegSid(cfg, sid) {
180
- if (!(cfg === null || cfg === void 0 ? void 0 : cfg.withSid) || !sid)
181
- return '';
182
- const short = shortSid(sid);
183
- return short ? `~k${short}` : '';
184
- }
185
- function formatSegEx(seg, cfg, gIdx) {
186
- var _a, _b;
187
- const label = seg.label ? `(${seg.label})` : '';
188
- const role = (cfg === null || cfg === void 0 ? void 0 : cfg.withRole) && seg.role ? `:${seg.role}` : '';
189
- const mode = (_a = cfg === null || cfg === void 0 ? void 0 : cfg.indexMode) !== null && _a !== void 0 ? _a : 'sibling';
190
- const style = (_b = cfg === null || cfg === void 0 ? void 0 : cfg.indexStyle) !== null && _b !== void 0 ? _b : 'classic';
191
- const idx = (cfg === null || cfg === void 0 ? void 0 : cfg.withIndex) ? formatSegIndex(seg, mode, style, gIdx) : '';
192
- const sid = formatSegSid(cfg, seg.sid);
193
- return `${seg.name}${label}${role}${idx}${sid}`;
194
- }
195
- function normPhase(k) {
196
- return k.replace(/^on/, '').replace(/^[A-Z]/, (m) => m.toLowerCase());
197
- }
198
- function trimText(x) {
199
- if (typeof x !== 'string')
200
- return '';
201
- const s = x.trim().split(/\s+/).join(' ');
202
- return s.length > 0 ? s : '';
203
- }
204
- function isLabelScope(el) {
205
- return (!!el &&
206
- typeof el.type === 'function' &&
207
- el.type.__AN_LABEL_SCOPE === true);
208
- }
209
- function getElTypeName(el) {
210
- var _a, _b;
211
- if (!el)
212
- return 'Anonymous';
213
- if (typeof el.type === 'string')
214
- return el.type;
215
- const raw = ((_a = el.type) === null || _a === void 0 ? void 0 : _a.displayName) || ((_b = el.type) === null || _b === void 0 ? void 0 : _b.name) || 'Anonymous';
216
- const m = /^ForwardRef\((.+)\)$/.exec(raw) || /^Memo\((.+)\)$/.exec(raw);
217
- return m ? m[1] : raw;
72
+ return false;
218
73
  }
219
- function collectLeafInfo(node, depth = 0, maxDepth = 5, maxNodes = 200, lastType) {
220
- let seen = 0;
221
- function makeTextLeaf(value, typeHint) {
222
- const text = trimText(value);
223
- if (!text)
224
- return null;
225
- return {
226
- label: text,
227
- type: typeHint || 'Text',
228
- source: 'text',
229
- };
230
- }
231
- function getIterableNode(n) {
232
- if (Array.isArray(n))
233
- return n;
234
- if (isReactNodeIterable(n))
235
- return n;
236
- return null;
237
- }
238
- function walkIterable(iterable, d, lastT) {
239
- for (const child of iterable) {
240
- const found = walk(child, d + 1, lastT);
241
- if (found)
242
- return found;
243
- }
244
- return null;
245
- }
246
- function makePropLeaf(props, thisType) {
247
- if (typeof (props === null || props === void 0 ? void 0 : props.accessibilityLabel) === 'string') {
248
- return {
249
- label: props.accessibilityLabel,
250
- type: thisType,
251
- source: 'accessibility',
252
- };
253
- }
254
- if (typeof (props === null || props === void 0 ? void 0 : props.testID) === 'string') {
74
+ function getHostComponentInfoFromEvent(event, cfg) {
75
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
76
+ let fiber = (_a = event === null || event === void 0 ? void 0 : event._targetInst) !== null && _a !== void 0 ? _a : (_b = event === null || event === void 0 ? void 0 : event.nativeEvent) === null || _b === void 0 ? void 0 : _b._targetInst;
77
+ if (!fiber)
78
+ return undefined;
79
+ const meta = (0, TouchMetaResolver_1.getTouchElementMeta)(event);
80
+ const resolvedPath = (_d = (_c = meta.press) === null || _c === void 0 ? void 0 : _c.appCodeTagPath) !== null && _d !== void 0 ? _d : meta.touch.appCodeTagPath;
81
+ if (!resolvedPath || resolvedPath === 'unknown')
82
+ return undefined;
83
+ const anyParentMasked = getAnyParentMasked(fiber);
84
+ const components = [lastSegment(resolvedPath) || 'Anonymous'];
85
+ const targetIsContainerHost = fiber.type === 'RCTView' ||
86
+ fiber.type === 'View' ||
87
+ fiber.type === 'RCTScrollView' ||
88
+ fiber.type === 'ScrollView';
89
+ if (!targetIsContainerHost && fiber.type !== 'RCTText') {
90
+ fiber = (_e = findRCTTextChild(fiber)) !== null && _e !== void 0 ? _e : fiber;
91
+ }
92
+ const textValue = flattenTextChildren((_f = fiber === null || fiber === void 0 ? void 0 : fiber.memoizedProps) === null || _f === void 0 ? void 0 : _f.children).trim();
93
+ const textMaskedByRule = textValue.length > 0 && ((_h = (_g = cfg === null || cfg === void 0 ? void 0 : cfg.mask) === null || _g === void 0 ? void 0 : _g.text) === null || _h === void 0 ? void 0 : _h.call(_g, textValue)) === true;
94
+ const testId = (_j = fiber === null || fiber === void 0 ? void 0 : fiber.memoizedProps) === null || _j === void 0 ? void 0 : _j.testID;
95
+ const testIdMaskedByRule = typeof testId === 'string' && !!((_l = (_k = cfg === null || cfg === void 0 ? void 0 : cfg.mask) === null || _k === void 0 ? void 0 : _k.testID) === null || _l === void 0 ? void 0 : _l.call(_k, testId));
96
+ const isMasked = anyParentMasked || textMaskedByRule || testIdMaskedByRule;
97
+ if (fiber.type === 'RCTText' && textValue.length > 0) {
98
+ if (isMasked) {
255
99
  return {
256
- label: props.testID,
257
- type: thisType,
258
- source: 'testid',
100
+ id: resolvedPath,
101
+ components,
102
+ detectedName: maskLabel(textValue, cfg),
103
+ nameOrigin: 'masked',
104
+ isMasked: true,
259
105
  };
260
106
  }
261
- return null;
262
- }
263
- function walkElement(el, d, lastT) {
264
- var _a, _b;
265
- const rawType = getElTypeName(el);
266
- const segmentName = (_a = el === null || el === void 0 ? void 0 : el.props) === null || _a === void 0 ? void 0 : _a.name;
267
- const hasSegmentName = rawType === 'Segment' &&
268
- typeof segmentName === 'string' &&
269
- segmentName.length > 0;
270
- const thisType = hasSegmentName ? segmentName : rawType;
271
- if (isLabelScope(el)) {
272
- const inner = walk((_b = el.props) === null || _b === void 0 ? void 0 : _b.children, d + 1, 'LabelClaimScope');
273
- return inner ? Object.assign(Object.assign({}, inner), { source: 'label-claim' }) : null;
274
- }
275
- const props = el === null || el === void 0 ? void 0 : el.props;
276
- if (!props)
277
- return null;
278
- const childLeaf = walk(props.children, d + 1, thisType);
279
- if (childLeaf)
280
- return childLeaf;
281
- return makePropLeaf(props, thisType);
282
- }
283
- function walk(n, d, lastT) {
284
- if (seen++ > maxNodes || d > maxDepth)
285
- return null;
286
- if (typeof n === 'string' || typeof n === 'number')
287
- return makeTextLeaf(String(n), lastT);
288
- if (!n)
289
- return null;
290
- const iterable = getIterableNode(n);
291
- if (iterable)
292
- return walkIterable(iterable, d, lastT);
293
- if (typeof n !== 'object')
294
- return null;
295
- return walkElement(n, d, lastT);
107
+ return {
108
+ id: resolvedPath,
109
+ components,
110
+ detectedName: textValue,
111
+ nameOrigin: 'text',
112
+ isMasked: false,
113
+ };
296
114
  }
297
- return walk(node, depth, lastType);
115
+ const detectedName = (_p = (_o = (_m = meta.press) === null || _m === void 0 ? void 0 : _m.elementName) !== null && _o !== void 0 ? _o : meta.touch.elementName) !== null && _p !== void 0 ? _p : 'Anonymous';
116
+ return {
117
+ id: resolvedPath,
118
+ components,
119
+ detectedName,
120
+ nameOrigin: 'component',
121
+ isMasked,
122
+ };
298
123
  }
299
124
  function readGlobalPrefix() {
300
125
  const globalRuntime = globalThis;
@@ -314,99 +139,10 @@ function readGlobalPrefix() {
314
139
  }
315
140
  return [];
316
141
  }
317
- function classifyByHeuristics(name, h) {
318
- const rules = h
319
- ? Object.assign(Object.assign({}, DEFAULT_ROLE_HEURISTICS), h) : DEFAULT_ROLE_HEURISTICS;
320
- const hit = (arr) => arr.some((rx) => rx.test(name));
321
- if (hit(rules.nav))
322
- return 'nav';
323
- if (hit(rules.theme))
324
- return 'theme';
325
- if (hit(rules.provider))
326
- return 'provider';
327
- if (hit(rules.list))
328
- return 'list';
329
- if (hit(rules.view))
330
- return 'view';
331
- return null;
332
- }
333
- function classifyRole(name, map, heur) {
334
- var _a;
335
- if (map && map[name])
336
- return map[name];
337
- if (heur === false) {
338
- if (name === 'ThemeProvider')
339
- return 'theme';
340
- if (name === 'FlatList' ||
341
- name === 'SectionList' ||
342
- name === 'VirtualizedList')
343
- return 'list';
344
- if (name === 'View' ||
345
- name === 'Text' ||
346
- name === 'Pressable' ||
347
- name === 'Image' ||
348
- name === 'ScrollView')
349
- return 'view';
350
- const low = name.toLowerCase();
351
- if (/provider|context/.test(low))
352
- return 'provider';
353
- if (/(stack|tabs|tab|drawer|navigator|screen$)/i.test(low))
354
- return 'nav';
355
- return 'comp';
356
- }
357
- return ((_a = classifyByHeuristics(name, heur || DEFAULT_ROLE_HEURISTICS)) !== null && _a !== void 0 ? _a : 'comp');
358
- }
359
- function hasArrayValue(arr, value) {
360
- return Array.isArray(arr) && Array.prototype.indexOf.call(arr, value) >= 0;
361
- }
362
- function shouldMaskLeaf(leaf, only, segRole, cfg) {
363
- var _a, _b, _c, _d, _e;
364
- if (((_a = only === null || only === void 0 ? void 0 : only.props) === null || _a === void 0 ? void 0 : _a.dtMask) === true)
365
- return true;
366
- if (isLabelScope(only) && ((_b = only === null || only === void 0 ? void 0 : only.props) === null || _b === void 0 ? void 0 : _b.mask))
367
- return true;
368
- const rules = cfg === null || cfg === void 0 ? void 0 : cfg.mask;
369
- if (!rules)
370
- return false;
371
- const name = getElTypeName(only);
372
- if (hasArrayValue(rules.names, name))
373
- return true;
374
- if (segRole && hasArrayValue(rules.roles, segRole))
375
- return true;
376
- if (typeof ((_c = only === null || only === void 0 ? void 0 : only.props) === null || _c === void 0 ? void 0 : _c.testID) === 'string' &&
377
- ((_d = rules.testID) === null || _d === void 0 ? void 0 : _d.call(rules, only.props.testID)))
378
- return true;
379
- if ((leaf === null || leaf === void 0 ? void 0 : leaf.source) === 'text' &&
380
- typeof leaf.label === 'string' &&
381
- ((_e = rules.text) === null || _e === void 0 ? void 0 : _e.call(rules, leaf.label)))
382
- return true;
383
- return false;
384
- }
385
142
  function maskLabel(_s, cfg) {
386
143
  var _a, _b;
387
144
  return (_b = (_a = cfg === null || cfg === void 0 ? void 0 : cfg.mask) === null || _a === void 0 ? void 0 : _a.replaceWith) !== null && _b !== void 0 ? _b : '***';
388
145
  }
389
- function extractPosition(args, cap) {
390
- if (cap === 'none')
391
- return undefined;
392
- const e = args[0];
393
- const ne = e === null || e === void 0 ? void 0 : e.nativeEvent;
394
- if (!ne)
395
- return undefined;
396
- if (cap === 'page')
397
- return {
398
- x: Number(ne.pageX),
399
- y: Number(ne.pageY),
400
- type: 'page',
401
- };
402
- if (cap === 'local')
403
- return {
404
- x: Number(ne.locationX),
405
- y: Number(ne.locationY),
406
- type: 'local',
407
- };
408
- return { x: Number(ne.pageX), y: Number(ne.pageY), type: 'both' };
409
- }
410
146
  function compactify(cfg, obj) {
411
147
  var _a;
412
148
  if (!((_a = cfg === null || cfg === void 0 ? void 0 : cfg.touch) === null || _a === void 0 ? void 0 : _a.compact))
@@ -426,14 +162,15 @@ function compactify(cfg, obj) {
426
162
  return (_a = keyMap[k]) !== null && _a !== void 0 ? _a : k;
427
163
  };
428
164
  const normalizeCompactObject = (compactObject) => {
429
- if (compactObject.pos && compactObject.pos.type) {
165
+ var _a, _b;
166
+ if ((_a = compactObject.pos) === null || _a === void 0 ? void 0 : _a.type) {
430
167
  compactObject.pos = {
431
168
  x: compactObject.pos.x,
432
169
  y: compactObject.pos.y,
433
170
  t: compactObject.pos.type,
434
171
  };
435
172
  }
436
- if (compactObject.m && compactObject.m.phase) {
173
+ if ((_b = compactObject.m) === null || _b === void 0 ? void 0 : _b.phase) {
437
174
  compactObject.ph = compactObject.m.phase;
438
175
  compactObject.ts = compactObject.m.ts;
439
176
  delete compactObject.m;
@@ -463,43 +200,17 @@ function compactify(cfg, obj) {
463
200
  return walk(obj);
464
201
  }
465
202
  exports.compactify = compactify;
466
- function registerHandle(handle, info) {
467
- if (!handle)
468
- return;
469
- if (info) {
470
- HANDLE_REG.set(handle, info);
471
- }
472
- else {
473
- HANDLE_REG.delete(handle);
474
- }
475
- }
476
- function findHitInfo(nativeTarget) {
477
- const h = Number(nativeTarget || 0);
478
- if (!h)
203
+ function findHostInfoHit(event, cfg) {
204
+ const hostInfo = getHostComponentInfoFromEvent(event, cfg);
205
+ if (!hostInfo)
479
206
  return null;
480
- const exact = HANDLE_REG.get(h) || null;
481
- if (exact)
482
- return Object.assign(Object.assign({}, exact), { __dtMatch: 'exact' });
483
- return null;
484
- }
485
- function resolveScrollableContextHit() {
486
- for (const v of HANDLE_REG.values()) {
487
- const p = v === null || v === void 0 ? void 0 : v.path;
488
- if (typeof p === 'string' && p.includes('FlatList')) {
489
- return Object.assign(Object.assign({}, v), { __dtMatch: 'override' });
490
- }
491
- }
492
- return null;
493
- }
494
- function normalizeFuzzyHit(hit) {
495
- if (!hit)
496
- return hit;
497
- if (hit.__dtMatch !== 'fuzzy')
498
- return hit;
499
- if (hit.element !== '<')
500
- return hit;
501
- const fl = resolveScrollableContextHit();
502
- return fl || hit;
207
+ return {
208
+ path: hostInfo.id,
209
+ element: hostInfo.detectedName,
210
+ isMasked: hostInfo.isMasked,
211
+ name_origin: hostInfo.nameOrigin,
212
+ __dtMatch: 'scan',
213
+ };
503
214
  }
504
215
  function makeSid() {
505
216
  const t = Date.now().toString(36);
@@ -529,26 +240,6 @@ function makePos(ne, cap) {
529
240
  };
530
241
  return undefined;
531
242
  }
532
- function supportsRefType(type) {
533
- if (!type)
534
- return false;
535
- if (typeof type === 'string')
536
- return true;
537
- const typeLike = type;
538
- const $$ = typeLike.$$typeof;
539
- if ($$ === RE_FORWARD_REF)
540
- return true;
541
- if ($$ === RE_MEMO) {
542
- const inner = typeLike.type;
543
- const innerSig = inner && typeof inner === 'object' ? inner.$$typeof : undefined;
544
- return innerSig === RE_FORWARD_REF || typeof inner === 'string';
545
- }
546
- if ($$ === RE_FRAGMENT)
547
- return false;
548
- return !!(typeLike &&
549
- typeLike.prototype &&
550
- typeof typeLike.prototype.render === 'function');
551
- }
552
243
  function lastSegment(path) {
553
244
  if (!path)
554
245
  return '';
@@ -564,7 +255,8 @@ function parseComponent(seg) {
564
255
  if (!seg)
565
256
  return 'Anonymous';
566
257
  const base = seg.split(':', 1)[0];
567
- const m = /^([^(]+)(?:\(.*\))?$/.exec(base);
258
+ const withoutPathId = base.split('#', 1)[0];
259
+ const m = /^([^(]+)(?:\(.*\))?$/.exec(withoutPathId);
568
260
  return (m ? m[1] : base) || 'Anonymous';
569
261
  }
570
262
  function __dt_set_scope_path(path) {
@@ -765,8 +457,19 @@ function useTouchManager(cfg, log) {
765
457
  }
766
458
  timerRef.current = setTimeout(() => doFlush(), delay);
767
459
  };
768
- const resolveTouchHit = (nativeTarget) => normalizeFuzzyHit(findHitInfo(nativeTarget)) ||
769
- resolveScrollableContextHit();
460
+ const resolveTouchHit = (_nativeTarget, event) => {
461
+ const hostHit = findHostInfoHit(event, cfg);
462
+ if (hostHit) {
463
+ uiDebugLog('resolveTouchHit: host hit found', {
464
+ path: hostHit.path,
465
+ element: hostHit.element,
466
+ match: hostHit.__dtMatch,
467
+ });
468
+ return hostHit;
469
+ }
470
+ uiDebugLog('resolveTouchHit: no hit found');
471
+ return null;
472
+ };
770
473
  const maybeLiftTouchHit = (hit) => {
771
474
  var _a;
772
475
  if (!hit || hit.__dtMatch === 'exact') {
@@ -798,10 +501,11 @@ function useTouchManager(cfg, log) {
798
501
  else
799
502
  scheduleFlush((_b = (_a = cfg.touch) === null || _a === void 0 ? void 0 : _a.linkWindowMs) !== null && _b !== void 0 ? _b : 250);
800
503
  };
801
- const handleStreamEnd = (ne, phase) => {
504
+ const handleStreamEnd = (event, phase) => {
802
505
  var _a, _b;
803
- const hit = resolveTouchHit(ne === null || ne === void 0 ? void 0 : ne.target);
804
- if (!hit || !hit.path)
506
+ const ne = event === null || event === void 0 ? void 0 : event.nativeEvent;
507
+ const hit = resolveTouchHit(ne === null || ne === void 0 ? void 0 : ne.target, event);
508
+ if (!(hit === null || hit === void 0 ? void 0 : hit.path))
805
509
  return;
806
510
  const lifted = maybeLiftTouchHit(hit);
807
511
  const pos = makePos(ne, (_b = (_a = cfg.click) === null || _a === void 0 ? void 0 : _a.capturePosition) !== null && _b !== void 0 ? _b : 'none');
@@ -826,9 +530,15 @@ function useTouchManager(cfg, log) {
826
530
  if (!((_a = cfg.touch) === null || _a === void 0 ? void 0 : _a.enabled))
827
531
  return;
828
532
  const ne = e === null || e === void 0 ? void 0 : e.nativeEvent;
829
- let hit = findHitInfo(ne === null || ne === void 0 ? void 0 : ne.target);
830
- hit = normalizeFuzzyHit(hit) || resolveScrollableContextHit();
831
- if (!hit || !hit.path) {
533
+ const hit = resolveTouchHit(ne === null || ne === void 0 ? void 0 : ne.target, e);
534
+ uiDebugLog('onStart', {
535
+ hasHit: !!(hit === null || hit === void 0 ? void 0 : hit.path),
536
+ targetType: typeof (ne === null || ne === void 0 ? void 0 : ne.target),
537
+ pageX: Number(ne === null || ne === void 0 ? void 0 : ne.pageX) || 0,
538
+ pageY: Number(ne === null || ne === void 0 ? void 0 : ne.pageY) || 0,
539
+ mode,
540
+ });
541
+ if (!(hit === null || hit === void 0 ? void 0 : hit.path)) {
832
542
  clearAll();
833
543
  sidRef.current = makeSid();
834
544
  startTsRef.current = Date.now();
@@ -891,15 +601,22 @@ function useTouchManager(cfg, log) {
891
601
  return;
892
602
  const ne = e === null || e === void 0 ? void 0 : e.nativeEvent;
893
603
  if (mode === 'stream') {
894
- handleStreamEnd(ne, phase);
604
+ handleStreamEnd(e, phase);
895
605
  return;
896
606
  }
897
607
  const pos = makePos(ne, (_c = (_b = cfg.click) === null || _b === void 0 ? void 0 : _b.capturePosition) !== null && _c !== void 0 ? _c : 'none');
898
- const hitRaw = resolveTouchHit(ne === null || ne === void 0 ? void 0 : ne.target);
608
+ const hitRaw = resolveTouchHit(ne === null || ne === void 0 ? void 0 : ne.target, e);
899
609
  const now = Date.now();
900
610
  const lifted = maybeLiftTouchHit(hitRaw);
901
611
  const usePath = lifted.usePath;
902
612
  const useEl = lifted.useElement || '';
613
+ uiDebugLog('onEnd', {
614
+ phase,
615
+ hasHit: !!(hitRaw === null || hitRaw === void 0 ? void 0 : hitRaw.path),
616
+ usePath: usePath || null,
617
+ useElement: useEl || null,
618
+ mode,
619
+ });
903
620
  if (!usePath) {
904
621
  const scopePath = startPathRef.current || __dt_get_scope_path();
905
622
  touchRef.current = {
@@ -935,6 +652,12 @@ function useTouchManager(cfg, log) {
935
652
  if (!((_a = cfg.touch) === null || _a === void 0 ? void 0 : _a.enabled))
936
653
  return;
937
654
  const now = Date.now();
655
+ uiDebugLog('registerPress', {
656
+ path: info.path,
657
+ elementName: info.elementName,
658
+ hasPos: !!info.pos,
659
+ mode,
660
+ });
938
661
  if (mode === 'stream') {
939
662
  const out = buildUiEventShape({
940
663
  pressPath: info.path,
@@ -971,12 +694,59 @@ function useTouchManager(cfg, log) {
971
694
  registerPress,
972
695
  };
973
696
  }
974
- function AnalyticsProvider({ children, log, config, }) {
697
+ function TouchCapture({ children, cfg, mgr, }) {
698
+ var _a, _b;
699
+ const last = getDtLastTouch();
700
+ const onStart = React.useCallback((e) => {
701
+ var _a, _b;
702
+ last.ts = Date.now();
703
+ last.x = Number((_a = e === null || e === void 0 ? void 0 : e.nativeEvent) === null || _a === void 0 ? void 0 : _a.pageX) || 0;
704
+ last.y = Number((_b = e === null || e === void 0 ? void 0 : e.nativeEvent) === null || _b === void 0 ? void 0 : _b.pageY) || 0;
705
+ return mgr === null || mgr === void 0 ? void 0 : mgr.onStart(e);
706
+ }, [mgr]);
707
+ const onMove = React.useCallback((e) => mgr === null || mgr === void 0 ? void 0 : mgr.onMove(e), [mgr]);
708
+ const onEnd = React.useCallback((e) => {
709
+ return mgr === null || mgr === void 0 ? void 0 : mgr.onEnd(e, 'end');
710
+ }, [mgr]);
711
+ const onCancel = React.useCallback((e) => {
712
+ return mgr === null || mgr === void 0 ? void 0 : mgr.onEnd(e, 'cancel');
713
+ }, [mgr]);
714
+ if (!ConfigurationHandler_1.ConfigurationHandler.isUserInteractionEnabled() ||
715
+ !((_a = cfg.touch) === null || _a === void 0 ? void 0 : _a.enabled) ||
716
+ !mgr) {
717
+ uiDebugLog('TouchCapture bypassed', {
718
+ uiEnabled: ConfigurationHandler_1.ConfigurationHandler.isUserInteractionEnabled(),
719
+ touchEnabled: !!((_b = cfg.touch) === null || _b === void 0 ? void 0 : _b.enabled),
720
+ hasManager: !!mgr,
721
+ });
722
+ return React.createElement(React.Fragment, null, children);
723
+ }
724
+ return (React.createElement(react_native_1.View, { pointerEvents: "box-none", collapsable: false, style: { flex: 1 }, onTouchStart: onStart, onTouchMove: onMove, onTouchEnd: onEnd, onTouchCancel: onCancel, onResponderRelease: onEnd, onResponderTerminate: onCancel }, children));
725
+ }
726
+ function AnalyticsRoot({ name = 'App', label, log, prefix, config, children, }) {
727
+ var _a, _b, _c, _d, _e;
975
728
  const cfg = (0, react_1.useMemo)(() => config !== null && config !== void 0 ? config : {}, [config]);
729
+ const fileConfiguredUiEnabled = ((_a = cfg === null || cfg === void 0 ? void 0 : cfg.touch) === null || _a === void 0 ? void 0 : _a.enabled) === true;
976
730
  const baseLogger = log || ((e) => logger.debug('[DT UI]' + JSON.stringify(e)));
731
+ React.useEffect(() => {
732
+ ConfigurationHandler_1.ConfigurationHandler.setUserInteractionEnabledLastKnownGood(fileConfiguredUiEnabled);
733
+ uiDebugLog('AnalyticsRoot initialized fallback from config', {
734
+ fileConfiguredUiEnabled,
735
+ userInteractionEnabled: ConfigurationHandler_1.ConfigurationHandler.isUserInteractionEnabled(),
736
+ });
737
+ }, [fileConfiguredUiEnabled]);
977
738
  const emit = React.useCallback((e) => {
978
- var _a, _b, _c;
979
- if (!ConfigurationHandler_1.ConfigurationHandler.isUserInteractionEnabled()) {
739
+ var _a, _b, _c, _d;
740
+ const uiEnabled = ConfigurationHandler_1.ConfigurationHandler.isUserInteractionEnabled();
741
+ if (!uiEnabled) {
742
+ const isInitiated = RuntimeConfigurationObserver_1.RuntimeConfigurationObserver.isInitiated();
743
+ const remoteCfg = isInitiated
744
+ ? RuntimeConfigurationObserver_1.RuntimeConfigurationObserver.getCurrentRuntimeConfiguration()
745
+ : undefined;
746
+ uiDebugLog('emit skipped: user interaction disabled', {
747
+ isRuntimeConfigInitiated: isInitiated,
748
+ remoteValue: remoteCfg === null || remoteCfg === void 0 ? void 0 : remoteCfg.touch_interaction_enabled,
749
+ });
980
750
  return;
981
751
  }
982
752
  const phase = ((_b = (_a = e === null || e === void 0 ? void 0 : e.ui_element) === null || _a === void 0 ? void 0 : _a.meta) === null || _b === void 0 ? void 0 : _b.phase) || '';
@@ -987,11 +757,20 @@ function AnalyticsProvider({ children, log, config, }) {
987
757
  id &&
988
758
  id === LAST_PRESS_ID &&
989
759
  now - LAST_PRESS_TS < 300) {
760
+ uiDebugLog('emit skipped: touch dedup after press', {
761
+ id,
762
+ deltaMs: now - LAST_PRESS_TS,
763
+ });
990
764
  return;
991
765
  }
992
766
  const key = id && phase ? id + '|' + phase : '';
993
- if (key && key === LAST_EMIT_KEY && now - LAST_EMIT_TS < 10)
767
+ if (key && key === LAST_EMIT_KEY && now - LAST_EMIT_TS < 10) {
768
+ uiDebugLog('emit skipped: duplicate key window', {
769
+ key,
770
+ deltaMs: now - LAST_EMIT_TS,
771
+ });
994
772
  return;
773
+ }
995
774
  LAST_EMIT_KEY = key;
996
775
  LAST_EMIT_TS = now;
997
776
  if (phase === 'press' && id) {
@@ -1002,493 +781,47 @@ function AnalyticsProvider({ children, log, config, }) {
1002
781
  const produceEvent = _an_flat(e);
1003
782
  const event = Object.assign(Object.assign({}, produceEvent), eventTimestamp.getEventTimeInfo());
1004
783
  EventPipeline_1.EventPipeline.insertEvent(event);
784
+ uiDebugLog('emit inserted event', {
785
+ phase,
786
+ id,
787
+ hasResponder: !!((_d = e === null || e === void 0 ? void 0 : e.ui_element) === null || _d === void 0 ? void 0 : _d.responder),
788
+ });
1005
789
  return baseLogger(produceEvent);
1006
790
  }, [baseLogger]);
1007
791
  const touch = useTouchManager(cfg, emit);
1008
792
  React.useEffect(() => {
793
+ var _a, _b, _c;
1009
794
  const g = globalThis;
1010
795
  g.__DT_UII_BRIDGE = {
1011
796
  registerPress: touch.registerPress,
1012
797
  getStartPath: touch.getStartPath,
1013
798
  };
799
+ uiDebugLog('AnalyticsRoot mounted: bridge registered', {
800
+ touchEnabled: !!((_a = cfg.touch) === null || _a === void 0 ? void 0 : _a.enabled),
801
+ mode: (_c = (_b = cfg.touch) === null || _b === void 0 ? void 0 : _b.mode) !== null && _c !== void 0 ? _c : 'grouped',
802
+ });
1014
803
  return () => {
1015
- if (g.__DT_UII_BRIDGE &&
1016
- g.__DT_UII_BRIDGE.registerPress === touch.registerPress) {
804
+ var _a;
805
+ if (((_a = g.__DT_UII_BRIDGE) === null || _a === void 0 ? void 0 : _a.registerPress) === touch.registerPress) {
1017
806
  delete g.__DT_UII_BRIDGE;
807
+ uiDebugLog('AnalyticsRoot unmounted: bridge removed');
1018
808
  }
1019
809
  };
1020
- }, [touch]);
1021
- return (React.createElement(exports.CfgCtx.Provider, { value: cfg },
1022
- React.createElement(LogCtx.Provider, { value: emit },
1023
- React.createElement(TouchCtx.Provider, { value: touch },
1024
- React.createElement(NodeCtx.Provider, { value: null },
1025
- React.createElement(SiblingCtx.Provider, { value: makePreIndexedRegistry(children) }, children))))));
1026
- }
1027
- exports.AnalyticsProvider = AnalyticsProvider;
1028
- function TouchCapture({ children }) {
1029
- var _a;
1030
- const cfg = (0, react_1.useContext)(exports.CfgCtx);
1031
- const mgr = (0, react_1.useContext)(TouchCtx);
1032
- const last = getDtLastTouch();
1033
- const onStart = React.useCallback((e) => {
1034
- var _a, _b;
1035
- last.ts = Date.now();
1036
- last.x = Number((_a = e === null || e === void 0 ? void 0 : e.nativeEvent) === null || _a === void 0 ? void 0 : _a.pageX) || 0;
1037
- last.y = Number((_b = e === null || e === void 0 ? void 0 : e.nativeEvent) === null || _b === void 0 ? void 0 : _b.pageY) || 0;
1038
- const targetObj = e === null || e === void 0 ? void 0 : e.target;
1039
- if (isExpoRuntime() && isNativeTextInputViewTarget(targetObj)) {
1040
- return;
1041
- }
1042
- return mgr === null || mgr === void 0 ? void 0 : mgr.onStart(e);
1043
- }, [mgr]);
1044
- const onMove = React.useCallback((e) => mgr === null || mgr === void 0 ? void 0 : mgr.onMove(e), [mgr]);
1045
- const onEnd = React.useCallback((e) => {
1046
- const targetObj = e === null || e === void 0 ? void 0 : e.target;
1047
- if (isExpoRuntime() && isNativeTextInputViewTarget(targetObj)) {
1048
- return;
1049
- }
1050
- return mgr === null || mgr === void 0 ? void 0 : mgr.onEnd(e, 'end');
1051
- }, [mgr]);
1052
- const onCancel = React.useCallback((e) => {
1053
- return mgr === null || mgr === void 0 ? void 0 : mgr.onEnd(e, 'cancel');
1054
- }, [mgr]);
1055
- if (!ConfigurationHandler_1.ConfigurationHandler.isUserInteractionEnabled() ||
1056
- !((_a = cfg.touch) === null || _a === void 0 ? void 0 : _a.enabled) ||
1057
- !mgr)
1058
- return React.createElement(React.Fragment, null, children);
1059
- return (React.createElement(react_native_1.View, { pointerEvents: "box-none", collapsable: false, style: { flex: 1 }, onTouchStart: onStart, onTouchMove: onMove, onTouchEnd: onEnd, onTouchCancel: onCancel, onResponderRelease: onEnd, onResponderTerminate: onCancel }, children));
1060
- }
1061
- function Segment({ name, label, children, }) {
1062
- var _a;
1063
- const parent = (0, react_1.useContext)(NodeCtx);
1064
- const cfg = (0, react_1.useContext)(exports.CfgCtx);
1065
- const rolesMap = (_a = cfg.path) === null || _a === void 0 ? void 0 : _a.roleMap;
1066
- const heur = cfg.roleHeuristics === undefined
1067
- ? DEFAULT_ROLE_HEURISTICS
1068
- : cfg.roleHeuristics || false;
1069
- const parentReg = (0, react_1.useContext)(SiblingCtx);
1070
- const only = react_1.Children.only(children);
1071
- const myRole = classifyRole(name, rolesMap, heur);
1072
- const node = (0, react_1.useMemo)(() => ({
1073
- name,
1074
- label,
1075
- role: myRole,
1076
- parent: parent !== null && parent !== void 0 ? parent : null,
1077
- }), [name, label, myRole, parent]);
1078
- if (!(0, react_1.isValidElement)(only)) {
1079
- return (React.createElement(NodeCtx.Provider, { value: node },
1080
- React.createElement(SiblingCtx.Provider, { value: makePreIndexedRegistry(null) }, children)));
1081
- }
1082
- return (React.createElement(SegmentWithElement, { name: name, label: label, only: only, parent: parent, cfg: cfg, rolesMap: rolesMap, heur: heur, parentReg: parentReg }));
1083
- }
1084
- exports.Segment = Segment;
1085
- function buildSegmentInteractionState(params) {
1086
- var _a;
1087
- const { childProps, childTypeName, name, parent, myRole, cfg, only, log, mgr, node, canAttachRef, } = params;
1088
- const identity = resolveSegmentIdentity({
1089
- childProps,
1090
- childTypeName,
1091
- name,
1092
- });
1093
- const masking = resolveSegmentMasking({
1094
- leaf: identity.leaf,
1095
- childProps,
1096
- childTypeName,
1097
- name,
1098
- myRole,
1099
- cfg,
1100
- only,
1101
- elementId: identity.elementId,
1102
- nameOrigin: identity.nameOrigin,
1103
- });
1104
- const nextProps = Object.assign({}, childProps);
1105
- const isInnerTextOfTouchable = applyInnerTextPointerEvents({
1106
- nextProps,
1107
- childTypeName,
1108
- parent,
1109
- });
1110
- const useTouchLink = !!(((_a = cfg.touch) === null || _a === void 0 ? void 0 : _a.enabled) && mgr && canAttachRef);
1111
- applyTextInputFocusHandler({
1112
- nextProps,
1113
- childProps,
1114
- childTypeName,
1115
- log,
1116
- cfg,
1117
- node,
1118
- leafTailStatic: masking.leafTailStatic,
1119
- elementIdOut: masking.elementIdOut,
1120
- needMask: masking.needMask,
1121
- nameOrigin: masking.nameOrigin,
1122
- });
1123
- applyAutoPressInHandler({
1124
- nextProps,
1125
- childProps,
1126
- childTypeName,
1127
- name,
1128
- useTouchLink,
1129
- isInnerTextOfTouchable,
1130
- node,
1131
- cfg,
1132
- leafTailStatic: masking.leafTailStatic,
1133
- elementIdOut: masking.elementIdOut,
1134
- mgr,
1135
- });
1136
- wireSegmentEventHandlers({
1137
- nextProps,
1138
- childProps,
1139
- childTypeName,
1140
- useTouchLink,
1141
- node,
1142
- cfg,
1143
- leafTailStatic: masking.leafTailStatic,
1144
- elementIdOut: masking.elementIdOut,
1145
- nameOrigin: masking.nameOrigin,
1146
- mgr,
1147
- log,
1148
- });
1149
- return {
1150
- nextProps,
1151
- needMask: masking.needMask,
1152
- elementIdOut: masking.elementIdOut,
1153
- nameOrigin: masking.nameOrigin,
1154
- leafTailStatic: masking.leafTailStatic,
1155
- isInnerTextOfTouchable,
1156
- };
1157
- }
1158
- function resolveSegmentIdentity(params) {
1159
- const { childProps, childTypeName, name } = params;
1160
- const leaf = collectLeafInfo(childProps === null || childProps === void 0 ? void 0 : childProps.children) || null;
1161
- const childLabel = typeof (childProps === null || childProps === void 0 ? void 0 : childProps.children) === 'string'
1162
- ? childProps.children.trim()
1163
- : '';
1164
- let elementId = childTypeName;
1165
- let nameOrigin = 'component';
1166
- if (childTypeName === 'TextInput' &&
1167
- typeof (childProps === null || childProps === void 0 ? void 0 : childProps.placeholder) === 'string' &&
1168
- childProps.placeholder.trim()) {
1169
- elementId = childProps.placeholder.trim();
1170
- }
1171
- else if (typeof (childProps === null || childProps === void 0 ? void 0 : childProps.accessibilityLabel) === 'string') {
1172
- elementId = childProps.accessibilityLabel.trim();
1173
- }
1174
- else if (typeof (childProps === null || childProps === void 0 ? void 0 : childProps.testID) === 'string') {
1175
- elementId = childProps.testID.trim();
1176
- }
1177
- else if (leaf && leaf.source === 'text' && leaf.label) {
1178
- elementId = leaf.label.trim();
1179
- nameOrigin = 'text';
1180
- }
1181
- else if (childLabel.length > 0) {
1182
- elementId = childLabel;
1183
- nameOrigin = 'text';
1184
- }
1185
- if (childTypeName === 'Button' && typeof (childProps === null || childProps === void 0 ? void 0 : childProps.title) === 'string') {
1186
- const title = childProps.title.trim();
1187
- if (title) {
1188
- elementId = title;
1189
- nameOrigin = 'text';
1190
- }
1191
- }
1192
- if (elementId === 'Anonymous') {
1193
- elementId = name;
1194
- nameOrigin = 'component';
1195
- }
1196
- if (childTypeName === 'Text' && elementId.trim()) {
1197
- nameOrigin = 'text';
1198
- }
1199
- return { leaf, elementId, nameOrigin };
1200
- }
1201
- function resolveSegmentMasking(params) {
1202
- var _a, _b, _c;
1203
- const { leaf, childProps, childTypeName, name, myRole, cfg, only, elementId, nameOrigin, } = params;
1204
- const hasSelfA11y = typeof (childProps === null || childProps === void 0 ? void 0 : childProps.accessibilityLabel) === 'string' ||
1205
- typeof (childProps === null || childProps === void 0 ? void 0 : childProps.testID) === 'string';
1206
- const segIsTouchable = exports.FORCED_TOUCHABLES.has(name) || exports.FORCED_TOUCHABLES.has(childTypeName);
1207
- const shouldAppendLeafTail = !!(leaf &&
1208
- leaf.source === 'text' &&
1209
- !hasSelfA11y &&
1210
- !segIsTouchable);
1211
- const needMask = shouldMaskLeaf(leaf, only, myRole, cfg);
1212
- const nextNameOrigin = needMask ? 'masked' : nameOrigin;
1213
- const maskedText = needMask
1214
- ? maskLabel((_a = leaf === null || leaf === void 0 ? void 0 : leaf.label) !== null && _a !== void 0 ? _a : elementId, cfg)
1215
- : undefined;
1216
- const elementIdOut = needMask ? maskedText : elementId;
1217
- const sep = (_c = (_b = cfg === null || cfg === void 0 ? void 0 : cfg.path) === null || _b === void 0 ? void 0 : _b.separator) !== null && _c !== void 0 ? _c : '->';
1218
- const leafTailStatic = shouldAppendLeafTail
1219
- ? `${sep}${(leaf === null || leaf === void 0 ? void 0 : leaf.type) || 'Text'}`
1220
- : '';
1221
- return {
1222
- needMask,
1223
- nameOrigin: nextNameOrigin,
1224
- elementIdOut,
1225
- leafTailStatic,
1226
- };
1227
- }
1228
- function applyInnerTextPointerEvents(params) {
1229
- const { nextProps, childTypeName, parent } = params;
1230
- const parentSegName = parent === null || parent === void 0 ? void 0 : parent.name;
1231
- const isInnerTextOfTouchable = childTypeName === 'Text' &&
1232
- !!parentSegName &&
1233
- exports.FORCED_TOUCHABLES.has(parentSegName);
1234
- if (isInnerTextOfTouchable && nextProps.pointerEvents == null) {
1235
- nextProps.pointerEvents = 'none';
1236
- }
1237
- return isInnerTextOfTouchable;
1238
- }
1239
- function applyTextInputFocusHandler(params) {
1240
- const { nextProps, childProps, childTypeName, log, cfg, node, leafTailStatic, elementIdOut, needMask, nameOrigin, } = params;
1241
- if (childTypeName !== 'TextInput')
1242
- return;
1243
- const emit = log !== null && log !== void 0 ? log : ((e) => console.log('[DT UI]', e));
1244
- const origOnFocus = childProps.onFocus;
1245
- nextProps.onFocus = (...args) => {
1246
- var _a;
1247
- const t0 = Date.now();
1248
- const lastTouch = getDtLastTouch();
1249
- try {
1250
- if (((_a = cfg.touch) === null || _a === void 0 ? void 0 : _a.enabled) && isExpoRuntime()) {
1251
- const baseNow = toPathString(node, cfg.path);
1252
- const pathOut = `${baseNow}${leafTailStatic}`;
1253
- const linked = t0 - (lastTouch.ts || 0) < 800;
1254
- const pos = linked
1255
- ? {
1256
- x: Number(lastTouch.x) || 0,
1257
- y: Number(lastTouch.y) || 0,
1258
- }
1259
- : undefined;
1260
- const out = buildUiEventShape({
1261
- touchPath: pathOut,
1262
- touchElementName: elementIdOut,
1263
- touchMasked: !!needMask,
1264
- meta: { phase: 'touch', ts: t0 },
1265
- pos: pos ? { x: pos.x, y: pos.y } : undefined,
1266
- reason: linked ? 'focus-linked' : 'focus',
1267
- name_origin: nameOrigin,
1268
- });
1269
- emit(compactify(cfg, out));
1270
- }
1271
- }
1272
- catch (e) {
1273
- const errorMsg = e instanceof Error ? e.stack || e.message : String(e);
1274
- logger.debug(`TextInput focus instrumentation failed: ${errorMsg}`);
1275
- }
1276
- if (typeof origOnFocus === 'function')
1277
- return origOnFocus(...args);
1278
- };
1279
- }
1280
- function hasAnyPressKey(props) {
1281
- for (const key in props) {
1282
- if (PRESS_KEYS.has(key))
1283
- return true;
1284
- }
1285
- return false;
1286
- }
1287
- function applyAutoPressInHandler(params) {
1288
- const { nextProps, childProps, childTypeName, name, useTouchLink, isInnerTextOfTouchable, node, cfg, leafTailStatic, elementIdOut, mgr, } = params;
1289
- const canAutoAddPress = useTouchLink &&
1290
- !isInnerTextOfTouchable &&
1291
- (exports.FORCED_TOUCHABLES.has(childTypeName) || exports.FORCED_TOUCHABLES.has(name));
1292
- if (!canAutoAddPress || hasAnyPressKey(childProps))
1293
- return;
1294
- nextProps.onPressIn = (...args) => {
810
+ }, [touch, (_b = cfg.touch) === null || _b === void 0 ? void 0 : _b.enabled, (_c = cfg.touch) === null || _c === void 0 ? void 0 : _c.mode]);
811
+ const pref = Array.isArray(prefix) ? prefix : readGlobalPrefix();
812
+ const scopePath = React.useMemo(() => {
1295
813
  var _a, _b;
1296
- const baseNow = toPathString(node, cfg.path);
1297
- const pathOut = `${baseNow}${leafTailStatic}`;
1298
- const position = extractPosition(args, (_b = (_a = cfg === null || cfg === void 0 ? void 0 : cfg.click) === null || _a === void 0 ? void 0 : _a.capturePosition) !== null && _b !== void 0 ? _b : 'none');
1299
- const info = {
1300
- path: pathOut,
1301
- elementName: elementIdOut,
1302
- };
1303
- if (position)
1304
- info.pos = { x: position.x, y: position.y };
1305
- mgr.registerPress(info);
1306
- };
1307
- }
1308
- function wireSegmentEventHandlers(params) {
1309
- const { nextProps, childProps, childTypeName, useTouchLink, node, cfg, leafTailStatic, elementIdOut, nameOrigin, mgr, log, } = params;
1310
- for (const k in childProps) {
1311
- const orig = childProps[k];
1312
- const isTextInputEvent = childTypeName === 'TextInput' && TEXTINPUT_KEYS.has(k);
1313
- if (!PRESS_KEYS.has(k) && !isTextInputEvent)
1314
- continue;
1315
- if (isTextInputEvent && k === 'onFocus')
1316
- continue;
1317
- nextProps[k] = (...args) => {
1318
- var _a, _b, _c, _d;
1319
- const baseNow = toPathString(node, cfg.path);
1320
- const pathOut = `${baseNow}${leafTailStatic}`;
1321
- const now = Date.now();
1322
- if (isTextInputEvent || !useTouchLink) {
1323
- const emit = log !== null && log !== void 0 ? log : ((e) => console.log('[DT UI]', e));
1324
- const position = k === 'onChangeText'
1325
- ? undefined
1326
- : extractPosition(args, (_b = (_a = cfg === null || cfg === void 0 ? void 0 : cfg.click) === null || _a === void 0 ? void 0 : _a.capturePosition) !== null && _b !== void 0 ? _b : 'none');
1327
- const out = buildUiEventShape({
1328
- pressPath: pathOut,
1329
- pressElementName: elementIdOut,
1330
- meta: { phase: normPhase(k), ts: now },
1331
- pos: position
1332
- ? { x: position.x, y: position.y }
1333
- : undefined,
1334
- name_origin: nameOrigin,
1335
- });
1336
- try {
1337
- emit(compactify(cfg, out));
1338
- }
1339
- catch (e) {
1340
- const errorMsg = e instanceof Error ? e.stack || e.message : String(e);
1341
- logger.debug(`Segment event emission failed for ${String(k)}: ${errorMsg}`);
1342
- }
1343
- if (typeof orig === 'function')
1344
- return orig(...args);
1345
- return;
1346
- }
1347
- if (k === 'onPress' ||
1348
- k === 'onLongPress' ||
1349
- k === 'onTap' ||
1350
- k === 'onClick') {
1351
- const position = extractPosition(args, (_d = (_c = cfg === null || cfg === void 0 ? void 0 : cfg.click) === null || _c === void 0 ? void 0 : _c.capturePosition) !== null && _d !== void 0 ? _d : 'none');
1352
- const info = {
1353
- path: pathOut,
1354
- elementName: elementIdOut,
1355
- };
1356
- if (position)
1357
- info.pos = { x: position.x, y: position.y };
1358
- mgr.registerPress(info);
1359
- }
1360
- if (typeof orig === 'function')
1361
- return orig(...args);
1362
- };
1363
- }
1364
- }
1365
- function SegmentWithElement({ name, label, only, parent, cfg, rolesMap, heur, parentReg, }) {
1366
- var _a;
1367
- const childType = only.type;
1368
- const childProps = only.props;
1369
- const canAttachRef = supportsRefType(childType);
1370
- const childTypeName = typeof childType === 'string'
1371
- ? childType
1372
- : childType
1373
- .displayName ||
1374
- childType.name ||
1375
- 'Anonymous';
1376
- const myNameForSiblingIndex = childTypeName;
1377
- const rawKey = (_a = only.key) !== null && _a !== void 0 ? _a : null;
1378
- const myKeyForSiblingIndex = String(rawKey !== null && rawKey !== void 0 ? rawKey : '__pos:unknown');
1379
- const myIdx = (0, react_1.useMemo)(() => parentReg
1380
- ? parentReg.getIndex(myNameForSiblingIndex, myKeyForSiblingIndex)
1381
- : 1, [parentReg, myNameForSiblingIndex, myKeyForSiblingIndex]);
1382
- const mySid = rawKey === null || rawKey === undefined
1383
- ? `pos:${myNameForSiblingIndex}:${myIdx}`
1384
- : String(rawKey);
1385
- const myRole = classifyRole(name, rolesMap, heur);
1386
- const node = (0, react_1.useMemo)(() => ({
1387
- name,
1388
- label,
1389
- role: myRole,
1390
- idx: myIdx,
1391
- sid: mySid,
1392
- parent: parent !== null && parent !== void 0 ? parent : null,
1393
- }), [name, label, myRole, myIdx, mySid, parent]);
1394
- const log = (0, react_1.useContext)(LogCtx);
1395
- const mgr = (0, react_1.useContext)(TouchCtx);
1396
- const { nextProps, needMask, elementIdOut, nameOrigin, leafTailStatic, isInnerTextOfTouchable, } = buildSegmentInteractionState({
1397
- childProps,
1398
- childTypeName,
1399
- name,
1400
- parent,
1401
- myRole,
1402
- cfg,
1403
- only,
1404
- log,
1405
- mgr,
1406
- node,
1407
- canAttachRef,
1408
- });
1409
- const childRegistry = (0, react_1.useMemo)(() => makePreIndexedRegistry(childProps === null || childProps === void 0 ? void 0 : childProps.children), [childProps === null || childProps === void 0 ? void 0 : childProps.children]);
1410
- const baseNow = toPathString(node, cfg.path);
1411
- React.useEffect(() => {
1412
- if (myRole === 'nav') {
1413
- __dt_set_scope_path(baseNow);
1414
- }
1415
- }, [myRole, baseNow]);
1416
- const pathOut = `${baseNow}${leafTailStatic}`;
1417
- const refAnchor = React.useRef(null);
814
+ const names = [
815
+ ...pref
816
+ .map((p) => p === null || p === void 0 ? void 0 : p.name)
817
+ .filter((n) => typeof n === 'string' && n.length > 0),
818
+ name,
819
+ ];
820
+ return names.join((_b = (_a = config === null || config === void 0 ? void 0 : config.path) === null || _a === void 0 ? void 0 : _a.separator) !== null && _b !== void 0 ? _b : '/');
821
+ }, [pref, name, (_d = config === null || config === void 0 ? void 0 : config.path) === null || _d === void 0 ? void 0 : _d.separator]);
1418
822
  React.useEffect(() => {
1419
- if (!canAttachRef)
1420
- return;
1421
- const h = (0, react_native_1.findNodeHandle)(refAnchor.current);
1422
- if (!h)
1423
- return;
1424
- if (!isInnerTextOfTouchable) {
1425
- registerHandle(h, {
1426
- path: pathOut,
1427
- element: elementIdOut,
1428
- isMasked: needMask || undefined,
1429
- name_origin: nameOrigin,
1430
- });
1431
- }
1432
- return () => {
1433
- if (!isInnerTextOfTouchable)
1434
- registerHandle(h, null);
1435
- };
1436
- }, [
1437
- canAttachRef,
1438
- pathOut,
1439
- elementIdOut,
1440
- needMask,
1441
- isInnerTextOfTouchable,
1442
- nameOrigin,
1443
- ]);
1444
- let extraRefProps = {};
1445
- if (canAttachRef) {
1446
- extraRefProps =
1447
- typeof childType === 'string'
1448
- ? { ref: refAnchor, collapsable: false }
1449
- : { ref: refAnchor };
1450
- }
1451
- const cloned = (0, react_1.cloneElement)(only, Object.assign(Object.assign({}, nextProps), extraRefProps));
1452
- return (React.createElement(NodeCtx.Provider, { value: node },
1453
- React.createElement(SiblingCtx.Provider, { value: childRegistry }, cloned)));
1454
- }
1455
- function PathPrefix({ names, children, }) {
1456
- var _a;
1457
- const base = (0, react_1.useContext)(NodeCtx);
1458
- const cfg = (0, react_1.useContext)(exports.CfgCtx);
1459
- const tail = (0, react_1.useMemo)(() => {
1460
- var _a;
1461
- let cur = base !== null && base !== void 0 ? base : null;
1462
- for (const n of names) {
1463
- cur = {
1464
- name: n.name,
1465
- label: n.label,
1466
- role: classifyRole(n.name, (_a = cfg.path) === null || _a === void 0 ? void 0 : _a.roleMap, cfg.roleHeuristics),
1467
- idx: undefined,
1468
- sid: undefined,
1469
- parent: cur,
1470
- };
1471
- }
1472
- return cur;
1473
- }, [base, names, (_a = cfg.path) === null || _a === void 0 ? void 0 : _a.roleMap, cfg.roleHeuristics]);
1474
- const childRegistry = (0, react_1.useMemo)(() => makePreIndexedRegistry(children), [children]);
1475
- return (React.createElement(NodeCtx.Provider, { value: tail },
1476
- React.createElement(SiblingCtx.Provider, { value: childRegistry }, children)));
1477
- }
1478
- exports.PathPrefix = PathPrefix;
1479
- function AnalyticsRoot({ name = 'App', label, log, prefix, config, children, }) {
1480
- var _a;
1481
- const content = (React.createElement(Segment, { name: name, label: label }, children));
1482
- const pref = Array.isArray(prefix) ? prefix : readGlobalPrefix();
1483
- const inner = pref.length ? (React.createElement(PathPrefix, { names: pref }, content)) : (content);
1484
- return (React.createElement(AnalyticsProvider, { log: log, config: config }, ((_a = config === null || config === void 0 ? void 0 : config.touch) === null || _a === void 0 ? void 0 : _a.enabled) ? (React.createElement(TouchCapture, null, inner)) : (inner)));
823
+ __dt_set_scope_path(scopePath);
824
+ }, [scopePath]);
825
+ return ((_e = cfg === null || cfg === void 0 ? void 0 : cfg.touch) === null || _e === void 0 ? void 0 : _e.enabled) ? (React.createElement(TouchCapture, { cfg: cfg, mgr: touch }, children)) : (React.createElement(React.Fragment, null, children));
1485
826
  }
1486
827
  exports.AnalyticsRoot = AnalyticsRoot;
1487
- exports.LabelClaimScope = Object.assign(({ children, mask }) => {
1488
- return (0, react_1.cloneElement)(react_1.Children.only(children), { mask });
1489
- }, { __AN_LABEL_SCOPE: true });
1490
- exports.TabButton = React.forwardRef(function TabButton(props, ref) {
1491
- const { children, style, testID, accessibilityLabel, onPress, onLongPress, onPressIn, onPressOut, } = props;
1492
- return (React.createElement(Segment, { name: "TabButton" },
1493
- React.createElement(react_native_1.Pressable, { ref: ref, style: style, testID: testID, accessibilityLabel: accessibilityLabel, onPress: onPress, onLongPress: onLongPress, onPressIn: onPressIn, onPressOut: onPressOut }, children)));
1494
- });