You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: dist/README.md
+334-1Lines changed: 334 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,4 +6,337 @@ You might have written code that uses redux and redux-saga to implement data fet
6
6
7
7
All you need to do now, is to instantiate redux-saga-query and use functions that it provides: _reducer_ - that you just need to connect to your store and it will manage data, _query_ - for requesting data that needs to be cached, _mutation_ - for requesting data without caching, and more.
8
8
9
-
The main idea is that you can request your data from anywhere in your sagas and not to worry about managing it's state.
9
+
The main idea is that you can request your data from anywhere in your sagas and not worry about managing its state.
10
+
11
+
This package has only one dependency - [redux-saga](https://github.com/redux-saga/redux-sag) which needs to be installed in your project.
12
+
13
+
# Gettings started
14
+
15
+
## Install
16
+
17
+
```sh
18
+
$ npm install redux-saga-query
19
+
```
20
+
21
+
or
22
+
23
+
```sh
24
+
$ yarn add redux-saga-query
25
+
```
26
+
27
+
or
28
+
29
+
```sh
30
+
$ pnpm add redux-saga-query
31
+
```
32
+
33
+
## Usage Example
34
+
35
+
Suppose you have a redux in your project. It can be vanilla redux or [redux-toolkit](https://redux-toolkit.js.org/), doesn't matter. It can even be a custom I/O environment like redux, since redux-saga [allows you to do that](https://redux-saga.js.org/docs/advanced/UsingRunSaga).
36
+
37
+
Since you have storage, you have some data that needs to be derived from some place, for example, from some API. This package gives you an `initSagaQuery` function which needs to be called once per domain. Domain is like a record in store that will be responsible for managing its data.
38
+
39
+
```
40
+
import { initSagaQuery } from "redux-saga-query";
41
+
42
+
var DOMAIN = "api";
43
+
44
+
var { reducer, query, mutation, selector } = initSagaQuery({
45
+
domain: DOMAIN,
46
+
query: {
47
+
staleTime: 1000 * 60,
48
+
},
49
+
});
50
+
51
+
var apiReducer = {
52
+
name: DOMAIN,
53
+
reducer,
54
+
};
55
+
56
+
export { apiReducer, query, mutation, selector };
57
+
```
58
+
59
+
Then you need to connect `apiReducer` to your redux store:
60
+
61
+
```
62
+
import { apiReducer } from "./api";
63
+
64
+
export var rootReducer = {
65
+
[apiReducer.name]: apiReducer.reducer,
66
+
};
67
+
```
68
+
69
+
Now you are ready to use other functions provided by `initSagaQuery` in your application.
Here we used a `query` function to retrieve a list of books from an external api. Under the hood this function dispatches `REQUEST` action if data is stale, makes a new call using your function, caches the result to storage and returns it back where you called it. If data is not stale, it doesn't make new requests and returns back cached data from storage. More information in [Documentation](https://github.com/zavvdev/redux-saga-query/tree/main?tab=readme-ov-file#documentation) and [Example](https://github.com/zavvdev/redux-saga-query/tree/main/example).
87
+
88
+
# Documentation
89
+
90
+
## API
91
+
92
+
### initSagaQuery
93
+
94
+
Use this function to initialize redux-saga-query. You should call it once per domain. Domain is responsible for storing cached data. It's just an object with keys that store your data. You can have one or multiple domains. For example, one common `api` domain.
95
+
96
+
**Arguments**
97
+
98
+
`domain`
99
+
100
+
-**Required**: Yes
101
+
-**Type**: String
102
+
-**Description**: Should be unique for each function call
103
+
104
+
`extractError`
105
+
106
+
-**Required**: No
107
+
-**Type**: Function
108
+
-**Description**: Accepts an error thrown by `fn` function of query or mutation and returns some value. Value returned by this function will be re-thrown and stored in domain storage, so it should be serializable. Applies for both queries and mutations
109
+
-**Default value**: Function that extracts a message from error or error name if message is missing. If both are missing - returns _"An error occurred"_ string
110
+
111
+
`retry`
112
+
113
+
-**Required**: No
114
+
-**Type**: Number
115
+
-**Description**: Amount of retries that should be done for query and mutation `fn` function in case it throws an error
116
+
117
+
`retryDelay`
118
+
119
+
-**Required**: No
120
+
-**Type**: Number
121
+
-**Description**: Amount of time in milliseconds that should pass until next retry will be executed in case `fn` function of query or mutation throws an error
122
+
123
+
`query`
124
+
125
+
-**Required**: Yes
126
+
-**Type**: Object
127
+
-**Description**: [Configuration](https://github.com/zavvdev/redux-saga-query/blob/3cc865dafe4194b1caccb39574e4a87c2ca18962/src/index.d.ts#L1) for queries
128
+
129
+
`staleTime`
130
+
131
+
-**Required**: Yes
132
+
-**Type**: Number
133
+
-**Description**: Amount of time in milliseconds that should pass, so query data can be considered as stale. If data is stale, it will be requested again next time when query gets executed
134
+
135
+
`extractError`
136
+
137
+
-**Required**: No
138
+
-**Type**: Function
139
+
-**Description**: Same as global, but applies only for queries
140
+
-**Default value**: Same as global
141
+
142
+
`retry`
143
+
144
+
-**Required**: No
145
+
-**Type**: Number
146
+
-**Description**: Same as global, but applies only for queries
147
+
-**Default value**: 3
148
+
149
+
`retryDelay`
150
+
151
+
-**Required**: No
152
+
-**Type**: Number
153
+
-**Description**: Same as global, but applies only for queries
154
+
-**Default value**: Exponential backoff
155
+
156
+
`mutation`
157
+
158
+
-**Required**: No
159
+
-**Type**: Object
160
+
-**Description**: [Configuration](https://github.com/zavvdev/redux-saga-query/blob/3cc865dafe4194b1caccb39574e4a87c2ca18962/src/index.d.ts#L8) for mutations
161
+
162
+
`extractError`
163
+
164
+
-**Required**: No
165
+
-**Type**: Function
166
+
-**Description**: Same as global, but applies only for mutations
167
+
-**Default value**: Same as global
168
+
169
+
`retry`
170
+
171
+
-**Required**: No
172
+
-**Type**: Number
173
+
-**Description**: Same as global, but applies only for mutations
174
+
-**Default value**: 0
175
+
176
+
`retryDelay`
177
+
178
+
-**Required**: No
179
+
-**Type**: Number
180
+
-**Description**: Same as global, but applies only for mutations
181
+
182
+
`createInstanceId`
183
+
184
+
-**Required**: No
185
+
-**Type**: Function
186
+
-**Description**: Returns a string that is used as unique identifier for constructing action type patterns
187
+
-**Default value**: Function that returns a string with number counted for each created domain with _initSagaQuery_ function
188
+
189
+
### Key
190
+
191
+
-**Type**: [Array<string | number | bigint | boolean>](https://github.com/zavvdev/redux-saga-query/blob/3cc865dafe4194b1caccb39574e4a87c2ca18962/src/index.d.ts#L14)
192
+
-**Description**: Unique identifier for each query and mutation
-**Description**: Object in domain storage that represents query state. Consists of next fields:
198
+
199
+
`isLoading`
200
+
201
+
-**Type**: Boolean
202
+
-**Description**: Has value `true` if `fn` function of query is being requested for the first time
203
+
204
+
`isFetching`
205
+
206
+
-**Type**: Boolean
207
+
-**Description**: Has value `true` if `fn` function of query is being requested at any time
208
+
209
+
`isLoaded`
210
+
211
+
-**Type**: Boolean
212
+
-**Description**: Has value `true` if `fn` function of query has successfully derived its data
213
+
214
+
`isError`
215
+
216
+
-**Type**: Boolean
217
+
-**Description**: Has value `true` if `fn` function of query has thrown an error or any error has been thrown during query execution
218
+
219
+
`isValid`
220
+
221
+
-**Type**: Boolean
222
+
-**Description**: Has value `true` if query data doesn't need to be requested again. In other words, it's not stale because `staleTime` milliseconds has not passed yet. But keep in mind that this value won't be updated automatically if nothing is being requested yet using the respective query Key. For example, if you have data that is valid and you didn't request it again after it had become invalid, this field will still show you that it's valid even if its staleTime had already passed. The only way to update state and get fresh status of this field is to trigger request again somewhere
223
+
224
+
`isReset`
225
+
226
+
-**Type**: Boolean
227
+
-**Description**: Has value `true` if fn query data is in reset state. Technically, a reset state is when you have no data but a query record is present in the domain state. Redux-saga-query does not reset your data. It can only be reset by you manually by calling [reset](https://github.com/zavvdev/redux-saga-query/tree/main?tab=readme-ov-file#initsagaquery) function
228
+
229
+
`timestamp`
230
+
231
+
-**Type**: Number | Undefined
232
+
-**Description**: Has the last timestamp when `fn` function of query has successfully derived its data
233
+
234
+
`data`
235
+
236
+
-**Type**: Unknown | Null
237
+
-**Description**: Data derived from `fn` function of query
238
+
239
+
`error`
240
+
241
+
-**Type**: Unknown | Null
242
+
-**Description**: Value returned by `extractError` function
-**Description**: Object in domain storage that represents mutation state. Consists of next fields:
248
+
249
+
`isLoading`
250
+
251
+
-**Type**: Boolean
252
+
-**Description**: Has value `true` if `fn` function of mutation is being executed
253
+
254
+
`isLoaded`
255
+
256
+
-**Type**: Boolean
257
+
-**Description**: Has value `true` if `fn` function of mutation has successfully derived its data
258
+
259
+
`isError`
260
+
261
+
-**Type**: Boolean
262
+
-**Description**: Has value `true` if `fn` function of mutation has thrown an error or any error has been thrown during mutation execution
263
+
264
+
`data`
265
+
266
+
-**Type**: Unknown | Null
267
+
-**Description**: Data derived from `fn` function of mutation
268
+
269
+
`error`
270
+
271
+
-**Type**: Unknown | Null
272
+
-**Description**: Value returned by `extractError` function
273
+
274
+
### reducer
275
+
276
+
-**Type**: Function
277
+
-**Description**: Used for managing your query and mutation data. You only need to connect this function to your store
278
+
-**Arguments**:
279
+
280
+
`state` - previous state
281
+
282
+
`action` - dispatched action
283
+
284
+
-**Returns**: Next state
285
+
286
+
### selector
287
+
288
+
-**Type**: Function
289
+
-**Description**: Selects QueryRecord or Mutation Record from the storage
290
+
-**Arguments**:
291
+
292
+
`key` - [Key](https://github.com/zavvdev/redux-saga-query/tree/main?tab=readme-ov-file#key) that represents specific query. Should not be partial.
293
+
294
+
-**Returns**: [QueryRecord](https://github.com/zavvdev/redux-saga-query/tree/main?tab=readme-ov-file#queryrecord), [MutationRecord](https://github.com/zavvdev/redux-saga-query/tree/main?tab=readme-ov-file#mutationrecord) or null
295
+
296
+
### query
297
+
298
+
-**Type**: Function
299
+
-**Arguments**: Object with next fields:
300
+
301
+
`key` - [Key](https://github.com/zavvdev/redux-saga-query/tree/main?tab=readme-ov-file#key) that represents this query. Should be unique for each query
302
+
303
+
`fn` - Any function that returns some serializable data
304
+
305
+
`options` - Fully partial [options](https://github.com/zavvdev/redux-saga-query/blob/272e83e5e8038f11e0231e6f4700f56e8d096b94/src/index.d.ts#L1) that will be applied only for this specific query. Represented as an object the same as in `initSagaQuery`_query_ argument but fully partial
306
+
307
+
-**Returns**: Generator function which yields redux-saga effects. Returns the result of `fn` if it has successfully derived data or throws an error with value returned from `extractError` function
308
+
-**Description**: Caches the data returned from `fn` function
309
+
310
+
### mutation
311
+
312
+
-**Type**: Function
313
+
-**Arguments**: Object with next fields:
314
+
315
+
`key` - [Key](https://github.com/zavvdev/redux-saga-query/tree/main?tab=readme-ov-file#key) that represents this mutation. Should be unique for each mutation
316
+
317
+
`fn` - Any function that returns some serializable data
318
+
319
+
`options` - [Options](https://github.com/zavvdev/redux-saga-query/blob/272e83e5e8038f11e0231e6f4700f56e8d096b94/src/index.d.ts#L8) that will be applied only for this specific mutation. Represented as an object the same as in `initSagaQuery`_mutation_ argument
320
+
321
+
-**Returns**: Generator function which yields redux-saga effects. Returns the result of `fn` if it has successfully derived data or throws an error with value returned from `extractError` function
322
+
-**Description**: Does not cache the data returned from `fn` function
323
+
324
+
### invalidate
325
+
326
+
-**Type**: Function
327
+
-**Arguments**:
328
+
329
+
`key` - [Key](https://github.com/zavvdev/redux-saga-query/tree/main?tab=readme-ov-file#key) that represents any query with exact or partial match
330
+
331
+
-**Returns**: Void
332
+
-**Description**: Searches in domain for any partially matched keys. If found any - invalidates their data if its valid and not currently in progress (isLoading or isFetching)
333
+
334
+
### reset
335
+
336
+
-**Type**: Function
337
+
-**Arguments**:
338
+
339
+
`key` - [Key](https://github.com/zavvdev/redux-saga-query/tree/main?tab=readme-ov-file#key) that represents any query with exact or partial match
340
+
341
+
-**Returns**: Void
342
+
-**Description**: Searches in domain for any partially matched keys. If found any - resets their data if it hasn't been reset yet. Reset means that domain still has a record for this specific query but without any data
0 commit comments