@checkflow/sdk 1.0.1 → 1.0.3
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/analytics-tracker.d.ts +1 -0
- package/dist/api-client.d.ts +3 -5
- package/dist/index.esm.js +85 -9
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +85 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -72,6 +72,7 @@ export declare class AnalyticsTracker {
|
|
|
72
72
|
constructor(apiClient: APIClient, options?: Partial<AnalyticsOptions>);
|
|
73
73
|
startTracking(): Promise<void>;
|
|
74
74
|
stopTracking(): Promise<void>;
|
|
75
|
+
private saveSessionRecording;
|
|
75
76
|
private createSession;
|
|
76
77
|
private updateSessionEnd;
|
|
77
78
|
private setupEventListeners;
|
package/dist/api-client.d.ts
CHANGED
|
@@ -45,15 +45,13 @@ export declare class APIClient {
|
|
|
45
45
|
*/
|
|
46
46
|
uploadScreenshotOnly(screenshotBase64: string, url: string): Promise<APIResponse>;
|
|
47
47
|
/**
|
|
48
|
-
* Save session recording to backend
|
|
49
|
-
*
|
|
48
|
+
* Save session recording to analytics backend
|
|
49
|
+
* Recordings are now part of analytics sessions (independent from feedbacks)
|
|
50
50
|
*/
|
|
51
51
|
saveSessionRecording(recording: {
|
|
52
52
|
events: any[];
|
|
53
53
|
sessionId: string;
|
|
54
|
-
|
|
55
|
-
endUrl?: string;
|
|
56
|
-
durationSeconds: number;
|
|
54
|
+
durationMs?: number;
|
|
57
55
|
}): Promise<APIResponse>;
|
|
58
56
|
/**
|
|
59
57
|
* Report an error to the backend
|
package/dist/index.esm.js
CHANGED
|
@@ -236,16 +236,13 @@ class APIClient {
|
|
|
236
236
|
});
|
|
237
237
|
}
|
|
238
238
|
/**
|
|
239
|
-
* Save session recording to backend
|
|
240
|
-
*
|
|
239
|
+
* Save session recording to analytics backend
|
|
240
|
+
* Recordings are now part of analytics sessions (independent from feedbacks)
|
|
241
241
|
*/
|
|
242
242
|
async saveSessionRecording(recording) {
|
|
243
|
-
return this.request('POST',
|
|
243
|
+
return this.request('POST', `/api/v1/analytics/sessions/${recording.sessionId}/recording`, {
|
|
244
244
|
events: recording.events,
|
|
245
|
-
|
|
246
|
-
start_url: recording.startUrl,
|
|
247
|
-
end_url: recording.endUrl,
|
|
248
|
-
duration_seconds: recording.durationSeconds,
|
|
245
|
+
duration_ms: recording.durationMs || 0,
|
|
249
246
|
});
|
|
250
247
|
}
|
|
251
248
|
/**
|
|
@@ -2707,6 +2704,10 @@ class SessionRecording {
|
|
|
2707
2704
|
start() {
|
|
2708
2705
|
if (this.isRecording || !this.config.enabled)
|
|
2709
2706
|
return;
|
|
2707
|
+
console.log(' [SessionRecording] Starting session recording...', {
|
|
2708
|
+
sessionId: this.sessionId,
|
|
2709
|
+
config: this.config
|
|
2710
|
+
});
|
|
2710
2711
|
this.isRecording = true;
|
|
2711
2712
|
this.startTime = Date.now();
|
|
2712
2713
|
this.events = [];
|
|
@@ -2715,20 +2716,25 @@ class SessionRecording {
|
|
|
2715
2716
|
// Setup event listeners
|
|
2716
2717
|
if (this.config.recordMouse) {
|
|
2717
2718
|
this.setupMouseTracking();
|
|
2719
|
+
console.log(' [SessionRecording] Mouse tracking enabled');
|
|
2718
2720
|
}
|
|
2719
2721
|
if (this.config.recordScroll) {
|
|
2720
2722
|
this.setupScrollTracking();
|
|
2723
|
+
console.log(' [SessionRecording] Scroll tracking enabled');
|
|
2721
2724
|
}
|
|
2722
2725
|
if (this.config.recordInput) {
|
|
2723
2726
|
this.setupInputTracking();
|
|
2727
|
+
console.log(' [SessionRecording] Input tracking enabled');
|
|
2724
2728
|
}
|
|
2725
2729
|
if (this.config.recordMutations) {
|
|
2726
2730
|
this.setupMutationObserver();
|
|
2731
|
+
console.log(' [SessionRecording] Mutation observer enabled');
|
|
2727
2732
|
}
|
|
2728
2733
|
// Track navigation
|
|
2729
2734
|
this.setupNavigationTracking();
|
|
2730
2735
|
// Track resize
|
|
2731
2736
|
this.setupResizeTracking();
|
|
2737
|
+
console.log(' [SessionRecording] Session recording started successfully');
|
|
2732
2738
|
// Auto-stop after max duration
|
|
2733
2739
|
setTimeout(() => {
|
|
2734
2740
|
if (this.isRecording) {
|
|
@@ -2784,13 +2790,29 @@ class SessionRecording {
|
|
|
2784
2790
|
* Get recording data for submission
|
|
2785
2791
|
*/
|
|
2786
2792
|
getRecordingData() {
|
|
2787
|
-
|
|
2793
|
+
console.log('🎥 [SessionRecording] getRecordingData called:', {
|
|
2794
|
+
eventCount: this.events.length,
|
|
2795
|
+
sessionId: this.sessionId,
|
|
2796
|
+
duration: this.getDuration(),
|
|
2797
|
+
isRecording: this.isRecording,
|
|
2798
|
+
startTime: this.startTime
|
|
2799
|
+
});
|
|
2800
|
+
if (this.events.length === 0) {
|
|
2801
|
+
console.warn('🎥 [SessionRecording] No events to return');
|
|
2788
2802
|
return null;
|
|
2789
|
-
|
|
2803
|
+
}
|
|
2804
|
+
const data = {
|
|
2790
2805
|
events: [...this.events],
|
|
2791
2806
|
sessionId: this.sessionId,
|
|
2792
2807
|
duration: this.getDuration(),
|
|
2793
2808
|
};
|
|
2809
|
+
console.log('🎥 [SessionRecording] Returning recording data:', {
|
|
2810
|
+
eventCount: data.events.length,
|
|
2811
|
+
duration: data.duration,
|
|
2812
|
+
firstEventType: data.events[0]?.type,
|
|
2813
|
+
lastEventType: data.events[data.events.length - 1]?.type
|
|
2814
|
+
});
|
|
2815
|
+
return data;
|
|
2794
2816
|
}
|
|
2795
2817
|
addEvent(type, data) {
|
|
2796
2818
|
// Sample rate filtering
|
|
@@ -3602,6 +3624,8 @@ class AnalyticsTracker {
|
|
|
3602
3624
|
try {
|
|
3603
3625
|
// Flush any remaining interactions
|
|
3604
3626
|
await this.flushInteractions();
|
|
3627
|
+
// Save session recording if available
|
|
3628
|
+
await this.saveSessionRecording();
|
|
3605
3629
|
// Update session with end time
|
|
3606
3630
|
await this.updateSessionEnd();
|
|
3607
3631
|
// Remove event listeners
|
|
@@ -3622,6 +3646,56 @@ class AnalyticsTracker {
|
|
|
3622
3646
|
console.error('Error stopping analytics tracking:', error);
|
|
3623
3647
|
}
|
|
3624
3648
|
}
|
|
3649
|
+
async saveSessionRecording() {
|
|
3650
|
+
// Get session recording from global CheckFlow instance if available
|
|
3651
|
+
try {
|
|
3652
|
+
console.log('🎬 [AnalyticsTracker] Starting saveSessionRecording for session:', this.sessionId);
|
|
3653
|
+
const checkflowInstance = window.checkflow;
|
|
3654
|
+
console.log('🎬 [AnalyticsTracker] CheckFlow instance found:', !!checkflowInstance);
|
|
3655
|
+
console.log('🎬 [AnalyticsTracker] SessionRecording instance found:', !!checkflowInstance?.sessionRecording);
|
|
3656
|
+
if (!checkflowInstance || !checkflowInstance.sessionRecording) {
|
|
3657
|
+
console.warn('🎬 [AnalyticsTracker] No session recording available - instance missing');
|
|
3658
|
+
this.log('No session recording available');
|
|
3659
|
+
return;
|
|
3660
|
+
}
|
|
3661
|
+
const recordingData = checkflowInstance.sessionRecording.getRecordingData();
|
|
3662
|
+
console.log('🎬 [AnalyticsTracker] Recording data retrieved:', {
|
|
3663
|
+
hasData: !!recordingData,
|
|
3664
|
+
eventCount: recordingData?.events?.length || 0,
|
|
3665
|
+
duration: recordingData?.duration || 0,
|
|
3666
|
+
sessionId: recordingData?.sessionId
|
|
3667
|
+
});
|
|
3668
|
+
if (!recordingData || recordingData.events.length === 0) {
|
|
3669
|
+
console.warn('🎬 [AnalyticsTracker] No recording events to save - events array empty');
|
|
3670
|
+
this.log('No recording events to save');
|
|
3671
|
+
return;
|
|
3672
|
+
}
|
|
3673
|
+
// Save recording to analytics backend
|
|
3674
|
+
console.log('🎬 [AnalyticsTracker] Saving recording to backend...', {
|
|
3675
|
+
sessionId: this.sessionId,
|
|
3676
|
+
eventCount: recordingData.events.length,
|
|
3677
|
+
durationMs: recordingData.duration * 1000
|
|
3678
|
+
});
|
|
3679
|
+
const result = await this.apiClient.saveSessionRecording({
|
|
3680
|
+
events: recordingData.events,
|
|
3681
|
+
sessionId: this.sessionId,
|
|
3682
|
+
durationMs: recordingData.duration * 1000
|
|
3683
|
+
});
|
|
3684
|
+
console.log('🎬 [AnalyticsTracker] Session recording saved successfully:', result);
|
|
3685
|
+
this.log('Session recording saved:', {
|
|
3686
|
+
eventCount: recordingData.events.length,
|
|
3687
|
+
duration: recordingData.duration
|
|
3688
|
+
});
|
|
3689
|
+
}
|
|
3690
|
+
catch (error) {
|
|
3691
|
+
console.error('🎬 [AnalyticsTracker] Failed to save session recording:', error);
|
|
3692
|
+
console.error('🎬 [AnalyticsTracker] Error details:', {
|
|
3693
|
+
message: error instanceof Error ? error.message : String(error),
|
|
3694
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
3695
|
+
sessionId: this.sessionId
|
|
3696
|
+
});
|
|
3697
|
+
}
|
|
3698
|
+
}
|
|
3625
3699
|
// ==================== Private Methods - Session Management ====================
|
|
3626
3700
|
async createSession() {
|
|
3627
3701
|
const sessionData = {
|
|
@@ -4044,6 +4118,8 @@ class CheckFlow {
|
|
|
4044
4118
|
}
|
|
4045
4119
|
// Store as singleton
|
|
4046
4120
|
CheckFlow.instance = this;
|
|
4121
|
+
// Expose globally for analytics tracker access
|
|
4122
|
+
window.checkflow = this;
|
|
4047
4123
|
}
|
|
4048
4124
|
/**
|
|
4049
4125
|
* Initialize the SDK
|