initial: bootstrap from BukidBountyApp base
This commit is contained in:
67
resources/js/utils/fetchWithCache.js
Normal file
67
resources/js/utils/fetchWithCache.js
Normal file
@@ -0,0 +1,67 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user