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.
- package/CHANGELOG.md +10 -0
- package/README.md +93 -0
- package/android/src/main/assets/ConnectBasicConfig.properties +1 -1
- package/android/src/main/java/com/acousticconnectrn/HybridAcousticConnectRN.kt +144 -13
- package/ios/HybridAcousticConnectRN.swift +36 -2
- package/lib/commonjs/TLTRN.js +90 -0
- package/lib/commonjs/TLTRN.js.map +1 -1
- package/lib/commonjs/components/Connect.js +128 -23
- package/lib/commonjs/components/Connect.js.map +1 -1
- package/lib/module/TLTRN.js +90 -0
- package/lib/module/TLTRN.js.map +1 -1
- package/lib/module/components/Connect.js +128 -23
- package/lib/module/components/Connect.js.map +1 -1
- package/lib/typescript/src/TLTRN.d.ts +63 -0
- package/lib/typescript/src/TLTRN.d.ts.map +1 -1
- package/lib/typescript/src/components/Connect.d.ts.map +1 -1
- package/lib/typescript/src/specs/react-native-acoustic-connect.nitro.d.ts +30 -3
- package/lib/typescript/src/specs/react-native-acoustic-connect.nitro.d.ts.map +1 -1
- package/package.json +4 -1
- package/src/TLTRN.ts +93 -0
- package/src/components/Connect.tsx +133 -22
- package/src/specs/react-native-acoustic-connect.nitro.ts +30 -3
- package/Examples/SampleUI/__tests__/App.test.tsx +0 -17
- package/Examples/SampleUI/src/styles/__tests__/fonts.test.js +0 -290
- package/cli/__tests__/doctor.test.mjs +0 -88
|
@@ -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
|
|
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,
|
|
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
|
|
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
|
|
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":"AAYA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAG3E,MAAM,MAAM,cAAc,GAAG;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAA;AAEjC,MAAM,MAAM,0BAA0B,GAAG,QAAQ,GAAG,iBAAiB,GAAG,MAAM,CAAA;AAE9E;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC1B,oEAAoE;IACpE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,gFAAgF;IAChF,OAAO,EAAE,MAAM,CAAA;CAClB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,oBAAoB;IACjC,gEAAgE;IAChE,OAAO,EAAE,OAAO,CAAA;IAChB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACxB;AAED,MAAM,WAAW,iBAAkB,SAAQ,YAAY,CAAC;IAAE,GAAG,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,QAAQ,CAAA;CAAE,CAAC;IACxF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAwCG;IACH,MAAM,IAAI,OAAO,CAAA;IAEjB;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,IAAI,OAAO,CAAA;IAClB,0BAA0B,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAA;IACpF,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAA;IAC5E,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAA;IAC5E,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAA;IAC/F,0BAA0B,CAAC,UAAU,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAA;IACzF,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAI,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;IACpG,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAAA;IAChF
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
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
|
|
207
|
-
if (
|
|
208
|
-
|
|
209
|
-
|
|
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
|
|
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
|
|
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
|
-
});
|