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.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
|
-
|
|
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:
|
|
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
|
|
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
|
-
|
|
1260
|
-
if (
|
|
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
|
|
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: {
|
|
1288
|
-
|
|
1289
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
|
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 && (
|
|
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(
|
|
1413
|
+
const rotated = state.session.setUser(normalizedUserId);
|
|
1377
1414
|
if (rotated) {
|
|
1378
|
-
state
|
|
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
|
-
|
|
1390
|
-
|
|
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
|
|
1433
|
+
pushSessionMeta(state);
|
|
1434
|
+
}
|
|
1435
|
+
function pushSessionMeta(s) {
|
|
1436
|
+
s.buffer.push({
|
|
1401
1437
|
type: "meta",
|
|
1402
1438
|
ts: Date.now(),
|
|
1403
|
-
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
|
-
|
|
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
|