55 lines
1.6 KiB
Dart
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 {}
|
|
}
|