react-redux-cache 0.16.1 → 0.17.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 +14 -16
- package/dist/createCache.d.ts +4 -0
- package/dist/createCache.js +8 -1
- package/dist/types.d.ts +5 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
# react-redux-cache (RRC)
|
|
11
11
|
|
|
12
|
-
### Supports both `Redux` and `Zustand`
|
|
12
|
+
### Supports both `Redux` and `Zustand` (check /example)
|
|
13
13
|
|
|
14
14
|
**Powerful**, **performant** yet **lightweight** data fetching and caching library that supports **normalization** unlike `React Query` and `RTK-Query`, while having similar but not over-engineered, simple interface. Another advantage over `RTK-Query` is that it **doesn't use Immer** ([perf issue](https://github.com/reduxjs/redux-toolkit/issues/4793)). Covered with tests, fully typed and written on Typescript.
|
|
15
15
|
|
|
@@ -48,7 +48,7 @@ Examples of states, generated by cache reducer from `/example` project:
|
|
|
48
48
|
},
|
|
49
49
|
getUsers: {
|
|
50
50
|
// example of paginated state under custom cache key
|
|
51
|
-
"
|
|
51
|
+
"feed": {
|
|
52
52
|
result: {items: [0,1,2], page: 1},
|
|
53
53
|
params: {page: 1}
|
|
54
54
|
}
|
|
@@ -86,7 +86,7 @@ Examples of states, generated by cache reducer from `/example` project:
|
|
|
86
86
|
},
|
|
87
87
|
getUsers: {
|
|
88
88
|
// example of paginated state under custom cache key
|
|
89
|
-
"
|
|
89
|
+
"feed": {
|
|
90
90
|
result: {
|
|
91
91
|
items: [
|
|
92
92
|
{id: 0, bank: {id: "0", name: "Bank 0"}, name: "User 0 *"},
|
|
@@ -137,13 +137,13 @@ Examples of states, generated by cache reducer from `/example` project:
|
|
|
137
137
|
|
|
138
138
|
```sh
|
|
139
139
|
# required
|
|
140
|
-
npm
|
|
140
|
+
npm i react-redux-cache react
|
|
141
141
|
|
|
142
142
|
# without react-redux
|
|
143
|
-
npm
|
|
143
|
+
npm i react-redux-cache react fast-deep-equal
|
|
144
144
|
|
|
145
145
|
# all required and optional peers
|
|
146
|
-
npm
|
|
146
|
+
npm i react-redux-cache react react-redux fast-deep-equal
|
|
147
147
|
```
|
|
148
148
|
|
|
149
149
|
### Initialization
|
|
@@ -221,15 +221,13 @@ const store = configureStore({
|
|
|
221
221
|
Zustand:
|
|
222
222
|
```typescript
|
|
223
223
|
type State = {[cache.name]: ReturnType<typeof reducer>}
|
|
224
|
-
type Actions = {dispatch: (action:
|
|
225
|
-
|
|
224
|
+
type Actions = {dispatch: (action: Parameters<typeof reducer>[1]) => void}
|
|
225
|
+
|
|
226
|
+
const initialState = getInitialState()
|
|
226
227
|
|
|
227
228
|
export const useStore = create<State & Actions>((set, get) => ({
|
|
228
|
-
|
|
229
|
-
[cache.name]: reducer(
|
|
230
|
-
dispatch: (action: CacheAction) => {
|
|
231
|
-
set({cache: reducer(get().cache, action)})
|
|
232
|
-
},
|
|
229
|
+
...initialState,
|
|
230
|
+
dispatch: (action) => set({[cache.name]: reducer(get()[cache.name], action)}),
|
|
233
231
|
}))
|
|
234
232
|
|
|
235
233
|
const store = {dispatch: useStore.getState().dispatch, getState: useStore.getState}
|
|
@@ -272,7 +270,7 @@ export const removeUser = (async (id, _, abortSignal) => {
|
|
|
272
270
|
|
|
273
271
|
### Usage
|
|
274
272
|
|
|
275
|
-
Please check `example/` folder (`npm run example` to run).
|
|
273
|
+
Please check `example/` folder (`npm run example` to run). There are examples for both Redux and Zustand.
|
|
276
274
|
|
|
277
275
|
#### UserScreen.tsx
|
|
278
276
|
```typescript
|
|
@@ -433,7 +431,7 @@ Here is an example of `getUsers` query configuration with pagination support. Yo
|
|
|
433
431
|
queries: {
|
|
434
432
|
getUsers: {
|
|
435
433
|
query: getUsers,
|
|
436
|
-
getCacheKey: () => '
|
|
434
|
+
getCacheKey: () => 'feed', // single cache key is used for all pages
|
|
437
435
|
mergeResults: (oldResult, {result: newResult}) => {
|
|
438
436
|
if (!oldResult || newResult.page === 1) {
|
|
439
437
|
return newResult
|
|
@@ -441,7 +439,7 @@ Here is an example of `getUsers` query configuration with pagination support. Yo
|
|
|
441
439
|
if (newResult.page === oldResult.page + 1) {
|
|
442
440
|
return {
|
|
443
441
|
...newResult,
|
|
444
|
-
items:
|
|
442
|
+
items: oldResult.items.concat(newResult.items),
|
|
445
443
|
}
|
|
446
444
|
}
|
|
447
445
|
return oldResult
|
package/dist/createCache.d.ts
CHANGED
|
@@ -175,6 +175,8 @@ export declare const withTypenames: <T extends Typenames = Typenames>() => {
|
|
|
175
175
|
useSelectEntityById: <TN extends keyof T>(id: Key | null | undefined, typename: TN) => T[TN] | undefined;
|
|
176
176
|
};
|
|
177
177
|
utils: {
|
|
178
|
+
/** Generates the initial state by calling a reducer. Not needed for redux — it already generates it the same way when creating the store. */
|
|
179
|
+
getInitialState: () => import("./types").CacheState<T, QP, QR, MP, MR>;
|
|
178
180
|
/** Apply changes to the entities map.
|
|
179
181
|
* @returns `undefined` if nothing to change, otherwise new `EntitiesMap<T>` with applied changes. */
|
|
180
182
|
applyEntityChanges: (entities: Parameters<typeof applyEntityChanges<T>>[0], changes: Parameters<typeof applyEntityChanges<T>>[1]) => import("./types").EntitiesMap<T> | undefined;
|
|
@@ -357,6 +359,8 @@ export declare const createCache: <N extends string, QP, QR, MP, MR>(partialCach
|
|
|
357
359
|
useSelectEntityById: <TN extends string>(id: Key | null | undefined, typename: TN) => object | undefined;
|
|
358
360
|
};
|
|
359
361
|
utils: {
|
|
362
|
+
/** Generates the initial state by calling a reducer. Not needed for redux — it already generates it the same way when creating the store. */
|
|
363
|
+
getInitialState: () => import("./types").CacheState<Typenames, QP, QR, MP, MR>;
|
|
360
364
|
/** Apply changes to the entities map.
|
|
361
365
|
* @returns `undefined` if nothing to change, otherwise new `EntitiesMap<T>` with applied changes. */
|
|
362
366
|
applyEntityChanges: (entities: import("./types").EntitiesMap<Typenames>, changes: import("./types").EntityChanges<Typenames>) => import("./types").EntitiesMap<Typenames> | undefined;
|
package/dist/createCache.js
CHANGED
|
@@ -58,11 +58,13 @@ const withTypenames = () => {
|
|
|
58
58
|
// actions
|
|
59
59
|
const actions = (0, createActions_1.createActions)(cache.name);
|
|
60
60
|
const { updateQueryStateAndEntities, updateMutationStateAndEntities, mergeEntityChanges, invalidateQuery, clearQueryState, clearMutationState, clearCache, } = actions;
|
|
61
|
+
// reducer
|
|
62
|
+
const reducer = (0, createCacheReducer_1.createCacheReducer)(actions, Object.keys(cache.queries), cache.options);
|
|
61
63
|
return {
|
|
62
64
|
/** Keeps all options, passed while creating the cache. */
|
|
63
65
|
cache,
|
|
64
66
|
/** Reducer of the cache, should be added to redux store. */
|
|
65
|
-
reducer
|
|
67
|
+
reducer,
|
|
66
68
|
actions: {
|
|
67
69
|
/** Updates query state, and optionally merges entity changes in a single action. */
|
|
68
70
|
updateQueryStateAndEntities,
|
|
@@ -147,6 +149,11 @@ const withTypenames = () => {
|
|
|
147
149
|
},
|
|
148
150
|
},
|
|
149
151
|
utils: {
|
|
152
|
+
/** Generates the initial state by calling a reducer. Not needed for redux — it already generates it the same way when creating the store. */
|
|
153
|
+
getInitialState: () => {
|
|
154
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
155
|
+
return reducer(undefined, utilsAndConstants_1.EMPTY_OBJECT);
|
|
156
|
+
},
|
|
150
157
|
/** Apply changes to the entities map.
|
|
151
158
|
* @returns `undefined` if nothing to change, otherwise new `EntitiesMap<T>` with applied changes. */
|
|
152
159
|
applyEntityChanges: (entities, changes) => {
|
package/dist/types.d.ts
CHANGED
|
@@ -119,6 +119,11 @@ params: P,
|
|
|
119
119
|
store: Store) => Promise<QueryResponse<R>>;
|
|
120
120
|
export type NormalizedQuery<T extends Typenames = Typenames, P = unknown, R = unknown> = (...args: Parameters<Query<P, R>>) => Promise<NormalizedQueryResponse<T, R>>;
|
|
121
121
|
export type QueryState<P, R> = MutationState<P, R> & {
|
|
122
|
+
/**
|
|
123
|
+
* Timestamp in milliseconds, after which state is considered expired.
|
|
124
|
+
* Hooks may refetch the query again when component mounts, cache key or skip option change, depending on the fetch policy.
|
|
125
|
+
* Client query calls also start making fetch if onlyIfExpired argument is truthy.
|
|
126
|
+
* */
|
|
122
127
|
expiresAt?: number;
|
|
123
128
|
};
|
|
124
129
|
export type UseQueryOptions<N extends string, T extends Typenames, QK extends keyof (QP & QR), QP, QR, MP, MR> = {
|
package/package.json
CHANGED
|
@@ -2,14 +2,15 @@
|
|
|
2
2
|
"name": "react-redux-cache",
|
|
3
3
|
"author": "Alexander Danilov",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.17.0",
|
|
6
6
|
"description": "Powerful data fetching and caching library for Redux and Zustand that supports normalization.",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"types": "dist/index.d.ts",
|
|
9
9
|
"scripts": {
|
|
10
|
-
"example": "(cd example && yarn && yarn
|
|
10
|
+
"example": "(cd example && yarn && yarn dev)",
|
|
11
11
|
"clean": "rm -rf dist",
|
|
12
12
|
"lint": "yarn eslint src",
|
|
13
|
+
"lint-fix": "yarn eslint --fix src",
|
|
13
14
|
"build": "yarn clean && yarn lint && tsc && rm -rf dist/testing && rm -rf dist/__tests__",
|
|
14
15
|
"test": "node node_modules/jest/bin/jest.js",
|
|
15
16
|
"preminor-rc": "yarn build && npm version preminor --preid rc",
|