clintplay-react-native 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -147,6 +147,8 @@ var Transport = class {
147
147
  return h;
148
148
  }
149
149
  };
150
+ var SNAPSHOT_AFTER_INTERACTION_MS = 400;
151
+ var UNCHANGED_RESEND_MS = 3e4;
150
152
  function mapAppState(state2) {
151
153
  if (state2 === "active") return "active";
152
154
  if (state2 === "background") return "background";
@@ -159,16 +161,25 @@ function createRecorder(deps) {
159
161
  const cleanups = [];
160
162
  let started = false;
161
163
  let wireframeTimer = null;
162
- function takeWireframeSnapshot() {
164
+ let interactionTimer = null;
165
+ let lastNodesKey = null;
166
+ let lastSentAt = 0;
167
+ function takeWireframeSnapshot(force = false) {
163
168
  if (!deps.captureViewHierarchy) return;
164
169
  try {
165
170
  const raw = deps.captureViewHierarchy();
166
171
  if (!raw || typeof raw !== "string") return;
167
172
  const payload = JSON.parse(raw);
168
173
  if (payload && Array.isArray(payload.nodes)) {
174
+ if (force && payload.nodes.length === 0) return;
175
+ const key = JSON.stringify(payload.nodes);
176
+ const now = deps.now();
177
+ if (!force && key === lastNodesKey && now - lastSentAt < UNCHANGED_RESEND_MS) return;
178
+ lastNodesKey = key;
179
+ lastSentAt = now;
169
180
  deps.onEvent({
170
181
  type: "wireframe",
171
- ts: deps.now(),
182
+ ts: now,
172
183
  version: typeof payload.version === "number" ? payload.version : 1,
173
184
  nodes: payload.nodes
174
185
  });
@@ -176,6 +187,20 @@ function createRecorder(deps) {
176
187
  } catch {
177
188
  }
178
189
  }
190
+ function scheduleWireframeSnapshot() {
191
+ if (!deps.captureWireframe || !deps.captureViewHierarchy) return;
192
+ if (interactionTimer) clearTimeout(interactionTimer);
193
+ interactionTimer = setTimeout(() => {
194
+ interactionTimer = null;
195
+ takeWireframeSnapshot();
196
+ }, SNAPSHOT_AFTER_INTERACTION_MS);
197
+ }
198
+ function cancelScheduledSnapshot() {
199
+ if (interactionTimer) {
200
+ clearTimeout(interactionTimer);
201
+ interactionTimer = null;
202
+ }
203
+ }
179
204
  function startWireframeTimer() {
180
205
  if (!deps.captureWireframe || !deps.captureViewHierarchy) return;
181
206
  if (wireframeTimer) return;
@@ -193,7 +218,11 @@ function createRecorder(deps) {
193
218
  }
194
219
  }
195
220
  return {
196
- takeWireframeSnapshot,
221
+ takeWireframeSnapshot: () => takeWireframeSnapshot(),
222
+ scheduleWireframeSnapshot,
223
+ resetWireframeBaseline() {
224
+ lastNodesKey = null;
225
+ },
197
226
  start() {
198
227
  if (started) return;
199
228
  started = true;
@@ -217,7 +246,9 @@ function createRecorder(deps) {
217
246
  if (mapped === "active") {
218
247
  startWireframeTimer();
219
248
  } else {
249
+ if (wireframeTimer) takeWireframeSnapshot(true);
220
250
  stopWireframeTimer();
251
+ cancelScheduledSnapshot();
221
252
  }
222
253
  }
223
254
  });
@@ -275,6 +306,7 @@ function createRecorder(deps) {
275
306
  if (!started) return;
276
307
  started = false;
277
308
  stopWireframeTimer();
309
+ cancelScheduledSnapshot();
278
310
  for (const fn of cleanups.splice(0)) {
279
311
  try {
280
312
  fn();
@@ -879,7 +911,7 @@ function captureViewHierarchy() {
879
911
  }
880
912
 
881
913
  // package.json
882
- var version = "0.1.0";
914
+ var version = "0.2.1";
883
915
  var CLINTPLAY_MASK_ID = "clintplay-mask";
884
916
  var ClintplayMaskView = React5.forwardRef(function ClintplayMaskView2({ children, testID, ...rest }, ref) {
885
917
  return /* @__PURE__ */ jsx(
@@ -1249,13 +1281,14 @@ async function flushOnce(s) {
1249
1281
  }
1250
1282
  }
1251
1283
  function init(rawConfig) {
1252
- if (state?.active) return;
1253
- if (!rawConfig.apiUrl) return;
1254
- if (rawConfig.enabled === false) return;
1284
+ if (state?.active) return Clintplay;
1285
+ const apiUrl = rawConfig.apiUrl ?? rawConfig.endpoint;
1286
+ if (!apiUrl) return Clintplay;
1287
+ if (rawConfig.enabled === false) return Clintplay;
1255
1288
  const sampleRate = rawConfig.sampleRate ?? 1;
1256
- if (sampleRate < 1 && Math.random() > sampleRate) return;
1289
+ if (sampleRate < 1 && Math.random() > sampleRate) return Clintplay;
1257
1290
  const config = {
1258
- apiUrl: rawConfig.apiUrl,
1291
+ apiUrl,
1259
1292
  apiKey: rawConfig.apiKey,
1260
1293
  projectId: rawConfig.projectId ?? rawConfig.apiKey ?? "",
1261
1294
  anonId: rawConfig.anonId,
@@ -1278,10 +1311,18 @@ function init(rawConfig) {
1278
1311
  buffer,
1279
1312
  session,
1280
1313
  transport,
1281
- recorder: { start: () => {
1282
- }, stop: () => {
1283
- }, takeWireframeSnapshot: () => {
1284
- } },
1314
+ recorder: {
1315
+ start: () => {
1316
+ },
1317
+ stop: () => {
1318
+ },
1319
+ takeWireframeSnapshot: () => {
1320
+ },
1321
+ scheduleWireframeSnapshot: () => {
1322
+ },
1323
+ resetWireframeBaseline: () => {
1324
+ }
1325
+ },
1285
1326
  networkInterceptor: null,
1286
1327
  consoleInterceptor: null,
1287
1328
  offlineQueue: rawConfig.asyncStorage ? new OfflineQueue({
@@ -1326,17 +1367,16 @@ function init(rawConfig) {
1326
1367
  captureConsoleLog: rawConfig.captureConsoleLog
1327
1368
  });
1328
1369
  }
1329
- buffer.push({
1330
- type: "meta",
1331
- ts: Date.now(),
1332
- sessionId: session.current().sessionId,
1333
- sdkVersion: SDK_VERSION,
1334
- device: deviceInfo()
1335
- });
1370
+ pushSessionMeta(local);
1336
1371
  recorder.start();
1337
1372
  local.networkInterceptor?.start();
1338
1373
  local.consoleInterceptor?.start();
1339
- _setSink(onEvent);
1374
+ _setSink((event) => {
1375
+ onEvent(event);
1376
+ if (event.type === "navigation" || event.type === "touch" && event.kind === "end") {
1377
+ recorder.scheduleWireframeSnapshot();
1378
+ }
1379
+ });
1340
1380
  if (local.offlineQueue) {
1341
1381
  const q = local.offlineQueue;
1342
1382
  void q.hydrate().then(() => q.drain()).catch(
@@ -1347,41 +1387,34 @@ function init(rawConfig) {
1347
1387
  if (local.session.isStale()) {
1348
1388
  await flushOnce(local);
1349
1389
  if (local.session.rotateIfStale()) {
1350
- local.buffer.push({
1351
- type: "meta",
1352
- ts: Date.now(),
1353
- sessionId: local.session.current().sessionId,
1354
- sdkVersion: SDK_VERSION,
1355
- device: deviceInfo()
1356
- });
1390
+ pushSessionMeta(local);
1357
1391
  }
1358
1392
  }
1359
1393
  void flushOnce(local);
1360
1394
  }, config.flushIntervalMs);
1361
1395
  debugLog(config, "init", { sessionId: session.current().sessionId });
1396
+ return Clintplay;
1362
1397
  }
1363
1398
  function identify(userId, traits) {
1364
1399
  if (!state?.active) return;
1400
+ if (userId === void 0 || userId === "") return;
1401
+ const normalizedUserId = userId === null ? null : String(userId);
1365
1402
  const prevUser = state.session.current().userId;
1366
- const isUserChange = prevUser !== null && (userId === null || prevUser !== userId);
1403
+ const isUserChange = prevUser !== null && (normalizedUserId === null || prevUser !== normalizedUserId);
1367
1404
  if (isUserChange) {
1368
1405
  void flushOnce(state);
1369
1406
  }
1370
- const rotated = state.session.setUser(userId);
1407
+ const rotated = state.session.setUser(normalizedUserId);
1371
1408
  if (rotated) {
1372
- state.buffer.push({
1373
- type: "meta",
1374
- ts: Date.now(),
1375
- sessionId: state.session.current().sessionId,
1376
- sdkVersion: SDK_VERSION,
1377
- device: deviceInfo()
1378
- });
1409
+ pushSessionMeta(state);
1379
1410
  }
1380
1411
  state.buffer.push({
1381
1412
  type: "identify",
1382
1413
  ts: Date.now(),
1383
- userId,
1384
- traits
1414
+ data: {
1415
+ userId: normalizedUserId,
1416
+ traits: traits ?? {}
1417
+ }
1385
1418
  });
1386
1419
  }
1387
1420
  function reset(options) {
@@ -1391,13 +1424,17 @@ function reset(options) {
1391
1424
  if (options?.clearOfflineQueue && state.offlineQueue) {
1392
1425
  void state.offlineQueue.clear();
1393
1426
  }
1394
- state.buffer.push({
1427
+ pushSessionMeta(state);
1428
+ }
1429
+ function pushSessionMeta(s) {
1430
+ s.buffer.push({
1395
1431
  type: "meta",
1396
1432
  ts: Date.now(),
1397
- sessionId: state.session.current().sessionId,
1433
+ sessionId: s.session.current().sessionId,
1398
1434
  sdkVersion: SDK_VERSION,
1399
1435
  device: deviceInfo()
1400
1436
  });
1437
+ s.recorder.resetWireframeBaseline();
1401
1438
  }
1402
1439
  function trackScreen(path, from) {
1403
1440
  if (!state?.active) return;
@@ -1408,9 +1445,7 @@ function trackScreen(path, from) {
1408
1445
  ...from ? { from } : {}
1409
1446
  });
1410
1447
  state.session.touch();
1411
- if (state.config.captureWireframe) {
1412
- state.recorder.takeWireframeSnapshot();
1413
- }
1448
+ state.recorder.scheduleWireframeSnapshot();
1414
1449
  }
1415
1450
  function reportError(err) {
1416
1451
  if (!state?.active) return;
@@ -1445,6 +1480,13 @@ function current() {
1445
1480
  const s = state.session.current();
1446
1481
  return { sessionId: s.sessionId, userId: s.userId };
1447
1482
  }
1483
+ function _getState() {
1484
+ if (!state) return null;
1485
+ return {
1486
+ ...state,
1487
+ buffer: state.buffer.peek()
1488
+ };
1489
+ }
1448
1490
  var Clintplay = {
1449
1491
  init,
1450
1492
  identify,
@@ -1453,9 +1495,10 @@ var Clintplay = {
1453
1495
  reportError,
1454
1496
  flush,
1455
1497
  stop,
1456
- current
1498
+ current,
1499
+ _getState
1457
1500
  };
1458
1501
 
1459
- export { CLINTPLAY_MASK_ID, Clintplay, ClintplayCaptureProvider, ClintplayMaskImage, ClintplayMaskTextInput, ClintplayMaskView, ClintplayNavigationTracker, SDK_VERSION, _resetLastTrackedRoute, createClintplayNavigationStateListener, formatEventForBatch, getActiveRouteName, sanitizeRoute, useClintplayNavigationTracking };
1502
+ export { CLINTPLAY_MASK_ID, Clintplay, ClintplayCaptureProvider, ClintplayMaskImage, ClintplayMaskTextInput, ClintplayMaskView, ClintplayNavigationTracker, SDK_VERSION, _resetLastTrackedRoute, createClintplayNavigationStateListener, formatEventForBatch, getActiveRouteName, init, sanitizeRoute, useClintplayNavigationTracking };
1460
1503
  //# sourceMappingURL=index.mjs.map
1461
1504
  //# sourceMappingURL=index.mjs.map