@interfere/next 0.0.0-alpha.10 → 0.0.1

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.
Files changed (120) hide show
  1. package/README.md +1 -0
  2. package/dist/__tests__/build/with-interfere-coverage.test.d.ts +2 -0
  3. package/dist/__tests__/build/with-interfere-coverage.test.d.ts.map +1 -0
  4. package/dist/__tests__/build/with-interfere-coverage.test.js +338 -0
  5. package/dist/__tests__/build/with-interfere-coverage.test.js.map +1 -0
  6. package/dist/__tests__/build/with-interfere.test.d.ts +2 -0
  7. package/dist/__tests__/build/with-interfere.test.d.ts.map +1 -0
  8. package/dist/__tests__/build/with-interfere.test.js +466 -0
  9. package/dist/__tests__/build/with-interfere.test.js.map +1 -0
  10. package/dist/__tests__/core/client.test.d.ts.map +1 -0
  11. package/dist/__tests__/core/client.test.js +373 -0
  12. package/dist/__tests__/core/client.test.js.map +1 -0
  13. package/dist/__tests__/core/encoders.test.d.ts.map +1 -0
  14. package/dist/{core → __tests__/core}/encoders.test.js +20 -19
  15. package/dist/__tests__/core/encoders.test.js.map +1 -0
  16. package/dist/__tests__/core/rage-click.test.d.ts +2 -0
  17. package/dist/__tests__/core/rage-click.test.d.ts.map +1 -0
  18. package/dist/__tests__/core/rage-click.test.js +121 -0
  19. package/dist/__tests__/core/rage-click.test.js.map +1 -0
  20. package/dist/__tests__/core/session-manager.test.d.ts +2 -0
  21. package/dist/__tests__/core/session-manager.test.d.ts.map +1 -0
  22. package/dist/__tests__/core/session-manager.test.js +1132 -0
  23. package/dist/__tests__/core/session-manager.test.js.map +1 -0
  24. package/dist/__tests__/integration/release-upload.test.d.ts +2 -0
  25. package/dist/__tests__/integration/release-upload.test.d.ts.map +1 -0
  26. package/dist/__tests__/integration/release-upload.test.js +173 -0
  27. package/dist/__tests__/integration/release-upload.test.js.map +1 -0
  28. package/dist/__tests__/session/persistence.test.d.ts +2 -0
  29. package/dist/__tests__/session/persistence.test.d.ts.map +1 -0
  30. package/dist/__tests__/session/persistence.test.js +129 -0
  31. package/dist/__tests__/session/persistence.test.js.map +1 -0
  32. package/dist/__tests__/session/session-summary.test.d.ts +2 -0
  33. package/dist/__tests__/session/session-summary.test.d.ts.map +1 -0
  34. package/dist/__tests__/session/session-summary.test.js +763 -0
  35. package/dist/__tests__/session/session-summary.test.js.map +1 -0
  36. package/dist/build/index.d.ts +3 -0
  37. package/dist/build/index.d.ts.map +1 -0
  38. package/dist/build/index.js +2 -0
  39. package/dist/build/index.js.map +1 -0
  40. package/dist/build/with-interfere.d.ts +54 -0
  41. package/dist/build/with-interfere.d.ts.map +1 -0
  42. package/dist/build/with-interfere.js +267 -0
  43. package/dist/build/with-interfere.js.map +1 -0
  44. package/dist/core/client-core.d.ts +27 -0
  45. package/dist/core/client-core.d.ts.map +1 -0
  46. package/dist/core/client-core.js +164 -0
  47. package/dist/core/client-core.js.map +1 -0
  48. package/dist/core/client.d.ts +70 -18
  49. package/dist/core/client.d.ts.map +1 -1
  50. package/dist/core/client.js +112 -104
  51. package/dist/core/client.js.map +1 -1
  52. package/dist/core/constants.d.ts +12 -0
  53. package/dist/core/constants.d.ts.map +1 -0
  54. package/dist/core/constants.js +17 -0
  55. package/dist/core/constants.js.map +1 -0
  56. package/dist/core/debug.d.ts +47 -0
  57. package/dist/core/debug.d.ts.map +1 -0
  58. package/dist/core/debug.js +79 -0
  59. package/dist/core/debug.js.map +1 -0
  60. package/dist/core/error-handlers.d.ts.map +1 -1
  61. package/dist/core/error-handlers.js +42 -41
  62. package/dist/core/error-handlers.js.map +1 -1
  63. package/dist/core/runtime.d.ts +7 -0
  64. package/dist/core/runtime.d.ts.map +1 -0
  65. package/dist/core/runtime.js +16 -0
  66. package/dist/core/runtime.js.map +1 -0
  67. package/dist/index.d.ts +10 -7
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +6 -7
  70. package/dist/index.js.map +1 -1
  71. package/dist/next/middleware.d.ts +1 -1
  72. package/dist/next/middleware.js +13 -13
  73. package/dist/persistence/storage.d.ts +5 -0
  74. package/dist/persistence/storage.d.ts.map +1 -0
  75. package/dist/persistence/storage.js +67 -0
  76. package/dist/persistence/storage.js.map +1 -0
  77. package/dist/react/provider.d.ts +9 -5
  78. package/dist/react/provider.d.ts.map +1 -1
  79. package/dist/react/provider.jsx +33 -10
  80. package/dist/react/provider.jsx.map +1 -1
  81. package/dist/session/constants.d.ts +19 -0
  82. package/dist/session/constants.d.ts.map +1 -0
  83. package/dist/session/constants.js +34 -0
  84. package/dist/session/constants.js.map +1 -0
  85. package/dist/session/persistence.d.ts +58 -0
  86. package/dist/session/persistence.d.ts.map +1 -0
  87. package/dist/session/persistence.js +180 -0
  88. package/dist/session/persistence.js.map +1 -0
  89. package/dist/session/rage-click.d.ts +17 -0
  90. package/dist/session/rage-click.d.ts.map +1 -0
  91. package/dist/session/rage-click.js +104 -0
  92. package/dist/session/rage-click.js.map +1 -0
  93. package/dist/session/replay.d.ts +2 -2
  94. package/dist/session/replay.d.ts.map +1 -1
  95. package/dist/session/replay.js +57 -24
  96. package/dist/session/replay.js.map +1 -1
  97. package/dist/session/session-manager.d.ts +126 -0
  98. package/dist/session/session-manager.d.ts.map +1 -0
  99. package/dist/session/session-manager.js +635 -0
  100. package/dist/session/session-manager.js.map +1 -0
  101. package/dist/session/session-summary.d.ts +2 -2
  102. package/dist/session/session-summary.d.ts.map +1 -1
  103. package/dist/session/session-summary.js +94 -47
  104. package/dist/session/session-summary.js.map +1 -1
  105. package/dist/types/storage.d.ts +7 -0
  106. package/dist/types/storage.d.ts.map +1 -0
  107. package/dist/types/storage.js +2 -0
  108. package/dist/types/storage.js.map +1 -0
  109. package/package.json +24 -7
  110. package/dist/core/client.test.d.ts.map +0 -1
  111. package/dist/core/client.test.js +0 -238
  112. package/dist/core/client.test.js.map +0 -1
  113. package/dist/core/encoders.test.d.ts.map +0 -1
  114. package/dist/core/encoders.test.js.map +0 -1
  115. package/dist/next/error-boundary.d.ts +0 -17
  116. package/dist/next/error-boundary.d.ts.map +0 -1
  117. package/dist/next/error-boundary.jsx +0 -32
  118. package/dist/next/error-boundary.jsx.map +0 -1
  119. /package/dist/{core → __tests__/core}/client.test.d.ts +0 -0
  120. /package/dist/{core → __tests__/core}/encoders.test.d.ts +0 -0
