react-redux-cache 0.7.0-rc.0 → 0.7.1

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
@@ -291,17 +291,22 @@ export const updateBank = (bank) => {
291
291
 
292
292
  #### Invalidation
293
293
 
294
- `cache-first` cache policy (default) skips fetching on component mount if result is already cached, but we can invalidate cached query results using `invalidateQuery` action to make it run again on a next mount. Also, we can return this action as a part of query or mutation response, to perform it in one batch update.
294
+ `cache-first` cache policy (default) skips fetching on component mount if result is already cached, but we can invalidate cached query results using `invalidateQuery` action to make it run again on a next mount.
295
295
 
296
296
  ```typescript
297
- const updateUser = (user: Partial<User>) => {
298
- const response = ...
299
- return {
300
- result: response.result,
301
- expiresAt: Date.now() + 10000, // optional, expiration time of current response
302
- actions: [invalidateQuery([{ key: 'getUsers' }])] // optional, this action sets `expiresAt` field of `getUsers` states to Date.now()
303
- }
304
- }
297
+
298
+ export const cache = createCache({
299
+ ...
300
+ mutations: {
301
+ updateUser: {
302
+ mutation: updateUser,
303
+ onSuccess(_, __, {dispatch}) {
304
+ // we invalidate getUsers after a single user update (can be done better by updating getUsers state with updateQueryStateAndEntities)
305
+ dispatch(cache.actions.invalidateQuery([{query: 'getUsers'}]))
306
+ },
307
+ },
308
+ },
309
+ })
305
310
  ```
306
311
 
307
312
  #### Extended cache policy
@@ -34,7 +34,7 @@ export declare const createActions: <N extends string, T extends Typenames, QP,
34
34
  invalidateQuery: {
35
35
  <K_2 extends keyof QP & keyof QR>(queries: {
36
36
  /** Query key */
37
- key: K_2;
37
+ query: K_2;
38
38
  /** Query cache key */
39
39
  cacheKey?: Key | undefined;
40
40
  /** Unix timestamp at which query expires. Is set to the query state. @default Date.now() */
@@ -43,7 +43,7 @@ export declare const createActions: <N extends string, T extends Typenames, QP,
43
43
  type: `@rrc/${N}/invalidateQuery`;
44
44
  queries: {
45
45
  /** Query key */
46
- key: K_2;
46
+ query: K_2;
47
47
  /** Query cache key */
48
48
  cacheKey?: Key | undefined;
49
49
  /** Unix timestamp at which query expires. Is set to the query state. @default Date.now() */
@@ -57,14 +57,14 @@ export declare const createActions: <N extends string, T extends Typenames, QP,
57
57
  clearQueryState: {
58
58
  <K_3 extends keyof QP & keyof QR>(queries: {
59
59
  /** Query key */
60
- key: K_3;
60
+ query: K_3;
61
61
  /** Query cache key */
62
62
  cacheKey?: Key | undefined;
63
63
  }[]): {
64
64
  type: `@rrc/${N}/clearQueryState`;
65
65
  queries: {
66
66
  /** Query key */
67
- key: K_3;
67
+ query: K_3;
68
68
  /** Query cache key */
69
69
  cacheKey?: Key | undefined;
70
70
  }[];
@@ -1,4 +1,4 @@
1
- import type { Cache, Key, MutationResult, MutationState, OptionalPartial, QueryOptions, QueryResult, QueryState, Typenames } from './types';
1
+ import type { Cache, Key, MutateOptions, MutationResult, MutationState, OptionalPartial, QueryOptions, QueryResult, QueryState, Typenames } from './types';
2
2
  import { useMutation } from './useMutation';
3
3
  import { useQuery } from './useQuery';
4
4
  import { applyEntityChanges } from './utilsAndConstants';
@@ -30,14 +30,14 @@ export declare const createCache: <N extends string, T extends Typenames, QP, QR
30
30
  } | {
31
31
  type: `@rrc/${N}/invalidateQuery`;
32
32
  queries: {
33
- key: keyof QP & keyof QR;
33
+ query: keyof QP & keyof QR;
34
34
  cacheKey?: Key | undefined;
35
35
  expiresAt?: number | undefined;
36
36
  }[];
37
37
  } | {
38
38
  type: `@rrc/${N}/clearQueryState`;
39
39
  queries: {
40
- key: keyof QP & keyof QR;
40
+ query: keyof QP & keyof QR;
41
41
  cacheKey?: Key | undefined;
42
42
  }[];
43
43
  } | {
@@ -77,13 +77,13 @@ export declare const createCache: <N extends string, T extends Typenames, QP, QR
77
77
  };
78
78
  invalidateQuery: {
79
79
  <K_2 extends keyof QP & keyof QR>(queries: {
80
- key: K_2;
80
+ query: K_2;
81
81
  cacheKey?: Key | undefined;
82
82
  expiresAt?: number | undefined;
83
83
  }[]): {
84
84
  type: `@rrc/${N}/invalidateQuery`;
85
85
  queries: {
86
- key: K_2;
86
+ query: K_2;
87
87
  cacheKey?: Key | undefined;
88
88
  expiresAt?: number | undefined;
89
89
  }[];
@@ -92,12 +92,12 @@ export declare const createCache: <N extends string, T extends Typenames, QP, QR
92
92
  };
93
93
  clearQueryState: {
94
94
  <K_3 extends keyof QP & keyof QR>(queries: {
95
- key: K_3;
95
+ query: K_3;
96
96
  cacheKey?: Key | undefined;
97
97
  }[]): {
98
98
  type: `@rrc/${N}/clearQueryState`;
99
99
  queries: {
100
- key: K_3;
100
+ query: K_3;
101
101
  cacheKey?: Key | undefined;
102
102
  }[];
103
103
  };
@@ -145,17 +145,12 @@ export declare const createCache: <N extends string, T extends Typenames, QP, QR
145
145
  /** Returns client object with query and mutate functions. */
146
146
  useClient: () => {
147
147
  query: <QK_7 extends keyof QP | keyof QR>(options: QueryOptions<T, QP, QR, QK_7>) => Promise<QueryResult<QK_7 extends keyof QP & keyof QR ? QR[QK_7] : never>>;
148
- mutate: <MK_6 extends keyof MP | keyof MR>(options: {
149
- mutation: MK_6;
150
- params: MK_6 extends keyof MP & keyof MR ? MP[MK_6] : never;
151
- }) => Promise<MutationResult<MK_6 extends keyof MP & keyof MR ? MR[MK_6] : never>>;
148
+ mutate: <MK_6 extends keyof MP | keyof MR>(options: MutateOptions<T, MP, MR, MK_6>) => Promise<MutationResult<MK_6 extends keyof MP & keyof MR ? MR[MK_6] : never>>;
152
149
  };
153
150
  /** Fetches query when params change and subscribes to query state changes (except `expiresAt` field). */
154
151
  useQuery: <QK_8 extends keyof QP | keyof QR>(options: import("./types").UseQueryOptions<T, QP, QR, QK_8>) => readonly [Omit<QueryState<QK_8 extends keyof QP & keyof QR ? QP[QK_8] : never, QK_8 extends keyof QP & keyof QR ? QR[QK_8] : never>, "expiresAt">, (options?: Partial<Pick<QueryOptions<T, QP, QR, QK_8>, "params" | "onlyIfExpired">> | undefined) => Promise<QueryResult<QK_8 extends infer T_5 ? T_5 extends QK_8 ? T_5 extends keyof QP & keyof QR ? QR[T_5] : never : never : never>>];
155
152
  /** Subscribes to provided mutation state and provides mutate function. */
156
- useMutation: <MK_7 extends keyof MP | keyof MR>(options: {
157
- mutation: MK_7;
158
- }) => readonly [(params: MK_7 extends keyof MP & keyof MR ? MP[MK_7] : never) => Promise<MutationResult<MK_7 extends infer T_6 ? T_6 extends MK_7 ? T_6 extends keyof MP & keyof MR ? MR[T_6] : never : never : never>>, MutationState<MK_7 extends keyof MP & keyof MR ? MP[MK_7] : never, MK_7 extends keyof MP & keyof MR ? MP[MK_7] : never>, () => boolean];
153
+ useMutation: <MK_7 extends keyof MP | keyof MR>(options: Omit<MutateOptions<T, MP, MR, MK_7>, "params">) => readonly [(params: MK_7 extends keyof MP & keyof MR ? MP[MK_7] : never) => Promise<MutationResult<MK_7 extends infer T_6 ? T_6 extends MK_7 ? T_6 extends keyof MP & keyof MR ? MR[T_6] : never : never : never>>, MutationState<MK_7 extends keyof MP & keyof MR ? MP[MK_7] : never, MK_7 extends keyof MP & keyof MR ? MP[MK_7] : never>, () => boolean];
159
154
  /** useSelector + selectEntityById. */
160
155
  useSelectEntityById: <TN_2 extends keyof T>(id: Key | null | undefined, typename: TN_2) => T[TN_2] | undefined;
161
156
  };
@@ -110,16 +110,18 @@ const createCache = (partialCache) => {
110
110
  const client = {
111
111
  query: (options) => {
112
112
  var _a;
113
- const { query: queryKey, params, onlyIfExpired, secondsToLive, mergeResults } = options;
113
+ const { query: queryKey, params } = options;
114
114
  const getCacheKey = (_a = cache.queries[queryKey].getCacheKey) !== null && _a !== void 0 ? _a : (utilsAndConstants_1.defaultGetCacheKey);
115
115
  // @ts-expect-error fix later
116
116
  const cacheKey = getCacheKey(params);
117
- return (0, query_1.query)('query', store, cache, actions, queryKey, cacheKey, params, secondsToLive, onlyIfExpired,
117
+ return (0, query_1.query)('query', store, cache, actions, queryKey, cacheKey, params, options.secondsToLive, options.onlyIfExpired,
118
118
  // @ts-expect-error fix later
119
- mergeResults);
119
+ options.mergeResults, options.onCompleted, options.onSuccess, options.onError);
120
120
  },
121
121
  mutate: (options) => {
122
- return (0, mutate_1.mutate)('mutate', store, cache, actions, options.mutation, options.params, abortControllers);
122
+ return (0, mutate_1.mutate)('mutate', store, cache, actions, options.mutation, options.params, abortControllers,
123
+ // @ts-expect-error fix later
124
+ options.onCompleted, options.onSuccess, options.onError);
123
125
  },
124
126
  };
125
127
  return client;
@@ -22,14 +22,14 @@ export declare const createCacheReducer: <N extends string, T extends Typenames,
22
22
  } | {
23
23
  type: `@rrc/${N}/invalidateQuery`;
24
24
  queries: {
25
- key: keyof QP & keyof QR;
25
+ query: keyof QP & keyof QR;
26
26
  cacheKey?: import("./types").Key | undefined;
27
27
  expiresAt?: number | undefined;
28
28
  }[];
29
29
  } | {
30
30
  type: `@rrc/${N}/clearQueryState`;
31
31
  queries: {
32
- key: keyof QP & keyof QR;
32
+ query: keyof QP & keyof QR;
33
33
  cacheKey?: import("./types").Key | undefined;
34
34
  }[];
35
35
  } | {
@@ -96,20 +96,20 @@ const createCacheReducer = (actions, typenames, queryKeys, cacheOptions) => {
96
96
  }
97
97
  const now = Date.now();
98
98
  let newQueries = undefined;
99
- for (const { key, cacheKey, expiresAt = now } of queriesToInvalidate) {
100
- const queryStates = (newQueries !== null && newQueries !== void 0 ? newQueries : state.queries)[key];
99
+ for (const { query: queryKey, cacheKey, expiresAt = now } of queriesToInvalidate) {
100
+ const queryStates = (newQueries !== null && newQueries !== void 0 ? newQueries : state.queries)[queryKey];
101
101
  if (cacheKey != null) {
102
102
  if (queryStates[cacheKey]) {
103
103
  const queryState = queryStates[cacheKey];
104
104
  if (queryState && queryState.expiresAt !== expiresAt) {
105
105
  newQueries !== null && newQueries !== void 0 ? newQueries : (newQueries = Object.assign({}, state.queries));
106
- if (state.queries[key] === newQueries[key]) {
107
- newQueries[key] = Object.assign({}, newQueries[key]);
106
+ if (state.queries[queryKey] === newQueries[queryKey]) {
107
+ newQueries[queryKey] = Object.assign({}, newQueries[queryKey]);
108
108
  }
109
109
  // @ts-expect-error fix type later
110
- newQueries[key][cacheKey] = Object.assign(Object.assign({}, queryState), { expiresAt });
110
+ newQueries[queryKey][cacheKey] = Object.assign(Object.assign({}, queryState), { expiresAt });
111
111
  if (expiresAt === undefined) {
112
- delete newQueries[key][cacheKey].expiresAt;
112
+ delete newQueries[queryKey][cacheKey].expiresAt;
113
113
  }
114
114
  }
115
115
  }
@@ -119,12 +119,12 @@ const createCacheReducer = (actions, typenames, queryKeys, cacheOptions) => {
119
119
  const queryState = queryStates[cacheKey];
120
120
  if (queryState && queryState.expiresAt !== expiresAt) {
121
121
  newQueries !== null && newQueries !== void 0 ? newQueries : (newQueries = Object.assign({}, state.queries));
122
- if (state.queries[key] === newQueries[key]) {
123
- newQueries[key] = Object.assign({}, newQueries[key]);
122
+ if (state.queries[queryKey] === newQueries[queryKey]) {
123
+ newQueries[queryKey] = Object.assign({}, newQueries[queryKey]);
124
124
  }
125
- newQueries[key][cacheKey] = Object.assign(Object.assign({}, queryState), { expiresAt });
125
+ newQueries[queryKey][cacheKey] = Object.assign(Object.assign({}, queryState), { expiresAt });
126
126
  if (expiresAt === undefined) {
127
- delete newQueries[key][cacheKey].expiresAt;
127
+ delete newQueries[queryKey][cacheKey].expiresAt;
128
128
  }
129
129
  }
130
130
  }
@@ -140,20 +140,20 @@ const createCacheReducer = (actions, typenames, queryKeys, cacheOptions) => {
140
140
  return state;
141
141
  }
142
142
  let newQueries = undefined;
143
- for (const { key, cacheKey } of queriesToClear) {
144
- const queryStates = (newQueries !== null && newQueries !== void 0 ? newQueries : state.queries)[key];
143
+ for (const { query: queryKey, cacheKey } of queriesToClear) {
144
+ const queryStates = (newQueries !== null && newQueries !== void 0 ? newQueries : state.queries)[queryKey];
145
145
  if (cacheKey != null) {
146
146
  if (queryStates[cacheKey]) {
147
147
  newQueries !== null && newQueries !== void 0 ? newQueries : (newQueries = Object.assign({}, state.queries));
148
- if (state.queries[key] === newQueries[key]) {
149
- newQueries[key] = Object.assign({}, newQueries[key]);
148
+ if (state.queries[queryKey] === newQueries[queryKey]) {
149
+ newQueries[queryKey] = Object.assign({}, newQueries[queryKey]);
150
150
  }
151
- delete newQueries[key][cacheKey];
151
+ delete newQueries[queryKey][cacheKey];
152
152
  }
153
153
  }
154
154
  else if (queryStates !== EMPTY_QUERY_STATE) {
155
155
  newQueries !== null && newQueries !== void 0 ? newQueries : (newQueries = Object.assign({}, state.queries));
156
- newQueries[key] = EMPTY_QUERY_STATE;
156
+ newQueries[queryKey] = EMPTY_QUERY_STATE;
157
157
  }
158
158
  }
159
159
  return !newQueries
package/dist/index.js CHANGED
@@ -23,7 +23,6 @@ Object.defineProperty(exports, "defaultGetCacheKey", { enumerable: true, get: fu
23
23
  Object.defineProperty(exports, "defaultQueryMutationState", { enumerable: true, get: function () { return utilsAndConstants_1.DEFAULT_QUERY_MUTATION_STATE; } });
24
24
  // Backlog
25
25
  // ! high (1.0.0)
26
- // key -> query
27
26
  // rca -> vite
28
27
  // defaults
29
28
  // remove cachePolicy? make skip/enabled a function? skip -> enabled/shouldFetch?
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>>) => 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>) => 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>>;
package/dist/mutate.js CHANGED
@@ -11,7 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.mutate = void 0;
13
13
  const utilsAndConstants_1 = require("./utilsAndConstants");
14
- const mutate = (logTag, store, cache, { updateMutationStateAndEntities, }, mutationKey, params, abortControllers) => __awaiter(void 0, void 0, void 0, function* () {
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
15
  let abortControllersOfStore = abortControllers.get(store);
16
16
  if (abortControllersOfStore === undefined) {
17
17
  abortControllersOfStore = {};
@@ -64,6 +64,10 @@ const mutate = (logTag, store, cache, { updateMutationStateAndEntities, }, mutat
64
64
  error: error,
65
65
  loading: false,
66
66
  }));
67
+ // @ts-expect-error params
68
+ onError === null || onError === void 0 ? void 0 : onError(error, params, store);
69
+ // @ts-expect-error response
70
+ onCompleted === null || onCompleted === void 0 ? void 0 : onCompleted(response, error, params, store);
67
71
  return { error };
68
72
  }
69
73
  if (response) {
@@ -73,6 +77,10 @@ const mutate = (logTag, store, cache, { updateMutationStateAndEntities, }, mutat
73
77
  result: response.result,
74
78
  };
75
79
  store.dispatch(updateMutationStateAndEntities(mutationKey, newState, response));
80
+ // @ts-expect-error params
81
+ onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(response, params, store);
82
+ // @ts-expect-error response
83
+ onCompleted === null || onCompleted === void 0 ? void 0 : onCompleted(response, error, params, store);
76
84
  // @ts-expect-error fix later
77
85
  return { result: response.result };
78
86
  }
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) => 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>) => 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>>;
package/dist/query.js CHANGED
@@ -11,7 +11,7 @@ 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) => __awaiter(void 0, void 0, void 0, function* () {
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
15
  var _a, _b;
16
16
  const logsEnabled = cache.options.logsEnabled;
17
17
  const cacheStateSelector = cache.cacheStateSelector;
@@ -52,6 +52,10 @@ const query = (logTag, store, cache, { updateQueryStateAndEntities, }, queryKey,
52
52
  error: error,
53
53
  loading: false,
54
54
  }));
55
+ // @ts-expect-error params
56
+ onError === null || onError === void 0 ? void 0 : onError(error, params, store);
57
+ // @ts-expect-error params
58
+ onCompleted === null || onCompleted === void 0 ? void 0 : onCompleted(undefined, error, params, store);
55
59
  return { error };
56
60
  }
57
61
  const newState = {
@@ -65,6 +69,10 @@ const query = (logTag, store, cache, { updateQueryStateAndEntities, }, queryKey,
65
69
  : response.result,
66
70
  };
67
71
  store.dispatch(updateQueryStateAndEntities(queryKey, cacheKey, newState, response));
72
+ // @ts-expect-error response
73
+ onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(response, params, store);
74
+ // @ts-expect-error response
75
+ onCompleted === null || onCompleted === void 0 ? void 0 : onCompleted(response, undefined, params, store);
68
76
  return {
69
77
  // @ts-expect-error fix types
70
78
  result: newState === null || newState === void 0 ? void 0 : newState.result,
package/dist/types.d.ts CHANGED
@@ -91,6 +91,12 @@ export type QueryInfo<T extends Typenames, P, R> = {
91
91
  * It is recommended to override it when default implementation is not optimal or when keys in params object can be sorted in random order etc.
92
92
  * */
93
93
  getCacheKey?: (params?: P) => Key;
94
+ /** Called after fetch finished either successfully or not. */
95
+ onCompleted?: (response: QueryResponse<T, R> | undefined, error: unknown | undefined, params: P | undefined, store: Store) => void;
96
+ /** Called after fetch finished without error. */
97
+ onSuccess?: (response: QueryResponse<T, R>, params: P | undefined, store: Store) => void;
98
+ /** Called after fetch finished with error. */
99
+ onError?: (error: unknown, params: P | undefined, store: Store) => void;
94
100
  };
95
101
  export type QueryState<P, R> = MutationState<P, R> & {
96
102
  expiresAt?: number;
@@ -100,7 +106,11 @@ export type UseQueryOptions<T extends Typenames, QP, QR, QK extends keyof (QP &
100
106
  params: QK extends keyof (QP | QR) ? QP[QK] : never;
101
107
  /** When true fetch is not performed. When switches to false fetch is performed depending on cache policy. */
102
108
  skip?: boolean;
103
- } & Pick<QueryInfo<T, QK extends keyof (QP | QR) ? QP[QK] : never, QK extends keyof (QP | QR) ? QR[QK] : never>, 'cachePolicy' | 'secondsToLive' | 'mergeResults'>;
109
+ } & Pick<QueryInfo<T, QK extends keyof (QP | QR) ? QP[QK] : never, QK extends keyof (QP | QR) ? QR[QK] : never>, 'cachePolicy' | 'secondsToLive' | 'mergeResults' | 'onCompleted' | 'onSuccess' | 'onError'>;
110
+ export type QueryOptions<T extends Typenames, QP, QR, QK extends keyof (QP & QR)> = Omit<UseQueryOptions<T, QP, QR, QK>, 'skip' | 'cachePolicy'> & {
111
+ /** If set to true, query will run only if it is expired or result not yet cached. */
112
+ onlyIfExpired?: boolean;
113
+ };
104
114
  /**
105
115
  * @param cache-first for each params key fetch is not called if cache exists.
106
116
  * @param cache-and-fetch for each params key result is taken from cache and fetch is called.
@@ -116,10 +126,6 @@ export type QueryResult<R> = {
116
126
  cancelled?: true;
117
127
  result?: R;
118
128
  };
119
- export type QueryOptions<T extends Typenames, QP, QR, QK extends keyof (QP & QR)> = Omit<UseQueryOptions<T, QP, QR, QK>, 'skip' | 'cachePolicy'> & {
120
- /** If set to true, query will run only if it is expired or result not yet cached. */
121
- onlyIfExpired?: boolean;
122
- };
123
129
  export type Mutation<P, T extends Typenames = Typenames, R = unknown> = (
124
130
  /** Mutation parameters */
125
131
  params: P,
@@ -127,9 +133,13 @@ params: P,
127
133
  store: Store,
128
134
  /** Signal is aborted for current mutation when the same mutation was called once again. */
129
135
  abortSignal: AbortSignal) => Promise<MutationResponse<T, R>>;
130
- export type MutationInfo<T extends Typenames, P, R> = {
136
+ export type MutationInfo<T extends Typenames, P, R> = Pick<QueryInfo<T, P, R>, 'onCompleted' | 'onSuccess' | 'onError'> & {
131
137
  mutation: Mutation<P, T, R>;
132
138
  };
139
+ export type MutateOptions<T extends Typenames, MP, MR, MK extends keyof (MP & MR)> = Pick<MutationInfo<T, MK extends keyof (MP | MR) ? MP[MK] : never, MK extends keyof (MP | MR) ? MR[MK] : never>, 'onCompleted' | 'onSuccess' | 'onError'> & {
140
+ mutation: MK;
141
+ params: MK extends keyof (MP | MR) ? MP[MK] : never;
142
+ };
133
143
  export type MutationResponse<T extends Typenames, R> = EntityChanges<T> & {
134
144
  result?: R;
135
145
  };
@@ -1,6 +1,4 @@
1
1
  import { Store } from 'redux';
2
2
  import { ActionMap } from './createActions';
3
- import { Cache, Key, MutationState, Typenames } from './types';
4
- export declare const useMutation: <N extends string, T extends Typenames, MP, MR, MK extends keyof MP | keyof MR>(cache: Cache<N, T, unknown, unknown, MP, MR>, actions: Pick<ActionMap<N, T, unknown, unknown, MP, MR>, "updateMutationStateAndEntities">, options: {
5
- mutation: MK;
6
- }, abortControllers: WeakMap<Store, Record<Key, AbortController>>) => readonly [(params: MK extends keyof MP & keyof MR ? MP[MK] : never) => Promise<import("./types").MutationResult<MK extends infer T_1 ? T_1 extends MK ? T_1 extends keyof MP & keyof MR ? MR[T_1] : never : never : never>>, MutationState<MK extends keyof MP & keyof MR ? MP[MK] : never, MK extends keyof MP & keyof MR ? MP[MK] : never>, () => boolean];
3
+ import { Cache, Key, MutateOptions, MutationState, Typenames } from './types';
4
+ export declare const useMutation: <N extends string, T extends Typenames, MP, MR, MK extends keyof MP | keyof MR>(cache: Cache<N, T, unknown, unknown, MP, MR>, actions: Pick<ActionMap<N, T, unknown, unknown, MP, MR>, "updateMutationStateAndEntities">, options: Omit<MutateOptions<T, MP, MR, MK>, "params">, abortControllers: WeakMap<Store, Record<Key, AbortController>>) => readonly [(params: MK extends keyof MP & keyof MR ? MP[MK] : never) => Promise<import("./types").MutationResult<MK extends infer T_1 ? T_1 extends MK ? T_1 extends keyof MP & keyof MR ? MR[T_1] : never : never : never>>, MutationState<MK extends keyof MP & keyof MR ? MP[MK] : never, MK extends keyof MP & keyof MR ? MP[MK] : never>, () => boolean];
@@ -16,7 +16,7 @@ const mutate_1 = require("./mutate");
16
16
  const utilsAndConstants_1 = require("./utilsAndConstants");
17
17
  const useMutation = (cache, actions, options, abortControllers) => {
18
18
  var _a;
19
- const { mutation: mutationKey } = options;
19
+ const { mutation: mutationKey, onCompleted, onSuccess, onError } = options;
20
20
  const store = (0, react_redux_1.useStore)();
21
21
  // Using single useMemo for performance reasons
22
22
  const [mutationStateSelector, mutate, abort] = (0, react_1.useMemo)(() => {
@@ -32,7 +32,9 @@ const useMutation = (cache, actions, options, abortControllers) => {
32
32
  },
33
33
  // mutate
34
34
  (params) => __awaiter(void 0, void 0, void 0, function* () {
35
- return yield (0, mutate_1.mutate)('useMutation.mutate', store, cache, actions, mutationKey, params, abortControllers);
35
+ return yield (0, mutate_1.mutate)('useMutation.mutate', store, cache, actions, mutationKey, params, abortControllers,
36
+ // @ts-expect-error fix later
37
+ onCompleted, onSuccess, onError);
36
38
  }),
37
39
  // abort
38
40
  () => {
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, } = options;
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;
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;
@@ -31,7 +31,7 @@ const useQuery = (cache, actions, options) => {
31
31
  paramsPassed ? getCacheKey(options.params) : cacheKey, paramsPassed ? options.params : params, // params type can also have null | undefined, thats why we don't check for it here
32
32
  secondsToLive, options === null || options === void 0 ? void 0 : options.onlyIfExpired,
33
33
  // @ts-expect-error fix later
34
- mergeResults);
34
+ mergeResults, onCompleted, onSuccess, onError);
35
35
  }),
36
36
  // eslint-disable-next-line react-hooks/exhaustive-deps
37
37
  [store, queryKey, cacheKey]);
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.7.0-rc.0",
5
+ "version": "0.7.1",
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",