@mikeci/pos-analytics-replay
v0.3.4
Published
Session replay wireframe helpers for the Pos Analytics React Native SDK.
Readme
@mikeci/pos-analytics-replay
Session replay cho app React Native: ghi cây component (không quay video, không gửi bitmap), che dữ liệu nhạy cảm, lưu hàng đợi trên máy và gửi lên collector theo protocol V2 (POST /v1/replay/chunks).
npm install @mikeci/pos-analytics-replayĐã gỡ định dạng wireframe cũ.
maskTree,applyFrames,buildChunk,shouldMask,maskTextvà mã chụp nativeWireframeCapture(Swift/Kotlin) không còn. Collector trả410 replay_legacy_removedchoPOST /v1/replay. App đang dùng định dạng cũ cần chuyển sangReplayRecorder+ReplayUploaderbên dưới.
Recorder
ReplayRecorder ghi snapshot, patch và tap/scroll theo protocol mới. Hàng đợi replay tách khỏi hàng đợi event. Input và component nhạy cảm được mask trước khi vào chunk. ReplayScreen, ReplayView, ReplayButton, ReplayText và ReplayInput đăng ký node. Sampling và kill switch lấy từ GET /v1/sdk/config.
Gửi replay lên collector
ReplayUploader lưu chunk xuống máy và gửi lên collector. Hàng đợi nằm trong AsyncStorage nên không mất khi app bị kill hoặc mất mạng.
import AsyncStorage from "@react-native-async-storage/async-storage";
import { ReplayRecorder, ReplayUploader, recorderOptionsFromConfig } from "@mikeci/pos-analytics-replay";
const uploader = new ReplayUploader({
endpoint: "https://ingest.example.com",
appId: "veso24h",
writeKey: CLIENT_WRITE_KEY,
environment: "production",
storage: AsyncStorage,
// compress: async (json) => pako.gzip(json), // tùy chọn: gửi gzip để tiết kiệm dữ liệu di động
});
// Chưa có mạng và chưa có cấu hình đã lưu thì trả enabled=false: không ghi, event vẫn gửi bình thường.
const config = await uploader.loadConfig();
const recorder = new ReplayRecorder({
replayId,
sessionId,
viewport,
...recorderOptionsFromConfig(config),
});
const replay = uploader.attach(recorder); // tự tick() mỗi 150 ms, gửi mỗi 5 giây
// AppState: 'background' -> await replay.background(); 'active' -> replay.foreground();
// Rời session: await replay.stop(); // gửi nốt hàng đợi và POST /v1/replay/endCách hoạt động:
| Tình huống | Hành vi |
| --- | --- |
| Mất mạng, 429, 5xx | Giữ chunk, thử lại theo backoff 5s → 15s → 30s → 1p → 5p (có jitter), dùng Retry-After nếu server gửi. Dừng ở chunk lỗi để giữ thứ tự. Quá maxAttempts (8) thì bỏ chunk |
| 400, 401, 409, 413 | Bỏ chunk đó và gửi tiếp chunk sau (gửi lại cũng không thành công) |
| 403 replay_disabled | Xóa hàng đợi, đặt uploader.isDisabled = true, không ghi thêm |
| Hàng đợi quá maxChunks (30) hoặc maxBytes (2 MB) | Bỏ chunk cũ nhất |
| Lỗi ghi storage | Bỏ chunk, không ném lỗi ra app |
Chunk đã gửi lại thì collector trả duplicate: true nên gửi lặp không tạo bản sao. Collector cũng mask lần hai dữ liệu cá nhân; SDK vẫn phải mask trước khi gửi.
