@logspace/sdk 1.0.0
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/index.d.ts +6 -0
- package/logspace.esm.js +15848 -0
- package/logspace.esm.js.map +1 -0
- package/logspace.iife.js +2 -0
- package/logspace.iife.js.map +1 -0
- package/logspace.umd.js +2 -0
- package/logspace.umd.js.map +1 -0
- package/package.json +44 -0
- package/sdk/capture/base.d.ts +45 -0
- package/sdk/capture/console.d.ts +5 -0
- package/sdk/capture/errors.d.ts +5 -0
- package/sdk/capture/index.d.ts +16 -0
- package/sdk/capture/interactions.d.ts +5 -0
- package/sdk/capture/network.d.ts +5 -0
- package/sdk/capture/performance.d.ts +5 -0
- package/sdk/capture/resources.d.ts +5 -0
- package/sdk/capture/rrweb.d.ts +101 -0
- package/sdk/capture/spa-navigation.d.ts +5 -0
- package/sdk/capture/sse.d.ts +5 -0
- package/sdk/capture/storage.d.ts +5 -0
- package/sdk/capture/websocket.d.ts +5 -0
- package/sdk/core/console-api.d.ts +26 -0
- package/sdk/core/multi-tab.d.ts +176 -0
- package/sdk/index.d.ts +69 -0
- package/sdk/storage/indexed-db.d.ts +72 -0
- package/sdk/types.d.ts +411 -0
- package/shared/browser-detection.d.ts +38 -0
- package/shared/displayMediaCapture.d.ts +23 -0
- package/shared/export.d.ts +15 -0
- package/shared/log-optimizer.d.ts +47 -0
- package/shared/types.d.ts +356 -0
- package/shared/utils.d.ts +45 -0
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@logspace/sdk",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "LogSpace JavaScript SDK for session recording and logging",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./logspace.umd.js",
|
|
7
|
+
"module": "./logspace.esm.js",
|
|
8
|
+
"types": "./index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./index.d.ts",
|
|
13
|
+
"default": "./logspace.esm.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./index.d.ts",
|
|
17
|
+
"default": "./logspace.umd.js"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"logspace.esm.js",
|
|
23
|
+
"logspace.esm.js.map",
|
|
24
|
+
"logspace.umd.js",
|
|
25
|
+
"logspace.umd.js.map",
|
|
26
|
+
"logspace.iife.js",
|
|
27
|
+
"logspace.iife.js.map",
|
|
28
|
+
"index.d.ts",
|
|
29
|
+
"sdk",
|
|
30
|
+
"shared"
|
|
31
|
+
],
|
|
32
|
+
"keywords": [
|
|
33
|
+
"logging",
|
|
34
|
+
"session-recording",
|
|
35
|
+
"rrweb",
|
|
36
|
+
"debugging",
|
|
37
|
+
"monitoring"
|
|
38
|
+
],
|
|
39
|
+
"author": "LogSpace",
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"scripts": {
|
|
42
|
+
"preinstall": "npx only-allow bun && bun --version | grep -q '^1.2.21$' || (echo 'Error: Bun version 1.2.21 is required' && exit 1)"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { LogEntry, LogType } from '../../shared/types';
|
|
2
|
+
import { CaptureHandler, PrivacyConfig } from '../types';
|
|
3
|
+
import { generateId, safeStringify, maskSensitiveData, maskHeaders } from '../../shared/utils';
|
|
4
|
+
export { generateId, safeStringify, maskSensitiveData, maskHeaders };
|
|
5
|
+
/**
|
|
6
|
+
* Check if running in browser environment (SSR safety)
|
|
7
|
+
*/
|
|
8
|
+
export declare function isBrowser(): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Check if URL should be excluded from capture
|
|
11
|
+
*/
|
|
12
|
+
export declare function shouldExcludeUrl(url: string, excludePatterns: string[]): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Get call stack for request initiator
|
|
15
|
+
*/
|
|
16
|
+
export declare function getCallStack(): string;
|
|
17
|
+
/**
|
|
18
|
+
* Truncate large JSON objects while maintaining structure
|
|
19
|
+
*/
|
|
20
|
+
export declare function truncateJSON(obj: any, maxLength: number): any;
|
|
21
|
+
/**
|
|
22
|
+
* Truncate message content
|
|
23
|
+
*/
|
|
24
|
+
export declare function truncateMessage(message: any, isBinary: boolean, maxSize?: number): {
|
|
25
|
+
content: string;
|
|
26
|
+
size: number;
|
|
27
|
+
truncated: boolean;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Create a log entry with common fields
|
|
31
|
+
*/
|
|
32
|
+
export declare function createLogEntry(type: LogType, data: any, severity?: 'info' | 'warn' | 'error'): Omit<LogEntry, 'tabId' | 'tabUrl'>;
|
|
33
|
+
/**
|
|
34
|
+
* Apply privacy settings to log data
|
|
35
|
+
*/
|
|
36
|
+
export declare function applyPrivacy(log: LogEntry, privacy: PrivacyConfig): LogEntry;
|
|
37
|
+
/**
|
|
38
|
+
* Capture module interface
|
|
39
|
+
*/
|
|
40
|
+
export interface CaptureModule {
|
|
41
|
+
name: string;
|
|
42
|
+
install(handler: CaptureHandler, privacy: PrivacyConfig): void;
|
|
43
|
+
uninstall(): void;
|
|
44
|
+
reset?(): void;
|
|
45
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capture Module Index
|
|
3
|
+
* Re-exports all capture modules
|
|
4
|
+
*/
|
|
5
|
+
export { consoleCapture } from './console';
|
|
6
|
+
export { networkCapture } from './network';
|
|
7
|
+
export { errorCapture } from './errors';
|
|
8
|
+
export { websocketCapture } from './websocket';
|
|
9
|
+
export { sseCapture } from './sse';
|
|
10
|
+
export { storageCapture } from './storage';
|
|
11
|
+
export { interactionCapture } from './interactions';
|
|
12
|
+
export { performanceCapture } from './performance';
|
|
13
|
+
export { resourceCapture } from './resources';
|
|
14
|
+
export { spaNavigationCapture } from './spa-navigation';
|
|
15
|
+
export type { CaptureModule } from './base';
|
|
16
|
+
export { applyPrivacy, createLogEntry, isBrowser } from './base';
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { eventWithTime } from 'rrweb';
|
|
2
|
+
import { RecordPlugin } from '@rrweb/types';
|
|
3
|
+
export interface RRWebCaptureConfig {
|
|
4
|
+
/** Mask all text input values (default: true) */
|
|
5
|
+
maskAllInputs?: boolean;
|
|
6
|
+
/** Mask text content matching these CSS selectors */
|
|
7
|
+
maskTextSelector?: string;
|
|
8
|
+
/** Block elements matching these CSS selectors from being recorded */
|
|
9
|
+
blockSelector?: string;
|
|
10
|
+
/** Ignore elements matching these CSS selectors */
|
|
11
|
+
ignoreSelector?: string;
|
|
12
|
+
/** Inline stylesheets for accurate replay (default: true) */
|
|
13
|
+
inlineStylesheet?: boolean;
|
|
14
|
+
/** Sample mouse movements to reduce data (default: true) */
|
|
15
|
+
sampling?: {
|
|
16
|
+
mousemove?: boolean | number;
|
|
17
|
+
mouseInteraction?: boolean | Record<string, boolean | undefined>;
|
|
18
|
+
scroll?: number;
|
|
19
|
+
media?: number;
|
|
20
|
+
input?: 'last' | 'all';
|
|
21
|
+
canvas?: number | 'all';
|
|
22
|
+
};
|
|
23
|
+
/** Take a full DOM snapshot every N events (default: 200) */
|
|
24
|
+
checkoutEveryNth?: number;
|
|
25
|
+
/** Take a full DOM snapshot every N milliseconds */
|
|
26
|
+
checkoutEveryNms?: number;
|
|
27
|
+
/** Record canvas content (default: false - can be expensive) */
|
|
28
|
+
recordCanvas?: boolean;
|
|
29
|
+
/** Collect fonts for replay (default: false) */
|
|
30
|
+
collectFonts?: boolean;
|
|
31
|
+
/** Enable inline images for replay (default: true) */
|
|
32
|
+
inlineImages?: boolean;
|
|
33
|
+
/** Plugins to use */
|
|
34
|
+
plugins?: RecordPlugin[];
|
|
35
|
+
}
|
|
36
|
+
export interface RRWebCaptureState {
|
|
37
|
+
isRecording: boolean;
|
|
38
|
+
events: eventWithTime[];
|
|
39
|
+
stopFn: (() => void) | null;
|
|
40
|
+
startTime: number | null;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Extended rrweb event with tab information
|
|
44
|
+
*/
|
|
45
|
+
export type TabAwareEvent = eventWithTime & {
|
|
46
|
+
tabId?: string;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Start rrweb DOM recording
|
|
50
|
+
* @param config - rrweb configuration options
|
|
51
|
+
* @param onEvent - callback for each recorded event
|
|
52
|
+
* @param tabId - optional tab identifier for multi-tab recording
|
|
53
|
+
*/
|
|
54
|
+
export declare function startRRWebRecording(config?: RRWebCaptureConfig, onEvent?: (event: TabAwareEvent) => void, tabId?: string): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Stop rrweb DOM recording and return captured events
|
|
57
|
+
*/
|
|
58
|
+
export declare function stopRRWebRecording(): eventWithTime[];
|
|
59
|
+
/**
|
|
60
|
+
* Get current recording state
|
|
61
|
+
*/
|
|
62
|
+
export declare function getRRWebState(): Readonly<RRWebCaptureState>;
|
|
63
|
+
/**
|
|
64
|
+
* Get current events (for incremental sending if needed)
|
|
65
|
+
*/
|
|
66
|
+
export declare function getRRWebEvents(): eventWithTime[];
|
|
67
|
+
/**
|
|
68
|
+
* Clear current events (useful for chunked sending)
|
|
69
|
+
*/
|
|
70
|
+
export declare function clearRRWebEvents(): void;
|
|
71
|
+
/**
|
|
72
|
+
* Get recording duration in milliseconds
|
|
73
|
+
*/
|
|
74
|
+
export declare function getRRWebDuration(): number;
|
|
75
|
+
/**
|
|
76
|
+
* Check if recording is active
|
|
77
|
+
*/
|
|
78
|
+
export declare function isRRWebRecording(): boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Get estimated size of recorded events in bytes
|
|
81
|
+
*/
|
|
82
|
+
export declare function getRRWebEventsSize(): number;
|
|
83
|
+
/**
|
|
84
|
+
* Force a full DOM snapshot
|
|
85
|
+
* Call this when the tab becomes visible to ensure complete DOM context
|
|
86
|
+
*/
|
|
87
|
+
export declare function forceFullSnapshot(): void;
|
|
88
|
+
/**
|
|
89
|
+
* Add a custom event to the rrweb recording
|
|
90
|
+
* Used for marking tab switches, navigation, etc.
|
|
91
|
+
*/
|
|
92
|
+
export declare function addRRWebCustomEvent<T>(tag: string, payload: T): void;
|
|
93
|
+
/**
|
|
94
|
+
* Get current tab ID
|
|
95
|
+
*/
|
|
96
|
+
export declare function getRRWebTabId(): string | null;
|
|
97
|
+
/**
|
|
98
|
+
* Set current tab ID (for when tab becomes leader)
|
|
99
|
+
*/
|
|
100
|
+
export declare function setRRWebTabId(tabId: string): void;
|
|
101
|
+
export type { eventWithTime } from 'rrweb';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { CaptureHandler } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* LogSpace console interface
|
|
4
|
+
*/
|
|
5
|
+
export interface LogSpaceConsole {
|
|
6
|
+
/** Log a custom event */
|
|
7
|
+
(event: string, data?: any): void;
|
|
8
|
+
/** Log an error with context */
|
|
9
|
+
error: (name: string, error: Error | any, context?: Record<string, any>) => void;
|
|
10
|
+
/** Add a breadcrumb */
|
|
11
|
+
breadcrumb: (message: string, category?: string) => void;
|
|
12
|
+
/** Log debug info (only in development) */
|
|
13
|
+
debug: (message: string, data?: any) => void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Install console.logspace on the window object
|
|
17
|
+
*/
|
|
18
|
+
export declare function installConsoleAPI(handler: CaptureHandler, debug?: boolean): void;
|
|
19
|
+
/**
|
|
20
|
+
* Uninstall console.logspace
|
|
21
|
+
*/
|
|
22
|
+
export declare function uninstallConsoleAPI(): void;
|
|
23
|
+
/**
|
|
24
|
+
* Get the logspace console (for direct use)
|
|
25
|
+
*/
|
|
26
|
+
export declare function getLogSpaceConsole(): LogSpaceConsole;
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { LogEntry } from '../../shared/types';
|
|
2
|
+
import { eventWithTime } from 'rrweb';
|
|
3
|
+
type TabAwareRRWebEvent = eventWithTime & {
|
|
4
|
+
tabId?: string;
|
|
5
|
+
};
|
|
6
|
+
type MultiTabMessage = {
|
|
7
|
+
type: 'leader-announce';
|
|
8
|
+
tabId: string;
|
|
9
|
+
sessionId: string;
|
|
10
|
+
} | {
|
|
11
|
+
type: 'leader-leaving';
|
|
12
|
+
tabId: string;
|
|
13
|
+
} | {
|
|
14
|
+
type: 'log';
|
|
15
|
+
tabId: string;
|
|
16
|
+
log: LogEntry;
|
|
17
|
+
} | {
|
|
18
|
+
type: 'rrweb-event';
|
|
19
|
+
tabId: string;
|
|
20
|
+
event: TabAwareRRWebEvent;
|
|
21
|
+
} | {
|
|
22
|
+
type: 'request-session';
|
|
23
|
+
tabId: string;
|
|
24
|
+
} | {
|
|
25
|
+
type: 'session-info';
|
|
26
|
+
sessionId: string;
|
|
27
|
+
startTime: number;
|
|
28
|
+
};
|
|
29
|
+
interface LeaderState {
|
|
30
|
+
tabId: string;
|
|
31
|
+
sessionId: string;
|
|
32
|
+
heartbeat: number;
|
|
33
|
+
}
|
|
34
|
+
interface SessionState {
|
|
35
|
+
id: string;
|
|
36
|
+
startTime: number;
|
|
37
|
+
userId?: string;
|
|
38
|
+
userTraits?: Record<string, any>;
|
|
39
|
+
}
|
|
40
|
+
interface MultiTabCallbacks {
|
|
41
|
+
onBecomeLeader: (sessionId: string, isNewSession: boolean) => void;
|
|
42
|
+
onBecomeFollower: (sessionId: string) => void;
|
|
43
|
+
onReceiveLog: (log: LogEntry) => void;
|
|
44
|
+
onReceiveRRWebEvent: (event: TabAwareRRWebEvent) => void;
|
|
45
|
+
onLeaderChanged: (newLeaderTabId: string) => void;
|
|
46
|
+
}
|
|
47
|
+
declare class MultiTabCoordinator {
|
|
48
|
+
private tabId;
|
|
49
|
+
private channel;
|
|
50
|
+
private isLeader;
|
|
51
|
+
private callbacks;
|
|
52
|
+
private heartbeatTimer;
|
|
53
|
+
private leaderCheckTimer;
|
|
54
|
+
private currentSessionId;
|
|
55
|
+
private initialized;
|
|
56
|
+
private debug;
|
|
57
|
+
constructor();
|
|
58
|
+
/**
|
|
59
|
+
* Generate unique tab identifier
|
|
60
|
+
*/
|
|
61
|
+
private generateTabId;
|
|
62
|
+
/**
|
|
63
|
+
* Check if BroadcastChannel is supported
|
|
64
|
+
*/
|
|
65
|
+
isSupported(): boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Initialize the multi-tab coordinator
|
|
68
|
+
*/
|
|
69
|
+
init(callbacks: MultiTabCallbacks, debug?: boolean): void;
|
|
70
|
+
/**
|
|
71
|
+
* Attempt to become leader or join as follower
|
|
72
|
+
*/
|
|
73
|
+
private electLeader;
|
|
74
|
+
/**
|
|
75
|
+
* Try to claim leadership
|
|
76
|
+
*/
|
|
77
|
+
private tryBecomeLeader;
|
|
78
|
+
/**
|
|
79
|
+
* Become the leader tab
|
|
80
|
+
*/
|
|
81
|
+
private becomeLeader;
|
|
82
|
+
/**
|
|
83
|
+
* Become a follower tab
|
|
84
|
+
*/
|
|
85
|
+
private becomeFollower;
|
|
86
|
+
/**
|
|
87
|
+
* Handle incoming broadcast messages
|
|
88
|
+
*/
|
|
89
|
+
private handleMessage;
|
|
90
|
+
/**
|
|
91
|
+
* Start heartbeat for leader
|
|
92
|
+
*/
|
|
93
|
+
private startHeartbeat;
|
|
94
|
+
/**
|
|
95
|
+
* Stop heartbeat timer
|
|
96
|
+
*/
|
|
97
|
+
private stopHeartbeat;
|
|
98
|
+
/**
|
|
99
|
+
* Update heartbeat in localStorage
|
|
100
|
+
*/
|
|
101
|
+
private updateHeartbeat;
|
|
102
|
+
/**
|
|
103
|
+
* Start checking if leader is alive (for followers)
|
|
104
|
+
*/
|
|
105
|
+
private startLeaderCheck;
|
|
106
|
+
/**
|
|
107
|
+
* Stop leader check timer
|
|
108
|
+
*/
|
|
109
|
+
private stopLeaderCheck;
|
|
110
|
+
/**
|
|
111
|
+
* Check if leader heartbeat is stale
|
|
112
|
+
*/
|
|
113
|
+
private isLeaderStale;
|
|
114
|
+
/**
|
|
115
|
+
* Get leader state from localStorage
|
|
116
|
+
*/
|
|
117
|
+
private getLeaderState;
|
|
118
|
+
/**
|
|
119
|
+
* Get session state from localStorage
|
|
120
|
+
*/
|
|
121
|
+
private getSessionState;
|
|
122
|
+
/**
|
|
123
|
+
* Generate session ID
|
|
124
|
+
*/
|
|
125
|
+
private generateSessionId;
|
|
126
|
+
/**
|
|
127
|
+
* Broadcast message to other tabs
|
|
128
|
+
*/
|
|
129
|
+
private broadcast;
|
|
130
|
+
/**
|
|
131
|
+
* Handle page unload - clean leader handoff
|
|
132
|
+
*/
|
|
133
|
+
private handleUnload;
|
|
134
|
+
/**
|
|
135
|
+
* Send log to leader (for follower tabs)
|
|
136
|
+
*/
|
|
137
|
+
sendLog(log: LogEntry): void;
|
|
138
|
+
/**
|
|
139
|
+
* Send rrweb event to leader (for follower tabs)
|
|
140
|
+
*/
|
|
141
|
+
sendRRWebEvent(event: TabAwareRRWebEvent): void;
|
|
142
|
+
/**
|
|
143
|
+
* Update session user info (stored in localStorage for all tabs)
|
|
144
|
+
*/
|
|
145
|
+
updateSessionUser(userId: string, traits?: Record<string, any>): void;
|
|
146
|
+
/**
|
|
147
|
+
* End session and clear shared state
|
|
148
|
+
*/
|
|
149
|
+
endSession(): void;
|
|
150
|
+
/**
|
|
151
|
+
* Get current tab ID
|
|
152
|
+
*/
|
|
153
|
+
getTabId(): string;
|
|
154
|
+
/**
|
|
155
|
+
* Get current session ID
|
|
156
|
+
*/
|
|
157
|
+
getSessionId(): string | null;
|
|
158
|
+
/**
|
|
159
|
+
* Check if this tab is the leader
|
|
160
|
+
*/
|
|
161
|
+
isLeaderTab(): boolean;
|
|
162
|
+
/**
|
|
163
|
+
* Check if multi-tab mode is active
|
|
164
|
+
*/
|
|
165
|
+
isActive(): boolean;
|
|
166
|
+
/**
|
|
167
|
+
* Clean up resources
|
|
168
|
+
*/
|
|
169
|
+
cleanup(): void;
|
|
170
|
+
/**
|
|
171
|
+
* Force become leader (for testing or recovery)
|
|
172
|
+
*/
|
|
173
|
+
forceLeadership(): void;
|
|
174
|
+
}
|
|
175
|
+
export declare const multiTabCoordinator: MultiTabCoordinator;
|
|
176
|
+
export type { MultiTabCallbacks, LeaderState, SessionState, MultiTabMessage };
|
package/sdk/index.d.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { LogEntry } from '../shared/types';
|
|
2
|
+
import { LogSpaceConfig, SDKSession, SessionPayload } from './types';
|
|
3
|
+
import { eventWithTime } from './capture/rrweb';
|
|
4
|
+
export declare const LogSpace: {
|
|
5
|
+
/**
|
|
6
|
+
* Initialize the SDK
|
|
7
|
+
*/
|
|
8
|
+
init(userConfig: LogSpaceConfig): void;
|
|
9
|
+
/**
|
|
10
|
+
* Start a new recording session
|
|
11
|
+
*/
|
|
12
|
+
startSession(metadata?: Record<string, any>): void;
|
|
13
|
+
/**
|
|
14
|
+
* Stop recording and send session to server
|
|
15
|
+
*/
|
|
16
|
+
stopSession(): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Identify user
|
|
19
|
+
*/
|
|
20
|
+
identify(userId: string, traits?: Record<string, any>): void;
|
|
21
|
+
/**
|
|
22
|
+
* Track custom event
|
|
23
|
+
*/
|
|
24
|
+
track(event: string, properties?: Record<string, any>): void;
|
|
25
|
+
/**
|
|
26
|
+
* Add breadcrumb
|
|
27
|
+
*/
|
|
28
|
+
breadcrumb(message: string, category?: string): void;
|
|
29
|
+
/**
|
|
30
|
+
* Pause recording
|
|
31
|
+
*/
|
|
32
|
+
pauseRecording(): void;
|
|
33
|
+
/**
|
|
34
|
+
* Resume recording
|
|
35
|
+
*/
|
|
36
|
+
resumeRecording(): void;
|
|
37
|
+
/**
|
|
38
|
+
* Manually trigger sampling (when sampling mode is enabled)
|
|
39
|
+
* Use this to mark a session as important even without an error
|
|
40
|
+
*/
|
|
41
|
+
trigger(reason?: string): void;
|
|
42
|
+
/**
|
|
43
|
+
* Get current session
|
|
44
|
+
*/
|
|
45
|
+
getSession(): SDKSession | null;
|
|
46
|
+
/**
|
|
47
|
+
* Get all logs for current session
|
|
48
|
+
*/
|
|
49
|
+
getSessionLogs(): LogEntry[];
|
|
50
|
+
/**
|
|
51
|
+
* Get session data (for local export without server)
|
|
52
|
+
*/
|
|
53
|
+
getSessionData(): SessionPayload | null;
|
|
54
|
+
/**
|
|
55
|
+
* Get rrweb events for current session
|
|
56
|
+
*/
|
|
57
|
+
getRRWebEvents(): eventWithTime[];
|
|
58
|
+
/**
|
|
59
|
+
* Destroy SDK
|
|
60
|
+
*/
|
|
61
|
+
destroy(): void;
|
|
62
|
+
/**
|
|
63
|
+
* SDK version
|
|
64
|
+
*/
|
|
65
|
+
version: string;
|
|
66
|
+
};
|
|
67
|
+
export type { LogSpaceConfig, NormalizedConfig, SDKSession, SessionPayload, CaptureConfig, PrivacyConfig, SessionLimits, SessionEndConfig, SamplingConfig, HooksConfig, LogSpacePlugin, } from './types';
|
|
68
|
+
export type { LogEntry, LogType, LogSeverity } from '../shared/types';
|
|
69
|
+
export default LogSpace;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { LogEntry } from '../../shared/types';
|
|
2
|
+
import { SessionPayload } from '../types';
|
|
3
|
+
import { eventWithTime } from 'rrweb';
|
|
4
|
+
interface StoredSession {
|
|
5
|
+
id: string;
|
|
6
|
+
data: SessionPayload;
|
|
7
|
+
createdAt: number;
|
|
8
|
+
retryCount: number;
|
|
9
|
+
lastRetryAt?: number;
|
|
10
|
+
}
|
|
11
|
+
interface CurrentSessionBackup {
|
|
12
|
+
id: string;
|
|
13
|
+
sessionId: string;
|
|
14
|
+
logs: LogEntry[];
|
|
15
|
+
rrwebEvents: eventWithTime[];
|
|
16
|
+
startTime: number;
|
|
17
|
+
url: string;
|
|
18
|
+
title: string;
|
|
19
|
+
userId?: string;
|
|
20
|
+
userTraits?: Record<string, any>;
|
|
21
|
+
metadata?: Record<string, any>;
|
|
22
|
+
lastCheckpoint: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Check if IndexedDB is available
|
|
26
|
+
*/
|
|
27
|
+
export declare function isIndexedDBAvailable(): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Save current session checkpoint to IndexedDB
|
|
30
|
+
* Called periodically to backup session data
|
|
31
|
+
*/
|
|
32
|
+
export declare function saveSessionCheckpoint(sessionId: string, logs: LogEntry[], rrwebEvents: eventWithTime[], sessionData: {
|
|
33
|
+
startTime: number;
|
|
34
|
+
url: string;
|
|
35
|
+
title: string;
|
|
36
|
+
userId?: string;
|
|
37
|
+
userTraits?: Record<string, any>;
|
|
38
|
+
metadata?: Record<string, any>;
|
|
39
|
+
}): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Get current session backup from IndexedDB
|
|
42
|
+
*/
|
|
43
|
+
export declare function getCurrentSessionBackup(): Promise<CurrentSessionBackup | null>;
|
|
44
|
+
/**
|
|
45
|
+
* Clear current session backup (called after successful send)
|
|
46
|
+
*/
|
|
47
|
+
export declare function clearCurrentSessionBackup(): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* Add a session to pending queue (for retry later)
|
|
50
|
+
*/
|
|
51
|
+
export declare function addPendingSession(payload: SessionPayload): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Get all pending sessions
|
|
54
|
+
*/
|
|
55
|
+
export declare function getPendingSessions(): Promise<StoredSession[]>;
|
|
56
|
+
/**
|
|
57
|
+
* Remove a pending session (after successful send)
|
|
58
|
+
*/
|
|
59
|
+
export declare function removePendingSession(sessionId: string): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Update retry count for a pending session
|
|
62
|
+
*/
|
|
63
|
+
export declare function updatePendingSessionRetry(sessionId: string): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Clean up old pending sessions (older than 7 days or too many retries)
|
|
66
|
+
*/
|
|
67
|
+
export declare function cleanupOldPendingSessions(): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Close database connection
|
|
70
|
+
*/
|
|
71
|
+
export declare function closeDB(): void;
|
|
72
|
+
export {};
|