Line data Source code
1 : import 'dart:async'; 2 : import 'dart:convert'; 3 : import 'package:flutter/widgets.dart'; 4 : import 'storage/html.dart' if (dart.library.io) 'storage/io.dart'; 5 : 6 : /// Instantiate GetStorage to access storage driver apis 7 : class GetStorage { 8 1 : factory GetStorage( 9 : [String container = 'GetStorage', 10 : String path, 11 : Map<String, dynamic> initialData]) { 12 2 : if (_sync.containsKey(container)) { 13 2 : return _sync[container]; 14 : } else { 15 1 : final instance = GetStorage._internal(container, path, initialData); 16 2 : _sync[container] = instance; 17 : return instance; 18 : } 19 : } 20 : 21 1 : GetStorage._internal(String key, 22 : [String path, Map<String, dynamic> initialData]) { 23 2 : _concrete = StorageImpl(key, path); 24 1 : _initialData = initialData; 25 : 26 3 : initStorage = Future<bool>(() async { 27 2 : await _init(); 28 : return true; 29 : }); 30 : } 31 : 32 3 : static final Map<String, GetStorage> _sync = {}; 33 : 34 : /// Start the storage drive. Importate: use await before calling this api, or side effects will happen. 35 1 : static Future<bool> init([String container = 'GetStorage']) { 36 1 : WidgetsFlutterBinding.ensureInitialized(); 37 : if (container == null) { 38 : throw 'key can not be null'; 39 : } 40 2 : return GetStorage(container).initStorage; 41 : } 42 : 43 1 : Future<void> _init() async { 44 : try { 45 4 : await _concrete.init(_initialData); 46 : } catch (err) { 47 : throw err; 48 : } 49 : } 50 : 51 : /// Reads a value in your container with the given key. 52 1 : T read<T>(String key) { 53 2 : return _concrete.read(key); 54 : } 55 : 56 : /// Listen changes in your container 57 1 : void listen(void Function() value) { 58 3 : _concrete.subject.addListener(value); 59 : } 60 : 61 : /// Remove listen of your container 62 1 : void removeListen(void Function() listener) { 63 3 : _concrete.subject.removeListener(listener); 64 : } 65 : 66 : /// Write data on your container 67 1 : Future<void> write(String key, dynamic value, 68 : [EncodeObject objectToEncode]) async { 69 : final _encoded = 70 1 : json.encode(objectToEncode != null ? objectToEncode(value) : value); 71 4 : await _concrete.write(key, json.decode(_encoded)); 72 : 73 1 : return _tryFlush(); 74 : } 75 : 76 : /// remove data from container by key 77 1 : Future<void> remove(String key) async { 78 3 : await _concrete.remove(key); 79 1 : return _tryFlush(); 80 : } 81 : 82 : /// clear all data on your container 83 1 : Future<void> erase() async { 84 3 : await _concrete.clear(); 85 1 : return _tryFlush(); 86 : } 87 : 88 1 : Future<void> _tryFlush() async { 89 1 : if (_lockDatabase != null) { 90 2 : await _lockDatabase; 91 : } 92 2 : _lockDatabase = _flush(); 93 1 : return _lockDatabase; 94 : } 95 : 96 1 : Future<void> _flush() async { 97 : try { 98 3 : await _concrete.flush(); 99 : } catch (e) { 100 : rethrow; 101 : } 102 : return; 103 : } 104 : 105 : StorageImpl _concrete; 106 : 107 : /// Start the storage drive. Importate: use await before calling this api, or side effects will happen. 108 : Future<bool> initStorage; 109 : 110 : Future<void> _lockDatabase; 111 : 112 : Map<String, dynamic> _initialData; 113 : } 114 : 115 : typedef EncodeObject = Object Function(Object);