utils tests created
TQueryFnData, TData & TQueryData now only can be Maps or subclass of Map
This commit is contained in:
@@ -29,7 +29,8 @@ void main() async {
|
||||
var key = QueryKey("TEST");
|
||||
QueryClient queryClient = QueryClient();
|
||||
queryClient.mount();
|
||||
var data = await queryClient.fetchQuery<Map, dynamic, Map>(
|
||||
var data = await queryClient
|
||||
.fetchQuery<Map<String, dynamic>, dynamic, Map<String, dynamic>>(
|
||||
queryKey: key,
|
||||
queryFn: (context) {
|
||||
return Future.value(todos.first);
|
||||
@@ -39,7 +40,7 @@ void main() async {
|
||||
print(data);
|
||||
print("======CACHED DATA======");
|
||||
print(queryClient.getQueryData(key));
|
||||
queryClient.setQueryData<Map>(key, (prevData) {
|
||||
queryClient.setQueryData<Map<String, dynamic>>(key, (prevData) {
|
||||
return {
|
||||
...(prevData) ?? {},
|
||||
"title": "Yehi aloh heh",
|
||||
|
||||
@@ -9,16 +9,19 @@ typedef QueryKeyHashFunction = String Function(QueryKey queryKey);
|
||||
typedef QueryFunction<T, TPageParam> = FutureOr<T> Function(
|
||||
QueryFunctionContext<TPageParam> context,
|
||||
);
|
||||
typedef GetPreviousPageParamFunction<TQueryFnData> = Function(
|
||||
typedef GetPreviousPageParamFunction<TQueryFnData extends Map<String, dynamic>>
|
||||
= Function(
|
||||
TQueryFnData firstPage,
|
||||
List<TQueryFnData> allPages,
|
||||
);
|
||||
typedef GetNextPageParamFunction<TQueryFnData> = Function(
|
||||
typedef GetNextPageParamFunction<TQueryFnData extends Map<String, dynamic>>
|
||||
= Function(
|
||||
TQueryFnData firstPage,
|
||||
List<TQueryFnData> allPages,
|
||||
);
|
||||
|
||||
class QueryOptions<TQueryFnData, TError, TData> {
|
||||
class QueryOptions<TQueryFnData extends Map<String, dynamic>, TError,
|
||||
TData extends Map<String, dynamic>> {
|
||||
ShouldRetryFunction<TError>? retry;
|
||||
RetryDelayFunction<TError>? retryDelay;
|
||||
Duration? cacheTime;
|
||||
@@ -259,7 +262,7 @@ enum QueryStatus {
|
||||
success,
|
||||
}
|
||||
|
||||
class QueryObserverResult<TData, TError> {
|
||||
class QueryObserverResult<TData extends Map<String, dynamic>, TError> {
|
||||
TData? data;
|
||||
DateTime? dataUpdatedAt;
|
||||
TError? error;
|
||||
@@ -373,7 +376,11 @@ class QueryObserverResult<TData, TError> {
|
||||
}
|
||||
}
|
||||
|
||||
typedef RefetchIntervalFunction<TQueryFnData, TError, TQueryData, TData>
|
||||
typedef RefetchIntervalFunction<
|
||||
TQueryFnData extends Map<String, dynamic>,
|
||||
TError,
|
||||
TQueryData extends Map<String, dynamic>,
|
||||
TData extends Map<String, dynamic>>
|
||||
= Duration? Function(
|
||||
TData? data,
|
||||
Query<TQueryFnData, TError, TQueryData> query,
|
||||
@@ -391,7 +398,11 @@ enum RefetchOnMount {
|
||||
always,
|
||||
}
|
||||
|
||||
class QueryObserverOptions<TQueryFnData, TError, TData, TQueryData>
|
||||
class QueryObserverOptions<
|
||||
TQueryFnData extends Map<String, dynamic>,
|
||||
TError,
|
||||
TData extends Map<String, dynamic>,
|
||||
TQueryData extends Map<String, dynamic>>
|
||||
extends QueryOptions<TQueryFnData, TError, TQueryData> {
|
||||
bool? enabled;
|
||||
Duration? staleTime;
|
||||
@@ -520,7 +531,8 @@ class DefaultOptions<TError> {
|
||||
});
|
||||
}
|
||||
|
||||
class FetchQueryOptions<TQueryFnData, TError, TData>
|
||||
class FetchQueryOptions<TQueryFnData extends Map<String, dynamic>, TError,
|
||||
TData extends Map<String, dynamic>>
|
||||
extends QueryOptions<TQueryFnData, TError, TData> {
|
||||
/// The time after data is considered stale.
|
||||
/// If the data is fresh it will be returned from the cache.
|
||||
|
||||
@@ -17,7 +17,8 @@ class FetchOptions {
|
||||
FetchOptions({this.cancelRefetch, this.meta});
|
||||
}
|
||||
|
||||
class FetchContext<TQueryFnData, TError, TData> {
|
||||
class FetchContext<TQueryFnData extends Map<String, dynamic>, TError,
|
||||
TData extends Map<String, dynamic>> {
|
||||
FutureOr<TQueryFnData> Function() fetchFn;
|
||||
FetchOptions? fetchOptions;
|
||||
QueryOptions<TQueryFnData, TError, TData> options;
|
||||
@@ -35,12 +36,13 @@ class FetchContext<TQueryFnData, TError, TData> {
|
||||
});
|
||||
}
|
||||
|
||||
class QueryBehavior<TQueryFnData, TError, TData> {
|
||||
class QueryBehavior<TQueryFnData extends Map<String, dynamic>, TError,
|
||||
TData extends Map<String, dynamic>> {
|
||||
void Function(FetchContext<TQueryFnData, TError, TData> context) onFetch;
|
||||
QueryBehavior({required this.onFetch});
|
||||
}
|
||||
|
||||
class QueryState<TData, TError> {
|
||||
class QueryState<TData extends Map<String, dynamic>, TError> {
|
||||
TData? data;
|
||||
TError? error;
|
||||
QueryStatus status;
|
||||
@@ -120,7 +122,7 @@ class SetStateOptions {
|
||||
}
|
||||
}
|
||||
|
||||
class Action<TData, TError> {
|
||||
class Action<TData extends Map<String, dynamic>, TError> {
|
||||
ActionType type;
|
||||
Object? meta;
|
||||
TData? data;
|
||||
@@ -160,7 +162,8 @@ class Action<TData, TError> {
|
||||
}
|
||||
}
|
||||
|
||||
class Query<TQueryFnData, TError, TData> {
|
||||
class Query<TQueryFnData extends Map<String, dynamic>, TError,
|
||||
TData extends Map<String, dynamic>> {
|
||||
QueryKey queryKey;
|
||||
String queryHash;
|
||||
late QueryOptions<TQueryFnData, TError, TData> options;
|
||||
@@ -277,7 +280,7 @@ class Query<TQueryFnData, TError, TData> {
|
||||
data = prevData as TData;
|
||||
} else if (this.options.structuralSharing != false) {
|
||||
// Structurally share data between prev and new data if needed
|
||||
data = replaceEqualDeep<TData>(prevData ?? {} as TData, data);
|
||||
data = replaceEqualDeep(prevData ?? {} as TData, data);
|
||||
}
|
||||
// Set data and mark it as cached
|
||||
_dispatch(Action(
|
||||
@@ -360,7 +363,7 @@ class Query<TQueryFnData, TError, TData> {
|
||||
var observer =
|
||||
_observers.firstWhereOrNull((x) => x.options.queryFn != null);
|
||||
if (observer != null) {
|
||||
_setOptions(QueryOptions(
|
||||
_setOptions(QueryOptions<TQueryFnData, TError, TData>(
|
||||
queryKey: observer.options.queryKey,
|
||||
queryKeyHashFn: observer.options.queryKeyHashFn,
|
||||
cacheTime: observer.options.cacheTime,
|
||||
@@ -368,7 +371,7 @@ class Query<TQueryFnData, TError, TData> {
|
||||
queryFn:
|
||||
observer.options.queryFn as QueryFunction<TQueryFnData, dynamic>,
|
||||
queryHash: observer.options.queryHash,
|
||||
initialData: observer.options.initialData,
|
||||
initialData: observer.options.initialData as TData?,
|
||||
initialDataUpdatedAt: observer.options.initialDataUpdatedAt,
|
||||
meta: observer.options.meta,
|
||||
structuralSharing: observer.options.structuralSharing,
|
||||
|
||||
@@ -59,7 +59,10 @@ class QueryCache extends Subscribable<QueryCacheListener> {
|
||||
_queriesMap = {},
|
||||
super();
|
||||
|
||||
Query<TQueryFnData, TError, TData> build<TQueryFnData, TError, TData>(
|
||||
Query<TQueryFnData, TError, TData> build<
|
||||
TQueryFnData extends Map<String, dynamic>,
|
||||
TError,
|
||||
TData extends Map<String, dynamic>>(
|
||||
QueryClient client,
|
||||
QueryOptions<TQueryFnData, TError, TData> options, [
|
||||
QueryState<TData, TError>? state,
|
||||
@@ -124,8 +127,10 @@ class QueryCache extends Subscribable<QueryCacheListener> {
|
||||
});
|
||||
}
|
||||
|
||||
Query<TQueryFnData, TError, TData>? get<TQueryFnData, TError, TData>(
|
||||
String queryHash) {
|
||||
Query<TQueryFnData, TError, TData>? get<
|
||||
TQueryFnData extends Map<String, dynamic>,
|
||||
TError,
|
||||
TData extends Map<String, dynamic>>(String queryHash) {
|
||||
return _queriesMap[queryHash] as Query<TQueryFnData, TError, TData>?;
|
||||
}
|
||||
|
||||
@@ -133,13 +138,16 @@ class QueryCache extends Subscribable<QueryCacheListener> {
|
||||
return _queries;
|
||||
}
|
||||
|
||||
Query? find<TQueryFnData, TError, TData>(
|
||||
Query<TQueryFnData, TError, TData>? find<
|
||||
TQueryFnData extends Map<String, dynamic>,
|
||||
TError,
|
||||
TData extends Map<String, dynamic>>(
|
||||
QueryKey queryKey,
|
||||
QueryFilters queryFilters,
|
||||
) {
|
||||
queryFilters.exact ??= true;
|
||||
return _queries
|
||||
.firstWhereOrNull((query) => matchQuery(queryFilters, query));
|
||||
return _queries.firstWhereOrNull((query) => matchQuery(queryFilters, query))
|
||||
as Query<TQueryFnData, TError, TData>?;
|
||||
}
|
||||
|
||||
List<Query> findAll(QueryKey? queryKey, [QueryFilters? filters]) {
|
||||
|
||||
@@ -26,7 +26,7 @@ class MutationDefaults {
|
||||
// });
|
||||
}
|
||||
|
||||
class QueryData<TData> {
|
||||
class QueryData<TData extends Map<String, dynamic>> {
|
||||
QueryKey queryKey;
|
||||
TData data;
|
||||
QueryData({
|
||||
@@ -85,17 +85,18 @@ class QueryClient {
|
||||
// return _mutationCache.findAll({ ...filters, fetching: true }).length
|
||||
// }
|
||||
|
||||
TData? getQueryData<TData>(
|
||||
TData? getQueryData<TData extends Map<String, dynamic>>(
|
||||
QueryKey queryKey, [
|
||||
QueryFilters? filters,
|
||||
]) {
|
||||
return _queryCache
|
||||
.find<TData, dynamic, dynamic>(queryKey, filters ?? QueryFilters())
|
||||
.find<TData, dynamic, Map<String, dynamic>>(
|
||||
queryKey, filters ?? QueryFilters())
|
||||
?.state
|
||||
.data;
|
||||
.data as TData?;
|
||||
}
|
||||
|
||||
List<QueryData<TData>> getQueriesData<TData>({
|
||||
List<QueryData<TData>> getQueriesData<TData extends Map<String, dynamic>>({
|
||||
QueryKey? queryKey,
|
||||
QueryFilters? filters,
|
||||
}) {
|
||||
@@ -107,26 +108,27 @@ class QueryClient {
|
||||
}).toList();
|
||||
}
|
||||
|
||||
TData setQueryData<TData>(
|
||||
TData setQueryData<TData extends Map<String, dynamic>>(
|
||||
QueryKey queryKey,
|
||||
DataUpdateFunction<TData?, TData> updater, [
|
||||
DateTime? updatedAt,
|
||||
]) {
|
||||
final QueryOptions<dynamic, dynamic, TData> defaultedOptions =
|
||||
QueryOptions<dynamic, dynamic, TData>.fromJson(
|
||||
defaultQueryOptions<dynamic, dynamic, TData, dynamic>(
|
||||
QueryObserverOptions<dynamic, dynamic, TData, dynamic>(
|
||||
queryKey: queryKey))
|
||||
final QueryOptions<Map<String, dynamic>, dynamic, TData> defaultedOptions =
|
||||
QueryOptions<Map<String, dynamic>, dynamic, TData>.fromJson(
|
||||
defaultQueryOptions<Map<String, dynamic>, dynamic, TData,
|
||||
Map<String, dynamic>>(
|
||||
QueryObserverOptions<Map<String, dynamic>, dynamic, TData,
|
||||
Map<String, dynamic>>(queryKey: queryKey))
|
||||
.toJson());
|
||||
return _queryCache
|
||||
.build<dynamic, dynamic, TData>(this, defaultedOptions)
|
||||
.build<Map<String, dynamic>, dynamic, TData>(this, defaultedOptions)
|
||||
.setData(
|
||||
updater,
|
||||
updatedAt: updatedAt,
|
||||
);
|
||||
}
|
||||
|
||||
List<QueryData> setQueriesData<TData>({
|
||||
List<QueryData> setQueriesData<TData extends Map<String, dynamic>>({
|
||||
required DataUpdateFunction<TData?, TData> updater,
|
||||
QueryKey? queryKey,
|
||||
QueryFilters? filters,
|
||||
@@ -149,12 +151,13 @@ class QueryClient {
|
||||
.toList();
|
||||
}
|
||||
|
||||
QueryState<TData, TError>? getQueryState<TData, TError>(
|
||||
QueryState<TData, TError>?
|
||||
getQueryState<TData extends Map<String, dynamic>, TError>(
|
||||
QueryKey queryKey, [
|
||||
QueryFilters? filters,
|
||||
]) {
|
||||
return _queryCache
|
||||
.find<TData, TError, dynamic>(
|
||||
.find<TData, TError, Map<String, dynamic>>(
|
||||
queryKey,
|
||||
filters ?? QueryFilters(),
|
||||
)
|
||||
@@ -257,13 +260,15 @@ class QueryClient {
|
||||
return future;
|
||||
}
|
||||
|
||||
Future<TData> fetchQuery<TQueryFnData, TError, TData>({
|
||||
Future<TData> fetchQuery<TQueryFnData extends Map<String, dynamic>, TError,
|
||||
TData extends Map<String, dynamic>>({
|
||||
QueryKey? queryKey,
|
||||
QueryFunction<TQueryFnData, dynamic>? queryFn,
|
||||
FetchQueryOptions<TQueryFnData, TError, TData>? options,
|
||||
}) {
|
||||
var defaultedOptions = this.defaultQueryOptions(
|
||||
QueryObserverOptions(
|
||||
QueryObserverOptions<Map<String, dynamic>, dynamic, Map<String, dynamic>,
|
||||
TData>(
|
||||
queryFn: queryFn,
|
||||
queryKey: queryKey,
|
||||
staleTime: options?.staleTime,
|
||||
@@ -280,28 +285,33 @@ class QueryClient {
|
||||
);
|
||||
// returning 0 indicates turing off retry
|
||||
defaultedOptions.retry ??= (_, __) => 0;
|
||||
var query = _queryCache.build(this, defaultedOptions);
|
||||
var query = _queryCache.build<Map<String, dynamic>, dynamic, TData>(
|
||||
this, defaultedOptions);
|
||||
return query.isStaleByTime(defaultedOptions.staleTime)
|
||||
? query.fetch(defaultedOptions)
|
||||
: Future.value(query.state.data as TData);
|
||||
}
|
||||
|
||||
Future<void> prefetchQuery<TQueryFnData, TError, TData>({
|
||||
Future<void> prefetchQuery<TQueryFnData extends Map<String, dynamic>, TError,
|
||||
TData extends Map<String, dynamic>>({
|
||||
QueryKey? queryKey,
|
||||
QueryFunction<TQueryFnData, dynamic>? queryFn,
|
||||
FetchQueryOptions<TQueryFnData, TError, TData>? options,
|
||||
}) {
|
||||
return fetchQuery(
|
||||
return fetchQuery<TQueryFnData, dynamic, TData>(
|
||||
queryKey: queryKey,
|
||||
queryFn: queryFn,
|
||||
options: options,
|
||||
).then(noop).catchError(noop);
|
||||
}
|
||||
|
||||
QueryObserverOptions<TQueryFnData, TError, TData, TQueryData>
|
||||
defaultQueryOptions<TQueryFnData, TError, TData, TQueryData>(
|
||||
QueryObserverOptions<TQueryFnData, TError, TData, TQueryData>?
|
||||
options) {
|
||||
QueryObserverOptions<TQueryFnData, TError, TData,
|
||||
TQueryData> defaultQueryOptions<
|
||||
TQueryFnData extends Map<String, dynamic>,
|
||||
TError,
|
||||
TData extends Map<String, dynamic>,
|
||||
TQueryData extends Map<String, dynamic>>(
|
||||
QueryObserverOptions<TQueryFnData, TError, TData, TQueryData>? options) {
|
||||
if (options?.defaulted == true) return options!;
|
||||
var defaultedOptions =
|
||||
QueryObserverOptions<TQueryFnData, TError, TData, TQueryData>.fromJson({
|
||||
@@ -322,7 +332,11 @@ class QueryClient {
|
||||
}
|
||||
|
||||
QueryObserverOptions<TQueryFnData, TError, TData, TQueryData>
|
||||
defaultQueryObserverOptions<TQueryFnData, TError, TData, TQueryData>([
|
||||
defaultQueryObserverOptions<
|
||||
TQueryFnData extends Map<String, dynamic>,
|
||||
TError,
|
||||
TData extends Map<String, dynamic>,
|
||||
TQueryData extends Map<String, dynamic>>([
|
||||
QueryObserverOptions<TQueryFnData, TError, TData, TQueryData>? options,
|
||||
]) {
|
||||
return this.defaultQueryOptions(options);
|
||||
|
||||
@@ -15,8 +15,8 @@ import 'package:fl_query/src/core/subscribable.dart';
|
||||
import 'package:fl_query/src/core/utils.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
typedef QueryObserverListener<TData, TError> = void Function(
|
||||
QueryObserverResult<TData, TError> result);
|
||||
typedef QueryObserverListener<TData extends Map<String, dynamic>, TError> = void
|
||||
Function(QueryObserverResult<TData, TError> result);
|
||||
|
||||
class NotifyOptions {
|
||||
bool? cache;
|
||||
@@ -52,13 +52,18 @@ class ObserverFetchOptions extends FetchOptions {
|
||||
}) : super(cancelRefetch: cancelRefetch, meta: meta);
|
||||
}
|
||||
|
||||
class SelectQuery<TQueryData, TData> {
|
||||
class SelectQuery<TQueryData extends Map<String, dynamic>,
|
||||
TData extends Map<String, dynamic>> {
|
||||
TData Function(TQueryData data) fn;
|
||||
TData result;
|
||||
SelectQuery(this.fn, this.result);
|
||||
}
|
||||
|
||||
class QueryObserver<TQueryFnData, TError, TData, TQueryData>
|
||||
class QueryObserver<
|
||||
TQueryFnData extends Map<String, dynamic>,
|
||||
TError,
|
||||
TData extends Map<String, dynamic>,
|
||||
TQueryData extends Map<String, dynamic>>
|
||||
extends Subscribable<QueryObserverListener> {
|
||||
late QueryObserverOptions<TQueryFnData, TError, TData, TQueryData> options;
|
||||
QueryClient _client;
|
||||
@@ -70,7 +75,7 @@ class QueryObserver<TQueryFnData, TError, TData, TQueryData>
|
||||
_currentResultOptions;
|
||||
QueryObserverResult<TData, TError>? _previousQueryResult;
|
||||
Exception? _previousSelectError;
|
||||
SelectQuery? _previousSelect;
|
||||
SelectQuery<TQueryData, TData>? _previousSelect;
|
||||
Timer? _staleTimeout;
|
||||
Timer? _refetchInterval;
|
||||
Duration? _currentRefetchInterval;
|
||||
@@ -119,8 +124,8 @@ class QueryObserver<TQueryFnData, TError, TData, TQueryData>
|
||||
QueryObserverOptions<TQueryFnData, TError, TData, TQueryData>? options, [
|
||||
NotifyOptions? notifyOptions,
|
||||
]) {
|
||||
var prevOptions = this.options;
|
||||
var prevQuery = _currentQuery;
|
||||
final prevOptions = this.options;
|
||||
final prevQuery = _currentQuery;
|
||||
|
||||
this.options = this._client.defaultQueryObserverOptions(options);
|
||||
|
||||
@@ -190,7 +195,7 @@ class QueryObserver<TQueryFnData, TError, TData, TQueryData>
|
||||
Future<QueryObserverResult<TData, TError>> getNextResult(
|
||||
bool? throwOnError,
|
||||
) {
|
||||
var completer = Completer<QueryObserverResult<TData, TError>>();
|
||||
final completer = Completer<QueryObserverResult<TData, TError>>();
|
||||
var unsubscribe;
|
||||
unsubscribe = subscribe((result) {
|
||||
if (!result.isFetching) {
|
||||
@@ -215,8 +220,8 @@ class QueryObserver<TQueryFnData, TError, TData, TQueryData>
|
||||
|
||||
Future<QueryObserverResult<TData, TError>> fetchOptimistic(
|
||||
QueryObserverOptions<TQueryFnData, TError, TData, TQueryData> options) {
|
||||
var defaultedOptions = _client.defaultQueryObserverOptions(options);
|
||||
var query = _client.getQueryCache().build(_client, defaultedOptions);
|
||||
final defaultedOptions = _client.defaultQueryObserverOptions(options);
|
||||
final query = _client.getQueryCache().build(_client, defaultedOptions);
|
||||
|
||||
return query.fetch().then((val) {
|
||||
return createResult(query, defaultedOptions);
|
||||
@@ -269,7 +274,7 @@ class QueryObserver<TQueryFnData, TError, TData, TQueryData>
|
||||
Map<String, dynamic> prevResultMap = prevResult.toJson();
|
||||
|
||||
return resultMap.keys.any((key) {
|
||||
var changed = resultMap[key] != prevResultMap[key];
|
||||
final changed = resultMap[key] != prevResultMap[key];
|
||||
bool? isIncluded = includedProps?.any((x) => x == key);
|
||||
bool isExcluded =
|
||||
options.notifyOnChangePropsExclusions?.any((x) => x == key) ?? false;
|
||||
@@ -280,7 +285,7 @@ class QueryObserver<TQueryFnData, TError, TData, TQueryData>
|
||||
}
|
||||
|
||||
void updateResult([NotifyOptions? notifyOptions]) {
|
||||
QueryObserverResult<TData, TError>? prevResult = _currentResult;
|
||||
final QueryObserverResult<TData, TError>? prevResult = _currentResult;
|
||||
|
||||
if (_currentQuery != null)
|
||||
_currentResult = this.createResult(_currentQuery!, this.options);
|
||||
@@ -288,7 +293,7 @@ class QueryObserver<TQueryFnData, TError, TData, TQueryData>
|
||||
_currentResultOptions = this.options;
|
||||
|
||||
// Only notify if something has changed
|
||||
if (shallowEqualMap(_currentResult.toJson(), prevResult.toJson())) {
|
||||
if (shallowEqualMap(_currentResult.toJson(), prevResult?.toJson())) {
|
||||
return;
|
||||
}
|
||||
NotifyOptions defaultNotifyOptions = NotifyOptions(cache: true);
|
||||
@@ -304,11 +309,12 @@ class QueryObserver<TQueryFnData, TError, TData, TQueryData>
|
||||
}
|
||||
|
||||
void _updateQuery() {
|
||||
var query = this._client.getQueryCache().build(this._client, this.options);
|
||||
final query =
|
||||
this._client.getQueryCache().build(this._client, this.options);
|
||||
|
||||
if (query == _currentQuery) return;
|
||||
|
||||
var prevQuery = _currentQuery;
|
||||
final prevQuery = _currentQuery;
|
||||
_currentQuery = query;
|
||||
_currentQueryInitialState = query.state;
|
||||
_previousQueryResult = _currentResult;
|
||||
@@ -339,22 +345,22 @@ class QueryObserver<TQueryFnData, TError, TData, TQueryData>
|
||||
Query<TQueryFnData, TError, TQueryData> query,
|
||||
QueryObserverOptions<TQueryFnData, TError, TData, TQueryData> options,
|
||||
) {
|
||||
var prevQuery = _currentQuery;
|
||||
var prevOptions = this.options;
|
||||
var prevResult = _currentResult;
|
||||
var prevResultState = _currentResultState;
|
||||
var prevResultOptions = _currentResultOptions;
|
||||
bool queryChange = query != prevQuery;
|
||||
var queryInitialState =
|
||||
final prevQuery = _currentQuery;
|
||||
final prevOptions = this.options;
|
||||
final prevResult = _currentResult;
|
||||
final prevResultState = _currentResultState;
|
||||
final prevResultOptions = _currentResultOptions;
|
||||
final bool queryChange = query != prevQuery;
|
||||
final queryInitialState =
|
||||
queryChange ? query.state : _currentQueryInitialState;
|
||||
var prevQueryResult = queryChange ? _currentResult : _previousQueryResult;
|
||||
final prevQueryResult = queryChange ? _currentResult : _previousQueryResult;
|
||||
|
||||
var state = query.state;
|
||||
var dataUpdatedAt = state.dataUpdatedAt;
|
||||
var error = state.error;
|
||||
var errorUpdatedAt = state.errorUpdatedAt;
|
||||
var isFetching = state.isFetching;
|
||||
var status = state.status;
|
||||
final state = query.state;
|
||||
DateTime? dataUpdatedAt = state.dataUpdatedAt;
|
||||
TError? error = state.error;
|
||||
DateTime? errorUpdatedAt = state.errorUpdatedAt;
|
||||
bool isFetching = state.isFetching;
|
||||
QueryStatus status = state.status;
|
||||
|
||||
bool isPreviousData = false;
|
||||
bool isPlaceholderData = false;
|
||||
@@ -362,9 +368,9 @@ class QueryObserver<TQueryFnData, TError, TData, TQueryData>
|
||||
|
||||
// Optimistically set result in fetching state if needed
|
||||
if (options.optimisticResults == true) {
|
||||
var mounted = hasListeners();
|
||||
final bool mounted = hasListeners();
|
||||
|
||||
var fetchOnMount = !mounted && shouldFetchOnMount(query, options);
|
||||
final bool fetchOnMount = !mounted && shouldFetchOnMount(query, options);
|
||||
|
||||
bool fetchOptionally = mounted &&
|
||||
prevQuery != null &&
|
||||
@@ -401,7 +407,7 @@ class QueryObserver<TQueryFnData, TError, TData, TQueryData>
|
||||
try {
|
||||
data = options.select?.call(state.data);
|
||||
if (options.structuralSharing != false) {
|
||||
data = replaceEqualDeep(prevResult?.data, data);
|
||||
data = replaceEqualDeep(prevResult.data, data);
|
||||
}
|
||||
if (options.select != null && data != null) {
|
||||
_previousSelect = SelectQuery<TQueryData, TData>(
|
||||
@@ -429,7 +435,7 @@ class QueryObserver<TQueryFnData, TError, TData, TQueryData>
|
||||
(status == QueryStatus.loading || status == QueryStatus.idle)) {
|
||||
var placeholderData;
|
||||
|
||||
if (prevResult?.isPlaceholderData == true &&
|
||||
if (prevResult.isPlaceholderData == true &&
|
||||
options.placeholderData == prevResultOptions?.placeholderData) {
|
||||
placeholderData = prevResult.data;
|
||||
} else {
|
||||
@@ -439,7 +445,7 @@ class QueryObserver<TQueryFnData, TError, TData, TQueryData>
|
||||
placeholderData = options.select?.call(placeholderData);
|
||||
if (options.structuralSharing != false) {
|
||||
placeholderData =
|
||||
replaceEqualDeep(prevResult?.data, placeholderData);
|
||||
replaceEqualDeep(prevResult.data, placeholderData);
|
||||
}
|
||||
_previousSelectError = null;
|
||||
} catch (selectError) {
|
||||
@@ -459,7 +465,8 @@ class QueryObserver<TQueryFnData, TError, TData, TQueryData>
|
||||
}
|
||||
}
|
||||
|
||||
QueryObserverResult<TData, TError> result = QueryObserverResult(
|
||||
final QueryObserverResult<TData, TError> result =
|
||||
QueryObserverResult<TData, TError>(
|
||||
status: status,
|
||||
dataUpdatedAt: dataUpdatedAt,
|
||||
isLoading: status == QueryStatus.loading,
|
||||
@@ -602,7 +609,11 @@ class QueryObserver<TQueryFnData, TError, TData, TQueryData>
|
||||
}
|
||||
}
|
||||
|
||||
bool shouldLoadOnMount<TQueryFnData, TError, TData, TQueryData>(
|
||||
bool shouldLoadOnMount<
|
||||
TQueryFnData extends Map<String, dynamic>,
|
||||
TError,
|
||||
TData extends Map<String, dynamic>,
|
||||
TQueryData extends Map<String, dynamic>>(
|
||||
Query<TQueryFnData, TError, TQueryData> query,
|
||||
QueryObserverOptions<TQueryFnData, TError, TData, TQueryData> options,
|
||||
) {
|
||||
@@ -612,7 +623,11 @@ bool shouldLoadOnMount<TQueryFnData, TError, TData, TQueryData>(
|
||||
options.retryOnMount == false));
|
||||
}
|
||||
|
||||
bool shouldRefetchOnMount<TQueryFnData, TError, TData, TQueryData>(
|
||||
bool shouldRefetchOnMount<
|
||||
TQueryFnData extends Map<String, dynamic>,
|
||||
TError,
|
||||
TData extends Map<String, dynamic>,
|
||||
TQueryData extends Map<String, dynamic>>(
|
||||
Query<TQueryFnData, TError, TQueryData> query,
|
||||
QueryObserverOptions<TQueryFnData, TError, TData, TQueryData> options,
|
||||
) {
|
||||
@@ -623,7 +638,11 @@ bool shouldRefetchOnMount<TQueryFnData, TError, TData, TQueryData>(
|
||||
isStale(query, options))));
|
||||
}
|
||||
|
||||
bool shouldFetchOnMount<TQueryFnData, TError, TData, TQueryData>(
|
||||
bool shouldFetchOnMount<
|
||||
TQueryFnData extends Map<String, dynamic>,
|
||||
TError,
|
||||
TData extends Map<String, dynamic>,
|
||||
TQueryData extends Map<String, dynamic>>(
|
||||
Query<TQueryFnData, TError, TQueryData> query,
|
||||
QueryObserverOptions<TQueryFnData, TError, TData, TQueryData> options,
|
||||
) {
|
||||
@@ -631,17 +650,26 @@ bool shouldFetchOnMount<TQueryFnData, TError, TData, TQueryData>(
|
||||
shouldRefetchOnMount(query, options));
|
||||
}
|
||||
|
||||
bool shouldFetchOnReconnect<TQueryFnData, TError, TData, TQueryData>(
|
||||
bool shouldFetchOnReconnect<
|
||||
TQueryFnData extends Map<String, dynamic>,
|
||||
TError,
|
||||
TData extends Map<String, dynamic>,
|
||||
TQueryData extends Map<String, dynamic>>(
|
||||
Query<TQueryFnData, TError, TQueryData> query,
|
||||
QueryObserverOptions<TQueryFnData, TError, TData, TQueryData> options,
|
||||
) {
|
||||
return (options.enabled != false &&
|
||||
(options.refetchOnReconnect == RefetchOnReconnect.always ||
|
||||
(options.refetchOnReconnect != RefetchOnReconnect.off &&
|
||||
isStale(query, options))));
|
||||
isStale<TQueryFnData, TError, TData, TQueryData>(
|
||||
query, options))));
|
||||
}
|
||||
|
||||
bool shouldFetchOptionally<TQueryFnData, TError, TData, TQueryData>(
|
||||
bool shouldFetchOptionally<
|
||||
TQueryFnData extends Map<String, dynamic>,
|
||||
TError,
|
||||
TData extends Map<String, dynamic>,
|
||||
TQueryData extends Map<String, dynamic>>(
|
||||
Query<TQueryFnData, TError, TQueryData> query,
|
||||
Query<TQueryFnData, TError, TQueryData> prevQuery,
|
||||
QueryObserverOptions<TQueryFnData, TError, TData, TQueryData> options,
|
||||
@@ -653,7 +681,11 @@ bool shouldFetchOptionally<TQueryFnData, TError, TData, TQueryData>(
|
||||
isStale(query, options));
|
||||
}
|
||||
|
||||
bool isStale<TQueryFnData, TError, TData, TQueryData>(
|
||||
bool isStale<
|
||||
TQueryFnData extends Map<String, dynamic>,
|
||||
TError,
|
||||
TData extends Map<String, dynamic>,
|
||||
TQueryData extends Map<String, dynamic>>(
|
||||
Query<TQueryFnData, TError, TQueryData> query,
|
||||
QueryObserverOptions<TQueryFnData, TError, TData, TQueryData> options,
|
||||
) {
|
||||
|
||||
@@ -36,9 +36,9 @@ bool isCancelledError(value) {
|
||||
}
|
||||
|
||||
typedef OnError<TError> = void Function(TError error);
|
||||
typedef OnData<TData> = void Function(TData data);
|
||||
typedef OnData<TData extends Map<String, dynamic>> = void Function(TData data);
|
||||
|
||||
class Retryer<TData, TError> {
|
||||
class Retryer<TData extends Map<String, dynamic>, TError> {
|
||||
late void Function({bool? revert, bool? silent}) cancel;
|
||||
late void Function() cancelRetry;
|
||||
late void Function() continueRetry;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
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';
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
/// Default query keys hash function.
|
||||
/// Dummy function just to fill the gaps for original react-query like
|
||||
@@ -95,41 +96,61 @@ bool shallowEqualMap(Map? a, Map? b) {
|
||||
/// If not, it will replace any deeply equal children of `b` with those
|
||||
/// of `a`\
|
||||
/// This can be used for structural sharing between JSON values for example.
|
||||
/// `a` & `b` can only be Type of [Iterable] or [Map]
|
||||
T replaceEqualDeep<T>(T a, T b) {
|
||||
/// `a` & `b` can only be Type of [List] or [Map]
|
||||
replaceEqualDeep(a, b) {
|
||||
if (a == b) {
|
||||
return a;
|
||||
}
|
||||
|
||||
bool isList = (a is Iterable && b is Iterable);
|
||||
if (isList || (a is Map && b is Map)) {
|
||||
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[i];
|
||||
if (isList) {
|
||||
copy ??= [];
|
||||
copy[key] = replaceEqualDeep((a as List)[key], (b as List)[key]);
|
||||
if (copy[key] == a[key]) {
|
||||
equalItems++;
|
||||
}
|
||||
} else {
|
||||
copy ??= {};
|
||||
copy[key] = replaceEqualDeep((a as Map)[key], (b as Map)[key]);
|
||||
if (copy[key] == a[key]) {
|
||||
equalItems++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return aSize == bSize && equalItems == aSize ? a : copy as T;
|
||||
int aSize;
|
||||
List bItems;
|
||||
int bSize;
|
||||
int equalItems = 0;
|
||||
onEqual() => equalItems++;
|
||||
var copy;
|
||||
if (a is List && b is List) {
|
||||
aSize = a.length;
|
||||
bItems = b;
|
||||
bSize = bItems.length;
|
||||
copy = replaceEqualDeepList(a, b, onEqual);
|
||||
} else if (a is Map && b is Map) {
|
||||
aSize = a.keys.length;
|
||||
bItems = b.keys.toList();
|
||||
bSize = bItems.length;
|
||||
copy = replaceEqualDeepMap(a, b, onEqual);
|
||||
} else {
|
||||
return b;
|
||||
}
|
||||
return b;
|
||||
return aSize == bSize && equalItems == aSize ? a : copy;
|
||||
}
|
||||
|
||||
Map replaceEqualDeepMap(Map a, Map b, void Function() onEqual) {
|
||||
final copy = Map.from(a);
|
||||
copy.clear();
|
||||
for (final bEntry in b.entries) {
|
||||
final aItem = a[bEntry.key];
|
||||
copy[bEntry.key] =
|
||||
aItem != null ? replaceEqualDeep(aItem, bEntry.value) : bEntry.value;
|
||||
if (copy[bEntry.key] == aItem) {
|
||||
onEqual();
|
||||
}
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
List replaceEqualDeepList(List a, List b, void Function() onEqual) {
|
||||
final copy = List.of(a, growable: true);
|
||||
copy.clear();
|
||||
for (final bEntry in b.asMap().entries) {
|
||||
final aItem = a.firstWhereIndexedOrNull((i, _) => i == bEntry.key);
|
||||
final result =
|
||||
aItem != null ? replaceEqualDeep(aItem, bEntry.value) : bEntry.value;
|
||||
copy.add(result);
|
||||
if (copy.last == aItem) {
|
||||
onEqual();
|
||||
}
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
Duration timeUntilStale(DateTime updatedAt, [Duration? staleTime]) =>
|
||||
|
||||
@@ -0,0 +1,320 @@
|
||||
import 'package:fl_query/src/core/utils.dart';
|
||||
import 'package:test/expect.dart';
|
||||
import 'package:test/scaffolding.dart';
|
||||
|
||||
void main() {
|
||||
group('core/utils', () {
|
||||
group('replaceEqualDeep', () {
|
||||
test(
|
||||
'Should return the previous value When the next value is an equal primitive',
|
||||
() {
|
||||
expect(replaceEqualDeep(1, 1), equals(1));
|
||||
expect(replaceEqualDeep('1', '1'), equals('1'));
|
||||
expect(replaceEqualDeep(true, true), true);
|
||||
expect(replaceEqualDeep(false, false), false);
|
||||
expect(replaceEqualDeep(null, null), null);
|
||||
});
|
||||
test(
|
||||
'Should return the next value When the previous value is a different value',
|
||||
() {
|
||||
expect(replaceEqualDeep(1, 0), equals(0));
|
||||
expect(replaceEqualDeep(1, 2), equals(2));
|
||||
expect(replaceEqualDeep('1', '2'), equals('2'));
|
||||
expect(replaceEqualDeep(true, false), equals(false));
|
||||
expect(replaceEqualDeep(false, true), equals(true));
|
||||
});
|
||||
|
||||
test(
|
||||
'Should return the next value When the previous value is a different type',
|
||||
() {
|
||||
final array = [1];
|
||||
final object = {"a": "a"};
|
||||
expect(replaceEqualDeep(0, null), equals(null));
|
||||
expect(replaceEqualDeep(null, 0), equals(0));
|
||||
expect(replaceEqualDeep(2, null), equals(null));
|
||||
expect(replaceEqualDeep(null, 2), equals(2));
|
||||
expect(replaceEqualDeep({}, null), equals(null));
|
||||
expect(replaceEqualDeep([], null), equals(null));
|
||||
expect(replaceEqualDeep(array, object), equals(object));
|
||||
expect(replaceEqualDeep(object, array), equals(array));
|
||||
});
|
||||
|
||||
test(
|
||||
'Should return the previous value When the next value is an equal array',
|
||||
() {
|
||||
final prev = [1, 2];
|
||||
final next = [1, 2];
|
||||
expect(replaceEqualDeep(prev, next), equals(prev));
|
||||
});
|
||||
|
||||
test(
|
||||
'Should return a copy When the previous value is a different array subset',
|
||||
() {
|
||||
final prev = [1, 2];
|
||||
final next = [1, 2, 3];
|
||||
final result = replaceEqualDeep(prev, next);
|
||||
expect(result, equals(next));
|
||||
expect(result, isNot(equals(prev)));
|
||||
});
|
||||
|
||||
test(
|
||||
'Should return the previous value When the next value is an equal empty array',
|
||||
() {
|
||||
final prev = [];
|
||||
final next = [];
|
||||
expect(replaceEqualDeep(prev, next), equals(prev));
|
||||
});
|
||||
|
||||
test(
|
||||
'Should return the previous value When the next value is an equal empty object',
|
||||
() {
|
||||
final prev = {};
|
||||
final next = {};
|
||||
expect(replaceEqualDeep(prev, next), equals(prev));
|
||||
});
|
||||
|
||||
test(
|
||||
'Should return the previous value When the next value is an equal object',
|
||||
() {
|
||||
final prev = {"a": 'a'};
|
||||
final next = {"a": 'a'};
|
||||
expect(replaceEqualDeep(prev, next), equals(prev));
|
||||
});
|
||||
|
||||
test('Should replace different values in objects', () {
|
||||
final prev = {
|
||||
"a": {"b": 'b'},
|
||||
"c": 'c'
|
||||
};
|
||||
final next = {
|
||||
"a": {"b": 'b'},
|
||||
"c": 'd'
|
||||
};
|
||||
final result = replaceEqualDeep(prev, next);
|
||||
expect(result, equals(next));
|
||||
expect(result, isNot(prev));
|
||||
expect(result["a"], equals(prev["a"]));
|
||||
expect(result["c"], equals(next["c"]));
|
||||
});
|
||||
|
||||
test('Should replace different values in arrays', () {
|
||||
final prev = [
|
||||
1,
|
||||
{"a": 'a'},
|
||||
{
|
||||
"b": {"b": 'b'}
|
||||
},
|
||||
[1]
|
||||
];
|
||||
final next = [
|
||||
1,
|
||||
{"a": 'a'},
|
||||
{
|
||||
"b": {"b": 'c'}
|
||||
},
|
||||
[1]
|
||||
];
|
||||
final result = replaceEqualDeep(prev, next);
|
||||
expect(result, equals(next));
|
||||
expect(result, isNot(prev));
|
||||
expect(result[0], prev[0]);
|
||||
expect(result[1], prev[1]);
|
||||
expect((result[2] as Map)["b"]["b"], (next[2] as Map)["b"]["b"]);
|
||||
expect(result[3], prev[3]);
|
||||
});
|
||||
|
||||
test(
|
||||
'Should replace different values in arrays When the next value is a subset',
|
||||
() {
|
||||
final prev = [
|
||||
{"a": 'a'},
|
||||
{"b": 'b'},
|
||||
{"c": 'c'}
|
||||
];
|
||||
final next = [
|
||||
{"a": 'a'},
|
||||
{"b": 'b'}
|
||||
];
|
||||
final result = replaceEqualDeep(prev, next);
|
||||
expect(result, equals(next));
|
||||
expect(result, isNot(prev));
|
||||
expect(result[0], prev[0]);
|
||||
expect(result[1], prev[1]);
|
||||
expect(() => result[2], throwsRangeError);
|
||||
});
|
||||
|
||||
test(
|
||||
'Should replace different values in arrays When the next value is a superset',
|
||||
() {
|
||||
final prev = [
|
||||
{"a": 'a'},
|
||||
{"b": 'b'}
|
||||
];
|
||||
final next = [
|
||||
{"a": 'a'},
|
||||
{"b": 'b'},
|
||||
{"c": 'c'}
|
||||
];
|
||||
final result = replaceEqualDeep(prev, next);
|
||||
expect(result, equals(next));
|
||||
expect(result[0], equals(prev[0]));
|
||||
expect(result[1], equals(prev[1]));
|
||||
expect(result[2], equals(next[2]));
|
||||
});
|
||||
|
||||
test('Should copy objects which are not arrays or objects', () {
|
||||
final prev = [
|
||||
{"a": 'a'},
|
||||
{"b": 'b'},
|
||||
{"c": 'c'},
|
||||
1
|
||||
];
|
||||
final next = [
|
||||
{"a": 'a'},
|
||||
Map(),
|
||||
{"c": 'c'},
|
||||
2
|
||||
];
|
||||
final result = replaceEqualDeep(prev, next);
|
||||
expect(result[0], equals(prev[0]));
|
||||
expect(result[1], equals(next[1]));
|
||||
expect(result[2], equals(prev[2]));
|
||||
expect(result[3], equals(next[3]));
|
||||
});
|
||||
|
||||
test('Should support equal objects which are not arrays or objects', () {
|
||||
final map = new Map();
|
||||
final prev = [
|
||||
map,
|
||||
[1]
|
||||
];
|
||||
final next = [
|
||||
map,
|
||||
[1]
|
||||
];
|
||||
final result = replaceEqualDeep(prev, next);
|
||||
expect(result, equals(prev));
|
||||
});
|
||||
|
||||
test('Should support non equal objects which are not arrays or objects',
|
||||
() {
|
||||
final map1 = new Map();
|
||||
final map2 = new Map();
|
||||
final prev = [
|
||||
map1,
|
||||
[1]
|
||||
];
|
||||
final next = [
|
||||
map2,
|
||||
[1]
|
||||
];
|
||||
final result = replaceEqualDeep(prev, next);
|
||||
expect(result[0], equals(next[0]));
|
||||
expect(result[1], equals(prev[1]));
|
||||
});
|
||||
|
||||
test('Should replace all parent objects if some nested value changes',
|
||||
() {
|
||||
final prev = {
|
||||
"todo": {
|
||||
"id": '1',
|
||||
"meta": {"createdAt": 0},
|
||||
"state": {"done": false},
|
||||
},
|
||||
"otherTodo": {
|
||||
"id": '2',
|
||||
"meta": {"createdAt": 0},
|
||||
"state": {"done": true},
|
||||
},
|
||||
};
|
||||
final next = {
|
||||
"todo": {
|
||||
"id": '1',
|
||||
"meta": {"createdAt": 0},
|
||||
"state": {"done": true},
|
||||
},
|
||||
"otherTodo": {
|
||||
"id": '2',
|
||||
"meta": {"createdAt": 0},
|
||||
"state": {"done": true},
|
||||
},
|
||||
};
|
||||
final result = replaceEqualDeep(prev, next);
|
||||
expect(result, equals(next));
|
||||
expect(result["todo"] == prev["todo"], isFalse);
|
||||
expect(result["todo"] == next["todo"], isFalse);
|
||||
expect(result["todo"]["id"], equals((next["todo"] as Map)["id"]));
|
||||
expect(result["todo"]["meta"], equals((prev["todo"] as Map)["meta"]));
|
||||
expect(
|
||||
result["todo"]["state"],
|
||||
equals((next["todo"] as Map)["state"]),
|
||||
);
|
||||
expect(
|
||||
result["todo"]["state"]["done"],
|
||||
(next["todo"] as Map)["state"]["done"],
|
||||
);
|
||||
expect(result["otherTodo"], prev["otherTodo"]);
|
||||
});
|
||||
|
||||
test('Should replace all parent arrays if some nested value changes', () {
|
||||
final Map<String, List<Map>> prev = {
|
||||
"todos": [
|
||||
{
|
||||
"id": '1',
|
||||
"meta": {"createdAt": 0},
|
||||
"state": {"done": false}
|
||||
},
|
||||
{
|
||||
"id": '2',
|
||||
"meta": {"createdAt": 0},
|
||||
"state": {"done": true}
|
||||
},
|
||||
],
|
||||
};
|
||||
final Map<String, List<Map>> next = {
|
||||
"todos": [
|
||||
{
|
||||
"id": '1',
|
||||
"meta": {"createdAt": 0},
|
||||
"state": {"done": true}
|
||||
},
|
||||
{
|
||||
"id": '2',
|
||||
"meta": {"createdAt": 0},
|
||||
"state": {"done": true}
|
||||
},
|
||||
],
|
||||
};
|
||||
final result = replaceEqualDeep(prev, next);
|
||||
expect(result, equals(next));
|
||||
expect(result["todos"][0], isNot(equals(prev["todos"]?.first)));
|
||||
expect(
|
||||
result["todos"][0]?["id"],
|
||||
equals(next["todos"]?.first["id"]),
|
||||
);
|
||||
expect(
|
||||
result["todos"][0]?["meta"],
|
||||
equals(prev["todos"]?.first["meta"]),
|
||||
);
|
||||
expect(result["todos"][0]?["state"]["done"],
|
||||
next["todos"]?.first["state"]["done"]);
|
||||
expect(result["todos"][1], equals(prev["todos"]?[1]));
|
||||
});
|
||||
});
|
||||
|
||||
group(
|
||||
'matchMutation',
|
||||
() => {
|
||||
// test('should return false if mutationKey options is undefined', () => {
|
||||
// const filters = { mutationKey: 'key1' };
|
||||
// const queryClient = new QueryClient();
|
||||
// const mutation = new Mutation({
|
||||
// mutationId: 1,
|
||||
// mutationCache: queryClient.getMutationCache(),
|
||||
// options: {},
|
||||
// })
|
||||
// expect(matchMutation(filters, mutation)).toBeFalsy()
|
||||
// })
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user