Skip to content

Commit 54aab8b

Browse files
authored
cleanup old sessionData_ localStorage values (#120)
## Summary Duplicate tabs would not clean up their old localStorage values, leading to issues where we would exceed localStorage quota. ## How did you test this change? local deploy https://www.loom.com/share/9c351101df184660a24433325f82bba4 ## Are there any deployment considerations? changeset
1 parent 6be685e commit 54aab8b

File tree

3 files changed

+73
-3
lines changed

3 files changed

+73
-3
lines changed

.changeset/swift-dodos-watch.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'highlight.run': patch
3+
'@launchdarkly/observability': patch
4+
'@launchdarkly/session-replay': patch
5+
---
6+
7+
delete sessionData\_ localstorage values to avoid overfilling quota

sdk/highlight-run/src/client/utils/sessionStorage/highlightSession.ts

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
import { SESSION_PUSH_THRESHOLD } from '../../constants/sessions'
2-
import { cookieStorage, getItem, removeItem, setItem } from '../storage'
2+
import {
3+
cookieStorage,
4+
getItem,
5+
removeItem,
6+
setItem,
7+
getPersistentStorage,
8+
} from '../storage'
39
import { SESSION_STORAGE_KEYS } from './sessionStorageKeys'
10+
import { internalLogOnce } from '../../../sdk/util'
411

512
export type SessionData = {
613
sessionSecureID: string
@@ -76,7 +83,10 @@ export const setSessionData = function (sessionData?: SessionData) {
7683
if (!sessionData?.sessionSecureID) return
7784
const secureID = sessionData.sessionSecureID!
7885
setPersistentSessionSecureID(secureID)
79-
setItem(getSessionDataKey(secureID), JSON.stringify(sessionData))
86+
const key = getSessionDataKey(secureID)
87+
setItem(key, JSON.stringify(sessionData))
88+
// delete old session data
89+
pruneSessionData(key)
8090
}
8191

8292
export const loadCookieSessionData = function () {
@@ -90,3 +100,46 @@ export const loadCookieSessionData = function () {
90100
setSessionData(JSON.parse(sessionDataStr) as SessionData)
91101
} catch (e) {}
92102
}
103+
104+
function pruneSessionData(keepKey: string): void {
105+
const prefix = `${SESSION_STORAGE_KEYS.SESSION_DATA}_`
106+
107+
// Walk backwards so index order isn’t upset by removals.
108+
for (let i = getPersistentStorage().length - 1; i >= 0; i--) {
109+
const key = getPersistentStorage().key(i)
110+
if (key && key.startsWith(prefix) && key !== keepKey) {
111+
try {
112+
const sessionData = JSON.parse(
113+
getItem(key) || '{}',
114+
) as SessionData
115+
if (sessionData.lastPushTime === undefined) {
116+
internalLogOnce(
117+
'highlightSession',
118+
'pruneSessionData',
119+
'error',
120+
`data for key ${key} is not session data`,
121+
)
122+
} else if (
123+
Date.now() - sessionData.lastPushTime >=
124+
SESSION_PUSH_THRESHOLD
125+
) {
126+
internalLogOnce(
127+
'highlightSession',
128+
'pruneSessionData',
129+
'debug',
130+
`removing session data for stale key ${key}`,
131+
)
132+
removeItem(key)
133+
}
134+
} catch (e) {
135+
internalLogOnce(
136+
'highlightSession',
137+
'pruneSessionData',
138+
'error',
139+
`failed to parse session data for key ${key}`,
140+
e,
141+
)
142+
}
143+
}
144+
}
145+
}

sdk/highlight-run/src/client/utils/storage.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@ let cookieWriteEnabled: boolean = true
1313

1414
class Storage {
1515
private storage: { [key: string]: string } = {}
16+
17+
public get length(): number {
18+
return Object.keys(this.storage).length
19+
}
20+
21+
public key(index: number): string | null {
22+
const keys = Object.keys(this.storage)
23+
return keys[index] ?? null
24+
}
25+
1626
public getItem(key: string) {
1727
return this.storage[key] ?? ''
1828
}
@@ -49,7 +59,7 @@ export class CookieStorage {
4959
export const globalStorage = new Storage()
5060
export const cookieStorage = new CookieStorage()
5161

52-
const getPersistentStorage = () => {
62+
export const getPersistentStorage = () => {
5363
let storage:
5464
| Storage
5565
| typeof window.localStorage

0 commit comments

Comments
 (0)