react-redux-cache 0.8.0 → 0.8.2

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.
@@ -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" | "defaults">) => {
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" | "defaults">) => {
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.defaults) !== null && _g !== void 0 ? _g : (partialCache.defaults = {});
38
+ (_h = (_o = partialCache.defaults).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;
package/dist/index.js CHANGED
@@ -25,33 +25,21 @@ Object.defineProperty(exports, "defaultQueryMutationState", { enumerable: true,
25
25
  // Backlog
26
26
  // ! high (1.0.0)
27
27
  // rca -> vite
28
- // defaults
28
+ // remove undefined optional fields & emtpy states. remove mutation state when it finished without errors
29
29
  // remove cachePolicy? make skip/enabled a function? skip -> enabled/shouldFetch?
30
- // remove mergeResults? bcs store is passed to queries/mutations
31
- // remove undefined optional fields & emtpy states
32
30
  // generate full api docs
33
31
  // ! medium
34
32
  // optimistic response
35
33
  // make query key / cache key difference more clear in the docs
36
34
  // check type of function arguments in dev
37
- // allow multiple mutation with same keys?
38
- // return back deserialize selector?
39
- // selector for entities by typename
40
- // callback option on error / success?
41
- // refetch queries on mutation success
42
- // remove query/mutation state when it finished without errors
43
- // deep equal entities while merging state
44
- // make error type generic
45
35
  // ! low
36
+ // make error type generic
37
+ // allow multiple mutation with same keys?
46
38
  // custom useStore & useSelector to support multiple stores?
47
- // access to currently loading queries and mutations?
48
- // add params to the state?
39
+ // easy access to all currently loading queries and mutations?
49
40
  // cancellation to queries
50
- // if mutation & query alrady loading - make options: last, throttle, debounce, parallel?
51
- // add time-to-live option, and/or time-to-refresh
41
+ // if mutation & query already loading - make options: last, throttle, debounce, parallel?
52
42
  // add refresh interval for queries that are mounted
53
- // replace try/catch with returned error
54
- // support any store, not only redux
55
43
  // readonly types?
56
44
  // proper types, remove as, any, todo
57
45
  // add number of retries param?
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;
16
+ var { updateQueryStateAndEntities, } = _a;
17
+ if (secondsToLive === void 0) { secondsToLive = (_b = cache.queries[queryKey].secondsToLive) !== null && _b !== void 0 ? _b : cache.defaults.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];
@@ -61,11 +67,11 @@ const query = (logTag, store, cache, { updateQueryStateAndEntities, }, queryKey,
61
67
  const newState = {
62
68
  error: undefined,
63
69
  loading: false,
64
- expiresAt: (_a = response.expiresAt) !== null && _a !== void 0 ? _a : (secondsToLive != null ? Date.now() + secondsToLive * 1000 : undefined),
70
+ expiresAt: (_c = response.expiresAt) !== null && _c !== void 0 ? _c : (secondsToLive != null ? Date.now() + secondsToLive * 1000 : undefined),
65
71
  result: mergeResults
66
72
  ? mergeResults(
67
73
  // @ts-expect-error fix later
68
- (_b = cacheStateSelector(store.getState()).queries[queryKey][cacheKey]) === null || _b === void 0 ? void 0 : _b.result, response, params, store)
74
+ (_d = cacheStateSelector(store.getState()).queries[queryKey][cacheKey]) === null || _d === void 0 ? void 0 : _d.result, response, params, store)
69
75
  : response.result,
70
76
  };
71
77
  store.dispatch(updateQueryStateAndEntities(queryKey, cacheKey, newState, response));
package/dist/types.d.ts CHANGED
@@ -27,10 +27,24 @@ 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.
31
+ * @default { cachePolicy: 'cache-first', sedondsToLive: undefined } */
32
+ defaults: Defaults;
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 Defaults = {
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
+ };
34
48
  export type CacheOptions = {
35
49
  /**
36
50
  * Enables validation of package function arguments. Recommened to enable in dev/testing mode.
@@ -64,15 +78,8 @@ export type Query<P, T extends Typenames = Typenames, R = unknown> = (
64
78
  params: P,
65
79
  /** Redux store */
66
80
  store: Store) => Promise<QueryResponse<T, R>>;
67
- export type QueryInfo<T extends Typenames, P, R> = {
81
+ export type QueryInfo<T extends Typenames, P, R> = Partial<Defaults> & {
68
82
  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
83
  /** Merges results before saving to the store. Default implementation is using the latest result. */
77
84
  mergeResults?: (oldResult: R | undefined, response: QueryResponse<T, R>, params: P | undefined, store: Store) => R;
78
85
  /**
@@ -101,10 +108,6 @@ export type QueryOptions<T extends Typenames, QP, QR, QK extends keyof (QP & QR)
101
108
  /** If set to true, query will run only if it is expired or result not yet cached. */
102
109
  onlyIfExpired?: boolean;
103
110
  };
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
111
  export type QueryCachePolicy = 'cache-first' | 'cache-and-fetch';
109
112
  export type QueryResponse<T extends Typenames, R> = EntityChanges<T> & {
110
113
  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.defaults.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;
@@ -8,6 +8,7 @@ export declare const DEFAULT_QUERY_MUTATION_STATE: Readonly<{
8
8
  loading: false;
9
9
  }>;
10
10
  export declare const EMPTY_OBJECT: Readonly<{}>;
11
+ export declare const EMPTY_ARRAY: readonly never[];
11
12
  export declare const defaultGetCacheKey: <P = unknown>(params: P) => Key;
12
13
  export declare const log: (tag: string, data?: unknown) => void;
13
14
  export declare const applyEntityChanges: <T extends Typenames>(entities: EntitiesMap<T>, changes: EntityChanges<T>, options: CacheOptions) => EntitiesMap<T> | undefined;
@@ -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_OBJECT = exports.DEFAULT_QUERY_MUTATION_STATE = exports.IS_DEV = exports.optionalUtils = exports.PACKAGE_SHORT_NAME = void 0;
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;
4
4
  exports.PACKAGE_SHORT_NAME = 'rrc';
5
5
  exports.optionalUtils = {
6
6
  deepEqual: undefined,
@@ -22,6 +22,7 @@ exports.IS_DEV = (() => {
22
22
  })();
23
23
  exports.DEFAULT_QUERY_MUTATION_STATE = Object.freeze({ loading: false });
24
24
  exports.EMPTY_OBJECT = Object.freeze({});
25
+ exports.EMPTY_ARRAY = Object.freeze([]);
25
26
  const defaultGetCacheKey = (params) => {
26
27
  switch (typeof params) {
27
28
  case 'string':
@@ -40,11 +41,8 @@ const log = (tag, data) => {
40
41
  exports.log = log;
41
42
  const applyEntityChanges = (entities, changes, options) => {
42
43
  var _a, _b, _c, _d;
43
- if (options.validateFunctionArguments) {
44
- // check for merge and entities both set
45
- if (changes.merge && changes.entities) {
46
- throw new Error('Merge and entities should not be both set');
47
- }
44
+ if (changes.merge && changes.entities) {
45
+ console.warn('react-redux-cache.applyEntityChanges: merge and entities should not be both set');
48
46
  }
49
47
  const { merge = changes.entities, replace, remove } = changes;
50
48
  if (!merge && !replace && !remove) {
@@ -52,11 +50,12 @@ const applyEntityChanges = (entities, changes, options) => {
52
50
  }
53
51
  const deepEqual = options.deepComparisonEnabled ? exports.optionalUtils.deepEqual : undefined;
54
52
  let result;
53
+ // TODO refactor to remove this Set
55
54
  const typenames = new Set([
56
- ...(changes.entities ? Object.keys(changes.entities) : []),
57
- ...(changes.merge ? Object.keys(changes.merge) : []),
58
- ...(changes.remove ? Object.keys(changes.remove) : []),
59
- ...(changes.replace ? Object.keys(changes.replace) : []),
55
+ ...(changes.entities ? Object.keys(changes.entities) : exports.EMPTY_ARRAY),
56
+ ...(changes.merge ? Object.keys(changes.merge) : exports.EMPTY_ARRAY),
57
+ ...(changes.remove ? Object.keys(changes.remove) : exports.EMPTY_ARRAY),
58
+ ...(changes.replace ? Object.keys(changes.replace) : exports.EMPTY_ARRAY),
60
59
  ]);
61
60
  for (const typename of typenames) {
62
61
  const entitiesToMerge = merge === null || merge === void 0 ? void 0 : merge[typename];
@@ -74,7 +73,8 @@ const applyEntityChanges = (entities, changes, options) => {
74
73
  entitiesToRemove === null || entitiesToRemove === void 0 ? void 0 : entitiesToRemove.forEach((id) => idsSet.add(String(id))); // String() because Object.keys always returns strings
75
74
  const totalKeysInResponse = ((_a = mergeIds === null || mergeIds === void 0 ? void 0 : mergeIds.length) !== null && _a !== void 0 ? _a : 0) + ((_b = replaceIds === null || replaceIds === void 0 ? void 0 : replaceIds.length) !== null && _b !== void 0 ? _b : 0) + ((_c = entitiesToRemove === null || entitiesToRemove === void 0 ? void 0 : entitiesToRemove.length) !== null && _c !== void 0 ? _c : 0);
76
75
  if (totalKeysInResponse !== 0 && idsSet.size !== totalKeysInResponse) {
77
- throw new Error('Merge, replace and remove changes have intersections for: ' + typename);
76
+ console.warn('react-redux-cache.applyEntityChanges: merge, replace and remove changes have intersections for: ' +
77
+ typename);
78
78
  }
79
79
  }
80
80
  const oldEntities = (_d = entities[typename]) !== null && _d !== void 0 ? _d : exports.EMPTY_OBJECT;
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.0",
5
+ "version": "0.8.2",
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",