39 lines
1.4 KiB
TypeScript
39 lines
1.4 KiB
TypeScript
import { SENT_STALE_MS, type VoiceRecord } from './record';
|
|
|
|
export interface Located {
|
|
path: string;
|
|
record: VoiceRecord;
|
|
}
|
|
|
|
const time = (iso?: string) => (iso ? Date.parse(iso) : NaN);
|
|
|
|
// Отсутствующее или испорченное время — не повод зависнуть навсегда.
|
|
export function isStaleSent(r: VoiceRecord, now: Date): boolean {
|
|
if (r.status !== 'sent') return false;
|
|
const t = time(r.sentAt);
|
|
return Number.isNaN(t) || now.getTime() - t > SENT_STALE_MS;
|
|
}
|
|
|
|
export function due(items: readonly Located[], now: Date, deviceId: string): Located[] {
|
|
return items
|
|
.filter(({ record: r }) => {
|
|
if (r.device !== deviceId) return false;
|
|
if (r.status === 'saved') return true;
|
|
if (r.status !== 'retry') return false;
|
|
const t = time(r.nextAttempt);
|
|
return Number.isNaN(t) || t <= now.getTime();
|
|
})
|
|
.sort((a, b) => (a.record.id < b.record.id ? -1 : a.record.id > b.record.id ? 1 : 0));
|
|
}
|
|
|
|
export function staleOwn(items: readonly Located[], now: Date, deviceId: string): Located[] {
|
|
return items.filter(({ record: r }) => r.device === deviceId && isStaleSent(r, now));
|
|
}
|
|
|
|
export function claimable(items: readonly Located[], now: Date, deviceId: string): Located[] {
|
|
return items.filter(
|
|
({ record: r }) =>
|
|
r.device !== deviceId && (r.status === 'saved' || r.status === 'retry' || isStaleSent(r, now)),
|
|
);
|
|
}
|