Files
wikideck/shared/enrichment.ts
T
2026-10-19 16:47:27 -04:00

37 lines
1.5 KiB
TypeScript

/** Live, off-chain Wikipedia data. Text fields are plain strings, never HTML. */
export interface PageEnrichment {
pageId: number;
title: string;
description: string | null;
wikidataId: string | null;
revisionId: number;
pageBytes: number;
/** Number of returned interlanguage links (a lower bound when truncated). */
languageCount: number;
languagesTruncated: boolean;
categories: string[];
categoriesTruncated: boolean;
fetchedAt: string;
pageviews: {
status: 'available' | 'unavailable';
/** Six completed UTC months, oldest first, identified as YYYY-MM. */
months: { month: string; views: number }[];
latestMonth: string;
total: number | null;
/** Latest completed month's views divided by its actual UTC day count. */
dailyAverage: number | null;
trendPercent: number | null;
};
stats: { attention: number | null; depth: number; reach: number };
}
/** Attention uses the latest completed month's views, not the six-month total. */
export function deriveStats(pageBytes: number, languageCount: number, monthlyViews: number | null): PageEnrichment['stats'] {
const score = (value: number, scale: number) => {
if (!Number.isFinite(value) || value < 0) throw new RangeError('Invalid enrichment score input');
return Math.min(100, Math.round(Math.log10(value + 1) / scale * 100));
};
return { attention: monthlyViews === null ? null : score(monthlyViews, 6),
depth: score(pageBytes, 6), reach: score(languageCount, 3) };
}