react-redux-cache 0.10.0 → 0.11.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
@@ -41,13 +41,12 @@ Examples of states, generated by cache reducer from `/example` project:
41
41
  queries: {
42
42
  // each query has its own map of query states, stored by cache key, which is generated from query params
43
43
  getUser: {
44
- "2": {loading: false, result: 2, params: 2, expiresAt: 1727217298025},
44
+ "2": {result: 2, params: 2, expiresAt: 1727217298025},
45
45
  "3": {loading: true, params: 3}
46
46
  },
47
47
  getUsers: {
48
48
  // example of paginated state under custom cache key
49
49
  "all-pages": {
50
- loading: false,
51
50
  result: {items: [0,1,2], page: 1},
52
51
  params: {page: 1}
53
52
  }
@@ -56,7 +55,6 @@ Examples of states, generated by cache reducer from `/example` project:
56
55
  mutations: {
57
56
  // each mutation has its own state as well
58
57
  updateUser: {
59
- loading: false,
60
58
  result: 1,
61
59
  params: {id: 1, name: "User 1 *"}
62
60
  }
@@ -78,7 +76,6 @@ Examples of states, generated by cache reducer from `/example` project:
78
76
  // each query has its own map of query states, stored by cache key, which is generated from query params
79
77
  getUser: {
80
78
  "2": {
81
- loading: false,
82
79
  result: {id: 2, bank: {id: "2", name: "Bank 2"}, name: "User 2"},
83
80
  params: 2,
84
81
  expiresAt: 1727217298025
@@ -88,7 +85,6 @@ Examples of states, generated by cache reducer from `/example` project:
88
85
  getUsers: {
89
86
  // example of paginated state under custom cache key
90
87
  "all-pages": {
91
- loading: false,
92
88
  result: {
93
89
  items: [
94
90
  {id: 0, bank: {id: "0", name: "Bank 0"}, name: "User 0 *"},
@@ -104,7 +100,6 @@ Examples of states, generated by cache reducer from `/example` project:
104
100
  mutations: {
105
101
  // each mutation has its own state as well
106
102
  updateUser: {
107
- loading: false,
108
103
  result: {id: 1, bank: {id: "1", name: "Bank 1"}, name: "User 1 *"},
109
104
  params: {id: 1, name: "User 1 *"}
110
105
  }
@@ -53,12 +53,12 @@ const withTypenames = () => {
53
53
  const selectQueryState = (state, query, cacheKey) => {
54
54
  var _a;
55
55
  // @ts-expect-error fix later
56
- return (_a = cache.cacheStateSelector(state).queries[query][cacheKey]) !== null && _a !== void 0 ? _a : utilsAndConstants_1.DEFAULT_QUERY_MUTATION_STATE;
56
+ return (_a = cache.cacheStateSelector(state).queries[query][cacheKey]) !== null && _a !== void 0 ? _a : utilsAndConstants_1.EMPTY_OBJECT;
57
57
  };
58
58
  const selectMutationState = (state, mutation) => {
59
59
  var _a;
60
60
  // @ts-expect-error fix later
61
- return (_a = cache.cacheStateSelector(state).mutations[mutation]) !== null && _a !== void 0 ? _a : utilsAndConstants_1.DEFAULT_QUERY_MUTATION_STATE;
61
+ return (_a = cache.cacheStateSelector(state).mutations[mutation]) !== null && _a !== void 0 ? _a : utilsAndConstants_1.EMPTY_OBJECT;
62
62
  };
63
63
  const actions = (0, createActions_1.createActions)(cache.name);
64
64
  return {
@@ -76,7 +76,8 @@ const withTypenames = () => {
76
76
  },
77
77
  /** Selects query loading state. */
78
78
  selectQueryLoading: (state, query, cacheKey) => {
79
- return selectQueryState(state, query, cacheKey).loading;
79
+ var _a;
80
+ return (_a = selectQueryState(state, query, cacheKey).loading) !== null && _a !== void 0 ? _a : false;
80
81
  },
81
82
  /** Selects query latest error. */
82
83
  selectQueryError: (state, query, cacheKey) => {
@@ -98,7 +99,8 @@ const withTypenames = () => {
98
99
  },
99
100
  /** Selects mutation loading state. */
100
101
  selectMutationLoading: (state, mutation) => {
101
- return selectMutationState(state, mutation).loading;
102
+ var _a;
103
+ return (_a = selectMutationState(state, mutation).loading) !== null && _a !== void 0 ? _a : false;
102
104
  },
103
105
  /** Selects mutation latest error. */
104
106
  selectMutationError: (state, mutation) => {
@@ -1,4 +1,15 @@
1
1
  "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
2
13
  Object.defineProperty(exports, "__esModule", { value: true });
3
14
  exports.createCacheReducer = void 0;
4
15
  const utilsAndConstants_1 = require("./utilsAndConstants");
@@ -23,22 +34,25 @@ const createCacheReducer = (actions, queryKeys, cacheOptions) => {
23
34
  });
24
35
  const deepEqual = cacheOptions.deepComparisonEnabled ? utilsAndConstants_1.optionalUtils.deepEqual : undefined;
25
36
  return (state = initialState, action) => {
26
- var _a, _b;
27
37
  switch (action.type) {
28
38
  case actions.updateQueryStateAndEntities.type: {
29
39
  const { queryKey, queryCacheKey, state: queryState, entityChanges, } = action;
30
- const oldQueryState = (_a = state.queries[queryKey][queryCacheKey]) !== null && _a !== void 0 ? _a : utilsAndConstants_1.DEFAULT_QUERY_MUTATION_STATE;
40
+ const oldQueryState = state.queries[queryKey][queryCacheKey];
31
41
  let newQueryState = queryState && Object.assign(Object.assign({}, oldQueryState), queryState);
32
- // remove undefined optional fields
33
42
  if (newQueryState) {
43
+ // remove undefined optional fields
34
44
  for (const key of optionalQueryKeys) {
35
45
  if (key in newQueryState && newQueryState[key] === undefined) {
36
46
  delete newQueryState[key];
37
47
  }
38
48
  }
39
- }
40
- if (deepEqual === null || deepEqual === void 0 ? void 0 : deepEqual(oldQueryState, newQueryState)) {
41
- newQueryState = undefined;
49
+ if ('loading' in newQueryState && !newQueryState.loading) {
50
+ delete newQueryState.loading;
51
+ }
52
+ // skip if new state deep equals to the old state
53
+ if (deepEqual === null || deepEqual === void 0 ? void 0 : deepEqual(oldQueryState !== null && oldQueryState !== void 0 ? oldQueryState : utilsAndConstants_1.EMPTY_OBJECT, newQueryState)) {
54
+ newQueryState = undefined;
55
+ }
42
56
  }
43
57
  const newEntities = entityChanges && (0, utilsAndConstants_1.applyEntityChanges)(state.entities, entityChanges, cacheOptions);
44
58
  let newState;
@@ -47,25 +61,37 @@ const createCacheReducer = (actions, queryKeys, cacheOptions) => {
47
61
  newState.entities = newEntities;
48
62
  }
49
63
  if (newQueryState) {
50
- newState !== null && newState !== void 0 ? newState : (newState = Object.assign({}, state));
51
- newState.queries = Object.assign(Object.assign({}, state.queries), { [queryKey]: Object.assign(Object.assign({}, state.queries[queryKey]), { [queryCacheKey]: newQueryState }) });
64
+ if (!(0, utilsAndConstants_1.isEmptyObject)(newQueryState)) {
65
+ newState !== null && newState !== void 0 ? newState : (newState = Object.assign({}, state));
66
+ newState.queries = Object.assign(Object.assign({}, state.queries), { [queryKey]: Object.assign(Object.assign({}, state.queries[queryKey]), { [queryCacheKey]: newQueryState }) });
67
+ }
68
+ else if (oldQueryState !== undefined) {
69
+ // empty states are removed
70
+ const _a = state.queries[queryKey], _b = queryCacheKey, _ = _a[_b], withoutCacheKey = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
71
+ newState !== null && newState !== void 0 ? newState : (newState = Object.assign({}, state));
72
+ newState.queries = Object.assign(Object.assign({}, state.queries), { [queryKey]: withoutCacheKey });
73
+ }
52
74
  }
53
75
  return newState !== null && newState !== void 0 ? newState : state;
54
76
  }
55
77
  case actions.updateMutationStateAndEntities.type: {
56
78
  const { mutationKey, state: mutationState, entityChanges, } = action;
57
- const oldMutationState = (_b = state.mutations[mutationKey]) !== null && _b !== void 0 ? _b : utilsAndConstants_1.DEFAULT_QUERY_MUTATION_STATE;
79
+ const oldMutationState = state.mutations[mutationKey];
58
80
  let newMutationState = mutationState && Object.assign(Object.assign({}, oldMutationState), mutationState);
59
- // remove undefined optional fields
60
81
  if (newMutationState) {
82
+ // remove optional fields with default values
61
83
  for (const key of optionalMutationKeys) {
62
84
  if (key in newMutationState && newMutationState[key] === undefined) {
63
85
  delete newMutationState[key];
64
86
  }
65
87
  }
66
- }
67
- if (deepEqual === null || deepEqual === void 0 ? void 0 : deepEqual(oldMutationState, newMutationState)) {
68
- newMutationState = undefined;
88
+ if ('loading' in newMutationState && !newMutationState.loading) {
89
+ delete newMutationState.loading;
90
+ }
91
+ // skip if new state deep equals to the old state
92
+ if (deepEqual === null || deepEqual === void 0 ? void 0 : deepEqual(oldMutationState !== null && oldMutationState !== void 0 ? oldMutationState : utilsAndConstants_1.EMPTY_OBJECT, newMutationState)) {
93
+ newMutationState = undefined;
94
+ }
69
95
  }
70
96
  const newEntities = entityChanges && (0, utilsAndConstants_1.applyEntityChanges)(state.entities, entityChanges, cacheOptions);
71
97
  let newState;
@@ -74,8 +100,16 @@ const createCacheReducer = (actions, queryKeys, cacheOptions) => {
74
100
  newState.entities = newEntities;
75
101
  }
76
102
  if (newMutationState) {
77
- newState !== null && newState !== void 0 ? newState : (newState = Object.assign({}, state));
78
- newState.mutations = Object.assign(Object.assign({}, state.mutations), { [mutationKey]: newMutationState });
103
+ if (!(0, utilsAndConstants_1.isEmptyObject)(newMutationState)) {
104
+ newState !== null && newState !== void 0 ? newState : (newState = Object.assign({}, state));
105
+ newState.mutations = Object.assign(Object.assign({}, state.mutations), { [mutationKey]: newMutationState });
106
+ }
107
+ else if (oldMutationState !== undefined) {
108
+ // empty states are removed
109
+ const _c = state.mutations, _d = mutationKey, _ = _c[_d], withoutMutationKey = __rest(_c, [typeof _d === "symbol" ? _d : _d + ""]);
110
+ newState !== null && newState !== void 0 ? newState : (newState = Object.assign({}, state));
111
+ newState.mutations = withoutMutationKey;
112
+ }
79
113
  }
80
114
  return newState !== null && newState !== void 0 ? newState : state;
81
115
  }
@@ -86,7 +120,7 @@ const createCacheReducer = (actions, queryKeys, cacheOptions) => {
86
120
  }
87
121
  case actions.invalidateQuery.type: {
88
122
  const { queries: queriesToInvalidate } = action;
89
- if (!queriesToInvalidate.length) {
123
+ if (queriesToInvalidate.length === 0) {
90
124
  return state;
91
125
  }
92
126
  const now = Date.now();
@@ -125,13 +159,13 @@ const createCacheReducer = (actions, queryKeys, cacheOptions) => {
125
159
  }
126
160
  }
127
161
  }
128
- return !newQueries
162
+ return newQueries === undefined
129
163
  ? state
130
164
  : Object.assign(Object.assign({}, state), { queries: newQueries });
131
165
  }
132
166
  case actions.clearQueryState.type: {
133
167
  const { queries: queriesToClear } = action;
134
- if (!queriesToClear.length) {
168
+ if (queriesToClear.length === 0) {
135
169
  return state;
136
170
  }
137
171
  let newQueries = undefined;
@@ -151,13 +185,13 @@ const createCacheReducer = (actions, queryKeys, cacheOptions) => {
151
185
  newQueries[queryKey] = utilsAndConstants_1.EMPTY_OBJECT;
152
186
  }
153
187
  }
154
- return !newQueries
188
+ return newQueries === undefined
155
189
  ? state
156
190
  : Object.assign(Object.assign({}, state), { queries: newQueries });
157
191
  }
158
192
  case actions.clearMutationState.type: {
159
193
  const { mutationKeys } = action;
160
- if (!mutationKeys.length) {
194
+ if (mutationKeys.length === 0) {
161
195
  return state;
162
196
  }
163
197
  let newMutations = undefined;
@@ -167,7 +201,7 @@ const createCacheReducer = (actions, queryKeys, cacheOptions) => {
167
201
  delete newMutations[mutation];
168
202
  }
169
203
  }
170
- return !newMutations
204
+ return newMutations === undefined
171
205
  ? state
172
206
  : Object.assign(Object.assign({}, state), { mutations: newMutations });
173
207
  }
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { createCache, withTypenames } from './createCache';
2
2
  export type { ReduxCacheState } from './createCacheReducer';
3
3
  export * from './types';
4
- export { defaultGetCacheKey, DEFAULT_QUERY_MUTATION_STATE as defaultQueryMutationState, } from './utilsAndConstants';
4
+ export { defaultGetCacheKey } from './utilsAndConstants';
package/dist/index.js CHANGED
@@ -14,17 +14,15 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.defaultQueryMutationState = exports.defaultGetCacheKey = exports.withTypenames = exports.createCache = void 0;
17
+ exports.defaultGetCacheKey = exports.withTypenames = exports.createCache = void 0;
18
18
  var createCache_1 = require("./createCache");
19
19
  Object.defineProperty(exports, "createCache", { enumerable: true, get: function () { return createCache_1.createCache; } });
20
20
  Object.defineProperty(exports, "withTypenames", { enumerable: true, get: function () { return createCache_1.withTypenames; } });
21
21
  __exportStar(require("./types"), exports);
22
22
  var utilsAndConstants_1 = require("./utilsAndConstants");
23
23
  Object.defineProperty(exports, "defaultGetCacheKey", { enumerable: true, get: function () { return utilsAndConstants_1.defaultGetCacheKey; } });
24
- Object.defineProperty(exports, "defaultQueryMutationState", { enumerable: true, get: function () { return utilsAndConstants_1.DEFAULT_QUERY_MUTATION_STATE; } });
25
24
  // Backlog
26
25
  // ! high (1.0.0)
27
- // remove undefined optional fields & emtpy states. remove mutation state when it finished without errors
28
26
  // remove cachePolicy? make skip/enabled a function? skip -> enabled/shouldFetch?
29
27
  // generate full api docs
30
28
  // ! medium
package/dist/types.d.ts CHANGED
@@ -145,8 +145,8 @@ export type MutationResult<R> = {
145
145
  result?: R;
146
146
  };
147
147
  export type MutationState<P, R> = {
148
- /** `true` when query or mutation is currently in progress. */
149
- loading: boolean;
148
+ /** `true` when fetch is currently in progress. */
149
+ loading?: boolean;
150
150
  /** Result of the latest successfull response. */
151
151
  result?: R;
152
152
  /** Error of the latest response. */
@@ -53,7 +53,7 @@ const useMutation = (cache, actions, options, abortControllers) => {
53
53
  // eslint-disable-next-line react-hooks/exhaustive-deps
54
54
  }, [mutationKey, store]);
55
55
  // @ts-expect-error fix later
56
- const mutationState = (_a = (0, react_redux_1.useSelector)(mutationStateSelector)) !== null && _a !== void 0 ? _a : utilsAndConstants_1.DEFAULT_QUERY_MUTATION_STATE;
56
+ const mutationState = (_a = (0, react_redux_1.useSelector)(mutationStateSelector)) !== null && _a !== void 0 ? _a : utilsAndConstants_1.EMPTY_OBJECT;
57
57
  cache.options.logsEnabled &&
58
58
  (0, utilsAndConstants_1.log)('useMutation', {
59
59
  options,
package/dist/useQuery.js CHANGED
@@ -39,7 +39,7 @@ const useQuery = (cache, actions, options) => {
39
39
  const queryState = (_c = (0, react_redux_1.useSelector)((state) => {
40
40
  const queryState = cacheStateSelector(state).queries[queryKey][cacheKey];
41
41
  return queryState; // TODO proper type
42
- }, (useQueryStateComparer))) !== null && _c !== void 0 ? _c : utilsAndConstants_1.DEFAULT_QUERY_MUTATION_STATE;
42
+ }, (useQueryStateComparer))) !== null && _c !== void 0 ? _c : utilsAndConstants_1.EMPTY_OBJECT;
43
43
  (0, react_1.useEffect)(() => {
44
44
  if (skip) {
45
45
  logsEnabled && (0, utilsAndConstants_1.log)('useQuery.useEffect skip fetch', { skip, cacheKey });
@@ -4,11 +4,9 @@ export declare const optionalUtils: {
4
4
  deepEqual?: (a: any, b: any) => boolean;
5
5
  };
6
6
  export declare const IS_DEV: boolean;
7
- export declare const DEFAULT_QUERY_MUTATION_STATE: Readonly<{
8
- loading: false;
9
- }>;
10
7
  export declare const EMPTY_OBJECT: Readonly<{}>;
11
8
  export declare const EMPTY_ARRAY: readonly never[];
12
9
  export declare const defaultGetCacheKey: <P = unknown>(params: P) => Key;
13
10
  export declare const log: (tag: string, data?: unknown) => void;
14
11
  export declare const applyEntityChanges: <T extends Typenames>(entities: EntitiesMap<T>, changes: EntityChanges<T>, options: CacheOptions) => EntitiesMap<T> | undefined;
12
+ export declare const isEmptyObject: (o: object) => boolean;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.applyEntityChanges = exports.log = exports.defaultGetCacheKey = exports.EMPTY_ARRAY = exports.EMPTY_OBJECT = exports.DEFAULT_QUERY_MUTATION_STATE = exports.IS_DEV = exports.optionalUtils = exports.PACKAGE_SHORT_NAME = void 0;
3
+ exports.isEmptyObject = exports.applyEntityChanges = exports.log = exports.defaultGetCacheKey = exports.EMPTY_ARRAY = exports.EMPTY_OBJECT = exports.IS_DEV = exports.optionalUtils = exports.PACKAGE_SHORT_NAME = void 0;
4
4
  exports.PACKAGE_SHORT_NAME = 'rrc';
5
5
  exports.optionalUtils = {
6
6
  deepEqual: undefined,
@@ -20,7 +20,6 @@ exports.IS_DEV = (() => {
20
20
  return process.env.NODE_ENV === 'development';
21
21
  }
22
22
  })();
23
- exports.DEFAULT_QUERY_MUTATION_STATE = Object.freeze({ loading: false });
24
23
  exports.EMPTY_OBJECT = Object.freeze({});
25
24
  exports.EMPTY_ARRAY = Object.freeze([]);
26
25
  const defaultGetCacheKey = (params) => {
@@ -124,3 +123,10 @@ const applyEntityChanges = (entities, changes, options) => {
124
123
  return result;
125
124
  };
126
125
  exports.applyEntityChanges = applyEntityChanges;
126
+ const isEmptyObject = (o) => {
127
+ for (const _ in o) {
128
+ return false;
129
+ }
130
+ return true;
131
+ };
132
+ exports.isEmptyObject = isEmptyObject;
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.10.0",
5
+ "version": "0.11.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",