clintplay-react-native 0.1.0 → 0.2.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.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Session capture SDK for React Native / Expo apps — companion to [`clintplay-sdk`](../sdk) (web). Captures lifecycle, screen dimensions, navigation, JS errors, network requests (Fetch & XHR/Axios), console output, touches (screen-relative & target-relative), and native visual wireframe replay on iOS and Android.
4
4
 
5
- > **Status:** `0.1.0` — Production-ready JS runtime and Native TurboModule. Supports native view hierarchy traversal on iOS (`ios/ClintplayRN.mm`) and Android (`android/.../ClintplayRNModule.kt`), visual wireframe session replay, network interception for `fetch` and `XMLHttpRequest`/Axios, automatic navigation tracking, and intelligent auto-masking for sensitive fields.
5
+ > **Status:** `0.2.0` — Production-ready JS runtime and Native TurboModule. Supports native view hierarchy traversal on iOS (`ios/ClintplayRN.mm`) and Android (`android/.../ClintplayRNModule.kt`), visual wireframe session replay, network interception for `fetch` and `XMLHttpRequest`/Axios, automatic navigation tracking, and intelligent auto-masking for sensitive fields.
6
6
 
7
7
  ## Install
8
8
 
@@ -328,7 +328,7 @@ class ClintplayRNModule(reactContext: ReactApplicationContext) :
328
328
 
