| 1 |
1 |
import type { Metadata } from 'next'; |
|
2 |
+import { unstable_cache } from 'next/cache'; |
| 2 |
3 |
|
| 3 |
4 |
import Link from 'next/link'; |
| 4 |
5 |
import { readFile } from 'node:fs/promises'; |
| 13 |
14 |
|
| 14 |
15 |
export const metadata: Metadata = { title: 'Data & methodology', description: 'Coverage by category, source and connector; RareIndex methodology; exports and API access.' }; |
| 15 |
16 |
// Coverage aggregates over millions of rows take ~70 s: prerender at build (staticPageGenerationTimeout raised), then hourly ISR. |
| 16 |
|
−export const revalidate = 3600; |
|
17 |
+// Rendered on demand and cached for an hour at runtime: the coverage aggregates run over millions of |
|
18 |
+// rows and exceeded the 240 s prerender budget at build time, which broke deployments. |
|
19 |
+export const dynamic = 'force-dynamic'; |
|
20 |
+const loadDataPage = unstable_cache(async () => Promise.all([getSiteStats(), getConnectorCoverage(), getFxCoverage(), getMarketRows()]), ['data-page-v1'], { revalidate: 3600 }); |
| 17 |
21 |
|
| 18 |
22 |
async function loadMethodology(): Promise<string> { |
| 19 |
23 |
const candidates = [path.resolve(process.cwd(), '../../docs/METHODOLOGY.md'), path.resolve(process.cwd(), 'docs/METHODOLOGY.md'), path.resolve(process.cwd(), '../docs/METHODOLOGY.md')]; |
| 49 |
53 |
} |
| 50 |
54 |
|
| 51 |
55 |
export default async function DataPage() { |
| 52 |
|
− const [stats, connectors, fx, rows, md] = await Promise.all([getSiteStats(), getConnectorCoverage(), getFxCoverage(), getMarketRows(), loadMethodology()]); |
|
56 |
+ const [[stats, connectors, fx, rows], md] = await Promise.all([loadDataPage(), loadMethodology()]); |
| 53 |
57 |
const active = rows.filter((r) => r.counts.assets > 0); |
| 54 |
58 |
return ( |
| 55 |
59 |
<div> |