@tracelog/lib 0.0.8 → 0.2.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/README.md +58 -24
- package/dist/browser/tracelog.js +1934 -3226
- package/dist/cjs/api.d.ts +33 -19
- package/dist/cjs/api.js +111 -156
- package/dist/cjs/app.constants.d.ts +80 -1
- package/dist/cjs/app.constants.js +90 -3
- package/dist/cjs/app.d.ts +29 -44
- package/dist/cjs/app.js +114 -212
- package/dist/cjs/app.types.d.ts +2 -7
- package/dist/cjs/app.types.js +10 -21
- package/dist/cjs/constants/api.constants.js +11 -5
- package/dist/cjs/constants/config.constants.d.ts +75 -0
- package/dist/cjs/constants/config.constants.js +178 -0
- package/dist/cjs/constants/error.constants.d.ts +29 -0
- package/dist/cjs/constants/error.constants.js +50 -0
- package/dist/cjs/constants/index.d.ts +3 -6
- package/dist/cjs/constants/index.js +3 -6
- package/dist/cjs/constants/performance.constants.d.ts +28 -0
- package/dist/cjs/constants/performance.constants.js +43 -0
- package/dist/cjs/handlers/click.handler.d.ts +1 -0
- package/dist/cjs/handlers/click.handler.js +30 -49
- package/dist/cjs/handlers/error.handler.d.ts +11 -6
- package/dist/cjs/handlers/error.handler.js +91 -51
- package/dist/cjs/handlers/page-view.handler.js +38 -29
- package/dist/cjs/handlers/performance.handler.d.ts +3 -0
- package/dist/cjs/handlers/performance.handler.js +76 -37
- package/dist/cjs/handlers/scroll.handler.d.ts +15 -0
- package/dist/cjs/handlers/scroll.handler.js +105 -31
- package/dist/cjs/handlers/session.handler.d.ts +6 -20
- package/dist/cjs/handlers/session.handler.js +38 -326
- package/dist/cjs/integrations/google-analytics.integration.d.ts +0 -1
- package/dist/cjs/integrations/google-analytics.integration.js +27 -98
- package/dist/cjs/listeners/input-listener-managers.d.ts +18 -9
- package/dist/cjs/listeners/input-listener-managers.js +24 -33
- package/dist/cjs/listeners/touch-listener-manager.d.ts +1 -3
- package/dist/cjs/listeners/touch-listener-manager.js +1 -23
- package/dist/cjs/listeners/visibility-listener-manager.d.ts +1 -4
- package/dist/cjs/listeners/visibility-listener-manager.js +6 -42
- package/dist/cjs/managers/api.manager.d.ts +13 -3
- package/dist/cjs/managers/api.manager.js +35 -5
- package/dist/cjs/managers/config.manager.d.ts +53 -3
- package/dist/cjs/managers/config.manager.js +131 -62
- package/dist/cjs/managers/event.manager.d.ts +57 -36
- package/dist/cjs/managers/event.manager.js +266 -417
- package/dist/cjs/managers/sender.manager.d.ts +40 -22
- package/dist/cjs/managers/sender.manager.js +200 -198
- package/dist/cjs/managers/session.manager.d.ts +80 -66
- package/dist/cjs/managers/session.manager.js +267 -522
- package/dist/cjs/managers/state.manager.d.ts +33 -0
- package/dist/cjs/managers/state.manager.js +79 -6
- package/dist/cjs/managers/storage.manager.d.ts +26 -2
- package/dist/cjs/managers/storage.manager.js +67 -34
- package/dist/cjs/managers/tags.manager.d.ts +31 -7
- package/dist/cjs/managers/tags.manager.js +123 -241
- package/dist/cjs/managers/user.manager.d.ts +14 -5
- package/dist/cjs/managers/user.manager.js +17 -9
- package/dist/cjs/public-api.d.ts +10 -1
- package/dist/cjs/public-api.js +18 -24
- package/dist/cjs/test-bridge.d.ts +48 -0
- package/dist/cjs/test-bridge.js +110 -0
- package/dist/cjs/types/api.types.d.ts +21 -6
- package/dist/cjs/types/api.types.js +21 -6
- package/dist/cjs/types/config.types.d.ts +22 -84
- package/dist/cjs/types/emitter.types.d.ts +11 -0
- package/dist/cjs/types/emitter.types.js +8 -0
- package/dist/cjs/types/event.types.d.ts +8 -11
- package/dist/cjs/types/index.d.ts +3 -1
- package/dist/cjs/types/index.js +3 -1
- package/dist/cjs/types/queue.types.d.ts +1 -0
- package/dist/cjs/types/session.types.d.ts +0 -64
- package/dist/cjs/types/state.types.d.ts +1 -0
- package/dist/cjs/types/test-bridge.types.d.ts +38 -0
- package/dist/cjs/types/validation-error.types.d.ts +7 -0
- package/dist/cjs/types/validation-error.types.js +11 -1
- package/dist/cjs/types/window.types.d.ts +1 -8
- package/dist/cjs/utils/data/uuid.utils.d.ts +1 -1
- package/dist/cjs/utils/data/uuid.utils.js +7 -5
- package/dist/cjs/utils/emitter.utils.d.ts +8 -0
- package/dist/cjs/utils/emitter.utils.js +33 -0
- package/dist/cjs/utils/index.d.ts +1 -0
- package/dist/cjs/utils/index.js +1 -0
- package/dist/cjs/utils/logging/debug-logger.utils.d.ts +10 -51
- package/dist/cjs/utils/logging/debug-logger.utils.js +36 -127
- package/dist/cjs/utils/network/fetch-with-timeout.utils.d.ts +4 -0
- package/dist/cjs/utils/network/fetch-with-timeout.utils.js +25 -0
- package/dist/cjs/utils/network/index.d.ts +1 -0
- package/dist/cjs/utils/network/index.js +1 -0
- package/dist/cjs/utils/network/url.utils.js +2 -42
- package/dist/cjs/utils/security/sanitize.utils.d.ts +1 -8
- package/dist/cjs/utils/security/sanitize.utils.js +7 -41
- package/dist/cjs/utils/validations/config-validations.utils.d.ts +7 -0
- package/dist/cjs/utils/validations/config-validations.utils.js +77 -22
- package/dist/esm/api.d.ts +33 -19
- package/dist/esm/api.js +105 -118
- package/dist/esm/app.constants.d.ts +80 -1
- package/dist/esm/app.constants.js +89 -1
- package/dist/esm/app.d.ts +29 -44
- package/dist/esm/app.js +115 -213
- package/dist/esm/app.types.d.ts +2 -7
- package/dist/esm/app.types.js +1 -7
- package/dist/esm/constants/api.constants.js +10 -4
- package/dist/esm/constants/config.constants.d.ts +75 -0
- package/dist/esm/constants/config.constants.js +174 -0
- package/dist/esm/constants/error.constants.d.ts +29 -0
- package/dist/esm/constants/error.constants.js +47 -0
- package/dist/esm/constants/index.d.ts +3 -6
- package/dist/esm/constants/index.js +3 -6
- package/dist/esm/constants/performance.constants.d.ts +28 -0
- package/dist/esm/constants/performance.constants.js +40 -0
- package/dist/esm/handlers/click.handler.d.ts +1 -0
- package/dist/esm/handlers/click.handler.js +30 -49
- package/dist/esm/handlers/error.handler.d.ts +11 -6
- package/dist/esm/handlers/error.handler.js +91 -51
- package/dist/esm/handlers/page-view.handler.js +38 -29
- package/dist/esm/handlers/performance.handler.d.ts +3 -0
- package/dist/esm/handlers/performance.handler.js +71 -32
- package/dist/esm/handlers/scroll.handler.d.ts +15 -0
- package/dist/esm/handlers/scroll.handler.js +106 -32
- package/dist/esm/handlers/session.handler.d.ts +6 -20
- package/dist/esm/handlers/session.handler.js +38 -326
- package/dist/esm/integrations/google-analytics.integration.d.ts +0 -1
- package/dist/esm/integrations/google-analytics.integration.js +27 -98
- package/dist/esm/listeners/input-listener-managers.d.ts +18 -9
- package/dist/esm/listeners/input-listener-managers.js +23 -32
- package/dist/esm/listeners/touch-listener-manager.d.ts +1 -3
- package/dist/esm/listeners/touch-listener-manager.js +1 -23
- package/dist/esm/listeners/visibility-listener-manager.d.ts +1 -4
- package/dist/esm/listeners/visibility-listener-manager.js +6 -42
- package/dist/esm/managers/api.manager.d.ts +13 -3
- package/dist/esm/managers/api.manager.js +34 -3
- package/dist/esm/managers/config.manager.d.ts +53 -3
- package/dist/esm/managers/config.manager.js +133 -64
- package/dist/esm/managers/event.manager.d.ts +57 -36
- package/dist/esm/managers/event.manager.js +268 -419
- package/dist/esm/managers/sender.manager.d.ts +40 -22
- package/dist/esm/managers/sender.manager.js +201 -199
- package/dist/esm/managers/session.manager.d.ts +80 -66
- package/dist/esm/managers/session.manager.js +269 -524
- package/dist/esm/managers/state.manager.d.ts +33 -0
- package/dist/esm/managers/state.manager.js +78 -6
- package/dist/esm/managers/storage.manager.d.ts +26 -2
- package/dist/esm/managers/storage.manager.js +66 -33
- package/dist/esm/managers/tags.manager.d.ts +31 -7
- package/dist/esm/managers/tags.manager.js +124 -242
- package/dist/esm/managers/user.manager.d.ts +14 -5
- package/dist/esm/managers/user.manager.js +17 -9
- package/dist/esm/public-api.d.ts +10 -1
- package/dist/esm/public-api.js +14 -1
- package/dist/esm/test-bridge.d.ts +48 -0
- package/dist/esm/test-bridge.js +106 -0
- package/dist/esm/types/api.types.d.ts +21 -6
- package/dist/esm/types/api.types.js +21 -6
- package/dist/esm/types/config.types.d.ts +22 -84
- package/dist/esm/types/emitter.types.d.ts +11 -0
- package/dist/esm/types/emitter.types.js +5 -0
- package/dist/esm/types/event.types.d.ts +8 -11
- package/dist/esm/types/index.d.ts +3 -1
- package/dist/esm/types/index.js +3 -1
- package/dist/esm/types/queue.types.d.ts +1 -0
- package/dist/esm/types/session.types.d.ts +0 -64
- package/dist/esm/types/state.types.d.ts +1 -0
- package/dist/esm/types/test-bridge.types.d.ts +38 -0
- package/dist/esm/types/validation-error.types.d.ts +7 -0
- package/dist/esm/types/validation-error.types.js +9 -0
- package/dist/esm/types/window.types.d.ts +1 -8
- package/dist/esm/utils/data/uuid.utils.d.ts +1 -1
- package/dist/esm/utils/data/uuid.utils.js +7 -5
- package/dist/esm/utils/emitter.utils.d.ts +8 -0
- package/dist/esm/utils/emitter.utils.js +29 -0
- package/dist/esm/utils/index.d.ts +1 -0
- package/dist/esm/utils/index.js +1 -0
- package/dist/esm/utils/logging/debug-logger.utils.d.ts +10 -51
- package/dist/esm/utils/logging/debug-logger.utils.js +36 -127
- package/dist/esm/utils/network/fetch-with-timeout.utils.d.ts +4 -0
- package/dist/esm/utils/network/fetch-with-timeout.utils.js +22 -0
- package/dist/esm/utils/network/index.d.ts +1 -0
- package/dist/esm/utils/network/index.js +1 -0
- package/dist/esm/utils/network/url.utils.js +2 -42
- package/dist/esm/utils/security/sanitize.utils.d.ts +1 -8
- package/dist/esm/utils/security/sanitize.utils.js +6 -39
- package/dist/esm/utils/validations/config-validations.utils.d.ts +7 -0
- package/dist/esm/utils/validations/config-validations.utils.js +76 -22
- package/package.json +23 -16
- package/dist/browser/web-vitals-CCnqwnC8.mjs +0 -198
- package/dist/cjs/constants/browser.constants.d.ts +0 -3
- package/dist/cjs/constants/browser.constants.js +0 -41
- package/dist/cjs/constants/initialization.constants.d.ts +0 -40
- package/dist/cjs/constants/initialization.constants.js +0 -48
- package/dist/cjs/constants/limits.constants.d.ts +0 -25
- package/dist/cjs/constants/limits.constants.js +0 -40
- package/dist/cjs/constants/security.constants.d.ts +0 -1
- package/dist/cjs/constants/security.constants.js +0 -12
- package/dist/cjs/constants/timing.constants.d.ts +0 -22
- package/dist/cjs/constants/timing.constants.js +0 -34
- package/dist/cjs/constants/validation.constants.d.ts +0 -13
- package/dist/cjs/constants/validation.constants.js +0 -31
- package/dist/cjs/handlers/network.handler.d.ts +0 -16
- package/dist/cjs/handlers/network.handler.js +0 -136
- package/dist/cjs/managers/cross-tab-session.manager.d.ts +0 -170
- package/dist/cjs/managers/cross-tab-session.manager.js +0 -730
- package/dist/cjs/managers/sampling.manager.d.ts +0 -8
- package/dist/cjs/managers/sampling.manager.js +0 -53
- package/dist/cjs/managers/session-recovery.manager.d.ts +0 -65
- package/dist/cjs/managers/session-recovery.manager.js +0 -237
- package/dist/cjs/types/web-vitals.types.d.ts +0 -6
- package/dist/esm/constants/browser.constants.d.ts +0 -3
- package/dist/esm/constants/browser.constants.js +0 -38
- package/dist/esm/constants/initialization.constants.d.ts +0 -40
- package/dist/esm/constants/initialization.constants.js +0 -45
- package/dist/esm/constants/limits.constants.d.ts +0 -25
- package/dist/esm/constants/limits.constants.js +0 -37
- package/dist/esm/constants/security.constants.d.ts +0 -1
- package/dist/esm/constants/security.constants.js +0 -9
- package/dist/esm/constants/timing.constants.d.ts +0 -22
- package/dist/esm/constants/timing.constants.js +0 -31
- package/dist/esm/constants/validation.constants.d.ts +0 -13
- package/dist/esm/constants/validation.constants.js +0 -28
- package/dist/esm/handlers/network.handler.d.ts +0 -16
- package/dist/esm/handlers/network.handler.js +0 -132
- package/dist/esm/managers/cross-tab-session.manager.d.ts +0 -170
- package/dist/esm/managers/cross-tab-session.manager.js +0 -726
- package/dist/esm/managers/sampling.manager.d.ts +0 -8
- package/dist/esm/managers/sampling.manager.js +0 -49
- package/dist/esm/managers/session-recovery.manager.d.ts +0 -65
- package/dist/esm/managers/session-recovery.manager.js +0 -233
- package/dist/esm/types/web-vitals.types.d.ts +0 -6
- /package/dist/cjs/types/{web-vitals.types.js → test-bridge.types.js} +0 -0
- /package/dist/esm/types/{web-vitals.types.js → test-bridge.types.js} +0 -0
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { EventType, WebVitalsData } from '../types';
|
|
2
|
-
import { StateManager } from './state.manager';
|
|
3
|
-
export declare class SamplingManager extends StateManager {
|
|
4
|
-
shouldSampleEvent(type: EventType, webVitals?: WebVitalsData): boolean;
|
|
5
|
-
private isSampledIn;
|
|
6
|
-
private isWebVitalEventSampledIn;
|
|
7
|
-
private getHash;
|
|
8
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { DEFAULT_SAMPLING_RATE, WEB_VITALS_SAMPLING, WEB_VITALS_LONG_TASK_SAMPLING } from '../constants';
|
|
2
|
-
import { EventType } from '../types';
|
|
3
|
-
import { StateManager } from './state.manager';
|
|
4
|
-
export class SamplingManager extends StateManager {
|
|
5
|
-
shouldSampleEvent(type, webVitals) {
|
|
6
|
-
const isQaMode = this.get('config')?.mode === 'qa' || this.get('config')?.mode === 'debug';
|
|
7
|
-
if (isQaMode) {
|
|
8
|
-
return true;
|
|
9
|
-
}
|
|
10
|
-
if (type === EventType.WEB_VITALS) {
|
|
11
|
-
return this.isWebVitalEventSampledIn(webVitals?.type);
|
|
12
|
-
}
|
|
13
|
-
return this.isSampledIn();
|
|
14
|
-
}
|
|
15
|
-
isSampledIn() {
|
|
16
|
-
const samplingRate = this.get('config').samplingRate ?? DEFAULT_SAMPLING_RATE;
|
|
17
|
-
if (samplingRate >= 1.0) {
|
|
18
|
-
return true;
|
|
19
|
-
}
|
|
20
|
-
if (samplingRate <= 0) {
|
|
21
|
-
return false;
|
|
22
|
-
}
|
|
23
|
-
const userHash = this.getHash(this.get('userId'));
|
|
24
|
-
const userValue = (userHash % 100) / 100;
|
|
25
|
-
const isSampled = userValue < samplingRate;
|
|
26
|
-
return isSampled;
|
|
27
|
-
}
|
|
28
|
-
isWebVitalEventSampledIn(type) {
|
|
29
|
-
const isLongTask = type === 'LONG_TASK';
|
|
30
|
-
const rate = isLongTask ? WEB_VITALS_LONG_TASK_SAMPLING : WEB_VITALS_SAMPLING;
|
|
31
|
-
if (rate >= 1)
|
|
32
|
-
return true;
|
|
33
|
-
if (rate <= 0)
|
|
34
|
-
return false;
|
|
35
|
-
const seed = `${this.get('userId')}|${isLongTask ? 'long_task' : 'web_vitals'}`;
|
|
36
|
-
const hash = this.getHash(seed);
|
|
37
|
-
const value = (hash % 100) / 100;
|
|
38
|
-
return value < rate;
|
|
39
|
-
}
|
|
40
|
-
getHash(input) {
|
|
41
|
-
let hash = 0;
|
|
42
|
-
for (let i = 0; i < input.length; i++) {
|
|
43
|
-
const char = input.charCodeAt(i);
|
|
44
|
-
hash = (hash << 5) - hash + char;
|
|
45
|
-
hash |= 0;
|
|
46
|
-
}
|
|
47
|
-
return Math.abs(hash);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { SessionRecoveryConfig, SessionContext } from '../types/session.types';
|
|
2
|
-
import { StateManager } from './state.manager';
|
|
3
|
-
import { StorageManager } from './storage.manager';
|
|
4
|
-
import { EventManager } from './event.manager';
|
|
5
|
-
export declare class SessionRecoveryManager extends StateManager {
|
|
6
|
-
private readonly config;
|
|
7
|
-
private readonly storageManager;
|
|
8
|
-
private readonly eventManager;
|
|
9
|
-
private readonly projectId;
|
|
10
|
-
private readonly debugMode;
|
|
11
|
-
constructor(storageManager: StorageManager, projectId: string, eventManager?: EventManager, config?: Partial<SessionRecoveryConfig>);
|
|
12
|
-
/**
|
|
13
|
-
* Attempt to recover a session
|
|
14
|
-
*/
|
|
15
|
-
attemptSessionRecovery(currentSessionId?: string): {
|
|
16
|
-
recovered: boolean;
|
|
17
|
-
recoveredSessionId?: string;
|
|
18
|
-
context?: SessionContext;
|
|
19
|
-
};
|
|
20
|
-
/**
|
|
21
|
-
* Calculate the recovery window with bounds checking
|
|
22
|
-
*/
|
|
23
|
-
private calculateRecoveryWindow;
|
|
24
|
-
/**
|
|
25
|
-
* Check if session recovery can be attempted
|
|
26
|
-
*/
|
|
27
|
-
private canAttemptRecovery;
|
|
28
|
-
/**
|
|
29
|
-
* Store session context for potential recovery
|
|
30
|
-
*/
|
|
31
|
-
storeSessionContextForRecovery(sessionContext: SessionContext): void;
|
|
32
|
-
/**
|
|
33
|
-
* Get stored recovery attempts
|
|
34
|
-
*/
|
|
35
|
-
private getStoredRecoveryAttempts;
|
|
36
|
-
/**
|
|
37
|
-
* Store recovery attempts
|
|
38
|
-
*/
|
|
39
|
-
private storeRecoveryAttempts;
|
|
40
|
-
/**
|
|
41
|
-
* Get the last recovery attempt
|
|
42
|
-
*/
|
|
43
|
-
private getLastRecoveryAttempt;
|
|
44
|
-
/**
|
|
45
|
-
* Clean up old recovery attempts
|
|
46
|
-
*/
|
|
47
|
-
cleanupOldRecoveryAttempts(): void;
|
|
48
|
-
/**
|
|
49
|
-
* Check if there's a recoverable session.
|
|
50
|
-
* Returns false when no recovery attempts are stored.
|
|
51
|
-
*/
|
|
52
|
-
hasRecoverableSession(): boolean;
|
|
53
|
-
/**
|
|
54
|
-
* Get recovery window in milliseconds
|
|
55
|
-
*/
|
|
56
|
-
getRecoveryWindowMs(): number;
|
|
57
|
-
/**
|
|
58
|
-
* Get max recovery attempts
|
|
59
|
-
*/
|
|
60
|
-
getMaxRecoveryAttempts(): number;
|
|
61
|
-
/**
|
|
62
|
-
* Clear all stored recovery data
|
|
63
|
-
*/
|
|
64
|
-
clearRecoveryData(): void;
|
|
65
|
-
}
|
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
import { DEFAULT_SESSION_TIMEOUT_MS, SESSION_RECOVERY_WINDOW_MULTIPLIER, MAX_SESSION_RECOVERY_ATTEMPTS, MAX_SESSION_RECOVERY_WINDOW_MS, MIN_SESSION_RECOVERY_WINDOW_MS, } from '../constants';
|
|
2
|
-
import { SESSION_RECOVERY_KEY } from '../constants/storage.constants';
|
|
3
|
-
import { debugLog } from '../utils/logging';
|
|
4
|
-
import { StateManager } from './state.manager';
|
|
5
|
-
export class SessionRecoveryManager extends StateManager {
|
|
6
|
-
constructor(storageManager, projectId, eventManager, config) {
|
|
7
|
-
super();
|
|
8
|
-
this.storageManager = storageManager;
|
|
9
|
-
this.eventManager = eventManager ?? null;
|
|
10
|
-
this.projectId = projectId;
|
|
11
|
-
this.debugMode = (this.get('config')?.mode === 'qa' || this.get('config')?.mode === 'debug') ?? false;
|
|
12
|
-
this.config = {
|
|
13
|
-
recoveryWindowMs: this.calculateRecoveryWindow(),
|
|
14
|
-
maxRecoveryAttempts: MAX_SESSION_RECOVERY_ATTEMPTS,
|
|
15
|
-
contextPreservation: true,
|
|
16
|
-
...config,
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Attempt to recover a session
|
|
21
|
-
*/
|
|
22
|
-
attemptSessionRecovery(currentSessionId) {
|
|
23
|
-
if (this.debugMode) {
|
|
24
|
-
debugLog.debug('SessionRecovery', 'Attempting session recovery');
|
|
25
|
-
}
|
|
26
|
-
// Get stored recovery attempts
|
|
27
|
-
const recoveryAttempts = this.getStoredRecoveryAttempts();
|
|
28
|
-
const lastAttempt = this.getLastRecoveryAttempt();
|
|
29
|
-
// Check if we can recover
|
|
30
|
-
if (!this.canAttemptRecovery(lastAttempt)) {
|
|
31
|
-
if (this.debugMode) {
|
|
32
|
-
debugLog.debug('SessionRecovery', 'Session recovery not possible - outside recovery window or max attempts reached');
|
|
33
|
-
}
|
|
34
|
-
return {
|
|
35
|
-
recovered: false,
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
// Get the last session context
|
|
39
|
-
const lastSessionContext = lastAttempt?.context;
|
|
40
|
-
if (!lastSessionContext) {
|
|
41
|
-
if (this.debugMode) {
|
|
42
|
-
debugLog.debug('SessionRecovery', 'No session context available for recovery');
|
|
43
|
-
}
|
|
44
|
-
return {
|
|
45
|
-
recovered: false,
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
// Check if recovery is possible
|
|
49
|
-
const now = Date.now();
|
|
50
|
-
const timeSinceLastActivity = now - lastSessionContext.lastActivity;
|
|
51
|
-
if (timeSinceLastActivity > this.config.recoveryWindowMs) {
|
|
52
|
-
if (this.debugMode) {
|
|
53
|
-
debugLog.debug('SessionRecovery', 'Session recovery failed - outside recovery window');
|
|
54
|
-
}
|
|
55
|
-
return {
|
|
56
|
-
recovered: false,
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
// Perform recovery
|
|
60
|
-
const recoveredSessionId = lastSessionContext.sessionId;
|
|
61
|
-
const attemptNumber = (lastAttempt?.attempt ?? 0) + 1;
|
|
62
|
-
// Create recovery attempt record
|
|
63
|
-
const recoveryAttempt = {
|
|
64
|
-
sessionId: currentSessionId ?? recoveredSessionId,
|
|
65
|
-
timestamp: now,
|
|
66
|
-
attempt: attemptNumber,
|
|
67
|
-
context: {
|
|
68
|
-
...lastSessionContext,
|
|
69
|
-
recoveryAttempts: attemptNumber,
|
|
70
|
-
lastActivity: now,
|
|
71
|
-
},
|
|
72
|
-
};
|
|
73
|
-
recoveryAttempts.push(recoveryAttempt);
|
|
74
|
-
this.storeRecoveryAttempts(recoveryAttempts);
|
|
75
|
-
if (this.debugMode) {
|
|
76
|
-
debugLog.debug('SessionRecovery', `Session recovery successful: recovery of session ${recoveredSessionId}`);
|
|
77
|
-
}
|
|
78
|
-
return {
|
|
79
|
-
recovered: true,
|
|
80
|
-
recoveredSessionId,
|
|
81
|
-
context: recoveryAttempt.context,
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Calculate the recovery window with bounds checking
|
|
86
|
-
*/
|
|
87
|
-
calculateRecoveryWindow() {
|
|
88
|
-
const sessionTimeout = this.get('config')?.sessionTimeout ?? DEFAULT_SESSION_TIMEOUT_MS;
|
|
89
|
-
const calculatedRecoveryWindow = sessionTimeout * SESSION_RECOVERY_WINDOW_MULTIPLIER;
|
|
90
|
-
const boundedRecoveryWindow = Math.max(Math.min(calculatedRecoveryWindow, MAX_SESSION_RECOVERY_WINDOW_MS), MIN_SESSION_RECOVERY_WINDOW_MS);
|
|
91
|
-
if (this.debugMode) {
|
|
92
|
-
if (calculatedRecoveryWindow > MAX_SESSION_RECOVERY_WINDOW_MS) {
|
|
93
|
-
debugLog.warn('SessionRecovery', `Recovery window capped at ${MAX_SESSION_RECOVERY_WINDOW_MS}ms (24h). Calculated: ${calculatedRecoveryWindow}ms`);
|
|
94
|
-
}
|
|
95
|
-
else if (calculatedRecoveryWindow < MIN_SESSION_RECOVERY_WINDOW_MS) {
|
|
96
|
-
debugLog.warn('SessionRecovery', `Recovery window increased to minimum ${MIN_SESSION_RECOVERY_WINDOW_MS}ms (2min). Calculated: ${calculatedRecoveryWindow}ms`);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
return boundedRecoveryWindow;
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Check if session recovery can be attempted
|
|
103
|
-
*/
|
|
104
|
-
canAttemptRecovery(lastAttempt) {
|
|
105
|
-
if (!lastAttempt) {
|
|
106
|
-
return true; // First recovery attempt
|
|
107
|
-
}
|
|
108
|
-
const now = Date.now();
|
|
109
|
-
const timeSinceLastActivity = now - lastAttempt.context.lastActivity;
|
|
110
|
-
// Check if within recovery window
|
|
111
|
-
if (timeSinceLastActivity > this.config.recoveryWindowMs) {
|
|
112
|
-
return false;
|
|
113
|
-
}
|
|
114
|
-
// Check max attempts
|
|
115
|
-
if (lastAttempt.attempt >= this.config.maxRecoveryAttempts) {
|
|
116
|
-
return false;
|
|
117
|
-
}
|
|
118
|
-
return true;
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Store session context for potential recovery
|
|
122
|
-
*/
|
|
123
|
-
storeSessionContextForRecovery(sessionContext) {
|
|
124
|
-
try {
|
|
125
|
-
const recoveryAttempts = this.getStoredRecoveryAttempts();
|
|
126
|
-
// Create a recovery attempt record
|
|
127
|
-
const recoveryAttempt = {
|
|
128
|
-
sessionId: sessionContext.sessionId,
|
|
129
|
-
timestamp: Date.now(),
|
|
130
|
-
attempt: 0,
|
|
131
|
-
context: sessionContext,
|
|
132
|
-
};
|
|
133
|
-
// Add to recovery attempts (keep only the latest few)
|
|
134
|
-
recoveryAttempts.push(recoveryAttempt);
|
|
135
|
-
const maxStoredRecoveryAttempts = 5;
|
|
136
|
-
if (recoveryAttempts.length > maxStoredRecoveryAttempts) {
|
|
137
|
-
recoveryAttempts.splice(0, recoveryAttempts.length - maxStoredRecoveryAttempts);
|
|
138
|
-
}
|
|
139
|
-
this.storeRecoveryAttempts(recoveryAttempts);
|
|
140
|
-
if (this.debugMode) {
|
|
141
|
-
debugLog.debug('SessionRecovery', `Stored session context for recovery: ${sessionContext.sessionId}`);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
catch (error) {
|
|
145
|
-
if (this.debugMode) {
|
|
146
|
-
debugLog.warn('SessionRecovery', 'Failed to store session context for recovery', { error });
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Get stored recovery attempts
|
|
152
|
-
*/
|
|
153
|
-
getStoredRecoveryAttempts() {
|
|
154
|
-
try {
|
|
155
|
-
const stored = this.storageManager.getItem(SESSION_RECOVERY_KEY(this.projectId));
|
|
156
|
-
return stored ? JSON.parse(stored) : [];
|
|
157
|
-
}
|
|
158
|
-
catch (error) {
|
|
159
|
-
if (this.debugMode) {
|
|
160
|
-
const stored = this.storageManager.getItem(SESSION_RECOVERY_KEY(this.projectId));
|
|
161
|
-
debugLog.warn('SessionRecovery', `Failed to parse stored recovery attempts for projectId ${this.projectId}. Data: ${stored}`, { error });
|
|
162
|
-
}
|
|
163
|
-
return [];
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* Store recovery attempts
|
|
168
|
-
*/
|
|
169
|
-
storeRecoveryAttempts(attempts) {
|
|
170
|
-
try {
|
|
171
|
-
this.storageManager.setItem(SESSION_RECOVERY_KEY(this.projectId), JSON.stringify(attempts));
|
|
172
|
-
}
|
|
173
|
-
catch (error) {
|
|
174
|
-
if (this.debugMode) {
|
|
175
|
-
debugLog.warn('SessionRecovery', 'Failed to store recovery attempts', { error });
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
/**
|
|
180
|
-
* Get the last recovery attempt
|
|
181
|
-
*/
|
|
182
|
-
getLastRecoveryAttempt() {
|
|
183
|
-
const attempts = this.getStoredRecoveryAttempts();
|
|
184
|
-
return attempts.length > 0 ? attempts[attempts.length - 1] : null;
|
|
185
|
-
}
|
|
186
|
-
/**
|
|
187
|
-
* Clean up old recovery attempts
|
|
188
|
-
*/
|
|
189
|
-
cleanupOldRecoveryAttempts() {
|
|
190
|
-
const attempts = this.getStoredRecoveryAttempts();
|
|
191
|
-
const now = Date.now();
|
|
192
|
-
// Remove attempts older than recovery window
|
|
193
|
-
const validAttempts = attempts.filter((attempt) => now - attempt.timestamp <= this.config.recoveryWindowMs);
|
|
194
|
-
if (validAttempts.length !== attempts.length) {
|
|
195
|
-
this.storeRecoveryAttempts(validAttempts);
|
|
196
|
-
if (this.debugMode) {
|
|
197
|
-
debugLog.debug('SessionRecovery', `Cleaned up ${attempts.length - validAttempts.length} old recovery attempts`);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* Check if there's a recoverable session.
|
|
203
|
-
* Returns false when no recovery attempts are stored.
|
|
204
|
-
*/
|
|
205
|
-
hasRecoverableSession() {
|
|
206
|
-
const lastAttempt = this.getLastRecoveryAttempt();
|
|
207
|
-
if (!lastAttempt) {
|
|
208
|
-
return false;
|
|
209
|
-
}
|
|
210
|
-
return this.canAttemptRecovery(lastAttempt);
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* Get recovery window in milliseconds
|
|
214
|
-
*/
|
|
215
|
-
getRecoveryWindowMs() {
|
|
216
|
-
return this.config.recoveryWindowMs;
|
|
217
|
-
}
|
|
218
|
-
/**
|
|
219
|
-
* Get max recovery attempts
|
|
220
|
-
*/
|
|
221
|
-
getMaxRecoveryAttempts() {
|
|
222
|
-
return this.config.maxRecoveryAttempts;
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
|
-
* Clear all stored recovery data
|
|
226
|
-
*/
|
|
227
|
-
clearRecoveryData() {
|
|
228
|
-
this.storageManager.removeItem(SESSION_RECOVERY_KEY(this.projectId));
|
|
229
|
-
if (this.debugMode) {
|
|
230
|
-
debugLog.debug('SessionRecovery', 'Cleared all recovery data');
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
}
|
|
File without changes
|
|
File without changes
|