@mixpanel/react-native-session-replay 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/MixpanelReactNativeSessionReplay.podspec +1 -1
  2. package/README.md +1 -1
  3. package/android/build.gradle +10 -3
  4. package/android/src/main/java/com/mixpanelreactnativesessionreplay/MixpanelReactNativeSessionReplayModule.kt +54 -0
  5. package/android/src/main/java/com/mixpanelreactnativesessionreplay/MixpanelSessionReplayView.kt +56 -0
  6. package/android/src/main/java/com/mixpanelreactnativesessionreplay/MixpanelSessionReplayViewManager.kt +5 -0
  7. package/android/src/test/java/com/mixpanelreactnativesessionreplay/WireframeTextDeclarationTest.kt +41 -0
  8. package/ios/MixpanelReactNativeSessionReplay.h +7 -2
  9. package/ios/MixpanelReactNativeSessionReplay.mm +35 -2
  10. package/ios/MixpanelSessionReplayViewManager.mm +9 -0
  11. package/ios/MixpanelSwiftSessionReplay.swift +43 -1
  12. package/lib/module/MixpanelSessionReplayView.js.map +1 -1
  13. package/lib/module/NativeMixpanelReactNativeSessionReplay.js.map +1 -1
  14. package/lib/module/index.js +468 -23
  15. package/lib/module/index.js.map +1 -1
  16. package/lib/typescript/src/MixpanelSessionReplayView.d.ts +32 -0
  17. package/lib/typescript/src/MixpanelSessionReplayView.d.ts.map +1 -1
  18. package/lib/typescript/src/NativeMixpanelReactNativeSessionReplay.d.ts +2 -0
  19. package/lib/typescript/src/NativeMixpanelReactNativeSessionReplay.d.ts.map +1 -1
  20. package/lib/typescript/src/index.d.ts +259 -10
  21. package/lib/typescript/src/index.d.ts.map +1 -1
  22. package/package.json +1 -1
  23. package/src/MixpanelSessionReplayView.tsx +33 -0
  24. package/src/NativeMixpanelReactNativeSessionReplay.ts +7 -0
  25. package/src/index.tsx +515 -22
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
- import { Platform, processColor } from 'react-native';
3
+ import { NativeEventEmitter, Platform, processColor } from 'react-native';
4
4
  import MixpanelReactNativeSessionReplay from "./NativeMixpanelReactNativeSessionReplay.js";
