new change to use intaleq_map sdk 04-16-4

This commit is contained in:
Hamza-Ayed
2026-04-16 19:45:03 +03:00
parent 0aa1f15f25
commit a54a7a4189
850 changed files with 83282 additions and 3075 deletions

View File

@@ -0,0 +1,32 @@
import 'package:get_storage/src/storage_impl.dart';
typedef StorageFactory = GetStorage Function();
class ReadWriteValue<T> {
final String key;
final T defaultValue;
final StorageFactory? getBox;
// final EncodeObject encoder;
ReadWriteValue(
this.key,
this.defaultValue, [
this.getBox,
// this.encoder,
]);
GetStorage _getRealBox() => getBox?.call() ?? GetStorage();
T get val => _getRealBox().read(key) ?? defaultValue;
set val(T newVal) => _getRealBox().write(key, newVal);
}
extension Data<T> on T {
ReadWriteValue<T> val(
String valueKey, {
StorageFactory? getBox,
T? defVal,
}) {
return ReadWriteValue(valueKey, defVal ?? this, getBox);
}
}

View File

@@ -0,0 +1,100 @@
import 'dart:async';
import 'dart:convert';
// ignore: avoid_web_libraries_in_flutter
import 'dart:html' as html;
import '../value.dart';
class StorageImpl {
StorageImpl(this.fileName, [this.path]);
html.Storage get localStorage => html.window.localStorage;
final String? path;
final String fileName;
ValueStorage<Map<String, dynamic>> subject =
ValueStorage<Map<String, dynamic>>(<String, dynamic>{});
void clear() {
localStorage.remove(fileName);
subject.value.clear();
subject
..value.clear()
..changeValue("", null);
}
Future<bool> _exists() async {
return localStorage.containsKey(fileName);
}
Future<void> flush() {
return _writeToStorage(subject.value);
}
T? read<T>(String key) {
return subject.value[key] as T?;
}
T getKeys<T>() {
return subject.value.keys as T;
}
T getValues<T>() {
return subject.value.values as T;
}
Future<void> init([Map<String, dynamic>? initialData]) async {
subject.value = initialData ?? <String, dynamic>{};
if (await _exists()) {
await _readFromStorage();
} else {
await _writeToStorage(subject.value);
}
return;
}
void remove(String key) {
subject
..value.remove(key)
..changeValue(key, null);
// return _writeToStorage(subject.value);
}
void write(String key, dynamic value) {
subject
..value[key] = value
..changeValue(key, value);
//return _writeToStorage(subject.value);
}
// void writeInMemory(String key, dynamic value) {
// }
Future<void> _writeToStorage(Map<String, dynamic> data) async {
localStorage.update(fileName, (val) => json.encode(subject.value),
ifAbsent: () => json.encode(subject.value));
}
Future<void> _readFromStorage() async {
final dataFromLocal = localStorage.entries.firstWhereOrNull(
(value) {
return value.key == fileName;
},
);
if (dataFromLocal != null) {
subject.value = json.decode(dataFromLocal.value) as Map<String, dynamic>;
} else {
await _writeToStorage(<String, dynamic>{});
}
}
}
extension FirstWhereExt<T> on Iterable<T> {
T? firstWhereOrNull(bool Function(T element) test) {
for (var element in this) {
if (test(element)) return element;
}
return null;
}
}

View File

