import { getAuth } from './auth'; export interface RequestScopeTicket { accountKey: string; pageGeneration: number; lane: string; laneGeneration: number; } export interface PageRequestScope { activate: () => void; begin: (lane: string) => RequestScopeTicket; invalidate: () => void; isCurrent: (ticket: RequestScopeTicket) => boolean; } const tokenFingerprint = (token: string) => { let hash = 2166136261; for (let index = 0; index < token.length; index += 1) { hash ^= token.charCodeAt(index); hash = Math.imul(hash, 16777619); } return (hash >>> 0).toString(16).padStart(8, '0'); }; export const currentAccountKey = () => { const auth = getAuth(); return `${auth.phone}|${auth.clientId}|${tokenFingerprint(auth.token)}`; }; export const createPageRequestScope = (): PageRequestScope => { let active = false; let accountKey = ''; let pageGeneration = 0; const laneGenerations = new Map(); const activate = () => { active = true; accountKey = currentAccountKey(); pageGeneration += 1; laneGenerations.clear(); }; const begin = (lane: string): RequestScopeTicket => { const nextAccountKey = currentAccountKey(); if (active && nextAccountKey !== accountKey) { accountKey = nextAccountKey; pageGeneration += 1; laneGenerations.clear(); } const laneGeneration = (laneGenerations.get(lane) || 0) + 1; laneGenerations.set(lane, laneGeneration); return { accountKey, pageGeneration, lane, laneGeneration }; }; return { activate, begin, invalidate: () => { active = false; pageGeneration += 1; laneGenerations.clear(); }, isCurrent: (ticket) => active && ticket.pageGeneration === pageGeneration && ticket.accountKey === accountKey && ticket.accountKey === currentAccountKey() && ticket.laneGeneration === laneGenerations.get(ticket.lane) }; };