feat(dashboard): fetch download manifests dynamically (#675)
This commit is contained in:
parent
eae77beeea
commit
5d1f442584
@ -10,7 +10,7 @@
|
||||
"prebuild": "tsx ../scripts/export-slugs.ts && tsx ../scripts/scan-md.ts && tsx ../scripts/fetch-dl-index.ts && node ../scripts/copy-manifests.js",
|
||||
"build": "next build",
|
||||
"build:static": "npm run prebuild && next build",
|
||||
"start": "next start",
|
||||
"start": "node ./scripts/start.js",
|
||||
"lint": "next lint",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"format": "prettier --write .",
|
||||
|
||||
23
dashboard/scripts/start.js
Normal file
23
dashboard/scripts/start.js
Normal file
@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const { spawn } = require('node:child_process')
|
||||
|
||||
const args = process.argv.slice(2)
|
||||
|
||||
const child = spawn('next', ['start', ...args], {
|
||||
stdio: 'inherit',
|
||||
shell: process.platform === 'win32',
|
||||
})
|
||||
|
||||
child.on('error', (error) => {
|
||||
console.error('Failed to launch Next.js:', error)
|
||||
process.exit(1)
|
||||
})
|
||||
|
||||
child.on('close', (code, signal) => {
|
||||
if (signal) {
|
||||
process.kill(process.pid, signal)
|
||||
} else {
|
||||
process.exit(code ?? 0)
|
||||
}
|
||||
})
|
||||
@ -1,4 +1,4 @@
|
||||
export const dynamic = 'error'
|
||||
export const dynamic = 'force-dynamic'
|
||||
|
||||
import { notFound } from 'next/navigation'
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@ interface RawDocResource {
|
||||
async function fetchDocs(): Promise<RawDocResource[]> {
|
||||
try {
|
||||
const response = await fetch(DOCS_MANIFEST_URL, {
|
||||
cache: 'no-cache',
|
||||
cache: 'no-store',
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
@ -58,15 +58,8 @@ async function loadDocs(): Promise<RawDocResource[]> {
|
||||
return fallbackDocs
|
||||
}
|
||||
|
||||
let cachedDocs: RawDocResource[] | null = null
|
||||
|
||||
async function getRawDocs(): Promise<RawDocResource[]> {
|
||||
if (cachedDocs) {
|
||||
return cachedDocs
|
||||
}
|
||||
|
||||
cachedDocs = await loadDocs()
|
||||
return cachedDocs
|
||||
return loadDocs()
|
||||
}
|
||||
|
||||
async function buildDocsDataset(): Promise<DocResource[]> {
|
||||
@ -76,20 +69,12 @@ async function buildDocsDataset(): Promise<DocResource[]> {
|
||||
)
|
||||
}
|
||||
|
||||
let cachedDocsDataset: DocResource[] | null = null
|
||||
|
||||
export async function getDocsDataset(): Promise<DocResource[]> {
|
||||
if (cachedDocsDataset) {
|
||||
return cachedDocsDataset
|
||||
}
|
||||
|
||||
cachedDocsDataset = await buildDocsDataset()
|
||||
return cachedDocsDataset
|
||||
return buildDocsDataset()
|
||||
}
|
||||
|
||||
export function clearDocsCache(): void {
|
||||
cachedDocs = null
|
||||
cachedDocsDataset = null
|
||||
// Intentionally left blank. Runtime fetches always return fresh data.
|
||||
}
|
||||
|
||||
|
||||
@ -258,20 +243,12 @@ async function buildDocsCollections(): Promise<DocCollection[]> {
|
||||
return buildCollections(docs)
|
||||
}
|
||||
|
||||
let cachedCollections: DocCollection[] | null = null
|
||||
|
||||
export async function getDocCollections(): Promise<DocCollection[]> {
|
||||
if (cachedCollections) {
|
||||
return cachedCollections
|
||||
}
|
||||
|
||||
cachedCollections = await buildDocsCollections()
|
||||
return cachedCollections
|
||||
return buildDocsCollections()
|
||||
}
|
||||
|
||||
export function clearCollectionsCache(): void {
|
||||
clearDocsCache()
|
||||
cachedCollections = null
|
||||
}
|
||||
|
||||
function normalizeResource(item: RawDocResource): DocResource | null {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export const dynamic = 'error'
|
||||
export const dynamic = 'force-dynamic'
|
||||
|
||||
import { notFound } from 'next/navigation'
|
||||
|
||||
|
||||
@ -2,15 +2,14 @@ import 'server-only'
|
||||
|
||||
import type { DirListing } from '@lib/download/types'
|
||||
import fallbackArtifacts from '../../../public/_build/artifacts-manifest.json'
|
||||
import fallbackOfflinePackage from '../../../public/_build/offline-package.json'
|
||||
|
||||
const ARTIFACTS_MANIFEST_URL = 'https://dl.svc.plus/dl-index/artifacts-manifest.json'
|
||||
const FALLBACK_LISTINGS_URL = 'https://dl.svc.plus/dl-index/offline-package.json'
|
||||
const FALLBACK_LISTINGS_URL = 'https://dl.svc.plus/dl-index/offline-package-manifest.json'
|
||||
|
||||
async function fetchListings(url: string): Promise<DirListing[]> {
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
cache: 'no-cache',
|
||||
cache: 'no-store',
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
@ -41,17 +40,10 @@ async function loadDownloadListings(): Promise<DirListing[]> {
|
||||
return fallbackArtifacts as DirListing[]
|
||||
}
|
||||
|
||||
let cachedListings: DirListing[] | null = null
|
||||
|
||||
export async function getDownloadListings(): Promise<DirListing[]> {
|
||||
if (cachedListings) {
|
||||
return cachedListings
|
||||
}
|
||||
|
||||
cachedListings = await loadDownloadListings()
|
||||
return cachedListings
|
||||
return loadDownloadListings()
|
||||
}
|
||||
|
||||
export function clearDownloadListingsCache(): void {
|
||||
cachedListings = null
|
||||
}
|
||||
// Intentionally left blank. Runtime fetches always return fresh data.
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ const OFFLINE_PACKAGE_URL = 'https://dl.svc.plus/dl-index/offline-package-manife
|
||||
export async function fetchOfflinePackageListings(): Promise<DirListing[]> {
|
||||
try {
|
||||
const response = await fetch(OFFLINE_PACKAGE_URL, {
|
||||
cache: 'no-cache',
|
||||
cache: 'no-store',
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
@ -27,18 +27,11 @@ export async function fetchOfflinePackageListings(): Promise<DirListing[]> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cached offline-package listings
|
||||
* This is a simple in-memory cache - in production you might want to use a more robust solution
|
||||
* Retrieve offline-package listings on demand.
|
||||
* Data is fetched dynamically so updates are reflected without a deploy.
|
||||
*/
|
||||
let cachedListings: DirListing[] | null = null
|
||||
|
||||
export async function getOfflinePackageListings(): Promise<DirListing[]> {
|
||||
if (cachedListings) {
|
||||
return cachedListings
|
||||
}
|
||||
|
||||
cachedListings = await fetchOfflinePackageListings()
|
||||
return cachedListings
|
||||
return fetchOfflinePackageListings()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -78,5 +71,5 @@ export async function getOfflinePackageFileCount(): Promise<number> {
|
||||
* Clear the cache (useful for testing or when data might have changed)
|
||||
*/
|
||||
export function clearOfflinePackageCache(): void {
|
||||
cachedListings = null
|
||||
// Intentionally left blank. Runtime fetches always return fresh data.
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user