@@ -0,0 +1,153 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:get/get.dart';
import 'package:path_provider/path_provider.dart';
import '../value.dart';
class StorageImpl {
StorageImpl(this.fileName, [this.path]);
final String? path;
final String fileName;
final ValueStorage<Map<String, dynamic>> subject =
ValueStorage<Map<String, dynamic>>(<String, dynamic>{});
RandomAccessFile? _randomAccessfile;
void clear() async {
subject
..value.clear()
..changeValue("", null);
}
Future<void> deleteBox() async {
final box = await _fileDb(isBackup: false);
final backup = await _fileDb(isBackup: true);
await Future.wait([box.delete(), backup.delete()]);
}
Future<void> flush() async {
final buffer = utf8.encode(json.encode(subject.value));
final length = buffer.length;
RandomAccessFile _file = await _getRandomFile();
_randomAccessfile = await _file.lock();
_randomAccessfile = await _randomAccessfile!.setPosition(0);
_randomAccessfile = await _randomAccessfile!.writeFrom(buffer);
_randomAccessfile = await _randomAccessfile!.truncate(length);
_randomAccessfile = await _file.unlock();
_madeBackup();
}
void _madeBackup() {
_getFile(true).then(
(value) => value.writeAsString(
json.encode(subject.value),
flush: true,
),
);
}
T? read<T>(String key) {
return subject.value[key] as T?;
}
T getKeys<T>() {
return subject.value.keys as T;
}
T getValues<T>() {
return subject.value.values as T;
}
Future<void> init([Map<String, dynamic>? initialData]) async {
subject.value = initialData ?? <String, dynamic>{};
RandomAccessFile _file = await _getRandomFile();
return _file.lengthSync() == 0 ? flush() : _readFile();
}
void remove(String key) {
subject
..value.remove(key)
..changeValue(key, null);
}
void write(String key, dynamic value) {
subject
..value[key] = value
..changeValue(key, value);
}
Future<void> _readFile() async {
try {
RandomAccessFile _file = await _getRandomFile();
_file = await _file.setPosition(0);
final buffer = new Uint8List(await _file.length());
await _file.readInto(buffer);
subject.value = json.decode(utf8.decode(buffer));
} catch (e) {
Get.log('Corrupted box, recovering backup file', isError: true);
final _file = await _getFile(true);
final content = await _file.readAsString()
..trim();
if (content.isEmpty) {
subject.value = {};
} else {
try {
subject.value = (json.decode(content) as Map<String, dynamic>?) ?? {};
} catch (e) {
Get.log('Can not recover Corrupted box', isError: true);
subject.value = {};
}
}
flush();
}
}
Future<RandomAccessFile> _getRandomFile() async {
if (_randomAccessfile != null) return _randomAccessfile!;
final fileDb = await _getFile(false);
_randomAccessfile = await fileDb.open(mode: FileMode.append);
return _randomAccessfile!;
}
Future<File> _getFile(bool isBackup) async {
final fileDb = await _fileDb(isBackup: isBackup);
if (!fileDb.existsSync()) {
fileDb.createSync(recursive: true);
}
return fileDb;
}
Future<File> _fileDb({required bool isBackup}) async {
final dir = await _getImplicitDir();
final _path = await _getPath(isBackup, path ?? dir.path);
final _file = File(_path);
return _file;
}
Future<Directory> _getImplicitDir() async {
try {
return getApplicationDocumentsDirectory();
} catch (err) {
throw err;
}
}
Future<String> _getPath(bool isBackup, String? path) async {
final _isWindows = GetPlatform.isWindows;
final _separator = _isWindows ? '\\' : '/';
return isBackup
? '$path$_separator$fileName.bak'
: '$path$_separator$fileName.gs';
}
}

View File

