react-redux-cache 0.2.0 → 0.3.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
@@ -13,6 +13,43 @@
13
13
  **Normalization** is the best way to keep the state of the app **consistent** between different views, reduces the number of fetches and allows to show cached data when navigating, which greatly improves **user experience**.
14
14
 
15
15
  Remains **full control** of redux state with ability to write custom selectors, actions and reducers to manage cached state.
16
+
17
+ Here is example of redux state, generated by cache reducer from `/example` project:
18
+ ```js
19
+ const state = {
20
+ entities: {
21
+ // each typename has its own map of entities, stored by id
22
+ users: {
23
+ "0": {id: 0, bankId: "0", name: "User 0 *"},
24
+ "1": {id: 1, bankId: "1", name: "User 1 *"},
25
+ "2": {id: 2, bankId: "2", name: "User 2"},
26
+ "3": {id: 3, bankId: "3", name: "User 3"}
27
+ },
28
+ banks: {
29
+ "0": {id: "0", name: "Bank 0"},
30
+ "1": {id: "1", name: "Bank 1"},
31
+ "2": {id: "2", name: "Bank 2"},
32
+ "3": {id: "3", name: "Bank 3"}
33
+ }
34
+ },
35
+ queries: {
36
+ // each query has its own map of query states, stored by cache key, which is generated from query params
37
+ getUser: {
38
+ "2": {loading: false, error: undefined, result: 2},
39
+ "3": {loading: true}
40
+ },
41
+ getUsers: {
42
+ // example of paginated state under custom cache key
43
+ "all-pages": {loading: false, result: {items: [0,1,2], page: 1}}
44
+ }
45
+ },
46
+ mutations: {
47
+ // each mutation has its own state as well
48
+ updateUser: {loading: false, result: 1}
49
+ }
50
+ }
51
+ ```
52
+
16
53
 
17
54
  ### Table of contents
18
55
 
@@ -1,4 +1,4 @@
1
- import type { Cache, EntitiesMap, Key, MutationResult, OptionalPartial, QueryOptions, QueryResult, Typenames } from './types';
1
+ import type { Cache, EntitiesMap, Key, MutationResult, OptionalPartial, QueryMutationState, QueryOptions, QueryResult, Typenames } from './types';
2
2
  import { useMutation } from './useMutation';
3
3
  import { useQuery } from './useQuery';
4
4
  import { applyEntityChanges } from './utilsAndConstants';
@@ -10,18 +10,18 @@ export declare const createCache: <N extends string, T extends Typenames, QP, QR
10
10
  /** Reducer of the cache, should be added to redux store. */
11
11
  reducer: (state: {
12
12
  entities: EntitiesMap<T>;
13
- queries: { [QK in keyof QR]: import("./types").Dict<import("./types").QueryMutationState<QR[QK]>>; };
14
- mutations: { [MK in keyof MR]: import("./types").QueryMutationState<MR[MK]>; };
13
+ queries: { [QK in keyof QR]: import("./types").Dict<QueryMutationState<QR[QK]>>; };
14
+ mutations: { [MK in keyof MR]: QueryMutationState<MR[MK]>; };
15
15
  } | undefined, action: {
16
16
  type: `@rrc/${N}/updateQueryStateAndEntities`;
17
17
  queryKey: keyof QR;
18
18
  queryCacheKey: Key;
19
- state: Partial<import("./types").QueryMutationState<QR[keyof QR]>> | undefined;
19
+ state: Partial<QueryMutationState<QR[keyof QR]>> | undefined;
20
20
  entityChagnes: import("./types").EntityChanges<T> | undefined;
21
21
  } | {
22
22
  type: `@rrc/${N}/updateMutationStateAndEntities`;
23
23
  mutationKey: keyof MR;
24
- state: Partial<import("./types").QueryMutationState<MR[keyof MR]>> | undefined;
24
+ state: Partial<QueryMutationState<MR[keyof MR]>> | undefined;
25
25
  entityChagnes: import("./types").EntityChanges<T> | undefined;
26
26
  } | {
27
27
  type: `@rrc/${N}/mergeEntityChanges`;
@@ -34,28 +34,28 @@ export declare const createCache: <N extends string, T extends Typenames, QP, QR
34
34
  }[];
35
35
  } | {
36
36
  type: `@rrc/${N}/clearMutationState`;
37
- mutationKeys: (keyof MR)[]; /** Select all entities of provided typename. */
37
+ mutationKeys: (keyof MR)[];
38
38
  }) => {
39
39
  entities: EntitiesMap<T>;
40
- queries: { [QK in keyof QR]: import("./types").Dict<import("./types").QueryMutationState<QR[QK]>>; };
41
- mutations: { [MK in keyof MR]: import("./types").QueryMutationState<MR[MK]>; };
40
+ queries: { [QK in keyof QR]: import("./types").Dict<QueryMutationState<QR[QK]>>; };
41
+ mutations: { [MK in keyof MR]: QueryMutationState<MR[MK]>; };
42
42
  };
