react-native-acoustic-connect-beta 19.0.19 → 19.0.21

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.
@@ -55,14 +55,77 @@ declare class TLTRN {
55
55
  * Passing no delay used to send a hardcoded `0`, which made
56
56
  * `CaptureLayoutDelay` inert for React Native apps and fired the capture at
57
57
  * the *start* of the transition rather than after it.
58
+ *
59
+ * @returns With no `delayMs` — the normal case — only that the capture was
60
+ * **scheduled**, not that it produced a layout message. The native
61
+ * deferred overload dispatches and returns immediately, so anything that
62
+ * goes wrong once it runs (no view controller resolved, layout capture
63
+ * gated off by config) cannot be reflected here; those surface in logcat
64
+ * / os_log instead. Pass `0` and the value describes the capture itself,
65
+ * at the cost of capturing mid-transition.
58
66
  */
59
67
  static logScreenLayout: (name: string | undefined, delayMs?: number) => boolean;
60
68
  static logClickEvent: (event: any) => Promise<boolean>;
61
69
  static logTextChangeEvent: (target: number, controlId: string, text: string, _ariaLabel: string) => Promise<boolean>;
70
+ /**
71
+ * Keys already warned about, so a call site inside a render or a list loop
72
+ * warns once rather than on every pass.
73
+ */
74
+ static warnedNestedValueSites: Set<string>;
75
+ /**
76
+ * Cap on {@link warnedNestedValueSites}.
77
+ *
78
+ * The site key includes the nested keys' names, so a payload built from an
79
+ * API response — per-record ids, timestamps — makes every call a distinct
80
+ * site, and the set would then grow for the life of the session. By the
81
+ * hundredth distinct shape the warning has made its point, so it stops
82
+ * instead of accumulating: bounded memory matters more than warning about
83
+ * shape 101.
84
+ */
85
+ static WARNED_NESTED_VALUE_SITES_MAX: number;
86
+ /**
87
+ * Warns when a flat-values payload carries a nested object or array.
88
+ *
89
+ * `logCustomEvent`/`logDialogCustomEvent` are typed for flat scalars, but
90
+ * TypeScript types are erased at runtime: a payload built from an API
91
+ * response, widened through `any`, or passed from untyped JS reaches the
92
+ * bridge with its nesting intact. Both platforms then reshape it silently —
93
+ * Android's SDK chain is typed `HashMap<String, String>` end to end, so a
94
+ * nested value is stringified into whatever its `toString()` yields — and
95
+ * the call still returns `true`. `logSignal` is the API that carries nested
96
+ * JSON on both platforms.
97
+ *
98
+ * Warning only: the payload is passed through untouched, so this changes no
99
+ * behaviour and cannot break a caller who is relying on today's reshaping.
100
+ *
101
+ * @param api Name of the calling API, for the message.
102
+ * @param values The payload about to cross the bridge.
103
+ */
104
+ static warnOnNestedValues: (api: string, values: Record<string, unknown>) => void;
105
+ /**
106
+ * Logs a custom event.
107
+ *
108
+ * @param eventName Event name, as it appears in the posted JSON.
109
+ * @param values Flat key/value pairs. Nested objects and arrays are NOT
110
+ * supported here and are reshaped by the native SDKs — use `logSignal`
111
+ * for nested JSON.
112
+ * @param level Monitoring level for this event.
113
+ * @returns Whether the native SDK **accepted the event for delivery** —
114
+ * not whether the collector received it. The event is queued locally and
115
+ * posted later, so no return value from this call can attest to delivery;
116
+ * a `true` here means only that the SDK took the event. A `false` is also
117
+ * logged natively (logcat / os_log) so the rejection is visible.
118
+ */
62
119
  static logCustomEvent: (eventName: string, values: Record<string, string | number | boolean>, level: number) => Promise<boolean>;
63
120
  static logDialogShowEvent: (dialogId: string, dialogTitle: string, dialogType: string) => Promise<boolean>;
64
121
  static logDialogDismissEvent: (dialogId: string, dismissReason: string) => Promise<boolean>;
65
122
  static logDialogButtonClickEvent: (dialogId: string, buttonText: string, buttonIndex: number) => Promise<boolean>;
123
+ /**
124
+ * Logs a custom event tied to a dialog.
125
+ *
126
+ * Same flat-values contract and same return-value meaning as
127
+ * {@link logCustomEvent} — it routes to the same native API.
128
+ */
66
129
  static logDialogCustomEvent: (dialogId: string, eventName: string, values: Record<string, string | number | boolean>) => Promise<boolean>;
67
130
  static eventListenerRegistered: boolean;
68
131
  static eventListenerUnsubscribe: (() => void) | null;
@@ -1 +1 @@
1
- {"version":3,"file":"TLTRN.d.ts","sourceRoot":"","sources":["../../../src/TLTRN.ts"],"names":[],"mappings":"AAAA;;;;;;;;6FAQ6F;;AAmC7F,cAAM,KAAK;IACT,MAAM,CAAC,aAAa,SACgD;IACpE,MAAM,CAAC,uBAAuB,SAAK;IACnC,MAAM,CAAC,eAAe,SAAK;IAC3B,MAAM,CAAC,iBAAiB,SAAK;IAC7B,MAAM,CAAC,SAAS,SAAK;IACrB,MAAM,CAAC,cAAc,SAAK;IAC1B,MAAM,CAAC,kBAAkB,SAAK;IAC9B,MAAM,CAAC,aAAa,SAAK;IACzB,MAAM,CAAC,YAAY,UAAS;IAE5B,MAAM,CAAC,OAAO;;;;QAIZ;;WAEG;;QAKH;;WAEG;;MAQH;IAEF,MAAM,CAAC,IAAI,yBAA0B,MAAM,4BAA4B,OAAO,UAQ5E;IAEF,MAAM,CAAC,uBAAuB,WAAY,OAAO,UAE/C;IAEF,MAAM,CAAC,qBAAqB,SAAU,MAAM,GAAG,SAAS,aAQtD;IAEF,MAAM,CAAC,wBAAwB,SAAU,MAAM,YAAY,MAAM,aAQ/D;IAEF;;;;;OAKG;IACH,MAAM,CAAC,4BAA4B,SAAM;IAEzC;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,eAAe,SAAU,MAAM,GAAG,SAAS,YAAY,MAAM,aAYlE;IAEF,MAAM,CAAC,aAAa,UAAiB,GAAG,sBA+BtC;IAEF,MAAM,CAAC,kBAAkB,WAAkB,MAAM,aAAa,MAAM,QAAQ,MAAM,cAAc,MAAM,sBAYpG;IAEF,MAAM,CAAC,cAAc,cAAqB,MAAM,UAAU,OAAO,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,SAAS,MAAM,sBAQhH;IAGF,MAAM,CAAC,kBAAkB,aAAoB,MAAM,eAAe,MAAM,cAAc,MAAM,sBAQ1F;IAEF,MAAM,CAAC,qBAAqB,aAAoB,MAAM,iBAAiB,MAAM,sBAQ3E;IAEF,MAAM,CAAC,yBAAyB,aAAoB,MAAM,cAAc,MAAM,eAAe,MAAM,sBAQjG;IAEF,MAAM,CAAC,oBAAoB,aAAoB,MAAM,aAAa,MAAM,UAAU,OAAO,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,sBAQzH;IAGF,MAAM,CAAC,uBAAuB,UAAS;IACvC,MAAM,CAAC,wBAAwB,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAQ;IAE5D,MAAM,CAAC,qBAAqB,WAAY,OAAO,UA0B7C;IAEF,MAAM,CAAC,cAAc,YAAa,GAAG,UAqEnC;IAEF,MAAM,CAAC,SAAS,aA6Bd;IAEF,MAAM,CAAC,OAAO,sBAyBZ;CACH;AAGD,eAAe,KAAK,CAAC"}
1
+ {"version":3,"file":"TLTRN.d.ts","sourceRoot":"","sources":["../../../src/TLTRN.ts"],"names":[],"mappings":"AAAA;;;;;;;;6FAQ6F;;AAmC7F,cAAM,KAAK;IACT,MAAM,CAAC,aAAa,SACgD;IACpE,MAAM,CAAC,uBAAuB,SAAK;IACnC,MAAM,CAAC,eAAe,SAAK;IAC3B,MAAM,CAAC,iBAAiB,SAAK;IAC7B,MAAM,CAAC,SAAS,SAAK;IACrB,MAAM,CAAC,cAAc,SAAK;IAC1B,MAAM,CAAC,kBAAkB,SAAK;IAC9B,MAAM,CAAC,aAAa,SAAK;IACzB,MAAM,CAAC,YAAY,UAAS;IAE5B,MAAM,CAAC,OAAO;;;;QAIZ;;WAEG;;QAKH;;WAEG;;MAQH;IAEF,MAAM,CAAC,IAAI,yBAA0B,MAAM,4BAA4B,OAAO,UAQ5E;IAEF,MAAM,CAAC,uBAAuB,WAAY,OAAO,UAE/C;IAEF,MAAM,CAAC,qBAAqB,SAAU,MAAM,GAAG,SAAS,aAQtD;IAEF,MAAM,CAAC,wBAAwB,SAAU,MAAM,YAAY,MAAM,aAQ/D;IAEF;;;;;OAKG;IACH,MAAM,CAAC,4BAA4B,SAAM;IAEzC;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,MAAM,CAAC,eAAe,SAAU,MAAM,GAAG,SAAS,YAAY,MAAM,aAYlE;IAEF,MAAM,CAAC,aAAa,UAAiB,GAAG,sBA+BtC;IAEF,MAAM,CAAC,kBAAkB,WAAkB,MAAM,aAAa,MAAM,QAAQ,MAAM,cAAc,MAAM,sBAYpG;IAEF;;;OAGG;IACH,MAAM,CAAC,sBAAsB,cAAqB;IAElD;;;;;;;;;OASG;IACH,MAAM,CAAC,6BAA6B,SAAO;IAE3C;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,CAAC,kBAAkB,QAAS,MAAM,UAAU,OAAO,MAAM,EAAE,OAAO,CAAC,UAyBvE;IAEF;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,cAAc,cAAqB,MAAM,UAAU,OAAO,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,SAAS,MAAM,sBAShH;IAGF,MAAM,CAAC,kBAAkB,aAAoB,MAAM,eAAe,MAAM,cAAc,MAAM,sBAQ1F;IAEF,MAAM,CAAC,qBAAqB,aAAoB,MAAM,iBAAiB,MAAM,sBAQ3E;IAEF,MAAM,CAAC,yBAAyB,aAAoB,MAAM,cAAc,MAAM,eAAe,MAAM,sBAQjG;IAEF;;;;;OAKG;IACH,MAAM,CAAC,oBAAoB,aAAoB,MAAM,aAAa,MAAM,UAAU,OAAO,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,sBASzH;IAGF,MAAM,CAAC,uBAAuB,UAAS;IACvC,MAAM,CAAC,wBAAwB,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAQ;IAE5D,MAAM,CAAC,qBAAqB,WAAY,OAAO,UA0B7C;IAEF,MAAM,CAAC,cAAc,YAAa,GAAG,UAqEnC;IAEF,MAAM,CAAC,SAAS,aA6Bd;IAEF,MAAM,CAAC,OAAO,sBAyBZ;CACH;AAGD,eAAe,KAAK,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Connect.d.ts","sourceRoot":"","sources":["../../../../src/components/Connect.tsx"],"names":[],"mappings":"AAAA;;;;;;;;6FAQ6F;AAC7F,OAAO,KAAmD,MAAM,OAAO,CAAC;AAKxE,UAAU,YAAY;IAClB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;CACxC;AAED,QAAA,MAAM,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CA0KnC,CAAC;AAWF,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"Connect.d.ts","sourceRoot":"","sources":["../../../../src/components/Connect.tsx"],"names":[],"mappings":"AAAA;;;;;;;;6FAQ6F;AAC7F,OAAO,KAAmD,MAAM,OAAO,CAAC;AAKxE,UAAU,YAAY;IAClB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;CACxC;AAED,QAAA,MAAM,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CA6KnC,CAAC;AAuHF,eAAe,OAAO,CAAC"}
@@ -147,7 +147,12 @@ export interface AcousticConnectRN extends HybridObject<{
147
147
  * @param eventName Event name; appears in the posted JSON.
148
148
  * @param values Flat key/value pairs to attach to the event.
149
149
  * @param level Monitoring level for this event.
150
- * @returns `true` if the event was queued.
150
+ * @returns `true` if the SDK **accepted the event for delivery** — not
151
+ * that the collector received it. Events are queued on device and posted
152
+ * in batches later, so nothing this call can return attests to delivery
153
+ * or to server-side acceptance. A `false` means the SDK rejected the
154
+ * event outright and nothing was queued; the bridge also logs that to
155
+ * logcat / os_log so it is visible without inspecting the return value.
151
156
  */
152
157
  logCustomEvent(eventName: string, values: Record<string, string | number | boolean>, level: number): boolean;
153
158
  /**
@@ -166,7 +171,12 @@ export interface AcousticConnectRN extends HybridObject<{
166
171
  * @param values Signal payload. Objects, arrays, strings, numbers,
167
172
  * booleans and `null` are all carried through.
168
173
  * @param level Monitoring level for this signal.
169
- * @returns `true` if the signal was queued.
174
+ * @returns `true` if the SDK **accepted the signal for delivery** — not
175
+ * that the collector received it, and not that it passed server-side
176
+ * schema validation. Signals are queued on device and posted later, so
177
+ * nothing this call can return attests to delivery. A `false` means the
178
+ * SDK rejected it and nothing was queued; the bridge logs that to
179
+ * logcat / os_log.
170
180
  *
171
181
  * @remarks
172
182
  * **Android limitation — top-level numbers.** The Android SDK's
@@ -177,7 +187,8 @@ export interface AcousticConnectRN extends HybridObject<{
177
187
  * `JSONObject`/`JSONArray` values itself. iOS carries top-level numbers
178
188
  * normally. Send numbers inside a nested object when cross-platform
179
189
  * parity matters. This is a pre-existing SDK-side gap, not a
180
- * restriction of this bridge.
190
+ * restriction of this bridge — the Android bridge now names the affected
191
+ * keys in a logcat warning so the loss is not silent.
181
192
  *
182
193
  * @example Nested payload
183
194
  * ```ts
@@ -218,6 +229,14 @@ export interface AcousticConnectRN extends HybridObject<{
218
229
  * screen"; `0` captures immediately.
219
230
  *
220
231
  * Prefer `TLTRN.logScreenLayout`, which defaults to the configured delay.
232
+ *
233
+ * @returns For a `delay` of `0`, whether the capture itself succeeded. For
234
+ * any positive or configured delay, only that the capture was
235
+ * **scheduled** — the native deferred overload dispatches and returns
236
+ * immediately, so a `true` says nothing about what the capture found
237
+ * when it eventually ran. Failures after that point (no view controller
238
+ * resolved, config gating the capture off) surface in logcat / os_log,
239
+ * not here.
221
240
  */
222
241
  logScreenLayout(name: string, delay: number): boolean;
223
242
  logDialogShowEvent(dialogId: string, dialogTitle: string, dialogType: string): boolean;
@@ -300,6 +319,14 @@ export interface AcousticConnectRN extends HybridObject<{
300
319
  * { registrationMethod: 'email' }
301
320
  * )
302
321
  * ```
322
+ *
323
+ * @returns `true` if the SDK **accepted the identity signal for
324
+ * delivery**. It does not mean the signal reached the collector, and it
325
+ * does not mean the collector kept it — a schema-invalid signal (the
326
+ * wrong method key above) is discarded server-side after resolving
327
+ * `true` here. Never rejects. A `false` means the SDK rejected the call
328
+ * locally, e.g. a blank identifier; the bridge logs that to logcat /
329
+ * os_log.
303
330
  */
304
331
  logIdentity(identifierName: string, identifierValue: string, signalType?: string, additionalParameters?: Record<string, string>): Promise<boolean>;
305
332
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"react-native-acoustic-connect.nitro.d.ts","sourceRoot":"","sources":["../../../../src/specs/react-native-acoustic-connect.nitro.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"react-native-acoustic-connect.nitro.d.ts","sourceRoot":"","sources":["../../../../src/specs/react-native-acoustic-connect.nitro.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -92,12 +92,15 @@
92
92
  "plugin/swift",
93
93
  "plugin/src",
94
94
  "cli",
95
+ "!cli/__tests__/**",
95
96
  "ConnectConfig.example.json",
96
97
  "*.podspec",
97
98
  "README.md",
98
99
  "CHANGELOG.md",
99
100
  "scripts",
100
101
  "Examples/SampleUI/**/*",
102
+ "!Examples/SampleUI/**/__tests__/**",
103
+ "!Examples/SampleUI/**/*.test.*",
101
104
  "!Examples/SampleUI/node_modules/**",
102
105
  "!Examples/SampleUI/temp/**",
103
106
  "!Examples/SampleUI/logs/**",
@@ -230,7 +233,7 @@
230
233
  "source": "src/index",
231
234
  "summary": "react-native ios android tealeaf connect cxa wxca er enhanced-replay",
232
235
  "types": "./lib/typescript/src/index.d.ts",
233
- "version": "19.0.19",
236
+ "version": "19.0.21",
234
237
  "workspaces": [
235
238
  "example",
236
239
  "Examples/bare-workflow"
package/src/TLTRN.ts CHANGED
@@ -131,6 +131,14 @@ class TLTRN {
131
131
  * Passing no delay used to send a hardcoded `0`, which made
132
132
  * `CaptureLayoutDelay` inert for React Native apps and fired the capture at
133
133
  * the *start* of the transition rather than after it.
134
+ *
135
+ * @returns With no `delayMs` — the normal case — only that the capture was
136
+ * **scheduled**, not that it produced a layout message. The native
137
+ * deferred overload dispatches and returns immediately, so anything that
138
+ * goes wrong once it runs (no view controller resolved, layout capture
139
+ * gated off by config) cannot be reflected here; those surface in logcat
140
+ * / os_log instead. Pass `0` and the value describes the capture itself,
141
+ * at the cost of capturing mid-transition.
134
142
  */
135
143
  static logScreenLayout = (name: string | undefined, delayMs?: number) => {
136
144
  TLTRN.currentScreen = name || '';
@@ -193,8 +201,86 @@ class TLTRN {
193
201
  return result;
194
202
  };
195
203
 
204
+ /**
205
+ * Keys already warned about, so a call site inside a render or a list loop
206
+ * warns once rather than on every pass.
207
+ */
208
+ static warnedNestedValueSites = new Set<string>();
209
+
210
+ /**
211
+ * Cap on {@link warnedNestedValueSites}.
212
+ *
213
+ * The site key includes the nested keys' names, so a payload built from an
214
+ * API response — per-record ids, timestamps — makes every call a distinct
215
+ * site, and the set would then grow for the life of the session. By the
216
+ * hundredth distinct shape the warning has made its point, so it stops
217
+ * instead of accumulating: bounded memory matters more than warning about
218
+ * shape 101.
219
+ */
220
+ static WARNED_NESTED_VALUE_SITES_MAX = 100;
221
+
222
+ /**
223
+ * Warns when a flat-values payload carries a nested object or array.
224
+ *
225
+ * `logCustomEvent`/`logDialogCustomEvent` are typed for flat scalars, but
226
+ * TypeScript types are erased at runtime: a payload built from an API
227
+ * response, widened through `any`, or passed from untyped JS reaches the
228
+ * bridge with its nesting intact. Both platforms then reshape it silently —
229
+ * Android's SDK chain is typed `HashMap<String, String>` end to end, so a
230
+ * nested value is stringified into whatever its `toString()` yields — and
231
+ * the call still returns `true`. `logSignal` is the API that carries nested
232
+ * JSON on both platforms.
233
+ *
234
+ * Warning only: the payload is passed through untouched, so this changes no
235
+ * behaviour and cannot break a caller who is relying on today's reshaping.
236
+ *
237
+ * @param api Name of the calling API, for the message.
238
+ * @param values The payload about to cross the bridge.
239
+ */
240
+ static warnOnNestedValues = (api: string, values: Record<string, unknown>) => {
241
+ if (values == null || typeof values !== 'object') {
242
+ return;
243
+ }
244
+ const nested = Object.keys(values).filter((key) => {
245
+ const value = (values as Record<string, unknown>)[key];
246
+ return typeof value === 'object' && value !== null;
247
+ });
248
+ if (nested.length === 0) {
249
+ return;
250
+ }
251
+ const site = `${api}:${nested.sort().join(',')}`;
252
+ if (TLTRN.warnedNestedValueSites.has(site)) {
253
+ return;
254
+ }
255
+ if (TLTRN.warnedNestedValueSites.size >= TLTRN.WARNED_NESTED_VALUE_SITES_MAX) {
256
+ return;
257
+ }
258
+ TLTRN.warnedNestedValueSites.add(site);
259
+ console.warn(
260
+ `TLTRN.${api}: nested value(s) [${nested.sort().join(', ')}] will be flattened — ` +
261
+ `${api} carries flat scalars only, and the native SDKs reshape anything else ` +
262
+ `without reporting it. Use logSignal for nested JSON; it is carried intact on ` +
263
+ `both platforms.`
264
+ );
265
+ };
266
+
267
+ /**
268
+ * Logs a custom event.
269
+ *
270
+ * @param eventName Event name, as it appears in the posted JSON.
271
+ * @param values Flat key/value pairs. Nested objects and arrays are NOT
272
+ * supported here and are reshaped by the native SDKs — use `logSignal`
273
+ * for nested JSON.
274
+ * @param level Monitoring level for this event.
275
+ * @returns Whether the native SDK **accepted the event for delivery** —
276
+ * not whether the collector received it. The event is queued locally and
277
+ * posted later, so no return value from this call can attest to delivery;
278
+ * a `true` here means only that the SDK took the event. A `false` is also
279
+ * logged natively (logcat / os_log) so the rejection is visible.
280
+ */
196
281
  static logCustomEvent = async (eventName: string, values: Record<string, string | number | boolean>, level: number) => {
197
282
  let result = false
283
+ TLTRN.warnOnNestedValues('logCustomEvent', values);
198
284
  try {
199
285
  result = AcousticConnectRN.logCustomEvent(eventName, values, level);
200
286
  } catch (error: Error | any) {
@@ -234,8 +320,15 @@ class TLTRN {
234
320
  return result;
235
321
  };
236
322
 
323
+ /**
324
+ * Logs a custom event tied to a dialog.
325
+ *
326
+ * Same flat-values contract and same return-value meaning as
327
+ * {@link logCustomEvent} — it routes to the same native API.
328
+ */
237
329
  static logDialogCustomEvent = async (dialogId: string, eventName: string, values: Record<string, string | number | boolean>) => {
238
330
  let result = false
331
+ TLTRN.warnOnNestedValues('logDialogCustomEvent', values);
239
332
  try {
240
333
  result = AcousticConnectRN.logDialogCustomEvent(dialogId, eventName, values);
241
334
  } catch (error: Error | any) {
@@ -131,7 +131,11 @@ const Connect: React.FC<ConnectProps> = ({
131
131
 
132
132
  // Listen for the 'state' event to track navigation state changes
133
133
  const unsubscribeState = navigation.current.addListener("state", () => {
134
- currentRoute.current = extractName(navigation) || navigation.current.getCurrentRoute()?.name;
134
+ // extractName resolves the focused route through the nested
135
+ // navigators itself, so there is no outer-level fallback to chain
136
+ // here — one used to be appended, which reported the tab name for
137
+ // every push inside that tab.
138
+ currentRoute.current = extractName(navigation);
135
139
 
136
140
  // Both platforms take the same path. iOS used to be excluded from
137
141
  // the layout call, which left the wrapper with no layout trigger
@@ -158,12 +162,9 @@ const Connect: React.FC<ConnectProps> = ({
158
162
  }, [navReady, navigation]);
159
163
 
160
164
  const onStartShouldSetResponderCapture = useCallback((event: any) => {
161
- if (navigation?.current?.getCurrentRoute) {
162
- currentRoute.current =
163
- extractName(navigation) || navigation.current.getCurrentRoute()?.name;
164
- if (currentRoute.current) {
165
- TLTRN.logScreenViewPageName(currentRoute.current);
166
- }
165
+ currentRoute.current = extractName(navigation);
166
+ if (currentRoute.current) {
167
+ TLTRN.logScreenViewPageName(currentRoute.current);
167
168
  }
168
169
  TLTRN.logClickEvent(event);
169
170
  return false; // Must remain false so events bubble to the host app's handlers
@@ -175,16 +176,18 @@ const Connect: React.FC<ConnectProps> = ({
175
176
  }
176
177
  initial.current = true;
177
178
 
178
- if (navigation?.current?.getCurrentRoute) {
179
- currentRoute.current = navigation.current.getCurrentRoute()?.name;
180
- // Same unification as the 'state' listener above: the split sent
181
- // only a screenview on iOS and only a layout on Android, so
182
- // neither platform got both from the first-paint trigger. No delay
183
- // argument, for the reason given there.
184
- if (currentRoute.current) {
185
- TLTRN.logScreenViewPageName(currentRoute.current);
186
- TLTRN.logScreenLayout(currentRoute.current);
187
- }
179
+ // Resolved through extractName like the other two triggers. This site
180
+ // used to read `getCurrentRoute()?.name` directly, so a `params.name`
181
+ // override was honoured on navigation but silently ignored for the
182
+ // first-paint screen the same screen reported under two names.
183
+ currentRoute.current = extractName(navigation);
184
+ // Same unification as the 'state' listener above: the split sent
185
+ // only a screenview on iOS and only a layout on Android, so
186
+ // neither platform got both from the first-paint trigger. No delay
187
+ // argument, for the reason given there.
188
+ if (currentRoute.current) {
189
+ TLTRN.logScreenViewPageName(currentRoute.current);
190
+ TLTRN.logScreenLayout(currentRoute.current);
188
191
  }
189
192
  return true;
190
193
  }, [navigation]);
@@ -202,13 +205,121 @@ const Connect: React.FC<ConnectProps> = ({
202
205
  );
203
206
  };
204
207
 
208
+ /**
209
+ * Walks a React Navigation state down to the deepest **focused** route.
210
+ *
211
+ * Nested navigators are the default architecture of production RN apps: a tab
212
+ * navigator whose tabs each hold a stack. The container's root state then
213
+ * describes only the outer level, and the route that the user is actually
214
+ * looking at lives in `routes[index].state`, recursively. Reading the outer
215
+ * level alone reports the *tab* name for every push inside that tab, so screen
216
+ * changes below the first level are invisible to analytics and replay.
217
+ *
218
+ * `index` can legitimately be absent on a partial/rehydrated state, in which
219
+ * case React Navigation treats the last route as focused — matched here.
220
+ *
221
+ * A depth cap guards against a malformed state whose nesting cycles; 32 is far
222
+ * past any real navigator tree.
223
+ */
224
+ function findFocusedRoute(state: any): any {
225
+ let current = state;
226
+ let depth = 0;
227
+ while (current?.routes?.length && depth++ < 32) {
228
+ const index = current.index ?? current.routes.length - 1;
229
+ const route = current.routes[index];
230
+ if (!route?.state?.routes?.length) {
231
+ return route;
232
+ }
233
+ current = route.state;
234
+ }
235
+ return undefined;
236
+ }
237
+
238
+ /**
239
+ * Containers already reported by {@link warnExtractNameFailed}.
240
+ *
241
+ * Keyed by the container itself, so a ref that throws on every navigation
242
+ * produces one line rather than one per transition, while a genuinely
243
+ * different container still gets its own. A `WeakSet` holds no strong
244
+ * reference, so remembering a container cannot keep it alive.
245
+ */
246
+ const extractNameErrorReported = new WeakSet<object>();
247
+
248
+ /**
249
+ * Reports, once per container, that resolving the current route threw.
250
+ *
251
+ * A throw here is expected and harmless during teardown, which is why
252
+ * ``extractName`` swallows it. A ref that keeps throwing is a different
253
+ * matter: every screen view goes unnamed, and without a line here that looks
254
+ * exactly like a ref that never attached. One warning separates the two
255
+ * without flooding a listener that fires per navigation.
256
+ */
257
+ function warnExtractNameFailed(container: unknown, error: unknown) {
258
+ if (typeof container === "object" && container !== null) {
259
+ if (extractNameErrorReported.has(container)) {
260
+ return;
261
+ }
262
+ extractNameErrorReported.add(container);
263
+ }
264
+ console.warn(
265
+ "Connect: could not resolve the current route — the navigation container ref threw. " +
266
+ "Screen views stay unnamed while this persists (harmless if the container is unmounting). " +
267
+ "Cause:",
268
+ error
269
+ );
270
+ }
271
+
272
+ /**
273
+ * The screen name to report for the navigation container's current position.
274
+ *
275
+ * Resolution order:
276
+ *
277
+ * 1. The focused route resolved from `getRootState()` by ``findFocusedRoute``.
278
+ * Taking the state and walking it here — rather than trusting a single
279
+ * accessor — keeps the wrapper correct regardless of whether the host app's
280
+ * navigation library resolves nesting inside `getCurrentRoute()`, and works
281
+ * for a custom container ref that exposes state but not that helper.
282
+ * 2. `getCurrentRoute()`, for refs that expose no `getRootState`.
283
+ *
284
+ * Either way `params.name` wins over the route's own `name` when the host app
285
+ * supplies it — the documented override for giving a route a human-readable
286
+ * analytics name. Only a non-empty string counts, so `params: { name: '' }`
287
+ * falls through to the route name instead of blanking the screenview.
288
+ *
289
+ * Returns `""` when nothing resolves, which both callers treat as "skip".
290
+ */
205
291
  function extractName(navigation: any): string {
206
- const routeParams = navigation?.current?.getCurrentRoute?.()?.params;
207
- if (routeParams) {
208
- const { name } = routeParams;
209
- return name ? name : navigation.current?.getCurrentRoute()?.name || "";
292
+ const container = navigation?.current;
293
+ if (!container) {
294
+ return "";
295
+ }
296
+
297
+ let route: any;
298
+ try {
299
+ route = findFocusedRoute(container.getRootState?.());
300
+ } catch (error) {
301
+ // A container mid-teardown can throw out of getRootState(). Screen
302
+ // naming is not worth taking the host app's navigation down for.
303
+ warnExtractNameFailed(container, error);
304
+ route = undefined;
305
+ }
306
+ if (!route) {
307
+ try {
308
+ route = container.getCurrentRoute?.();
309
+ } catch (error) {
310
+ warnExtractNameFailed(container, error);
311
+ route = undefined;
312
+ }
313
+ }
314
+ if (!route) {
315
+ return "";
316
+ }
317
+
318
+ const overridden = route.params?.name;
319
+ if (typeof overridden === "string" && overridden.length > 0) {
320
+ return overridden;
210
321
  }
211
- return "";
322
+ return typeof route.name === "string" ? route.name : "";
212
323
  }
213
324
 
214
325
  export default Connect;
@@ -164,7 +164,12 @@ export interface AcousticConnectRN extends HybridObject<{ ios: 'swift', android:
164
164
  * @param eventName Event name; appears in the posted JSON.
165
165
  * @param values Flat key/value pairs to attach to the event.
166
166
  * @param level Monitoring level for this event.
167
- * @returns `true` if the event was queued.
167
+ * @returns `true` if the SDK **accepted the event for delivery** — not
168
+ * that the collector received it. Events are queued on device and posted
169
+ * in batches later, so nothing this call can return attests to delivery
170
+ * or to server-side acceptance. A `false` means the SDK rejected the
171
+ * event outright and nothing was queued; the bridge also logs that to
172
+ * logcat / os_log so it is visible without inspecting the return value.
168
173
  */
169
174
  logCustomEvent(eventName: string, values: Record<string, string | number | boolean>, level: number): boolean
170
175
 
@@ -184,7 +189,12 @@ export interface AcousticConnectRN extends HybridObject<{ ios: 'swift', android:
184
189
  * @param values Signal payload. Objects, arrays, strings, numbers,
185
190
  * booleans and `null` are all carried through.
186
191
  * @param level Monitoring level for this signal.
187
- * @returns `true` if the signal was queued.
192
+ * @returns `true` if the SDK **accepted the signal for delivery** — not
193
+ * that the collector received it, and not that it passed server-side
194
+ * schema validation. Signals are queued on device and posted later, so
195
+ * nothing this call can return attests to delivery. A `false` means the
196
+ * SDK rejected it and nothing was queued; the bridge logs that to
197
+ * logcat / os_log.
188
198
  *
189
199
  * @remarks
190
200
  * **Android limitation — top-level numbers.** The Android SDK's
@@ -195,7 +205,8 @@ export interface AcousticConnectRN extends HybridObject<{ ios: 'swift', android:
195
205
  * `JSONObject`/`JSONArray` values itself. iOS carries top-level numbers
196
206
  * normally. Send numbers inside a nested object when cross-platform
197
207
  * parity matters. This is a pre-existing SDK-side gap, not a
198
- * restriction of this bridge.
208
+ * restriction of this bridge — the Android bridge now names the affected
209
+ * keys in a logcat warning so the loss is not silent.
199
210
  *
200
211
  * @example Nested payload
201
212
  * ```ts
@@ -236,6 +247,14 @@ export interface AcousticConnectRN extends HybridObject<{ ios: 'swift', android:
236
247
  * screen"; `0` captures immediately.
237
248
  *
238
249
  * Prefer `TLTRN.logScreenLayout`, which defaults to the configured delay.
250
+ *
251
+ * @returns For a `delay` of `0`, whether the capture itself succeeded. For
252
+ * any positive or configured delay, only that the capture was
253
+ * **scheduled** — the native deferred overload dispatches and returns
254
+ * immediately, so a `true` says nothing about what the capture found
255
+ * when it eventually ran. Failures after that point (no view controller
256
+ * resolved, config gating the capture off) surface in logcat / os_log,
257
+ * not here.
239
258
  */
240
259
  logScreenLayout(name: string, delay: number): boolean
241
260
  // New dialog event handling methods
@@ -320,6 +339,14 @@ export interface AcousticConnectRN extends HybridObject<{ ios: 'swift', android:
320
339
  * { registrationMethod: 'email' }
321
340
  * )
322
341
  * ```
342
+ *
343
+ * @returns `true` if the SDK **accepted the identity signal for
344
+ * delivery**. It does not mean the signal reached the collector, and it
345
+ * does not mean the collector kept it — a schema-invalid signal (the
346
+ * wrong method key above) is discarded server-side after resolving
347
+ * `true` here. Never rejects. A `false` means the SDK rejected the call
348
+ * locally, e.g. a blank identifier; the bridge logs that to logcat /
349
+ * os_log.
323
350
  */
324
351
  logIdentity(
325
352
  identifierName: string,
@@ -1,17 +0,0 @@
1
- /**
2
- * @format
3
- */
4
-
5
- import 'react-native';
6
- import React from 'react';
7
- import App from '../App';
8
-
9
- // Note: import explicitly to use the types shipped with jest.
10
- import {it} from '@jest/globals';
11
-
12
- // Note: test renderer must be required after react-native.
13
- import renderer from 'react-test-renderer';
14
-
15
- it('renders correctly', () => {
16
- renderer.create(<App />);
17
- });