@@ -0,0 +1,182 @@
import 'dart:async';
import 'package:flutter/widgets.dart';
import 'package:get/utils.dart';
import 'storage/html.dart' if (dart.library.io) 'storage/io.dart';
import 'value.dart';
/// Instantiate GetStorage to access storage driver apis
class GetStorage {
factory GetStorage(
[String container = 'GetStorage',
String? path,
Map<String, dynamic>? initialData]) {
if (_sync.containsKey(container)) {
return _sync[container]!;
} else {
final instance = GetStorage._internal(container, path, initialData);
_sync[container] = instance;
return instance;
}
}
GetStorage._internal(String key,
[String? path, Map<String, dynamic>? initialData]) {
_concrete = StorageImpl(key, path);
_initialData = initialData;
initStorage = Future<bool>(() async {
await _init();
return true;
});
}
static final Map<String, GetStorage> _sync = {};
final microtask = Microtask();
/// Start the storage drive. It's important to use await before calling this API, or side effects will occur.
static Future<bool> init([String container = 'GetStorage']) {
WidgetsFlutterBinding.ensureInitialized();
return GetStorage(container).initStorage;
}
Future<void> _init() async {
try {
await _concrete.init(_initialData);
} catch (err) {
throw err;
}
}
/// Reads a value in your container with the given key.
T? read<T>(String key) {
return _concrete.read(key);
}
T getKeys<T>() {
return _concrete.getKeys();
}
T getValues<T>() {
return _concrete.getValues();
}
/// return data true if value is different of null;
bool hasData(String key) {
return (read(key) == null ? false : true);
}
Map<String, dynamic> get changes => _concrete.subject.changes;
/// Listen changes in your container
VoidCallback listen(VoidCallback value) {
return _concrete.subject.addListener(value);
}
Map<Function, Function> _keyListeners = <Function, Function>{};
VoidCallback listenKey(String key, ValueSetter callback) {
final VoidCallback listen = () {
if (changes.keys.first == key) {
callback(changes[key]);
}
};
_keyListeners[callback] = listen;
return _concrete.subject.addListener(listen);
}
// /// Remove listen of your container
// void removeKeyListen(Function(Map<String, dynamic>) callback) {
// _concrete.subject.removeListener(_keyListeners[callback]);
// }
// /// Remove listen of your container
// void removeListen(void Function() listener) {
// _concrete.subject.removeListener(listener);
// }
/// Write data on your container
Future<void> write(String key, dynamic value) async {
writeInMemory(key, value);
// final _encoded = json.encode(value);
// await _concrete.write(key, json.decode(_encoded));
return _tryFlush();
}
void writeInMemory(String key, dynamic value) {
_concrete.write(key, value);
}
/// Write data on your only if data is null
Future<void> writeIfNull(String key, dynamic value) async {
if (read(key) != null) return;
return write(key, value);
}
/// remove data from container by key
Future<void> remove(String key) async {
_concrete.remove(key);
return _tryFlush();
}
/// clear all data on your container
Future<void> erase() async {
_concrete.clear();
return _tryFlush();
}
Future<void> save() async {
return _tryFlush();
}
Future<void> _tryFlush() async {
return microtask.exec(_addToQueue);
}
Future _addToQueue() {
return queue.add(_flush);
}
Future<void> _flush() async {
try {
await _concrete.flush();
} catch (e) {
rethrow;
}
return;
}
late StorageImpl _concrete;
GetQueue queue = GetQueue();
/// listenable of container
ValueStorage<Map<String, dynamic>> get listenable => _concrete.subject;
/// Start the storage drive. Important: use await before calling this api, or side effects will happen.
late Future<bool> initStorage;
Map<String, dynamic>? _initialData;
}
class Microtask {
int _version = 0;
int _microtask = 0;
void exec(Function callback) {
if (_microtask == _version) {
_microtask++;
scheduleMicrotask(() {
_version++;
_microtask = _version;
callback();
});
}
}
}
typedef KeyCallback = Function(String);

View File

@@ -0,0 +1,28 @@
import 'package:flutter/widgets.dart';
import 'package:get/state_manager.dart';
class ValueStorage<T> {
ValueStorage(T value) : this._value = Value(value);
final Value _value;
Map<String, dynamic> changes = <String, dynamic>{};
void changeValue(String key, dynamic value) {
changes = {key: value};
// ignore: invalid_use_of_protected_member
_value.refresh();
}
T get value => _value.value;
set value(T value) {
_value.value = value;
}
VoidCallback addListener(VoidCallback callback) {
_value.addListener(callback);
return () => _value.removeListener(callback);
}
}