react-redux-cache 0.7.1 → 0.8.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
@@ -139,23 +139,26 @@ Examples of states, generated by cache reducer from `/example` project:
139
139
  npm add react-redux-cache react redux react-redux fast-deep-equal
140
140
  ```
141
141
  ### Initialization
142
- The only function that needs to be imported is `createCache`, which creates fully typed reducer, hooks, actions, selectors and utils to be used in the app. You can create as many caches as needed, but keep in mind that normalization is not shared between them.
143
- All typenames, queries and mutations should be passed while initializing the cache for proper typing.
142
+ The only function that needs to be imported is either `withTypenames`, which is needed for normalization, or directly `createCache` if it is not needed. `createCache` creates fully typed reducer, hooks, actions, selectors and utils to be used in the app. You can create as many caches as needed, but keep in mind that normalization is not shared between them.
143
+ All queries and mutations should be passed while initializing the cache for proper typing.
144
144
  #### cache.ts
145
145
  ```typescript
146
+ // Mapping of all typenames to their entity types, which is needed for proper normalization typing.
147
+ // Not needed if normalization is not used.
148
+ export type CacheTypenames = {
149
+ users: User, // here `users` entities will have type `User`
150
+ banks: Bank,
151
+ }
152
+
146
153
  export const {
147
154
  cache,
148
155
  reducer,
149
156
  hooks: {useClient, useMutation, useQuery},
150
- } = createCache({
157
+ // `withTypenames` is only needed to provide proper Typenames for normalization - limitation of Typescript.
158
+ // `createCache` can be imported directly without `withTypenames`.
159
+ } = withTypenames<CacheTypenames>().createCache({
151
160
  // Used as prefix for actions and in default cacheStateSelector for selecting cache state from redux state.
152
161
  name: 'cache',
153
- // Mapping of all typenames to their entity types, which is needed for proper normalization. Should be empty if normalization is not needed.
154
- // Empty objects with type casting can be used as values.
155
- typenames: {
156
- users: {} as User, // here `users` entities will have type `User`
157
- banks: {} as Bank,
158
- },
159
162
  queries: {
160
163
  getUsers: { query: getUsers },
161
164
  getUser: {
@@ -174,7 +177,7 @@ export const {
174
177
 
175
178
  For normalization two things are required:
176
179
  - Set proper typenames while creating the cache - mapping of all entities and their corresponding TS types.
177
- - Return an object from queries and mutations, that contains the following fields (besides `result`):
180
+ - Return an object from queries and mutations that contains the following fields (besides `result`):
178
181
 
179
182
  ```typescript
180
183
  type EntityChanges<T extends Typenames> = {
@@ -2,31 +2,198 @@ import type { Cache, Key, MutateOptions, MutationResult, MutationState, Optional
2
2
  import { useMutation } from './useMutation';
3
3
  import { useQuery } from './useQuery';
4
4
  import { applyEntityChanges } from './utilsAndConstants';
5
+ /**
6
+ * Function to provide generic Typenames if normalization is needed - this is a Typescript limitation.
7
+ * Returns object with createCache function with provided typenames.
8
+ * @example
9
+ * const cache = withTypenames<MyTypenames>().createCache({
10
+ * ...
11
+ * })
12
+ */
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">) => {
15
+ /** Keeps all options, passed while creating the cache. */
16
+ cache: Cache<N, T, QP, QR, MP, MR>;
17
+ /** Reducer of the cache, should be added to redux store. */
18
+ reducer: (state: {
19
+ entities: import("./types").EntitiesMap<T>;
20
+ queries: QP | QR extends infer T_1 ? { [QK in keyof T_1]: import("./types").Dict<QueryState<QP[QK], QR[QK]> | undefined>; } : never;
21
+ mutations: MP | MR extends infer T_2 ? { [MK in keyof T_2]: MutationState<MP[MK], MR[MK]>; } : never;
22
+ } | undefined, action: {
23
+ type: `@rrc/${N}/updateQueryStateAndEntities`;
24
+ queryKey: keyof QP & keyof QR;
25
+ queryCacheKey: Key;
26
+ state: Partial<QueryState<QP[keyof QP & keyof QR], QR[keyof QP & keyof QR]>> | undefined;
27
+ entityChanges: import("./types").EntityChanges<T> | undefined;
28
+ } | {
29
+ type: `@rrc/${N}/updateMutationStateAndEntities`;
30
+ mutationKey: keyof MP & keyof MR;
31
+ state: Partial<MutationState<MP[keyof MP & keyof MR], MR[keyof MP & keyof MR]>> | undefined;
32
+ entityChanges: import("./types").EntityChanges<T> | undefined;
33
+ } | {
34
+ type: `@rrc/${N}/mergeEntityChanges`;
35
+ changes: import("./types").EntityChanges<T>;
36
+ } | {
37
+ type: `@rrc/${N}/invalidateQuery`;
38
+ queries: {
39
+ query: keyof QP & keyof QR;
40
+ cacheKey?: Key | undefined;
41
+ expiresAt?: number | undefined;
42
+ }[];
43
+ } | {
44
+ type: `@rrc/${N}/clearQueryState`;
45
+ queries: {
46
+ query: keyof QP & keyof QR;
47
+ cacheKey?: Key | undefined;
48
+ }[];
49
+ } | {
50
+ type: `@rrc/${N}/clearMutationState`;
51
+ mutationKeys: (keyof MP & keyof MR)[];
52
+ }) => {
53
+ entities: import("./types").EntitiesMap<T>;
54
+ queries: QP | QR extends infer T_3 ? { [QK in keyof T_3]: import("./types").Dict<QueryState<QP[QK], QR[QK]> | undefined>; } : never;
55
+ mutations: MP | MR extends infer T_4 ? { [MK in keyof T_4]: MutationState<MP[MK], MR[MK]>; } : never;
56
+ };
57
+ actions: {
58
+ updateQueryStateAndEntities: {
59
+ <K extends keyof QP & keyof QR>(queryKey: K, queryCacheKey: Key, state?: Partial<QueryState<QP[K], QR[K]>> | undefined, entityChanges?: import("./types").EntityChanges<T> | undefined): {
60
+ type: `@rrc/${N}/updateQueryStateAndEntities`;
61
+ queryKey: K;
62
+ queryCacheKey: Key;
63
+ state: Partial<QueryState<QP[K], QR[K]>> | undefined;
64
+ entityChanges: import("./types").EntityChanges<T> | undefined;
65
+ };
66
+ type: `@rrc/${N}/updateQueryStateAndEntities`;
67
+ };
68
+ updateMutationStateAndEntities: {
69
+ <K_1 extends keyof MP & keyof MR>(mutationKey: K_1, state?: Partial<MutationState<MP[K_1], MR[K_1]>> | undefined, entityChanges?: import("./types").EntityChanges<T> | undefined): {
70
+ type: `@rrc/${N}/updateMutationStateAndEntities`;
71
+ mutationKey: K_1;
72
+ state: Partial<MutationState<MP[K_1], MR[K_1]>> | undefined;
73
+ entityChanges: import("./types").EntityChanges<T> | undefined;
74
+ };
75
+ type: `@rrc/${N}/updateMutationStateAndEntities`;
76
+ };
77
+ mergeEntityChanges: {
78
+ (changes: import("./types").EntityChanges<T>): {
79
+ type: `@rrc/${N}/mergeEntityChanges`;
80
+ changes: import("./types").EntityChanges<T>;
81
+ };
82
+ type: `@rrc/${N}/mergeEntityChanges`;
83
+ };
84
+ invalidateQuery: {
85
+ <K_2 extends keyof QP & keyof QR>(queries: {
86
+ query: K_2;
87
+ cacheKey?: Key | undefined;
88
+ expiresAt?: number | undefined;
89
+ }[]): {
90
+ type: `@rrc/${N}/invalidateQuery`;
91
+ queries: {
92
+ query: K_2;
93
+ cacheKey?: Key | undefined;
94
+ expiresAt?: number | undefined;
95
+ }[];
96
+ };
97
+ type: `@rrc/${N}/invalidateQuery`;
98
+ };
99
+ clearQueryState: {
100
+ <K_3 extends keyof QP & keyof QR>(queries: {
101
+ query: K_3;
102
+ cacheKey?: Key | undefined;
103
+ }[]): {
104
+ type: `@rrc/${N}/clearQueryState`;
105
+ queries: {
106
+ query: K_3;
107
+ cacheKey?: Key | undefined;
108
+ }[];
109
+ };
110
+ type: `@rrc/${N}/clearQueryState`;
111
+ };
112
+ clearMutationState: {
113
+ <K_4 extends keyof MP & keyof MR>(mutationKeys: K_4[]): {
114
+ type: `@rrc/${N}/clearMutationState`;
115
+ mutationKeys: K_4[];
116
+ };
117
+ type: `@rrc/${N}/clearMutationState`;
118
+ };
119
+ };
120
+ selectors: {
121
+ /** Selects query state. */
122
+ selectQueryState: <QK_1 extends keyof QP | keyof QR>(state: unknown, query: QK_1, cacheKey: Key) => QueryState<QK_1 extends keyof QP & keyof QR ? QP[QK_1] : never, QK_1 extends keyof QP & keyof QR ? QR[QK_1] : never>;
123
+ /** Selects query latest result. */
124
+ selectQueryResult: <QK_2 extends keyof QP | keyof QR>(state: unknown, query: QK_2, cacheKey: Key) => (QK_2 extends keyof QP & keyof QR ? QR[QK_2] : never) | undefined;
125
+ /** Selects query loading state. */
126
+ selectQueryLoading: <QK_3 extends keyof QP | keyof QR>(state: unknown, query: QK_3, cacheKey: Key) => boolean;
127
+ /** Selects query latest error. */
128
+ selectQueryError: <QK_4 extends keyof QP | keyof QR>(state: unknown, query: QK_4, cacheKey: Key) => Error | undefined;
129
+ /** Selects query latest params. */
130
+ selectQueryParams: <QK_5 extends keyof QP | keyof QR>(state: unknown, query: QK_5, cacheKey: Key) => (QK_5 extends keyof QP & keyof QR ? QP[QK_5] : never) | undefined;
131
+ /** Selects query latest expiresAt. */
132
+ selectQueryExpiresAt: <QK_6 extends keyof QP | keyof QR>(state: unknown, query: QK_6, cacheKey: Key) => number | undefined;
133
+ /** Selects mutation state. */
134
+ selectMutationState: <MK_1 extends keyof MP | keyof MR>(state: unknown, mutation: MK_1) => MutationState<MK_1 extends keyof MP & keyof MR ? MP[MK_1] : never, MK_1 extends keyof MP & keyof MR ? MR[MK_1] : never>;
135
+ /** Selects mutation latest result. */
136
+ 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;
137
+ /** Selects mutation loading state. */
138
+ selectMutationLoading: <MK_3 extends keyof MP | keyof MR>(state: unknown, mutation: MK_3) => boolean;
139
+ /** Selects mutation latest error. */
140
+ selectMutationError: <MK_4 extends keyof MP | keyof MR>(state: unknown, mutation: MK_4) => Error | undefined;
141
+ /** Selects mutation latest params. */
142
+ selectMutationParams: <MK_5 extends keyof MP | keyof MR>(state: unknown, mutation: MK_5) => (MK_5 extends keyof MP & keyof MR ? MP[MK_5] : never) | undefined;
143
+ /** Selects entity by id and typename. */
144
+ selectEntityById: <TN extends keyof T>(state: unknown, id: Key | null | undefined, typename: TN) => T[TN] | undefined;
145
+ /** Selects all entities. */
146
+ selectEntities: (state: unknown) => import("./types").EntitiesMap<T>;
147
+ /** Selects all entities of provided typename. */
148
+ selectEntitiesByTypename: <TN_1 extends keyof T>(state: unknown, typename: TN_1) => import("./types").EntitiesMap<T>[TN_1];
149
+ };
150
+ hooks: {
151
+ /** Returns client object with query and mutate functions. */
152
+ useClient: () => {
153
+ 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>>;
154
+ 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>>;
155
+ };
156
+ /** Fetches query when params change and subscribes to query state changes (except `expiresAt` field). */
157
+ 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>>];
158
+ /** Subscribes to provided mutation state and provides mutate function. */
159
+ 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];
160
+ /** useSelector + selectEntityById. */
161
+ useSelectEntityById: <TN_2 extends keyof T>(id: Key | null | undefined, typename: TN_2) => T[TN_2] | undefined;
162
+ };
163
+ utils: {
164
+ /**
165
+ * Apply changes to the entities map.
166
+ * @return `undefined` if nothing to change, otherwise new entities map with applied changes.
167
+ */
168
+ applyEntityChanges: (entities: import("./types").EntitiesMap<T>, changes: import("./types").EntityChanges<T>) => import("./types").EntitiesMap<T> | undefined;
169
+ };
170
+ };
171
+ };
5
172
  /**
6
173
  * Creates reducer, actions and hooks for managing queries and mutations through redux cache.
7
174
  */
8
- export declare const createCache: <N extends string, T extends Typenames, QP, QR, MP, MR>(partialCache: OptionalPartial<Cache<N, T, 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">) => {
9
176
  /** Keeps all options, passed while creating the cache. */
10
- cache: Cache<N, T, QP, QR, MP, MR>;
177
+ cache: Cache<N, Typenames, QP, QR, MP, MR>;
11
178
  /** Reducer of the cache, should be added to redux store. */
12
179
  reducer: (state: {
13
- entities: import("./types").EntitiesMap<T>;
14
- queries: QP | QR extends infer T_1 ? { [QK in keyof T_1]: import("./types").Dict<QueryState<QP[QK], QR[QK]> | undefined>; } : never;
15
- mutations: MP | MR extends infer T_2 ? { [MK in keyof T_2]: MutationState<MP[MK], MR[MK]>; } : never;
180
+ entities: import("./types").EntitiesMap<Typenames>;
181
+ queries: QP | QR extends infer T ? { [QK in keyof T]: import("./types").Dict<QueryState<QP[QK], QR[QK]> | undefined>; } : never;
182
+ mutations: MP | MR extends infer T_1 ? { [MK in keyof T_1]: MutationState<MP[MK], MR[MK]>; } : never;
16
183
  } | undefined, action: {
17
184
  type: `@rrc/${N}/updateQueryStateAndEntities`;
18
185
  queryKey: keyof QP & keyof QR;
19
186
  queryCacheKey: Key;
20
187
  state: Partial<QueryState<QP[keyof QP & keyof QR], QR[keyof QP & keyof QR]>> | undefined;
21
- entityChanges: import("./types").EntityChanges<T> | undefined;
188
+ entityChanges: import("./types").EntityChanges<Typenames> | undefined;
22
189
  } | {
23
190
  type: `@rrc/${N}/updateMutationStateAndEntities`;
24
191
  mutationKey: keyof MP & keyof MR;
25
192
  state: Partial<MutationState<MP[keyof MP & keyof MR], MR[keyof MP & keyof MR]>> | undefined;
26
- entityChanges: import("./types").EntityChanges<T> | undefined;
193
+ entityChanges: import("./types").EntityChanges<Typenames> | undefined;
27
194
  } | {
28
195
  type: `@rrc/${N}/mergeEntityChanges`;
29
- changes: import("./types").EntityChanges<T>;
196
+ changes: import("./types").EntityChanges<Typenames>;
30
197
  } | {
31
198
  type: `@rrc/${N}/invalidateQuery`;
32
199
  queries: {
@@ -44,34 +211,34 @@ export declare const createCache: <N extends string, T extends Typenames, QP, QR
44
211
  type: `@rrc/${N}/clearMutationState`;
45
212
  mutationKeys: (keyof MP & keyof MR)[];
46
213
  }) => {
47
- entities: import("./types").EntitiesMap<T>;
48
- queries: QP | QR extends infer T_3 ? { [QK in keyof T_3]: import("./types").Dict<QueryState<QP[QK], QR[QK]> | undefined>; } : never;
49
- mutations: MP | MR extends infer T_4 ? { [MK in keyof T_4]: MutationState<MP[MK], MR[MK]>; } : never;
214
+ entities: import("./types").EntitiesMap<Typenames>;
215
+ queries: QP | QR extends infer T_2 ? { [QK in keyof T_2]: import("./types").Dict<QueryState<QP[QK], QR[QK]> | undefined>; } : never;
216
+ mutations: MP | MR extends infer T_3 ? { [MK in keyof T_3]: MutationState<MP[MK], MR[MK]>; } : never;
50
217
  };
51
218
  actions: {
52
219
  updateQueryStateAndEntities: {
53
- <K extends keyof QP & keyof QR>(queryKey: K, queryCacheKey: Key, state?: Partial<QueryState<QP[K], QR[K]>> | undefined, entityChanges?: import("./types").EntityChanges<T> | undefined): {
220
+ <K extends keyof QP & keyof QR>(queryKey: K, queryCacheKey: Key, state?: Partial<QueryState<QP[K], QR[K]>> | undefined, entityChanges?: import("./types").EntityChanges<Typenames> | undefined): {
54
221
  type: `@rrc/${N}/updateQueryStateAndEntities`;
55
222
  queryKey: K;
56
223
  queryCacheKey: Key;
57
224
  state: Partial<QueryState<QP[K], QR[K]>> | undefined;
58
- entityChanges: import("./types").EntityChanges<T> | undefined;
225
+ entityChanges: import("./types").EntityChanges<Typenames> | undefined;
59
226
  };
60
227
  type: `@rrc/${N}/updateQueryStateAndEntities`;
61
228
  };
62
229
  updateMutationStateAndEntities: {
63
- <K_1 extends keyof MP & keyof MR>(mutationKey: K_1, state?: Partial<MutationState<MP[K_1], MR[K_1]>> | undefined, entityChanges?: import("./types").EntityChanges<T> | undefined): {
230
+ <K_1 extends keyof MP & keyof MR>(mutationKey: K_1, state?: Partial<MutationState<MP[K_1], MR[K_1]>> | undefined, entityChanges?: import("./types").EntityChanges<Typenames> | undefined): {
64
231
  type: `@rrc/${N}/updateMutationStateAndEntities`;
65
232
  mutationKey: K_1;
66
233
  state: Partial<MutationState<MP[K_1], MR[K_1]>> | undefined;
67
- entityChanges: import("./types").EntityChanges<T> | undefined;
234
+ entityChanges: import("./types").EntityChanges<Typenames> | undefined;
68
235
  };
69
236
  type: `@rrc/${N}/updateMutationStateAndEntities`;
70
237
  };
71
238
  mergeEntityChanges: {
72
- (changes: import("./types").EntityChanges<T>): {
239
+ (changes: import("./types").EntityChanges<Typenames>): {
73
240
  type: `@rrc/${N}/mergeEntityChanges`;
74
- changes: import("./types").EntityChanges<T>;
241
+ changes: import("./types").EntityChanges<Typenames>;
75
242
  };
76
243
  type: `@rrc/${N}/mergeEntityChanges`;
77
244
  };
@@ -122,7 +289,7 @@ export declare const createCache: <N extends string, T extends Typenames, QP, QR
122
289
  selectQueryError: <QK_4 extends keyof QP | keyof QR>(state: unknown, query: QK_4, cacheKey: Key) => Error | undefined;
123
290
  /** Selects query latest params. */
124
291
  selectQueryParams: <QK_5 extends keyof QP | keyof QR>(state: unknown, query: QK_5, cacheKey: Key) => (QK_5 extends keyof QP & keyof QR ? QP[QK_5] : never) | undefined;
125
- /** Selects query expiresAt value. */
292
+ /** Selects query latest expiresAt. */
126
293
  selectQueryExpiresAt: <QK_6 extends keyof QP | keyof QR>(state: unknown, query: QK_6, cacheKey: Key) => number | undefined;
127
294
  /** Selects mutation state. */
128
295
  selectMutationState: <MK_1 extends keyof MP | keyof MR>(state: unknown, mutation: MK_1) => MutationState<MK_1 extends keyof MP & keyof MR ? MP[MK_1] : never, MK_1 extends keyof MP & keyof MR ? MR[MK_1] : never>;
@@ -135,30 +302,30 @@ export declare const createCache: <N extends string, T extends Typenames, QP, QR
135
302
  /** Selects mutation latest params. */
136
303
  selectMutationParams: <MK_5 extends keyof MP | keyof MR>(state: unknown, mutation: MK_5) => (MK_5 extends keyof MP & keyof MR ? MP[MK_5] : never) | undefined;
137
304
  /** Selects entity by id and typename. */
138
- selectEntityById: <TN extends keyof T>(state: unknown, id: Key | null | undefined, typename: TN) => T[TN] | undefined;
305
+ selectEntityById: <TN extends string>(state: unknown, id: Key | null | undefined, typename: TN) => object | undefined;
139
306
  /** Selects all entities. */
140
- selectEntities: (state: unknown) => import("./types").EntitiesMap<T>;
307
+ selectEntities: (state: unknown) => import("./types").EntitiesMap<Typenames>;
141
308
  /** Selects all entities of provided typename. */
142
- selectEntitiesByTypename: <TN_1 extends keyof T>(state: unknown, typename: TN_1) => import("./types").EntitiesMap<T>[TN_1];
309
+ selectEntitiesByTypename: <TN_1 extends string>(state: unknown, typename: TN_1) => import("./types").Dict<object> | undefined;
143
310
  };
144
311
  hooks: {
145
312
  /** Returns client object with query and mutate functions. */
146
313
  useClient: () => {
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: MutateOptions<T, MP, MR, MK_6>) => Promise<MutationResult<MK_6 extends keyof MP & keyof MR ? MR[MK_6] : never>>;
314
+ query: <QK_7 extends keyof QP | keyof QR>(options: QueryOptions<Typenames, QP, QR, QK_7>) => Promise<QueryResult<QK_7 extends keyof QP & keyof QR ? QR[QK_7] : never>>;
315
+ mutate: <MK_6 extends keyof MP | keyof MR>(options: MutateOptions<Typenames, MP, MR, MK_6>) => Promise<MutationResult<MK_6 extends keyof MP & keyof MR ? MR[MK_6] : never>>;
149
316
  };
150
317
  /** Fetches query when params change and subscribes to query state changes (except `expiresAt` field). */
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>>];
318
+ useQuery: <QK_8 extends keyof QP | keyof QR>(options: import("./types").UseQueryOptions<Typenames, 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<Typenames, QP, QR, QK_8>, "params" | "onlyIfExpired">> | undefined) => Promise<QueryResult<QK_8 extends infer T_4 ? T_4 extends QK_8 ? T_4 extends keyof QP & keyof QR ? QR[T_4] : never : never : never>>];
152
319
  /** Subscribes to provided mutation state and provides mutate function. */
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];
320
+ useMutation: <MK_7 extends keyof MP | keyof MR>(options: Omit<MutateOptions<Typenames, 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_5 ? T_5 extends MK_7 ? T_5 extends keyof MP & keyof MR ? MR[T_5] : 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];
154
321
  /** useSelector + selectEntityById. */
155
- useSelectEntityById: <TN_2 extends keyof T>(id: Key | null | undefined, typename: TN_2) => T[TN_2] | undefined;
322
+ useSelectEntityById: <TN_2 extends string>(id: Key | null | undefined, typename: TN_2) => object | undefined;
156
323
  };
157
324
  utils: {
158
325
  /**
159
326
  * Apply changes to the entities map.
160
327
  * @return `undefined` if nothing to change, otherwise new entities map with applied changes.
161
328
  */
162
- applyEntityChanges: (entities: import("./types").EntitiesMap<T>, changes: import("./types").EntityChanges<T>) => import("./types").EntitiesMap<T> | undefined;
329
+ applyEntityChanges: (entities: import("./types").EntitiesMap<Typenames>, changes: import("./types").EntityChanges<Typenames>) => import("./types").EntitiesMap<Typenames> | undefined;
163
330
  };
164
331
  };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createCache = void 0;
3
+ exports.createCache = exports.withTypenames = void 0;
4
4
  const react_1 = require("react");
5
5
  const react_redux_1 = require("react-redux");
6
6
  const createActions_1 = require("./createActions");
@@ -11,140 +11,161 @@ const useMutation_1 = require("./useMutation");
11
11
  const useQuery_1 = require("./useQuery");
12
12
  const utilsAndConstants_1 = require("./utilsAndConstants");
13
13
  /**
14
- * Creates reducer, actions and hooks for managing queries and mutations through redux cache.
14
+ * Function to provide generic Typenames if normalization is needed - this is a Typescript limitation.
15
+ * Returns object with createCache function with provided typenames.
16
+ * @example
17
+ * const cache = withTypenames<MyTypenames>().createCache({
18
+ * ...
19
+ * })
15
20
  */
16
- const createCache = (partialCache) => {
17
- var _a, _b, _c, _d, _e, _f, _g;
18
- var _h, _j, _k;
19
- const abortControllers = new WeakMap();
20
- // provide all optional fields
21
- (_a = partialCache.options) !== null && _a !== void 0 ? _a : (partialCache.options = {});
22
- (_b = (_h = partialCache.options).logsEnabled) !== null && _b !== void 0 ? _b : (_h.logsEnabled = false);
23
- (_c = (_j = partialCache.options).validateFunctionArguments) !== null && _c !== void 0 ? _c : (_j.validateFunctionArguments = utilsAndConstants_1.IS_DEV);
24
- (_d = (_k = partialCache.options).deepComparisonEnabled) !== null && _d !== void 0 ? _d : (_k.deepComparisonEnabled = true);
25
- (_e = partialCache.queries) !== null && _e !== void 0 ? _e : (partialCache.queries = {});
26
- (_f = partialCache.mutations) !== null && _f !== void 0 ? _f : (partialCache.mutations = {});
27
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
28
- (_g = partialCache.cacheStateSelector) !== null && _g !== void 0 ? _g : (partialCache.cacheStateSelector = (state) => state[cache.name]);
29
- // @ts-expect-error private field for testing
30
- partialCache.abortControllers = abortControllers;
31
- const cache = partialCache;
32
- // make selectors
33
- const selectEntityById = (state, id, typename) => {
34
- return id == null ? undefined : cache.cacheStateSelector(state).entities[typename][id];
35
- };
36
- const selectQueryState = (state, query, cacheKey) => {
37
- var _a;
38
- // @ts-expect-error fix later
39
- return (_a = cache.cacheStateSelector(state).queries[query][cacheKey]) !== null && _a !== void 0 ? _a : utilsAndConstants_1.DEFAULT_QUERY_MUTATION_STATE;
40
- };
41
- const selectMutationState = (state, mutation) => {
42
- var _a;
43
- // @ts-expect-error fix later
44
- return (_a = cache.cacheStateSelector(state).mutations[mutation]) !== null && _a !== void 0 ? _a : utilsAndConstants_1.DEFAULT_QUERY_MUTATION_STATE;
45
- };
46
- const actions = (0, createActions_1.createActions)(cache.name);
21
+ const withTypenames = () => {
22
+ /**
23
+ * Creates reducer, actions and hooks for managing queries and mutations through redux cache.
24
+ */
47
25
  return {
48
- /** Keeps all options, passed while creating the cache. */
49
- cache,
50
- /** Reducer of the cache, should be added to redux store. */
51
- reducer: (0, createCacheReducer_1.createCacheReducer)(actions, cache.typenames, Object.keys(cache.queries), cache.options),
52
- actions,
53
- selectors: {
54
- /** Selects query state. */
55
- selectQueryState,
56
- /** Selects query latest result. */
57
- selectQueryResult: (state, query, cacheKey) => {
58
- return selectQueryState(state, query, cacheKey).result;
59
- },
60
- /** Selects query loading state. */
61
- selectQueryLoading: (state, query, cacheKey) => {
62
- return selectQueryState(state, query, cacheKey).loading;
63
- },
64
- /** Selects query latest error. */
65
- selectQueryError: (state, query, cacheKey) => {
66
- return selectQueryState(state, query, cacheKey).error;
67
- },
68
- /** Selects query latest params. */
69
- selectQueryParams: (state, query, cacheKey) => {
70
- return selectQueryState(state, query, cacheKey).params;
71
- },
72
- /** Selects query expiresAt value. */
73
- selectQueryExpiresAt: (state, query, cacheKey) => {
74
- return selectQueryState(state, query, cacheKey).expiresAt;
75
- },
76
- /** Selects mutation state. */
77
- selectMutationState,
78
- /** Selects mutation latest result. */
79
- selectMutationResult: (state, mutation) => {
80
- return selectMutationState(state, mutation).result;
81
- },
82
- /** Selects mutation loading state. */
83
- selectMutationLoading: (state, mutation) => {
84
- return selectMutationState(state, mutation).loading;
85
- },
86
- /** Selects mutation latest error. */
87
- selectMutationError: (state, mutation) => {
88
- return selectMutationState(state, mutation).error;
89
- },
90
- /** Selects mutation latest params. */
91
- selectMutationParams: (state, mutation) => {
92
- return selectMutationState(state, mutation).params;
93
- },
94
- /** Selects entity by id and typename. */
95
- selectEntityById,
96
- /** Selects all entities. */
97
- selectEntities: (state) => {
98
- return cache.cacheStateSelector(state).entities;
99
- },
100
- /** Selects all entities of provided typename. */
101
- selectEntitiesByTypename: (state, typename) => {
102
- return cache.cacheStateSelector(state).entities[typename];
103
- },
104
- },
105
- hooks: {
106
- /** Returns client object with query and mutate functions. */
107
- useClient: () => {
108
- const store = (0, react_redux_1.useStore)();
109
- return (0, react_1.useMemo)(() => {
110
- const client = {
111
- query: (options) => {
112
- var _a;
113
- const { query: queryKey, params } = options;
114
- const getCacheKey = (_a = cache.queries[queryKey].getCacheKey) !== null && _a !== void 0 ? _a : (utilsAndConstants_1.defaultGetCacheKey);
115
- // @ts-expect-error fix later
116
- const cacheKey = getCacheKey(params);
117
- return (0, query_1.query)('query', store, cache, actions, queryKey, cacheKey, params, options.secondsToLive, options.onlyIfExpired,
118
- // @ts-expect-error fix later
119
- options.mergeResults, options.onCompleted, options.onSuccess, options.onError);
120
- },
121
- mutate: (options) => {
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);
125
- },
126
- };
127
- return client;
128
- }, [store]);
129
- },
130
- /** Fetches query when params change and subscribes to query state changes (except `expiresAt` field). */
131
- useQuery: (options) => (0, useQuery_1.useQuery)(cache, actions, options),
132
- /** Subscribes to provided mutation state and provides mutate function. */
133
- useMutation: (options) => (0, useMutation_1.useMutation)(cache, actions, options, abortControllers),
134
- /** useSelector + selectEntityById. */
135
- useSelectEntityById: (id, typename) => {
136
- return (0, react_redux_1.useSelector)((state) => selectEntityById(state, id, typename));
137
- },
138
- },
139
- utils: {
140
- /**
141
- * Apply changes to the entities map.
142
- * @return `undefined` if nothing to change, otherwise new entities map with applied changes.
143
- */
144
- applyEntityChanges: (entities, changes) => {
145
- return (0, utilsAndConstants_1.applyEntityChanges)(entities, changes, cache.options);
146
- },
26
+ createCache: (partialCache) => {
27
+ var _a, _b, _c, _d, _e, _f, _g;
28
+ var _h, _j, _k;
29
+ const abortControllers = new WeakMap();
30
+ // provide all optional fields
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);
35
+ (_e = partialCache.queries) !== null && _e !== void 0 ? _e : (partialCache.queries = {});
36
+ (_f = partialCache.mutations) !== null && _f !== void 0 ? _f : (partialCache.mutations = {});
37
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
38
+ (_g = partialCache.cacheStateSelector) !== null && _g !== void 0 ? _g : (partialCache.cacheStateSelector = (state) => state[cache.name]);
39
+ // @ts-expect-error private field for testing
40
+ partialCache.abortControllers = abortControllers;
41
+ const cache = partialCache;
42
+ // validate options
43
+ if (cache.options.deepComparisonEnabled && !utilsAndConstants_1.optionalUtils.deepEqual) {
44
+ console.warn('react-redux-cache: optional dependency for fast-deep-equal was not provided, while deepComparisonEnabled option is true');
45
+ }
46
+ // make selectors
47
+ const selectEntityById = (state, id, typename) => {
48
+ var _a;
49
+ return id == null ? undefined : (_a = cache.cacheStateSelector(state).entities[typename]) === null || _a === void 0 ? void 0 : _a[id];
50
+ };
51
+ const selectQueryState = (state, query, cacheKey) => {
52
+ var _a;
53
+ // @ts-expect-error fix later
54
+ return (_a = cache.cacheStateSelector(state).queries[query][cacheKey]) !== null && _a !== void 0 ? _a : utilsAndConstants_1.DEFAULT_QUERY_MUTATION_STATE;
55
+ };
56
+ const selectMutationState = (state, mutation) => {
57
+ var _a;
58
+ // @ts-expect-error fix later
59
+ return (_a = cache.cacheStateSelector(state).mutations[mutation]) !== null && _a !== void 0 ? _a : utilsAndConstants_1.DEFAULT_QUERY_MUTATION_STATE;
60
+ };
61
+ const actions = (0, createActions_1.createActions)(cache.name);
62
+ return {
63
+ /** Keeps all options, passed while creating the cache. */
64
+ cache,
65
+ /** Reducer of the cache, should be added to redux store. */
66
+ reducer: (0, createCacheReducer_1.createCacheReducer)(actions, Object.keys(cache.queries), cache.options),
67
+ actions,
68
+ selectors: {
69
+ /** Selects query state. */
70
+ selectQueryState,
71
+ /** Selects query latest result. */
72
+ selectQueryResult: (state, query, cacheKey) => {
73
+ return selectQueryState(state, query, cacheKey).result;
74
+ },
75
+ /** Selects query loading state. */
76
+ selectQueryLoading: (state, query, cacheKey) => {
77
+ return selectQueryState(state, query, cacheKey).loading;
78
+ },
79
+ /** Selects query latest error. */
80
+ selectQueryError: (state, query, cacheKey) => {
81
+ return selectQueryState(state, query, cacheKey).error;
82
+ },
83
+ /** Selects query latest params. */
84
+ selectQueryParams: (state, query, cacheKey) => {
85
+ return selectQueryState(state, query, cacheKey).params;
86
+ },
87
+ /** Selects query latest expiresAt. */
88
+ selectQueryExpiresAt: (state, query, cacheKey) => {
89
+ return selectQueryState(state, query, cacheKey).expiresAt;
90
+ },
91
+ /** Selects mutation state. */
92
+ selectMutationState,
93
+ /** Selects mutation latest result. */
94
+ selectMutationResult: (state, mutation) => {
95
+ return selectMutationState(state, mutation).result;
96
+ },
97
+ /** Selects mutation loading state. */
98
+ selectMutationLoading: (state, mutation) => {
99
+ return selectMutationState(state, mutation).loading;
100
+ },
101
+ /** Selects mutation latest error. */
102
+ selectMutationError: (state, mutation) => {
103
+ return selectMutationState(state, mutation).error;
104
+ },
105
+ /** Selects mutation latest params. */
106
+ selectMutationParams: (state, mutation) => {
107
+ return selectMutationState(state, mutation).params;
108
+ },
109
+ /** Selects entity by id and typename. */
110
+ selectEntityById,
111
+ /** Selects all entities. */
112
+ selectEntities: (state) => {
113
+ return cache.cacheStateSelector(state).entities;
114
+ },
115
+ /** Selects all entities of provided typename. */
116
+ selectEntitiesByTypename: (state, typename) => {
117
+ return cache.cacheStateSelector(state).entities[typename];
118
+ },
119
+ },
120
+ hooks: {
121
+ /** Returns client object with query and mutate functions. */
122
+ useClient: () => {
123
+ const store = (0, react_redux_1.useStore)();
124
+ return (0, react_1.useMemo)(() => {
125
+ const client = {
126
+ query: (options) => {
127
+ var _a;
128
+ const { query: queryKey, params } = options;
129
+ const getCacheKey = (_a = cache.queries[queryKey].getCacheKey) !== null && _a !== void 0 ? _a : (utilsAndConstants_1.defaultGetCacheKey);
130
+ // @ts-expect-error fix later
131
+ const cacheKey = getCacheKey(params);
132
+ return (0, query_1.query)('query', store, cache, actions, queryKey, cacheKey, params, options.secondsToLive, options.onlyIfExpired,
133
+ // @ts-expect-error fix later
134
+ options.mergeResults, options.onCompleted, options.onSuccess, options.onError);
135
+ },
136
+ mutate: (options) => {
137
+ return (0, mutate_1.mutate)('mutate', store, cache, actions, options.mutation, options.params, abortControllers,
138
+ // @ts-expect-error fix later
139
+ options.onCompleted, options.onSuccess, options.onError);
140
+ },
141
+ };
142
+ return client;
143
+ }, [store]);
144
+ },
145
+ /** Fetches query when params change and subscribes to query state changes (except `expiresAt` field). */
146
+ useQuery: (options) => (0, useQuery_1.useQuery)(cache, actions, options),
147
+ /** Subscribes to provided mutation state and provides mutate function. */
148
+ useMutation: (options) => (0, useMutation_1.useMutation)(cache, actions, options, abortControllers),
149
+ /** useSelector + selectEntityById. */
150
+ useSelectEntityById: (id, typename) => {
151
+ return (0, react_redux_1.useSelector)((state) => selectEntityById(state, id, typename));
152
+ },
153
+ },
154
+ utils: {
155
+ /**
156
+ * Apply changes to the entities map.
157
+ * @return `undefined` if nothing to change, otherwise new entities map with applied changes.
158
+ */
159
+ applyEntityChanges: (entities, changes) => {
160
+ return (0, utilsAndConstants_1.applyEntityChanges)(entities, changes, cache.options);
161
+ },
162
+ },
163
+ };
147
164
  },
148
165
  };
149
166
  };
150
- exports.createCache = createCache;
167
+ exports.withTypenames = withTypenames;
168
+ /**
169
+ * Creates reducer, actions and hooks for managing queries and mutations through redux cache.
170
+ */
171
+ exports.createCache = (0, exports.withTypenames)().createCache;
@@ -1,7 +1,7 @@
1
1
  import type { ActionMap } from './createActions';
2
2
  import type { CacheOptions, Dict, EntitiesMap, MutationState, QueryState, Typenames } from './types';
3
3
  export type ReduxCacheState<T extends Typenames, QP, QR, MP, MR> = ReturnType<ReturnType<typeof createCacheReducer<string, T, QP, QR, MP, MR>>>;
4
- export declare const createCacheReducer: <N extends string, T extends Typenames, QP, QR, MP, MR>(actions: ActionMap<N, T, QP, QR, MP, MR>, typenames: T, queryKeys: (keyof QP & keyof QR)[], cacheOptions: CacheOptions) => (state: {
4
+ export declare const createCacheReducer: <N extends string, T extends Typenames, QP, QR, MP, MR>(actions: ActionMap<N, T, QP, QR, MP, MR>, queryKeys: (keyof QP & keyof QR)[], cacheOptions: CacheOptions) => (state: {
5
5
  entities: EntitiesMap<T>;
6
6
  queries: QP | QR extends infer T_1 ? { [QK in keyof T_1]: Dict<QueryState<QP[QK], QR[QK]> | undefined>; } : never;
7
7
  mutations: MP | MR extends infer T_2 ? { [MK in keyof T_2]: MutationState<MP[MK], MR[MK]>; } : never;
@@ -2,14 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createCacheReducer = void 0;
4
4
  const utilsAndConstants_1 = require("./utilsAndConstants");
5
- const EMPTY_QUERY_STATE = Object.freeze({});
6
5
  const optionalQueryKeys = ['error', 'expiresAt', 'result', 'params'];
7
6
  const optionalMutationKeys = ['error', 'result', 'params'];
8
- const createCacheReducer = (actions, typenames, queryKeys, cacheOptions) => {
7
+ const createCacheReducer = (actions, queryKeys, cacheOptions) => {
9
8
  const entitiesMap = {};
10
- for (const key in typenames) {
11
- entitiesMap[key] = EMPTY_QUERY_STATE;
12
- }
13
9
  const queryStateMap = {};
14
10
  for (const key of queryKeys) {
15
11
  queryStateMap[key] = {};
@@ -22,7 +18,6 @@ const createCacheReducer = (actions, typenames, queryKeys, cacheOptions) => {
22
18
  };
23
19
  cacheOptions.logsEnabled &&
24
20
  (0, utilsAndConstants_1.log)('createCacheReducer', {
25
- typenames,
26
21
  queryKeys,
27
22
  initialState,
28
23
  });
@@ -151,9 +146,9 @@ const createCacheReducer = (actions, typenames, queryKeys, cacheOptions) => {
151
146
  delete newQueries[queryKey][cacheKey];
152
147
  }
153
148
  }
154
- else if (queryStates !== EMPTY_QUERY_STATE) {
149
+ else if (queryStates !== utilsAndConstants_1.EMPTY_OBJECT) {
155
150
  newQueries !== null && newQueries !== void 0 ? newQueries : (newQueries = Object.assign({}, state.queries));
156
- newQueries[queryKey] = EMPTY_QUERY_STATE;
151
+ newQueries[queryKey] = utilsAndConstants_1.EMPTY_OBJECT;
157
152
  }
158
153
  }
159
154
  return !newQueries
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { createCache } from './createCache';
1
+ export { createCache, withTypenames } from './createCache';
2
2
  export type { ReduxCacheState } from './createCacheReducer';
3
3
  export * from './types';
4
4
  export { defaultGetCacheKey, DEFAULT_QUERY_MUTATION_STATE as defaultQueryMutationState, } from './utilsAndConstants';
package/dist/index.js CHANGED
@@ -14,9 +14,10 @@ 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.createCache = void 0;
17
+ exports.defaultQueryMutationState = 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
+ Object.defineProperty(exports, "withTypenames", { enumerable: true, get: function () { return createCache_1.withTypenames; } });
20
21
  __exportStar(require("./types"), exports);
21
22
  var utilsAndConstants_1 = require("./utilsAndConstants");
22
23
  Object.defineProperty(exports, "defaultGetCacheKey", { enumerable: true, get: function () { return utilsAndConstants_1.defaultGetCacheKey; } });
@@ -26,8 +27,6 @@ Object.defineProperty(exports, "defaultQueryMutationState", { enumerable: true,
26
27
  // rca -> vite
27
28
  // defaults
28
29
  // remove cachePolicy? make skip/enabled a function? skip -> enabled/shouldFetch?
29
- // optional typenames: {} as Typenames
30
- // remove mergeResults? bcs store is passed to queries/mutations
31
30
  // remove undefined optional fields & emtpy states
32
31
  // generate full api docs
33
32
  // ! medium
package/dist/types.d.ts CHANGED
@@ -21,16 +21,6 @@ export type Typenames = Record<string, object>;
21
21
  export type Cache<N extends string, T extends Typenames, QP, QR, MP, MR> = {
22
22
  /** Used as prefix for actions and in default cacheStateSelector for selecting cache state from redux state. */
23
23
  name: N;
24
- /**
25
- * Mapping of all typenames to their entity types, which is needed for proper normalization. Should be empty if normalization is not needed.
26
- * @key Typename.
27
- * @value Object with proper type of the typename. Empty objects with type casting can be used.
28
- * @example
29
- * typenames: {
30
- users: {} as User, // here `users` entities will have type `User`
31
- banks: {} as Bank,
32
- } */
33
- typenames: T;
34
24
  queries: {
35
25
  [QK in keyof (QP & QR)]: QK extends keyof (QP | QR) ? QueryInfo<T, QP[QK], QR[QK]> : never;
36
26
  };
@@ -64,7 +54,7 @@ export type PartialEntitiesMap<T extends Typenames> = {
64
54
  [K in keyof T]?: Dict<Partial<T[K]>>;
65
55
  };
66
56
  export type EntitiesMap<T extends Typenames> = {
67
- [K in keyof T]: Dict<T[K]>;
57
+ [K in keyof T]?: Dict<T[K]>;
68
58
  };
69
59
  export type EntityIds<T extends Typenames> = {
70
60
  [K in keyof T]?: Key[];
@@ -7,6 +7,8 @@ export declare const IS_DEV: boolean;
7
7
  export declare const DEFAULT_QUERY_MUTATION_STATE: Readonly<{
8
8
  loading: false;
9
9
  }>;
10
+ export declare const EMPTY_OBJECT: Readonly<{}>;
11
+ export declare const EMPTY_ARRAY: readonly never[];
10
12
  export declare const defaultGetCacheKey: <P = unknown>(params: P) => Key;
11
13
  export declare const log: (tag: string, data?: unknown) => void;
12
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.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,
@@ -21,6 +21,8 @@ exports.IS_DEV = (() => {
21
21
  }
22
22
  })();
23
23
  exports.DEFAULT_QUERY_MUTATION_STATE = Object.freeze({ loading: false });
24
+ exports.EMPTY_OBJECT = Object.freeze({});
25
+ exports.EMPTY_ARRAY = Object.freeze([]);
24
26
  const defaultGetCacheKey = (params) => {
25
27
  switch (typeof params) {
26
28
  case 'string':
@@ -38,12 +40,9 @@ const log = (tag, data) => {
38
40
  };
39
41
  exports.log = log;
40
42
  const applyEntityChanges = (entities, changes, options) => {
41
- var _a, _b, _c;
42
- if (options.validateFunctionArguments) {
43
- // check for merge and entities both set
44
- if (changes.merge && changes.entities) {
45
- throw new Error('Merge and entities should not be both set');
46
- }
43
+ var _a, _b, _c, _d;
44
+ if (changes.merge && changes.entities) {
45
+ console.warn('react-redux-cache.applyEntityChanges: merge and entities should not be both set');
47
46
  }
48
47
  const { merge = changes.entities, replace, remove } = changes;
49
48
  if (!merge && !replace && !remove) {
@@ -51,7 +50,14 @@ const applyEntityChanges = (entities, changes, options) => {
51
50
  }
52
51
  const deepEqual = options.deepComparisonEnabled ? exports.optionalUtils.deepEqual : undefined;
53
52
  let result;
54
- for (const typename in entities) {
53
+ // TODO refactor to remove this Set
54
+ const typenames = new Set([
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),
59
+ ]);
60
+ for (const typename of typenames) {
55
61
  const entitiesToMerge = merge === null || merge === void 0 ? void 0 : merge[typename];
56
62
  const entitiesToReplace = replace === null || replace === void 0 ? void 0 : replace[typename];
57
63
  const entitiesToRemove = remove === null || remove === void 0 ? void 0 : remove[typename];
@@ -67,10 +73,11 @@ const applyEntityChanges = (entities, changes, options) => {
67
73
  entitiesToRemove === null || entitiesToRemove === void 0 ? void 0 : entitiesToRemove.forEach((id) => idsSet.add(String(id))); // String() because Object.keys always returns strings
68
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);
69
75
  if (totalKeysInResponse !== 0 && idsSet.size !== totalKeysInResponse) {
70
- 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);
71
78
  }
72
79
  }
73
- const oldEntities = entities[typename];
80
+ const oldEntities = (_d = entities[typename]) !== null && _d !== void 0 ? _d : exports.EMPTY_OBJECT;
74
81
  let newEntities;
75
82
  // remove
76
83
  entitiesToRemove === null || entitiesToRemove === void 0 ? void 0 : entitiesToRemove.forEach((id) => {
@@ -104,6 +111,7 @@ const applyEntityChanges = (entities, changes, options) => {
104
111
  continue;
105
112
  }
106
113
  result !== null && result !== void 0 ? result : (result = Object.assign({}, entities));
114
+ // @ts-expect-error fix later
107
115
  result[typename] = newEntities;
108
116
  }
109
117
  options.logsEnabled &&
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.1",
5
+ "version": "0.8.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",