Initial commit MKD fixes
This commit is contained in:
141
services/offlineCacheService.ts
Executable file
141
services/offlineCacheService.ts
Executable file
@@ -0,0 +1,141 @@
|
||||
// Сервис кэширования данных для offline режима
|
||||
type CachedRequest = {
|
||||
id: string;
|
||||
method: string;
|
||||
url: string;
|
||||
body?: unknown;
|
||||
timestamp: number;
|
||||
retries: number;
|
||||
};
|
||||
|
||||
const CACHE_KEY = 'mkd_offline_cache';
|
||||
const MAX_RETRIES = 10;
|
||||
const MAX_CACHE_AGE = 7 * 24 * 60 * 60 * 1000; // 7 дней
|
||||
|
||||
class OfflineCacheService {
|
||||
// Сохранить запрос в кэш
|
||||
cacheRequest(method: string, url: string, body?: unknown): string {
|
||||
const cachedRequests = this.getCachedRequests();
|
||||
const id = `req-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
||||
|
||||
const request: CachedRequest = {
|
||||
id,
|
||||
method,
|
||||
url,
|
||||
body,
|
||||
timestamp: Date.now(),
|
||||
retries: 0,
|
||||
};
|
||||
|
||||
cachedRequests.push(request);
|
||||
this.saveCachedRequests(cachedRequests);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
// Получить все закэшированные запросы
|
||||
getCachedRequests(): CachedRequest[] {
|
||||
try {
|
||||
const stored = localStorage.getItem(CACHE_KEY);
|
||||
if (stored) {
|
||||
const requests = JSON.parse(stored) as CachedRequest[];
|
||||
// Фильтруем устаревшие запросы
|
||||
const now = Date.now();
|
||||
return requests.filter(req => now - req.timestamp < MAX_CACHE_AGE);
|
||||
}
|
||||
return [];
|
||||
} catch (e) {
|
||||
console.error('Failed to get cached requests', e);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// Сохранить закэшированные запросы
|
||||
private saveCachedRequests(requests: CachedRequest[]) {
|
||||
try {
|
||||
localStorage.setItem(CACHE_KEY, JSON.stringify(requests));
|
||||
} catch (e) {
|
||||
console.error('Failed to save cached requests', e);
|
||||
}
|
||||
}
|
||||
|
||||
// Удалить запрос из кэша
|
||||
removeRequest(id: string): void {
|
||||
const cachedRequests = this.getCachedRequests();
|
||||
const filtered = cachedRequests.filter(req => req.id !== id);
|
||||
this.saveCachedRequests(filtered);
|
||||
}
|
||||
|
||||
// Увеличить счётчик попыток для запроса
|
||||
incrementRetries(id: string): void {
|
||||
const cachedRequests = this.getCachedRequests();
|
||||
const updated = cachedRequests.map(req => {
|
||||
if (req.id === id) {
|
||||
return { ...req, retries: req.retries + 1 };
|
||||
}
|
||||
return req;
|
||||
});
|
||||
this.saveCachedRequests(updated);
|
||||
}
|
||||
|
||||
// Синхронизировать все закэшированные запросы
|
||||
async syncCachedRequests(apiBaseUrl: string): Promise<{ success: number; failed: number }> {
|
||||
const cachedRequests = this.getCachedRequests();
|
||||
let success = 0;
|
||||
let failed = 0;
|
||||
|
||||
for (const request of cachedRequests) {
|
||||
// Пропускаем запросы с превышенным лимитом попыток
|
||||
if (request.retries >= MAX_RETRIES) {
|
||||
this.removeRequest(request.id);
|
||||
failed++;
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
const fullUrl = request.url.startsWith('http')
|
||||
? request.url
|
||||
: `${apiBaseUrl}${request.url}`;
|
||||
|
||||
const options: RequestInit = {
|
||||
method: request.method,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
};
|
||||
|
||||
if (request.body && (request.method === 'POST' || request.method === 'PUT')) {
|
||||
options.body = JSON.stringify(request.body);
|
||||
}
|
||||
|
||||
const response = await fetch(fullUrl, options);
|
||||
|
||||
if (response.ok) {
|
||||
this.removeRequest(request.id);
|
||||
success++;
|
||||
} else {
|
||||
this.incrementRetries(request.id);
|
||||
failed++;
|
||||
}
|
||||
} catch (error) {
|
||||
this.incrementRetries(request.id);
|
||||
failed++;
|
||||
}
|
||||
}
|
||||
|
||||
return { success, failed };
|
||||
}
|
||||
|
||||
// Очистить весь кэш
|
||||
clearCache(): void {
|
||||
localStorage.removeItem(CACHE_KEY);
|
||||
}
|
||||
|
||||
// Получить количество закэшированных запросов
|
||||
getCacheSize(): number {
|
||||
return this.getCachedRequests().length;
|
||||
}
|
||||
}
|
||||
|
||||
// Создаём единственный экземпляр сервиса
|
||||
export const offlineCacheService = new OfflineCacheService();
|
||||
Reference in New Issue
Block a user