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.js CHANGED
@@ -153,6 +153,8 @@ var Transport = class {
153
153
  return h;
154
154
  }
155
155
  };
156
+ var SNAPSHOT_AFTER_INTERACTION_MS = 400;
157
+ var UNCHANGED_RESEND_MS = 3e4;
156
158
  function mapAppState(state2) {
157
159
  if (state2 === "active") return "active";
158
160
  if (state2 === "background") return "background";
@@ -165,16 +167,25 @@ function createRecorder(deps) {
165
167
  const cleanups = [];
166
168
  let started = false;
167
169
  let wireframeTimer = null;
168
- function takeWireframeSnapshot() {
170
+ let interactionTimer = null;
171
+ let lastNodesKey = null;
172
+ let lastSentAt = 0;
173
+ function takeWireframeSnapshot(force = false) {
169
174
  if (!deps.captureViewHierarchy) return;
170
175
  try {
171
176
  const raw = deps.captureViewHierarchy();
172
177
  if (!raw || typeof raw !== "string") return;
173
178
  const payload = JSON.parse(raw);
174
179
  if (payload && Array.isArray(payload.nodes)) {
180
+ if (force && payload.nodes.length === 0) return;
181
+ const key = JSON.stringify(payload.nodes);
182
+ const now = deps.now();
183
+ if (!force && key === lastNodesKey && now - lastSentAt < UNCHANGED_RESEND_MS) return;
184
+ lastNodesKey = key;
185
+ lastSentAt = now;
175
186
  deps.onEvent({
176
187
  type: "wireframe",
177
- ts: deps.now(),
188
+ ts: now,
178
189
  version: typeof payload.version === "number" ? payload.version : 1,
179
190
  nodes: payload.nodes
180
191
  });
@@ -182,6 +193,20 @@ function createRecorder(deps) {
182
193
  } catch {
183
194
  }
184
195
  }
196
+ function scheduleWireframeSnapshot() {
197
+ if (!deps.captureWireframe || !deps.captureViewHierarchy) return;
198
+ if (interactionTimer) clearTimeout(interactionTimer);
199
+ interactionTimer = setTimeout(() => {
200
+ interactionTimer = null;
201
+ takeWireframeSnapshot();
202
+ }, SNAPSHOT_AFTER_INTERACTION_MS);
203
+ }
204
+ function cancelScheduledSnapshot() {
205
+ if (interactionTimer) {
206
+ clearTimeout(interactionTimer);
207
+ interactionTimer = null;
208
+ }
209
+ }
185
210
  function startWireframeTimer() {
186
211
  if (!deps.captureWireframe || !deps.captureViewHierarchy) return;
187
212
  if (wireframeTimer) return;
@@ -199,7 +224,11 @@ function createRecorder(deps) {
199
224
  }
200
225
  }
201
226
  return {
202
- takeWireframeSnapshot,
227
+ takeWireframeSnapshot: () => takeWireframeSnapshot(),
228
+ scheduleWireframeSnapshot,
229
+ resetWireframeBaseline() {
230
+ lastNodesKey = null;
231
+ },
203
232
  start() {
204
233
  if (started) return;
205
234
  started = true;
@@ -223,7 +252,9 @@ function createRecorder(deps) {
223
252
  if (mapped === "active") {
224
253
  startWireframeTimer();
225
254
  } else {
255
+ if (wireframeTimer) takeWireframeSnapshot(true);
226
256
  stopWireframeTimer();
257
+ cancelScheduledSnapshot();
227
258
  }
228
259
  }
229
260
  });
@@ -281,6 +312,7 @@ function createRecorder(deps) {
281
312
  if (!started) return;
282
313
  started = false;
283
314
  stopWireframeTimer();
315
+ cancelScheduledSnapshot();
284
316
  for (const fn of cleanups.splice(0)) {
285
317
  try {
286
318
  fn();
@@ -885,7 +917,7 @@ function captureViewHierarchy() {
885
917
  }
886
918
 
887
919
  // package.json
888
- var version = "0.1.0";
920
+ var version = "0.2.1";
889
921
  var CLINTPLAY_MASK_ID = "clintplay-mask";
890
922
  var ClintplayMaskView = React5__default.default.forwardRef(function ClintplayMaskView2({ children, testID, ...rest }, ref) {
891
923
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -1255,13 +1287,14 @@ async function flushOnce(s) {
1255
1287
  }
1256
1288
  }
1257
1289
  function init(rawConfig) {
1258
- if (state?.active) return;
1259
- if (!rawConfig.apiUrl) return;
1260
- if (rawConfig.enabled === false) return;
1290
+ if (state?.active) return Clintplay;
1291
+ const apiUrl = rawConfig.apiUrl ?? rawConfig.endpoint;
1292
+ if (!apiUrl) return Clintplay;
1293
+ if (rawConfig.enabled === false) return Clintplay;
1261
1294
  const sampleRate = rawConfig.sampleRate ?? 1;
1262
- if (sampleRate < 1 && Math.random() > sampleRate) return;
1295
+ if (sampleRate < 1 && Math.random() > sampleRate) return Clintplay;
1263
1296
  const config = {
1264
- apiUrl: rawConfig.apiUrl,
1297
+ apiUrl,
1265
1298
  apiKey: rawConfig.apiKey,
1266
1299
  projectId: rawConfig.projectId ?? rawConfig.apiKey ?? "",
1267
1300
  anonId: rawConfig.anonId,
@@ -1284,10 +1317,18 @@ function init(rawConfig) {
1284
1317
  buffer,
1285
1318
  session,
1286
1319
  transport,
1287
- recorder: { start: () => {
1288
- }, stop: () => {
1289
- }, takeWireframeSnapshot: () => {
1290
- } },
1320
+ recorder: {
1321
+ start: () => {
1322
+ },
1323
+ stop: () => {
1324
+ },
1325
+ takeWireframeSnapshot: () => {
1326
+ },
1327
+ scheduleWireframeSnapshot: () => {
1328
+ },
1329
+ resetWireframeBaseline: () => {
1330
+ }
1331
+ },
1291
1332
  networkInterceptor: null,
1292
1333
  consoleInterceptor: null,
1293
1334
  offlineQueue: rawConfig.asyncStorage ? new OfflineQueue({
@@ -1332,17 +1373,16 @@ function init(rawConfig) {
1332
1373
  captureConsoleLog: rawConfig.captureConsoleLog
1333
1374
  });
1334
1375
  }
1335
- buffer.push({
1336
- type: "meta",
1337
- ts: Date.now(),
1338
- sessionId: session.current().sessionId,
1339
- sdkVersion: SDK_VERSION,
1340
- device: deviceInfo()
1341
- });
1376
+ pushSessionMeta(local);
1342
1377
  recorder.start();
1343
1378
  local.networkInterceptor?.start();
1344
1379
  local.consoleInterceptor?.start();
1345
- _setSink(onEvent);
1380
+ _setSink((event) => {
1381
+ onEvent(event);
1382
+ if (event.type === "navigation" || event.type === "touch" && event.kind === "end") {
1383
+ recorder.scheduleWireframeSnapshot();
1384
+ }
1385
+ });
1346
1386
  if (local.offlineQueue) {
1347
1387
  const q = local.offlineQueue;
1348
1388
  void q.hydrate().then(() => q.drain()).catch(
@@ -1353,41 +1393,34 @@ function init(rawConfig) {
1353
1393
  if (local.session.isStale()) {
1354
1394
  await flushOnce(local);
1355
1395
  if (local.session.rotateIfStale()) {
1356
- local.buffer.push({
1357
- type: "meta",
1358
- ts: Date.now(),
1359
- sessionId: local.session.current().sessionId,
1360
- sdkVersion: SDK_VERSION,
1361
- device: deviceInfo()
1362
- });
1396
+ pushSessionMeta(local);
1363
1397
  }
1364
1398
  }
1365
1399
  void flushOnce(local);
1366
1400
  }, config.flushIntervalMs);
1367
1401
  debugLog(config, "init", { sessionId: session.current().sessionId });
1402
+ return Clintplay;
1368
1403
  }
1369
1404
  function identify(userId, traits) {
1370
1405
  if (!state?.active) return;
1406
+ if (userId === void 0 || userId === "") return;
1407
+ const normalizedUserId = userId === null ? null : String(userId);
1371
1408
  const prevUser = state.session.current().userId;
1372
- const isUserChange = prevUser !== null && (userId === null || prevUser !== userId);
1409
+ const isUserChange = prevUser !== null && (normalizedUserId === null || prevUser !== normalizedUserId);
1373
1410
  if (isUserChange) {
1374
1411
  void flushOnce(state);
1375
1412
  }
1376
- const rotated = state.session.setUser(userId);
1413
+ const rotated = state.session.setUser(normalizedUserId);
1377
1414
  if (rotated) {
1378
- state.buffer.push({
1379
- type: "meta",
1380
- ts: Date.now(),
1381
- sessionId: state.session.current().sessionId,
1382
- sdkVersion: SDK_VERSION,
1383
- device: deviceInfo()
1384
- });
1415
+ pushSessionMeta(state);
1385
1416
  }
1386
1417
  state.buffer.push({
1387
1418
  type: "identify",
1388
1419
  ts: Date.now(),
1389
- userId,
1390
- traits
1420
+ data: {
1421
+ userId: normalizedUserId,
1422
+ traits: traits ?? {}
1423
+ }
1391
1424
  });
1392
1425
  }
1393
1426
  function reset(options) {
@@ -1397,13 +1430,17 @@ function reset(options) {
1397
1430
  if (options?.clearOfflineQueue && state.offlineQueue) {
1398
1431
  void state.offlineQueue.clear();
1399
1432
  }
1400
- state.buffer.push({
1433
+ pushSessionMeta(state);
1434
+ }
1435
+ function pushSessionMeta(s) {
1436
+ s.buffer.push({
1401
1437
  type: "meta",
1402
1438
  ts: Date.now(),
1403
- sessionId: state.session.current().sessionId,
1439
+ sessionId: s.session.current().sessionId,
1404
1440
  sdkVersion: SDK_VERSION,
1405
1441
  device: deviceInfo()
1406
1442
  });
1443
+ s.recorder.resetWireframeBaseline();
1407
1444
  }
1408
1445
  function trackScreen(path, from) {
1409
1446
  if (!state?.active) return;
@@ -1414,9 +1451,7 @@ function trackScreen(path, from) {
1414
1451
  ...from ? { from } : {}
1415
1452
  });
1416
1453
  state.session.touch();
1417
- if (state.config.captureWireframe) {
1418
- state.recorder.takeWireframeSnapshot();
1419
- }
1454
+ state.recorder.scheduleWireframeSnapshot();
1420
1455
  }
1421
1456
  function reportError(err) {
1422
1457
  if (!state?.active) return;
@@ -1451,6 +1486,13 @@ function current() {
1451
1486
  const s = state.session.current();
1452
1487
  return { sessionId: s.sessionId, userId: s.userId };
1453
1488
  }
1489
+ function _getState() {
1490
+ if (!state) return null;
1491
+ return {
1492
+ ...state,
1493
+ buffer: state.buffer.peek()
1494
+ };
1495
+ }
1454
1496
  var Clintplay = {
1455
1497
  init,
1456
1498
  identify,
@@ -1459,7 +1501,8 @@ var Clintplay = {
1459
1501
  reportError,
1460
1502
  flush,
1461
1503
  stop,
1462
- current
1504
+ current,
1505
+ _getState
1463
1506
  };
1464
1507
 
1465
1508
  exports.CLINTPLAY_MASK_ID = CLINTPLAY_MASK_ID;
@@ -1474,6 +1517,7 @@ exports._resetLastTrackedRoute = _resetLastTrackedRoute;
1474
1517
  exports.createClintplayNavigationStateListener = createClintplayNavigationStateListener;
1475
1518
  exports.formatEventForBatch = formatEventForBatch;
1476
1519
  exports.getActiveRouteName = getActiveRouteName;
1520
+ exports.init = init;
1477
1521
  exports.sanitizeRoute = sanitizeRoute;
1478
1522
  exports.useClintplayNavigationTracking = useClintplayNavigationTracking;
1479
1523
  //# sourceMappingURL=index.js.map