5
5
  export let MPSessionReplayMask = /*#__PURE__*/function (MPSessionReplayMask) {
6
6
  MPSessionReplayMask["Text"] = "text";
@@ -32,6 +32,73 @@ export const MPDataResidency = {
32
32
  IN: 'https://api-in.mixpanel.com'
33
33
  };
34
34
 
35
+ /**
36
+ * Why a wireframe element's text was kept, rewritten, or dropped.
37
+ *
38
+ * Reported through {@link MPDebugOptions.wireframeEmitter} for local inspection only.
39
+ * These are the same `SCREAMING_SNAKE_CASE` tokens Android, iOS and Flutter report, so
40
+ * the same decision reads identically on every platform.
41
+ *
42
+ * ⚠️ **Not a stable contract.** Values may be added or renamed; treat an unrecognized
43
+ * one as "some kind of masking" rather than matching exhaustively. That is also why
44
+ * {@link MPWireframeElement.maskDecision} is typed `string` rather than a closed union —
45
+ * a new native value should not become a type error.
46
+ */
47
+ export const MPMaskDecision = {
48
+ /** Text emitted as-is. */
49
+ None: 'NONE',
50
+ /** Text you declared with the `wireframeText` prop. Sent even when masked. */
51
+ Declared: 'DECLARED',
52
+ /** Explicitly masked — `<MPSessionReplayView sensitive>` or a registered class. */
53
+ Explicit: 'EXPLICIT',
54
+ /** Auto-masked by an `autoMaskedViews` category. */
55
+ Auto: 'AUTO',
56
+ /** A text-entry field. Always masked, cannot be overridden. */
57
+ TextEntry: 'TEXT_ENTRY',
58
+ /** Bounds intersected a mask rect the screenshot painted over. */
59
+ Geometric: 'GEOMETRIC',
60
+ /** Matched a strip rule; text was dropped. */
61
+ RuleStrip: 'RULE_STRIP',
62
+ /** Matched a redact rule; text was rewritten. */
63
+ RuleRedact: 'RULE_REDACT'
64
+ };
65
+
66
+ /** One element of a captured wireframe. See {@link MPWireframeSnapshot}. */
67
+
68
+ /**
69
+ * One captured wireframe, exactly as the SDK built it.
70
+ *
71
+ * ⚠️ **Not a stable contract** — a debugging aid, not a schema to build tooling on.
72
+ */
73
+
74
+ /**
75
+ * Native event carrying one wireframe snapshot as JSON.
76
+ *
77
+ * The payload crosses as a *string* rather than a structured map on purpose: both SDKs
78
+ * already own a `toJson()` for their debug snapshot, so forwarding it verbatim keeps the
79
+ * bridge from becoming a third place where the shape can drift.
80
+ */
81
+ const WIREFRAME_EVENT = 'MixpanelSessionReplayWireframe';
82
+ let wireframeEventEmitter = null;
83
+
84
+ // The one live subscription, owned by `initialize`. Replaced on every initialize so a
85
+ // re-init cannot leave the previous config's callback attached.
86
+ let wireframeSubscription = null;
87
+
88
+ // Which `initialize` call the live subscription belongs to. Bumped on every attach, so a
89
+ // call that fails can tell whether the subscription still in place is its own — see
90
+ // `attachWireframeEmitter`.
91
+ let wireframeGeneration = 0;
92
+ function getWireframeEventEmitter() {
93
+ if (wireframeEventEmitter === null) {
94
+ // Constructed lazily: importing this module must not create an emitter for an app
95
+ // that never listens. The module is passed on both platforms because a TurboModule
96
+ // has to supply `addListener`/`removeListeners` itself.
97
+ wireframeEventEmitter = new NativeEventEmitter(MixpanelReactNativeSessionReplay);
98
+ }
99
+ return wireframeEventEmitter;
100
+ }
101
+
35
102
  /**
36
103
  * Color configuration for the on-device debug mask overlay.
37
104
  *
@@ -40,8 +107,8 @@ export const MPDataResidency = {
40
107
  * Setting any of `maskColor`, `autoMaskColor`, or `unmaskColor` to `null` hides that
41
108
  * category from the overlay.
42
109
  *
43
- * The overlay only renders when `__DEV__` is `true` — `debugOptions` is ignored in
44
- * production bundles regardless of what is passed.
110
+ * The overlay only renders in a debuggable build. That is enforced by the native SDKs
111
+ * themselves, so it is safe to leave `overlayColors` set unconditionally.
45
112
  */
46
113
  export class MPDebugOverlayColors {
47
114
  /**
@@ -92,9 +159,10 @@ export class MPDebugOverlayColors {
92
159
  * `overlayColors` to `null` to disable the overlay while keeping `MPDebugOptions`
93
160
  * available for future debug features.
94
161
  *
95
- * Debug features only render when `__DEV__` is `true`. In production bundles
96
- * (`__DEV__ === false`), `debugOptions` is dropped before reaching the native SDK so
97
- * the overlay never ships to end users.
162
+ * `debugOptions` reaches the native SDK in every bundle, exactly as it would if you
163
+ * configured it natively. Each feature decides for itself what a release build may do:
164
+ * the overlay is restricted to debuggable builds by the native SDKs, while
165
+ * {@link MPDebugOptions.wireframeEmitter} runs wherever you configure it.
98
166
  */
99
167
  export class MPDebugOptions {
100
168
  /**
@@ -103,10 +171,47 @@ export class MPDebugOptions {
103
171
  * - **Default:** `new MPDebugOverlayColors()` (overlay enabled with default colors)
104
172
  */
105
173
 
174
+ /**
175
+ * Hands each captured wireframe back to JavaScript as it is captured, so you can check
176
+ * what you are sending while you develop.
177
+ *
178
+ * You get exactly the elements that go to Mixpanel, plus the reason each one's text was
179
+ * kept or removed. Nothing delivered here leaves the device.
180
+ *
181
+ * This *observes* wireframe capture; it does not enable it. Wireframes are only captured
182
+ * when {@link MPSessionReplayConfig.wireframesOptions} is set, so a callback on its own is
183
+ * harmless but never fires.
184
+ *
185
+ * It runs in whichever bundle you configure it in, matching the native SDKs. Nothing it
186
+ * delivers leaves the device, but building each snapshot is work the SDK otherwise skips
187
+ * and every frame crosses the bridge — so leave it unset once you are done checking.
188
+ *
189
+ * Configuration only, and deliberately so: declaring the callback is what turns snapshot
190
+ * building on, so there is no way to pay for the work with nothing listening. Set it before
191
+ * {@link MPSessionReplay.initialize}, which is where the destination is attached — a later
192
+ * `initialize` replaces it, and there is no runtime subscribe.
193
+ *
194
+ * Snapshots arrive on a background thread natively and are delivered one per frame, so a
195
+ * slow callback queues work on the bridge. Keep it cheap.
196
+ *
197
+ * ```ts
198
+ * config.debugOptions = new MPDebugOptions({
199
+ * wireframeEmitter: (frame) => {
200
+ * const withText = frame.elements.filter((e) => e.text !== null).length;
201
+ * console.log(`[wireframe] ${frame.elements.length} elements, ${withText} with text`);
202
+ * },
203
+ * });
204
+ * ```
205
+ *
206
+ * - **Default:** `null` (no snapshots are built)
207
+ */
208
+
106
209
  constructor({
107
- overlayColors = new MPDebugOverlayColors()
210
+ overlayColors = new MPDebugOverlayColors(),
211
+ wireframeEmitter = null
108
212
  } = {}) {
109
213
  this.overlayColors = overlayColors;
214
+ this.wireframeEmitter = wireframeEmitter;
110
215
  }
111
216
  }
112
217
  function processOverlayColor(color) {
@@ -128,16 +233,11 @@ function serializeDebugOptions(debugOptions) {
128
233
  if (debugOptions === null) {
129
234
  return null;
130
235
  }
131
- // Hard-gate debug features on `__DEV__` so they are never sent to native in
132
- // production bundles. The Android SDK already restricts the overlay to debuggable
133
- // builds, but the iOS SDK ships as a release XCFramework and would otherwise
134
- // render the overlay in production if a customer forgot to gate the call site.
135
- if (!__DEV__) {
136
- if (debugOptions.overlayColors !== null) {
137
- console.warn('MixpanelSessionReplay: `debugOptions` is ignored in production builds (__DEV__ is false).');
138
- }
139
- return null;
140
- }
236
+ // No `__DEV__` gate: `debugOptions` is passed through in every bundle, the same as
237
+ // configuring it natively. Each SDK decides for itself what a release build may do —
238
+ // the overlay is restricted to debuggable builds by the native SDKs (`FLAG_DEBUGGABLE`
239
+ // on Android, `#if DEBUG` on iOS, which holds because the pod ships source, not a
240
+ // prebuilt binary) — so JavaScript does not need a second, differently-shaped opinion.
141
241
  const overlayColors = debugOptions.overlayColors;
142
242
  return {
143
243
  overlayColors: overlayColors === null ? null : {
@@ -145,7 +245,239 @@ function serializeDebugOptions(debugOptions) {
145
245
  autoMaskColor: processOverlayColor(overlayColors.autoMaskColor),
146
246
  unmaskColor: processOverlayColor(overlayColors.unmaskColor),
147
247
  alpha: overlayColors.alpha
148
- }
248
+ },
249
+ // This package's own debug switch, not SDK configuration: neither SDK models the key, and
250
+ // both ignore it when they decode this payload. Their `wireframeEmitter` is a callback and
251
+ // cannot travel here, so each bridge reads the flag and attaches the destination itself.
252
+ // Keeping it out of the SDKs' public `DebugOptions` keeps an RN-only knob off their native
253
+ // API surface, where it would do nothing.
254
+ //
255
+ // Derived rather than declared: a caller who wants snapshots supplies a callback, and the
256
+ // flag follows from that. It is never possible to ask the SDKs to build snapshots that
257
+ // nothing in JavaScript is waiting for.
258
+ emitWireframes: debugOptions.wireframeEmitter !== null
259
+ };
260
+ }
261
+
262
+ /**
263
+ * A rule that rewrites or drops the text of a wireframe element when it matches.
264
+ *
265
+ * Build rules with the {@link MPSensitiveRule} factories rather than by hand — the object
266
+ * shape below is the wire format the native SDKs decode, not an API to write literals
267
+ * against.
268
+ *
269
+ * Rules run in the order you list them in {@link MPWireframesOptions.sensitiveRules},
270
+ * after the SDK's own masking, over whatever text is left — including text you declared
271
+ * with the `wireframeText` prop on {@link MPSessionReplayView}. A matching strip rule
272
+ * drops the text and stops immediately; a matching redact rule rewrites the text, and any
273
+ * rule after it sees the rewritten value.
274
+ */
275
+
276
+ /** Replacement used by the redact rules when you do not supply one. */
277
+ export const MP_DEFAULT_REPLACEMENT = '[REDACTED]';
278
+
279
+ /**
280
+ * Factories for the four {@link MPSensitiveRule} variants.
281
+ *
282
+ * ```ts
283
+ * new MPWireframesOptions({
284
+ * sensitiveRules: [
285
+ * MPSensitiveRule.strip('password'),
286
+ * MPSensitiveRule.redactRegex(/[\w.+-]+@[\w-]+\.[\w.]+/g, '[EMAIL]'),
287
+ * ],
288
+ * });
289
+ * ```
290
+ */
291
+ export const MPSensitiveRule = {
292
+ /**
293
+ * Replaces case-insensitive substring matches of `text` with `replacement`, leaving the
294
+ * surrounding text intact.
295
+ */
296
+ redact(text, replacement = MP_DEFAULT_REPLACEMENT) {
297
+ return {
298
+ type: 'redact',
299
+ text,
300
+ replacement
301
+ };
302
+ },
303
+ /** Drops the element's text entirely if it contains `text` (case-insensitive). */
304
+ strip(text) {
305
+ return {
306
+ type: 'strip',
307
+ text
308
+ };
309
+ },
310
+ /**
311
+ * Replaces matches of `regex` with `replacement`, leaving surrounding text intact.
312
+ *
313
+ * Only the `i`, `m` and `s` flags carry over to native; see
314
+ * {@link MPWireframesOptions} for what the regex itself is subject to.
315
+ */
316
+ redactRegex(regex, replacement = MP_DEFAULT_REPLACEMENT) {
317
+ return {
318
+ type: 'redactRegex',
319
+ regex,
320
+ replacement
321
+ };
322
+ },
323
+ /** Drops the element's text entirely if `regex` finds a match anywhere in the text. */
324
+ stripRegex(regex) {
325
+ return {
326
+ type: 'stripRegex',
327
+ regex
328
+ };
329
+ }
330
+ };
331
+
332
+ /**
333
+ * Enables wireframe capture for Session Replay.
334
+ *
335
+ * **Beta.** Wireframes are in beta. Before shipping to production, inspect the wireframes
336
+ * your app produces with {@link MPDebugOptions.wireframeEmitter} and confirm that no
337
+ * sensitive information is captured.
338
+ *
339
+ * A wireframe is a lightweight text outline of a screen: the visible elements, what kind
340
+ * each one is (text, button, input, image), what it says, and where it sits. One is
341
+ * captured alongside each screenshot, which lets Mixpanel summarize what your users saw
342
+ * and did without anyone having to watch the replay.
343
+ *
344
+ * Pass one to {@link MPSessionReplayConfig.wireframesOptions} to turn wireframes on.
345
+ * Leave it `null` — the default — and none are captured.
346
+ *
347
+ * Mixpanel can also turn wireframe capture off for a project from the server. The native
348
+ * SDKs honor that switch: the rest of session replay keeps recording, only the wireframe
349
+ * payload is dropped, and the reason is logged at init.
350
+ *
351
+ * ### Your masking settings are respected
352
+ *
353
+ * Anything hidden in the replay video is also removed from the wireframe. The element is
354
+ * still listed so the shape of the screen is preserved, but its text is dropped. That
355
+ * includes anything inside a `<MPSessionReplayView sensitive>`, anything covered by
356
+ * {@link MPSessionReplayConfig.autoMaskedViews}, every `TextInput`, and anything sitting
357
+ * underneath a masked area even if it was never marked sensitive itself.
358
+ *
359
+ * Note what this means for the defaults: `autoMaskedViews` masks `Text` out of the box, so
360
+ * with the default configuration every element ships as a textless shell. Narrow
361
+ * `autoMaskedViews` (and mask what matters with `<MPSessionReplayView sensitive>`) for
362
+ * wireframes to carry readable copy.
363
+ *
364
+ * ### Describing an element yourself
365
+ *
366
+ * The `wireframeText` prop on {@link MPSessionReplayView} supplies the text for an element
367
+ * — useful for custom-drawn content, or anywhere the text picked up automatically isn't
368
+ * meaningful. Because you authored it rather than the SDK scraping it off the screen, it is
369
+ * sent even for an element you've masked in the video.
370
+ *
371
+ * ### Catching sensitive content by pattern
372
+ *
373
+ * {@link sensitiveRules} match on the text itself and run last, over everything above,
374
+ * including text you supplied with `wireframeText`.
375
+ */
376
+ export class MPWireframesOptions {
377
+ /**
378
+ * Rules applied to each element's text before it is sent, in the order you declare them.
379
+ * Elements are always kept; only their text is affected.
380
+ *
381
+ * - A matching strip rule drops the text and stops — no later rule runs.
382
+ * - Redact rules build on one another: a rule declared later sees the result of the ones
383
+ * before it, not the original text.
384
+ *
385
+ * A `RegExp` is compiled by the platform's own engine — `java.util.regex` on Android,
386
+ * ICU on iOS — not by JavaScript. A pattern that is valid JS may behave differently, or
387
+ * be rejected outright, on one of them; a rejected pattern fails `initialize` rather
388
+ * than silently matching nothing. Only the `i`, `m` and `s` flags cross the bridge (they
389
+ * are the three that mean the same thing in all three engines); `g` is implied, since
390
+ * every match is replaced, and any other flag is ignored with a warning. Replacement
391
+ * strings are literal — `$1` is emitted verbatim, not as a back-reference.
392
+ *
393
+ * - **Default:** `[]`
394
+ */
395
+
396
+ /**
397
+ * Whether an element with no text of its own may fall back to its accessibility label
398
+ * (React Native's `accessibilityLabel` prop). Off by default: a label is not drawn on
399
+ * screen, so unlike visible text you cannot confirm what it contains by watching the
400
+ * replay, and labels sometimes hold more than what is shown.
401
+ *
402
+ * Turn it on if you want icons and image buttons named. For an icon-only control the
403
+ * label is usually the only description of what the element is for, and with the fallback
404
+ * off it is sent as a bare shell instead — `wireframeText` is then the only way to
405
+ * describe it.
406
+ *
407
+ * The label is only ever a fallback. Text you set with `wireframeText` wins over it, an
408
+ * element's own visible text wins over it, and a masked element stays textless either way.
409
+ *
410
+ * - **Default:** `false`
411
+ */
412
+
413
+ constructor({
414
+ sensitiveRules = [],
415
+ useAccessibilityLabelFallback = false
416
+ } = {}) {
417
+ this.sensitiveRules = sensitiveRules;
418
+ this.useAccessibilityLabelFallback = useAccessibilityLabelFallback;
419
+ }
420
+ }
421
+
422
+ /**
423
+ * Flags a `RegExp` carries that mean the same thing in JavaScript, `java.util.regex` and
424
+ * ICU. `g` is deliberately accepted and dropped: the native rules always replace every
425
+ * match, so a global regex is what a caller means either way.
426
+ */
427
+ const SUPPORTED_REGEX_FLAGS = 'imsg';
428
+ function serializeRegex(regex, ruleType) {
429
+ const unsupported = [...regex.flags].filter(flag => !SUPPORTED_REGEX_FLAGS.includes(flag));
430
+ if (unsupported.length > 0) {
431
+ console.warn(`MixpanelSessionReplay: the ${unsupported.join('')} flag(s) on ${regex} (${ruleType}) are not supported by the native regex engines and will be ignored.`);
432
+ }
433
+ return {
434
+ pattern: regex.source,
435
+ caseInsensitive: regex.flags.includes('i'),
436
+ multiline: regex.flags.includes('m'),
437
+ dotMatchesAll: regex.flags.includes('s')
438
+ };
439
+ }
440
+
441
+ /**
442
+ * The `wireframesOptions` payload, in the one shape both native SDKs decode.
443
+ *
444
+ * Unlike `autoMaskedViews` and `remoteSettingsMode`, this needs no per-platform
445
+ * transformation: Android's `SensitiveRuleSerializer` and iOS's `MPSensitiveRule`
446
+ * decoder were written against the same field names and `type` tokens, and each
447
+ * platform's suite pins them as literal text.
448
+ */
449
+ function serializeWireframesOptions(options) {
450
+ if (options === null || options === undefined) {
451
+ return null;
452
+ }
453
+ return {
454
+ sensitiveRules: options.sensitiveRules.map(rule => {
455
+ switch (rule.type) {
456
+ case 'redact':
457
+ return {
458
+ type: rule.type,
459
+ text: rule.text,
460
+ replacement: rule.replacement
461
+ };
462
+ case 'strip':
463
+ return {
464
+ type: rule.type,
465
+ text: rule.text
466
+ };
467
+ case 'redactRegex':
468
+ return {
469
+ type: rule.type,
470
+ ...serializeRegex(rule.regex, rule.type),
471
+ replacement: rule.replacement
472
+ };
473
+ case 'stripRegex':
474
+ return {
475
+ type: rule.type,
476
+ ...serializeRegex(rule.regex, rule.type)
477
+ };
478
+ }
479
+ }),
480
+ useAccessibilityLabelFallback: options.useAccessibilityLabelFallback
149
481
  };
150
482
  }
151
483
  export class MPSessionReplayConfig {
@@ -229,9 +561,10 @@ export class MPSessionReplayConfig {
229
561
  * masking coverage during development. Pass `new MPDebugOptions()` to enable the
230
562
  * overlay with default colors, or customize via `MPDebugOverlayColors`.
231
563
  *
232
- * `debugOptions` is only honored when `__DEV__` is `true`. In production bundles
233
- * it is dropped before reaching the native SDK, so it is safe to leave the option
234
- * set unconditionally — the overlay will not render for end users.
564
+ * The overlay only renders in a debuggable build — the native SDKs enforce that, so it
565
+ * is safe to leave the option set unconditionally and the overlay will not reach end
566
+ * users. {@link MPDebugOptions.wireframeEmitter}, the other member, has no such
567
+ * restriction and runs wherever you configure it.
235
568
  *
236
569
  * - **Default:** `null` (disabled)
237
570
  */
@@ -251,6 +584,22 @@ export class MPSessionReplayConfig {
251
584
  * - **Default:** `MPDataResidency.US` (`https://api.mixpanel.com`)
252
585
  */
253
586
 
587
+ /**
588
+ * Enables wireframe capture: a text outline of each captured screen — the visible
589
+ * elements, what they say, and where they sit — recorded alongside the replay so
590
+ * sessions can be summarized without watching them.
591
+ *
592
+ * Pass `new MPWireframesOptions()` to turn it on with the defaults, or customize the
593
+ * content rules and the accessibility-label fallback. Your masking settings apply to
594
+ * it; see {@link MPWireframesOptions}.
595
+ *
596
+ * **Beta.** Wireframes are in beta. Before shipping to production, inspect the wireframes
597
+ * your app produces and confirm that no sensitive information is captured; see
598
+ * {@link MPWireframesOptions}.
599
+ *
600
+ * - **Default:** `null` (wireframe capture disabled)
601
+ */
602
+
254
603
  constructor({
255
604
  wifiOnly = true,
256
605
  autoStartRecording = true,
@@ -260,7 +609,8 @@ export class MPSessionReplayConfig {
260
609
  enableLogging = false,
261
610
  remoteSettingsMode = MPSessionReplayRemoteSettingsMode.Disabled,
262
611
  debugOptions = null,
263
- serverURL = MPDataResidency.US
612
+ serverURL = MPDataResidency.US,
613
+ wireframesOptions = null
264
614
  } = {}) {
265
615
  this.wifiOnly = wifiOnly;
266
616
  this.autoStartRecording = autoStartRecording;
@@ -271,6 +621,7 @@ export class MPSessionReplayConfig {
271
621
  this.remoteSettingsMode = remoteSettingsMode;
272
622
  this.debugOptions = debugOptions;
273
623
  this.serverURL = serverURL;
624
+ this.wireframesOptions = wireframesOptions;
274
625
  }
275
626
  transformMaskValueForPlatform(value) {
276
627
  if (Platform.OS === 'android') {
@@ -293,6 +644,7 @@ export class MPSessionReplayConfig {
293
644
  enableLogging: this.enableLogging,
294
645
  remoteSettingsMode: transformedRemoteSettingsMode,
295
646
  debugOptions: serializeDebugOptions(this.debugOptions),
647
+ wireframesOptions: serializeWireframesOptions(this.wireframesOptions),
296
648
  // The native SDKs spell the server URL field differently — Android's
297
649
  // kotlinx.serialization expects `serverUrl`, iOS's Codable expects `serverURL`.
298
650
  ...Platform.select({
@@ -338,7 +690,28 @@ async function initialize(token, distinctId, config) {
338
690
  throw new Error('recordingSessionsPercent must be between 0 and 100');
339
691
  }
340
692
  const json = config.toJSON();
341
- return MixpanelReactNativeSessionReplay.initialize(token, distinctId, json);
693
+ // Attached before the native call so no frame can be emitted before the destination
694
+ // exists, then reconciled once the call settles.
695
+ //
696
+ // `initialize` is async and nothing stops an app calling it twice, so the two paths
697
+ // below hold one invariant between them: a call that succeeds ends up owning the
698
+ // subscription, and a call that fails never leaves one behind that outlives it.
699
+ // Without both halves an overlap silently ends with no destination attached at all —
700
+ // the newer call tears its own down on failure, while the older one has already had
701
+ // its callback replaced and would never restore it.
702
+ const generation = attachWireframeEmitter(config.debugOptions?.wireframeEmitter);
703
+ try {
704
+ const result = await MixpanelReactNativeSessionReplay.initialize(token, distinctId, json);
705
+ if (generation !== wireframeGeneration) {
706
+ // Another initialize attached after this one started. This call is the one that
707
+ // succeeded, so its configuration is the one that should be delivering.
708
+ attachWireframeEmitter(config.debugOptions?.wireframeEmitter);
709
+ }
710
+ return result;
711
+ } catch (error) {
712
+ detachWireframeEmitterIfCurrent(generation);
713
+ throw error;
714
+ }
342
715
  }
343
716
 
344
717
  /**
@@ -413,6 +786,78 @@ async function getReplayId() {
413
786
  async function flush() {
414
787
  return MixpanelReactNativeSessionReplay.flush();
415
788
  }
789
+
790
+ /**
791
+ * Presents one shape to JavaScript regardless of which SDK produced the payload.
792
+ *
793
+ * A textless element is `"text": null` on both platforms now, but iOS used to *omit* the
794
+ * key — Swift's synthesized `Encodable` uses `encodeIfPresent` for optionals — which
795
+ * reached JS as `undefined` and printed as the string `"undefined"` in anything that only
796
+ * checked for `null`. The SDK is fixed; this keeps the declared
797
+ * `text: string | null` contract true against an older one too.
798
+ */
799
+ function normalizeSnapshot(raw) {
800
+ return {
801
+ ...raw,
802
+ elements: (raw.elements ?? []).map(element => ({
803
+ ...element,
804
+ text: element.text ?? null
805
+ }))
806
+ };
807
+ }
808
+
809
+ /**
810
+ * Points the native wireframe event at {@link MPDebugOptions.wireframeEmitter}, replacing
811
+ * whatever a previous `initialize` attached.
812
+ *
813
+ * There is no public subscribe. The callback is declared on the config beside the switch that
814
+ * turns wireframes on, which is how Android, iOS and Flutter spell it too, and it means the
815
+ * one-callback lifetime is the instance's rather than something a caller has to remember to
816
+ * tear down.
817
+ */
818
+ function attachWireframeEmitter(listener) {
819
+ wireframeSubscription?.remove();
820
+ wireframeSubscription = null;
821
+ const generation = ++wireframeGeneration;
822
+ if (!listener) {
823
+ return generation;
824
+ }
825
+ wireframeSubscription = getWireframeEventEmitter().addListener(WIREFRAME_EVENT, payload => {
826
+ let snapshot;
827
+ try {
828
+ snapshot = normalizeSnapshot(JSON.parse(payload));
829
+ } catch (error) {
830
+ // The payload is whichever SDK's `toJson()` produced it. Report and drop the
831
+ // frame rather than throwing out of the emitter callback, which would take the
832
+ // subscription down with it.
833
+ console.warn(`MixpanelSessionReplay: could not parse a wireframe snapshot: ${error}`);
834
+ return;
835
+ }
836
+ try {
837
+ listener(snapshot);
838
+ } catch (error) {
839
+ // A consumer callback is application code. Keep it from escaping through React
840
+ // Native's synchronous EventEmitter and destabilizing the host app or later frames.
841
+ console.warn(`MixpanelSessionReplay: wireframe callback threw: ${error}`);
842
+ }
843
+ });
844
+ return generation;
845
+ }
846
+
847
+ /**
848
+ * Detaches only if the live subscription is still the one `generation` installed.
849
+ *
850
+ * `initialize` is async and nothing stops an app calling it twice. Without this check, an
851
+ * earlier call that rejects would tear down the subscription a *later*, successful call had
852
+ * already installed, and that configuration would silently stop receiving snapshots.
853
+ */
854
+ function detachWireframeEmitterIfCurrent(generation) {
855
+ if (generation !== wireframeGeneration) {
856
+ return;
857
+ }
858
+ wireframeSubscription?.remove();
859
+ wireframeSubscription = null;
860
+ }
416
861
  export { MPSessionReplayView } from "./MixpanelSessionReplayView.js";
417
862
  export const MPSessionReplay = {
418
863
  initialize,
@@ -1 +1 @@
1
- {"version":3,"names":["Platform","processColor","MixpanelReactNativeSessionReplay","MPSessionReplayMask","MPSessionReplayRemoteSettingsMode","MPDataResidency","US","EU","IN","MPDebugOverlayColors","constructor","maskColor","autoMaskColor","unmaskColor","alpha","MPDebugOptions","overlayColors","processOverlayColor","color","undefined","processed","console","warn","JSON","stringify","serializeDebugOptions","debugOptions","__DEV__","MPSessionReplayConfig","wifiOnly","autoStartRecording","recordingSessionsPercent","autoMaskedViews","Image","Text","Web","Map","flushInterval","enableLogging","remoteSettingsMode","Disabled","serverURL","transformMaskValueForPlatform","value","OS","charAt","toUpperCase","slice","toJSON","transformedAutoMaskedViews","filter","mask","map","transformedRemoteSettingsMode","config","select","ios","enableSessionReplayOniOS26AndLater","android","serverUrl","default","initialize","token","distinctId","Error","json","startRecording","stopRecording","isRecording","identify","getReplayId","flush","MPSessionReplayView","MPSessionReplay"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,SAASA,QAAQ,EAAEC,YAAY,QAAyB,cAAc;AACtE,OAAOC,gCAAgC,MAAM,6CAA0C;AAEvF,WAAYC,mBAAmB,0BAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAnBA,mBAAmB;EAAA,OAAnBA,mBAAmB;AAAA;AAO/B,WAAYC,iCAAiC,0BAAjCA,iCAAiC;EAAjCA,iCAAiC;EAAjCA,iCAAiC;EAAjCA,iCAAiC;EAAA,OAAjCA,iCAAiC;AAAA;;AAM7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,eAA6D,GAAG;EAC3E;EACAC,EAAE,EAAE,0BAA0B;EAC9B;EACAC,EAAE,EAAE,6BAA6B;EACjC;EACAC,EAAE,EAAE;AACN,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,oBAAoB,CAAC;EAChC;AACF;AACA;AACA;AACA;AACA;;EAGE;AACF;AACA;AACA;AACA;AACA;;EAGE;AACF;AACA;AACA;AACA;AACA;;EAGE;AACF;AACA;AACA;AACA;;EAGEC,WAAWA,CAAC;IACVC,SAAS,GAAG,KAAK;IACjBC,aAAa,GAAG,QAAQ;IACxBC,WAAW,GAAG,OAAO;IACrBC,KAAK,GAAG;EACqB,CAAC,GAAG,CAAC,CAAC,EAAE;IACrC,IAAI,CAACH,SAAS,GAAGA,SAAS;IAC1B,IAAI,CAACC,aAAa,GAAGA,aAAa;IAClC,IAAI,CAACC,WAAW,GAAGA,WAAW;IAC9B,IAAI,CAACC,KAAK,GAAGA,KAAK;EACpB;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,cAAc,CAAC;EAC1B;AACF;AACA;AACA;AACA;;EAGEL,WAAWA,CAAC;IACVM,aAAa,GAAG,IAAIP,oBAAoB,CAAC;EAClB,CAAC,GAAG,CAAC,CAAC,EAAE;IAC/B,IAAI,CAACO,aAAa,GAAGA,aAAa;EACpC;AACF;AAEA,SAASC,mBAAmBA,CAACC,KAAwB,EAAiB;EACpE,IAAIA,KAAK,KAAK,IAAI,IAAIA,KAAK,KAAKC,SAAS,EAAE;IACzC,OAAO,IAAI;EACb;EACA;EACA;EACA;EACA;EACA,MAAMC,SAAS,GAAGnB,YAAY,CAACiB,KAAK,CAAC;EACrC,IAAI,OAAOE,SAAS,KAAK,QAAQ,EAAE;IACjCC,OAAO,CAACC,IAAI,CACV,sDAAsDC,IAAI,CAACC,SAAS,CAACN,KAAK,CAAC,mDAC7E,CAAC;IACD,OAAO,IAAI;EACb;EACA,OAAOE,SAAS;AAClB;AAEA,SAASK,qBAAqBA,CAC5BC,YAAmC,EACpB;EACf,IAAIA,YAAY,KAAK,IAAI,EAAE;IACzB,OAAO,IAAI;EACb;EACA;EACA;EACA;EACA;EACA,IAAI,CAACC,OAAO,EAAE;IACZ,IAAID,YAAY,CAACV,aAAa,KAAK,IAAI,EAAE;MACvCK,OAAO,CAACC,IAAI,CACV,2FACF,CAAC;IACH;IACA,OAAO,IAAI;EACb;EACA,MAAMN,aAAa,GAAGU,YAAY,CAACV,aAAa;EAChD,OAAO;IACLA,aAAa,EACXA,aAAa,KAAK,IAAI,GAClB,IAAI,GACJ;MACEL,SAAS,EAAEM,mBAAmB,CAACD,aAAa,CAACL,SAAS,CAAC;MACvDC,aAAa,EAAEK,mBAAmB,CAACD,aAAa,CAACJ,aAAa,CAAC;MAC/DC,WAAW,EAAEI,mBAAmB,CAACD,aAAa,CAACH,WAAW,CAAC;MAC3DC,KAAK,EAAEE,aAAa,CAACF;IACvB;EACR,CAAC;AACH;AAEA,OAAO,MAAMc,qBAAqB,CAAC;EACjC;AACF;AACA;AACA;AACA;AACA;AACA;AACA;;EAGE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;EAGE;AACF;AACA;AACA;AACA;AACA;;EAGE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;EAGE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;EAGE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;;EAGE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;EAG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","ignoreList":[]}
1
+ {"version":3,"names":["NativeEventEmitter","Platform","processColor","MixpanelReactNativeSessionReplay","MPSessionReplayMask","MPSessionReplayRemoteSettingsMode","MPDataResidency","US","EU","IN","MPMaskDecision","None","Declared","Explicit","Auto","TextEntry","Geometric","RuleStrip","RuleRedact","WIREFRAME_EVENT","wireframeEventEmitter","wireframeSubscription","wireframeGeneration","getWireframeEventEmitter","MPDebugOverlayColors","constructor","maskColor","autoMaskColor","unmaskColor","alpha","MPDebugOptions","overlayColors","wireframeEmitter","processOverlayColor","color","undefined","processed","console","warn","JSON","stringify","serializeDebugOptions","debugOptions","emitWireframes","MP_DEFAULT_REPLACEMENT","MPSensitiveRule","redact","text","replacement","type","strip","redactRegex","regex","stripRegex","MPWireframesOptions","sensitiveRules","useAccessibilityLabelFallback","SUPPORTED_REGEX_FLAGS","serializeRegex","ruleType","unsupported","flags","filter","flag","includes","length","join","pattern","source","caseInsensitive","multiline","dotMatchesAll","serializeWireframesOptions","options","map","rule","MPSessionReplayConfig","wifiOnly","autoStartRecording","recordingSessionsPercent","autoMaskedViews","Image","Text","Web","Map","flushInterval","enableLogging","remoteSettingsMode","Disabled","serverURL","wireframesOptions","transformMaskValueForPlatform","value","OS","charAt","toUpperCase","slice","toJSON","transformedAutoMaskedViews","mask","transformedRemoteSettingsMode","config","select","ios","enableSessionReplayOniOS26AndLater","android","serverUrl","default","initialize","token","distinctId","Error","json","generation","attachWireframeEmitter","result","error","detachWireframeEmitterIfCurrent","startRecording","stopRecording","isRecording","identify","getReplayId","flush","normalizeSnapshot","raw","elements","element","listener","remove","addListener","payload","snapshot","parse","MPSessionReplayView","MPSessionReplay"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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ACF,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAME,mBAAmB,CAAC;EAC/B;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;EAGE;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;EAGE7B,WAAWA,CAAC;IACV8B,cAAc,GAAG,EAAE;IACnBC,6BAA6B,GAAG;EACJ,CAAC,GAAG,CAAC,CAAC,EAAE;IACpC,IAAI,CAACD,cAAc,GAAGA,cAAc;IACpC,IAAI,CAACC,6BAA6B,GAAGA,6BAA6B;EACpE;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA,MAAMC,qBAAqB,GAAG,MAAM;AAEpC,SAASC,cAAcA,CAACN,KAAa,EAAEO,QAAgB,EAAU;EAC/D,MAAMC,WAAW,GAAG,CAAC,GAAGR,KAAK,CAACS,KAAK,CAAC,CAACC,MAAM,CACxCC,IAAI,IAAK,CAACN,qBAAqB,CAACO,QAAQ,CAACD,IAAI,CAChD,CAAC;EACD,IAAIH,WAAW,CAACK,MAAM,GAAG,CAAC,EAAE;IAC1B5B,OAAO,CAACC,IAAI,CACV,8BAA8BsB,WAAW,CAACM,IAAI,CAAC,EAAE,CAAC,eAAed,KAAK,KAAKO,QAAQ,sEACrF,CAAC;EACH;EACA,OAAO;IACLQ,OAAO,EAAEf,KAAK,CAACgB,MAAM;IACrBC,eAAe,EAAEjB,KAAK,CAACS,KAAK,CAACG,QAAQ,CAAC,GAAG,CAAC;IAC1CM,SAAS,EAAElB,KAAK,CAACS,KAAK,CAACG,QAAQ,CAAC,GAAG,CAAC;IACpCO,aAAa,EAAEnB,KAAK,CAACS,KAAK,CAACG,QAAQ,CAAC,GAAG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","ignoreList":[]}