From 40911d2f2fa4813c911fd4debcdbc139979f4e5d Mon Sep 17 00:00:00 2001 From: Jovi De Croock Date: Thu, 16 Mar 2023 15:08:21 +0100 Subject: [PATCH] major(core): remove default exchanges (#3033) Co-authored-by: Phil Pluckthun --- .changeset/calm-buckets-scream.md | 18 +++ .changeset/honest-apples-join.md | 6 + docs/advanced/authoring-exchanges.md | 1 - docs/advanced/subscriptions.md | 18 ++- docs/api/core.md | 11 +- docs/architecture.md | 3 +- docs/basics/core.md | 12 +- docs/basics/react-preact.md | 8 +- docs/basics/svelte.md | 8 +- docs/basics/vue.md | 10 +- exchanges/auth/src/authExchange.test.ts | 5 +- exchanges/context/src/context.test.ts | 5 +- .../src/ast/schemaPredicates.test.ts | 6 +- .../graphcache/src/cacheExchange.test.ts | 116 ++++++++++++++---- .../graphcache/src/offlineExchange.test.ts | 10 +- exchanges/refocus/src/refocusExchange.test.ts | 5 +- .../src/requestPolicyExchange.test.ts | 5 +- exchanges/retry/src/retryExchange.test.ts | 5 +- packages/core/src/client.test.ts | 11 +- packages/core/src/client.ts | 13 +- packages/core/src/exchanges/index.ts | 15 --- .../src/__tests__/with-urql-client.spec.ts | 19 ++- packages/preact-urql/README.md | 4 +- packages/preact-urql/src/context.ts | 37 +++--- packages/react-urql/src/context.ts | 38 +++--- packages/vue-urql/src/useClient.test.ts | 1 + 26 files changed, 247 insertions(+), 143 deletions(-) create mode 100644 .changeset/calm-buckets-scream.md create mode 100644 .changeset/honest-apples-join.md diff --git a/.changeset/calm-buckets-scream.md b/.changeset/calm-buckets-scream.md new file mode 100644 index 0000000000..c9de0dd453 --- /dev/null +++ b/.changeset/calm-buckets-scream.md @@ -0,0 +1,18 @@ +--- +'@urql/core': major +--- + +Remove `defaultExchanges` from `@urql/core` and make `exchanges` a required property on `Client` construction. +In doing so we make the `urql` package more tree-shakeable as the three default exchanges are in no code paths +meaning they can be removed if not used. + +A migration would look as follows if you are currently creating a client without exchanges + +```js +import { createClient, cacheExchange, fetchExchange } from '@urql/core' + +const client = createClient({ + url: '', + exchanges: [cacheExchange, fetchExchange] +}); +``` diff --git a/.changeset/honest-apples-join.md b/.changeset/honest-apples-join.md new file mode 100644 index 0000000000..dc5efc5d07 --- /dev/null +++ b/.changeset/honest-apples-join.md @@ -0,0 +1,6 @@ +--- +'@urql/preact': major +'urql': major +--- + +Remove the default `Client` from `Context`. Previously, `urql` kept a legacy default client in its context, with default exchanges and calling an API at `/graphql`. This has now been removed and you will have to create your own `Client` if you were relying on this behaviour. diff --git a/docs/advanced/authoring-exchanges.md b/docs/advanced/authoring-exchanges.md index 41a342a9a6..2710f56bd7 100644 --- a/docs/advanced/authoring-exchanges.md +++ b/docs/advanced/authoring-exchanges.md @@ -283,7 +283,6 @@ The default order of exchanges is: ```js import { dedupExchange, cacheExchange, fetchExchange } from 'urql'; -// Also exported as `defaultExchanges`: [dedupExchange, cacheExchange, fetchExchange]; ``` diff --git a/docs/advanced/subscriptions.md b/docs/advanced/subscriptions.md index f626c9b46b..5b94634e1f 100644 --- a/docs/advanced/subscriptions.md +++ b/docs/advanced/subscriptions.md @@ -13,12 +13,14 @@ APIs and ability to handle GraphQL subscriptions. To add support for subscriptions we need to add the `subscriptionExchange` to our `Client`. ```js -import { Client, defaultExchanges, subscriptionExchange } from 'urql'; +import { Client, dedupExchange, cacheExchange, fetchExchange, subscriptionExchange } from 'urql'; const client = new Client({ url: 'http://localhost:3000/graphql', exchanges: [ - ...defaultExchanges, + dedupExchange, + cacheExchange, + fetchExchange, subscriptionExchange({ forwardSubscription, }), @@ -45,7 +47,7 @@ object with a `.subscribe()` method accepting an observer. For backends supporting `graphql-ws`, we recommend using the [graphql-ws](https://github.com/enisdenjo/graphql-ws) client. ```js -import { createClient, defaultExchanges, subscriptionExchange } from 'urql'; +import { createClient, dedupExchange, cacheExchange, fetchExchange, subscriptionExchange } from 'urql'; import { createClient as createWSClient } from 'graphql-ws'; const wsClient = createWSClient({ @@ -55,7 +57,9 @@ const wsClient = createWSClient({ const client = createClient({ url: '/graphql', exchanges: [ - ...defaultExchanges, + dedupExchange, + cacheExchange, + fetchExchange, subscriptionExchange({ forwardSubscription: request => ({ subscribe: sink => ({ @@ -81,7 +85,7 @@ package](https://github.com/apollographql/subscriptions-transport-ws) can be use > The `subscriptions-transport-ws` package isn't actively maintained. If your API supports the new protocol or you can swap the package out, consider using [`graphql-ws`](#setting-up-graphql-ws) instead. ```js -import { Client, defaultExchanges, subscriptionExchange } from 'urql'; +import { Client, dedupExchange, cacheExchange, fetchExchange, subscriptionExchange } from 'urql'; import { SubscriptionClient } from 'subscriptions-transport-ws'; const subscriptionClient = new SubscriptionClient('ws://localhost/graphql', { reconnect: true }); @@ -89,7 +93,9 @@ const subscriptionClient = new SubscriptionClient('ws://localhost/graphql', { re const client = new Client({ url: '/graphql', exchanges: [ - ...defaultExchanges, + dedupExchange, + cacheExchange, + fetchExchange, subscriptionExchange({ forwardSubscription: request => subscriptionClient.request(request), }), diff --git a/docs/api/core.md b/docs/api/core.md index b417e9b85d..7c9e5092c0 100644 --- a/docs/api/core.md +++ b/docs/api/core.md @@ -22,7 +22,7 @@ It accepts several options on creation. | Input | Type | Description | | ----------------- | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `exchanges` | `Exchange[]` | An array of `Exchange`s that the client should use instead of the list of `defaultExchanges` | +| `exchanges` | `Exchange[]` | An array of `Exchange`s that the client should use | | `url` | `string` | The GraphQL API URL as used by `fetchExchange` | | `fetchOptions` | `RequestInit \| () => RequestInit` | Additional `fetchOptions` that `fetch` in `fetchExchange` should use to make a request | | `fetch` | `typeof fetch` | An alternative implementation of `fetch` that will be used by the `fetchExchange` instead of `window.fetch` | @@ -523,15 +523,6 @@ this problem. It's used by the [`Client`](#client) when the `maskTypename` option is enabled. -### defaultExchanges - -This is an array of the default `Exchange`s that the `Client` uses when the `exchanges` option isn't -passed. - -```js -const defaultExchanges = [dedupExchange, cacheExchange, fetchExchange]; -``` - ### composeExchanges This utility accepts an array of `Exchange`s and composes them into a single one. diff --git a/docs/architecture.md b/docs/architecture.md index 8d8fcba277..0c5f4d958b 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -45,11 +45,12 @@ Whenever we decide to send a request to our API we start by using `urql`'s extra information on how the GraphQL requests are executed. ```js -import { Client } from '@urql/core'; +import { Client, dedupExchange, cacheExchange, fetchExchange } from '@urql/core'; new Client({ url: 'http://localhost:3000/graphql', requestPolicy: 'cache-first', + exchanges: [dedupExchange, cacheExchange, fetchExchange] }); ``` diff --git a/docs/basics/core.md b/docs/basics/core.md index 295aca9e5c..11742e5b61 100644 --- a/docs/basics/core.md +++ b/docs/basics/core.md @@ -134,10 +134,11 @@ The `@urql/core` package exports a function called `createClient` which we can u create the GraphQL client. This central `Client` manages all of our GraphQL requests and results. ```js -import { createClient } from '@urql/core'; +import { createClient, dedupExchange, cacheExchange, fetchExchange } from '@urql/core'; const client = createClient({ url: 'http://localhost:3000/graphql', + exchanges: [dedupExchange, cacheExchange, fetchExchange], }); ``` @@ -153,6 +154,7 @@ GraphQL API. ```js const client = createClient({ url: 'http://localhost:3000/graphql', + exchanges: [dedupExchange, cacheExchange, fetchExchange], fetchOptions: () => { const token = getToken(); return { @@ -168,17 +170,13 @@ As we've seen above, the most important option for the `Client` is `url`, since without it. However, another important option on the `Client` is the `exchanges` option. This option passes a list of exchanges to the `Client`, which tell it how to execute our requests -and how to cache data in a certain order. By default, this will be populated with the list of -`defaultExchanges`. +and how to cache data in a certain order. ```js -import { createClient, defaultExchanges } from '@urql/core'; +import { createClient, dedupExchange, cacheExchange, fetchExchange } from '@urql/core'; const client = createClient({ url: 'http://localhost:3000/graphql', - // the default: - exchanges: defaultExchanges, - // the same as: exchanges: [dedupExchange, cacheExchange, fetchExchange], }); ``` diff --git a/docs/basics/react-preact.md b/docs/basics/react-preact.md index 3b20dc3483..269b519876 100644 --- a/docs/basics/react-preact.md +++ b/docs/basics/react-preact.md @@ -41,10 +41,11 @@ The `urql` and `@urql/preact` packages export a method called `createClient` whi create the GraphQL client. This central `Client` manages all of our GraphQL requests and results. ```js -import { createClient } from 'urql'; +import { createClient, dedupExchange, cacheExchange, fetchExchange } from 'urql'; const client = createClient({ url: 'http://localhost:3000/graphql', + exchanges: [dedupExchange, cacheExchange, fetchExchange], }); ``` @@ -60,6 +61,7 @@ GraphQL API. ```js const client = createClient({ url: 'http://localhost:3000/graphql', + exchanges: [dedupExchange, cacheExchange, fetchExchange], fetchOptions: () => { const token = getToken(); return { @@ -76,10 +78,11 @@ To make use of the `Client` in React & Preact we will have to provide it via the the `Provider` export. ```jsx -import { createClient, Provider } from 'urql'; +import { createClient, Provider, dedupExchange, cacheExchange, fetchExchange } from 'urql'; const client = createClient({ url: 'http://localhost:3000/graphql', + exchanges: [dedupExchange, cacheExchange, fetchExchange], }); const App = () => ( @@ -245,6 +248,7 @@ import { createClient } from 'urql'; const client = createClient({ url: 'http://localhost:3000/graphql', + exchanges: [dedupExchange, cacheExchange, fetchExchange], // every operation will by default use cache-and-network rather // than cache-first now: requestPolicy: 'cache-and-network', diff --git a/docs/basics/svelte.md b/docs/basics/svelte.md index 0e884e6635..f2da40d149 100644 --- a/docs/basics/svelte.md +++ b/docs/basics/svelte.md @@ -48,10 +48,11 @@ The `@urql/svelte` package exports a method called `createClient` which we can u the GraphQL client. This central `Client` manages all of our GraphQL requests and results. ```js -import { createClient } from '@urql/svelte'; +import { createClient, dedupExchange, cacheExchange, fetchExchange } from '@urql/svelte'; const client = createClient({ url: 'http://localhost:3000/graphql', + exchanges: [dedupExchange, cacheExchange, fetchExchange], }); ``` @@ -67,6 +68,7 @@ GraphQL API. ```js const client = createClient({ url: 'http://localhost:3000/graphql', + exchanges: [dedupExchange, cacheExchange, fetchExchange], fetchOptions: () => { const token = getToken(); return { @@ -85,10 +87,11 @@ components. This will share one `Client` with the rest of our app, if we for ins ```html