+2
-3
docs/advanced/authentication.md
+2
-3
docs/advanced/authentication.md
···in front of all `fetchExchange`s but after all other synchronous exchanges, like the `cacheExchange`.
···in front of all `fetchExchange`s but after all other synchronous exchanges, like the `cacheExchange`.
+4
-4
docs/advanced/auto-populate-mutations.md
+4
-4
docs/advanced/auto-populate-mutations.md
···The `populateExchange` should be placed in front of the `cacheExchange`, especially if you're using[Graphcache](../graphcache/README.md), since it won't understand the `@populate` directive on its
···The `populateExchange` should be placed in front of the `cacheExchange`, especially if you're using[Graphcache](../graphcache/README.md), since it won't understand the `@populate` directive on its
+1
-1
docs/advanced/debugging.md
+1
-1
docs/advanced/debugging.md
+34
-34
docs/advanced/persistence-and-uploads.md
+34
-34
docs/advanced/persistence-and-uploads.md
···-Queries](https://www.apollographql.com/docs/apollo-server/performance/apq/), Persisted Queries, and-While File Uploads should work without any modifications, an additional exchange must be installed···easier for a CDN to cache, as by default most caches would not cache POST requests automatically.-implement Automatic Persisted Queries. This exchange works alongside the default `fetchExchange`······As we can see, typically it's recommended to set `preferGetForPersistedQueries` to `true` to force-`preferGetMethod`](../api/core.md#client) but only switches persisted queries to use GET requests-instead. This is preferable since sometimes the GraphQL query can grow too large for a simple GET·········-Spec](https://github.com/jaydenseric/graphql-multipart-request-spec) to allow files to be uploaded.-This allows us to pass a `File` or `Blob` directly to our GraphQL requests as variables, and the-Files are often handled in the browser via the [File API](https://developer.mozilla.org/en-US/docs/Web/API/File),-which we may typically get to via a [file input](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)-In `urql`, these are supported natively, so as long as your JS environment supports either `File` or-Previously, this worked by installing the [`@urql/multipart-fetch-exchange` package](../api/multipart-fetch-exchange.md),
······easier for a CDN to cache, as by default most caches would not cache POST requests automatically.······As we can see, typically it's recommended to set `preferGetForPersistedQueries` to `true` to force·········+spec](https://github.com/jaydenseric/graphql-multipart-request-spec) to allow for File Uploads+If a GraphQL API supports this, we can pass a [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File)+or a [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) directly into our variables and+[file input](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications),+The `@urql/core@4` package supports File Uploads natively, so we won't have to do any installation+or setup work. When `urql` sees a `File` or a `Blob` anywhere in your `variables`, it switches to+a `multipart/form-data` request, converts the request to a `FormData` object, according to the+> **Note:** Previously, this worked by installing the `@urql/multipart-fetch-exchange` package.+> however, this package has been deprecated and file uploads are now built into `@urql/core@4`.
+5
-7
docs/advanced/retry-operations.md
+5
-7
docs/advanced/retry-operations.md
·········
·········
+6
-7
docs/advanced/server-side-rendering.md
+6
-7
docs/advanced/server-side-rendering.md
···-import { createClient, dedupExchange, cacheExchange, fetchExchange, ssrExchange } from '@urql/core';·········
············
+13
-18
docs/advanced/subscriptions.md
+13
-18
docs/advanced/subscriptions.md
···-import { Client, dedupExchange, cacheExchange, fetchExchange, subscriptionExchange } from 'urql';···For backends supporting `graphql-ws`, we recommend using the [graphql-ws](https://github.com/enisdenjo/graphql-ws) client.-import { createClient, dedupExchange, cacheExchange, fetchExchange, subscriptionExchange } from 'urql';···> 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.-import { Client, dedupExchange, cacheExchange, fetchExchange, subscriptionExchange } from 'urql';const subscriptionClient = new SubscriptionClient('ws://localhost/graphql', { reconnect: true });···············
······For backends supporting `graphql-ws`, we recommend using the [graphql-ws](https://github.com/enisdenjo/graphql-ws) client.···> 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.const subscriptionClient = new SubscriptionClient('ws://localhost/graphql', { reconnect: true });···············
+5
-1
docs/api/README.md
+5
-1
docs/api/README.md
···Most of these packages will refer to or use utilities and types from the `@urql/core` package. [Read···
···Most of these packages will refer to or use utilities and types from the `@urql/core` package. [Read···
+5
docs/api/auth-exchange.md
+5
docs/api/auth-exchange.md
···The `@urql/exchange-auth` package contains an addon `authExchange` for `urql` that aims to make iteasy to implement complex authentication and reauthentication flows as are typically found with JWT
+6
-1
docs/api/core.md
+6
-1
docs/api/core.md
···like [`urql` for React](./urql.md) or [`@urql/preact`](./preact.md), will reuse the core logic and···| ----------------- | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- || `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` |
···like [`urql` for React](./urql.md) or [`@urql/preact`](./preact.md), will reuse the core logic and···| ----------------- | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- || `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` |
+5
docs/api/execute-exchange.md
+5
docs/api/execute-exchange.md
···The `@urql/exchange-execute` package contains an addon `executeExchange` for `urql` that may be used to
···The `@urql/exchange-execute` package contains an addon `executeExchange` for `urql` that may be used to
+5
docs/api/graphcache.md
+5
docs/api/graphcache.md
···used to replace the default [`cacheExchange`](./core.md#cacheexchange), which switches `urql` from
···used to replace the default [`cacheExchange`](./core.md#cacheexchange), which switches `urql` from
-46
docs/api/multipart-fetch-exchange.md
-46
docs/api/multipart-fetch-exchange.md
···-The `@urql/exchange-multipart-fetch` package contains an addon `multipartFetchExchange` for `urql`-This exchange uses the same fetch logic as the [`fetchExchange`](./core.md#fetchexchange) and by reusing logic from `@urql/core/internal`.-[`fetchExchange`](./core.md#fetchexchange) and will act exactly like the `fetchExchange` unless the-`variables` that it receives for mutations contain any `File`s as detected by the `extract-files` package.
···
+5
docs/api/preact.md
+5
docs/api/preact.md
···
+5
docs/api/refocus-exchange.md
+5
docs/api/refocus-exchange.md
···`@urql/exchange-refocus` is an exchange for the `urql` that tracks currently active operations and redispatches them when the
+5
docs/api/request-policy-exchange.md
+5
docs/api/request-policy-exchange.md
···
+5
docs/api/retry-exchange.md
+5
docs/api/retry-exchange.md
···The `@urql/exchange-retry` package contains an addon `retryExchange` for `urql` that may be used to
+5
docs/api/svelte.md
+5
docs/api/svelte.md
···The `queryStore` factory accepts properties as inputs and returns a Svelte pausable, readable store
+12
-7
docs/api/urql.md
+12
-7
docs/api/urql.md
······| `query` | `string \| DocumentNode` | The query to be executed. Accepts as a plain string query or GraphQL DocumentNode. || `requestPolicy` | `?RequestPolicy` | An optional [request policy](./core.md#requestpolicy) that should be used specifying the cache strategy. |-| `pause` | `?boolean` | A boolean flag instructing [execution to be paused](../basics/react-preact.md#pausing-usequery). |···-| ---------------------------------------------------- | ------------------------ | ---------------------------------------------------------------------------------- |-| `query` | `string \| DocumentNode` | The query to be executed. Accepts as a plain string query or GraphQL DocumentNode. |-| `pause` | `?boolean` | A boolean flag instructing [execution to be paused](../basics/react-preact.md#pausing-usequery). |The hook optionally accepts a second argument, which may be a handler function with a type signature
······| `query` | `string \| DocumentNode` | The query to be executed. Accepts as a plain string query or GraphQL DocumentNode. || `requestPolicy` | `?RequestPolicy` | An optional [request policy](./core.md#requestpolicy) that should be used specifying the cache strategy. |+| `pause` | `?boolean` | A boolean flag instructing [execution to be paused](../basics/react-preact.md#pausing-usequery). |···+| ----------- | ------------------------ | ------------------------------------------------------------------------------------------------ |+| `query` | `string \| DocumentNode` | The query to be executed. Accepts as a plain string query or GraphQL DocumentNode. |+| `pause` | `?boolean` | A boolean flag instructing [execution to be paused](../basics/react-preact.md#pausing-usequery). |The hook optionally accepts a second argument, which may be a handler function with a type signature
+5
docs/api/vue.md
+5
docs/api/vue.md
···
+110
-91
docs/architecture.md
+110
-91
docs/architecture.md
···-`urql` is a highly customizable and flexible GraphQL client, that happens to come with some default···If `urql` was a train it would take several stops to arrive at its terminus, our API. It starts with us-defining queries or mutations. Any GraphQL request can be abstracted into their query documents and-their variables. In `urql`, these GraphQL requests are treated as unique objects, which are uniquely-identified by the query document and variables (which is why a `key` is generated from the two). This-[`Client`](./api/core.md#client). It accepts several options like `url` or `requestPolicy` which are-`Client`](./api/core.md#client) directly and are a thin abstraction on top of it. Though some methods can be called on it directly, as seen [on the "Core Usage"-[`Operation`](./api/core.md#operation)s. An "Operation" is an extension of `GraphQLRequest`s. Not-It's the `Client`s responsibility to accept an `Operation` and execute it. The bindings internally-call the `client.executeQuery`, `client.executeMutation`, or `client.executeSubscription` methods,-In the diagram we can see that each operation is a signal for our request to start at which point-we can expect to receive our results eventually on a callback. Once we're not interested in results-anymore a special "teardown" signal is issued on the `Client`. While we don't see operations outsideTo reiterate, when we use `urql`'s bindings for our framework of choice, methods are called on the`Client`, but we never see the operations that are created in the background from our bindings. Wecall a method like `client.executeQuery` (or it's called for us in the bindings), an operation is-issued internally when we subscribe with a callback, and later our callback is called with results.···-- `cacheExchange`: The default caching logic with ["Document Caching"](./basics/document-caching.md)-- `fetchExchange`: Sends an operation to the API using `fetch` and adds results to the output stream-When we don't pass the `exchanges` option manually to our `Client` then these are the ones that will-be applied. As we can see, an exchange exerts a lot of power over our operations and results. They-determine a lot of the logic of the `Client`, taking care of things like deduplication, caching, and-- [`mapExchange`](./api/core.md#mapexchange): Allows reacting to operations, results, and errors-- [`multipartFetchExchange`](./advanced/persistence-and-uploads.md#file-uploads): Provides multipart file upload capability- [`persistedFetchExchange`](./advanced/persistence-and-uploads.md#automatic-persisted-queries): Provides support for Automatic-- [`authExchange`](./advanced/authentication.md): Allows complex authentication flows to be implemented-- [`requestPolicyExchange`](./api/request-policy-exchange.md): Automatically upgrades `cache-only` and `cache-first` operations to `cache-and-network` after a given amount of time.- `devtoolsExchange`: Provides the ability to use the [urql-devtools](https://github.com/urql-graphql/urql-devtools)We can even swap out our [document cache](./basics/document-caching.md), which is implemented by···directly](./basics/core.md#one-off-queries-and-mutations) or write exchanges then we'll see streams-`urql` utilises the [Wonka](https://github.com/kitten/wonka) library for its streams. It has a-In Wonka, like with Observables, streams are cancellable by calling the `unsubscribe` method that aWhen we call methods on the `Client` like [`client.executeQuery`](./api/core.md#clientexecutequery)-or [`client.query`](./api/core.md#clientquery) then these will return a Wonka stream. Those are-We can use [`wonka`'s `subscribe`](https://wonka.kitten.sh/api/sinks#subscribe) function to start-this stream. We pass this function a callback and will receive results back from the `Client`, as it-starts our operation. When we unsubscribe then the `Client` will stop this operation by sending a···
···+- The Client — as created [with the core `@urql/core` package](./basics/code.md), which interacts with "exchanges" to execute GraphQL···If `urql` was a train it would take several stops to arrive at its terminus, our API. It starts with us+In `urql`, these GraphQL requests are treated as unique objects and each GraphQL request will have+a `key` generated for them. This `key` is a hash of the query document and the variables you provide+The `Client` accepts several options to configure its behaviour and the behaviour of exchanges,+The bindings that we've seen in [the "Basics" section](./basics/README.md), like `useQuery` for+[`GraphQLRequest`s](./api/core.md#graphqlrequest). However, since we have more metadata that is+needed, like our `url` option on the `Client`, `urql` internally creates [`Operation`s](./api/core.md#operation)+An "Operation" is an extension of `GraphQLRequest`s. Not only do they carry the `query`, `variables`,+This means, once we hand over a GraphQL request to the `Client`, it will create an `Operation`,+As shown in the diagram, each operation is like an event or signal for a GraphQL request to start,+However, because the cache can send updates to us whenever it detects a change, or you could cancel+a GraphQL request before it finishes, a special "teardown" `Operation` also exists, which cancelsTo reiterate, when we use `urql`'s bindings for our framework of choice, methods are called on the`Client`, but we never see the operations that are created in the background from our bindings. Wecall a method like `client.executeQuery` (or it's called for us in the bindings), an operation is···+By default, the `Client` doesn't do anything with GraphQL requests. It contains only the logic to+manage and differentiate between active and inactive requests and converts them to operations.+To actually do something with our GraphQL requests, it needs _exchanges_, which are like plugins+By default, you may want to add the `cacheExchange` and the `fetchExchange` from `@urql/core`:+- `cacheExchange`: Caches GraphQL results with ["Document Caching"](./basics/document-caching.md)+As we can tell, exchanges define not only how GraphQL requests are executed and handled, but also+get control over caching. Exchanges can be used to change almost any behaviour in the `Client`,+although internally they only handle incoming & outgoing requests and incoming & outgoing results.+- [`mapExchange`](./api/core.md#mapexchange): Allows changing and reacting to operations, results, and errors+- [`retryExchange`](./advanced/retry-operations.md): Allows operations to be retried on errors- [`persistedFetchExchange`](./advanced/persistence-and-uploads.md#automatic-persisted-queries): Provides support for Automatic+- [`authExchange`](./advanced/authentication.md): Allows refresh authentication to be implemented easily.+- [`requestPolicyExchange`](./api/request-policy-exchange.md): Automatically refreshes results given a TTL.- `devtoolsExchange`: Provides the ability to use the [urql-devtools](https://github.com/urql-graphql/urql-devtools)We can even swap out our [document cache](./basics/document-caching.md), which is implemented by···directly](./basics/core.md#one-off-queries-and-mutations) or write exchanges then we'll see streamsWhen we call methods on the `Client` like [`client.executeQuery`](./api/core.md#clientexecutequery)+It's normal for GraphQL subscriptions to deliver multiple results, however, even GraphQL queries can+give you multiple results in `urql`. This is because operations influence one another. When a cache+invalidates a query, this query may refetch, and a new result is delivered to your application.+Multiple results mean that once you subscribe to a GraphQL query via the `Client`, you may receive···+library. It is used to write exchanges and when we interact with the `Client` it is used internally
+56
-32
docs/basics/core.md
+56
-32
docs/basics/core.md
·········create the GraphQL client. This central `Client` manages all of our GraphQL requests and results.-At the bare minimum we'll need to pass an API's `url` when we create a `Client` to get started.Another common option is `fetchOptions`. This option allows us to customize the options that will bepassed to `fetch` when a request is sent to the given API `url`. We may pass in an options object, or······-This option passes a list of exchanges to the `Client`, which tell it how to execute our requestsLater, [in the "Advanced" section](../advanced/README.md) we'll see many more features that `urql`-exchanges in order. First, the `dedupExchange` deduplicates requests if we send the same queries-twice, the `cacheExchange` implements the default "document caching" behaviour (as we'll learn about······somewhere else then we'll get notified of the new API result as well, as long as we're subscribed.···This code example is similar to the one before. However, instead of sending a one-off query, we're
·········create the GraphQL client. This central `Client` manages all of our GraphQL requests and results.Another common option is `fetchOptions`. This option allows us to customize the options that will bepassed to `fetch` when a request is sent to the given API `url`. We may pass in an options object, or······+The `exchanges` option is of particular importance however because it tells the `Client` what to do+For instance, here, the `Client`'s caching and fetching features are only available because we're+passing it exchanges. In the above example, the `Client` will try to first read a GraphQL request+The caching in `urql` is also implemented as an exchange, so for instance, the behavior described+on the ["Document Caching" page](./document-caching.md) is all contained within the `cacheExchange`Later, [in the "Advanced" section](../advanced/README.md) we'll see many more features that `urql`···+This can also be written using async/await by simply awaiting the return value of `client.query`:+It's worth noting that promisifying a query result will always only give us _one_ result, because+we're not calling `subscribe`. This means that we'll never see cache updates when we're asking for···somewhere else then we'll get notified of the new API result as well, as long as we're subscribed.···This code example is similar to the one before. However, instead of sending a one-off query, we're
+21
-21
docs/basics/react-preact.md
+21
-21
docs/basics/react-preact.md
······-The `urql` and `@urql/preact` packages export a method called `createClient` which we can use tocreate the GraphQL client. This central `Client` manages all of our GraphQL requests and results.-At the bare minimum we'll need to pass an API's `url` when we create a `Client` to get started.Another common option is `fetchOptions`. This option allows us to customize the options that will bepassed to `fetch` when a request is sent to the given API `url`. We may pass in an options object, or··················
······create the GraphQL client. This central `Client` manages all of our GraphQL requests and results.+At the bare minimum we'll need to pass an API's `url` and `exchanges` when we create a `Client`Another common option is `fetchOptions`. This option allows us to customize the options that will bepassed to `fetch` when a request is sent to the given API `url`. We may pass in an options object, or···············+const shouldPause = from === undefined || from === null || limit === undefined || limit === null;···
+17
-16
docs/basics/svelte.md
+17
-16
docs/basics/svelte.md
······-At the bare minimum we'll need to pass an API's `url` when we create a `Client` to get started.Another common option is `fetchOptions`. This option allows us to customize the options that will bepassed to `fetch` when a request is sent to the given API `url`. We may pass in an options object or······-import { createClient, setContextClient, dedupExchange, cacheExchange, fetchExchange } from '@urql/svelte';······
······Another common option is `fetchOptions`. This option allows us to customize the options that will bepassed to `fetch` when a request is sent to the given API `url`. We may pass in an options object or············
+6
-5
docs/basics/typescript-integration.md
+6
-5
docs/basics/typescript-integration.md
······-const [{ data }] = useQuery({ query: allFilmsWithVariablesQueryDocument, variables: { first: 10 } });
······
+3
-3
docs/basics/ui-patterns.md
+3
-3
docs/basics/ui-patterns.md
···
···
+42
-41
docs/basics/vue.md
+42
-41
docs/basics/vue.md
···-At the bare minimum we'll need to pass an API's `url` when we create a `Client` to get started.Another common option is `fetchOptions`. This option allows us to customize the options that will bepassed to `fetch` when a request is sent to the given API `url`. We may pass in an options object or······your parent components and accepts either a `Client` directly or just the options that you'd pass to-import { createClient, provideClient, dedupExchange, cacheExchange, fetchExchange } from '@urql/vue';····································
···+At the bare minimum we'll need to pass an API's `url` and `exchanges` when we create a `Client`Another common option is `fetchOptions`. This option allows us to customize the options that will bepassed to `fetch` when a request is sent to the given API `url`. We may pass in an options object or······your parent components and accepts either a `Client` directly or just the options that you'd pass to····································
+46
-47
docs/comparison.md
+46
-47
docs/comparison.md
···-| ------------------------------------------ | ---------------------------------- | -------------------------------------------------------------------------- | ------------------------------ |-| Base Bundle Size | **5.9kB** (7.1kB with bindings) | 32.9kB | 27.7kB (34.1kB with bindings) |-| Defer & Stream Directives | ✅ | ✅ / 🛑 (`@defer` is supported in >=3.7.0, `@stream` is not yet supported) | 🟡 (unreleased) |-| Retrying Failed Queries | ✅ `@urql/exchange-retry` | ✅ `apollo-link-retry` | ✅ `DefaultNetworkLayer` |-| Easy Authentication Flows | ✅ `@urql/exchange-auth` | 🛑 (no docs for refresh-based authentication) | 🟡 `react-relay-network-layer` |matter which framework you use it with. It's worth mentioning that all three clients support some······-| ------------------------------------------------------- | --------------------------------------------------------------------- | ------------------------- | ---------------------------------------------- |-| Caching Strategy | Document Caching, Normalized Caching with `@urql/exchange-graphcache` | Normalized Caching | Normalized Caching (schema restrictions apply) |caching](./graphcache/normalized-caching.md) as its default caching strategy. Typically this is seen···-- All packages in `urql` reuse parts of `@urql/core` and `wonka`, which means adding all their total-- These sizes may change drastically given the code you write and add yourself, but can be managed-via precompilation (e.g. with `babel-plugin-graphql-tag` or GraphQL Code Generator for Apollo and
···+| ------------------------------------------ | ---------------------------------------------- | ------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- |+| Base Bundle Size | **10kB** (11kB with bindings) | ~50kB (55kB with React hooks) | 45kB (66kB with bindings) |+| Subscriptions | 🔶 [Docs](./advanced/subscriptions.md) | 🔶 [Docs](https://www.apollographql.com/docs/react/data/subscriptions/#setting-up-the-transport) | 🔶 [Docs](https://relay.dev/docs/guided-tour/updating-data/graphql-subscriptions/#configuring-the-network-layer) |+| Client-side Rehydration | ✅ [Docs](./advanced/server-side-rendering.md) | ✅ [Docs](https://www.apollographql.com/docs/react/performance/server-side-rendering) | 🛑 |+| Defer & Stream Directives | ✅ | ✅ / 🛑 (`@defer` is supported in >=3.7.0, `@stream` is not yet supported) | 🟡 (unreleased) |+| Retrying Failed Queries | ✅ `@urql/exchange-retry` | ✅ `apollo-link-retry` | ✅ `DefaultNetworkLayer` |+| Easy Authentication Flows | ✅ `@urql/exchange-auth` | 🛑 (no docs for refresh-based authentication) | 🟡 `react-relay-network-layer` |matter which framework you use it with. It's worth mentioning that all three clients support some······+| ------------------------------------------------------- | --------------------------------------------------------------------- | ----------------------------------- | ---------------------------------------------- |+| Caching Strategy | Document Caching, Normalized Caching with `@urql/exchange-graphcache` | Normalized Caching | Normalized Caching (schema restrictions apply) |caching](./graphcache/normalized-caching.md) as its default caching strategy. Typically this is seen···+- Some dependencies may be external and the above sizes listed are total minified+gzipped sizes+- `@urql/core` imports from `wonka` for stream utilities and `@0no-co/graphql.web` for GraphQL query+- All `urql` packages reuse parts of `@urql/core` and `wonka`, which means adding all their total
+3
-3
docs/graphcache/README.md
+3
-3
docs/graphcache/README.md
···
···
+6
-6
docs/graphcache/offline.md
+6
-6
docs/graphcache/offline.md
············
············