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

68 lines
1.6 KiB
JavaScript
Raw 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)
}
}