43
43
  actions: {
44
44
  updateQueryStateAndEntities: {
45
- <K extends keyof QR>(queryKey: K, queryCacheKey: Key, state?: Partial<import("./types").QueryMutationState<QR[K]>> | undefined, entityChagnes?: import("./types").EntityChanges<T> | undefined): {
45
+ <K extends keyof QR>(queryKey: K, queryCacheKey: Key, state?: Partial<QueryMutationState<QR[K]>> | undefined, entityChagnes?: import("./types").EntityChanges<T> | undefined): {
46
46
  type: `@rrc/${N}/updateQueryStateAndEntities`;
47
47
  queryKey: K;
48
48
  queryCacheKey: Key;
49
- state: Partial<import("./types").QueryMutationState<QR[K]>> | undefined;
49
+ state: Partial<QueryMutationState<QR[K]>> | undefined;
50
50
  entityChagnes: import("./types").EntityChanges<T> | undefined;
51
51
  };
52
52
  type: `@rrc/${N}/updateQueryStateAndEntities`;
53
53
  };
54
54
  updateMutationStateAndEntities: {
55
- <K_1 extends keyof MR>(mutationKey: K_1, state?: Partial<import("./types").QueryMutationState<MR[K_1]>> | undefined, entityChagnes?: import("./types").EntityChanges<T> | undefined): {
55
+ <K_1 extends keyof MR>(mutationKey: K_1, state?: Partial<QueryMutationState<MR[K_1]>> | undefined, entityChagnes?: import("./types").EntityChanges<T> | undefined): {
56
56
  type: `@rrc/${N}/updateMutationStateAndEntities`;
57
57
  mutationKey: K_1;
58
- state: Partial<import("./types").QueryMutationState<MR[K_1]>> | undefined;
58
+ state: Partial<QueryMutationState<MR[K_1]>> | undefined;
59
59
  entityChagnes: import("./types").EntityChanges<T> | undefined;
60
60
  };
61
61
  type: `@rrc/${N}/updateMutationStateAndEntities`;
@@ -83,12 +83,20 @@ export declare const createCache: <N extends string, T extends Typenames, QP, QR
83
83
  clearMutationState: {
84
84
  <K_3 extends keyof MR>(mutationKeys: K_3[]): {
85
85
  type: `@rrc/${N}/clearMutationState`;
86
- mutationKeys: K_3[]; /** Select all entities of provided typename. */
86
+ mutationKeys: K_3[];
87
87
  };
88
88
  type: `@rrc/${N}/clearMutationState`;
89
89
  };
90
90
  };
91
91
  selectors: {
92
+ selectQueryState: <QK_1 extends keyof QR | keyof QP>(state: unknown, query: QK_1, cacheKey: Key) => QueryMutationState<QK_1 extends keyof QP & keyof QR ? QR[QK_1] : never> | undefined;
93
+ selectQueryResult: <QK_2 extends keyof QR | keyof QP>(state: unknown, query: QK_2, cacheKey: Key) => (QK_2 extends keyof QP & keyof QR ? QR[QK_2] : never) | undefined;
94
+ selectQueryLoading: <QK_3 extends keyof QR | keyof QP>(state: unknown, query: QK_3, cacheKey: Key) => boolean | undefined;
95
+ selectQueryError: <QK_4 extends keyof QR | keyof QP>(state: unknown, query: QK_4, cacheKey: Key) => Error | undefined;
96
+ selectMutationState: <MK_1 extends keyof MP | keyof MR>(state: unknown, mutation: MK_1) => QueryMutationState<MK_1 extends keyof MP & keyof MR ? MR[MK_1] : never>;
97
+ selectMutationResult: <MK_2 extends keyof MP | keyof MR>(state: unknown, mutation: MK_2) => (MK_2 extends keyof MP & keyof MR ? MR[MK_2] : never) | undefined;
98
+ selectMutationLoading: <MK_3 extends keyof MP | keyof MR>(state: unknown, mutation: MK_3) => boolean;
99
+ selectMutationError: <MK_4 extends keyof MP | keyof MR>(state: unknown, mutation: MK_4) => Error | undefined;
92
100
  /** Select all entities from the state. */
93
101
  entitiesSelector: (state: unknown) => EntitiesMap<T>;
94
102
  /** Select all entities of provided typename. */
@@ -97,18 +105,18 @@ export declare const createCache: <N extends string, T extends Typenames, QP, QR
97
105
  hooks: {
98
106
  /** Returns client object with query function */
99
107
  useClient: () => {
100
- query: <QK_1 extends keyof QR | keyof QP>(options: QueryOptions<T, QP, QR, MR, QK_1>) => Promise<QueryResult<QK_1 extends keyof QP & keyof QR ? QR[QK_1] : never>>;
101
- mutate: <MK_1 extends keyof MP | keyof MR>(options: {
102
- mutation: MK_1;
103
- params: MK_1 extends keyof MP & keyof MR ? MP[MK_1] : never;
104
- }) => Promise<MutationResult<MK_1 extends keyof MP & keyof MR ? MR[MK_1] : never>>;
108
+ query: <QK_5 extends keyof QR | keyof QP>(options: Omit<QueryOptions<T, QP, QR, MR, QK_5>, "cachePolicy">) => Promise<QueryResult<QK_5 extends keyof QP & keyof QR ? QR[QK_5] : never>>;
109
+ mutate: <MK_5 extends keyof MP | keyof MR>(options: {
110
+ mutation: MK_5;
111
+ params: MK_5 extends keyof MP & keyof MR ? MP[MK_5] : never;
112
+ }) => Promise<MutationResult<MK_5 extends keyof MP & keyof MR ? MR[MK_5] : never>>;
105
113
  };
106
114
  /** Fetches query when params change and subscribes to query state. */
107
- useQuery: <QK_2 extends keyof QR | keyof QP>(options: import("./types").UseQueryOptions<T, QP, QR, MR, QK_2>) => readonly [import("./types").QueryMutationState<QK_2 extends keyof QP & keyof QR ? QR[QK_2] : never>, () => Promise<void>];
115
+ useQuery: <QK_6 extends keyof QR | keyof QP>(options: import("./types").UseQueryOptions<T, QP, QR, MR, QK_6>) => readonly [QueryMutationState<QK_6 extends keyof QP & keyof QR ? QR[QK_6] : never>, () => Promise<QueryResult<QK_6 extends infer T_1 ? T_1 extends QK_6 ? T_1 extends keyof QP & keyof QR ? QR[T_1] : never : never : never>>];
108
116
  /** Subscribes to provided mutation state and provides mutate function. */
109
- useMutation: <MK_2 extends keyof MP | keyof MR>(options: {
110
- mutation: MK_2;
111
- }) => readonly [(params: MK_2 extends keyof MP & keyof MR ? MP[MK_2] : never) => Promise<void>, import("./types").QueryMutationState<MK_2 extends keyof MP & keyof MR ? MP[MK_2] : never>, () => boolean];
117
+ useMutation: <MK_6 extends keyof MP | keyof MR>(options: {
118
+ mutation: MK_6;
119
+ }) => readonly [(params: MK_6 extends keyof MP & keyof MR ? MP[MK_6] : never) => Promise<MutationResult<MK_6 extends infer T_2 ? T_2 extends MK_6 ? T_2 extends keyof MP & keyof MR ? MR[T_2] : never : never : never>>, QueryMutationState<MK_6 extends keyof MP & keyof MR ? MP[MK_6] : never>, () => boolean];
112
120
  /** Selects entity by id and subscribes to the changes. */
113
121
  useSelectEntityById: <TN_1 extends keyof T>(id: Key | null | undefined, typename: TN_1) => T[TN_1] | undefined;
114
122
  };
@@ -36,6 +36,14 @@ const createCache = (partialCache) => {
36
36
  result[x] = (state) => cache.cacheStateSelector(state).entities[x];
37
37
  return result;
38
38
  }, {});
39
+ const selectQueryState = (state, query, cacheKey) => {
40
+ // @ts-expect-error fix later
41
+ return cache.cacheStateSelector(state).queries[query][cacheKey];
42
+ };
43
+ const selectMutationState = (state, mutation) => {
44
+ // @ts-expect-error fix later
45
+ return cache.cacheStateSelector(state).mutations[mutation];
46
+ };
39
47
  const actions = (0, createActions_1.createActions)(cache.name);
40
48
  return {
41
49
  cache,
@@ -43,6 +51,29 @@ const createCache = (partialCache) => {
43
51
  reducer: (0, reducer_1.createCacheReducer)(actions, cache.typenames, Object.keys(cache.queries), cache.options),
44
52
  actions,
45
53
  selectors: {
54
+ selectQueryState,
55
+ selectQueryResult: (state, query, cacheKey) => {
56
+ var _a;
57
+ return (_a = selectQueryState(state, query, cacheKey)) === null || _a === void 0 ? void 0 : _a.result;
58
+ },
59
+ selectQueryLoading: (state, query, cacheKey) => {
60
+ var _a;
61
+ return (_a = selectQueryState(state, query, cacheKey)) === null || _a === void 0 ? void 0 : _a.loading;
62
+ },
63
+ selectQueryError: (state, query, cacheKey) => {
64
+ var _a;
65
+ return (_a = selectQueryState(state, query, cacheKey)) === null || _a === void 0 ? void 0 : _a.error;
66
+ },
67
+ selectMutationState,
68
+ selectMutationResult: (state, mutation) => {
69
+ return selectMutationState(state, mutation).result;
70
+ },
71
+ selectMutationLoading: (state, mutation) => {
72
+ return selectMutationState(state, mutation).loading;
73
+ },
74
+ selectMutationError: (state, mutation) => {
75
+ return selectMutationState(state, mutation).error;
76
+ },
46
77
  /** Select all entities from the state. */
47
78
  entitiesSelector,
48
79
  /** Select all entities of provided typename. */
@@ -62,10 +93,10 @@ const createCache = (partialCache) => {
62
93
  const getCacheKey = (_a = cache.queries[queryKey].getCacheKey) !== null && _a !== void 0 ? _a : (utilsAndConstants_1.defaultGetCacheKey);
63
94
  // @ts-expect-error fix later
64
95
  const cacheKey = getCacheKey(params);
65
- return (0, query_1.query)('query', true, store, cache, actions, queryKey, cacheKey, params);
96
+ return (0, query_1.query)('query', store, cache, actions, queryKey, cacheKey, params);
66
97
  },
67
98
  mutate: (options) => {
68
- return (0, mutate_1.mutate)('mutate', true, store, cache, actions, options.mutation, options.params, abortControllers);
99
+ return (0, mutate_1.mutate)('mutate', store, cache, actions, options.mutation, options.params, abortControllers);
69
100
  },
70
101
  };
71
102
  return client;
package/dist/index.js CHANGED
@@ -23,13 +23,10 @@ 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
26
- // screenshot of redux state to README
27
- // optimistic response
28
- // cover with tests
29
- // try use skip for refreshing strategy?
30
26
  // add example without normalization
31
- // make query key / cache key difference more clear in the docs
32
- // support multiple caches = reducers
27
+ // try use skip for refreshing strategy?
28
+ // optimistic response
29
+ // make query key / cache key difference more clear in the docs, or remove queryKey at all?
33
30
  // ! medium
34
31
  // make named caches to produce named hooks, actions etc (same as slices in RTK)?
35
32
  // allow multiple mutation with same keys?
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, returnResult: boolean, store: Store, cache: Cache<N, T, QP, QR, MP, MR>, { updateMutationStateAndEntities }: Pick<ActionMap<N, T, QR, MR>, "updateMutationStateAndEntities">, mutationKey: MK, params: MK extends keyof MP & keyof MR ? MP[MK] : never, abortControllers: WeakMap<Store, Record<Key, AbortController>>) => Promise<void | 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, QR, 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>>;
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, returnResult, store, cache, { updateMutationStateAndEntities }, mutationKey, params, abortControllers) => __awaiter(void 0, void 0, void 0, function* () {
14
+ const mutate = (logTag, store, cache, { updateMutationStateAndEntities }, mutationKey, params, abortControllers) => __awaiter(void 0, void 0, void 0, function* () {
15
15
  let abortControllersOfStore = abortControllers.get(store);
16
16
  if (abortControllersOfStore === undefined) {
17
17
  abortControllersOfStore = {};
@@ -55,7 +55,7 @@ const mutate = (logTag, returnResult, store, cache, { updateMutationStateAndEnti
55
55
  aborted: abortController.signal.aborted,
56
56
  });
57
57
  if (abortController.signal.aborted) {
58
- return returnResult ? { aborted: true } : undefined;
58
+ return ABORTED_RESULT;
59
59
  }
60
60
  delete abortControllersOfStore[mutationKey];
61
61
  if (error) {
@@ -73,8 +73,9 @@ const mutate = (logTag, returnResult, store, cache, { updateMutationStateAndEnti
73
73
  result: response.result,
74
74
  }, response));
75
75
  // @ts-expect-error fix later
76
- return returnResult ? { result: response.result } : undefined;
76
+ return { result: response.result };
77
77
  }
78
78
  throw new Error(`${logTag}: both error and response are not defined`);
79
79
  });
80
80
  exports.mutate = mutate;
81
+ const ABORTED_RESULT = Object.freeze({ aborted: true });
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, returnResult: boolean, store: Store, cache: Cache<N, T, QP, QR, MP, MR>, { updateQueryStateAndEntities }: Pick<ActionMap<N, T, QR, MR>, "updateQueryStateAndEntities">, queryKey: QK, cacheKey: Key, params: QK extends keyof QP & keyof QR ? QP[QK] : never) => Promise<void | 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, QR, MR>, "updateQueryStateAndEntities">, queryKey: QK, cacheKey: Key, params: QK extends keyof QP & keyof QR ? QP[QK] : never) => 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, returnResult, store, cache, { updateQueryStateAndEntities }, queryKey, cacheKey, params) => __awaiter(void 0, void 0, void 0, function* () {
14
+ const query = (logTag, store, cache, { updateQueryStateAndEntities }, queryKey, cacheKey, params) => __awaiter(void 0, void 0, void 0, function* () {
15
15
  var _a;
16
16
  const logsEnabled = cache.options.logsEnabled;
17
17
  const cacheStateSelector = cache.cacheStateSelector;
@@ -25,7 +25,7 @@ const query = (logTag, returnResult, store, cache, { updateQueryStateAndEntities
25
25
  params,
26
26
  cacheKey,
27
27
  });
28
- return returnResult ? { cancelled: true } : undefined;
28
+ return CANCELLED_RESULT;
29
29
  }
30
30
  store.dispatch(updateQueryStateAndEntities(queryKey, cacheKey, {
31
31
  loading: true,
@@ -43,7 +43,7 @@ const query = (logTag, returnResult, store, cache, { updateQueryStateAndEntities
43
43
  error: error,
44
44
  loading: false,
45
45
  }));
46
- return returnResult ? { error } : undefined;
46
+ return { error };
47
47
  }
48
48
  const newState = {
49
49
  error: undefined,
@@ -53,19 +53,18 @@ const query = (logTag, returnResult, store, cache, { updateQueryStateAndEntities
53
53
  : mergeResults
54
54
  ? mergeResults(
55
55
  // @ts-expect-error fix later
56
- (_a = cacheStateSelector(store.getState()).queries[queryKey][cacheKey]) === null || _a === void 0 ? void 0 : _a.result, response, params)
56
+ (_a = cacheStateSelector(store.getState()).queries[queryKey][cacheKey]) === null || _a === void 0 ? void 0 : _a.result, response, params, store)
57
57
  : response.result,
58
58
  };
59
59
  store.dispatch(updateQueryStateAndEntities(queryKey, cacheKey, newState, response));
60
- // @ts-expect-error fix types
61
- return returnResult
62
- ? {
63
- result: cacheResultSelector
64
- ? cacheResultSelector(cacheStateSelector(store.getState()),
65
- // @ts-expect-error fix types
66
- params)
67
- : newState === null || newState === void 0 ? void 0 : newState.result,
68
- }
69
- : undefined;
60
+ return {
61
+ // @ts-expect-error fix types
62
+ result: cacheResultSelector
63
+ ? cacheResultSelector(cacheStateSelector(store.getState()),
64
+ // @ts-expect-error fix types
65
+ params)
66
+ : newState === null || newState === void 0 ? void 0 : newState.result,
67
+ };
70
68
  });
71
69
  exports.query = query;
70
+ const CANCELLED_RESULT = Object.freeze({ cancelled: true });
package/dist/types.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { Store } from 'redux';
1
2
  import type { ReduxCacheState } from './reducer';
2
3
  export type Key = string | number | symbol;
3
4
  export type Dict<T> = Record<Key, T>;
@@ -73,8 +74,8 @@ export type QueryInfo<T extends Typenames, P, R, S> = {
73
74
  * Needed when query result may already be in the cache, e.g. for single entity query by id.
74
75
  * */
75
76
  resultSelector?: (state: S, params: P) => R | undefined;
76
- /** Merges results before saving to the store. */
77
- mergeResults?: (oldResult: R | undefined, response: QueryResponse<T, R>, params: P | undefined) => R;
77
+ /** Merges results before saving to the store. Default implementation is using the latest result. */
78
+ mergeResults?: (oldResult: R | undefined, response: QueryResponse<T, R>, params: P | undefined, store: Store) => R;
78
79
  /**
79
80
  * Cache key is used for storing the query state and for performing a fetch when it changes. Queries with the same cache key share their state.
80
81
  * Default implementation uses `JSON.stringify` or `String()` depending on type.
@@ -86,7 +87,7 @@ export type UseQueryOptions<T extends Typenames, QP, QR, MR, QK extends keyof (Q
86
87
  query: QK;
87
88
  params: QK extends keyof (QP | QR) ? QP[QK] : never;
88
89
  skip?: boolean;
89
- } & Pick<QK extends keyof (QP | QR) ? QueryInfo<T, QP[QK], QR[QK], ReduxCacheState<T, QR, MR>> : never, 'cachePolicy' | 'mergeResults' | 'getCacheKey'>;
90
+ } & Pick<QK extends keyof (QP | QR) ? QueryInfo<T, QP[QK], QR[QK], ReduxCacheState<T, QR, MR>> : never, 'cachePolicy'>;
90
91
  /**
91
92
  * @param cache-first for each params key fetch is not called if cache exists.
92
93
  * @param cache-and-fetch for each params key result is taken from cache and fetch is called.
@@ -3,4 +3,4 @@ import { ActionMap } from './createActions';
3
3
  import { Cache, Key, QueryMutationState, Typenames } from './types';
4
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, MR>, "updateMutationStateAndEntities">, options: {
5
5
  mutation: MK;
6
- }, abortControllers: WeakMap<Store, Record<Key, AbortController>>) => readonly [(params: MK extends keyof MP & keyof MR ? MP[MK] : never) => Promise<void>, QueryMutationState<MK extends keyof MP & keyof MR ? MP[MK] : never>, () => boolean];
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>>, QueryMutationState<MK extends keyof MP & keyof MR ? MP[MK] : never>, () => boolean];
@@ -32,7 +32,7 @@ const useMutation = (cache, actions, options, abortControllers) => {
32
32
  },
33
33
  // mutate
34
34
  (params) => __awaiter(void 0, void 0, void 0, function* () {
35
- yield (0, mutate_1.mutate)('useMutation.mutate', false, store, cache, actions, mutationKey, params, abortControllers);
35
+ return yield (0, mutate_1.mutate)('useMutation.mutate', store, cache, actions, mutationKey, params, abortControllers);
36
36
  }),
37
37
  // abort
38
38
  () => {
@@ -1,3 +1,3 @@
1
1
  import { ActionMap } from './createActions';
2
2
  import { Cache, QueryMutationState, Typenames, UseQueryOptions } from './types';
3
- export declare const useQuery: <N extends string, T extends Typenames, QP, QR, MP, MR, QK extends keyof QP | keyof QR>(cache: Cache<N, T, QP, QR, MP, MR>, actions: Pick<ActionMap<N, T, QR, MR>, "updateQueryStateAndEntities">, options: UseQueryOptions<T, QP, QR, MR, QK>) => readonly [QueryMutationState<QK extends keyof QP & keyof QR ? QR[QK] : never>, () => Promise<void>];
3
+ export declare const useQuery: <N extends string, T extends Typenames, QP, QR, MP, MR, QK extends keyof QP | keyof QR>(cache: Cache<N, T, QP, QR, MP, MR>, actions: Pick<ActionMap<N, T, QR, MR>, "updateQueryStateAndEntities">, options: UseQueryOptions<T, QP, QR, MR, QK>) => readonly [QueryMutationState<QK extends keyof QP & keyof QR ? QR[QK] : never>, () => Promise<import("./types").QueryResult<QK extends infer T_1 ? T_1 extends QK ? T_1 extends keyof QP & keyof QR ? QR[T_1] : never : never : never>>];
package/dist/useQuery.js CHANGED
@@ -16,8 +16,9 @@ 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, cachePolicy = (_a = cache.queries[queryKey].cachePolicy) !== null && _a !== void 0 ? _a : 'cache-first', getCacheKey = (_b = cache.queries[queryKey].getCacheKey) !== null && _b !== void 0 ? _b : (utilsAndConstants_1.defaultGetCacheKey), } = options;
19
+ const { query: queryKey, skip, params, cachePolicy = (_a = cache.queries[queryKey].cachePolicy) !== null && _a !== void 0 ? _a : 'cache-first', } = options;
20
20
  const logsEnabled = cache.options.logsEnabled;
21
+ const getCacheKey = (_b = cache.queries[queryKey].getCacheKey) !== null && _b !== void 0 ? _b : (utilsAndConstants_1.defaultGetCacheKey);
21
22
  const cacheResultSelector = cache.queries[queryKey].resultSelector;
22
23
  const cacheStateSelector = cache.cacheStateSelector;
23
24
  const store = (0, react_redux_1.useStore)();
@@ -34,7 +35,7 @@ const useQuery = (cache, actions, options) => {
34
35
  const resultFromSelector = (resultSelector && (0, react_redux_1.useSelector)(resultSelector));
35
36
  const hasResultFromSelector = resultFromSelector !== undefined;
36
37
  const fetch = (0, react_1.useCallback)(() => __awaiter(void 0, void 0, void 0, function* () {
37
- yield (0, query_1.query)('useQuery.fetch', false, store, cache, actions, queryKey, cacheKey, params);
38
+ return yield (0, query_1.query)('useQuery.fetch', store, cache, actions, queryKey, cacheKey, params);
38
39
  // eslint-disable-next-line react-hooks/exhaustive-deps
39
40
  }), [store, queryKey, cacheKey]);
40
41
  const queryStateFromSelector = (_c = (0, react_redux_1.useSelector)((state) => {
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.2.0",
5
+ "version": "0.3.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",