@@ -0,0 +1,635 @@
1
+ import { v7 as uuidv7 } from "uuid";
2
+ import { sessionStore } from "../persistence/storage.js";
3
+ import { DEFAULT_SESSION_IDLE_TIMEOUT_SECONDS, MAX_SESSION_IDLE_TIMEOUT_SECONDS, MIN_SESSION_IDLE_TIMEOUT_SECONDS, SESSION_ID, SESSION_LENGTH_LIMIT_MILLISECONDS, toMs, } from "./constants.js";
4
+ /**
5
+ * Default clock implementation using native browser APIs
6
+ */
7
+ const defaultClock = {
8
+ now: () => Date.now(),
9
+ setTimeout: (callback, delay) => setTimeout(callback, delay),
10
+ clearTimeout: (timeoutId) => clearTimeout(timeoutId),
11
+ };
12
+ /**
13
+ * Reasons why a session ID might change
14
+ */
15
+ export const SessionChangeReason = {
16
+ NO_SESSION_ID: "noSessionId",
17
+ ACTIVITY_TIMEOUT: "activityTimeout",
18
+ SESSION_PAST_MAXIMUM_LENGTH: "sessionPastMaximumLength",
19
+ };
20
+ const clampToRange = (value, min, max, defaultValue) => {
21
+ if (value < min || value > max) {
22
+ return defaultValue;
23
+ }
24
+ return value;
25
+ };
26
+ /**
27
+ * Manages session and window IDs with automatic timeout and persistence
28
+ */
29
+ export class SessionIdManager {
30
+ _sessionIdGenerator;
31
+ _windowIdGenerator;
32
+ _config;
33
+ _persistence;
34
+ _clock;
35
+ _windowId;
36
+ _sessionId;
37
+ _windowIdStorageKey;
38
+ _primaryWindowExistsStorageKey;
39
+ _sessionStartTimestamp;
40
+ _sessionActivityTimestamp;
41
+ _sessionIdChangedHandlers = [];
42
+ _sessionTimeoutMs;
43
+ _enforceIdleTimeout;
44
+ _canUseSessionStorageCache = null;
45
+ _lastStorageCheck = null;
46
+ _beforeUnloadHandler = null;
47
+ _pageHideHandler = null;
48
+ _visibilityChangeHandler = null;
49
+ _heartbeatInterval = null;
50
+ heartbeatPaused = false;
51
+ _debugLogger;
52
+ /**
53
+ * Creates a new SessionIdManager
54
+ * @param surface - The surface ID for storage key namespacing
55
+ * @param config - Configuration options
56
+ * @param persistence - Persistence layer for storing session data
57
+ * @param options - Optional generators and clock for testing
58
+ */
59
+ constructor(surface, config, persistence, options) {
60
+ this._config = config;
61
+ this._persistence = persistence;
62
+ this._clock = options?.clock || defaultClock;
63
+ this._debugLogger = options?.debugLogger;
64
+ this._windowId = undefined;
65
+ this._sessionId = undefined;
66
+ this._sessionStartTimestamp = null;
67
+ this._sessionActivityTimestamp = null;
68
+ this._sessionIdGenerator = options?.sessionId || uuidv7;
69
+ this._windowIdGenerator = options?.windowId || uuidv7;
70
+ const persistenceName = surface;
71
+ // Session idle timeout is now static - may be server-configurable in the future
72
+ const desiredTimeout = DEFAULT_SESSION_IDLE_TIMEOUT_SECONDS;
73
+ // Normalize timeout to milliseconds using utility function
74
+ this._sessionTimeoutMs = toMs(clampToRange(desiredTimeout, MIN_SESSION_IDLE_TIMEOUT_SECONDS, MAX_SESSION_IDLE_TIMEOUT_SECONDS, DEFAULT_SESSION_IDLE_TIMEOUT_SECONDS));
75
+ this._windowIdStorageKey = `interfere_${persistenceName}_window_id`;
76
+ this._primaryWindowExistsStorageKey = `interfere_${persistenceName}_primary_window_exists`;
77
+ // Handle window ID persistence
78
+ if (this._canUseSessionStorage()) {
79
+ // Clean up stale window flags first
80
+ this._cleanupStaleWindowFlags();
81
+ const lastWindowId = sessionStore._parse(this._windowIdStorageKey);
82
+ const primaryWindowExists = sessionStore._parse(this._primaryWindowExistsStorageKey);
83
+ if (lastWindowId &&
84
+ !primaryWindowExists &&
85
+ typeof lastWindowId === "string") {
86
+ this._windowId = lastWindowId;
87
+ }
88
+ else {
89
+ sessionStore._remove(this._windowIdStorageKey);
90
+ }
91
+ try {
92
+ sessionStore._set(this._primaryWindowExistsStorageKey, true);
93
+ // Set heartbeat timestamp for this window
94
+ sessionStore._set(`${this._windowIdStorageKey}_heartbeat`, this._clock.now());
95
+ }
96
+ catch {
97
+ // Gracefully handle session storage errors
98
+ }
99
+ }
100
+ // Handle bootstrap sessionID
101
+ if (config.sessionId) {
102
+ try {
103
+ const now = this._clock.now();
104
+ this._setSessionId(config.sessionId, now, now);
105
+ }
106
+ catch {
107
+ // Invalid sessionID in config, will generate a new one
108
+ }
109
+ }
110
+ this._resetIdleTimer();
111
+ this._listenToReloadWindow();
112
+ this._startWindowHeartbeat();
113
+ }
114
+ get sessionTimeoutMs() {
115
+ return this._sessionTimeoutMs;
116
+ }
117
+ /**
118
+ * Register a callback to be called when the session ID changes
119
+ * @param callback - Function to call when session changes
120
+ * @returns Unsubscribe function
121
+ */
122
+ onSessionId(callback) {
123
+ this._sessionIdChangedHandlers.push(callback);
124
+ // Always call callback with current state, even if sessionId is null
125
+ // Include appropriate change reason for initial call
126
+ const initialChangeReason = this._sessionId
127
+ ? undefined // Existing session, no change reason needed
128
+ : { [SessionChangeReason.NO_SESSION_ID]: true }; // No session yet
129
+ callback(this._sessionId || null, this._windowId || null, initialChangeReason);
130
+ return () => {
131
+ this._sessionIdChangedHandlers = this._sessionIdChangedHandlers.filter((h) => h !== callback);
132
+ };
133
+ }
134
+ _debugLog(message, error) {
135
+ if (this._debugLogger) {
136
+ this._debugLogger(message, error);
137
+ }
138
+ }
139
+ _canUseSessionStorage() {
140
+ // Re-evaluate periodically in case storage availability changes
141
+ // (e.g., Safari Private Mode toggles, quota exhausted)
142
+ const now = this._clock.now();
143
+ const CACHE_DURATION = 30_000; // Re-check every 30 seconds
144
+ if (this._canUseSessionStorageCache === null ||
145
+ !this._lastStorageCheck ||
146
+ now - this._lastStorageCheck > CACHE_DURATION) {
147
+ this._canUseSessionStorageCache =
148
+ this._config.persistence !== "memory" &&
149
+ !this._persistence.isDisabled() &&
150
+ sessionStore._is_supported();
151
+ this._lastStorageCheck = now;
152
+ }
153
+ return this._canUseSessionStorageCache;
154
+ }
155
+ _cleanupStaleWindowFlags() {
156
+ if (!this._canUseSessionStorage()) {
157
+ return;
158
+ }
159
+ try {
160
+ const STALE_WINDOW_TIMEOUT = 60_000; // Increased from 30s to 60s for mobile browser compatibility
161
+ const heartbeatKey = `${this._windowIdStorageKey}_heartbeat`;
162
+ const lastHeartbeat = sessionStore._parse(heartbeatKey);
163
+ if (typeof lastHeartbeat === "number") {
164
+ const timeSinceHeartbeat = this._clock.now() - lastHeartbeat;
165
+ if (timeSinceHeartbeat > STALE_WINDOW_TIMEOUT) {
166
+ // Clean up stale window flags
167
+ sessionStore._remove(this._primaryWindowExistsStorageKey);
168
+ sessionStore._remove(heartbeatKey);
169
+ }
170
+ }
171
+ else {
172
+ // No heartbeat found - check if primary window flag exists without heartbeat
173
+ // This handles cases where all tabs crashed and left phantom flags
174
+ const primaryWindowExists = sessionStore._parse(this._primaryWindowExistsStorageKey);
175
+ if (primaryWindowExists) {
176
+ this._debugLog("Found phantom primary window flag without heartbeat, cleaning up");
177
+ sessionStore._remove(this._primaryWindowExistsStorageKey);
178
+ }
179
+ }
180
+ }
181
+ catch (error) {
182
+ // Gracefully handle storage errors
183
+ this._debugLog("Heartbeat cleanup failed", error instanceof Error ? error : undefined);
184
+ }
185
+ }
186
+ _startWindowHeartbeat() {
187
+ if (typeof window === "undefined") {
188
+ return;
189
+ }
190
+ const HEARTBEAT_INTERVAL_MS = 5000; // 5 seconds
191
+ const writeHeartbeat = () => {
192
+ // Only write heartbeat when tab is visible and not paused to reduce storage pressure
193
+ if (!this.heartbeatPaused &&
194
+ typeof document !== "undefined" &&
195
+ document.visibilityState === "visible" &&
196
+ this._canUseSessionStorage()) {
197
+ try {
198
+ const heartbeatKey = `${this._windowIdStorageKey}_heartbeat`;
199
+ sessionStore._set(heartbeatKey, this._clock.now());
200
+ }
201
+ catch (error) {
202
+ // Storage failed - invalidate cache to re-check availability
203
+ this._debugLog("Heartbeat storage failed", error instanceof Error ? error : undefined);
204
+ this._canUseSessionStorageCache = null;
205
+ this._lastStorageCheck = null;
206
+ }
207
+ }
208
+ };
209
+ // Write initial heartbeat
210
+ writeHeartbeat();
211
+ // Continue periodic heartbeats
212
+ this._heartbeatInterval = setInterval(writeHeartbeat, HEARTBEAT_INTERVAL_MS);
213
+ }
214
+ _setWindowId(windowId) {
215
+ if (windowId !== this._windowId) {
216
+ this._windowId = windowId;
217
+ if (this._canUseSessionStorage() && windowId) {
218
+ try {
219
+ sessionStore._set(this._windowIdStorageKey, windowId);
220
+ }
221
+ catch {
222
+ // Gracefully handle session storage errors
223
+ }
224
+ }
225
+ }
226
+ }
227
+ _getWindowId() {
228
+ if (this._windowId) {
229
+ return this._windowId;
230
+ }
231
+ if (this._canUseSessionStorage()) {
232
+ const stored = sessionStore._parse(this._windowIdStorageKey);
233
+ return typeof stored === "string" ? stored : null;
234
+ }
235
+ return null;
236
+ }
237
+ _setSessionId(sessionId, sessionActivityTimestamp, sessionStartTimestamp) {
238
+ if (sessionId !== this._sessionId ||
239
+ sessionActivityTimestamp !== this._sessionActivityTimestamp ||
240
+ sessionStartTimestamp !== this._sessionStartTimestamp) {
241
+ this._sessionStartTimestamp = sessionStartTimestamp;
242
+ this._sessionActivityTimestamp = sessionActivityTimestamp;
243
+ this._sessionId = sessionId;
244
+ this._persistSessionWithOptimisticLocking(sessionId, sessionActivityTimestamp, sessionStartTimestamp);
245
+ }
246
+ }
247
+ _persistSessionWithOptimisticLocking(sessionId, sessionActivityTimestamp, sessionStartTimestamp) {
248
+ // Use optimistic locking to prevent race conditions between tabs
249
+ try {
250
+ const currentData = this._persistence.getProperty(SESSION_ID);
251
+ // If another tab updated more recently, don't overwrite
252
+ if (Array.isArray(currentData) &&
253
+ typeof currentData[0] === "number" &&
254
+ typeof sessionActivityTimestamp === "number" &&
255
+ currentData[0] > sessionActivityTimestamp) {
256
+ // Another tab has more recent activity, sync our state
257
+ this._sessionActivityTimestamp = currentData[0];
258
+ this._sessionId =
259
+ typeof currentData[1] === "string" ? currentData[1] : null;
260
+ this._sessionStartTimestamp =
261
+ typeof currentData[2] === "number"
262
+ ? currentData[2]
263
+ : sessionActivityTimestamp;
264
+ return;
265
+ }
266
+ // Add microsecond jitter to reduce same-timestamp collisions in production
267
+ // Skip jitter in test environments to maintain predictable behavior
268
+ const isTestEnvironment = typeof process !== "undefined" && process.env?.NODE_ENV === "test";
269
+ const finalTimestamp = sessionActivityTimestamp !== null && !isTestEnvironment
270
+ ? sessionActivityTimestamp + Math.random()
271
+ : sessionActivityTimestamp;
272
+ this._persistence.register({
273
+ [SESSION_ID]: [finalTimestamp, sessionId, sessionStartTimestamp],
274
+ });
275
+ // Only update our internal state after successful persistence
276
+ this._sessionActivityTimestamp = finalTimestamp;
277
+ }
278
+ catch (error) {
279
+ // Gracefully handle persistence errors (e.g., storage quota exceeded)
280
+ this._debugLog("Session persistence failed", error instanceof Error ? error : undefined);
281
+ // Don't update internal state if persistence failed to keep them in sync
282
+ }
283
+ }
284
+ _getSessionId() {
285
+ if (this._sessionId !== null &&
286
+ this._sessionId !== undefined &&
287
+ this._sessionActivityTimestamp !== null &&
288
+ this._sessionStartTimestamp !== null) {
289
+ return [
290
+ this._sessionActivityTimestamp,
291
+ this._sessionId,
292
+ this._sessionStartTimestamp,
293
+ ];
294
+ }
295
+ const sessionIdInfo = this._persistence.getProperty(SESSION_ID);
296
+ return this._parseSessionIdInfo(sessionIdInfo);
297
+ }
298
+ _parseSessionIdInfo(sessionIdInfo) {
299
+ if (!Array.isArray(sessionIdInfo)) {
300
+ this._debugLog(`Malformed session data: expected array, got ${typeof sessionIdInfo}`);
301
+ return [0, null, 0];
302
+ }
303
+ // Handle backwards compatibility for 2-element arrays
304
+ let normalizedInfo = sessionIdInfo;
305
+ if (sessionIdInfo.length === 2) {
306
+ const activityTs = sessionIdInfo[0];
307
+ const startTs = typeof activityTs === "number" ? activityTs : 0;
308
+ normalizedInfo = [...sessionIdInfo, startTs];
309
+ }
310
+ // Type guard for proper 3-element array
311
+ const EXPECTED_ARRAY_LENGTH = 3;
312
+ if (normalizedInfo.length < EXPECTED_ARRAY_LENGTH) {
313
+ this._debugLog(`Malformed session data: array too short (${normalizedInfo.length} < ${EXPECTED_ARRAY_LENGTH})`);
314
+ return [0, null, 0];
315
+ }
316
+ const rawActivityTs = normalizedInfo[0];
317
+ const rawSessionId = normalizedInfo[1];
318
+ const rawStartTs = normalizedInfo[2];
319
+ const parsedActivityTs = typeof rawActivityTs === "number" ? rawActivityTs : 0;
320
+ const parsedStartTs = typeof rawStartTs === "number" ? rawStartTs : 0;
321
+ // Log type mismatches for debugging
322
+ if (typeof rawActivityTs !== "number") {
323
+ this._debugLog(`Invalid activity timestamp type: ${typeof rawActivityTs}`);
324
+ }
325
+ if (typeof rawSessionId !== "string" && rawSessionId !== null) {
326
+ this._debugLog(`Invalid session ID type: ${typeof rawSessionId}`);
327
+ }
328
+ if (typeof rawStartTs !== "number") {
329
+ this._debugLog(`Invalid start timestamp type: ${typeof rawStartTs}`);
330
+ }
331
+ // Ensure start timestamp is not later than activity timestamp
332
+ const validStartTs = parsedStartTs > parsedActivityTs ? parsedActivityTs : parsedStartTs;
333
+ return [
334
+ parsedActivityTs,
335
+ typeof rawSessionId === "string" ? rawSessionId : null,
336
+ validStartTs,
337
+ ];
338
+ }
339
+ /**
340
+ * Reset the current session, forcing a new session to be created on next access
341
+ * @param reason - Optional reason for the reset
342
+ */
343
+ resetSessionId(reason) {
344
+ this._setSessionId(null, null, null);
345
+ // Notify handlers that session has been reset with appropriate reason
346
+ const changeReason = reason ?? {
347
+ [SessionChangeReason.NO_SESSION_ID]: true,
348
+ };
349
+ for (const handler of this._sessionIdChangedHandlers) {
350
+ handler(null, null, changeReason);
351
+ }
352
+ }
353
+ _performWindowCleanup() {
354
+ if (this._canUseSessionStorage()) {
355
+ // Check if we're the primary window before removing anything
356
+ const storedWindowId = sessionStore._parse(this._windowIdStorageKey);
357
+ const isPrimaryWindow = storedWindowId === this._windowId;
358
+ // Check for orphaned primary flag BEFORE removing our heartbeat
359
+ let shouldCleanupOrphanedFlag = false;
360
+ if (!isPrimaryWindow) {
361
+ try {
362
+ const heartbeatKey = `${this._windowIdStorageKey}_heartbeat`;
363
+ const lastHeartbeat = sessionStore._parse(heartbeatKey);
364
+ const ORPHAN_THRESHOLD = 30_000; // Increased from 10s to 30s
365
+ shouldCleanupOrphanedFlag =
366
+ typeof lastHeartbeat === "number" &&
367
+ this._clock.now() - lastHeartbeat > ORPHAN_THRESHOLD;
368
+ }
369
+ catch {
370
+ // If we can't check, err on the side of cleaning up
371
+ shouldCleanupOrphanedFlag = true;
372
+ }
373
+ }
374
+ // Now remove our own window ID and heartbeat
375
+ sessionStore._remove(this._windowIdStorageKey);
376
+ sessionStore._remove(`${this._windowIdStorageKey}_heartbeat`);
377
+ // Remove primary window flag if appropriate
378
+ if (isPrimaryWindow || shouldCleanupOrphanedFlag) {
379
+ sessionStore._remove(this._primaryWindowExistsStorageKey);
380
+ }
381
+ }
382
+ }
383
+ _listenToReloadWindow() {
384
+ if (typeof window === "undefined") {
385
+ return;
386
+ }
387
+ // Create shared cleanup handler
388
+ const cleanupHandler = () => this._performWindowCleanup();
389
+ // Set up multiple event listeners for better cross-browser compatibility
390
+ this._beforeUnloadHandler = cleanupHandler;
391
+ this._pageHideHandler = cleanupHandler;
392
+ this._visibilityChangeHandler = () => {
393
+ if (document.visibilityState === "hidden") {
394
+ // Pause heartbeat when document is hidden to save resources
395
+ this.heartbeatPaused = true;
396
+ // Use a small delay to distinguish between temporary hiding and permanent navigation
397
+ const VISIBILITY_CLEANUP_DELAY_MS = 100;
398
+ setTimeout(() => {
399
+ if (document.visibilityState === "hidden") {
400
+ this._performWindowCleanup();
401
+ }
402
+ }, VISIBILITY_CLEANUP_DELAY_MS);
403
+ }
404
+ else if (document.visibilityState === "visible") {
405
+ // Resume heartbeat when document becomes visible again
406
+ this.heartbeatPaused = false;
407
+ }
408
+ };
409
+ // Add all event listeners
410
+ window.addEventListener("beforeunload", this._beforeUnloadHandler, {
411
+ capture: false,
412
+ });
413
+ window.addEventListener("pagehide", this._pageHideHandler, {
414
+ capture: false,
415
+ });
416
+ if (typeof document !== "undefined") {
417
+ document.addEventListener("visibilitychange", this._visibilityChangeHandler, {
418
+ capture: false,
419
+ });
420
+ }
421
+ }
422
+ _sessionHasBeenIdleTooLong(timestamp, lastActivityTimestamp) {
423
+ // Don't use Math.abs - clock skew backwards should not revive old sessions
424
+ // Only consider session idle if current time is actually later than last activity
425
+ const timeSinceActivity = timestamp - lastActivityTimestamp;
426
+ // If clock went backwards, consider session still active (conservative approach)
427
+ if (timeSinceActivity < 0) {
428
+ return false;
429
+ }
430
+ return timeSinceActivity > this.sessionTimeoutMs;
431
+ }
432
+ /**
433
+ * Check and get the current session and window IDs, updating them if necessary
434
+ * @param readOnly - If true, won't update activity timestamp or reset idle timer
435
+ * @param _timestamp - Optional timestamp override (primarily for testing)
436
+ * @returns Session data with optional change reason
437
+ */
438
+ checkAndGetSessionAndWindowId(readOnly = false, _timestamp = null) {
439
+ const timestamp = _timestamp || this._clock.now();
440
+ const [lastActivityTimestamp, sessionId, startTimestamp] = this._getSessionId();
441
+ const windowId = this._getWindowId();
442
+ const changeReasons = this._evaluateSessionChangeReasons({
443
+ timestamp,
444
+ sessionId,
445
+ startTimestamp,
446
+ lastActivityTimestamp,
447
+ });
448
+ const { updatedSessionId, updatedWindowId, updatedStartTimestamp, valuesChanged, } = this._updateSessionIfNeeded({
449
+ sessionId,
450
+ windowId,
451
+ startTimestamp,
452
+ timestamp,
453
+ changeReasons,
454
+ });
455
+ const sessionData = this._finalizeSessionUpdate({
456
+ sessionId: updatedSessionId,
457
+ windowId: updatedWindowId,
458
+ startTimestamp: updatedStartTimestamp,
459
+ lastActivityTimestamp,
460
+ timestamp,
461
+ readOnly,
462
+ sessionPastMaximumLength: changeReasons.sessionPastMaximumLength,
463
+ valuesChanged,
464
+ changeReasons,
465
+ });
466
+ return sessionData;
467
+ }
468
+ _evaluateSessionChangeReasons(params) {
469
+ const { timestamp, sessionId, startTimestamp, lastActivityTimestamp } = params;
470
+ return {
471
+ [SessionChangeReason.NO_SESSION_ID]: !sessionId,
472
+ [SessionChangeReason.ACTIVITY_TIMEOUT]: this._sessionHasBeenIdleTooLong(timestamp, lastActivityTimestamp),
473
+ [SessionChangeReason.SESSION_PAST_MAXIMUM_LENGTH]: typeof startTimestamp === "number" &&
474
+ startTimestamp > 0 &&
475
+ timestamp - startTimestamp > SESSION_LENGTH_LIMIT_MILLISECONDS,
476
+ };
477
+ }
478
+ _updateSessionIfNeeded(params) {
479
+ const { sessionId, windowId, startTimestamp, timestamp, changeReasons } = params;
480
+ const { [SessionChangeReason.NO_SESSION_ID]: noSessionId, [SessionChangeReason.ACTIVITY_TIMEOUT]: activityTimeout, [SessionChangeReason.SESSION_PAST_MAXIMUM_LENGTH]: sessionPastMaximumLength, } = changeReasons;
481
+ if (noSessionId || activityTimeout || sessionPastMaximumLength) {
482
+ return {
483
+ updatedSessionId: this._sessionIdGenerator(),
484
+ // Keep existing window ID for continuity, only generate new one if none exists
485
+ updatedWindowId: windowId || this._windowIdGenerator(),
486
+ updatedStartTimestamp: timestamp,
487
+ valuesChanged: true,
488
+ };
489
+ }
490
+ if (!windowId) {
491
+ return {
492
+ updatedSessionId: sessionId,
493
+ updatedWindowId: this._windowIdGenerator(),
494
+ updatedStartTimestamp: startTimestamp,
495
+ valuesChanged: true,
496
+ };
497
+ }
498
+ return {
499
+ updatedSessionId: sessionId,
500
+ updatedWindowId: windowId,
501
+ updatedStartTimestamp: startTimestamp,
502
+ valuesChanged: false,
503
+ };
504
+ }
505
+ _calculateActivityTimestamp(params) {
506
+ const { lastActivityTimestamp, timestamp, readOnly, sessionPastMaximumLength, valuesChanged, changeReasons, } = params;
507
+ // Check if session was regenerated due to specific conditions
508
+ const noSessionId = changeReasons[SessionChangeReason.NO_SESSION_ID];
509
+ const activityTimeout = changeReasons[SessionChangeReason.ACTIVITY_TIMEOUT];
510
+ const sessionPastMaxLength = changeReasons[SessionChangeReason.SESSION_PAST_MAXIMUM_LENGTH];
511
+ const sessionWasRegenerated = valuesChanged && (noSessionId || activityTimeout || sessionPastMaxLength);
512
+ // Fixed logic: For timeout regeneration, preserve last activity time unless it's invalid
513
+ const shouldUpdateActivity = !readOnly ||
514
+ sessionPastMaximumLength ||
515
+ lastActivityTimestamp === 0 ||
516
+ (sessionWasRegenerated && (noSessionId || sessionPastMaxLength)); // Only update for new session or max length, NOT timeout
517
+ // For activity timeout, preserve the original last activity time to show when timeout occurred
518
+ // For other regenerations, use current timestamp to mark new activity
519
+ return shouldUpdateActivity ? timestamp : lastActivityTimestamp;
520
+ }
521
+ _finalizeSessionUpdate(params) {
522
+ const { sessionId, windowId, startTimestamp, lastActivityTimestamp, timestamp, readOnly, sessionPastMaximumLength, valuesChanged, changeReasons, } = params;
523
+ // Calculate the appropriate activity timestamp
524
+ const newActivityTimestamp = this._calculateActivityTimestamp({
525
+ lastActivityTimestamp,
526
+ timestamp,
527
+ readOnly,
528
+ sessionPastMaximumLength,
529
+ valuesChanged,
530
+ changeReasons,
531
+ });
532
+ // Handle session start timestamp consistently
533
+ const noSessionId = changeReasons[SessionChangeReason.NO_SESSION_ID];
534
+ const activityTimeout = changeReasons[SessionChangeReason.ACTIVITY_TIMEOUT];
535
+ const sessionPastMaxLength = changeReasons[SessionChangeReason.SESSION_PAST_MAXIMUM_LENGTH];
536
+ const sessionWasRegenerated = valuesChanged && (noSessionId || activityTimeout || sessionPastMaxLength);
537
+ // Use current timestamp if no start timestamp or if session was reset/regenerated
538
+ const sessionStartTimestamp = startTimestamp === 0 || sessionWasRegenerated
539
+ ? timestamp
540
+ : startTimestamp;
541
+ this._setWindowId(windowId);
542
+ this._setSessionId(sessionId, // Keep null internally
543
+ newActivityTimestamp, sessionStartTimestamp);
544
+ if (!readOnly) {
545
+ this._resetIdleTimer();
546
+ }
547
+ if (valuesChanged) {
548
+ for (const handler of this._sessionIdChangedHandlers) {
549
+ handler(sessionId, windowId, changeReasons); // Pass null values to handlers
550
+ }
551
+ }
552
+ // Ensure we always have a sessionId - generate one if null
553
+ const finalSessionId = sessionId || this._sessionIdGenerator();
554
+ // If we had to generate a sessionId, persist it
555
+ if (!sessionId && finalSessionId) {
556
+ this._setSessionId(finalSessionId, newActivityTimestamp, sessionStartTimestamp);
557
+ }
558
+ return {
559
+ sessionId: finalSessionId,
560
+ windowId, // Keep null for consistency with callbacks
561
+ sessionStartTimestamp,
562
+ lastActivityTimestamp: newActivityTimestamp,
563
+ ...(valuesChanged && { changeReason: changeReasons }),
564
+ };
565
+ }
566
+ _resetIdleTimer() {
567
+ // Always reset the timer - throttling was causing sessions to end prematurely
568
+ if (this._enforceIdleTimeout) {
569
+ this._clock.clearTimeout(this._enforceIdleTimeout);
570
+ }
571
+ this._enforceIdleTimeout = this._clock.setTimeout(() => {
572
+ try {
573
+ // Get fresh activity timestamp directly from persistence, not cached value
574
+ const sessionIdInfo = this._persistence.getProperty(SESSION_ID);
575
+ let lastActivityTimestamp = null;
576
+ if (Array.isArray(sessionIdInfo) &&
577
+ typeof sessionIdInfo[0] === "number") {
578
+ lastActivityTimestamp = sessionIdInfo[0];
579
+ }
580
+ const currentTime = this._clock.now();
581
+ // If we can't get a valid timestamp, reset the session to be safe
582
+ if (typeof lastActivityTimestamp === "number") {
583
+ if (this._sessionHasBeenIdleTooLong(currentTime, lastActivityTimestamp)) {
584
+ this.resetSessionId({
585
+ [SessionChangeReason.ACTIVITY_TIMEOUT]: true,
586
+ });
587
+ }
588
+ }
589
+ else {
590
+ // Persistence failure or corrupt data - reset session
591
+ this.resetSessionId({ [SessionChangeReason.ACTIVITY_TIMEOUT]: true });
592
+ }
593
+ }
594
+ catch (error) {
595
+ // Persistence error - reset session to be safe
596
+ this._debugLog("Idle timeout check failed", error instanceof Error ? error : undefined);
597
+ this.resetSessionId({ [SessionChangeReason.ACTIVITY_TIMEOUT]: true });
598
+ }
599
+ }, this._sessionTimeoutMs); // Use exact configured timeout
600
+ }
601
+ /**
602
+ * Clean up resources and event listeners
603
+ * Call this when the SessionIdManager is no longer needed
604
+ */
605
+ dispose() {
606
+ // Clear idle timeout
607
+ if (this._enforceIdleTimeout) {
608
+ this._clock.clearTimeout(this._enforceIdleTimeout);
609
+ this._enforceIdleTimeout = undefined;
610
+ }
611
+ // Clear heartbeat interval
612
+ if (this._heartbeatInterval) {
613
+ clearInterval(this._heartbeatInterval);
614
+ this._heartbeatInterval = null;
615
+ }
616
+ // Remove event listeners
617
+ if (typeof window !== "undefined") {
618
+ if (this._beforeUnloadHandler) {
619
+ window.removeEventListener("beforeunload", this._beforeUnloadHandler);
620
+ this._beforeUnloadHandler = null;
621
+ }
622
+ if (this._pageHideHandler) {
623
+ window.removeEventListener("pagehide", this._pageHideHandler);
624
+ this._pageHideHandler = null;
625
+ }
626
+ }
627
+ if (typeof document !== "undefined" && this._visibilityChangeHandler) {
628
+ document.removeEventListener("visibilitychange", this._visibilityChangeHandler);
629
+ this._visibilityChangeHandler = null;
630
+ }
631
+ // Clear handlers
632
+ this._sessionIdChangedHandlers = [];
633
+ }
634
+ }
635
+ //# sourceMappingURL=session-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../../src/session/session-manager.ts"],"names":[],"mappings":"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"}