Files
prop-ai-hr/mobile-uni/src/services/request-scope.ts
T

71 lines
1.9 KiB
TypeScript

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<string, number>();
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)
};
};