react-redux-cache 0.8.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -289,7 +289,23 @@ export const updateBank = (bank) => {
289
289
  }
290
290
  }
291
291
  } satisfies Mutation<Partial<Bank>>
292
+ ```
293
+
294
+ If global error handling is needed for errors, not handled by query / mutation `onError` callback, global `onError` can be used:
292
295
 
296
+ ```typescript
297
+ export const cache = createCache({
298
+ name: 'cache',
299
+ globals: {
300
+ onError: (error, key) {
301
+ console.log('Not handled error', { error, key })
302
+ }
303
+ },
304
+ queries: {
305
+ getUsers: { query: getUsers },
306
+ },
307
+ ...
308
+ })
293
309
  ```
294
310
 
295
311
  #### Invalidation
@@ -11,7 +11,7 @@ import { applyEntityChanges } from './utilsAndConstants';
11
11
  * })
12
12
  */
13
13
  export declare const withTypenames: <T extends Typenames = Typenames>() => {
14
- createCache: <N extends string, QP, QR, MP, MR>(partialCache: OptionalPartial<Cache<N, T, QP, QR, MP, MR>, "queries" | "options" | "mutations" | "cacheStateSelector">) => {
14
+ createCache: <N extends string, QP, QR, MP, MR>(partialCache: OptionalPartial<Cache<N, T, QP, QR, MP, MR>, "queries" | "options" | "mutations" | "cacheStateSelector" | "globals">) => {
15
15
  /** Keeps all options, passed while creating the cache. */
16
16
  cache: Cache<N, T, QP, QR, MP, MR>;
17
17
  /** Reducer of the cache, should be added to redux store. */
@@ -172,7 +172,7 @@ export declare const withTypenames: <T extends Typenames = Typenames>() => {
172
172
  /**
173
173
  * Creates reducer, actions and hooks for managing queries and mutations through redux cache.
174
174
  */
175
- export declare const createCache: <N extends string, QP, QR, MP, MR>(partialCache: OptionalPartial<Cache<N, Typenames, QP, QR, MP, MR>, "queries" | "options" | "mutations" | "cacheStateSelector">) => {
175
+ export declare const createCache: <N extends string, QP, QR, MP, MR>(partialCache: OptionalPartial<Cache<N, Typenames, QP, QR, MP, MR>, "queries" | "options" | "mutations" | "cacheStateSelector" | "globals">) => {
176
176
  /** Keeps all options, passed while creating the cache. */
177
177
  cache: Cache<N, Typenames, QP, QR, MP, MR>;
178
178
  /** Reducer of the cache, should be added to redux store. */
@@ -24,18 +24,20 @@ const withTypenames = () => {
24
24
  */
25
25
  return {
26
26
  createCache: (partialCache) => {
27
- var _a, _b, _c, _d, _e, _f, _g;
28
- var _h, _j, _k;
27
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
28
+ var _k, _l, _m, _o;
29
29
  const abortControllers = new WeakMap();
30
30
  // provide all optional fields
31
31
  (_a = partialCache.options) !== null && _a !== void 0 ? _a : (partialCache.options = {});
32
- (_b = (_h = partialCache.options).logsEnabled) !== null && _b !== void 0 ? _b : (_h.logsEnabled = false);
33
- (_c = (_j = partialCache.options).validateFunctionArguments) !== null && _c !== void 0 ? _c : (_j.validateFunctionArguments = utilsAndConstants_1.IS_DEV);
34
- (_d = (_k = partialCache.options).deepComparisonEnabled) !== null && _d !== void 0 ? _d : (_k.deepComparisonEnabled = true);
32
+ (_b = (_k = partialCache.options).logsEnabled) !== null && _b !== void 0 ? _b : (_k.logsEnabled = false);
33
+ (_c = (_l = partialCache.options).validateFunctionArguments) !== null && _c !== void 0 ? _c : (_l.validateFunctionArguments = utilsAndConstants_1.IS_DEV);
34
+ (_d = (_m = partialCache.options).deepComparisonEnabled) !== null && _d !== void 0 ? _d : (_m.deepComparisonEnabled = true);
35
35
  (_e = partialCache.queries) !== null && _e !== void 0 ? _e : (partialCache.queries = {});
36
36
  (_f = partialCache.mutations) !== null && _f !== void 0 ? _f : (partialCache.mutations = {});
37
+ (_g = partialCache.globals) !== null && _g !== void 0 ? _g : (partialCache.globals = {});
38
+ (_h = (_o = partialCache.globals).cachePolicy) !== null && _h !== void 0 ? _h : (_o.cachePolicy = 'cache-first');
37
39
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
38
- (_g = partialCache.cacheStateSelector) !== null && _g !== void 0 ? _g : (partialCache.cacheStateSelector = (state) => state[cache.name]);
40
+ (_j = partialCache.cacheStateSelector) !== null && _j !== void 0 ? _j : (partialCache.cacheStateSelector = (state) => state[cache.name]);
39
41
  // @ts-expect-error private field for testing
40
42
  partialCache.abortControllers = abortControllers;
41
43
  const cache = partialCache;
@@ -145,7 +147,9 @@ const withTypenames = () => {
145
147
  /** Fetches query when params change and subscribes to query state changes (except `expiresAt` field). */
146
148
  useQuery: (options) => (0, useQuery_1.useQuery)(cache, actions, options),
147
149
  /** Subscribes to provided mutation state and provides mutate function. */
148
- useMutation: (options) => (0, useMutation_1.useMutation)(cache, actions, options, abortControllers),
150
+ useMutation: (options
151
+ // @ts-expect-error cache type
152
+ ) => (0, useMutation_1.useMutation)(cache, actions, options, abortControllers),
149
153
  /** useSelector + selectEntityById. */
150
154
  useSelectEntityById: (id, typename) => {
151
155
  return (0, react_redux_1.useSelector)((state) => selectEntityById(state, id, typename));
package/dist/index.js CHANGED
@@ -25,32 +25,25 @@ Object.defineProperty(exports, "defaultQueryMutationState", { enumerable: true,
25
25
  // Backlog
26
26
  // ! high (1.0.0)
27
27
  // rca -> vite
28
- // defaults
28
+ // check validateFunctionArguments
29
+ // remove undefined optional fields & emtpy states. remove mutation state when it finished without errors
29
30
  // remove cachePolicy? make skip/enabled a function? skip -> enabled/shouldFetch?
30
- // remove undefined optional fields & emtpy states
31
31
  // generate full api docs
32
32
  // ! medium
33
33
  // optimistic response
34
+ // reset [whole] cache to initial / to provided state
35
+ // globals for success, completions and loading states?
34
36
  // make query key / cache key difference more clear in the docs
35
37
  // check type of function arguments in dev
36
- // allow multiple mutation with same keys?
37
- // return back deserialize selector?
38
- // selector for entities by typename
39
- // callback option on error / success?
40
- // refetch queries on mutation success
41
- // remove query/mutation state when it finished without errors
42
- // deep equal entities while merging state
43
- // make error type generic
44
38
  // ! low
39
+ // local cache policy to keep in component state?
40
+ // make error type generic
41
+ // allow multiple mutation with same keys?
45
42
  // custom useStore & useSelector to support multiple stores?
46
- // access to currently loading queries and mutations?
47
- // add params to the state?
43
+ // easy access to all currently loading queries and mutations?
48
44
  // cancellation to queries
49
- // if mutation & query alrady loading - make options: last, throttle, debounce, parallel?
50
- // add time-to-live option, and/or time-to-refresh
51
- // add refresh interval for queries that are mounted
52
- // replace try/catch with returned error
53
- // support any store, not only redux
45
+ // if mutation & query already loading - make options: last, throttle, debounce, parallel?
46
+ // add refresh interval for queries that are mounted?
54
47
  // readonly types?
55
48
  // proper types, remove as, any, todo
56
49
  // add number of retries param?
package/dist/mutate.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import { Store } from 'redux';
2
2
  import type { ActionMap } from './createActions';
3
3
  import type { Cache, Key, MutationResult, Typenames } from './types';
4
- export declare const mutate: <N extends string, T extends Typenames, QP, QR, MP, MR, MK extends keyof MP | keyof MR>(logTag: string, store: Store, cache: Cache<N, T, QP, QR, MP, MR>, { updateMutationStateAndEntities, }: Pick<ActionMap<N, T, unknown, unknown, MP, MR>, "updateMutationStateAndEntities">, mutationKey: MK, params: MK extends keyof MP & keyof MR ? MP[MK] : never, abortControllers: WeakMap<Store, Record<Key, AbortController>>, onCompleted?: ((response: import("./types").QueryResponse<T, MR[keyof MP & keyof MR & string]> | undefined, error: unknown, params: MP[keyof MP & keyof MR & string] | undefined, store: Store<any, import("redux").AnyAction>) => void) | ((response: import("./types").QueryResponse<T, MR[keyof MP & keyof MR & number]> | undefined, error: unknown, params: MP[keyof MP & keyof MR & number] | undefined, store: Store<any, import("redux").AnyAction>) => void) | ((response: import("./types").QueryResponse<T, MR[keyof MP & keyof MR & symbol]> | undefined, error: unknown, params: MP[keyof MP & keyof MR & symbol] | undefined, store: Store<any, import("redux").AnyAction>) => void) | undefined, onSuccess?: ((response: import("./types").QueryResponse<T, MR[keyof MP & keyof MR & string]>, params: MP[keyof MP & keyof MR & string] | undefined, store: Store<any, import("redux").AnyAction>) => void) | ((response: import("./types").QueryResponse<T, MR[keyof MP & keyof MR & number]>, params: MP[keyof MP & keyof MR & number] | undefined, store: Store<any, import("redux").AnyAction>) => void) | ((response: import("./types").QueryResponse<T, MR[keyof MP & keyof MR & symbol]>, params: MP[keyof MP & keyof MR & symbol] | undefined, store: Store<any, import("redux").AnyAction>) => void) | undefined, onError?: ((error: unknown, params: MP[keyof MP & keyof MR & string] | undefined, store: Store<any, import("redux").AnyAction>) => void) | ((error: unknown, params: MP[keyof MP & keyof MR & number] | undefined, store: Store<any, import("redux").AnyAction>) => void) | ((error: unknown, params: MP[keyof MP & keyof MR & symbol] | undefined, store: Store<any, import("redux").AnyAction>) => void) | undefined) => Promise<MutationResult<MK extends keyof MP & keyof MR ? MR[MK] : never>>;
4
+ export declare const mutate: <N extends string, T extends Typenames, QP, QR, MP, MR, MK extends keyof MP | keyof MR>(logTag: string, store: Store, cache: Cache<N, T, QP, QR, MP, MR>, { updateMutationStateAndEntities, }: Pick<ActionMap<N, T, unknown, unknown, MP, MR>, "updateMutationStateAndEntities">, mutationKey: MK, params: MK extends keyof MP & keyof MR ? MP[MK] : never, abortControllers: WeakMap<Store, Record<Key, AbortController>>, onCompleted?: ((response: import("./types").QueryResponse<T, MR[keyof MP & keyof MR & string]> | undefined, error: unknown, params: MP[keyof MP & keyof MR & string] | undefined, store: Store<any, import("redux").AnyAction>) => void) | ((response: import("./types").QueryResponse<T, MR[keyof MP & keyof MR & number]> | undefined, error: unknown, params: MP[keyof MP & keyof MR & number] | undefined, store: Store<any, import("redux").AnyAction>) => void) | ((response: import("./types").QueryResponse<T, MR[keyof MP & keyof MR & symbol]> | undefined, error: unknown, params: MP[keyof MP & keyof MR & symbol] | undefined, store: Store<any, import("redux").AnyAction>) => void) | undefined, onSuccess?: ((response: import("./types").QueryResponse<T, MR[keyof MP & keyof MR & string]>, params: MP[keyof MP & keyof MR & string] | undefined, store: Store<any, import("redux").AnyAction>) => void) | ((response: import("./types").QueryResponse<T, MR[keyof MP & keyof MR & number]>, params: MP[keyof MP & keyof MR & number] | undefined, store: Store<any, import("redux").AnyAction>) => void) | ((response: import("./types").QueryResponse<T, MR[keyof MP & keyof MR & symbol]>, params: MP[keyof MP & keyof MR & symbol] | undefined, store: Store<any, import("redux").AnyAction>) => void) | undefined, onError?: ((error: unknown, params: MP[keyof MP & keyof MR & string] | undefined, store: Store<any, import("redux").AnyAction>) => boolean | void | null | undefined) | ((error: unknown, params: MP[keyof MP & keyof MR & number] | undefined, store: Store<any, import("redux").AnyAction>) => boolean | void | null | undefined) | ((error: unknown, params: MP[keyof MP & keyof MR & symbol] | undefined, store: Store<any, import("redux").AnyAction>) => boolean | void | null | undefined) | undefined) => Promise<MutationResult<MK extends keyof MP & keyof MR ? MR[MK] : never>>;
package/dist/mutate.js CHANGED
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.mutate = void 0;
13
13
  const utilsAndConstants_1 = require("./utilsAndConstants");
14
14
  const mutate = (logTag, store, cache, { updateMutationStateAndEntities, }, mutationKey, params, abortControllers, onCompleted = cache.mutations[mutationKey].onCompleted, onSuccess = cache.mutations[mutationKey].onSuccess, onError = cache.mutations[mutationKey].onError) => __awaiter(void 0, void 0, void 0, function* () {
15
+ var _a, _b;
15
16
  let abortControllersOfStore = abortControllers.get(store);
16
17
  if (abortControllersOfStore === undefined) {
17
18
  abortControllersOfStore = {};
@@ -65,7 +66,10 @@ const mutate = (logTag, store, cache, { updateMutationStateAndEntities, }, mutat
65
66
  loading: false,
66
67
  }));
67
68
  // @ts-expect-error params
68
- onError === null || onError === void 0 ? void 0 : onError(error, params, store);
69
+ if (!(onError === null || onError === void 0 ? void 0 : onError(error, params, store))) {
70
+ // @ts-expect-error queryKey
71
+ (_b = (_a = cache.globals).onError) === null || _b === void 0 ? void 0 : _b.call(_a, error, mutationKey, params, store);
72
+ }
69
73
  // @ts-expect-error response
70
74
  onCompleted === null || onCompleted === void 0 ? void 0 : onCompleted(response, error, params, store);
71
75
  return { error };
package/dist/query.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import { Store } from 'redux';
2
2
  import type { ActionMap } from './createActions';
3
3
  import type { Cache, Key, QueryResult, Typenames } from './types';
4
- export declare const query: <N extends string, T extends Typenames, QP, QR, MP, MR, QK extends keyof QP | keyof QR>(logTag: string, store: Store, cache: Cache<N, T, QP, QR, MP, MR>, { updateQueryStateAndEntities, }: Pick<ActionMap<N, T, QP, QR, unknown, unknown>, "updateQueryStateAndEntities">, queryKey: QK, cacheKey: Key, params: QK extends keyof QP & keyof QR ? QP[QK] : never, secondsToLive: number | undefined, onlyIfExpired: boolean | undefined, mergeResults?: ((oldResult: QR[keyof QP & keyof QR & string] | undefined, response: import("./types").QueryResponse<T, QR[keyof QP & keyof QR & string]>, params: QP[keyof QP & keyof QR & string] | undefined, store: Store<any, import("redux").AnyAction>) => QR[keyof QP & keyof QR & string]) | ((oldResult: QR[keyof QP & keyof QR & number] | undefined, response: import("./types").QueryResponse<T, QR[keyof QP & keyof QR & number]>, params: QP[keyof QP & keyof QR & number] | undefined, store: Store<any, import("redux").AnyAction>) => QR[keyof QP & keyof QR & number]) | ((oldResult: QR[keyof QP & keyof QR & symbol] | undefined, response: import("./types").QueryResponse<T, QR[keyof QP & keyof QR & symbol]>, params: QP[keyof QP & keyof QR & symbol] | undefined, store: Store<any, import("redux").AnyAction>) => QR[keyof QP & keyof QR & symbol]) | undefined, onCompleted?: ((response: import("./types").QueryResponse<T, QR[keyof QP & keyof QR & string]> | undefined, error: unknown, params: QP[keyof QP & keyof QR & string] | undefined, store: Store<any, import("redux").AnyAction>) => void) | ((response: import("./types").QueryResponse<T, QR[keyof QP & keyof QR & number]> | undefined, error: unknown, params: QP[keyof QP & keyof QR & number] | undefined, store: Store<any, import("redux").AnyAction>) => void) | ((response: import("./types").QueryResponse<T, QR[keyof QP & keyof QR & symbol]> | undefined, error: unknown, params: QP[keyof QP & keyof QR & symbol] | undefined, store: Store<any, import("redux").AnyAction>) => void) | undefined, onSuccess?: ((response: import("./types").QueryResponse<T, QR[keyof QP & keyof QR & string]>, params: QP[keyof QP & keyof QR & string] | undefined, store: Store<any, import("redux").AnyAction>) => void) | ((response: import("./types").QueryResponse<T, QR[keyof QP & keyof QR & number]>, params: QP[keyof QP & keyof QR & number] | undefined, store: Store<any, import("redux").AnyAction>) => void) | ((response: import("./types").QueryResponse<T, QR[keyof QP & keyof QR & symbol]>, params: QP[keyof QP & keyof QR & symbol] | undefined, store: Store<any, import("redux").AnyAction>) => void) | undefined, onError?: ((error: unknown, params: QP[keyof QP & keyof QR & string] | undefined, store: Store<any, import("redux").AnyAction>) => void) | ((error: unknown, params: QP[keyof QP & keyof QR & number] | undefined, store: Store<any, import("redux").AnyAction>) => void) | ((error: unknown, params: QP[keyof QP & keyof QR & symbol] | undefined, store: Store<any, import("redux").AnyAction>) => void) | undefined) => Promise<QueryResult<QK extends keyof QP & keyof QR ? QR[QK] : never>>;
4
+ export declare const query: <N extends string, T extends Typenames, QP, QR, MP, MR, QK extends keyof QP | keyof QR>(logTag: string, store: Store, cache: Cache<N, T, QP, QR, MP, MR>, { updateQueryStateAndEntities, }: Pick<ActionMap<N, T, QP, QR, unknown, unknown>, "updateQueryStateAndEntities">, queryKey: QK, cacheKey: Key, params: QK extends keyof QP & keyof QR ? QP[QK] : never, secondsToLive: number | undefined, onlyIfExpired: boolean | undefined, mergeResults?: ((oldResult: QR[keyof QP & keyof QR & string] | undefined, response: import("./types").QueryResponse<T, QR[keyof QP & keyof QR & string]>, params: QP[keyof QP & keyof QR & string] | undefined, store: Store<any, import("redux").AnyAction>) => QR[keyof QP & keyof QR & string]) | ((oldResult: QR[keyof QP & keyof QR & number] | undefined, response: import("./types").QueryResponse<T, QR[keyof QP & keyof QR & number]>, params: QP[keyof QP & keyof QR & number] | undefined, store: Store<any, import("redux").AnyAction>) => QR[keyof QP & keyof QR & number]) | ((oldResult: QR[keyof QP & keyof QR & symbol] | undefined, response: import("./types").QueryResponse<T, QR[keyof QP & keyof QR & symbol]>, params: QP[keyof QP & keyof QR & symbol] | undefined, store: Store<any, import("redux").AnyAction>) => QR[keyof QP & keyof QR & symbol]) | undefined, onCompleted?: ((response: import("./types").QueryResponse<T, QR[keyof QP & keyof QR & string]> | undefined, error: unknown, params: QP[keyof QP & keyof QR & string] | undefined, store: Store<any, import("redux").AnyAction>) => void) | ((response: import("./types").QueryResponse<T, QR[keyof QP & keyof QR & number]> | undefined, error: unknown, params: QP[keyof QP & keyof QR & number] | undefined, store: Store<any, import("redux").AnyAction>) => void) | ((response: import("./types").QueryResponse<T, QR[keyof QP & keyof QR & symbol]> | undefined, error: unknown, params: QP[keyof QP & keyof QR & symbol] | undefined, store: Store<any, import("redux").AnyAction>) => void) | undefined, onSuccess?: ((response: import("./types").QueryResponse<T, QR[keyof QP & keyof QR & string]>, params: QP[keyof QP & keyof QR & string] | undefined, store: Store<any, import("redux").AnyAction>) => void) | ((response: import("./types").QueryResponse<T, QR[keyof QP & keyof QR & number]>, params: QP[keyof QP & keyof QR & number] | undefined, store: Store<any, import("redux").AnyAction>) => void) | ((response: import("./types").QueryResponse<T, QR[keyof QP & keyof QR & symbol]>, params: QP[keyof QP & keyof QR & symbol] | undefined, store: Store<any, import("redux").AnyAction>) => void) | undefined, onError?: ((error: unknown, params: QP[keyof QP & keyof QR & string] | undefined, store: Store<any, import("redux").AnyAction>) => boolean | void | null | undefined) | ((error: unknown, params: QP[keyof QP & keyof QR & number] | undefined, store: Store<any, import("redux").AnyAction>) => boolean | void | null | undefined) | ((error: unknown, params: QP[keyof QP & keyof QR & symbol] | undefined, store: Store<any, import("redux").AnyAction>) => boolean | void | null | undefined) | undefined) => Promise<QueryResult<QK extends keyof QP & keyof QR ? QR[QK] : never>>;
package/dist/query.js CHANGED
@@ -11,8 +11,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.query = void 0;
13
13
  const utilsAndConstants_1 = require("./utilsAndConstants");
14
- const query = (logTag, store, cache, { updateQueryStateAndEntities, }, queryKey, cacheKey, params, secondsToLive = cache.queries[queryKey].secondsToLive, onlyIfExpired, mergeResults = cache.queries[queryKey].mergeResults, onCompleted = cache.queries[queryKey].onCompleted, onSuccess = cache.queries[queryKey].onSuccess, onError = cache.queries[queryKey].onError) => __awaiter(void 0, void 0, void 0, function* () {
15
- var _a, _b;
14
+ const query = (logTag, store, cache, _a, queryKey, cacheKey, params, secondsToLive, onlyIfExpired, mergeResults, onCompleted, onSuccess, onError) => __awaiter(void 0, void 0, void 0, function* () {
15
+ var _b, _c, _d, _e, _f;
16
+ var { updateQueryStateAndEntities, } = _a;
17
+ if (secondsToLive === void 0) { secondsToLive = (_b = cache.queries[queryKey].secondsToLive) !== null && _b !== void 0 ? _b : cache.globals.secondsToLive; }
18
+ if (mergeResults === void 0) { mergeResults = cache.queries[queryKey].mergeResults; }
19
+ if (onCompleted === void 0) { onCompleted = cache.queries[queryKey].onCompleted; }
20
+ if (onSuccess === void 0) { onSuccess = cache.queries[queryKey].onSuccess; }
21
+ if (onError === void 0) { onError = cache.queries[queryKey].onError; }
16
22
  const logsEnabled = cache.options.logsEnabled;
17
23
  const cacheStateSelector = cache.cacheStateSelector;
18
24
  const queryStateOnStart = cacheStateSelector(store.getState()).queries[queryKey][cacheKey];
@@ -53,7 +59,10 @@ const query = (logTag, store, cache, { updateQueryStateAndEntities, }, queryKey,
53
59
  loading: false,
54
60
  }));
55
61
  // @ts-expect-error params
56
- onError === null || onError === void 0 ? void 0 : onError(error, params, store);
62
+ if (!(onError === null || onError === void 0 ? void 0 : onError(error, params, store))) {
63
+ // @ts-expect-error queryKey
64
+ (_d = (_c = cache.globals).onError) === null || _d === void 0 ? void 0 : _d.call(_c, error, queryKey, params, store);
65
+ }
57
66
  // @ts-expect-error params
58
67
  onCompleted === null || onCompleted === void 0 ? void 0 : onCompleted(undefined, error, params, store);
59
68
  return { error };
@@ -61,11 +70,11 @@ const query = (logTag, store, cache, { updateQueryStateAndEntities, }, queryKey,
61
70
  const newState = {
62
71
  error: undefined,
63
72
  loading: false,
64
- expiresAt: (_a = response.expiresAt) !== null && _a !== void 0 ? _a : (secondsToLive != null ? Date.now() + secondsToLive * 1000 : undefined),
73
+ expiresAt: (_e = response.expiresAt) !== null && _e !== void 0 ? _e : (secondsToLive != null ? Date.now() + secondsToLive * 1000 : undefined),
65
74
  result: mergeResults
66
75
  ? mergeResults(
67
76
  // @ts-expect-error fix later
68
- (_b = cacheStateSelector(store.getState()).queries[queryKey][cacheKey]) === null || _b === void 0 ? void 0 : _b.result, response, params, store)
77
+ (_f = cacheStateSelector(store.getState()).queries[queryKey][cacheKey]) === null || _f === void 0 ? void 0 : _f.result, response, params, store)
69
78
  : response.result,
70
79
  };
71
80
  store.dispatch(updateQueryStateAndEntities(queryKey, cacheKey, newState, response));
package/dist/types.d.ts CHANGED
@@ -27,10 +27,27 @@ export type Cache<N extends string, T extends Typenames, QP, QR, MP, MR> = {
27
27
  mutations: {
28
28
  [MK in keyof (MP & MR)]: MK extends keyof (MP | MR) ? MutationInfo<T, MP[MK], MR[MK]> : never;
29
29
  };
30
+ /** Default options for queries and mutations.
31
+ * @default { cachePolicy: 'cache-first', sedondsToLive: undefined, onError: undefined } */
32
+ globals: Globals<QP, MP>;
30
33
  options: CacheOptions;
31
34
  /** Should return cache state from redux root state. Default implementation returns `state[name]`. */
32
35
  cacheStateSelector: (state: any) => ReduxCacheState<T, QP, QR, MP, MR>;
33
36
  };
37
+ export type Globals<QP, MP> = {
38
+ /**
39
+ * Cache policy.
40
+ * @cache-first fetch only if cache either does not exist or is expired on useQuery mount.
41
+ * @cache-and-fetch fetch on every useQuery mount.
42
+ * @default cache-first
43
+ */
44
+ cachePolicy: QueryCachePolicy;
45
+ /** If set, this value updates expiresAt value of query state when query result is received. */
46
+ secondsToLive?: number;
47
+ /** Handles errors, not handled by onError from queries and mutations. */
48
+ onError?: <K extends keyof QP | keyof MP>(error: unknown, key: K, params: QP[keyof QP] | MP[keyof MP], // TODO proper type
49
+ store: Store) => void;
50
+ };
34
51
  export type CacheOptions = {
35
52
  /**
36
53
  * Enables validation of package function arguments. Recommened to enable in dev/testing mode.
@@ -64,15 +81,8 @@ export type Query<P, T extends Typenames = Typenames, R = unknown> = (
64
81
  params: P,
65
82
  /** Redux store */
66
83
  store: Store) => Promise<QueryResponse<T, R>>;
67
- export type QueryInfo<T extends Typenames, P, R> = {
84
+ export type QueryInfo<T extends Typenames, P, R> = Partial<Pick<Globals<unknown, unknown>, 'cachePolicy' | 'secondsToLive'>> & {
68
85
  query: Query<P, T, R>;
69
- /**
70
- * Cache policy.
71
- * @default cache-first
72
- */
73
- cachePolicy?: QueryCachePolicy;
74
- /** If set, this value updates expiresAt value of query state when query resut is received. */
75
- secondsToLive?: number;
76
86
  /** Merges results before saving to the store. Default implementation is using the latest result. */
77
87
  mergeResults?: (oldResult: R | undefined, response: QueryResponse<T, R>, params: P | undefined, store: Store) => R;
78
88
  /**
@@ -85,8 +95,8 @@ export type QueryInfo<T extends Typenames, P, R> = {
85
95
  onCompleted?: (response: QueryResponse<T, R> | undefined, error: unknown | undefined, params: P | undefined, store: Store) => void;
86
96
  /** Called after fetch finished without error. */
87
97
  onSuccess?: (response: QueryResponse<T, R>, params: P | undefined, store: Store) => void;
88
- /** Called after fetch finished with error. */
89
- onError?: (error: unknown, params: P | undefined, store: Store) => void;
98
+ /** Called after fetch finished with error. Should return true if error was handled and does not require global onError handling. */
99
+ onError?: (error: unknown, params: P | undefined, store: Store) => boolean | void | null | undefined;
90
100
  };
91
101
  export type QueryState<P, R> = MutationState<P, R> & {
92
102
  expiresAt?: number;
@@ -101,10 +111,6 @@ export type QueryOptions<T extends Typenames, QP, QR, QK extends keyof (QP & QR)
101
111
  /** If set to true, query will run only if it is expired or result not yet cached. */
102
112
  onlyIfExpired?: boolean;
103
113
  };
104
- /**
105
- * @param cache-first for each params key fetch is not called if cache exists.
106
- * @param cache-and-fetch for each params key result is taken from cache and fetch is called.
107
- */
108
114
  export type QueryCachePolicy = 'cache-first' | 'cache-and-fetch';
109
115
  export type QueryResponse<T extends Typenames, R> = EntityChanges<T> & {
110
116
  result: R;
package/dist/useQuery.js CHANGED
@@ -16,7 +16,7 @@ const query_1 = require("./query");
16
16
  const utilsAndConstants_1 = require("./utilsAndConstants");
17
17
  const useQuery = (cache, actions, options) => {
18
18
  var _a, _b, _c;
19
- const { query: queryKey, skip, params, secondsToLive, cachePolicy = (_a = cache.queries[queryKey].cachePolicy) !== null && _a !== void 0 ? _a : 'cache-first', mergeResults, onCompleted, onSuccess, onError, } = options;
19
+ const { query: queryKey, skip, params, secondsToLive, cachePolicy = (_a = cache.queries[queryKey].cachePolicy) !== null && _a !== void 0 ? _a : cache.globals.cachePolicy, mergeResults, onCompleted, onSuccess, onError, } = options;
20
20
  const logsEnabled = cache.options.logsEnabled;
21
21
  const getCacheKey = (_b = cache.queries[queryKey].getCacheKey) !== null && _b !== void 0 ? _b : (utilsAndConstants_1.defaultGetCacheKey);
22
22
  const cacheStateSelector = cache.cacheStateSelector;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "react-redux-cache",
3
3
  "author": "Alexander Danilov",
4
4
  "license": "MIT",
5
- "version": "0.8.1",
5
+ "version": "0.9.0",
6
6
  "description": "Powerful data fetching and caching library that supports normalization, built on top of redux",
7
7
  "main": "dist/index.js",
8
8
  "types": "dist/index.d.ts",