query_cache related bug fix using query_cache_test

This commit is contained in:
Kingkor Roy Tirtho
2022-02-18 10:36:20 +06:00
parent 0b4c030806
commit 3d3f3381e9
8 changed files with 280 additions and 50 deletions
+2 -2
View File
@@ -537,7 +537,7 @@ class FetchQueryOptions<TQueryFnData extends Map<String, dynamic>, TError,
/// The time after data is considered stale.
/// If the data is fresh it will be returned from the cache.
Duration? staleTime;
FetchQueryOptions(
FetchQueryOptions({
ShouldRetryFunction<TError>? retry,
RetryDelayFunction<TError>? retryDelay,
Duration? cacheTime,
@@ -554,7 +554,7 @@ class FetchQueryOptions<TQueryFnData extends Map<String, dynamic>, TError,
GetNextPageParamFunction<TQueryFnData>? getNextPageParam,
bool? defaulted,
this.staleTime,
) : super(
}) : super(
retry: retry,
retryDelay: retryDelay,
cacheTime: cacheTime,
+1 -1
View File
@@ -280,7 +280,7 @@ class Query<TQueryFnData extends Map<String, dynamic>, TError,
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);
data = replaceEqualDeep(prevData, data);
}
// Set data and mark it as cached
_dispatch(Action(
+21 -22
View File
@@ -139,26 +139,31 @@ class QueryCache extends Subscribable<QueryCacheListener> {
}
Query<TQueryFnData, TError, TData>? find<
TQueryFnData extends Map<String, dynamic>,
TError,
TData extends Map<String, dynamic>>(
QueryKey queryKey,
QueryFilters queryFilters,
) {
TQueryFnData extends Map<String, dynamic>,
TError,
TData extends Map<String, dynamic>>(QueryKey queryKey,
[QueryFilters? queryFilters]) {
queryFilters ??= QueryFilters();
queryFilters.exact ??= true;
return _queries.firstWhereOrNull((query) => matchQuery(queryFilters, query))
as Query<TQueryFnData, TError, TData>?;
return _queries.firstWhereOrNull((query) => matchQuery(
queryFilters!,
query,
queryKey,
)) as Query<TQueryFnData, TError, TData>?;
}
List<Query> findAll(QueryKey? queryKey, [QueryFilters? filters]) {
if (queryKey == null && filters == null)
throw Exception(
"[QueryCache.findAll] both `queryKey` & `filters` can't be null");
bool filterIsEmpty =
filters?.toJson().entries.every((map) => map.value == null) ?? false;
return filterIsEmpty
List<Query> findAll([QueryKey? queryKeys, QueryFilters? filters]) {
return filters == null && queryKeys == null
? _queries
: _queries.where((query) => matchQuery(filters!, query)).toList();
: _queries
.where(
(query) => matchQuery(
filters ?? QueryFilters(),
query,
queryKeys,
),
)
.toList();
}
void notify(QueryCacheNotifyEvent event) {
@@ -169,12 +174,6 @@ class QueryCache extends Subscribable<QueryCacheListener> {
});
}
@override
void onSubscribe() {}
@override
void onUnsubscribe() {}
/// Dummy function just to keep the API similar to react-query
void onFocus() {}
@@ -97,10 +97,10 @@ class QueryClient {
}
List<QueryData<TData>> getQueriesData<TData extends Map<String, dynamic>>({
QueryKey? queryKey,
QueryKey? queryKeys,
QueryFilters? filters,
}) {
return getQueryCache().findAll(queryKey, filters).map((query) {
return getQueryCache().findAll(queryKeys, filters).map((query) {
return QueryData<TData>(
data: query.state.data as TData,
queryKey: query.queryKey,
@@ -130,15 +130,15 @@ class QueryClient {
List<QueryData> setQueriesData<TData extends Map<String, dynamic>>({
required DataUpdateFunction<TData?, TData> updater,
QueryKey? queryKey,
QueryKey? queryKeys,
QueryFilters? filters,
DateTime? updatedAt,
}) {
if (queryKey == null && filters == null)
if (queryKeys == null && filters == null)
throw Exception(
"[QueryClient.setQueriesData] both `queryKey` & `filters` can't be null at the same time");
return notifyManager
.batch(() => getQueryCache().findAll(queryKey, filters).map(
.batch(() => getQueryCache().findAll(queryKeys, filters).map(
(query) => QueryData(
queryKey: query.queryKey,
data: setQueryData<TData>(
@@ -164,10 +164,10 @@ class QueryClient {
?.state as QueryState<TData, TError>?;
}
void removeQueries({QueryKey? queryKey, QueryFilters? filters}) {
void removeQueries({QueryKey? queryKeys, QueryFilters? filters}) {
notifyManager.batch(
() => {
_queryCache.findAll(queryKey, filters).forEach((query) {
_queryCache.findAll(queryKeys, filters).forEach((query) {
_queryCache.remove(query);
})
},
@@ -175,7 +175,7 @@ class QueryClient {
}
Future<void> resetQueries<TPageData>({
QueryKey? queryKey,
QueryKey? queryKeys,
RefetchableQueryFilters<TPageData>? filters,
bool? throwOnError,
}) {
@@ -186,7 +186,7 @@ class QueryClient {
});
return notifyManager.batch(() {
_queryCache.findAll(queryKey, filters).forEach((query) {
_queryCache.findAll(queryKeys, filters).forEach((query) {
query.reset();
});
return refetchQueries(
@@ -197,13 +197,13 @@ class QueryClient {
}
Future<void> cancelQueries({
QueryKey? queryKey,
QueryKey? queryKeys,
QueryFilters? filters,
bool? revert = true,
bool? silent,
}) {
var futures = notifyManager.batch(() =>
_queryCache.findAll(queryKey, filters).map((query) => query.cancel(
_queryCache.findAll(queryKeys, filters).map((query) => query.cancel(
revert: revert,
silent: silent,
)));
@@ -211,7 +211,7 @@ class QueryClient {
}
Future<void> invalidateQueries<TPageData>({
QueryKey? queryKey,
QueryKey? queryKeys,
InvalidateQueryFilters<TPageData>? filters,
RefetchOptions? options,
}) {
@@ -223,7 +223,7 @@ class QueryClient {
"inactive": filters?.refetchInactive ?? false,
});
return notifyManager.batch(() {
_queryCache.findAll(queryKey, filters).forEach((query) {
_queryCache.findAll(queryKeys, filters).forEach((query) {
query.invalidate();
});
return this.refetchQueries(
@@ -234,12 +234,12 @@ class QueryClient {
}
Future<void> refetchQueries<TPageData>({
QueryKey? queryKey,
QueryKey? queryKeys,
RefetchableQueryFilters<TPageData>? filters,
RefetchOptions? options,
}) {
var futures = notifyManager.batch(
() => _queryCache.findAll(queryKey, filters).map(
() => _queryCache.findAll(queryKeys, filters).map(
(query) => query.fetch(
null,
ObserverFetchOptions(
@@ -6,14 +6,14 @@ abstract class Subscribable<TListener extends Function> {
Subscribable() : listeners = [];
void Function() subscribe([TListener? listener]) {
var callback = listener ?? (() => null);
listener ??= (() => null) as TListener;
listeners.add(callback as TListener);
listeners.add(listener);
onSubscribe();
return () {
listeners = listeners.where((x) => x != callback).toList();
listeners = listeners.where((x) => x != listener).toList();
onUnsubscribe();
};
}
@@ -23,8 +23,8 @@ abstract class Subscribable<TListener extends Function> {
}
@protected
void onSubscribe();
void onSubscribe() {}
@protected
void onUnsubscribe();
void onUnsubscribe() {}
}
+13 -5
View File
@@ -39,12 +39,20 @@ QueryStatusFilter mapQueryStatusFilter(
}
}
bool matchQuery(QueryFilters filters, Query query, [QueryKey? queryKey]) {
if (queryKey != null) {
if (filters.exact! &&
query.queryHash != hashQueryKeyByOptions(queryKey, query.options))
bool matchQuery(
QueryFilters filters,
Query query, [
/// multiple queryKeys to find the query
QueryKey? queryKeys,
]) {
if (queryKeys != null) {
if (filters.exact == true &&
query.queryHash != hashQueryKeyByOptions(queryKeys, query.options))
return false;
else if (query.queryKey.key != queryKey) return false;
else if (query.queryKey.key != queryKeys.key &&
!queryKeys.keyAsList.contains(query.queryKey.key) &&
!query.queryKey.keyAsList.contains(queryKeys.key)) return false;
}
QueryStatusFilter queryStatusFilter =
mapQueryStatusFilter(filters.active, filters.inactive);