// composables/useCachedRequest.js import { useApiCache } from "~/composables/useApiCache"; const tryParseJSON = (str) => { if (typeof str !== "string") return str; if (!str.trim()) return null; try { return JSON.parse(str); } catch (e) { return str; // اگر parse نشد، رشته را همون‌طور برگردون } }; export const useCachedRequest = () => { const cache = useApiCache(); const { $http: httpService } = useNuxtApp(); // ساختن کلید ساده و یکتا برای هر request const getRequestKey = (config = {}) => { const method = (config.crud || "GET").toUpperCase(); const payloadNorm = tryParseJSON(config.payload) ?? null; return `${method}:${config.url}:${JSON.stringify(payloadNorm)}`; }; // درخواست با cache و dedupe const fetchRequest = async (config = {}) => { if (!config?.url) throw new Error("apiConfig.url is required"); const key = getRequestKey(config); // پاک کردن cache منقضی شده if (cache.hasData(key) && cache.isExpired(key)) cache.removeData(key); // 1. اگر قبلاً داده موجود است → برگردان if (cache.hasData(key)) return cache.getData(key); // 2. اگر درخواست در حال اجراست → promise را await کن (dedupe) const pending = cache.getPending(key); if (pending) return await pending; // 3. ایجاد request جدید const promise = (async () => { let response; const method = (config.crud || "GET").toUpperCase(); if (method === "POST") { const payload = tryParseJSON(config.payload) ?? {}; response = await httpService.postRequest(config.url, payload); } else { response = await httpService.getRequest(config.url); } const data = response?.data ?? response; // ذخیره با TTL در صورت وجود const ttl = config.ttlSeconds || 0; if (ttl > 0) { cache.saveDataWithTTL(key, data, ttl); } else { cache.saveData(key, data); } return data; })(); cache.setPending(key, promise); try { return await promise; } finally { cache.clearPending(key); } }; // پاکسازی دستی cache برای logout یا تغییر داده‌ها const invalidate = (configOrKey) => { const key = typeof configOrKey === "string" ? configOrKey : getRequestKey(configOrKey || {}); cache.removeData(key); }; const clearAll = () => cache.clearAllData(); return { fetchRequest, invalidate, clearAll }; };