62 lines
1.7 KiB
JavaScript
62 lines
1.7 KiB
JavaScript
const MODELS_DEV_API_URL = 'https://models.dev/api.json';
|
|||
|
|
const DEFAULT_TTL_MS = 10 * 60 * 1000;
|
||
|
|
const DEFAULT_TIMEOUT_MS = 8000;
|
||
|
|
|
||
|
|
// Shared in-process cache of the models.dev catalog. Used by the
|
||
|
|
// /api/openchamber/models-metadata route and the small-model resolver so the
|
||
|
|
// server fetches the catalog once, not per consumer.
|
||
|
|
let cachedMetadata = null;
|
||
|
|
let cachedAt = 0;
|
||
|
|
let inflight = null;
|
||
|
|
|
||
|
|
const fetchCatalog = async (url, timeoutMs) => {
|
||
|
|
const response = await fetch(url, {
|
||
|
|
headers: { Accept: 'application/json' },
|
||
|
|
signal: AbortSignal.timeout(timeoutMs),
|
||
|
|
});
|
||
|
|
if (!response.ok) {
|
||
|
|
throw new Error(`models.dev responded with status ${response.status}`);
|
||
|
|
}
|
||
|
|
const metadata = await response.json();
|
||
|
|
if (!metadata || typeof metadata !== 'object') {
|
||
|
|
throw new Error('models.dev returned an unexpected payload');
|
||
|
|
}
|
||
|
|
return metadata;
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the models.dev catalog, serving the in-memory copy while fresh.
|
||
|
|
* On fetch failure a stale cached copy is returned when available; otherwise
|
||
|
|
* the error propagates.
|
||
|
|
*/
|
||
|
|
export async function getModelsMetadata({
|
||
|
|
url = MODELS_DEV_API_URL,
|
||
|
|
ttlMs = DEFAULT_TTL_MS,
|
||
|
|
timeoutMs = DEFAULT_TIMEOUT_MS,
|
||
|
|
} = {}) {
|
||
|
|
const now = Date.now();
|
||
|
|
if (cachedMetadata && now - cachedAt < ttlMs) {
|
||
|
|
return { metadata: cachedMetadata, fromCache: true };
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!inflight) {
|
||
|
|
inflight = fetchCatalog(url, timeoutMs).finally(() => {
|
||
|
|
inflight = null;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
try {
|
||
|
|
const metadata = await inflight;
|
||
|
|
cachedMetadata = metadata;
|
||
|
|
cachedAt = Date.now();
|
||
|
|
return { metadata, fromCache: false };
|
||
|
|
} catch (error) {
|
||
|
|
if (cachedMetadata) {
|
||
|
|
return { metadata: cachedMetadata, fromCache: true, stale: true };
|
||
|
|
}
|
||
|
|
throw error;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export { MODELS_DEV_API_URL };
|