project-transition-state.ts 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. export const FALLBACK_LONG_RUNNING_STATE_THRESHOLD_MINUTES = 10
  2. // Persist long enough for same-browser reloads, but not so long that a later transition reuses stale state.
  3. export const MAX_PERSISTED_TRANSITION_AGE_HOURS = 24
  4. const MS_PER_MINUTE = 60 * 1000
  5. const MS_PER_HOUR = 60 * MS_PER_MINUTE
  6. export const minutesToMilliseconds = (minutes: number) => minutes * MS_PER_MINUTE
  7. export const hoursToMilliseconds = (hours: number) => hours * MS_PER_HOUR
  8. export const getPersistedTransitionStartTime = (
  9. storageKey: string,
  10. now = Date.now(),
  11. maxAgeMs = Number.POSITIVE_INFINITY
  12. ) => {
  13. if (typeof window === 'undefined') return now
  14. const existingValue = window.localStorage.getItem(storageKey)
  15. if (existingValue !== null) {
  16. const parsedStartTime = Number(existingValue)
  17. const elapsedMs = now - parsedStartTime
  18. if (
  19. Number.isFinite(parsedStartTime) &&
  20. parsedStartTime > 0 &&
  21. elapsedMs >= 0 &&
  22. elapsedMs <= maxAgeMs
  23. ) {
  24. return parsedStartTime
  25. }
  26. }
  27. window.localStorage.setItem(storageKey, String(now))
  28. return now
  29. }
  30. export const clearPersistedTransitionStartTime = (storageKey: string) => {
  31. if (typeof window === 'undefined') return
  32. window.localStorage.removeItem(storageKey)
  33. }
  34. export const getRemainingTransitionTimeMs = ({
  35. startTimeMs,
  36. thresholdMs,
  37. now = Date.now(),
  38. }: {
  39. startTimeMs: number
  40. thresholdMs: number
  41. now?: number
  42. }) => {
  43. const elapsedMs = now - startTimeMs
  44. return Math.max(thresholdMs - elapsedMs, 0)
  45. }