@sailfish-ai/recorder 1.8.12 → 1.8.15
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/graphql.js +7 -0
- package/dist/index.js +30 -4
- package/dist/recorder.cjs +802 -772
- package/dist/recorder.js +805 -772
- package/dist/recorder.js.br +0 -0
- package/dist/recorder.js.gz +0 -0
- package/dist/recorder.umd.cjs +802 -772
- package/dist/types/graphql.d.ts +2 -1
- package/dist/types/types.d.ts +3 -0
- package/dist/types/websocket.d.ts +10 -0
- package/dist/websocket.js +149 -71
- package/package.json +2 -2
package/dist/types/graphql.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { CaptureSettingsResponse, CreateTriageResponse, GraphQLResponse, StartSessionResponse } from "./types";
|
|
1
|
+
import { CaptureSettingsResponse, CreateTriageResponse, FunctionSpanTrackingEnabledResponse, GraphQLResponse, StartSessionResponse } from "./types";
|
|
2
2
|
export declare function sendGraphQLRequest<T>(operationName: string, query: string, variables: object, retries?: number, // Number of retries before giving up
|
|
3
3
|
initialBackoff?: number, // Initial backoff in milliseconds
|
|
4
4
|
backoffFactor?: number): Promise<GraphQLResponse<T>>;
|
|
5
5
|
export declare function fetchCaptureSettings(apiKey: string, backendApi: string): Promise<GraphQLResponse<CaptureSettingsResponse>>;
|
|
6
|
+
export declare function fetchFunctionSpanTrackingEnabled(apiKey: string, backendApi: string): Promise<GraphQLResponse<FunctionSpanTrackingEnabledResponse>>;
|
|
6
7
|
export declare function startRecordingSession(apiKey: string, recordingId: string, backendApi: string, serviceIdentifier: string, serviceVersion?: string, mapUuid?: string, gitSha?: string, library?: string, serviceAdditionalMetadata?: Record<string, any>): Promise<GraphQLResponse<StartSessionResponse>>;
|
|
7
8
|
export declare function sendDomainsToNotPropagateHeaderTo(apiKey: string, domains: string[], backendApi: string): Promise<GraphQLResponse<void>>;
|
|
8
9
|
export declare function createTriageFromRecorder(apiKey: string, backendApi: string, recordingSessionId: string, timestampStart: string, timestampEnd: string, description?: string): Promise<GraphQLResponse<CreateTriageResponse>>;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -46,6 +46,9 @@ export interface GraphQLResponse<T> {
|
|
|
46
46
|
export interface CaptureSettingsResponse {
|
|
47
47
|
captureSettingsFromApiKey: CaptureSettings;
|
|
48
48
|
}
|
|
49
|
+
export interface FunctionSpanTrackingEnabledResponse {
|
|
50
|
+
isFunctionSpanTrackingEnabledFromApiKey: boolean;
|
|
51
|
+
}
|
|
49
52
|
export interface StartSessionResponse {
|
|
50
53
|
startRecordingSession: {
|
|
51
54
|
id: string;
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import ReconnectingWebSocket from "reconnecting-websocket";
|
|
2
|
+
/**
|
|
3
|
+
* Clear stale function span tracking state (called from index.tsx to validate localStorage)
|
|
4
|
+
* This disables tracking and clears localStorage if backend says tracking is not active
|
|
5
|
+
*/
|
|
6
|
+
export declare function clearStaleFuncSpanState(): void;
|
|
2
7
|
export declare function flushBufferedEvents(): Promise<void>;
|
|
3
8
|
export declare function sendEvent(event: any): void;
|
|
4
9
|
export declare function initializeWebSocket(backendApi: string, apiKey: string, sessionId: string, envValue?: string): ReconnectingWebSocket;
|
|
@@ -17,6 +22,11 @@ export declare function disableFunctionSpanTracking(): void;
|
|
|
17
22
|
* Check if function span tracking is currently enabled
|
|
18
23
|
*/
|
|
19
24
|
export declare function isFunctionSpanTrackingEnabled(): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Initialize function span tracking state from API response (during page load)
|
|
27
|
+
* This is called before the WebSocket connects to ensure headers are added from the start
|
|
28
|
+
*/
|
|
29
|
+
export declare function initializeFunctionSpanTrackingFromApi(isEnabled: boolean): void;
|
|
20
30
|
/**
|
|
21
31
|
* Get the current funcspan header name and value
|
|
22
32
|
* Header constants are defined here but used by HTTP interceptors in index.tsx
|
package/dist/websocket.js
CHANGED
|
@@ -10,16 +10,28 @@ const MAX_MESSAGE_SIZE_MB = 50;
|
|
|
10
10
|
const MAX_MESSAGE_SIZE_BYTES = MAX_MESSAGE_SIZE_MB * 1024 * 1024;
|
|
11
11
|
// Function span tracking header constants
|
|
12
12
|
const FUNCSPAN_HEADER_NAME = "X-Sf3-FunctionSpanCaptureOverride";
|
|
13
|
-
const FUNCSPAN_HEADER_VALUE = "1-
|
|
13
|
+
const FUNCSPAN_HEADER_VALUE = "1-1-10-10-1-1.0-1-0-0";
|
|
14
14
|
// Tracking configuration type constants (must match backend TrackingConfigurationType enum)
|
|
15
15
|
const TRACKING_CONFIG_GLOBAL = "global";
|
|
16
16
|
const TRACKING_CONFIG_PER_SESSION = "per_session";
|
|
17
|
-
// localStorage key for persisting global function span tracking state
|
|
18
|
-
const FUNCSPAN_GLOBAL_STATE_KEY = "sailfish_funcspan_global_state";
|
|
19
17
|
let webSocket = null;
|
|
20
18
|
let isDraining = false;
|
|
21
19
|
let inFlightFlush = null;
|
|
22
20
|
let flushIntervalId = null;
|
|
21
|
+
// Function span tracking state (only manages enabled/disabled)
|
|
22
|
+
let funcSpanTrackingEnabled = false;
|
|
23
|
+
let funcSpanTimeoutId = null;
|
|
24
|
+
let funcSpanExpirationTime = null; // Timestamp when tracking should expire (milliseconds)
|
|
25
|
+
let isLocalTrackingMode = false; // True when tracking is enabled locally (Report Issue), not globally
|
|
26
|
+
// Saved global state when switching to local mode
|
|
27
|
+
let savedGlobalTimeoutId = null;
|
|
28
|
+
let savedGlobalExpirationTime = null;
|
|
29
|
+
// LocalStorage key for persisting global function span tracking state
|
|
30
|
+
const FUNCSPAN_STORAGE_KEY = "sailfish_funcspan_global_state";
|
|
31
|
+
/**
|
|
32
|
+
* Save global function span tracking state to localStorage
|
|
33
|
+
* This persists the state across page refreshes
|
|
34
|
+
*/
|
|
23
35
|
function saveGlobalFuncSpanState(enabled, expirationTimestampMs) {
|
|
24
36
|
try {
|
|
25
37
|
if (typeof localStorage === "undefined")
|
|
@@ -27,73 +39,73 @@ function saveGlobalFuncSpanState(enabled, expirationTimestampMs) {
|
|
|
27
39
|
const state = {
|
|
28
40
|
enabled,
|
|
29
41
|
expirationTimestampMs,
|
|
42
|
+
savedAt: Date.now(),
|
|
30
43
|
};
|
|
31
|
-
localStorage.setItem(
|
|
44
|
+
localStorage.setItem(FUNCSPAN_STORAGE_KEY, JSON.stringify(state));
|
|
32
45
|
if (DEBUG) {
|
|
33
|
-
console.log(
|
|
46
|
+
console.log("[Sailfish] Saved funcSpan state to localStorage:", state);
|
|
34
47
|
}
|
|
35
48
|
}
|
|
36
49
|
catch (e) {
|
|
37
50
|
if (DEBUG) {
|
|
38
|
-
console.warn(
|
|
51
|
+
console.warn("[Sailfish] Failed to save funcSpan state to localStorage:", e);
|
|
39
52
|
}
|
|
40
53
|
}
|
|
41
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Load global function span tracking state from localStorage
|
|
57
|
+
*/
|
|
42
58
|
function loadGlobalFuncSpanState() {
|
|
43
59
|
try {
|
|
44
60
|
if (typeof localStorage === "undefined")
|
|
45
61
|
return null;
|
|
46
|
-
const stored = localStorage.getItem(
|
|
62
|
+
const stored = localStorage.getItem(FUNCSPAN_STORAGE_KEY);
|
|
47
63
|
if (!stored)
|
|
48
64
|
return null;
|
|
49
65
|
const state = JSON.parse(stored);
|
|
50
|
-
// Check if the stored state has expired
|
|
51
|
-
if (state.enabled && state.expirationTimestampMs) {
|
|
52
|
-
const now = Date.now();
|
|
53
|
-
if (now >= state.expirationTimestampMs) {
|
|
54
|
-
// Expired - clear localStorage and return null
|
|
55
|
-
if (DEBUG) {
|
|
56
|
-
console.log(`[Sailfish] Stored global function span state has expired, clearing`);
|
|
57
|
-
}
|
|
58
|
-
localStorage.removeItem(FUNCSPAN_GLOBAL_STATE_KEY);
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
66
|
if (DEBUG) {
|
|
63
|
-
console.log(
|
|
67
|
+
console.log("[Sailfish] Loaded funcSpan state from localStorage:", state);
|
|
64
68
|
}
|
|
65
69
|
return state;
|
|
66
70
|
}
|
|
67
71
|
catch (e) {
|
|
68
72
|
if (DEBUG) {
|
|
69
|
-
console.warn(
|
|
73
|
+
console.warn("[Sailfish] Failed to load funcSpan state from localStorage:", e);
|
|
70
74
|
}
|
|
71
75
|
return null;
|
|
72
76
|
}
|
|
73
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Clear global function span tracking state from localStorage
|
|
80
|
+
*/
|
|
74
81
|
function clearGlobalFuncSpanState() {
|
|
75
82
|
try {
|
|
76
83
|
if (typeof localStorage === "undefined")
|
|
77
84
|
return;
|
|
78
|
-
localStorage.removeItem(
|
|
85
|
+
localStorage.removeItem(FUNCSPAN_STORAGE_KEY);
|
|
79
86
|
if (DEBUG) {
|
|
80
|
-
console.log(
|
|
87
|
+
console.log("[Sailfish] Cleared funcSpan state from localStorage");
|
|
81
88
|
}
|
|
82
89
|
}
|
|
83
90
|
catch (e) {
|
|
84
91
|
if (DEBUG) {
|
|
85
|
-
console.warn(
|
|
92
|
+
console.warn("[Sailfish] Failed to clear funcSpan state from localStorage:", e);
|
|
86
93
|
}
|
|
87
94
|
}
|
|
88
95
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
96
|
+
/**
|
|
97
|
+
* Clear stale function span tracking state (called from index.tsx to validate localStorage)
|
|
98
|
+
* This disables tracking and clears localStorage if backend says tracking is not active
|
|
99
|
+
*/
|
|
100
|
+
export function clearStaleFuncSpanState() {
|
|
101
|
+
funcSpanTrackingEnabled = false;
|
|
102
|
+
funcSpanExpirationTime = null;
|
|
103
|
+
isLocalTrackingMode = false;
|
|
104
|
+
clearGlobalFuncSpanState();
|
|
105
|
+
if (DEBUG) {
|
|
106
|
+
console.log("[Sailfish] Cleared stale function span tracking state (backend validation failed)");
|
|
107
|
+
}
|
|
108
|
+
}
|
|
97
109
|
// Load persisted global state immediately on module initialization
|
|
98
110
|
// This ensures headers are added from the very first HTTP request, even before WebSocket connects
|
|
99
111
|
(() => {
|
|
@@ -105,9 +117,34 @@ let savedGlobalExpirationTime = null;
|
|
|
105
117
|
if (DEBUG) {
|
|
106
118
|
console.log(`[Sailfish] Module init: Restored global function span tracking from localStorage:`, {
|
|
107
119
|
enabled: true,
|
|
108
|
-
|
|
120
|
+
expirationTime: funcSpanExpirationTime,
|
|
109
121
|
});
|
|
110
122
|
}
|
|
123
|
+
// Check if tracking has already expired
|
|
124
|
+
if (funcSpanExpirationTime !== null) {
|
|
125
|
+
const now = Date.now();
|
|
126
|
+
if (now >= funcSpanExpirationTime) {
|
|
127
|
+
// Already expired, clear it
|
|
128
|
+
funcSpanTrackingEnabled = false;
|
|
129
|
+
funcSpanExpirationTime = null;
|
|
130
|
+
clearGlobalFuncSpanState();
|
|
131
|
+
if (DEBUG) {
|
|
132
|
+
console.log("[Sailfish] Module init: Persisted tracking already expired, cleared state");
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
// State is still valid, keep it temporarily until WebSocket provides the true state
|
|
137
|
+
if (DEBUG) {
|
|
138
|
+
console.log("[Sailfish] Module init: Function span tracking is active and valid (temporary until WebSocket confirms)");
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
// No expiration time - keep enabled temporarily until WebSocket provides the true state
|
|
144
|
+
if (DEBUG) {
|
|
145
|
+
console.log("[Sailfish] Module init: Function span tracking is active (no expiration, temporary until WebSocket confirms)");
|
|
146
|
+
}
|
|
147
|
+
}
|
|
111
148
|
}
|
|
112
149
|
})();
|
|
113
150
|
function isWebSocketOpen(ws) {
|
|
@@ -204,9 +241,6 @@ export function sendEvent(event) {
|
|
|
204
241
|
}
|
|
205
242
|
}
|
|
206
243
|
export function initializeWebSocket(backendApi, apiKey, sessionId, envValue) {
|
|
207
|
-
// Note: Global function span tracking state is now loaded at module initialization time
|
|
208
|
-
// (see IIFE above) so headers work immediately, even before WebSocket connects.
|
|
209
|
-
// The WebSocket "funcSpanTrackingControl" message will update the state if needed.
|
|
210
244
|
const wsHost = getWebSocketHost(backendApi);
|
|
211
245
|
const apiProtocol = new URL(backendApi).protocol;
|
|
212
246
|
const wsScheme = apiProtocol === "https:" ? "wss" : "ws";
|
|
@@ -222,7 +256,7 @@ export function initializeWebSocket(backendApi, apiKey, sessionId, envValue) {
|
|
|
222
256
|
webSocket.addEventListener("open", () => {
|
|
223
257
|
if (DEBUG) {
|
|
224
258
|
console.log("[Sailfish] WebSocket connection opened");
|
|
225
|
-
console.log(`[Sailfish] Function span tracking state: ${funcSpanTrackingEnabled ?
|
|
259
|
+
console.log(`[Sailfish] Function span tracking state: ${funcSpanTrackingEnabled ? "ENABLED" : "DISABLED"}`);
|
|
226
260
|
}
|
|
227
261
|
(async () => {
|
|
228
262
|
try {
|
|
@@ -255,7 +289,7 @@ export function initializeWebSocket(backendApi, apiKey, sessionId, envValue) {
|
|
|
255
289
|
console.log(`[Sailfish] Received funcSpanTrackingControl message:`, {
|
|
256
290
|
enabled: data.enabled,
|
|
257
291
|
timeoutSeconds: data.timeoutSeconds,
|
|
258
|
-
expirationTimestampMs: data.expirationTimestampMs
|
|
292
|
+
expirationTimestampMs: data.expirationTimestampMs,
|
|
259
293
|
});
|
|
260
294
|
}
|
|
261
295
|
// Clear any existing timeout
|
|
@@ -267,7 +301,7 @@ export function initializeWebSocket(backendApi, apiKey, sessionId, envValue) {
|
|
|
267
301
|
funcSpanTrackingEnabled = data.enabled;
|
|
268
302
|
isLocalTrackingMode = false; // Mark as global tracking, not local
|
|
269
303
|
if (DEBUG) {
|
|
270
|
-
console.log(`[Sailfish] Function span tracking ${data.enabled ?
|
|
304
|
+
console.log(`[Sailfish] Function span tracking ${data.enabled ? "ENABLED (GLOBAL)" : "DISABLED (GLOBAL)"}`);
|
|
271
305
|
}
|
|
272
306
|
if (data.enabled) {
|
|
273
307
|
// Use server-provided expiration timestamp for synchronization across all clients/pods
|
|
@@ -293,6 +327,25 @@ export function initializeWebSocket(backendApi, apiKey, sessionId, envValue) {
|
|
|
293
327
|
if (DEBUG) {
|
|
294
328
|
console.log(`[Sailfish] GLOBAL function span tracking auto-disabled at server expiration time`);
|
|
295
329
|
}
|
|
330
|
+
// Notify backend that this client's tracking has expired
|
|
331
|
+
// Backend will update database and broadcast to all other clients
|
|
332
|
+
try {
|
|
333
|
+
if (isWebSocketOpen(webSocket)) {
|
|
334
|
+
webSocket.send(JSON.stringify({
|
|
335
|
+
type: "funcSpanTrackingExpired",
|
|
336
|
+
sessionId: getOrSetSessionId(),
|
|
337
|
+
expiredAt: Date.now(),
|
|
338
|
+
}));
|
|
339
|
+
if (DEBUG) {
|
|
340
|
+
console.log(`[Sailfish] Notified backend that function span tracking expired`);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
catch (e) {
|
|
345
|
+
if (DEBUG) {
|
|
346
|
+
console.warn(`[Sailfish] Failed to notify backend of tracking expiry:`, e);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
296
349
|
}
|
|
297
350
|
}, msUntilExpiration);
|
|
298
351
|
}
|
|
@@ -311,7 +364,7 @@ export function initializeWebSocket(backendApi, apiKey, sessionId, envValue) {
|
|
|
311
364
|
// Fallback: no server timestamp provided, use local calculation (legacy behavior)
|
|
312
365
|
const timeoutSeconds = data.timeoutSeconds || 3600; // Default 1 hour
|
|
313
366
|
if (timeoutSeconds > 0) {
|
|
314
|
-
funcSpanExpirationTime = Date.now() +
|
|
367
|
+
funcSpanExpirationTime = Date.now() + timeoutSeconds * 1000;
|
|
315
368
|
// Save to localStorage for persistence across page refreshes
|
|
316
369
|
saveGlobalFuncSpanState(true, funcSpanExpirationTime);
|
|
317
370
|
funcSpanTimeoutId = window.setTimeout(() => {
|
|
@@ -323,6 +376,24 @@ export function initializeWebSocket(backendApi, apiKey, sessionId, envValue) {
|
|
|
323
376
|
if (DEBUG) {
|
|
324
377
|
console.log(`[Sailfish] GLOBAL function span tracking auto-disabled after ${timeoutSeconds}s (legacy)`);
|
|
325
378
|
}
|
|
379
|
+
// Notify backend that this client's tracking has expired
|
|
380
|
+
try {
|
|
381
|
+
if (isWebSocketOpen(webSocket)) {
|
|
382
|
+
webSocket.send(JSON.stringify({
|
|
383
|
+
type: "funcSpanTrackingExpired",
|
|
384
|
+
sessionId: getOrSetSessionId(),
|
|
385
|
+
expiredAt: Date.now(),
|
|
386
|
+
}));
|
|
387
|
+
if (DEBUG) {
|
|
388
|
+
console.log(`[Sailfish] Notified backend that function span tracking expired (legacy timeout)`);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
catch (e) {
|
|
393
|
+
if (DEBUG) {
|
|
394
|
+
console.warn(`[Sailfish] Failed to notify backend of tracking expiry:`, e);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
326
397
|
}
|
|
327
398
|
}, timeoutSeconds * 1000);
|
|
328
399
|
}
|
|
@@ -335,7 +406,7 @@ export function initializeWebSocket(backendApi, apiKey, sessionId, envValue) {
|
|
|
335
406
|
type: "funcSpanTrackingSessionReport",
|
|
336
407
|
sessionId: sessionId,
|
|
337
408
|
enabled: true,
|
|
338
|
-
configurationType: TRACKING_CONFIG_GLOBAL
|
|
409
|
+
configurationType: TRACKING_CONFIG_GLOBAL,
|
|
339
410
|
}));
|
|
340
411
|
if (DEBUG) {
|
|
341
412
|
console.log(`[Sailfish] GLOBAL tracking session report sent for session: ${sessionId}`);
|
|
@@ -395,18 +466,14 @@ export function enableFunctionSpanTracking() {
|
|
|
395
466
|
if (DEBUG) {
|
|
396
467
|
console.log("[Sailfish] enableFunctionSpanTracking() called - Report Issue recording started (LOCAL MODE)");
|
|
397
468
|
}
|
|
398
|
-
// If global tracking was already active, save its state so we can restore it later
|
|
399
|
-
if (funcSpanTrackingEnabled && !isLocalTrackingMode) {
|
|
400
|
-
savedGlobalTimeoutId = funcSpanTimeoutId;
|
|
401
|
-
savedGlobalExpirationTime = funcSpanExpirationTime;
|
|
402
|
-
if (DEBUG) {
|
|
403
|
-
console.log("[Sailfish] Saved global tracking state while switching to local mode");
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
469
|
funcSpanTrackingEnabled = true;
|
|
407
470
|
isLocalTrackingMode = true; // Mark as local tracking
|
|
408
471
|
funcSpanExpirationTime = null; // Local mode has no expiration
|
|
409
|
-
|
|
472
|
+
// Clear any existing timeout
|
|
473
|
+
if (funcSpanTimeoutId !== null) {
|
|
474
|
+
window.clearTimeout(funcSpanTimeoutId);
|
|
475
|
+
funcSpanTimeoutId = null;
|
|
476
|
+
}
|
|
410
477
|
// Report this session to backend for tracking with per_session configuration type
|
|
411
478
|
if (isWebSocketOpen(webSocket)) {
|
|
412
479
|
try {
|
|
@@ -459,29 +526,17 @@ export function disableFunctionSpanTracking() {
|
|
|
459
526
|
console.warn(`[FUNCSPAN STOP] ✗ WebSocket not open, cannot notify tracking end`);
|
|
460
527
|
}
|
|
461
528
|
if (isLocalTrackingMode) {
|
|
529
|
+
funcSpanTrackingEnabled = false;
|
|
462
530
|
isLocalTrackingMode = false;
|
|
463
|
-
|
|
464
|
-
if (
|
|
465
|
-
|
|
466
|
-
funcSpanExpirationTime = savedGlobalExpirationTime;
|
|
467
|
-
funcSpanTimeoutId = savedGlobalTimeoutId;
|
|
468
|
-
if (DEBUG) {
|
|
469
|
-
console.log("[Sailfish] LOCAL tracking mode disabled, restored GLOBAL tracking state");
|
|
470
|
-
}
|
|
471
|
-
// Clear saved state
|
|
472
|
-
savedGlobalTimeoutId = null;
|
|
473
|
-
savedGlobalExpirationTime = null;
|
|
474
|
-
}
|
|
475
|
-
else {
|
|
476
|
-
// No global tracking was active, fully disable
|
|
477
|
-
funcSpanTrackingEnabled = false;
|
|
478
|
-
funcSpanExpirationTime = null;
|
|
479
|
-
funcSpanTimeoutId = null;
|
|
480
|
-
if (DEBUG) {
|
|
481
|
-
console.log("[Sailfish] LOCAL tracking mode disabled, no global tracking to restore");
|
|
482
|
-
}
|
|
531
|
+
funcSpanExpirationTime = null;
|
|
532
|
+
if (DEBUG) {
|
|
533
|
+
console.log("[Sailfish] LOCAL tracking mode disabled");
|
|
483
534
|
}
|
|
484
535
|
}
|
|
536
|
+
if (funcSpanTimeoutId !== null) {
|
|
537
|
+
window.clearTimeout(funcSpanTimeoutId);
|
|
538
|
+
funcSpanTimeoutId = null;
|
|
539
|
+
}
|
|
485
540
|
}
|
|
486
541
|
/**
|
|
487
542
|
* Check if function span tracking is currently enabled
|
|
@@ -489,6 +544,28 @@ export function disableFunctionSpanTracking() {
|
|
|
489
544
|
export function isFunctionSpanTrackingEnabled() {
|
|
490
545
|
return funcSpanTrackingEnabled;
|
|
491
546
|
}
|
|
547
|
+
/**
|
|
548
|
+
* Initialize function span tracking state from API response (during page load)
|
|
549
|
+
* This is called before the WebSocket connects to ensure headers are added from the start
|
|
550
|
+
*/
|
|
551
|
+
export function initializeFunctionSpanTrackingFromApi(isEnabled) {
|
|
552
|
+
if (isEnabled && !funcSpanTrackingEnabled) {
|
|
553
|
+
funcSpanTrackingEnabled = true;
|
|
554
|
+
isLocalTrackingMode = false; // This is global tracking from API
|
|
555
|
+
funcSpanExpirationTime = null; // Will be set by WebSocket message later
|
|
556
|
+
if (DEBUG) {
|
|
557
|
+
console.log("[Sailfish] Function span tracking initialized as ENABLED from API check");
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
else if (!isEnabled && funcSpanTrackingEnabled) {
|
|
561
|
+
funcSpanTrackingEnabled = false;
|
|
562
|
+
isLocalTrackingMode = false;
|
|
563
|
+
funcSpanExpirationTime = null;
|
|
564
|
+
if (DEBUG) {
|
|
565
|
+
console.log("[Sailfish] Function span tracking initialized as DISABLED from API check");
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
492
569
|
/**
|
|
493
570
|
* Get the current funcspan header name and value
|
|
494
571
|
* Header constants are defined here but used by HTTP interceptors in index.tsx
|
|
@@ -505,6 +582,7 @@ export function getFuncSpanHeader() {
|
|
|
505
582
|
// Tracking has expired, disable it immediately
|
|
506
583
|
funcSpanTrackingEnabled = false;
|
|
507
584
|
funcSpanExpirationTime = null;
|
|
585
|
+
clearGlobalFuncSpanState();
|
|
508
586
|
if (DEBUG) {
|
|
509
587
|
console.log("[Sailfish] Function span tracking expired on header check - disabling now");
|
|
510
588
|
}
|
|
@@ -513,6 +591,6 @@ export function getFuncSpanHeader() {
|
|
|
513
591
|
}
|
|
514
592
|
return {
|
|
515
593
|
name: FUNCSPAN_HEADER_NAME,
|
|
516
|
-
value: FUNCSPAN_HEADER_VALUE
|
|
594
|
+
value: FUNCSPAN_HEADER_VALUE,
|
|
517
595
|
};
|
|
518
596
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sailfish-ai/recorder",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.15",
|
|
4
4
|
"publishPublicly": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/recorder.cjs",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"dist"
|
|
38
38
|
],
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@sailfish-ai/sf-map-utils": "0.4.
|
|
40
|
+
"@sailfish-ai/sf-map-utils": "0.4.5",
|
|
41
41
|
"@sailfish-rrweb/rrweb-plugin-console-record": "0.5.2",
|
|
42
42
|
"@sailfish-rrweb/rrweb-record-only": "0.5.2",
|
|
43
43
|
"@sailfish-rrweb/types": "0.5.2",
|