@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/sdk/types.d.ts
ADDED
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
import { LogEntry, LogType, LogSeverity, SessionStats } from '../shared/types';
|
|
2
|
+
import { eventWithTime } from 'rrweb';
|
|
3
|
+
export type { LogEntry, LogType, LogSeverity, SessionStats };
|
|
4
|
+
export type { NetworkLog, ConsoleLog, ErrorLog, InteractionLog, PerformanceLog, WebSocketLog, SSELog, StorageLog, AnnotationLog, } from '../shared/types';
|
|
5
|
+
export type { eventWithTime };
|
|
6
|
+
/**
|
|
7
|
+
* Recording type - determines replay format
|
|
8
|
+
*/
|
|
9
|
+
export type RecordingType = 'video' | 'rrweb';
|
|
10
|
+
/**
|
|
11
|
+
* SDK Session state
|
|
12
|
+
*/
|
|
13
|
+
export interface SDKSession {
|
|
14
|
+
id: string;
|
|
15
|
+
startTime: number;
|
|
16
|
+
endTime?: number;
|
|
17
|
+
status: 'idle' | 'recording' | 'paused' | 'stopped';
|
|
18
|
+
userId?: string;
|
|
19
|
+
userTraits?: Record<string, any>;
|
|
20
|
+
metadata?: Record<string, any>;
|
|
21
|
+
stats: SessionStats;
|
|
22
|
+
url: string;
|
|
23
|
+
title: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Capture configuration - what to record
|
|
27
|
+
*/
|
|
28
|
+
export interface CaptureConfig {
|
|
29
|
+
/** Enable rrweb DOM recording for visual replay
|
|
30
|
+
* @default true
|
|
31
|
+
*/
|
|
32
|
+
rrweb?: boolean;
|
|
33
|
+
/** Capture console logs (log, info, warn, error, debug)
|
|
34
|
+
* @default true
|
|
35
|
+
*/
|
|
36
|
+
console?: boolean;
|
|
37
|
+
/** Capture network requests (XHR/Fetch)
|
|
38
|
+
* @default true
|
|
39
|
+
*/
|
|
40
|
+
network?: boolean;
|
|
41
|
+
/** Capture JavaScript errors
|
|
42
|
+
* @default true
|
|
43
|
+
*/
|
|
44
|
+
errors?: boolean;
|
|
45
|
+
/** Capture user interactions (clicks, inputs)
|
|
46
|
+
* @default true
|
|
47
|
+
*/
|
|
48
|
+
interactions?: boolean;
|
|
49
|
+
/** Capture performance metrics
|
|
50
|
+
* @default true
|
|
51
|
+
*/
|
|
52
|
+
performance?: boolean;
|
|
53
|
+
/** Capture WebSocket connections
|
|
54
|
+
* @default true
|
|
55
|
+
*/
|
|
56
|
+
websocket?: boolean;
|
|
57
|
+
/** Capture Server-Sent Events
|
|
58
|
+
* @default true
|
|
59
|
+
*/
|
|
60
|
+
sse?: boolean;
|
|
61
|
+
/** Capture localStorage/sessionStorage changes
|
|
62
|
+
* @default true
|
|
63
|
+
*/
|
|
64
|
+
storage?: boolean;
|
|
65
|
+
/** Capture resource loading (CSS, JS, images, fonts)
|
|
66
|
+
* @default true
|
|
67
|
+
*/
|
|
68
|
+
resources?: boolean;
|
|
69
|
+
/** Capture SPA route changes (History API, hash changes)
|
|
70
|
+
* @default true
|
|
71
|
+
*/
|
|
72
|
+
spaNavigation?: boolean;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* rrweb specific configuration
|
|
76
|
+
*/
|
|
77
|
+
export interface RRWebConfig {
|
|
78
|
+
/** Mask all text input values for privacy
|
|
79
|
+
* @default false
|
|
80
|
+
*/
|
|
81
|
+
maskAllInputs?: boolean;
|
|
82
|
+
/** Mask text content matching these CSS selectors
|
|
83
|
+
* @default undefined
|
|
84
|
+
*/
|
|
85
|
+
maskTextSelector?: string;
|
|
86
|
+
/** Block elements matching these CSS selectors from being recorded
|
|
87
|
+
* @default undefined
|
|
88
|
+
*/
|
|
89
|
+
blockSelector?: string;
|
|
90
|
+
/** Ignore elements matching these CSS selectors
|
|
91
|
+
* @default undefined
|
|
92
|
+
*/
|
|
93
|
+
ignoreSelector?: string;
|
|
94
|
+
/** Record canvas content (can be expensive)
|
|
95
|
+
* @default false
|
|
96
|
+
*/
|
|
97
|
+
recordCanvas?: boolean;
|
|
98
|
+
/** Take a full DOM snapshot every N events
|
|
99
|
+
* @default 200
|
|
100
|
+
*/
|
|
101
|
+
checkoutEveryNth?: number;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Privacy configuration
|
|
105
|
+
*/
|
|
106
|
+
export interface PrivacyConfig {
|
|
107
|
+
/** Mask PII patterns (emails, phones, SSN, credit cards)
|
|
108
|
+
* @default true
|
|
109
|
+
*/
|
|
110
|
+
maskSensitiveData?: boolean;
|
|
111
|
+
/** CSS selectors to always mask
|
|
112
|
+
* @default []
|
|
113
|
+
*/
|
|
114
|
+
maskSelectors?: string[];
|
|
115
|
+
/** URL patterns to exclude from logging (regex strings)
|
|
116
|
+
* @default []
|
|
117
|
+
*/
|
|
118
|
+
excludeUrls?: string[];
|
|
119
|
+
/** Network URL patterns to block request/response bodies
|
|
120
|
+
* @default []
|
|
121
|
+
*/
|
|
122
|
+
blockNetworkBodies?: string[];
|
|
123
|
+
/** Header names to always redact
|
|
124
|
+
* @default []
|
|
125
|
+
*/
|
|
126
|
+
redactHeaders?: string[];
|
|
127
|
+
/** Console log levels to capture
|
|
128
|
+
* @default ['log', 'info', 'warn', 'error', 'debug']
|
|
129
|
+
*/
|
|
130
|
+
logLevels?: LogSeverity[];
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Session limits - protection against infinite loops and memory issues
|
|
134
|
+
*/
|
|
135
|
+
export interface SessionLimits {
|
|
136
|
+
/** Maximum logs per session before auto-ending
|
|
137
|
+
* @default 10000
|
|
138
|
+
*/
|
|
139
|
+
maxLogs?: number;
|
|
140
|
+
/** Maximum session size in bytes before auto-ending
|
|
141
|
+
* @default 10485760 (10MB)
|
|
142
|
+
*/
|
|
143
|
+
maxSize?: number;
|
|
144
|
+
/** Maximum session duration in seconds before auto-ending
|
|
145
|
+
* @default 300 (5 minutes)
|
|
146
|
+
*/
|
|
147
|
+
maxDuration?: number;
|
|
148
|
+
/** Idle timeout in seconds - auto-end if no activity
|
|
149
|
+
* @default 30
|
|
150
|
+
*/
|
|
151
|
+
idleTimeout?: number;
|
|
152
|
+
/** Navigate away timeout in seconds - grace period when tab becomes hidden
|
|
153
|
+
* Session only ends after this period of being hidden (like switching tabs)
|
|
154
|
+
* @default 120 (2 minutes)
|
|
155
|
+
*/
|
|
156
|
+
navigateAwayTimeout?: number;
|
|
157
|
+
/** Rate limit - max logs per second (excess logs are dropped)
|
|
158
|
+
* @default 100
|
|
159
|
+
*/
|
|
160
|
+
rateLimit?: number;
|
|
161
|
+
/** Deduplicate consecutive identical logs
|
|
162
|
+
* @default true
|
|
163
|
+
*/
|
|
164
|
+
deduplicate?: boolean;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Session end triggers
|
|
168
|
+
*/
|
|
169
|
+
export interface SessionEndConfig {
|
|
170
|
+
/** Continue session across page refreshes instead of creating new sessions.
|
|
171
|
+
* When true, refreshing the page merges data into the same session.
|
|
172
|
+
* When false, each page load creates a new session.
|
|
173
|
+
* Note: Data is always saved to storage on page unload for reliability.
|
|
174
|
+
* @default true
|
|
175
|
+
*/
|
|
176
|
+
continueOnRefresh?: boolean;
|
|
177
|
+
/** Auto-end session on idle timeout
|
|
178
|
+
* @default true
|
|
179
|
+
*/
|
|
180
|
+
onIdle?: boolean;
|
|
181
|
+
/** Auto-end session when limits are reached
|
|
182
|
+
* @default true
|
|
183
|
+
*/
|
|
184
|
+
onLimitReached?: boolean;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Sampling configuration - only record sessions when specific events occur
|
|
188
|
+
* When enabled, the SDK keeps a rolling buffer and only sends sessions when triggered
|
|
189
|
+
*/
|
|
190
|
+
export interface SamplingConfig {
|
|
191
|
+
/** Enable sampling mode - only send sessions when triggered by errors or custom events
|
|
192
|
+
* @default false
|
|
193
|
+
*/
|
|
194
|
+
enabled?: boolean;
|
|
195
|
+
/** Seconds of logs to keep before the trigger event
|
|
196
|
+
* @default 15
|
|
197
|
+
*/
|
|
198
|
+
bufferBefore?: number;
|
|
199
|
+
/** Seconds to continue recording after the trigger event
|
|
200
|
+
* @default 15
|
|
201
|
+
*/
|
|
202
|
+
recordAfter?: number;
|
|
203
|
+
/** What triggers a session to be saved */
|
|
204
|
+
triggers?: {
|
|
205
|
+
/** Trigger on uncaught JavaScript errors
|
|
206
|
+
* @default true
|
|
207
|
+
*/
|
|
208
|
+
onError?: boolean;
|
|
209
|
+
/** Trigger on console.error calls
|
|
210
|
+
* @default true
|
|
211
|
+
*/
|
|
212
|
+
onConsoleError?: boolean;
|
|
213
|
+
/** Trigger on specific HTTP status codes (e.g., [500, 502, 503])
|
|
214
|
+
* @default [500, 502, 503, 504]
|
|
215
|
+
*/
|
|
216
|
+
onNetworkStatus?: number[];
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Lifecycle hooks
|
|
221
|
+
*/
|
|
222
|
+
export interface HooksConfig {
|
|
223
|
+
/** Called on every captured action
|
|
224
|
+
* @default undefined
|
|
225
|
+
*/
|
|
226
|
+
onAction?: (log: LogEntry, session: SDKSession) => void;
|
|
227
|
+
/** Transform/filter logs before sending - return null to drop all logs
|
|
228
|
+
* @default undefined
|
|
229
|
+
*/
|
|
230
|
+
beforeSend?: (logs: LogEntry[]) => LogEntry[] | null;
|
|
231
|
+
/** Called when session starts
|
|
232
|
+
* @default undefined
|
|
233
|
+
*/
|
|
234
|
+
onSessionStart?: (session: SDKSession) => void;
|
|
235
|
+
/** Called when session ends
|
|
236
|
+
* @default undefined
|
|
237
|
+
*/
|
|
238
|
+
onSessionEnd?: (session: SDKSession, logs: LogEntry[]) => void;
|
|
239
|
+
/** Called when session auto-ends due to limits
|
|
240
|
+
* @default undefined
|
|
241
|
+
*/
|
|
242
|
+
onLimitReached?: (reason: 'maxLogs' | 'maxSize' | 'maxDuration' | 'idle') => void;
|
|
243
|
+
/** Called when sampling is triggered (error detected)
|
|
244
|
+
* @default undefined
|
|
245
|
+
*/
|
|
246
|
+
onSamplingTrigger?: (trigger: 'error' | 'consoleError' | 'networkError' | 'manual', log?: LogEntry) => void;
|
|
247
|
+
/** Called on transport/network errors
|
|
248
|
+
* @default undefined
|
|
249
|
+
*/
|
|
250
|
+
onError?: (error: Error) => void;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Main SDK configuration - all fields are optional
|
|
254
|
+
*/
|
|
255
|
+
export interface LogSpaceConfig {
|
|
256
|
+
/** Server URL for sending sessions. If not provided, sessions are stored locally only.
|
|
257
|
+
* @default undefined
|
|
258
|
+
*/
|
|
259
|
+
serverUrl?: string;
|
|
260
|
+
/** API key in format 'project_id:environment_id' for authentication
|
|
261
|
+
* @default undefined
|
|
262
|
+
*/
|
|
263
|
+
apiKey?: string;
|
|
264
|
+
/** Configure what to capture (console, network, errors, etc.)
|
|
265
|
+
* @default All capture options enabled (true)
|
|
266
|
+
*/
|
|
267
|
+
capture?: CaptureConfig;
|
|
268
|
+
/** rrweb DOM recording settings
|
|
269
|
+
* @default { maskAllInputs: false, recordCanvas: false, checkoutEveryNth: 200 }
|
|
270
|
+
*/
|
|
271
|
+
rrweb?: RRWebConfig;
|
|
272
|
+
/** Privacy settings for masking sensitive data
|
|
273
|
+
* @default { maskSensitiveData: true, maskSelectors: [], excludeUrls: [], blockNetworkBodies: [], redactHeaders: [], logLevels: ['log', 'info', 'warn', 'error', 'debug'] }
|
|
274
|
+
*/
|
|
275
|
+
privacy?: PrivacyConfig;
|
|
276
|
+
/** Session limits for protection against memory issues
|
|
277
|
+
* @default { maxLogs: 10000, maxSize: 10485760, maxDuration: 300, idleTimeout: 30, rateLimit: 100, deduplicate: true }
|
|
278
|
+
*/
|
|
279
|
+
limits?: SessionLimits;
|
|
280
|
+
/** Configure when to auto-end sessions
|
|
281
|
+
* @default { continueOnRefresh: true, onIdle: true, onLimitReached: true }
|
|
282
|
+
*/
|
|
283
|
+
autoEnd?: SessionEndConfig;
|
|
284
|
+
/** Sampling configuration - only save sessions when errors occur
|
|
285
|
+
* When enabled, keeps a rolling buffer and only sends when triggered by errors
|
|
286
|
+
* @default { enabled: false }
|
|
287
|
+
*/
|
|
288
|
+
sampling?: SamplingConfig;
|
|
289
|
+
/** Lifecycle hooks for customizing behavior
|
|
290
|
+
* @default All hooks undefined
|
|
291
|
+
*/
|
|
292
|
+
hooks?: HooksConfig;
|
|
293
|
+
/** Custom headers to include in API requests
|
|
294
|
+
* @default {}
|
|
295
|
+
*/
|
|
296
|
+
headers?: Record<string, string>;
|
|
297
|
+
/** Enable debug logging to console
|
|
298
|
+
* @default false
|
|
299
|
+
*/
|
|
300
|
+
debug?: boolean;
|
|
301
|
+
/** Dry run mode - log payload instead of sending (for testing)
|
|
302
|
+
* @default false
|
|
303
|
+
*/
|
|
304
|
+
dryRun?: boolean;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Normalized config with all defaults applied
|
|
308
|
+
*/
|
|
309
|
+
export interface NormalizedConfig {
|
|
310
|
+
serverUrl?: string;
|
|
311
|
+
apiKey?: string;
|
|
312
|
+
capture: Required<CaptureConfig>;
|
|
313
|
+
rrweb: RRWebConfig;
|
|
314
|
+
privacy: Required<PrivacyConfig>;
|
|
315
|
+
limits: Required<SessionLimits>;
|
|
316
|
+
autoEnd: Required<SessionEndConfig>;
|
|
317
|
+
sampling: Required<Omit<SamplingConfig, 'triggers'>> & {
|
|
318
|
+
triggers: Required<NonNullable<SamplingConfig['triggers']>>;
|
|
319
|
+
};
|
|
320
|
+
hooks: HooksConfig;
|
|
321
|
+
headers: Record<string, string>;
|
|
322
|
+
debug: boolean;
|
|
323
|
+
dryRun: boolean;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Session payload sent to server
|
|
327
|
+
*/
|
|
328
|
+
export interface SessionPayload {
|
|
329
|
+
id: string;
|
|
330
|
+
startTime: number;
|
|
331
|
+
endTime: number;
|
|
332
|
+
duration: number;
|
|
333
|
+
url: string;
|
|
334
|
+
title: string;
|
|
335
|
+
userId?: string;
|
|
336
|
+
userTraits?: Record<string, any>;
|
|
337
|
+
metadata?: Record<string, any>;
|
|
338
|
+
logs: LogEntry[];
|
|
339
|
+
stats: SessionStats;
|
|
340
|
+
endReason: 'manual' | 'unload' | 'idle' | 'navigateAway' | 'maxLogs' | 'maxSize' | 'maxDuration' | 'samplingTriggered' | 'crash';
|
|
341
|
+
/** Recording type - 'rrweb' for SDK, 'video' for extension */
|
|
342
|
+
recordingType: RecordingType;
|
|
343
|
+
/** rrweb DOM events for visual replay (SDK only) */
|
|
344
|
+
rrwebEvents?: eventWithTime[];
|
|
345
|
+
/** What triggered the sampling (only present when sampling is enabled) */
|
|
346
|
+
samplingTrigger?: 'error' | 'consoleError' | 'networkError' | 'manual';
|
|
347
|
+
/** User agent string */
|
|
348
|
+
userAgent?: string;
|
|
349
|
+
/** SDK version */
|
|
350
|
+
sdkVersion?: string;
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Public SDK interface
|
|
354
|
+
*/
|
|
355
|
+
export interface LogSpaceSDK {
|
|
356
|
+
/** Initialize the SDK */
|
|
357
|
+
init(config: LogSpaceConfig): void;
|
|
358
|
+
/** Identify user */
|
|
359
|
+
identify(userId: string, traits?: Record<string, any>): void;
|
|
360
|
+
/** Track custom event */
|
|
361
|
+
track(event: string, properties?: Record<string, any>): void;
|
|
362
|
+
/** Add breadcrumb */
|
|
363
|
+
breadcrumb(message: string, category?: string): void;
|
|
364
|
+
/** Start recording session */
|
|
365
|
+
startSession(metadata?: Record<string, any>): void;
|
|
366
|
+
/** Stop recording session and send to server */
|
|
367
|
+
stopSession(): Promise<void>;
|
|
368
|
+
/** Pause recording */
|
|
369
|
+
pauseRecording(): void;
|
|
370
|
+
/** Resume recording */
|
|
371
|
+
resumeRecording(): void;
|
|
372
|
+
/** Get current session */
|
|
373
|
+
getSession(): SDKSession | null;
|
|
374
|
+
/** Get all logs for current session */
|
|
375
|
+
getSessionLogs(): LogEntry[];
|
|
376
|
+
/** Get session data (for local export without server) */
|
|
377
|
+
getSessionData(): SessionPayload | null;
|
|
378
|
+
/** Destroy SDK and cleanup */
|
|
379
|
+
destroy(): void;
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Plugin interface for extending SDK
|
|
383
|
+
*/
|
|
384
|
+
export interface LogSpacePlugin {
|
|
385
|
+
name: string;
|
|
386
|
+
setup(sdk: LogSpaceSDK, config: NormalizedConfig): void;
|
|
387
|
+
teardown?(): void;
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Internal capture handler type
|
|
391
|
+
* Accepts partial log data, SDK adds id/timestamp/tabId/tabUrl
|
|
392
|
+
*/
|
|
393
|
+
export type CaptureHandler = (log: {
|
|
394
|
+
type: LogEntry['type'];
|
|
395
|
+
data: any;
|
|
396
|
+
severity?: LogEntry['severity'];
|
|
397
|
+
}) => void;
|
|
398
|
+
/**
|
|
399
|
+
* Rate limiter state
|
|
400
|
+
*/
|
|
401
|
+
export interface RateLimiterState {
|
|
402
|
+
count: number;
|
|
403
|
+
windowStart: number;
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Deduplication state
|
|
407
|
+
*/
|
|
408
|
+
export interface DeduplicationState {
|
|
409
|
+
lastLogHash: string | null;
|
|
410
|
+
lastLogCount: number;
|
|
411
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { default as Browser } from 'webextension-polyfill';
|
|
2
|
+
/**
|
|
3
|
+
* Cross-browser API namespace
|
|
4
|
+
* Uses webextension-polyfill for Firefox/Safari compatibility
|
|
5
|
+
* Falls back to chrome namespace if polyfill not available
|
|
6
|
+
*/
|
|
7
|
+
export declare const browser: typeof Browser;
|
|
8
|
+
export interface BrowserCapabilities {
|
|
9
|
+
hasTabCapture: boolean;
|
|
10
|
+
hasDisplayMedia: boolean;
|
|
11
|
+
hasOffscreenDocuments: boolean;
|
|
12
|
+
hasMediaRecorder: boolean;
|
|
13
|
+
recommendedMode: 'auto' | 'fullscreen' | 'custom';
|
|
14
|
+
browserName: string;
|
|
15
|
+
isChromium: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Detect browser capabilities
|
|
19
|
+
*/
|
|
20
|
+
export declare function detectBrowserCapabilities(): BrowserCapabilities;
|
|
21
|
+
/**
|
|
22
|
+
* Get user-friendly description for capture mode
|
|
23
|
+
*/
|
|
24
|
+
export declare function getCaptureModeDescription(mode: 'auto' | 'fullscreen' | 'custom'): string;
|
|
25
|
+
/**
|
|
26
|
+
* Check if a capture mode is available in current browser
|
|
27
|
+
*/
|
|
28
|
+
export declare function isCaptureModeAvailable(mode: 'auto' | 'fullscreen' | 'custom'): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Get list of available capture modes for UI
|
|
31
|
+
*/
|
|
32
|
+
export declare function getAvailableCaptureModes(): Array<{
|
|
33
|
+
mode: 'auto' | 'fullscreen' | 'custom';
|
|
34
|
+
label: string;
|
|
35
|
+
description: string;
|
|
36
|
+
icon: string;
|
|
37
|
+
available: boolean;
|
|
38
|
+
}>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { CaptureMode } from './types';
|
|
2
|
+
export interface DisplayMediaOptions {
|
|
3
|
+
mode: 'fullscreen' | 'tab' | 'custom';
|
|
4
|
+
preferCurrentTab?: boolean;
|
|
5
|
+
frameRate?: number;
|
|
6
|
+
videoQuality?: 'low' | 'medium' | 'high';
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Request display media capture from user
|
|
10
|
+
* This must be called from a user gesture (e.g., button click)
|
|
11
|
+
*/
|
|
12
|
+
export declare function requestDisplayMedia(options: DisplayMediaOptions): Promise<MediaStream>;
|
|
13
|
+
/**
|
|
14
|
+
* Transfer MediaStream to offscreen for recording
|
|
15
|
+
* Since we can't serialize MediaStream, we'll use a different approach:
|
|
16
|
+
* Store the stream globally and let offscreen access it
|
|
17
|
+
*/
|
|
18
|
+
export declare function transferStreamToBackground(stream: MediaStream, sessionId: string, mode: CaptureMode): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Alternative: Create offscreen document to handle getDisplayMedia
|
|
21
|
+
* This avoids stream transfer issues by letting offscreen handle everything
|
|
22
|
+
*/
|
|
23
|
+
export declare function requestOffscreenDisplayMedia(sessionId: string, mode: 'fullscreen' | 'tab' | 'custom'): Promise<void>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { RecordingSession } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Export session data as a .zip file containing:
|
|
4
|
+
* - session.json: Session metadata and logs (compressed)
|
|
5
|
+
* - video.webm: Recorded video (if available)
|
|
6
|
+
*/
|
|
7
|
+
export declare function exportSession(session: RecordingSession): Promise<void>;
|
|
8
|
+
/**
|
|
9
|
+
* Export session as separate JSON file (no video)
|
|
10
|
+
*/
|
|
11
|
+
export declare function exportSessionJSON(session: RecordingSession): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Export video only
|
|
14
|
+
*/
|
|
15
|
+
export declare function exportSessionVideo(sessionId: string): Promise<void>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { LogEntry } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Optimized log entry for storage (normalized)
|
|
4
|
+
*/
|
|
5
|
+
export interface OptimizedLogEntry {
|
|
6
|
+
id: string;
|
|
7
|
+
ts: number;
|
|
8
|
+
type: string;
|
|
9
|
+
data: any;
|
|
10
|
+
sev?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Session context stored once per session
|
|
14
|
+
*/
|
|
15
|
+
export interface SessionContext {
|
|
16
|
+
id: string;
|
|
17
|
+
startTime: number;
|
|
18
|
+
tabs: Record<number, TabContext>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Tab context stored once per tab
|
|
22
|
+
*/
|
|
23
|
+
export interface TabContext {
|
|
24
|
+
url: string;
|
|
25
|
+
title: string;
|
|
26
|
+
startTime: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Optimize log entry for storage
|
|
30
|
+
* Removes redundant fields that can be inferred from context
|
|
31
|
+
*/
|
|
32
|
+
export declare function optimizeLog(log: LogEntry, sessionId: string): OptimizedLogEntry;
|
|
33
|
+
/**
|
|
34
|
+
* Denormalize log entry for export/usage
|
|
35
|
+
* Restores the full LogEntry structure with context
|
|
36
|
+
*/
|
|
37
|
+
export declare function denormalizeLog(optimized: OptimizedLogEntry | any, // Accept any to handle stored format
|
|
38
|
+
sessionId: string, tabId: number, tabUrl: string): LogEntry;
|
|
39
|
+
/**
|
|
40
|
+
* Calculate storage savings
|
|
41
|
+
*/
|
|
42
|
+
export declare function calculateSavings(original: LogEntry[], optimized: OptimizedLogEntry[]): {
|
|
43
|
+
originalSize: number;
|
|
44
|
+
optimizedSize: number;
|
|
45
|
+
savingsBytes: number;
|
|
46
|
+
savingsPercent: number;
|
|
47
|
+
};
|