import { type OperationInterval, operationIntervalsOverlap, operationsSyncPriority } from './operations-sync-plan'; export type OperationsIntent = { atomic: boolean; atomicIntervals?: string[]; intervals: string[]; screenIntervals?: string[]; }; export function intervalKey(interval: OperationInterval): string { // eslint-disable-next-line sonarjs/no-inverted-boolean-check -- Negation also rejects Invalid Date; >= would silently accept NaN. if (!(interval.from < interval.to)) { throw new Error('Invalid operations interval'); } return JSON.stringify([ interval.accountId, interval.from.toISOString(), interval.to.toISOString(), interval.instrumentUid ?? '', ]); } export function decodeInterval(key: string): OperationInterval { const [accountId, from, to, instrumentUid] = JSON.parse(key) as string[]; return { accountId, from: new Date(from), to: new Date(to), ...(instrumentUid ? { instrumentUid } : {}), }; } export function extendRunningIntent(input: { additions: OperationInterval[]; intervals: OperationInterval[]; pending: OperationInterval[]; previous: OperationsIntent | undefined; previousPriority: number; priority: number; publicationAtomic: boolean; }): OperationsIntent { const { previous, pending, additions, intervals, priority, previousPriority, publicationAtomic } = input; const overlapsRequested = (item: OperationInterval) => intervals.some((target) => operationIntervalsOverlap(item, target)); const retainedScreen = previous?.screenIntervals ?? (previousPriority === operationsSyncPriority.screen ? (previous?.intervals ?? []) : []); const addedScreen = priority === operationsSyncPriority.screen ? [...pending, ...additions].filter(overlapsRequested).map(intervalKey) : []; const ordered = priority < previousPriority ? [ ...pending.filter(overlapsRequested), ...additions, ...pending.filter((item) => !overlapsRequested(item)), ] : [...pending, ...additions]; return { atomic: previous?.atomic ?? publicationAtomic, atomicIntervals: previous?.atomic ? [...new Set([...(previous.atomicIntervals ?? previous.intervals), ...additions.map(intervalKey)])] : [], screenIntervals: [...new Set([...retainedScreen, ...addedScreen])], intervals: ordered.map(intervalKey), }; }