clintplay-react-native 0.2.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.2.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(
@@ -1279,10 +1311,18 @@ function init(rawConfig) {
1279
1311
  buffer,
1280
1312
  session,
1281
1313
  transport,
1282
- recorder: { start: () => {
1283
- }, stop: () => {
1284
- }, takeWireframeSnapshot: () => {
1285
- } },
1314
+ recorder: {
1315
+ start: () => {
1316
+ },
1317
+ stop: () => {
1318
+ },
1319
+ takeWireframeSnapshot: () => {
1320
+ },
1321
+ scheduleWireframeSnapshot: () => {
1322
+ },
1323
+ resetWireframeBaseline: () => {
1324
+ }
1325
+ },
1286
1326
  networkInterceptor: null,
1287
1327
  consoleInterceptor: null,
1288
1328
  offlineQueue: rawConfig.asyncStorage ? new OfflineQueue({
@@ -1327,17 +1367,16 @@ function init(rawConfig) {
1327
1367
  captureConsoleLog: rawConfig.captureConsoleLog
1328
1368
  });
1329
1369
  }
1330
- buffer.push({
1331
- type: "meta",
1332
- ts: Date.now(),
1333
- sessionId: session.current().sessionId,
1334
- sdkVersion: SDK_VERSION,
1335
- device: deviceInfo()
1336
- });
1370
+ pushSessionMeta(local);
1337
1371
  recorder.start();
1338
1372
  local.networkInterceptor?.start();
1339
1373
  local.consoleInterceptor?.start();
1340
- _setSink(onEvent);
1374
+ _setSink((event) => {
1375
+ onEvent(event);
1376
+ if (event.type === "navigation" || event.type === "touch" && event.kind === "end") {
1377
+ recorder.scheduleWireframeSnapshot();
1378
+ }
1379
+ });
1341
1380
  if (local.offlineQueue) {
1342
1381
  const q = local.offlineQueue;
1343
1382
  void q.hydrate().then(() => q.drain()).catch(
@@ -1348,13 +1387,7 @@ function init(rawConfig) {
1348
1387
  if (local.session.isStale()) {
1349
1388
  await flushOnce(local);
1350
1389
  if (local.session.rotateIfStale()) {
1351
- local.buffer.push({
1352
- type: "meta",
1353
- ts: Date.now(),
1354
- sessionId: local.session.current().sessionId,
1355
- sdkVersion: SDK_VERSION,
1356
- device: deviceInfo()
1357
- });
1390
+ pushSessionMeta(local);
1358
1391
  }
1359
1392
  }
1360
1393
  void flushOnce(local);
@@ -1373,13 +1406,7 @@ function identify(userId, traits) {
1373
1406
  }
1374
1407
  const rotated = state.session.setUser(normalizedUserId);
1375
1408
  if (rotated) {
1376
- state.buffer.push({
1377
- type: "meta",
1378
- ts: Date.now(),
1379
- sessionId: state.session.current().sessionId,
1380
- sdkVersion: SDK_VERSION,
1381
- device: deviceInfo()
1382
- });
1409
+ pushSessionMeta(state);
1383
1410
  }
1384
1411
  state.buffer.push({
1385
1412
  type: "identify",
@@ -1397,13 +1424,17 @@ function reset(options) {
1397
1424
  if (options?.clearOfflineQueue && state.offlineQueue) {
1398
1425
  void state.offlineQueue.clear();
1399
1426
  }
1400
- state.buffer.push({
1427
+ pushSessionMeta(state);
1428
+ }
1429
+ function pushSessionMeta(s) {
1430
+ s.buffer.push({
1401
1431
  type: "meta",
1402
1432
  ts: Date.now(),
1403
- sessionId: state.session.current().sessionId,
1433
+ sessionId: s.session.current().sessionId,
1404
1434
  sdkVersion: SDK_VERSION,
1405
1435
  device: deviceInfo()
1406
1436
  });
1437
+ s.recorder.resetWireframeBaseline();
1407
1438
  }
1408
1439
  function trackScreen(path, from) {
1409
1440
  if (!state?.active) return;
@@ -1414,9 +1445,7 @@ function trackScreen(path, from) {
1414
1445
  ...from ? { from } : {}
1415
1446
  });
1416
1447
  state.session.touch();
1417
- if (state.config.captureWireframe) {
1418
- state.recorder.takeWireframeSnapshot();
1419
- }
1448
+ state.recorder.scheduleWireframeSnapshot();
1420
1449
  }
1421
1450
  function reportError(err) {
1422
1451
  if (!state?.active) return;