import 'dart:convert'; import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:path_provider/path_provider.dart'; /// Persistent key-value cache that serializes to a JSON file. /// /// Stores values by string key, with optional scoping (e.g. by houseId). /// All mutations auto-persist to disk. class CacheStore { final String fileName; Map _data = {}; CacheStore(this.fileName); // -- Disk I/O -- Future get _file async { final dir = await getApplicationDocumentsDirectory(); return File('${dir.path}/$fileName'); } Future load() async { try { final file = await _file; if (!await file.exists()) return; _data = jsonDecode(await file.readAsString()) as Map; } catch (e) { debugPrint('[CacheStore:$fileName] Failed to load: $e'); } } Future _save() async { try { final file = await _file; await file.writeAsString(jsonEncode(_data)); } catch (e) { debugPrint('[CacheStore:$fileName] Failed to save: $e'); } } Future clear() async { _data.clear(); await _save(); } // -- Scalar values -- T? get(String key) => _data[key] as T?; void set(String key, T? value) { _data[key] = value; _save(); } // -- Single object cache -- Map? getObject(String key) { final val = _data[key]; return val is Map ? val : null; } // -- List cache -- List? getList(String key, T Function(Map) fromJson) { final val = _data[key]; if (val is! List) return null; return val.map((e) => fromJson(e as Map)).toList(); } void setList( String key, List items, Map Function(T) toJson, ) { _data[key] = items.map(toJson).toList(); _save(); } // -- Keyed list cache (e.g. items per listId) -- List? getKeyedList( String prefix, String key, T Function(Map) fromJson, ) { return getList('$prefix:$key', fromJson); } void setKeyedList( String prefix, String key, List items, Map Function(T) toJson, ) { setList('$prefix:$key', items, toJson); } void removeKeyed(String prefix, {String? keepKey}) { final keysToRemove = _data.keys .where((k) => k.startsWith('$prefix:') && k != '$prefix:$keepKey') .toList(); for (final k in keysToRemove) { _data.remove(k); } _save(); } void removeKey(String key) { _data.remove(key); _save(); } }