Files
BarangaySystem/resources/js/utils/fetchWithCache.js
2026-06-06 18:43:00 +08:00

68 lines
1.6 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { deepEqual } from '@/utils/deepEqual'
import { executeRequest } from './executeRequest'
const cacheStore = new Map()
/**
* Cache-first, stale-while-revalidate data fetcher.
*
* Supports:
* - URL string (GET)
* - Request object (GET / POST)
* - Custom async fetcher function
*
* @param {Object} options
* @param {string} options.key - Unique cache key
* @param {string|Object} [options.request] - URL or request config
* @param {Function} [options.fetcher] - Custom async function
* @param {Function} options.onUpdate - Callback with data
*
* @example
* fetchWithCache({
* key: 'users.list',
* request: '/api/users',
* onUpdate: (data, source) => {
* users.value = data
* }
* })
*/
export async function fetchWithCache({
key,
request = null,
fetcher = null,
onUpdate = null
}) {
if (!key) {
throw new Error('fetchWithCache requires a cache key')
}
// 1⃣ Emit cached data immediately
if (cacheStore.has(key)) {
onUpdate?.(cacheStore.get(key), 'cache')
}
// 2⃣ Build fetcher if not provided
let resolvedFetcher = fetcher
if (!resolvedFetcher && request) {
resolvedFetcher = () => executeRequest(request)
}
if (typeof resolvedFetcher !== 'function') {
throw new Error('fetchWithCache requires either fetcher or request')
}
// 3⃣ Fetch fresh data
try {
const fresh = await resolvedFetcher()
const cached = cacheStore.get(key)
if (!cached || !deepEqual(cached, fresh)) {
cacheStore.set(key, fresh)
onUpdate?.(fresh, 'fresh')
}
} catch (err) {
console.error('[fetchWithCache] fetch failed:', err)
}
}