···11+---
22+'@urql/exchange-suspense': patch
33+---
44+55+Move @urql/exchange-suspense to the monorepo and switch it over to @urql/core
66+See: [`83325a9`](https://github.com/FormidableLabs/urql/commit/83325a9)
···11+MIT License
22+33+Copyright (c) 2018–2020 Formidable
44+55+Permission is hereby granted, free of charge, to any person obtaining a copy
66+of this software and associated documentation files (the "Software"), to deal
77+in the Software without restriction, including without limitation the rights
88+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
99+copies of the Software, and to permit persons to whom the Software is
1010+furnished to do so, subject to the following conditions:
1111+1212+The above copyright notice and this permission notice shall be included in all
1313+copies or substantial portions of the Software.
1414+1515+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1616+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1717+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1818+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1919+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2020+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2121+SOFTWARE.
+163
exchanges/suspense/README.md
···11+<h2 align="center">@urql/exchange-suspense</h2>
22+<p align="center">
33+<strong>An exchange for client-side React Suspense support in <code>urql</code></strong>
44+<br /><br />
55+<a href="https://npmjs.com/package/@urql/exchange-suspense">
66+ <img alt="NPM Version" src="https://img.shields.io/npm/v/@urql/exchange-suspense.svg" />
77+</a>
88+<a href="https://bundlephobia.com/result?p=@urql/exchange-suspense">
99+ <img alt="Minified gzip size"
1010+ src="https://img.shields.io/bundlephobia/minzip/@urql/exchange-suspense.svg?label=gzip%20size" />
1111+</a>
1212+<a href="https://github.com/FormidableLabs/urql-exchange-suspense#maintenance-status">
1313+ <img alt="Maintenance Status" src="https://img.shields.io/badge/maintenance-experimental-blueviolet.svg" />
1414+</a>
1515+</p>
1616+1717+`@urql/exchange-suspense` is an exchange for the [`urql`](../../README.md) GraphQL client that allows the
1818+use of React Suspense on the client-side with `urql`'s built-in suspense mode.
1919+2020+`urql` already supports suspense today, but it's typically used to implement prefetching
2121+during server-side rendering with `react-ssr-prepass`, which allows it to execute React
2222+suspense on the server.
2323+But since `<Suspense>` is mainly intended for client-side use it made sense to build and publish
2424+this exchange, which allows you to try out `urql` and suspense in your React app!
2525+2626+> ⚠️ Note: React's Suspense feature is currently unstable and may still change.
2727+> This exchange is experimental and demonstrates how `urql` already supports and
2828+> interacts with client-side suspense and how it may behave in the future, when React
2929+> Suspense ships and becomes stable. You may use it, but do so at your own risk!
3030+3131+## Quick Start Guide
3232+3333+First install `@urql/exchange-suspense` alongside `urql`:
3434+3535+```sh
3636+yarn add @urql/exchange-suspense
3737+# or
3838+npm install --save @urql/exchange-suspense
3939+```
4040+4141+You'll then need to add the `suspenseExchange`, that this package exposes, to your
4242+`urql` Client and set the `suspense` mode to `true`:
4343+4444+```js
4545+import { createClient, dedupExchange, cacheExchange, fetchExchange } from 'urql';
4646+import { suspenseExchange } from '@urql/exchange-suspense';
4747+4848+const client = createClient({
4949+ url: 'http://localhost:1234/graphql',
5050+ suspense: true, // Enable suspense mode
5151+ exchanges: [
5252+ dedupExchange,
5353+ suspenseExchange, // Add suspenseExchange to your urql exchanges
5454+ cacheExchange,
5555+ fetchExchange,
5656+ ],
5757+});
5858+```
5959+6060+**Important:**
6161+In React Suspense when a piece of data is still loading, a promise will
6262+be thrown that tells React to wait for this promise to complete and try rendering the
6363+suspended component again. The `suspenseExchange` works by caching
6464+the result of any operation until React retries, but it doesn't replace the
6565+`cacheExchange`, since it only briefly keeps the result around.
6666+6767+This means that, in your array of Exchanges, the `suspenseExchange` should be
6868+added _after the `dedupExchange`_ and _before the `cacheExchange`_.
6969+7070+## Usage
7171+7272+After installing `@urql/exchange-suspense` and adding it to your `urql` client,
7373+`urql` will load all your queries in suspense mode. So instead of relying
7474+on the `fetching` flag, you can wrap your components in a `<Suspense>`
7575+element.
7676+7777+```js
7878+import React from 'react';
7979+import { useQuery } from 'urql';
8080+8181+const LoadingIndicator = () => <h1>Loading...</h1>;
8282+8383+const YourContent = () => {
8484+ const [result] = useQuery({ query: allPostsQuery });
8585+ // result.fetching will always be false here, as
8686+ // this component only renders when it has data
8787+ return null; // ...
8888+};
8989+9090+<React.Suspense fallback={<LoadingIndicator />}>
9191+ <YourContent />
9292+</React.Suspense>;
9393+```
9494+9595+Note that in React Suspense, the thrown promises bubble up the component tree until the first `React.Suspense` boundary. This means that the Suspense boundary does not need to be the immediate parent of the component that does the fetching! You should place it in the component hierarchy wherever you want to see the fallback loading indicator, e.g.
9696+9797+```js
9898+<React.Suspense fallback={<LoadingIndicator />}>
9999+ <AnyOtherComponent>
100100+ <AsDeepAsYouWant>
101101+ <YourContent />
102102+ </AsDeepAsYouWant>
103103+ </AnyOtherComponent>
104104+</React.Suspense>
105105+```
106106+107107+[You can also find a fully working demo on CodeSandbox.](https://codesandbox.io/s/urql-client-side-suspense-demo-81obe)
108108+109109+## Caveats
110110+111111+### About server-side usage
112112+113113+The suspense exchange is not intended to work for server-side rendering suspense! This is
114114+what the `ssrExchange` is intended for and it's built into the main `urql` package. The
115115+`suspenseExchange` however is just intended for client-side suspense and use with
116116+`<React.Suspense>`.
117117+118118+The `<React.Suspense>` element currently won't even be rendered during server-side rendering,
119119+and has been disabled in `react-dom/server`. So if you use `suspenseExchange` and
120120+`<React.Suspense>` in your server-side code you may see some unexpected behaviour and
121121+errors.
122122+123123+### Usage with `ssrExchange`
124124+125125+If you're also using the `ssrExchange` for server-side rendered data, you will have to use
126126+an additonal flag to indicate to it when it's running on the server-side and when it's running
127127+on the client-side.
128128+129129+By default, the `ssrExchange` will look at `client.suspense`. If the `urql` Client is in suspense
130130+mode then the `ssrExchange` assumes that it's running on the server-side. When it's not
131131+in suspense mode (`!client.suspense`) it assumes that it's running on the client-side.
132132+133133+When you're using `@urql/exchange-suspense` you'll enable the suspense mode on the
134134+client-side as well, which means that you'll have to tell the `ssrExchange` manually
135135+when it's running on the client-side.
136136+137137+Most of the time you can achieve this by checking `process.browser` in any Webpack
138138+environment. The `ssrExchange` accepts an `isClient` flag that you can set to
139139+true on the client-side.
140140+141141+```js
142142+const isClient = !!process.browser;
143143+144144+const client = createClient({
145145+ url: 'http://localhost:1234/graphql',
146146+ suspense: true,
147147+ exchanges: [
148148+ dedupExchange,
149149+ isClient && suspenseExchange,
150150+ ssrExchange({
151151+ initialData: isClient ? window.URQL_DATA : undefined,
152152+ // This will need to be passed explicitly to ssrExchange:
153153+ isClient: !!isClient
154154+ })
155155+ cacheExchange,
156156+ fetchExchange,
157157+ ].filter(Boolean),
158158+});
159159+```
160160+161161+## Maintenance Status
162162+163163+**Experimental:** This project is quite new. We're not sure what our ongoing maintenance plan for this project will be. Bug reports, feature requests and pull requests are welcome. If you like this project, let us know by starring the repo!