From 074175ed392370d5165d0573977af8d83422ac31 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Thu, 15 Dec 2022 15:43:40 +0600 Subject: [PATCH] feat: add query and infinite query disk caching support --- packages/fl_query/.flutter-plugins | 6 ++ .../fl_query/.flutter-plugins-dependencies | 2 +- packages/fl_query/example/.flutter-plugins | 6 ++ .../example/.flutter-plugins-dependencies | 2 +- .../plugins/GeneratedPluginRegistrant.java | 5 + .../ios/Runner/GeneratedPluginRegistrant.m | 7 ++ .../components/infinite_query_disk_cache.dart | 99 +++++++++++++++++ .../lib/components/query_disk_cache.dart | 79 ++++++++++++++ packages/fl_query/example/lib/main.dart | 8 +- .../Flutter/GeneratedPluginRegistrant.swift | 2 + packages/fl_query/example/pubspec.lock | 102 +++++++++++++++++- packages/fl_query/lib/fl_query.dart | 45 ++++++++ packages/fl_query/lib/src/base_query.dart | 62 ++++++++++- packages/fl_query/lib/src/infinite_query.dart | 57 +++++++++- .../lib/src/models/infinite_query_job.dart | 31 +++++- .../fl_query/lib/src/models/query_job.dart | 18 +++- packages/fl_query/lib/src/query.dart | 30 +++++- packages/fl_query/lib/src/query_bowl.dart | 1 + packages/fl_query/lib/src/query_cache.dart | 31 +++++- packages/fl_query/pubspec.yaml | 1 + packages/fl_query_hooks/.flutter-plugins | 6 ++ .../.flutter-plugins-dependencies | 2 +- .../fl_query_hooks/example/.flutter-plugins | 6 ++ .../example/.flutter-plugins-dependencies | 2 +- packages/fl_query_hooks/example/pubspec.lock | 98 +++++++++++++++++ 25 files changed, 689 insertions(+), 19 deletions(-) create mode 100644 packages/fl_query/example/lib/components/infinite_query_disk_cache.dart create mode 100644 packages/fl_query/example/lib/components/query_disk_cache.dart diff --git a/packages/fl_query/.flutter-plugins b/packages/fl_query/.flutter-plugins index 84381da..4868dd5 100644 --- a/packages/fl_query/.flutter-plugins +++ b/packages/fl_query/.flutter-plugins @@ -4,3 +4,9 @@ connectivity_plus_linux=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connec connectivity_plus_macos=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_macos-1.2.6/ connectivity_plus_web=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_web-1.2.5/ connectivity_plus_windows=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_windows-1.2.2/ +path_provider=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.11/ +path_provider_android=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_android-2.0.22/ +path_provider_ios=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_ios-2.0.11/ +path_provider_linux=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-2.1.7/ +path_provider_macos=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-2.0.6/ +path_provider_windows=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-2.1.3/ diff --git a/packages/fl_query/.flutter-plugins-dependencies b/packages/fl_query/.flutter-plugins-dependencies index 1a7ddc9..9614e81 100644 --- a/packages/fl_query/.flutter-plugins-dependencies +++ b/packages/fl_query/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"connectivity_plus","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus-2.3.9/","native_build":true,"dependencies":[]}],"android":[{"name":"connectivity_plus","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus-2.3.9/","native_build":true,"dependencies":[]}],"macos":[{"name":"connectivity_plus_macos","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_macos-1.2.6/","native_build":true,"dependencies":[]}],"linux":[{"name":"connectivity_plus_linux","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_linux-1.3.1/","native_build":false,"dependencies":[]}],"windows":[{"name":"connectivity_plus_windows","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_windows-1.2.2/","native_build":true,"dependencies":[]}],"web":[{"name":"connectivity_plus_web","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_web-1.2.5/","dependencies":[]}]},"dependencyGraph":[{"name":"connectivity_plus","dependencies":["connectivity_plus_linux","connectivity_plus_macos","connectivity_plus_web","connectivity_plus_windows"]},{"name":"connectivity_plus_linux","dependencies":[]},{"name":"connectivity_plus_macos","dependencies":[]},{"name":"connectivity_plus_web","dependencies":[]},{"name":"connectivity_plus_windows","dependencies":[]}],"date_created":"2022-12-14 11:46:10.170392","version":"3.3.8"} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"connectivity_plus","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus-2.3.9/","native_build":true,"dependencies":[]},{"name":"path_provider_ios","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_ios-2.0.11/","native_build":true,"dependencies":[]}],"android":[{"name":"connectivity_plus","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus-2.3.9/","native_build":true,"dependencies":[]},{"name":"path_provider_android","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_android-2.0.22/","native_build":true,"dependencies":[]}],"macos":[{"name":"connectivity_plus_macos","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_macos-1.2.6/","native_build":true,"dependencies":[]},{"name":"path_provider_macos","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-2.0.6/","native_build":true,"dependencies":[]}],"linux":[{"name":"connectivity_plus_linux","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_linux-1.3.1/","native_build":false,"dependencies":[]},{"name":"path_provider_linux","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-2.1.7/","native_build":false,"dependencies":[]}],"windows":[{"name":"connectivity_plus_windows","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_windows-1.2.2/","native_build":true,"dependencies":[]},{"name":"path_provider_windows","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-2.1.3/","native_build":false,"dependencies":[]}],"web":[{"name":"connectivity_plus_web","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_web-1.2.5/","dependencies":[]}]},"dependencyGraph":[{"name":"connectivity_plus","dependencies":["connectivity_plus_linux","connectivity_plus_macos","connectivity_plus_web","connectivity_plus_windows"]},{"name":"connectivity_plus_linux","dependencies":[]},{"name":"connectivity_plus_macos","dependencies":[]},{"name":"connectivity_plus_web","dependencies":[]},{"name":"connectivity_plus_windows","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_ios","path_provider_linux","path_provider_macos","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_ios","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]}],"date_created":"2022-12-15 14:11:20.974968","version":"3.3.8"} \ No newline at end of file diff --git a/packages/fl_query/example/.flutter-plugins b/packages/fl_query/example/.flutter-plugins index d393acb..7051ea8 100644 --- a/packages/fl_query/example/.flutter-plugins +++ b/packages/fl_query/example/.flutter-plugins @@ -4,3 +4,9 @@ connectivity_plus_linux=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connec connectivity_plus_macos=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_macos-1.2.4/ connectivity_plus_web=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_web-1.2.5/ connectivity_plus_windows=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_windows-1.2.2/ +path_provider=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.11/ +path_provider_android=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_android-2.0.22/ +path_provider_ios=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_ios-2.0.11/ +path_provider_linux=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-2.1.7/ +path_provider_macos=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-2.0.6/ +path_provider_windows=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-2.1.3/ diff --git a/packages/fl_query/example/.flutter-plugins-dependencies b/packages/fl_query/example/.flutter-plugins-dependencies index bd33416..16deaca 100644 --- a/packages/fl_query/example/.flutter-plugins-dependencies +++ b/packages/fl_query/example/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"connectivity_plus","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus-2.3.9/","native_build":true,"dependencies":[]}],"android":[{"name":"connectivity_plus","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus-2.3.9/","native_build":true,"dependencies":[]}],"macos":[{"name":"connectivity_plus_macos","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_macos-1.2.4/","native_build":true,"dependencies":[]}],"linux":[{"name":"connectivity_plus_linux","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_linux-1.3.1/","native_build":false,"dependencies":[]}],"windows":[{"name":"connectivity_plus_windows","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_windows-1.2.2/","native_build":true,"dependencies":[]}],"web":[{"name":"connectivity_plus_web","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_web-1.2.5/","dependencies":[]}]},"dependencyGraph":[{"name":"connectivity_plus","dependencies":["connectivity_plus_linux","connectivity_plus_macos","connectivity_plus_web","connectivity_plus_windows"]},{"name":"connectivity_plus_linux","dependencies":[]},{"name":"connectivity_plus_macos","dependencies":[]},{"name":"connectivity_plus_web","dependencies":[]},{"name":"connectivity_plus_windows","dependencies":[]}],"date_created":"2022-12-14 12:54:36.553871","version":"3.3.8"} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"connectivity_plus","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus-2.3.9/","native_build":true,"dependencies":[]},{"name":"path_provider_ios","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_ios-2.0.11/","native_build":true,"dependencies":[]}],"android":[{"name":"connectivity_plus","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus-2.3.9/","native_build":true,"dependencies":[]},{"name":"path_provider_android","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_android-2.0.22/","native_build":true,"dependencies":[]}],"macos":[{"name":"connectivity_plus_macos","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_macos-1.2.4/","native_build":true,"dependencies":[]},{"name":"path_provider_macos","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-2.0.6/","native_build":true,"dependencies":[]}],"linux":[{"name":"connectivity_plus_linux","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_linux-1.3.1/","native_build":false,"dependencies":[]},{"name":"path_provider_linux","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-2.1.7/","native_build":false,"dependencies":[]}],"windows":[{"name":"connectivity_plus_windows","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_windows-1.2.2/","native_build":true,"dependencies":[]},{"name":"path_provider_windows","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-2.1.3/","native_build":false,"dependencies":[]}],"web":[{"name":"connectivity_plus_web","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_web-1.2.5/","dependencies":[]}]},"dependencyGraph":[{"name":"connectivity_plus","dependencies":["connectivity_plus_linux","connectivity_plus_macos","connectivity_plus_web","connectivity_plus_windows"]},{"name":"connectivity_plus_linux","dependencies":[]},{"name":"connectivity_plus_macos","dependencies":[]},{"name":"connectivity_plus_web","dependencies":[]},{"name":"connectivity_plus_windows","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_ios","path_provider_linux","path_provider_macos","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_ios","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]}],"date_created":"2022-12-15 14:54:08.206645","version":"3.3.8"} \ No newline at end of file diff --git a/packages/fl_query/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java b/packages/fl_query/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java index 47e95c9..13c6128 100644 --- a/packages/fl_query/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java +++ b/packages/fl_query/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java @@ -20,5 +20,10 @@ public final class GeneratedPluginRegistrant { } catch(Exception e) { Log.e(TAG, "Error registering plugin connectivity_plus, dev.fluttercommunity.plus.connectivity.ConnectivityPlugin", e); } + try { + flutterEngine.getPlugins().add(new io.flutter.plugins.pathprovider.PathProviderPlugin()); + } catch(Exception e) { + Log.e(TAG, "Error registering plugin path_provider_android, io.flutter.plugins.pathprovider.PathProviderPlugin", e); + } } } diff --git a/packages/fl_query/example/ios/Runner/GeneratedPluginRegistrant.m b/packages/fl_query/example/ios/Runner/GeneratedPluginRegistrant.m index a85d5ee..d8aace8 100644 --- a/packages/fl_query/example/ios/Runner/GeneratedPluginRegistrant.m +++ b/packages/fl_query/example/ios/Runner/GeneratedPluginRegistrant.m @@ -12,10 +12,17 @@ @import connectivity_plus; #endif +#if __has_include() +#import +#else +@import path_provider_ios; +#endif + @implementation GeneratedPluginRegistrant + (void)registerWithRegistry:(NSObject*)registry { [ConnectivityPlusPlugin registerWithRegistrar:[registry registrarForPlugin:@"ConnectivityPlusPlugin"]]; + [FLTPathProviderPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTPathProviderPlugin"]]; } @end diff --git a/packages/fl_query/example/lib/components/infinite_query_disk_cache.dart b/packages/fl_query/example/lib/components/infinite_query_disk_cache.dart new file mode 100644 index 0000000..3bdb5ec --- /dev/null +++ b/packages/fl_query/example/lib/components/infinite_query_disk_cache.dart @@ -0,0 +1,99 @@ +import 'dart:convert'; + +import 'package:fl_query/fl_query.dart'; +import 'package:fl_query_example/components/query_disk_cache.dart'; +import 'package:flutter/material.dart'; +import 'package:http/http.dart' as http; + +final infiniteQueryDiskCacheExampleQuery = + InfiniteQueryJob, void, int>( + queryKey: 'infiniteQueryDiskCacheExampleQuery', + initialParam: 0, + getNextPageParam: (lastPage, lastParam) { + if (lastPage.length < 5) return null; + return lastParam + 5; + }, + getPreviousPageParam: (firstPage, firstParam) { + if (firstParam == 0) return null; + return firstParam - 5; + }, + serialize: (data) { + return jsonEncode(data.map((user) => user.toJson()).toList()); + }, + deserialize: (raw) { + return List.from(jsonDecode(raw)) + .map((user) => User.fromJson(user)) + .toList(); + }, + serializePageParam: (param) => param.toString(), + deserializePageParam: (rawParam) => int.parse(rawParam), + task: (_, pageParam, __) async { + final res = await http.get( + Uri.parse( + "https://jsonplaceholder.typicode.com/users?_start=$pageParam&_end=${pageParam + 5}"), + ); + final body = List.from(jsonDecode(res.body)) + .map((user) => User.fromJson(user)) + .toList() + ..shuffle(); + if (pageParam == 0) await Future.delayed(const Duration(seconds: 5)); + return body; + }, +); + +class InfiniteQueryDiskCacheExample extends StatefulWidget { + const InfiniteQueryDiskCacheExample({Key? key}) : super(key: key); + + @override + State createState() => + _InfiniteQueryDiskCacheExampleState(); +} + +class _InfiniteQueryDiskCacheExampleState + extends State { + @override + Widget build(BuildContext context) { + return ListTile( + title: const Text("Infinite Query Disk Cache Example"), + onTap: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) { + return Scaffold( + appBar: AppBar( + title: const Text("Infinite Query Disk Cache Example")), + body: InfiniteQueryBuilder, void, int>( + job: infiniteQueryDiskCacheExampleQuery, + externalData: null, + builder: (context, query) { + final data = + query.pages.expand((page) => page!.toList()).toList(); + return Scaffold( + floatingActionButton: FloatingActionButton( + child: const Icon(Icons.download_rounded), + onPressed: () { + if (query.hasNextPage == true) { + query.fetchNextPage(); + } + }, + ), + body: ListView.builder( + itemCount: data.length, + itemBuilder: (context, index) { + return ListTile( + title: Text(data[index].name!), + subtitle: Text(data[index].email!), + ); + }, + ), + ); + }, + ), + ); + }, + ), + ); + }, + ); + } +} diff --git a/packages/fl_query/example/lib/components/query_disk_cache.dart b/packages/fl_query/example/lib/components/query_disk_cache.dart new file mode 100644 index 0000000..b6b4dd2 --- /dev/null +++ b/packages/fl_query/example/lib/components/query_disk_cache.dart @@ -0,0 +1,79 @@ +import 'dart:convert'; + +import 'package:fl_query/fl_query.dart'; +import 'package:flutter/material.dart'; +import 'package:http/http.dart' as http; + +final queryDiskCacheExampleQuery = QueryJob, void>( + queryKey: 'queryDiskCacheExampleQuery', + serialize: (data) { + return jsonEncode(data.map((user) => user.toJson()).toList()); + }, + deserialize: (raw) { + return List.from(jsonDecode(raw)) + .map((user) => User.fromJson(user)) + .toList(); + }, + task: (_, __) async { + final res = + await http.get(Uri.parse("https://jsonplaceholder.typicode.com/users")); + final body = List.from(jsonDecode(res.body)) + .map((user) => User.fromJson(user)) + .toList() + ..shuffle(); + await Future.delayed(const Duration(seconds: 5)); + return body; + }, +); + +class User { + int? id; + String? name; + String? username; + String? email; + + User({this.id, this.name, this.username, this.email}); + + User.fromJson(Map json) { + id = json['id']; + name = json['name']; + username = json['username']; + email = json['email']; + } + + Map toJson() { + final Map data = {}; + data['id'] = id; + data['name'] = name; + data['username'] = username; + data['email'] = email; + return data; + } +} + +class QueryDiskCacheExample extends StatelessWidget { + const QueryDiskCacheExample({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return QueryBuilder, void>( + job: queryDiskCacheExampleQuery, + externalData: null, + builder: (context, query) { + if (!query.hasData) { + return const Center(child: CircularProgressIndicator()); + } + return ListView.builder( + shrinkWrap: true, + itemCount: query.data?.length, + itemBuilder: (context, index) { + return ListTile( + title: Text(query.data![index].name!), + subtitle: Text(query.data![index].email!), + ); + }, + ); + }, + ); + } +} diff --git a/packages/fl_query/example/lib/main.dart b/packages/fl_query/example/lib/main.dart index bdddd44..1bca34e 100644 --- a/packages/fl_query/example/lib/main.dart +++ b/packages/fl_query/example/lib/main.dart @@ -2,15 +2,19 @@ import 'package:fl_query_example/components/basic_infinite_query.dart'; import 'package:fl_query_example/components/basic_mutation.dart'; import 'package:fl_query/fl_query.dart'; import 'package:fl_query_example/components/basic_query.dart'; +import 'package:fl_query_example/components/infinite_query_disk_cache.dart'; import 'package:fl_query_example/components/lazy_query.dart'; import 'package:fl_query_example/components/mutation_variable_key.dart'; +import 'package:fl_query_example/components/query_disk_cache.dart'; import 'package:fl_query_example/components/query_external_data.dart'; import 'package:fl_query_example/components/query_previous_data.dart'; import 'package:fl_query_example/components/query_variable_key.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; -void main() { +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + await initializeFlQuery(cacheKey: "example"); debugRepaintRainbowEnabled = true; runApp(const MyApp()); } @@ -70,6 +74,8 @@ class _MyHomePageState extends State with WidgetsBindingObserver { ); }, ), + const QueryDiskCacheExample(), + const InfiniteQueryDiskCacheExample(), const Divider(), const BasicMutationExample(), const MutationVariableKeyExample(), diff --git a/packages/fl_query/example/macos/Flutter/GeneratedPluginRegistrant.swift b/packages/fl_query/example/macos/Flutter/GeneratedPluginRegistrant.swift index be95aee..79818f9 100644 --- a/packages/fl_query/example/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/packages/fl_query/example/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,7 +6,9 @@ import FlutterMacOS import Foundation import connectivity_plus_macos +import path_provider_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin")) + PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) } diff --git a/packages/fl_query/example/pubspec.lock b/packages/fl_query/example/pubspec.lock index 790430a..86b66bb 100644 --- a/packages/fl_query/example/pubspec.lock +++ b/packages/fl_query/example/pubspec.lock @@ -120,6 +120,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.1" + file: + dependency: transitive + description: + name: file + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.4" fl_query: dependency: "direct main" description: @@ -149,6 +156,20 @@ packages: description: flutter source: sdk version: "0.0.0" + hive: + dependency: transitive + description: + name: hive + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.3" + hive_flutter: + dependency: transitive + description: + name: hive_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" http: dependency: "direct main" description: @@ -219,6 +240,55 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.2" + path_provider: + dependency: transitive + description: + name: path_provider + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.11" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.22" + path_provider_ios: + dependency: transitive + description: + name: path_provider_ios + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.11" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.7" + path_provider_macos: + dependency: transitive + description: + name: path_provider_macos + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.6" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.5" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.3" petitparser: dependency: transitive description: @@ -226,6 +296,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "5.0.0" + platform: + dependency: transitive + description: + name: platform + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" plugin_platform_interface: dependency: transitive description: @@ -233,13 +310,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.2" + process: + dependency: transitive + description: + name: process + url: "https://pub.dartlang.org" + source: hosted + version: "4.2.4" queue: dependency: transitive description: name: queue url: "https://pub.dartlang.org" source: hosted - version: "3.1.0+1" + version: "3.1.0+2" sky_engine: dependency: transitive description: flutter @@ -315,6 +399,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.2" + win32: + dependency: transitive + description: + name: win32 + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.2" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.0+2" xml: dependency: transitive description: @@ -324,4 +422,4 @@ packages: version: "6.1.0" sdks: dart: ">=2.17.1 <3.0.0" - flutter: ">=1.22.0" + flutter: ">=3.0.0" diff --git a/packages/fl_query/lib/fl_query.dart b/packages/fl_query/lib/fl_query.dart index f1b281d..5751885 100644 --- a/packages/fl_query/lib/fl_query.dart +++ b/packages/fl_query/lib/fl_query.dart @@ -1,5 +1,12 @@ library fl_query; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/foundation.dart'; +import 'package:hive_flutter/hive_flutter.dart'; +import 'package:path/path.dart' + if (dart.library.html) 'package:hive_flutter/src/stub/path.dart' + as path_helper; + export 'src/infinite_query.dart'; export 'src/infinite_query_builder.dart'; export 'src/query.dart'; @@ -10,4 +17,42 @@ export 'src/mutation_builder.dart'; export 'src/models/infinite_query_job.dart'; export 'src/models/query_job.dart'; export 'src/models/mutation_job.dart'; +import 'package:path_provider/path_provider.dart'; export 'src/utils.dart' show isShallowEqual, getVariable; + +late final kFlQueryBoxKey; + +/// `cacheKey`: An unique key to identify the cache of fl_query for this +/// application +/// +/// `cacheSubDirectory`: The sub directory to store the cache file +/// +/// `encryptionKey`: The encryption key to encrypt the cache of fl_query +/// +/// If not provided then the cache won't be encrypted. +/// The encryption key must be a list of 32 integers +/// +/// You can use [Random.secure().nextBytes(32)] to generate a random encryption key. +/// And store that key in a secure storage like +/// [flutter_secure_storage](https://pub.dev/packages/flutter_secure_storage) +/// for securely storing the encryption key when your application is closed. +Future initializeFlQuery({ + required String cacheKey, + List? encryptionKey, + String? cacheSubDirectory, +}) async { + WidgetsFlutterBinding.ensureInitialized(); + if (kIsWeb) return; + + final appDir = await getApplicationDocumentsDirectory(); + Hive.init( + path_helper.join(appDir.path, cacheSubDirectory), + backendPreference: HiveStorageBackendPreference.webWorker, + ); + kFlQueryBoxKey = cacheKey + "-fl_query"; + await Hive.openLazyBox( + kFlQueryBoxKey, + encryptionCipher: + encryptionKey != null ? HiveAesCipher(encryptionKey) : null, + ); +} diff --git a/packages/fl_query/lib/src/base_query.dart b/packages/fl_query/lib/src/base_query.dart index 0674a34..2df7e3f 100644 --- a/packages/fl_query/lib/src/base_query.dart +++ b/packages/fl_query/lib/src/base_query.dart @@ -1,11 +1,12 @@ import 'dart:async'; import 'package:connectivity_plus/connectivity_plus.dart'; +import 'package:fl_query/fl_query.dart'; import 'package:fl_query/src/base_operation.dart'; import 'package:fl_query/src/mixins/autocast.dart'; -import 'package:fl_query/src/query.dart'; import 'package:fl_query/src/utils.dart'; import 'package:flutter/widgets.dart'; +import 'package:hive/hive.dart'; abstract class BaseQuery extends BaseOperation with AutoCast { @@ -79,6 +80,9 @@ abstract class BaseQuery if (refetchInterval != null && refetchInterval != Duration.zero) { _refetchIntervalTimer = createRefetchTimer(); } + if (canCacheToDisk) { + loadFromDisk(); + } } // all getters & setters @@ -88,6 +92,33 @@ abstract class BaseQuery @protected Timer createRefetchTimer(); + @protected + Future loadFromDisk() async { + final box = await Hive.lazyBox(kFlQueryBoxKey); + final rawData = await box.get(queryKey); + if (rawData == null) return; + data = deserialize(rawData); + if (!isLoading && !isRefetching) { + status = QueryStatus.cached; + } + updatedAt = DateTime.now(); + await notifyDataListeners(); + notifyListeners(); + } + + Future saveToDisk({bool delete = false}) async { + if (!canCacheToDisk) return; + if (!hasData) { + if (delete) { + final box = await Hive.lazyBox(kFlQueryBoxKey); + await box.delete(queryKey); + } + return; + } + final box = await Hive.lazyBox(kFlQueryBoxKey); + await box.put(queryKey, serialize(data!)!); + } + /// Calls the task function & doesn't check if there's already /// cached data available @protected @@ -95,6 +126,7 @@ abstract class BaseQuery try { retryAttempts = 0; await setData(); + await saveToDisk(); _prevUsedExternalData = _externalData; updatedAt = DateTime.now(); status = QueryStatus.success; @@ -112,6 +144,7 @@ abstract class BaseQuery await Future.delayed(retryDelay); try { await setData(); + await saveToDisk(); _prevUsedExternalData = _externalData; status = QueryStatus.success; await notifyDataListeners(); @@ -159,6 +192,15 @@ abstract class BaseQuery Future fetch() async { if (!enabled) return null; + if (isCachedData) { + status = QueryStatus.loading; + await execute().then((_) { + fetched = true; + }); + notifyListeners(); + return data; + } + /// if isLoading/isRefetching is true that means its already fetching/ /// refetching. So [_execute] again can create a race condition if (isLoading || isRefetching || (hasData && !isPreviousData)) return data; @@ -195,6 +237,15 @@ abstract class BaseQuery return await execute().then((_) => data); } + @protected + String? serialize(T data); + + @protected + T? deserialize(String rawData); + + @protected + bool get canCacheToDisk; + @protected FutureOr setData(); @protected @@ -229,6 +280,7 @@ abstract class BaseQuery void reset() { refetchCount = 0; data = _previousData ?? _initialData; + saveToDisk(delete: true); error = null; fetched = false; status = QueryStatus.idle; @@ -238,6 +290,12 @@ abstract class BaseQuery mounts.clear(); } + @override + void dispose() async { + await Hive.openLazyBox(kFlQueryBoxKey).then((box) => box.delete(queryKey)); + super.dispose(); + } + /// Update configurations of the query /// after already creating the Query instance /// @@ -314,6 +372,7 @@ abstract class BaseQuery final newData = await updateFn(data); if (data == newData) return; data = newData; + await saveToDisk(); status = QueryStatus.success; notifyListeners(); } @@ -347,6 +406,7 @@ abstract class BaseQuery bool get isLoading => status == QueryStatus.loading; bool get isRefetching => status == QueryStatus.refetching; bool get isSuccess => status == QueryStatus.success; + bool get isCachedData => status == QueryStatus.cached; bool get isPreviousData { return _previousData != null ? _previousData == data : false; } diff --git a/packages/fl_query/lib/src/infinite_query.dart b/packages/fl_query/lib/src/infinite_query.dart index 9a702f3..8058808 100644 --- a/packages/fl_query/lib/src/infinite_query.dart +++ b/packages/fl_query/lib/src/infinite_query.dart @@ -1,9 +1,9 @@ import 'dart:async'; +import 'dart:convert'; import 'package:connectivity_plus/connectivity_plus.dart'; +import 'package:fl_query/fl_query.dart'; import 'package:fl_query/src/base_query.dart'; -import 'package:fl_query/src/models/infinite_query_job.dart'; -import 'package:fl_query/src/query.dart'; import 'package:flutter/cupertino.dart'; import 'package:queue/queue.dart'; @@ -46,6 +46,12 @@ class InfiniteQuery final Set> onErrorListeners = Set(); + final SerializeFunction? _serializePage; + final DeserializeFunction? _deserializePage; + + final SerializeFunction? serializePageParam; + final DeserializeFunction? deserializePageParam; + InfiniteQuery({ required super.queryKey, required this.task, @@ -63,13 +69,21 @@ class InfiniteQuery super.previousData, super.connectivity, super.refetchOnApplicationResume, + DeserializeFunction? deserialize, + SerializeFunction? serialize, InfiniteQueryListeners? super.onData, InfiniteQueryListeners? super.onError, required T? initialPage, this.getNextPageParam, this.getPreviousPageParam, + this.serializePageParam, + this.deserializePageParam, }) : _currentParam = initialParam, - super(initialData: {initialParam: initialPage}); + _serializePage = serialize, + _deserializePage = deserialize, + super( + initialData: {initialParam: initialPage}, + ); InfiniteQuery.fromOptions( InfiniteQueryJob options, { @@ -80,6 +94,10 @@ class InfiniteQuery _currentParam = options.initialParam, getNextPageParam = options.getNextPageParam, getPreviousPageParam = options.getPreviousPageParam, + _serializePage = options.serialize, + _deserializePage = options.deserialize, + serializePageParam = options.serializePageParam, + deserializePageParam = options.deserializePageParam, super( cacheTime: options.cacheTime ?? const Duration(minutes: 5), retries: options.retries ?? 3, @@ -273,4 +291,37 @@ class InfiniteQuery @override bool get hasData => data?[_currentParam] != null; + + @override + bool get canCacheToDisk => + _serializePage != null && + _deserializePage != null && + serializePageParam != null && + deserializePageParam != null; + + @override + deserialize(String rawData) { + if (deserializePageParam == null || _deserializePage == null) return null; + return Map.from(jsonDecode(rawData)).cast().map( + (key, value) { + return MapEntry(deserializePageParam!(key), _deserializePage!(value)); + }, + ); + } + + @override + serialize(data) { + if (serializePageParam == null || _serializePage == null) return null; + + data.removeWhere((key, value) => value == null); + + return jsonEncode(data.map( + (key, value) { + return MapEntry( + serializePageParam!(key), + _serializePage!(value!), + ); + }, + )); + } } diff --git a/packages/fl_query/lib/src/models/infinite_query_job.dart b/packages/fl_query/lib/src/models/infinite_query_job.dart index d92b66b..d6756fb 100644 --- a/packages/fl_query/lib/src/models/infinite_query_job.dart +++ b/packages/fl_query/lib/src/models/infinite_query_job.dart @@ -1,11 +1,16 @@ import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:fl_query/src/infinite_query.dart'; +import 'package:fl_query/src/models/query_job.dart'; import 'package:flutter/widgets.dart'; class InfiniteQueryJob { // all params String _queryKey; InfiniteQueryTaskFunction task; + SerializeFunction? serialize; + DeserializeFunction? deserialize; + SerializeFunction? serializePageParam; + DeserializeFunction? deserializePageParam; final int? retries; final Duration? retryDelay; T? initialPage; @@ -51,7 +56,23 @@ class InfiniteQueryJob { this.refetchOnApplicationResume, this.refetchOnWindowFocus, this.connectivity, - }) : _queryKey = queryKey; + this.deserialize, + this.serialize, + this.serializePageParam, + this.deserializePageParam, + }) : assert( + serialize == null && + deserialize == null && + serializePageParam == null && + deserializePageParam == null || + (serialize != null && + deserialize != null && + serializePageParam != null && + deserializePageParam != null && + enabled != false), + "All or none of the serialize, deserialize, serializePageParam & deserializePageParam function must be provided. And `enabled` must be true if all of them are provided.", + ), + _queryKey = queryKey; String get queryKey => _queryKey; @@ -79,6 +100,10 @@ class InfiniteQueryJob { bool? refetchOnApplicationResume, bool? refetchOnWindowFocus, Connectivity? connectivity, + SerializeFunction? serialize, + DeserializeFunction? deserialize, + SerializeFunction? serializePageParam, + DeserializeFunction? deserializePageParam, }) { return (String queryKey) { if (preQueryKey != null) queryKey = "$preQueryKey#$queryKey"; @@ -101,6 +126,10 @@ class InfiniteQueryJob { refetchOnWindowFocus: refetchOnWindowFocus, connectivity: connectivity, initialParam: initialParam, + serialize: serialize, + deserialize: deserialize, + serializePageParam: serializePageParam, + deserializePageParam: deserializePageParam, ); query.isDynamic = true; return query; diff --git a/packages/fl_query/lib/src/models/query_job.dart b/packages/fl_query/lib/src/models/query_job.dart index 4886021..fa9cf1e 100644 --- a/packages/fl_query/lib/src/models/query_job.dart +++ b/packages/fl_query/lib/src/models/query_job.dart @@ -2,10 +2,15 @@ import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:fl_query/src/query.dart'; import 'package:flutter/widgets.dart'; +typedef SerializeFunction = String Function(T data); +typedef DeserializeFunction = T Function(String raw); + class QueryJob { // all params String _queryKey; QueryTaskFunction task; + final SerializeFunction? serialize; + final DeserializeFunction? deserialize; final int? retries; final Duration? retryDelay; T? initialData; @@ -47,7 +52,14 @@ class QueryJob { this.keepPreviousData, this.refetchOnApplicationResume, this.refetchOnWindowFocus, - }) : _queryKey = queryKey; + this.deserialize, + this.serialize, + }) : assert( + serialize == null && deserialize == null || + (serialize != null && deserialize != null && enabled != false), + "Both or none of the serialize and deserialize function must be provided and enabled must be true if you want to use disk caching", + ), + _queryKey = queryKey; String get queryKey => _queryKey; @@ -73,6 +85,8 @@ class QueryJob { bool? refetchOnWindowFocus, Connectivity? connectivity, bool? keepPreviousData, + SerializeFunction? serialize, + DeserializeFunction? deserialize, }) { return (String queryKey) { if (preQueryKey != null) queryKey = "$preQueryKey#$queryKey"; @@ -93,6 +107,8 @@ class QueryJob { keepPreviousData: keepPreviousData, refetchOnApplicationResume: refetchOnApplicationResume, refetchOnWindowFocus: refetchOnWindowFocus, + serialize: serialize, + deserialize: deserialize, ); query.isDynamic = true; return query; diff --git a/packages/fl_query/lib/src/query.dart b/packages/fl_query/lib/src/query.dart index 5b2a653..bd13062 100644 --- a/packages/fl_query/lib/src/query.dart +++ b/packages/fl_query/lib/src/query.dart @@ -22,7 +22,10 @@ enum QueryStatus { idle, /// when the query is refetching (rerunning) - refetching; + refetching, + + /// when the query data is loaded from cache + cached, } typedef QueryTaskFunction = FutureOr Function( @@ -42,6 +45,9 @@ class Query extends BaseQuery { final Set> onDataListeners = Set(); final Set> onErrorListeners = Set(); + final SerializeFunction? _serialize; + final DeserializeFunction? _deserialize; + Query({ required super.queryKey, required this.task, @@ -59,9 +65,12 @@ class Query extends BaseQuery { super.connectivity, super.initialData, super.refetchOnApplicationResume, + SerializeFunction? serialize, + DeserializeFunction? deserialize, QueryListener? super.onData, QueryListener? super.onError, - }); + }) : _deserialize = deserialize, + _serialize = serialize; Query.fromOptions( QueryJob options, { @@ -70,6 +79,8 @@ class Query extends BaseQuery { QueryListener? onData, QueryListener? onError, }) : task = options.task, + _deserialize = options.deserialize, + _serialize = options.serialize, super( cacheTime: options.cacheTime ?? const Duration(minutes: 5), retries: options.retries ?? 3, @@ -133,4 +144,19 @@ class Query extends BaseQuery { void setError(e) { error = e; } + + @override + deserialize(rawData) { + if (_deserialize == null) return null; + return _deserialize!(rawData); + } + + @override + serialize(data) { + if (_serialize == null) return null; + return _serialize!(data); + } + + @override + bool get canCacheToDisk => _serialize != null && _deserialize != null; } diff --git a/packages/fl_query/lib/src/query_bowl.dart b/packages/fl_query/lib/src/query_bowl.dart index d7421e6..fef421a 100644 --- a/packages/fl_query/lib/src/query_bowl.dart +++ b/packages/fl_query/lib/src/query_bowl.dart @@ -5,6 +5,7 @@ import 'package:fl_query/src/utils.dart'; import 'package:flutter/cupertino.dart'; import 'package:collection/collection.dart'; import 'package:flutter/services.dart'; +import 'package:hive_flutter/hive_flutter.dart'; /// The widget that holds every [Query] & [Mutation] to your /// entire Flutter application in anywhere diff --git a/packages/fl_query/lib/src/query_cache.dart b/packages/fl_query/lib/src/query_cache.dart index 1d3154a..308729e 100644 --- a/packages/fl_query/lib/src/query_cache.dart +++ b/packages/fl_query/lib/src/query_cache.dart @@ -40,7 +40,13 @@ class QueryCache { _listenToQueryChanges(Query query) { query.addListener(() { if (query.isInactive) { - _queries.removeWhere((el) => el.queryKey != query.queryKey); + _queries.removeWhere((el) { + if (el.queryKey != query.queryKey) { + el.dispose(); + return true; + } + return false; + }); _notifyListeners(CacheEvent.query, null); } else { _notifyListeners(CacheEvent.query, query); @@ -51,8 +57,13 @@ class QueryCache { _listenToInfiniteQueryChanges(InfiniteQuery infiniteQuery) { infiniteQuery.addListener(() { if (infiniteQuery.isInactive) { - _infiniteQueries - .removeWhere((el) => el.queryKey != infiniteQuery.queryKey); + _infiniteQueries.removeWhere((el) { + if (el.queryKey != infiniteQuery.queryKey) { + el.dispose(); + return true; + } + return false; + }); _notifyListeners(CacheEvent.infiniteQuery, null); } else { _notifyListeners(CacheEvent.infiniteQuery, infiniteQuery); @@ -64,7 +75,13 @@ class QueryCache { mutation.addListener(() { if (mutation.isInactive) { _mutations.removeWhere( - (el) => el.mutationKey != mutation.mutationKey, + (el) { + if (el.mutationKey != mutation.mutationKey) { + el.dispose(); + return true; + } + return false; + }, ); _notifyListeners(CacheEvent.mutation, null); } else { @@ -92,21 +109,27 @@ class QueryCache { } void removeQuery(Query query) { + query.dispose(); _queries.remove(query); _notifyListeners(CacheEvent.query, null); } void removeInfiniteQuery(InfiniteQuery infiniteQuery) { + infiniteQuery.dispose(); _infiniteQueries.remove(infiniteQuery); _notifyListeners(CacheEvent.infiniteQuery, null); } void removeMutation(Mutation mutation) { + mutation.dispose(); _mutations.remove(mutation); _notifyListeners(CacheEvent.mutation, null); } void clearCache() { + _infiniteQueries.forEach((el) => el.dispose()); + _queries.forEach((el) => el.dispose()); + _mutations.forEach((el) => el.dispose()); _infiniteQueries.clear(); _queries.clear(); _mutations.clear(); diff --git a/packages/fl_query/pubspec.yaml b/packages/fl_query/pubspec.yaml index b9f8aec..f0619e6 100644 --- a/packages/fl_query/pubspec.yaml +++ b/packages/fl_query/pubspec.yaml @@ -17,6 +17,7 @@ dependencies: connectivity_plus: ^2.3.9 flutter: sdk: flutter + hive_flutter: ^1.1.0 queue: ^3.1.0+1 uuid: ^3.0.6 diff --git a/packages/fl_query_hooks/.flutter-plugins b/packages/fl_query_hooks/.flutter-plugins index 84381da..4868dd5 100644 --- a/packages/fl_query_hooks/.flutter-plugins +++ b/packages/fl_query_hooks/.flutter-plugins @@ -4,3 +4,9 @@ connectivity_plus_linux=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connec connectivity_plus_macos=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_macos-1.2.6/ connectivity_plus_web=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_web-1.2.5/ connectivity_plus_windows=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_windows-1.2.2/ +path_provider=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.11/ +path_provider_android=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_android-2.0.22/ +path_provider_ios=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_ios-2.0.11/ +path_provider_linux=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-2.1.7/ +path_provider_macos=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-2.0.6/ +path_provider_windows=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-2.1.3/ diff --git a/packages/fl_query_hooks/.flutter-plugins-dependencies b/packages/fl_query_hooks/.flutter-plugins-dependencies index 62bad65..e8bd197 100644 --- a/packages/fl_query_hooks/.flutter-plugins-dependencies +++ b/packages/fl_query_hooks/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"connectivity_plus","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus-2.3.9/","native_build":true,"dependencies":[]}],"android":[{"name":"connectivity_plus","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus-2.3.9/","native_build":true,"dependencies":[]}],"macos":[{"name":"connectivity_plus_macos","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_macos-1.2.6/","native_build":true,"dependencies":[]}],"linux":[{"name":"connectivity_plus_linux","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_linux-1.3.1/","native_build":false,"dependencies":[]}],"windows":[{"name":"connectivity_plus_windows","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_windows-1.2.2/","native_build":true,"dependencies":[]}],"web":[{"name":"connectivity_plus_web","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_web-1.2.5/","dependencies":[]}]},"dependencyGraph":[{"name":"connectivity_plus","dependencies":["connectivity_plus_linux","connectivity_plus_macos","connectivity_plus_web","connectivity_plus_windows"]},{"name":"connectivity_plus_linux","dependencies":[]},{"name":"connectivity_plus_macos","dependencies":[]},{"name":"connectivity_plus_web","dependencies":[]},{"name":"connectivity_plus_windows","dependencies":[]}],"date_created":"2022-12-14 11:46:01.321906","version":"3.3.8"} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"connectivity_plus","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus-2.3.9/","native_build":true,"dependencies":[]},{"name":"path_provider_ios","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_ios-2.0.11/","native_build":true,"dependencies":[]}],"android":[{"name":"connectivity_plus","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus-2.3.9/","native_build":true,"dependencies":[]},{"name":"path_provider_android","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_android-2.0.22/","native_build":true,"dependencies":[]}],"macos":[{"name":"connectivity_plus_macos","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_macos-1.2.6/","native_build":true,"dependencies":[]},{"name":"path_provider_macos","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-2.0.6/","native_build":true,"dependencies":[]}],"linux":[{"name":"connectivity_plus_linux","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_linux-1.3.1/","native_build":false,"dependencies":[]},{"name":"path_provider_linux","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-2.1.7/","native_build":false,"dependencies":[]}],"windows":[{"name":"connectivity_plus_windows","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_windows-1.2.2/","native_build":true,"dependencies":[]},{"name":"path_provider_windows","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-2.1.3/","native_build":false,"dependencies":[]}],"web":[{"name":"connectivity_plus_web","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_web-1.2.5/","dependencies":[]}]},"dependencyGraph":[{"name":"connectivity_plus","dependencies":["connectivity_plus_linux","connectivity_plus_macos","connectivity_plus_web","connectivity_plus_windows"]},{"name":"connectivity_plus_linux","dependencies":[]},{"name":"connectivity_plus_macos","dependencies":[]},{"name":"connectivity_plus_web","dependencies":[]},{"name":"connectivity_plus_windows","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_ios","path_provider_linux","path_provider_macos","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_ios","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]}],"date_created":"2022-12-15 14:11:22.006668","version":"3.3.8"} \ No newline at end of file diff --git a/packages/fl_query_hooks/example/.flutter-plugins b/packages/fl_query_hooks/example/.flutter-plugins index d393acb..7051ea8 100644 --- a/packages/fl_query_hooks/example/.flutter-plugins +++ b/packages/fl_query_hooks/example/.flutter-plugins @@ -4,3 +4,9 @@ connectivity_plus_linux=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connec connectivity_plus_macos=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_macos-1.2.4/ connectivity_plus_web=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_web-1.2.5/ connectivity_plus_windows=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_windows-1.2.2/ +path_provider=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.11/ +path_provider_android=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_android-2.0.22/ +path_provider_ios=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_ios-2.0.11/ +path_provider_linux=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-2.1.7/ +path_provider_macos=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-2.0.6/ +path_provider_windows=/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-2.1.3/ diff --git a/packages/fl_query_hooks/example/.flutter-plugins-dependencies b/packages/fl_query_hooks/example/.flutter-plugins-dependencies index fffc13e..8f41978 100644 --- a/packages/fl_query_hooks/example/.flutter-plugins-dependencies +++ b/packages/fl_query_hooks/example/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"connectivity_plus","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus-2.3.9/","native_build":true,"dependencies":[]}],"android":[{"name":"connectivity_plus","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus-2.3.9/","native_build":true,"dependencies":[]}],"macos":[{"name":"connectivity_plus_macos","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_macos-1.2.4/","native_build":true,"dependencies":[]}],"linux":[{"name":"connectivity_plus_linux","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_linux-1.3.1/","native_build":false,"dependencies":[]}],"windows":[{"name":"connectivity_plus_windows","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_windows-1.2.2/","native_build":true,"dependencies":[]}],"web":[{"name":"connectivity_plus_web","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_web-1.2.5/","dependencies":[]}]},"dependencyGraph":[{"name":"connectivity_plus","dependencies":["connectivity_plus_linux","connectivity_plus_macos","connectivity_plus_web","connectivity_plus_windows"]},{"name":"connectivity_plus_linux","dependencies":[]},{"name":"connectivity_plus_macos","dependencies":[]},{"name":"connectivity_plus_web","dependencies":[]},{"name":"connectivity_plus_windows","dependencies":[]}],"date_created":"2022-12-14 11:46:05.508816","version":"3.3.8"} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"connectivity_plus","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus-2.3.9/","native_build":true,"dependencies":[]},{"name":"path_provider_ios","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_ios-2.0.11/","native_build":true,"dependencies":[]}],"android":[{"name":"connectivity_plus","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus-2.3.9/","native_build":true,"dependencies":[]},{"name":"path_provider_android","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_android-2.0.22/","native_build":true,"dependencies":[]}],"macos":[{"name":"connectivity_plus_macos","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_macos-1.2.4/","native_build":true,"dependencies":[]},{"name":"path_provider_macos","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-2.0.6/","native_build":true,"dependencies":[]}],"linux":[{"name":"connectivity_plus_linux","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_linux-1.3.1/","native_build":false,"dependencies":[]},{"name":"path_provider_linux","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-2.1.7/","native_build":false,"dependencies":[]}],"windows":[{"name":"connectivity_plus_windows","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_windows-1.2.2/","native_build":true,"dependencies":[]},{"name":"path_provider_windows","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-2.1.3/","native_build":false,"dependencies":[]}],"web":[{"name":"connectivity_plus_web","path":"/home/krtirtho/.pub-cache/hosted/pub.dartlang.org/connectivity_plus_web-1.2.5/","dependencies":[]}]},"dependencyGraph":[{"name":"connectivity_plus","dependencies":["connectivity_plus_linux","connectivity_plus_macos","connectivity_plus_web","connectivity_plus_windows"]},{"name":"connectivity_plus_linux","dependencies":[]},{"name":"connectivity_plus_macos","dependencies":[]},{"name":"connectivity_plus_web","dependencies":[]},{"name":"connectivity_plus_windows","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_ios","path_provider_linux","path_provider_macos","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_ios","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]}],"date_created":"2022-12-15 14:11:24.851693","version":"3.3.8"} \ No newline at end of file diff --git a/packages/fl_query_hooks/example/pubspec.lock b/packages/fl_query_hooks/example/pubspec.lock index 4d70010..678fc21 100644 --- a/packages/fl_query_hooks/example/pubspec.lock +++ b/packages/fl_query_hooks/example/pubspec.lock @@ -120,6 +120,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.1" + file: + dependency: transitive + description: + name: file + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.4" fl_query: dependency: "direct main" description: @@ -163,6 +170,20 @@ packages: description: flutter source: sdk version: "0.0.0" + hive: + dependency: transitive + description: + name: hive + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.3" + hive_flutter: + dependency: transitive + description: + name: hive_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" http: dependency: "direct main" description: @@ -226,6 +247,55 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.2" + path_provider: + dependency: transitive + description: + name: path_provider + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.11" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.22" + path_provider_ios: + dependency: transitive + description: + name: path_provider_ios + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.11" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.7" + path_provider_macos: + dependency: transitive + description: + name: path_provider_macos + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.6" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.5" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.3" petitparser: dependency: transitive description: @@ -233,6 +303,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "5.0.0" + platform: + dependency: transitive + description: + name: platform + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" plugin_platform_interface: dependency: transitive description: @@ -240,6 +317,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.2" + process: + dependency: transitive + description: + name: process + url: "https://pub.dartlang.org" + source: hosted + version: "4.2.4" queue: dependency: transitive description: @@ -315,6 +399,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.2" + win32: + dependency: transitive + description: + name: win32 + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.2" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.0+2" xml: dependency: transitive description: