2025-11-24 16:38:26 +05:30
|
|
|
import '../services/cache_manager.dart';
|
2025-08-20 22:15:26 +05:30
|
|
|
import '../utils/debug_logger.dart';
|
2025-11-24 16:38:26 +05:30
|
|
|
import 'auth_state_manager.dart';
|
2025-08-10 01:20:45 +05:30
|
|
|
|
2025-11-24 16:38:26 +05:30
|
|
|
/// Comprehensive caching manager for auth-related operations.
|
|
|
|
|
///
|
|
|
|
|
/// Delegates to the shared [CacheManager] to keep TTL and eviction behavior
|
|
|
|
|
/// consistent across the app.
|
2025-08-10 01:20:45 +05:30
|
|
|
class AuthCacheManager {
|
|
|
|
|
static final AuthCacheManager _instance = AuthCacheManager._internal();
|
|
|
|
|
factory AuthCacheManager() => _instance;
|
|
|
|
|
AuthCacheManager._internal();
|
|
|
|
|
|
2025-11-24 16:38:26 +05:30
|
|
|
static const Duration _shortCache = Duration(minutes: 2);
|
|
|
|
|
static const Duration _mediumCache = Duration(minutes: 5);
|
|
|
|
|
static const Duration _longCache = Duration(minutes: 15);
|
2025-08-10 01:20:45 +05:30
|
|
|
|
|
|
|
|
static const String _userDataKey = 'user_data';
|
|
|
|
|
static const String _serverConnectionKey = 'server_connection';
|
|
|
|
|
static const String _credentialsExistKey = 'credentials_exist';
|
|
|
|
|
static const String _serverConfigsKey = 'server_configs';
|
2025-11-24 16:38:26 +05:30
|
|
|
static const String _authStatusKey = 'auth_status';
|
|
|
|
|
|
|
|
|
|
final CacheManager _cache = CacheManager(
|
|
|
|
|
defaultTtl: _mediumCache,
|
|
|
|
|
maxEntries: 32,
|
|
|
|
|
);
|
2025-08-10 01:20:45 +05:30
|
|
|
|
|
|
|
|
void cacheUserData(dynamic userData) {
|
2025-11-24 16:38:26 +05:30
|
|
|
_cache.write<dynamic>(_userDataKey, userData, ttl: _mediumCache);
|
2025-08-20 22:15:26 +05:30
|
|
|
DebugLogger.storage('User data cached');
|
2025-08-10 01:20:45 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dynamic getCachedUserData() {
|
2025-11-24 16:38:26 +05:30
|
|
|
final (hit: hit, value: user) = _cache.lookup<dynamic>(_userDataKey);
|
|
|
|
|
if (hit) {
|
2025-08-20 22:15:26 +05:30
|
|
|
DebugLogger.storage('Using cached user data');
|
2025-08-10 01:20:45 +05:30
|
|
|
}
|
2025-11-24 16:38:26 +05:30
|
|
|
return user;
|
2025-08-10 01:20:45 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void cacheServerConnection(bool isConnected) {
|
2025-11-24 16:38:26 +05:30
|
|
|
_cache.write<bool>(_serverConnectionKey, isConnected, ttl: _shortCache);
|
2025-08-10 01:20:45 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool? getCachedServerConnection() {
|
2025-11-24 16:38:26 +05:30
|
|
|
final (hit: hit, value: connection) = _cache.lookup<bool>(
|
|
|
|
|
_serverConnectionKey,
|
|
|
|
|
);
|
|
|
|
|
return hit ? connection : null;
|
2025-08-10 01:20:45 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void cacheCredentialsExist(bool exist) {
|
2025-11-24 16:38:26 +05:30
|
|
|
_cache.write<bool>(_credentialsExistKey, exist, ttl: _mediumCache);
|
2025-08-10 01:20:45 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool? getCachedCredentialsExist() {
|
2025-11-24 16:38:26 +05:30
|
|
|
final (hit: hit, value: hasCreds) = _cache.lookup<bool>(
|
|
|
|
|
_credentialsExistKey,
|
|
|
|
|
);
|
|
|
|
|
return hit ? hasCreds : null;
|
2025-08-10 01:20:45 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void cacheServerConfigs(List<dynamic> configs) {
|
2025-11-24 16:38:26 +05:30
|
|
|
_cache.write<List<dynamic>>(_serverConfigsKey, configs, ttl: _longCache);
|
2025-08-10 01:20:45 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<dynamic>? getCachedServerConfigs() {
|
2025-11-24 16:38:26 +05:30
|
|
|
final (hit: hit, value: configs) = _cache.lookup<List<dynamic>>(
|
|
|
|
|
_serverConfigsKey,
|
|
|
|
|
);
|
|
|
|
|
return hit ? configs : null;
|
2025-08-10 01:20:45 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void clearCacheEntry(String key) {
|
2025-11-24 16:38:26 +05:30
|
|
|
_cache.invalidate(key);
|
2025-08-20 22:15:26 +05:30
|
|
|
DebugLogger.storage('Cache entry cleared: $key');
|
2025-08-10 01:20:45 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void clearAuthCache() {
|
|
|
|
|
_cache.clear();
|
2025-11-24 16:38:26 +05:30
|
|
|
DebugLogger.storage(
|
|
|
|
|
'All auth cache cleared (including server configs and custom headers)',
|
|
|
|
|
);
|
2025-08-10 01:20:45 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void cleanExpiredCache() {
|
2025-11-24 16:38:26 +05:30
|
|
|
final stats = _cache.stats();
|
|
|
|
|
final entries = stats['entries'];
|
|
|
|
|
if (entries is! Map<String, dynamic>) return;
|
|
|
|
|
|
|
|
|
|
var expiredCount = 0;
|
|
|
|
|
entries.forEach((key, value) {
|
|
|
|
|
if (value is! Map) return;
|
|
|
|
|
final ageSeconds = value['ageSeconds'];
|
|
|
|
|
final ttlSeconds = value['ttlSeconds'];
|
|
|
|
|
if (ageSeconds is num && ttlSeconds is num && ageSeconds > ttlSeconds) {
|
|
|
|
|
_cache.invalidate(key);
|
|
|
|
|
expiredCount++;
|
2025-08-10 01:20:45 +05:30
|
|
|
}
|
2025-11-24 16:38:26 +05:30
|
|
|
});
|
2025-08-10 01:20:45 +05:30
|
|
|
|
2025-11-24 16:38:26 +05:30
|
|
|
if (expiredCount > 0) {
|
|
|
|
|
DebugLogger.storage('Cleaned $expiredCount expired auth cache entries');
|
2025-08-10 01:20:45 +05:30
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-24 16:38:26 +05:30
|
|
|
Map<String, dynamic> getCacheStats() => _cache.stats();
|
2025-08-10 01:20:45 +05:30
|
|
|
|
|
|
|
|
void optimizeCache() {
|
2025-11-24 16:38:26 +05:30
|
|
|
// CacheManager enforces maxEntries using LRU; no extra work needed.
|
2025-08-10 01:20:45 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void cacheAuthState(AuthState authState) {
|
|
|
|
|
if (authState.user != null) {
|
|
|
|
|
cacheUserData(authState.user);
|
|
|
|
|
}
|
|
|
|
|
if (authState.status == AuthStatus.authenticated) {
|
2025-11-24 16:38:26 +05:30
|
|
|
_cache.write<AuthStatus>(
|
|
|
|
|
_authStatusKey,
|
|
|
|
|
authState.status,
|
|
|
|
|
ttl: _shortCache,
|
|
|
|
|
);
|
2025-08-10 01:20:45 +05:30
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AuthStatus? getCachedAuthStatus() {
|
2025-11-24 16:38:26 +05:30
|
|
|
final (hit: hit, value: status) = _cache.lookup<AuthStatus>(_authStatusKey);
|
|
|
|
|
return hit ? status : null;
|
2025-08-10 01:20:45 +05:30
|
|
|
}
|
|
|
|
|
}
|