329
329
  companion object {
330
330
  const val NAME = "ClintplayRN"
331
- private const val VERSION = "0.1.0"
331
+ private const val VERSION = "0.2.0"
332
332
  private const val FALLBACK_JSON = "{\"version\":1,\"nodes\":[]}"
333
333
 
334
334
  private val NO_METHOD_SENTINEL = Any()
package/dist/index.d.mts CHANGED
@@ -2,6 +2,25 @@ import React from 'react';
2
2
  import { ViewProps, View, TextInputProps, TextInput, ImageProps, Image, StyleProp, ViewStyle } from 'react-native';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
 
5
+ interface SessionState {
6
+ sessionId: string;
7
+ startedAt: number;
8
+ lastActivity: number;
9
+ userId: string | null;
10
+ }
11
+ declare class SessionManager {
12
+ private state;
13
+ private readonly now;
14
+ constructor(now?: () => number);
15
+ private create;
16
+ current(): SessionState;
17
+ touch(): void;
18
+ setUser(userId: string | null): boolean;
19
+ isStale(): boolean;
20
+ rotateIfStale(): boolean;
21
+ reset(): void;
22
+ }
23
+
5
24
  type EventType = 'meta' | 'screen' | 'lifecycle' | 'navigation' | 'touch' | 'error' | 'log' | 'identify' | 'network' | 'wireframe';
6
25
  interface DeviceInfo {
7
26
  platform: 'ios' | 'android' | 'web';
@@ -59,8 +78,10 @@ interface LogEvent {
59
78
  interface IdentifyEvent {
60
79
  type: 'identify';
61
80
  ts: number;
62
- userId: string | null;
63
- traits?: Record<string, unknown>;
81
+ data: {
82
+ userId: string | null;
83
+ traits?: Record<string, unknown>;
84
+ };
64
85
  }
65
86
  interface NetworkEvent {
66
87
  type: 'network';
@@ -112,7 +133,8 @@ interface ReplayBatch {
112
133
  sdkVersion?: string;
113
134
  }
114
135
  interface ClintplayReactNativeConfig {
115
- apiUrl: string;
136
+ apiUrl?: string;
137
+ endpoint?: string;
116
138
  apiKey?: string;
117
139
  projectId?: string;
118
140
  anonId?: string;
@@ -139,6 +161,107 @@ interface AsyncStorageLike {
139
161
  multiRemove(keys: readonly string[]): Promise<void>;
140
162
  }
141
163
 
164
+ interface TransportConfig {
165
+ apiUrl: string;
166
+ apiKey?: string;
167
+ projectId?: string;
168
+ maxRetries?: number;
169
+ timeoutMs?: number;
170
+ backoffMs?: (attempt: number) => number;
171
+ }
172
+ interface TransportResult {
173
+ ok: boolean;
174
+ status?: number;
175
+ retryable?: boolean;
176
+ }
177
+ declare class Transport {
178
+ private readonly cfg;
179
+ constructor(cfg: TransportConfig);
180
+ sendDetailed(batch: ReplayBatch): Promise<TransportResult>;
181
+ send(batch: ReplayBatch): Promise<boolean>;
182
+ private headers;
183
+ }
184
+
185
+ interface Recorder {
186
+ start(): void;
187
+ stop(): void;
188
+ takeWireframeSnapshot(): void;
189
+ }
190
+
191
+ interface NetworkInterceptorDeps {
192
+ onEvent: (event: ReplayEvent) => void;
193
+ now: () => number;
194
+ sanitizeUrl?: (url: string) => string;
195
+ apiUrl?: string;
196
+ }
197
+ declare class NetworkInterceptor {
198
+ private readonly deps;
199
+ private originalFetch;
200
+ private wrappedFetch;
201
+ private originalXHROpen;
202
+ private wrappedXHROpen;
203
+ private originalXHRSend;
204
+ private wrappedXHRSend;
205
+ private started;
206
+ private isCallingFetchSync;
207
+ private readonly sanitize;
208
+ private readonly ingestOrigin;
209
+ private readonly ingestPath;
210
+ constructor(deps: NetworkInterceptorDeps);
211
+ private isSelfIngestUrl;
212
+ start(): void;
213
+ stop(): void;
214
+ private extractUrl;
215
+ private extractMethod;
216
+ }
217
+
218
+ interface ConsoleInterceptorDeps {
219
+ onEvent: (event: ReplayEvent) => void;
220
+ now: () => number;
221
+ maxMessageLength?: number;
222
+ captureConsoleLog?: boolean;
223
+ }
224
+ declare class ConsoleInterceptor {
225
+ private readonly deps;
226
+ private readonly originals;
227
+ private readonly wrapped;
228
+ private started;
229
+ private isEmitting;
230
+ private readonly maxLength;
231
+ constructor(deps: ConsoleInterceptorDeps);
232
+ start(): void;
233
+ private wrapMethod;
234
+ stop(): void;
235
+ private formatMessage;
236
+ }
237
+
238
+ type SendBatchResult = boolean | {
239
+ ok: boolean;
240
+ status?: number;
241
+ retryable?: boolean;
242
+ };
243
+ interface OfflineQueueDeps {
244
+ storage: AsyncStorageLike;
245
+ send: (batch: ReplayBatch) => Promise<SendBatchResult>;
246
+ maxBytes?: number;
247
+ keyPrefix?: string;
248
+ debug?: (msg: string) => void;
249
+ }
250
+ declare class OfflineQueue {
251
+ private readonly deps;
252
+ private currentBytes;
253
+ private seq;
254
+ private readonly prefix;
255
+ private readonly maxBytes;
256
+ private hydrationPromise;
257
+ constructor(deps: OfflineQueueDeps);
258
+ hydrate(force?: boolean): Promise<void>;
259
+ persist(batch: ReplayBatch): Promise<void>;
260
+ drain(): Promise<number>;
261
+ clear(): Promise<void>;
262
+ private evictUntilFits;
263
+ }
264
+
142
265
  declare const CLINTPLAY_MASK_ID = "clintplay-mask";
143
266
  interface ClintplayMaskViewProps extends ViewProps {
144
267
  children?: React.ReactNode;
@@ -252,9 +375,20 @@ declare function _resetLastTrackedRoute(): void;
252
375
  declare function useClintplayNavigationTracking(routeNameOrPath?: string, options?: UseClintplayNavigationOptions): UseClintplayNavigationResult;
253
376
 
254
377
  declare const SDK_VERSION: string;
378
+ interface InternalConfig {
379
+ apiUrl: string;
380
+ apiKey?: string;
381
+ projectId: string;
382
+ anonId?: string;
383
+ flushIntervalMs: number;
384
+ flushSize: number;
385
+ maxBufferSize: number;
386
+ debug: boolean;
387
+ captureWireframe: boolean;
388
+ }
255
389
  declare function formatEventForBatch(event: ReplayEvent | BackendEvent, defaultSessionId: string): BackendEvent;
256
- declare function init(rawConfig: ClintplayReactNativeConfig): void;
257
- declare function identify(userId: string | null, traits?: Record<string, unknown>): void;
390
+ declare function init(rawConfig: ClintplayReactNativeConfig): typeof Clintplay;
391
+ declare function identify(userId: string | number | null, traits?: Record<string, unknown>): void;
258
392
  declare function reset(options?: {
259
393
  clearOfflineQueue?: boolean;
260
394
  }): void;
@@ -266,6 +400,19 @@ declare function current(): {
266
400
  sessionId: string;
267
401
  userId: string | null;
268
402
  } | null;
403
+ declare function _getState(): {
404
+ buffer: readonly ReplayEvent[];
405
+ config: InternalConfig;
406
+ session: SessionManager;
407
+ transport: Transport;
408
+ recorder: Recorder;
409
+ networkInterceptor: NetworkInterceptor | null;
410
+ consoleInterceptor: ConsoleInterceptor | null;
411
+ offlineQueue: OfflineQueue | null;
412
+ flushTimer: ReturnType<typeof setInterval> | null;
413
+ excluded: ReadonlySet<EventType>;
414
+ active: boolean;
415
+ } | null;
269
416
  declare const Clintplay: {
270
417
  init: typeof init;
271
418
  identify: typeof identify;
@@ -275,6 +422,7 @@ declare const Clintplay: {
275
422
  flush: typeof flush;
276
423
  stop: typeof stop;
277
424
  current: typeof current;
425
+ _getState: typeof _getState;
278
426
  };
279
427
 
280
- export { type BackendEvent, CLINTPLAY_MASK_ID, Clintplay, ClintplayCaptureProvider, type ClintplayCaptureProviderProps, ClintplayMaskImage, type ClintplayMaskImageProps, ClintplayMaskTextInput, type ClintplayMaskTextInputProps, ClintplayMaskView, type ClintplayMaskViewProps, ClintplayNavigationTracker, type ClintplayNavigationTrackerProps, type ClintplayReactNativeConfig, type DeviceInfo, type NavigationRouteLike, type NavigationStateLike, type NavigationStateListenerCallback, type NavigationStateListenerOptions, type ReplayBatch, type ReplayEvent, SDK_VERSION, type UseClintplayNavigationOptions, type UseClintplayNavigationResult, type WireframeEvent, type WireframeNode, _resetLastTrackedRoute, createClintplayNavigationStateListener, formatEventForBatch, getActiveRouteName, sanitizeRoute, useClintplayNavigationTracking };
428
+ export { type BackendEvent, CLINTPLAY_MASK_ID, Clintplay, ClintplayCaptureProvider, type ClintplayCaptureProviderProps, ClintplayMaskImage, type ClintplayMaskImageProps, ClintplayMaskTextInput, type ClintplayMaskTextInputProps, ClintplayMaskView, type ClintplayMaskViewProps, ClintplayNavigationTracker, type ClintplayNavigationTrackerProps, type ClintplayReactNativeConfig, type DeviceInfo, type NavigationRouteLike, type NavigationStateLike, type NavigationStateListenerCallback, type NavigationStateListenerOptions, type ReplayBatch, type ReplayEvent, SDK_VERSION, type UseClintplayNavigationOptions, type UseClintplayNavigationResult, type WireframeEvent, type WireframeNode, _resetLastTrackedRoute, createClintplayNavigationStateListener, formatEventForBatch, getActiveRouteName, init, sanitizeRoute, useClintplayNavigationTracking };
package/dist/index.d.ts CHANGED
@@ -2,6 +2,25 @@ import React from 'react';
2
2
  import { ViewProps, View, TextInputProps, TextInput, ImageProps, Image, StyleProp, ViewStyle } from 'react-native';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
 
5
+ interface SessionState {
6
+ sessionId: string;
7
+ startedAt: number;
8
+ lastActivity: number;
9
+ userId: string | null;
10
+ }
11
+ declare class SessionManager {
12
+ private state;
13
+ private readonly now;
14
+ constructor(now?: () => number);
15
+ private create;
16
+ current(): SessionState;
17
+ touch(): void;
18
+ setUser(userId: string | null): boolean;
19
+ isStale(): boolean;
20
+ rotateIfStale(): boolean;
21
+ reset(): void;
22
+ }
23
+
5
24
  type EventType = 'meta' | 'screen' | 'lifecycle' | 'navigation' | 'touch' | 'error' | 'log' | 'identify' | 'network' | 'wireframe';
6
25
  interface DeviceInfo {
7
26
  platform: 'ios' | 'android' | 'web';
@@ -59,8 +78,10 @@ interface LogEvent {
59
78
  interface IdentifyEvent {
60
79
  type: 'identify';
61
80
  ts: number;
62
- userId: string | null;
63
- traits?: Record<string, unknown>;
81
+ data: {
82
+ userId: string | null;
83
+ traits?: Record<string, unknown>;
84
+ };
64
85
  }
65
86
  interface NetworkEvent {
66
87
  type: 'network';
@@ -112,7 +133,8 @@ interface ReplayBatch {
112
133
  sdkVersion?: string;
113
134
  }
114
135
  interface ClintplayReactNativeConfig {
115
- apiUrl: string;
136
+ apiUrl?: string;
137
+ endpoint?: string;
116
138
  apiKey?: string;
117
139
  projectId?: string;
118
140
  anonId?: string;
@@ -139,6 +161,107 @@ interface AsyncStorageLike {
139
161
  multiRemove(keys: readonly string[]): Promise<void>;
140
162
  }
141
163
 
164
+ interface TransportConfig {
165
+ apiUrl: string;
166
+ apiKey?: string;
167
+ projectId?: string;
168
+ maxRetries?: number;
169
+ timeoutMs?: number;
170
+ backoffMs?: (attempt: number) => number;
171
+ }
172
+ interface TransportResult {
173
+ ok: boolean;
174
+ status?: number;
175
+ retryable?: boolean;
176
+ }
177
+ declare class Transport {
178
+ private readonly cfg;
179
+ constructor(cfg: TransportConfig);
180
+ sendDetailed(batch: ReplayBatch): Promise<TransportResult>;
181
+ send(batch: ReplayBatch): Promise<boolean>;
182
+ private headers;
183
+ }
184
+
185
+ interface Recorder {
186
+ start(): void;
187
+ stop(): void;
188
+ takeWireframeSnapshot(): void;
189
+ }
190
+
191
+ interface NetworkInterceptorDeps {
192
+ onEvent: (event: ReplayEvent) => void;
193
+ now: () => number;
194
+ sanitizeUrl?: (url: string) => string;
195
+ apiUrl?: string;
196
+ }
197
+ declare class NetworkInterceptor {
198
+ private readonly deps;
199
+ private originalFetch;
200
+ private wrappedFetch;
201
+ private originalXHROpen;
202
+ private wrappedXHROpen;
203
+ private originalXHRSend;
204
+ private wrappedXHRSend;
205
+ private started;
206
+ private isCallingFetchSync;
207
+ private readonly sanitize;
208
+ private readonly ingestOrigin;
209
+ private readonly ingestPath;
210
+ constructor(deps: NetworkInterceptorDeps);
211
+ private isSelfIngestUrl;
212
+ start(): void;
213
+ stop(): void;
214
+ private extractUrl;
215
+ private extractMethod;
216
+ }
217
+
218
+ interface ConsoleInterceptorDeps {
219
+ onEvent: (event: ReplayEvent) => void;
220
+ now: () => number;
221
+ maxMessageLength?: number;
222
+ captureConsoleLog?: boolean;
223
+ }
224
+ declare class ConsoleInterceptor {
225
+ private readonly deps;
226
+ private readonly originals;
227
+ private readonly wrapped;
228
+ private started;
229
+ private isEmitting;
230
+ private readonly maxLength;
231
+ constructor(deps: ConsoleInterceptorDeps);
232
+ start(): void;
233
+ private wrapMethod;
234
+ stop(): void;
235
+ private formatMessage;
236
+ }
237
+
238
+ type SendBatchResult = boolean | {
239
+ ok: boolean;
240
+ status?: number;
241
+ retryable?: boolean;
242
+ };
243
+ interface OfflineQueueDeps {
244
+ storage: AsyncStorageLike;
245
+ send: (batch: ReplayBatch) => Promise<SendBatchResult>;
246
+ maxBytes?: number;
247
+ keyPrefix?: string;
248
+ debug?: (msg: string) => void;
249
+ }
250
+ declare class OfflineQueue {
251
+ private readonly deps;
252
+ private currentBytes;
253
+ private seq;
254
+ private readonly prefix;
255
+ private readonly maxBytes;
256
+ private hydrationPromise;
257
+ constructor(deps: OfflineQueueDeps);
258
+ hydrate(force?: boolean): Promise<void>;
259
+ persist(batch: ReplayBatch): Promise<void>;
260
+ drain(): Promise<number>;
261
+ clear(): Promise<void>;
262
+ private evictUntilFits;
263
+ }
264
+
142
265
  declare const CLINTPLAY_MASK_ID = "clintplay-mask";
143
266
  interface ClintplayMaskViewProps extends ViewProps {
144
267
  children?: React.ReactNode;
@@ -252,9 +375,20 @@ declare function _resetLastTrackedRoute(): void;
252
375
  declare function useClintplayNavigationTracking(routeNameOrPath?: string, options?: UseClintplayNavigationOptions): UseClintplayNavigationResult;
253
376
 
254
377
  declare const SDK_VERSION: string;
378
+ interface InternalConfig {
379
+ apiUrl: string;
380
+ apiKey?: string;
381
+ projectId: string;
382
+ anonId?: string;
383
+ flushIntervalMs: number;
384
+ flushSize: number;
385
+ maxBufferSize: number;
386
+ debug: boolean;
387
+ captureWireframe: boolean;
388
+ }
255
389
  declare function formatEventForBatch(event: ReplayEvent | BackendEvent, defaultSessionId: string): BackendEvent;
256
- declare function init(rawConfig: ClintplayReactNativeConfig): void;
257
- declare function identify(userId: string | null, traits?: Record<string, unknown>): void;
390
+ declare function init(rawConfig: ClintplayReactNativeConfig): typeof Clintplay;
391
+ declare function identify(userId: string | number | null, traits?: Record<string, unknown>): void;
258
392
  declare function reset(options?: {
259
393
  clearOfflineQueue?: boolean;
260
394
  }): void;
@@ -266,6 +400,19 @@ declare function current(): {
266
400
  sessionId: string;
267
401
  userId: string | null;
268
402
  } | null;
403
+ declare function _getState(): {
404
+ buffer: readonly ReplayEvent[];
405
+ config: InternalConfig;
406
+ session: SessionManager;
407
+ transport: Transport;
408
+ recorder: Recorder;
409
+ networkInterceptor: NetworkInterceptor | null;
410
+ consoleInterceptor: ConsoleInterceptor | null;
411
+ offlineQueue: OfflineQueue | null;
412
+ flushTimer: ReturnType<typeof setInterval> | null;
413
+ excluded: ReadonlySet<EventType>;
414
+ active: boolean;
415
+ } | null;
269
416
  declare const Clintplay: {
270
417
  init: typeof init;
271
418
  identify: typeof identify;
@@ -275,6 +422,7 @@ declare const Clintplay: {
275
422
  flush: typeof flush;
276
423
  stop: typeof stop;
277
424
  current: typeof current;
425
+ _getState: typeof _getState;
278
426
  };
279
427
 
280
- export { type BackendEvent, CLINTPLAY_MASK_ID, Clintplay, ClintplayCaptureProvider, type ClintplayCaptureProviderProps, ClintplayMaskImage, type ClintplayMaskImageProps, ClintplayMaskTextInput, type ClintplayMaskTextInputProps, ClintplayMaskView, type ClintplayMaskViewProps, ClintplayNavigationTracker, type ClintplayNavigationTrackerProps, type ClintplayReactNativeConfig, type DeviceInfo, type NavigationRouteLike, type NavigationStateLike, type NavigationStateListenerCallback, type NavigationStateListenerOptions, type ReplayBatch, type ReplayEvent, SDK_VERSION, type UseClintplayNavigationOptions, type UseClintplayNavigationResult, type WireframeEvent, type WireframeNode, _resetLastTrackedRoute, createClintplayNavigationStateListener, formatEventForBatch, getActiveRouteName, sanitizeRoute, useClintplayNavigationTracking };
428
+ export { type BackendEvent, CLINTPLAY_MASK_ID, Clintplay, ClintplayCaptureProvider, type ClintplayCaptureProviderProps, ClintplayMaskImage, type ClintplayMaskImageProps, ClintplayMaskTextInput, type ClintplayMaskTextInputProps, ClintplayMaskView, type ClintplayMaskViewProps, ClintplayNavigationTracker, type ClintplayNavigationTrackerProps, type ClintplayReactNativeConfig, type DeviceInfo, type NavigationRouteLike, type NavigationStateLike, type NavigationStateListenerCallback, type NavigationStateListenerOptions, type ReplayBatch, type ReplayEvent, SDK_VERSION, type UseClintplayNavigationOptions, type UseClintplayNavigationResult, type WireframeEvent, type WireframeNode, _resetLastTrackedRoute, createClintplayNavigationStateListener, formatEventForBatch, getActiveRouteName, init, sanitizeRoute, useClintplayNavigationTracking };
package/dist/index.js CHANGED
@@ -885,7 +885,7 @@ function captureViewHierarchy() {
885
885
  }
886
886
 
887
887
  // package.json
888
- var version = "0.1.0";
888
+ var version = "0.2.0";
889
889
  var CLINTPLAY_MASK_ID = "clintplay-mask";
890
890
  var ClintplayMaskView = React5__default.default.forwardRef(function ClintplayMaskView2({ children, testID, ...rest }, ref) {
891
891
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -1255,13 +1255,14 @@ async function flushOnce(s) {
1255
1255
  }
1256
1256
  }
1257
1257
  function init(rawConfig) {
1258
- if (state?.active) return;
1259
- if (!rawConfig.apiUrl) return;
1260
- if (rawConfig.enabled === false) return;
1258
+ if (state?.active) return Clintplay;
1259
+ const apiUrl = rawConfig.apiUrl ?? rawConfig.endpoint;
1260
+ if (!apiUrl) return Clintplay;
1261
+ if (rawConfig.enabled === false) return Clintplay;
1261
1262
  const sampleRate = rawConfig.sampleRate ?? 1;
1262
- if (sampleRate < 1 && Math.random() > sampleRate) return;
1263
+ if (sampleRate < 1 && Math.random() > sampleRate) return Clintplay;
1263
1264
  const config = {
1264
- apiUrl: rawConfig.apiUrl,
1265
+ apiUrl,
1265
1266
  apiKey: rawConfig.apiKey,
1266
1267
  projectId: rawConfig.projectId ?? rawConfig.apiKey ?? "",
1267
1268
  anonId: rawConfig.anonId,
@@ -1365,15 +1366,18 @@ function init(rawConfig) {
1365
1366
  void flushOnce(local);
1366
1367
  }, config.flushIntervalMs);
1367
1368
  debugLog(config, "init", { sessionId: session.current().sessionId });
1369
+ return Clintplay;
1368
1370
  }
1369
1371
  function identify(userId, traits) {
1370
1372
  if (!state?.active) return;
1373
+ if (userId === void 0 || userId === "") return;
1374
+ const normalizedUserId = userId === null ? null : String(userId);
1371
1375
  const prevUser = state.session.current().userId;
1372
- const isUserChange = prevUser !== null && (userId === null || prevUser !== userId);
1376
+ const isUserChange = prevUser !== null && (normalizedUserId === null || prevUser !== normalizedUserId);
1373
1377
  if (isUserChange) {
1374
1378
  void flushOnce(state);
1375
1379
  }
1376
- const rotated = state.session.setUser(userId);
1380
+ const rotated = state.session.setUser(normalizedUserId);
1377
1381
  if (rotated) {
1378
1382
  state.buffer.push({
1379
1383
  type: "meta",
@@ -1386,8 +1390,10 @@ function identify(userId, traits) {
1386
1390
  state.buffer.push({
1387
1391
  type: "identify",
1388
1392
  ts: Date.now(),
1389
- userId,
1390
- traits
1393
+ data: {
1394
+ userId: normalizedUserId,
1395
+ traits: traits ?? {}
1396
+ }
1391
1397
  });
1392
1398
  }
1393
1399
  function reset(options) {
@@ -1451,6 +1457,13 @@ function current() {
1451
1457
  const s = state.session.current();
1452
1458
  return { sessionId: s.sessionId, userId: s.userId };
1453
1459
  }
1460
+ function _getState() {
1461
+ if (!state) return null;
1462
+ return {
1463
+ ...state,
1464
+ buffer: state.buffer.peek()
1465
+ };
1466
+ }
1454
1467
  var Clintplay = {
1455
1468
  init,
1456
1469
  identify,
@@ -1459,7 +1472,8 @@ var Clintplay = {
1459
1472
  reportError,
1460
1473
  flush,
1461
1474
  stop,
1462
- current
1475
+ current,
1476
+ _getState
1463
1477
  };
1464
1478
 
1465
1479
  exports.CLINTPLAY_MASK_ID = CLINTPLAY_MASK_ID;
@@ -1474,6 +1488,7 @@ exports._resetLastTrackedRoute = _resetLastTrackedRoute;
1474
1488
  exports.createClintplayNavigationStateListener = createClintplayNavigationStateListener;
1475
1489
  exports.formatEventForBatch = formatEventForBatch;
1476
1490
  exports.getActiveRouteName = getActiveRouteName;
1491
+ exports.init = init;
1477
1492
  exports.sanitizeRoute = sanitizeRoute;
1478
1493
  exports.useClintplayNavigationTracking = useClintplayNavigationTracking;
1479
1494
  //# sourceMappingURL=index.js.map