Skip to content

Commit 6d9365d

Browse files
feat: add bindings for @urql/exchange-persisted-fetch and @urql/exchange-refocus (#251)
1 parent 1463301 commit 6d9365d

File tree

6 files changed

+256
-160
lines changed

6 files changed

+256
-160
lines changed

__tests__/Client_test.res

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -210,34 +210,30 @@ describe("Client", () => {
210210
}))
211211

212212
describe("Ecosystem exchanges", () => {
213-
describe("retryExchange", () => {
214-
it("should apply the default retryExchange options from urql if none are applied", () => {
215-
let retryExchangeOptions = Client.Exchanges.makeRetryExchangeOptions()
213+
describe("persistedFetchExchange", () => {
214+
it("should return None for all persistedFetchExchange options if unspecified", () => {
215+
let persistedFetchExchangeOptions = Client.Exchanges.makePersistedFetchExchangeOptions()
216216

217217
open Expect
218-
expect(retryExchangeOptions) |> toEqual({
219-
Client.Exchanges.initialDelayMs: None,
220-
maxDelayMs: None,
221-
maxNumberAttempts: None,
222-
randomDelay: None,
223-
retryIf: None,
218+
expect(persistedFetchExchangeOptions) |> toEqual({
219+
Client.Exchanges.preferGetForPersistedQueries: None,
220+
generateHash: None,
224221
})
225222
})
226223

227-
it("should apply any specified options to the retryExchange", () => {
228-
let retryExchangeOptions = Client.Exchanges.makeRetryExchangeOptions(
229-
~initialDelayMs=200,
230-
~randomDelay=false,
224+
it("should apply any specified options to the persistedFetchExchange", () => {
225+
let hashFn = (query, _) => Js.Promise.resolve(Js.String.normalize(query))
226+
227+
let persistedFetchExchangeOptions = Client.Exchanges.makePersistedFetchExchangeOptions(
228+
~preferGetForPersistedQueries=true,
229+
~generateHash=hashFn,
231230
(),
232231
)
233232

234233
open Expect
235-
expect(retryExchangeOptions) |> toEqual({
236-
Client.Exchanges.initialDelayMs: Some(200),
237-
maxDelayMs: None,
238-
maxNumberAttempts: None,
239-
randomDelay: Some(false),
240-
retryIf: None,
234+
expect(persistedFetchExchangeOptions) |> toEqual({
235+
Client.Exchanges.preferGetForPersistedQueries: Some(true),
236+
generateHash: Some(hashFn),
241237
})
242238
})
243239
})
@@ -270,5 +266,37 @@ describe("Client", () => {
270266
})
271267
})
272268
})
269+
270+
describe("retryExchange", () => {
271+
it("should apply the default retryExchange options from urql if none are applied", () => {
272+
let retryExchangeOptions = Client.Exchanges.makeRetryExchangeOptions()
273+
274+
open Expect
275+
expect(retryExchangeOptions) |> toEqual({
276+
Client.Exchanges.initialDelayMs: None,
277+
maxDelayMs: None,
278+
maxNumberAttempts: None,
279+
randomDelay: None,
280+
retryIf: None,
281+
})
282+
})
283+
284+
it("should apply any specified options to the retryExchange", () => {
285+
let retryExchangeOptions = Client.Exchanges.makeRetryExchangeOptions(
286+
~initialDelayMs=200,
287+
~randomDelay=false,
288+
(),
289+
)
290+
291+
open Expect
292+
expect(retryExchangeOptions) |> toEqual({
293+
Client.Exchanges.initialDelayMs: Some(200),
294+
maxDelayMs: None,
295+
maxNumberAttempts: None,
296+
randomDelay: Some(false),
297+
retryIf: None,
298+
})
299+
})
300+
})
273301
})
274302
})

docs/exchanges.md

Lines changed: 91 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -165,78 +165,77 @@ let client = Client.make(
165165
~exchanges=[
166166
Client.Exchanges.dedupExchange,
167167
Client.Exchanges.cacheExchange,
168-
Client.Exchanges.multipartFetchExchange
168+
Client.Exchanges.multipartFetchExchange,
169169
],
170170
()
171171
)
172172
```
173173

174174
Read more on the `multipartFetchExchange` [here](https://github.com/FormidableLabs/urql/tree/main/exchanges/multipart-fetch).
175175

176-
### `retryExchange`
176+
### `persistedFetchExchange`
177177

178-
The `retryExchange` is useful for retrying particular operations. By default, adding this exchange with the base options will retry any operations that failed due to network errors. However, we can customize the exchange to catch more specific error cases as well.
178+
The `persistedFetchExchange` adds support for [persisted queries](https://www.onegraph.com/docs/persisted_queries.html), building off of the standard `fetchExchange`.
179179

180-
To use the `retryExchange`, add the package to your dependencies:
180+
To use the `persistedFetchExchange`, add the package to your dependencies:
181181

182182
```sh
183-
yarn add @urql/exchange-retry
183+
yarn add @urql/exchange-persisted-fetch
184184
```
185185

186-
Then, add the exchange to your array of `exchanges`, specifying the options you want to configure:
186+
Then, add the exchange to your array of `exchanges`, sepcifying the options you want to configure:
187187

188188
```rescript
189189
open ReasonUrql
190190
191-
let retryExchangeOptions =
192-
Client.Exchanges.makeRetryExchangeOptions(~initialDelayMs=2000, ~randomDelay=false, ())
191+
let persistedFetchExchangeOptions = Client.Exchanges.makePersistedFetchExchangeOptions(
192+
~preferGetForPersistedQueries=true,
193+
(),
194+
)
193195
194196
let client = Client.make(
195197
~url="http://localhost:3000",
196198
~exchanges=[
197199
Client.Exchanges.dedupExchange,
198200
Client.Exchanges.cacheExchange,
199-
Client.Exchanges.retryExchange(retryExchangeOptions),
200-
Client.Exchanges.fetchExchange
201+
Client.Exchanges.persistedFetchExchange(persistedFetchExchangeOptions),
202+
// Keep the fetchExchange to handle mutations.
203+
// The persistedFetchExchange only handles queries.
204+
Client.Exchanges.fetchExchange,
201205
],
202206
()
203207
)
204208
```
205209

206-
By default, `urql` will apply the following configuration for you:
210+
Read more about the `persistedFetchExchange` [here](https://github.com/FormidableLabs/urql/tree/main/exchanges/persisted-fetch).
207211

208-
```typescript
209-
{
210-
initialDelayMs: 1000,
211-
maxDelayMs: 15000,
212-
randomDelay: true,
213-
maxNumberAttempts: 2,
214-
retryIf: err => err && err.networkError,
215-
}
212+
### `refocusExchange`
213+
214+
The `refocusExchange` allows `reason-urql` to redispatch active operations when the window regains focus.
215+
216+
To use the `refocusExchange`, add the package to your dependencies:
217+
218+
```sh
219+
yarn add @urql/exchange-refocus
216220
```
217221

218-
If you want to use the defaults from `urql`, call `makeRetryExchangeOptions` with just a `unit` parameter.
222+
Then, add the exchange to your array of `exchanges`. The `refocusExchange` should be added _after_ the `dedupeExchange`, to prevent doing additional work on requests that are later deduplicated, and _before_ the `fetchExchange`:
219223

220224
```rescript
221225
open ReasonUrql
222226
223-
let retryExchangeOptions =
224-
Client.Exchanges.makeRetryExchangeOptions()
225-
226227
let client = Client.make(
227228
~url="http://localhost:3000",
228229
~exchanges=[
229230
Client.Exchanges.dedupExchange,
231+
Client.Exchanges.refocusExchange(),
230232
Client.Exchanges.cacheExchange,
231-
Client.Exchanges.retryExchange(retryExchangeOptions),
232-
Client.Exchanges.fetchExchange
233+
Client.Exchanges.fetchExchange,
233234
],
234235
()
235236
)
236237
```
237238

238-
Read more on the `retryExchange` [here](https://formidable.com/open-source/urql/docs/advanced/retry-operations/).
239-
240239
### `requestPolicyExchange`
241240

242241
The `requestPolicyExchange` allows `reason-urql` to automatically upgrade an operation's `requestPolicy` on a time-to-live basis. When the specified TTL has elapsed, `reason-urql` will either:
@@ -270,14 +269,78 @@ let client = Client.make(
270269
Client.Exchanges.dedupExchange,
271270
Client.Exchanges.cacheExchange,
272271
Client.Exchanges.requestPolicyExchange(requestPolicyExchangeOptions),
273-
Client.Exchanges.fetchExchange
272+
Client.Exchanges.fetchExchange,
274273
],
275274
()
276275
)
277276
```
278277

279278
Read more about the `requestPolicyExchange` [here](https://github.com/FormidableLabs/urql/tree/main/exchanges/request-policy).
280279

280+
### `retryExchange`
281+
282+
The `retryExchange` is useful for retrying particular operations. By default, adding this exchange with the base options will retry any operations that failed due to network errors. However, we can customize the exchange to catch more specific error cases as well.
283+
284+
To use the `retryExchange`, add the package to your dependencies:
285+
286+
```sh
287+
yarn add @urql/exchange-retry
288+
```
289+
290+
Then, add the exchange to your array of `exchanges`, specifying the options you want to configure:
291+
292+
```rescript
293+
open ReasonUrql
294+
295+
let retryExchangeOptions =
296+
Client.Exchanges.makeRetryExchangeOptions(~initialDelayMs=2000, ~randomDelay=false, ())
297+
298+
let client = Client.make(
299+
~url="http://localhost:3000",
300+
~exchanges=[
301+
Client.Exchanges.dedupExchange,
302+
Client.Exchanges.cacheExchange,
303+
Client.Exchanges.retryExchange(retryExchangeOptions),
304+
Client.Exchanges.fetchExchange,
305+
],
306+
()
307+
)
308+
```
309+
310+
By default, `urql` will apply the following configuration for you:
311+
312+
```typescript
313+
{
314+
initialDelayMs: 1000,
315+
maxDelayMs: 15000,
316+
randomDelay: true,
317+
maxNumberAttempts: 2,
318+
retryIf: err => err && err.networkError,
319+
}
320+
```
321+
322+
If you want to use the defaults from `urql`, call `makeRetryExchangeOptions` with just a `unit` parameter.
323+
324+
```rescript
325+
open ReasonUrql
326+
327+
let retryExchangeOptions =
328+
Client.Exchanges.makeRetryExchangeOptions()
329+
330+
let client = Client.make(
331+
~url="http://localhost:3000",
332+
~exchanges=[
333+
Client.Exchanges.dedupExchange,
334+
Client.Exchanges.cacheExchange,
335+
Client.Exchanges.retryExchange(retryExchangeOptions),
336+
Client.Exchanges.fetchExchange,
337+
],
338+
()
339+
)
340+
```
341+
342+
Read more on the `retryExchange` [here](https://formidable.com/open-source/urql/docs/advanced/retry-operations/).
343+
281344
## Custom Exchanges
282345

283346
`reason-urql` also allows you to write your own exchanges to modify outgoing GraphQL requests and incoming responses. To read up on the basics of exchanges, check out the excellent [`urql` documentation](https://formidable.com/open-source/urql/docs/concepts/exchanges/).

package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@
3535
"@babel/plugin-transform-modules-commonjs": "^7.12.1",
3636
"@glennsl/bs-jest": "^0.6.0",
3737
"@reasonml-community/graphql-ppx": "^1.0.1",
38-
"@urql/exchange-multipart-fetch": "^0.1.11",
39-
"@urql/exchange-retry": "^0.2.0",
4038
"all-contributors-cli": "^6.19.0",
4139
"babel-jest": "^26.6.3",
4240
"bs-platform": "^8.3.2",

0 commit comments

Comments
 (0)