From 58f98e6e74f054802db3eb5285e6d8ffc66f8ac8 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Sat, 12 Feb 2022 12:58:17 +0600 Subject: [PATCH] scheduleMicrotask utils removed in favor of dart:async getQueryData wrong arrangment of arguments Query & Retryer's future property is replaced with Completer queryFn, fetchFn & fn types corrected exported all the functions/class/enum from core (incomplete) flutter dependency dropped since the core is a Dart package --- packages/fl_query/example/bin/example.dart | 30 ++++---- packages/fl_query/example/pubspec.lock | 25 ------- packages/fl_query/lib/fl_query.dart | 3 + packages/fl_query/lib/src/core/core.dart | 21 ++++++ packages/fl_query/lib/src/core/models.dart | 6 +- .../fl_query/lib/src/core/notify_manager.dart | 6 +- packages/fl_query/lib/src/core/query.dart | 72 +++++++++++-------- .../fl_query/lib/src/core/query_client.dart | 10 +-- packages/fl_query/lib/src/core/retryer.dart | 13 ++-- .../fl_query/lib/src/core/subscribable.dart | 2 +- packages/fl_query/lib/src/core/utils.dart | 18 ++--- packages/fl_query/pubspec.yaml | 8 +-- 12 files changed, 109 insertions(+), 105 deletions(-) create mode 100644 packages/fl_query/lib/src/core/core.dart diff --git a/packages/fl_query/example/bin/example.dart b/packages/fl_query/example/bin/example.dart index 04860f2..619c3d9 100644 --- a/packages/fl_query/example/bin/example.dart +++ b/packages/fl_query/example/bin/example.dart @@ -127,20 +127,18 @@ var todos = [ }, ]; -void main(List arguments) { - QueryCache cache = QueryCache(); - for (var todo in todos.asMap().entries) { - cache.writeQuery(QueryKey.fromList(["KEY", todo.key.toString()]), data: { - "data": todo.value, - "meta": { - "created": DateTime.now(), - "expiration": DateTime.now().add(Duration(hours: 2)) - } - }); - } - - for (var i = 0; i < todos.length; i++) { - var result = cache.readQuery(QueryKey.fromList(["KEY", i.toString()])); - print(result); - } +void main(List arguments) async { + var key = QueryKey("TEST"); + QueryClient queryClient = QueryClient(); + queryClient.mount(); + var data = await queryClient.fetchQuery( + queryKey: key, + queryFn: (context) { + return Future.value(todos.first); + }, + ); + print("FETCHED DATA====="); + print(data); + print("======CACHED DATA"); + print(queryClient.getQueryData(key)); } diff --git a/packages/fl_query/example/pubspec.lock b/packages/fl_query/example/pubspec.lock index 43f064c..97410f2 100644 --- a/packages/fl_query/example/pubspec.lock +++ b/packages/fl_query/example/pubspec.lock @@ -8,13 +8,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.8.2" - characters: - dependency: transitive - description: - name: characters - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" charcode: dependency: transitive description: @@ -43,11 +36,6 @@ packages: relative: true source: path version: "0.0.1" - flutter: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" hive: dependency: transitive description: @@ -97,11 +85,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.1" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" source_span: dependency: transitive description: @@ -137,13 +120,5 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.0.5" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.1" sdks: dart: ">=2.15.1 <3.0.0" - flutter: ">=1.17.0" diff --git a/packages/fl_query/lib/fl_query.dart b/packages/fl_query/lib/fl_query.dart index b44307e..a44b61b 100644 --- a/packages/fl_query/lib/fl_query.dart +++ b/packages/fl_query/lib/fl_query.dart @@ -1 +1,4 @@ library fl_query; + +export 'package:fl_query/src/core/core.dart'; +// export 'package:fl_query/src/core/framework.dart'; diff --git a/packages/fl_query/lib/src/core/core.dart b/packages/fl_query/lib/src/core/core.dart new file mode 100644 index 0000000..c00ff42 --- /dev/null +++ b/packages/fl_query/lib/src/core/core.dart @@ -0,0 +1,21 @@ +export 'package:fl_query/src/core/retryer.dart' show CancelledError; +export 'package:fl_query/src/core/query_cache.dart' show QueryCache; +export 'package:fl_query/src/core/query_client.dart' show QueryClient; +export 'package:fl_query/src/core/query_observer.dart' show QueryObserver; +export 'package:fl_query/src/core/query_key.dart'; +// export 'package:fl_query/src/core/queriesObserver.dart' show QueriesObserver; +// export 'package:fl_query/src/core/infiniteQueryObserver.dart' show InfiniteQueryObserver; +// export 'package:fl_query/src/core/mutationCache.dart' show MutationCache; +// export 'package:fl_query/src/core/mutationObserver.dart' show MutationObserver; +// export 'package:fl_query/src/core/logger.dart' show setLogger; +export 'package:fl_query/src/core/notify_manager.dart' show notifyManager; +// export 'package:fl_query/src/core/focusManager.dart' show focusManager; +export 'package:fl_query/src/core/online_manager.dart' show onlineManager; +export 'package:fl_query/src/core/utils.dart' show hashQueryKey; +export 'package:fl_query/src/core/retryer.dart' show isCancelledError; +// export 'package:fl_query/src/core/hydration.dart' show dehydrate, DehydrateOptions, DehydratedState, HydrateOptions, ShouldDehydrateMutationFunction, ShouldDehydrateQueryFunction; + +export 'package:fl_query/src/core/models.dart'; +export 'package:fl_query/src/core/query.dart' show Query; +// export type { Mutation } from './mutation' +// export type { Logger } from './logger' \ No newline at end of file diff --git a/packages/fl_query/lib/src/core/models.dart b/packages/fl_query/lib/src/core/models.dart index 6258cd4..ba4d3b8 100644 --- a/packages/fl_query/lib/src/core/models.dart +++ b/packages/fl_query/lib/src/core/models.dart @@ -23,7 +23,7 @@ class QueryOptions { RetryDelayFunction? retryDelay; Duration? cacheTime; bool Function(TData? oldData, TData newData)? isDataEqual; - QueryFunction? queryFn; + QueryFunction? queryFn; QueryKey? queryKey; /// Basically [QueryKey.key] in short form @@ -434,7 +434,7 @@ class QueryObserverOptions QueryKeyHashFunction? queryKeyHashFn, Duration? cacheTime, bool Function(TQueryData? oldData, TQueryData newData)? isDataEqual, - QueryFunction? queryFn, + QueryFunction? queryFn, String? queryHash, TQueryData? initialData, DateTime? initialDataUpdatedAt, @@ -532,7 +532,7 @@ class FetchQueryOptions RetryDelayFunction? retryDelay, Duration? cacheTime, bool Function(TData? oldData, TData newData)? isDataEqual, - QueryFunction? queryFn, + QueryFunction? queryFn, QueryKey? queryKey, String? queryHash, QueryKeyHashFunction? queryKeyHashFn, diff --git a/packages/fl_query/lib/src/core/notify_manager.dart b/packages/fl_query/lib/src/core/notify_manager.dart index 522c97c..85231e9 100644 --- a/packages/fl_query/lib/src/core/notify_manager.dart +++ b/packages/fl_query/lib/src/core/notify_manager.dart @@ -1,6 +1,6 @@ // TYPES -import 'package:fl_query/src/core/utils.dart'; +import 'dart:async'; typedef NotifyCallback = void Function(); @@ -44,7 +44,7 @@ class _NotifyManager { if (_transactions > 0) { _queue.add(callback); } else { - scheduleMicrotask((val) { + scheduleMicrotask(() { _notifyFn(callback); }); } @@ -66,7 +66,7 @@ class _NotifyManager { var queue = _queue; _queue = []; if (queue.isNotEmpty) { - scheduleMicrotask((val) { + scheduleMicrotask(() { _batchNotifyFn(() { queue.forEach((fn) { _notifyFn(fn); diff --git a/packages/fl_query/lib/src/core/query.dart b/packages/fl_query/lib/src/core/query.dart index 9093ed1..a4d16a0 100644 --- a/packages/fl_query/lib/src/core/query.dart +++ b/packages/fl_query/lib/src/core/query.dart @@ -18,7 +18,7 @@ class FetchOptions { } class FetchContext { - FutureOr Function() fetchFn; + FutureOr Function() fetchFn; FetchOptions? fetchOptions; QueryOptions options; QueryKey queryKey; @@ -171,7 +171,8 @@ class Query { QueryMeta? meta; QueryCache _cache; - Future? _future; + // Future? _future; + Completer? _completer; Timer? _gcTimeout; Retryer? _retryer; List _observers; @@ -268,22 +269,28 @@ class Query { DataUpdateFunction updater, { DateTime? updatedAt, }) { - var prevData = this.state.data; - var data = updater(prevData); - // Use prev data if an isDataEqual function is defined and returns `true` - if (this.options.isDataEqual?.call(prevData, data) == true) { - data = prevData as TData; - } else if (this.options.structuralSharing != false) { - // Structurally share data between prev and new data if needed - data = replaceEqualDeep(prevData ?? {} as TData, data); + try { + var prevData = this.state.data; + var data = updater(prevData); + // Use prev data if an isDataEqual function is defined and returns `true` + if (this.options.isDataEqual?.call(prevData, data) == true) { + data = prevData as TData; + } else if (this.options.structuralSharing != false) { + // Structurally share data between prev and new data if needed + data = replaceEqualDeep(prevData ?? {} as TData, data); + } + // Set data and mark it as cached + _dispatch(Action( + ActionType.success, + data: data, + dataUpdatedAt: updatedAt, + )); + return data; + } catch (e, stack) { + print("[Query.setData] $e"); + print(stack); + rethrow; } - // Set data and mark it as cached - _dispatch(Action( - ActionType.success, - data: data, - dataUpdatedAt: updatedAt, - )); - return data; } void setState( @@ -298,9 +305,13 @@ class Query { } Future cancel({bool? revert, bool? silent}) { - var future = _future; + // var future = _future; _retryer?.cancel(revert: revert, silent: silent); - return future != null ? future.then(noop).catchError(noop) : Future.value(); + if (_completer != null && !_completer!.isCompleted) { + _completer!.completeError("Cancelled Job", StackTrace.current); + return _completer!.future.then(noop).catchError(noop); + } + return Future.value(); } void reset() { @@ -330,11 +341,11 @@ class Query { fetchOptions?.cancelRefetch == true) { // Silently cancel current fetch if the user wants to cancel re-fetches this.cancel(silent: true); - } else if (_future != null) { + } else if (_completer != null) { // make sure that retries that were potentially cancelled due to unmounts can continue _retryer?.continueRetry(); // Return current promise if we are already fetching - return _future!; + return _completer!.future; } } @@ -354,7 +365,8 @@ class Query { queryKeyHashFn: observer.options.queryKeyHashFn, cacheTime: observer.options.cacheTime, isDataEqual: observer.options.isDataEqual, - queryFn: observer.options.queryFn, + queryFn: + observer.options.queryFn as QueryFunction, queryHash: observer.options.queryHash, initialData: observer.options.initialData, initialDataUpdatedAt: observer.options.initialDataUpdatedAt, @@ -387,16 +399,17 @@ class Query { // }) // Create fetch function - fetchFn() { + FutureOr fetchFn() { if (this.options.queryFn == null) { return Future.error('Missing queryFn'); } _abortSignalConsumed = false; - return options?.queryFn?.call(queryFnContext); + return options!.queryFn!.call(queryFnContext); } // Trigger behavior hook - FetchContext context = FetchContext( + FetchContext context = + FetchContext( fetchOptions: fetchOptions, options: this.options, queryKey: queryKey, @@ -423,7 +436,7 @@ class Query { // Notify cache callback _cache.onData?.call(data, this); - + if (_completer?.isCompleted == false) _completer?.complete(data); // Remove query after fetching if cache time is 0 if (this.cacheTime == null || this.cacheTime == Duration.zero) { _optionalRemove(); @@ -447,6 +460,9 @@ class Query { if (this.cacheTime == null || this.cacheTime == Duration.zero) { _optionalRemove(); } + if (_completer?.isCompleted == false) + _completer?.completeError( + error ?? "Retry Failed", StackTrace.current); }, onFail: (failureCount, error) { _dispatch(Action(ActionType.failed)); @@ -461,8 +477,8 @@ class Query { retryDelay: context.options.retryDelay, ); - this._future = _retryer!.future; - return this._future!; + this._completer = _retryer!.completer; + return this._completer!.future; } void _dispatch(Action action) { diff --git a/packages/fl_query/lib/src/core/query_client.dart b/packages/fl_query/lib/src/core/query_client.dart index 7f12eeb..23c62b6 100644 --- a/packages/fl_query/lib/src/core/query_client.dart +++ b/packages/fl_query/lib/src/core/query_client.dart @@ -86,8 +86,7 @@ class QueryClient { // } TData? getQueryData( - QueryKey, - queryKey, [ + QueryKey queryKey, [ QueryFilters? filters, ]) { return _queryCache @@ -357,13 +356,14 @@ class QueryClient { } } - getMutationDefaults() {} - setMutationDefaults() {} + // getMutationDefaults() {} + // setMutationDefaults() {} + // getMutationCache() {} + QueryCache getQueryCache() { return _queryCache; } - getMutationCache() {} void clear() { _queryCache.clear(); // _mutationCache.clear(); diff --git a/packages/fl_query/lib/src/core/retryer.dart b/packages/fl_query/lib/src/core/retryer.dart index 6162000..2370da0 100644 --- a/packages/fl_query/lib/src/core/retryer.dart +++ b/packages/fl_query/lib/src/core/retryer.dart @@ -43,7 +43,8 @@ class Retryer { late void Function() cancelRetry; late void Function() continueRetry; late void Function() continueFn; - late Future future; + // late Future future; + late Completer completer; int failureCount; bool isPaused; bool isResolved; @@ -92,9 +93,9 @@ class Retryer { this.continueFn = () => continueFn?.call(); - Completer completer = Completer(); + completer = Completer(); - this.future = completer.future; + // this.future = completer.future; resolve(value) { if (!this.isResolved) { @@ -115,11 +116,11 @@ class Retryer { } pause() { - Completer completer = Completer(); - if (!completer.isCompleted) continueFn = completer.complete; + Completer pauseCompleter = Completer(); + if (!pauseCompleter.isCompleted) continueFn = pauseCompleter.complete; this.isPaused = true; onPause?.call(); - return completer.future.then((val) { + return pauseCompleter.future.then((val) { continueFn = null; this.isPaused = false; onContinue?.call(); diff --git a/packages/fl_query/lib/src/core/subscribable.dart b/packages/fl_query/lib/src/core/subscribable.dart index 48a68f8..23e01c4 100644 --- a/packages/fl_query/lib/src/core/subscribable.dart +++ b/packages/fl_query/lib/src/core/subscribable.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; +import 'package:meta/meta.dart'; abstract class Subscribable { @protected diff --git a/packages/fl_query/lib/src/core/utils.dart b/packages/fl_query/lib/src/core/utils.dart index 8fc42b4..74c6f0b 100644 --- a/packages/fl_query/lib/src/core/utils.dart +++ b/packages/fl_query/lib/src/core/utils.dart @@ -2,16 +2,6 @@ import 'package:fl_query/src/core/models.dart'; import 'package:fl_query/src/core/query.dart'; import 'package:fl_query/src/core/query_key.dart'; -/** - * Schedules a microtask. - * This can be useful to schedule state updates after rendering. - */ -void scheduleMicrotask(void Function(dynamic val) callback) { - Future.value() - .then(callback) - .catchError((error) => Future.delayed(Duration.zero, () => throw error)); -} - /// Default query keys hash function. /// Dummy function just to fill the gaps for original react-query like /// function body signatures @@ -113,15 +103,15 @@ T replaceEqualDeep(T a, T b) { bool isList = (a is Iterable && b is Iterable); if (isList || (a is Map && b is Map)) { - var aSize = isList ? a.length : (a as Map).keys.length; - var bItems = isList ? b : (b as Map).keys; - var bSize = bItems.length; + int aSize = isList ? a.length : (a as Map).keys.length; + List bItems = (isList ? b : (b as Map).keys).toList(); + int bSize = bItems.length; var copy; int equalItems = 0; for (int i = 0; i < bSize; i++) { - var key = isList ? i : (bItems as Map)[i]; + var key = isList ? i : bItems[i]; if (isList) { copy ??= []; copy[key] = replaceEqualDeep((a as List)[key], (b as List)[key]); diff --git a/packages/fl_query/pubspec.yaml b/packages/fl_query/pubspec.yaml index c614393..5672a98 100644 --- a/packages/fl_query/pubspec.yaml +++ b/packages/fl_query/pubspec.yaml @@ -5,11 +5,11 @@ homepage: https://github.com/KRTirtho/fl-query environment: sdk: ">=2.15.1 <3.0.0" - flutter: ">=1.17.0" + # flutter: ">=1.17.0" dependencies: - flutter: - sdk: flutter + # flutter: + # sdk: flutter meta: ^1.3.0 path: ^1.8.0 hive: ^2.0.0 @@ -27,4 +27,4 @@ dev_dependencies: lints: ^1.0.1 # The following section is specific to Flutter. -flutter: +# flutter: