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/README.md +3 -3
- package/android/src/main/java/digital/clint/clintplay/ClintplayRNModule.kt +49 -1
- package/dist/index.d.mts +158 -6
- package/dist/index.d.ts +158 -6
- package/dist/index.js +89 -45
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +89 -46
- package/dist/index.mjs.map +1 -1
- package/ios/ClintplayRN.mm +112 -6
- package/package.json +1 -1
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
|
-
|
|
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:
|
|
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
|
|
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
|
-
|
|
1254
|
-
if (
|
|
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
|
|
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: {
|
|
1282
|
-
|
|
1283
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
|
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 && (
|
|
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(
|
|
1407
|
+
const rotated = state.session.setUser(normalizedUserId);
|
|
1371
1408
|
if (rotated) {
|
|
1372
|
-
state
|
|
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
|
-
|
|
1384
|
-
|
|
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
|
|
1427
|
+
pushSessionMeta(state);
|
|
1428
|
+
}
|
|
1429
|
+
function pushSessionMeta(s) {
|
|
1430
|
+
s.buffer.push({
|
|
1395
1431
|
type: "meta",
|
|
1396
1432
|
ts: Date.now(),
|
|
1397
|
-
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
|
-
|
|
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
|