import fetch from 'node-fetch' import crypto from 'crypto' import { config } from './config.js' async function fetchData (path, baseUrl) { const response = await fetch(new URL(path, baseUrl)) if (!response.ok) throw new Error('Error fetching file') const content = await response.buffer() const sha256Sum = crypto.createHash('sha256').update(content).digest('base64') return [path, { 'content-type': response.headers.get('content-type'), sha256Sum, content }] } class FileCache { constructor () { this._cache = {} } async warmUp (manifests, deps) { const cache = Object.fromEntries(await (async function () { const files = Object.keys(deps) const chunkSize = Math.ceil(files.length / 50) const result = [] while (files.length > 0) { result.push.apply(result, (await Promise.all(files.splice(0, chunkSize).map(async file => { try { const manifest = manifests[file] || Object.values(manifests).find(m => m.file === file || (m?.assets?.indexOf(file) >= 0) || (m?.css?.indexOf(file) >= 0) ) if (!manifest) { console.error('could not find manifest for', file) return null } return fetchData(file, manifest.meta.baseUrl) } catch (e) { console.error(e) } }))).filter(data => Array.isArray(data) && data.length === 2)) } return result }())) this._cache = cache } async fetchAndStore (path) { if (config.urls.length === 0) await config.load() const [[key, value]] = (await Promise.allSettled(config.urls.map(baseUrl => fetchData(path, baseUrl)))) .filter(r => r.status === 'fulfilled').map(r => r.value) this._cache[key] = value return value } get (path) { return this?._cache[path.slice(1)] || {} } } export const fileCache = new FileCache()