Files
Client/lib/storage/hydrated_storage_bootstrap.dart
T

55 lines
1.6 KiB
Dart

import 'dart:developer';
import 'dart:io';
import 'package:hydrated_bloc/hydrated_bloc.dart';
/// Opens the HydratedBloc box; a corrupt box is dropped and rebuilt, and if
/// even that fails the app runs on [InMemoryStorage] instead of never
/// reaching `runApp`.
Future<Storage> buildHydratedStorageWithFallback(String directoryPath) async {
final directory = HydratedStorageDirectory(directoryPath);
try {
return await HydratedStorage.build(storageDirectory: directory);
} catch (e, s) {
log('HydratedStorage open failed, rebuilding: $e', stackTrace: s);
}
try {
await _deleteHydratedBox(directoryPath);
return await HydratedStorage.build(storageDirectory: directory);
} catch (e, s) {
log('HydratedStorage rebuild failed, using memory: $e', stackTrace: s);
return InMemoryStorage();
}
}
Future<void> _deleteHydratedBox(String directoryPath) async {
final directory = Directory(directoryPath);
if (!directory.existsSync()) return;
await for (final entity in directory.list()) {
final name = entity.uri.pathSegments.lastWhere((s) => s.isNotEmpty);
if (entity is File && name.startsWith('hydrated_box')) {
await entity.delete();
}
}
}
/// Non-persistent [Storage]; state lives for the session only.
class InMemoryStorage implements Storage {
final Map<String, dynamic> _values = {};
@override
dynamic read(String key) => _values[key];
@override
Future<void> write(String key, dynamic value) async => _values[key] = value;
@override
Future<void> delete(String key) async => _values.remove(key);
@override
Future<void> clear() async => _values.clear();
@override
Future<void> close() async {}
}