| import type { FreshnessCheck } from './types'; |
|
|
| function parseFiniteRecordCount(raw: unknown): number | null { |
| if (typeof raw === 'number') return Number.isFinite(raw) ? raw : null; |
| if (typeof raw === 'string' && raw.trim() !== '') { |
| const parsed = Number(raw); |
| return Number.isFinite(parsed) ? parsed : null; |
| } |
| return null; |
| } |
|
|
| export function evaluateFreshness(checks: FreshnessCheck[], metas: unknown[], now = Date.now()): { cached_at: string | null; stale: boolean } { |
| let stale = false; |
| let oldestFetchedAt = Number.POSITIVE_INFINITY; |
| let hasAnyValidMeta = false; |
| let hasAllValidMeta = true; |
|
|
| for (const [i, check] of checks.entries()) { |
| const meta = metas[i]; |
| const fetchedAt = meta && typeof meta === 'object' && 'fetchedAt' in meta |
| ? Number((meta as { fetchedAt: unknown }).fetchedAt) |
| : Number.NaN; |
|
|
| if (!Number.isFinite(fetchedAt) || fetchedAt <= 0) { |
| hasAllValidMeta = false; |
| stale = true; |
| continue; |
| } |
|
|
| hasAnyValidMeta = true; |
| oldestFetchedAt = Math.min(oldestFetchedAt, fetchedAt); |
| stale ||= (now - fetchedAt) / 60_000 > check.maxStaleMin; |
|
|
| if (check.minRecordCount != null) { |
| const recordCount = meta && typeof meta === 'object' && 'recordCount' in meta |
| ? parseFiniteRecordCount((meta as { recordCount: unknown }).recordCount) |
| : null; |
| stale ||= recordCount == null || recordCount < check.minRecordCount; |
| } |
| } |
|
|
| return { |
| cached_at: hasAnyValidMeta && hasAllValidMeta ? new Date(oldestFetchedAt).toISOString() : null, |
| stale, |
| }; |
| } |
|
|