Files
Client/lib/api/requestCache.dart
T
2026-05-05 13:49:45 +02:00

63 lines
1.8 KiB
Dart

import 'dart:async';
import 'dart:convert';
import 'package:localstore/localstore.dart';
import 'apiResponse.dart';
abstract class RequestCache<T extends ApiResponse?> {
static const int cacheNothing = 0;
static const int cacheMinute = 60;
static const int cacheHour = 60 * 60;
static const int cacheDay = 60 * 60 * 24;
static String collection = 'MarianumMobile';
int maxCacheTime;
void Function(T)? onUpdate;
void Function(Exception) onError;
bool? renew;
final Completer<void> _ready = Completer<void>();
/// Resolves when [start] has finished, regardless of whether the network
/// call succeeded, failed, or was skipped due to a fresh cache. Callers
/// can await this to know when both the cache lookup and the network
/// attempt have settled.
Future<void> get ready => _ready.future;
RequestCache(this.maxCacheTime, this.onUpdate, {this.onError = ignore, this.renew = false});
static void ignore(Exception e) {}
Future<void> start(String document) async {
try {
final tableData = await Localstore.instance.collection(collection).doc(document).get();
if (tableData != null) {
onUpdate?.call(onLocalData(tableData['json']));
}
if (DateTime.now().millisecondsSinceEpoch - (maxCacheTime * 1000) < (tableData?['lastupdate'] ?? 0)) {
if (renew == null || !renew!) return;
}
try {
final newValue = await onLoad();
onUpdate?.call(newValue);
Localstore.instance.collection(collection).doc(document).set({
'json': jsonEncode(newValue),
'lastupdate': DateTime.now().millisecondsSinceEpoch,
});
} on Exception catch (e) {
onError(e);
}
} finally {
if (!_ready.isCompleted) _ready.complete();
}
}
T onLocalData(String json);
Future<T> onLoad();
}