native-tab-page-cache.ts 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import { isPageCacheEnabled } from 'app/lib/cache/cache-flags'
  2. /** Separates composite key parts; never appears in tabKey / url / session. */
  3. const SEP = '\u0000'
  4. const pageDataCache = new Map()
  5. /** `${url}${SEP}${session}` → Set of full page cache keys (all tabs). */
  6. const keysByUrlSession = new Map()
  7. function sessionKey(userId: number | string, confirmed: boolean) {
  8. return userId ? `${userId}:${confirmed ? 1 : 0}` : 'guest'
  9. }
  10. function pageCacheKey(tabKey: string | null | undefined, url: string, session: any) {
  11. return `${tabKey}${SEP}${url}${SEP}${session}`
  12. }
  13. function urlSessionIndexKey(url: string, session: any) {
  14. return `${url}${SEP}${session}`
  15. }
  16. function indexAdd(url: string, session: any, key: string) {
  17. const indexKey = urlSessionIndexKey(url, session)
  18. let set = keysByUrlSession.get(indexKey)
  19. if (!set) {
  20. set = new Set()
  21. keysByUrlSession.set(indexKey, set)
  22. }
  23. set.add(key)
  24. }
  25. export function getCachedPageData(tabKey: string | null | undefined, url: string, userId: number | string, confirmed: boolean) {
  26. if (!isPageCacheEnabled()) return null
  27. if (!tabKey || !url) return null
  28. return pageDataCache.get(pageCacheKey(tabKey, url, sessionKey(userId, confirmed))) ?? null
  29. }
  30. export function setCachedPageData(tabKey: string | null | undefined, url: string, props: any, userId: number | string, confirmed: boolean) {
  31. if (!isPageCacheEnabled()) return
  32. if (!tabKey || !url || !props) return
  33. const session = sessionKey(userId, confirmed)
  34. const key = pageCacheKey(tabKey, url, session)
  35. pageDataCache.set(key, props)
  36. indexAdd(url, session, key)
  37. }
  38. /**
  39. * Write-through after in-page soft-reload (e.g. Trust/connections).
  40. * Updates every tab entry for this URL + session via the url/session index
  41. * (no string parsing of composite keys).
  42. */
  43. export function patchCachedPageDataByUrl(url: string, pageData: any, userId: number | string, confirmed: boolean) {
  44. if (!isPageCacheEnabled()) return
  45. if (!url || !pageData) return
  46. const session = sessionKey(userId, confirmed)
  47. const keys = keysByUrlSession.get(urlSessionIndexKey(url, session))
  48. if (!keys?.size) return
  49. const now = Date.now()
  50. for (const key of keys) {
  51. const props = pageDataCache.get(key)
  52. if (!props) continue
  53. pageDataCache.set(key, {
  54. ...props,
  55. data: {
  56. ...pageData,
  57. timestamp: now,
  58. },
  59. })
  60. }
  61. }
  62. export function clearTabPageCache() {
  63. pageDataCache.clear()
  64. keysByUrlSession.clear()
  65. }