1
0
mirror of https://github.com/jcwimer/wrestlingApp synced 2026-04-15 01:17:12 +00:00
Files
wrestlingdev.com/app/assets/javascripts/lib/match_state/transport.js

117 lines
2.9 KiB
JavaScript

export const MATCH_DATA_TTL_MS = 48 * 60 * 60 * 1000
export const SHORT_LIVED_TTL_MS = 4 * 60 * 60 * 1000
const STORAGE_MARKER = "__wrestlingAppStorage"
export function loadJson(storage, key) {
try {
const rawValue = storage.getItem(key)
if (!rawValue) return null
const parsed = JSON.parse(rawValue)
if (!isExpiringStorageValue(parsed)) return parsed
if (isExpired(parsed)) {
storage.removeItem(key)
return null
}
return parsed.value
} catch (_error) {
return null
}
}
export function saveJson(storage, key, value, options = {}) {
try {
const valueToStore = options.ttlMs
? expiringStorageValue(value, options.ttlMs)
: value
storage.setItem(key, JSON.stringify(valueToStore))
return true
} catch (_error) {
return false
}
}
export function removeKey(storage, key) {
try {
storage.removeItem(key)
return true
} catch (_error) {
return false
}
}
export function performIfChanged(subscription, action, payload, lastSerializedPayload) {
if (!subscription) return lastSerializedPayload
const serializedPayload = JSON.stringify(payload)
if (serializedPayload === lastSerializedPayload) {
return lastSerializedPayload
}
subscription.perform(action, payload)
return serializedPayload
}
export function cleanupExpiredLocalStorage(storage, now = Date.now()) {
try {
const keys = []
for (let index = 0; index < storage.length; index += 1) {
const key = storage.key(index)
if (key && ttlForStorageKey(key)) keys.push(key)
}
keys.forEach((key) => cleanupStorageKey(storage, key, now))
} catch (_error) {
}
}
function cleanupStorageKey(storage, key, now) {
const ttlMs = ttlForStorageKey(key)
if (!ttlMs) return
const rawValue = storage.getItem(key)
if (!rawValue) return
try {
const parsed = JSON.parse(rawValue)
if (isExpiringStorageValue(parsed)) {
if (isExpired(parsed, now)) storage.removeItem(key)
return
}
const legacyUpdatedAt = Date.parse(parsed?.updated_at)
if (legacyUpdatedAt && now - legacyUpdatedAt > ttlMs) {
storage.removeItem(key)
return
}
storage.setItem(key, JSON.stringify(expiringStorageValue(parsed, ttlMs, legacyUpdatedAt || now)))
} catch (_error) {
storage.removeItem(key)
}
}
function expiringStorageValue(value, ttlMs, storedAt = Date.now()) {
return {
[STORAGE_MARKER]: true,
expiresAt: storedAt + ttlMs,
value
}
}
function isExpiringStorageValue(value) {
return value && typeof value === "object" && value[STORAGE_MARKER] === true
}
function isExpired(value, now = Date.now()) {
return Number(value.expiresAt) <= now
}
function ttlForStorageKey(key) {
if (key.startsWith("match-state:")) return MATCH_DATA_TTL_MS
if (/^w[12]-\d+-\d+$/.test(key)) return MATCH_DATA_TTL_MS
if (key.startsWith("mat-selected-bout:")) return SHORT_LIVED_TTL_MS
if (key.startsWith("mat-last-match-result:")) return SHORT_LIVED_TTL_MS
return null
}