+52
-8
.circleci/config.yml
························
+4
-10
docs/README.md
···-started](./basics/setting-up-the-client.md) you'll only need to install a single package for your···- **Main Concepts** then explains more about how `urql` functions, what it's made up of, and covers···- **Graphcache** documents one of the most important addons to `urql`, which adds ["NormalizedCaching" support](./graphcache/normalized-caching.md) to the `Client` and enables more complex+- **Showcase** aims to list some companies that use `urql`, third-party packages, and other helpful- **API** contains a detailed list of all helpers, utilities, components, and other parts of each of-Apart from these main sections there is also some additional content that doesn't fit into any of-- **Showcase** aims to list some companies that use `urql`, third-party packages, and other helpful
+11
docs/advanced/README.md
···+- **Subscriptions** covers how to use `useSubscription` and how to set up GraphQL subscriptions with+- **Server-side Rendering** guides us through how to set up server-side rendering and rehydration.+- **Auto-populate Mutations** presents the `populateExchange` addon which can make it easier to
+33
-10
docs/advanced/auto-populate-mutations.md
···+`@populate` directive. In combination with [Graphcache](../graphcache/README.md) this is a useful+tool to update the data in your application automatically following a mutation, when your app grows+> **NOTE:** The `populateExchange` is currently _experimental_! Certain patterns and usage paths+> like GraphQL field arguments aren't covered yet, and the exchange hasn't been extensively used-> Note: Populate needs to be declared before the cache in order to ensure the `populate` directive is replaced with the respective attributes.+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+Adding the `populateExchange` now enables us to use the `@populate` directive in our mutations.···You may not want to populate your whole mutation response. In order to reduce your payload, pass populate lower in your query.···-If you find yourself using multiple queries with variables, it may be necessary to [use aliases](https://graphql.org/learn/queries/#aliases) in order to allow merging of queries.+[use aliases](https://graphql.org/learn/queries/#aliases) in order to allow merging of queries.···
+217
-22
docs/advanced/server-side-rendering.md
···+In server-side rendered applications we often need to set our application up so that data will be+fetched on the server-side and later sent down to the client for hydration. `urql` supports this+The `ssrExchange` has two functions. On the server-side it's able to gather all results as they're+being fetched, which can then be serialised and sent to the client. On the client-side it's able to+use these serialised results to rehydrate and render the application without refetching this data.+The `ssrExchange` must be initialised with the `isClient` and `initialState` options. The `isClient`+option tells the exchange whether it's on the server- or client-side. In our example we use `typeof window` to determine this, but in Webpack environments you may also be able to use `process.browser`.+The `initialState` option should be set to the serialised data you retrieve on your server-side.+This data may be retrieved using methods on `ssrExchange()`. You can retrive the serialised data+This will provide `__URQL_DATA__` globally which we've used in our first example to inject data into+Alternatively you can also call `restoreData` as long as this call happens synchronously before the+In the previous examples we've set up the `ssrExchange`, however with React this still requires us+to manually execute our queries before rendering a server-side React app [using `renderToString`+rendering](https://reactjs.org/docs/concurrent-mode-suspense.html). However, suspense is currently+Using [the `react-ssr-prepass` package](https://github.com/FormidableLabs/react-ssr-prepass) however,+we can implement a prerendering step before we let React server-side render, which allows us to+To set this up, first we'll install `react-ssr-prepass`. It has a peer dependency on `react-is`+Next, we'll modify our server-side code and add `react-ssr-prepass` in front of `renderToString`.-this option tells the exchange you're in the browser rather than in the process of a server-side-render. The other option is called `initialState`, this being a mapping of `operationKey` to `operationResult`,+It's important to set enable the `suspense` option on the `Client`, which switches it to support-The returned exchange will have two methods available on it, `restoreData` and `extractData`, during your ssr-we extract the gathered data and serialize it into a `<script>` tag inside head, this should bind it to a unique+`react-ssr-prepass`, which is called `preact-ssr-prepass`. It only has a peer dependency on Preact+All above examples for `react-ssr-prepass` will still be the exact same, except that instead of+using the `urql` package we'll have to import from `@urql/preact`, and instead of `react-ssr-prepass`+`next-urql`. The `next-urql` package includes setup for `react-ssr-prepass` already, which automatesWe have a custom integration with [`Next.js`](https://nextjs.org/), being [`next-urql`](https://github.com/FormidableLabs/next-urql)+To setup `next-urql`, first we'll install `next-urql` with `react-is` and `isomorphic-unfetch` as+The peer dependency on `react-is` is inherited from `react-ssr-prepass` requiring it, and the peer+dependency on `isomorphic-unfetch` exists, since `next-urql` automatically injects it as a `fetch`+We're now able to wrap any page or `_app.js` using the `withUrqlClient` higher-order component. If+we wrap `_app.js` we won't have to wrap any individual page, but we also won't be able to make use+This will automatically set up server-side rendering on the page. The `withUrqlClient` higher-order+component function accepts the usual `Client` options as an argument. This may either just be an+One added caveat is that these options may not include the `exchanges` option because `next-urql`+injects the `ssrExchange` automatically at the right location. If you're setting up custom exchanges+you'll need to instead provide them in a custom `mergeExchanges` function as the second argument:+const mergeExchanges = ssrExchange => [dedupExchange, cacheExchange, ssrExchange, fetchExchange];+export default withUrqlClient({ url: 'http://localhost:3000/graphql' }, mergeExchanges)(Index);
+6
-9
docs/advanced/testing.md
···-When testing your components, you're likely going to want to check arguments and force different states for your components using Urql.-> **Note:** Examples demonstrate the _React hooks_ version of Urql being used but underlying patterns apply to all implementations.+The following examples demonstrate this method of testing for React and the `urql` package only,···
+10
-1
docs/api/README.md
···+`urql` is a collection of multiple packages. You'll likely be using one of the framework bindings+Most of these packages will refer to or use utilities and types from the `@urql/core` package. [Read
+265
-180
docs/api/core.md
···+like [`urql` for React](./urql.md) or [`@urql/preact`](./preact.md) will reuse the core logic and+Therefore if you're not accessing utilities directly, aren't in a Node.js environment, and are using+framework bindings, you'll likely want to import from your framework bindings package directly.-| ------------ | ---------------------------------- | --------------------------------------------------------------------------------------------------------------- |-| 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` |-| suspense | `?boolean` | Activates the experimental React suspense mode, which can be used during server-side rendering to prefetch data |-| exchanges | `Exchange[]` | An array of `Exchange`s that the client should use instead of the list of `defaultExchanges` |-`urql` also exposes `createClient()` that is just a convenient alternative to calling `new Client()`.+`@urql/core` also exposes `createClient()` that is just a convenient alternative to calling `new Client()`.+| --------------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |+| exchanges | `Exchange[]` | An array of `Exchange`s that the client should use instead of the list of `defaultExchanges` |+| 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` |+| suspense | `?boolean` | Activates the experimental React suspense mode, which can be used during server-side rendering to prefetch data |+| requestPolicy | `?RequestPolicy` | Changes the default request policy that will be used. By default this will be `cache-first`. |+| preferGetMethod | `?boolean` | This is picked up by the `fetchExchange` and will force all queries (not mutations) to be sent using the HTTP GET method instead of POST. |+| maskTypename | `?boolean` | Enables the `Client` to automatically apply the `maskTypename` utility to all `data` on [`OperationResult`s](#operationresult). This makes the `__typename` properties non-enumerable. |+Accepts a [`GraphQLRequest`](#graphqlrequest) and optionally `Partial<OperationContext>`, and returns a+[`Source<OperationResult>`](#operationresult) — a stream of query results that can be subscribed to.+exchanges pipeline. If no subscribers are listening to this operation anymore and unsubscribe from-are ideal for SSR, like for example the `getInitialProps` method in [Next.js](https://nextjs.org/).+`client.executeSubscription` and `client.executeMutation` is polling. You may optionally pass a+`pollInterval` option on the `OperationContext` object, which will instruct the query to reexecute+This is functionally the same as `client.executeQuery`, but creates operations for subscriptions+A mutation source is always guaranteed to only respond with a single [`OperationResult`](#operationresult) and then complete.+This is a shorthand method for [`client.executeQuery`](#clientexecutequery), which accepts a query+(`DocumentNode | string`) and variables separately and creates a [`GraphQLRequest`](#graphqlrequest) [`createRequest`](#createrequest) automatically.+The returned `Source<OperationResult>` will also have an added `toPromise` method so the stream can+The `CominedError` is used in `urql` to normalize network errors and `GraphQLError`s if anything+| ------------- | -------------------------------- | --------------------------------------------------------------------------------- |+| networkError | `?Error` | An unexpected error that might've occured when trying to send the GraphQL request |+| graphQLErrors | `?Array<string \| GraphQLError>` | GraphQL Errors (if any) that were returned by the GraphQL API |+| --------- | -------------- | --------------------------------------------------------------------------------------------------------------------- |+| key | `number` | A unique key that identifies this exact combination of `query` and `variables`, which is derived using a stable hash. |+| query | `DocumentNode` | The query to be executed. Accepts as a plain string query or GraphQL DocumentNode. |+identify the request. When `variables` are passed it is ensured that they're stabily stringified so+that the same variables in a different order will result in the same `key`, since variables are+[A `GraphQLRequest` may be manually created using the `createRequest` helper.](#createrequest)···+It extends the [GraphQLRequest](#graphqlrequest) type and contains these additional properties:+> **Note:** In `urql` the `operationName` on the `Operation` isn't the actual name of an operation+> and dervied from the GraphQL `DocumentNode`, but instead a type of operation, like `'query'` or···+[Read more about request policies on the "Queries" page.](../basics/queries.md#request-policies)-| --------- | -------------- | --------------------------------------------------------------------------------------------------------------------- | -------- | --- |-| key | `number` | An optional [request policy](/basics/querying-data#request-policy) that should be used specifying the cache strategy. | No |-| query | `DocumentNode` | The query to be executed. Accepts as a plain string query or GraphQL DocumentNode. | Yes |+The context often carries options or metadata for individual exchanges, but may also contain custom+| --------------- | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |+| fetchOptions | `?RequestInit \| (() => RequestInit)` | An optional [request policy](/basics/querying-data#request-policy) that should be used specifying the cache strategy. |+| fetch | `typeof fetch` | An alternative implementation of `fetch` that will be used by the `fetchExchange` instead of `window.fetch` |+| requestPolicy | `RequestPolicy` | An optional [request policy](/basics/querying-data#request-policy) that should be used specifying the cache strategy. |+| meta | `?OperationDebugMeta` | Metadata that is only available in development for devtools. |-| --------------- | ------------------------------------ | --------------------------------------------------------------------------------------------------------------------- | -------------- | --- |-| fetchOptions | `RequestInit \| (() => RequestInit)` | An optional [request policy](/basics/querying-data#request-policy) that should be used specifying the cache strategy. | No |-| requestPolicy | `RequestPolicy` | An optional [request policy](/basics/querying-data#request-policy) that should be used specifying the cache strategy. | Yes |-| pollInterval | `number` | Every `pollInterval` milliseconds the query will be refetched. | No |-| meta | `OperationDebugMeta` | Metadata that is only available in development for devtools. | No |-It contains all properties in the [GraphQLRequest](#graphqlrequest-type) type, as well as the additional properties below.+The result of every GraphQL request, i.e. an `Operation`. It's very similar to what comes back from-| ------------- | ------------------ | --------------------------------------------- | -------- | --- |+| ---------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |+| error | `?CombinedError` | A [`CombinedError`](#combinederror) instances that wraps network or `GraphQLError`s (if any) |+| extensions | `?Record<string, any>` | Extensions that the GraphQL server may have returned. |+| stale | `?boolean` | A flag that may be set to `true` by exchanges to indicate that the `data` is incomplete or out-of-date, and that the result will be updated soon. |-| ---------- | --------------------- | ----------------------------------------------------- | -------------- |-| extensions | `Record<string, any>` | Extensions that the GraphQL server may have returned. | No |+| ------- | ------------ | ----------------------------------------------------------------------------------------------------------------------- |+| forward | `ExchangeIO` | The unction responsible for receiving an observable operation and returning a result |+| client | `Client` | The URQL application-wide client library. Each execute method starts a GraphQL request and returns a stream of results. |-| ------------- | ------------------------------- | --------------------------------------------------------------------------------- | -------- |-| networkError | `Error` | An unexpected error that might've occured when trying to send the GraphQL request | No |-| graphQLErrors | `Array<string \| GraphQLError>` | GraphQL Errors (if any) that were returned by the GraphQL API | No |-These are both inputs and properties on the `CombinedError`. Additionally it exposes a default `message`-This is on every `OperationResult` that has one or more errors and groups the usual `errors` property-| ------- | ------------ | ----------------------------------------------------------------------------------------------------------------------- | -------- |-| forward | `ExchangeIO` | The unction responsible for receiving an observable operation and returning a result | Yes |-| client | `Client` | The URQL application-wide client library. Each execute method starts a GraphQL request and returns a stream of results. | Yes |+An exchange is defined to be a function that receives [`ExchangeInput`](#exchangeinput) and returns+an `ExchangeIO` function. The `ExchangeIO` function in turn will receive a stream of operations, and-The `cacheExchange` as [described in the Basics section](https://formidable.com/open-source/urql/docs/basics#cacheexchange).+The `cacheExchange` as [described on the "Document Caching" page.](../basics/document-caching.md). It's of type `Exchange`.-The `subscriptionExchange` as [described in the Basics section](https://formidable.com/open-source/urql/docs/basics#subscriptions).+The `subscriptionExchange` as [described on the "Subscriptions" page.](../advanced/subscriptions.md). It's of type `Options => Exchange`.-The `ssrExchange` as [described in the Basics section](https://formidable.com/open-source/urql/docs/basics#server-side-rendering).···+The `fetchExchange` of type `Exchange` is responsible for sending operations of type `'query'` and+stringified to ensure that two objects with a different order of keys will be stabily stringified to+This utility accepts a GraphQL query of type `string | DocumentNode` and optionally an object of+[`GraphQLRequest`s](#graphqlrequest), this helper is commonly used to create that request first. The+[`client.query`](#clientquery) and [`client.mutation`](#clientmutation) methods use this helper as+The helper takes are of creating a unique `key` for the `GraphQLRequest`. This is a hash of the+Additionally, this utility will ensure that the `query` reference will remain stable. This means+that if the same `query` will be passed in as a string or as a fresh `DocumentNode`, then the output+It accepts an [`Operation`](#operation), the API result, and optionally the original `FetchResponse`+This is a helper function that creates an [`OperationResult`](#operationresult) for GraphQL API+It accepts an [`Operation`](#operation), the error, and optionally the original `FetchResponse`+This utility accepts a GraphQL `data` object, like `data` on [`OperationResult`s](#operationresult)+The [`formatDocument`](#formatdocument) is often used by `urql` automatically and adds `__typename`+fields to all results. However, this means that data can often not be passed back into variables or+inputs on mutations, which is a common use-case. This utility hides these fields which can solves-The `fetchExchange` as [described in the Basics section](https://formidable.com/open-source/urql/docs/basics#fetchexchange).+This is an array of the default `Exchange`s that the `Client` uses when the `exchanges` option isn't
+424
docs/api/graphcache.md
···+The `@urql/exchange-graphcache` package contains an addon `cacheExchange` for `urql` that may be+used to replace the default [`cacheExchange`](./core.md#cacheexchange), which switches `urql` from+The `cacheExchange` function, as exported by `@urql/exchange-graphcache`, accepts a single object of+| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |+| _keys_ | A mapping of key generator functions for types that are used to override the default key generation that _Graphcache_ uses to normalize data for given types. |+| _resolvers_ | A nested mapping of resolvers, which are used to override the record or entity that _Graphcache_ resolves for a given field for a type. |+| _updates_ | A nested mapping of updater functions for mutation and subscription fields, which may be used to add side-effects that update other parts of the cache when the given subscription or mutation field is written to the cache. |+| _optimistic_ | A mapping of mutation fields to resolvers that may be used to provide _Graphcache_ with an optimistic result for a given mutation field that should be applied to the cached data temporarily. |+| _schema_ | A serialized GraphQL schema that is used by _Graphcache_ to resolve partial data, to resolve interfaces and enums, and to provide helpful warnings. |+It may be used to alter how _Graphcache_ generates the key it uses for normalization for individual+[Read more about how to set up `keys` in the "Key Generation" section of the "Normalized Caching"+| -------- | -------- | ----------------------------------------------------------------------------------------------------------- |+| cache | `Cache` | The cache using which data can be read or written. [See `Cache`.](#cache) |+| info | `Info` | Additional metadata and information about the current operation and the current field. [See `Info`.](#info) |+`UpdateResolver` functions. An update resolver may be defined to add side-effects that run when a+given mutation field or subscription field is written to the cache. These side-effects are helpful+to update data in the cache that is implicitly changed on the GraphQL API, that _Graphcache_ can't+| -------- | -------- | ----------------------------------------------------------------------------------------------------------- |+| cache | `Cache` | The cache using which data can be read or written. [See `Cache`.](#cache) |+| info | `Info` | Additional metadata and information about the current operation and the current field. [See `Info`.](#info) |+The `optimistic` configuration is a mapping of Mutation field names to `OptimisticMutationResolver`+functions, which return optimistic mutation results for given fields. These results are used by+_Graphcache_ to optimistically update the cache data, which provides an immediate and temporary+A `OptimisticMutationResolver` receives three arguments when it's called: `variables`, `cache`, and+| --------- | -------- | ----------------------------------------------------------------------------------------------------------- |+| cache | `Cache` | The cache using which data can be read or written. [See `Cache`.](#cache) |+| info | `Info` | Additional metadata and information about the current operation and the current field. [See `Info`.](#info) |+The `schema` option may be used to pass a `IntrospectionQuery` data to _Graphcache_, in other words+partial results when querying, which are results that the cache can partially resolve as long as no+An instance of the `Cache` interface is passed to every resolvers and updater function. It may be+[`cacheExchange` configuration](#cacheexchange) to alter the default behaviour of _Graphcache_.+The `cache.keyOfEntity` method may be called with a partial `Data` object and will return the key+An object may not be keyable if it's missing the `__typename` or `id` (which falls back to `_id`)+There's an alternative method, `cache.keyOfField` which generates a key for a given field. This is+This method retrieves a value or link for a given field, given a partially keyable `Data` object or+entity, a field name, and optionally the field's arguments. Internally this method accesses the+As you can see in the last example of this code snippet, the `Data` object can also be replaced by+an entity key, which makes it possible to pass a key from `cache.keyOfEntity` or another call to+> **Note:** Because `cache.resolve` may return either a scalar value or another entity key, it may+> be dangerous to use in some cases. It's a good idea to make sure first whether the field you're+There's an alternative method, `cache.resolveFieldByKey` which accepts a field key that may be+cache.resolveFieldByKey({ __typename: 'Query' }, cache.keyOfField('todo', { id: 1 })); // 'Todo:1'+The `cache.inspectFields` method may be used to interrogate the cache about all available fields on+a specific entity. It accepts a partial entity or an entity key, like [`cache.resolve`](#resolve)'s+When calling the method this returns an array of `FieldInfo` objects, one per field (including+differing arguments) that is known to the cache. The `FieldInfo` interface has three properties:+| --------- | ---------------- | ------------------------------------------------------------------------------- |+| arguments | `object \| null` | The field's arguments, or `null` if the field doesn't have any arguments |+| fieldKey | `string` | The field's cache key, which is similar to what `cache.keyOfField` would return |+This works on any given entity. When calling this method the cache works in reverse on its data+`cache.readFragment` accepts a GraphQL `DocumentNode` as the first argument and a partial entity or+The method will then attempt to read the entity according to the fragment entirely from the cached+Note that the `__typename` may be left out on the partial entity, since the `__typename` is already+The `cache.readQuery` method is similar to `cache.readFragment`, but instead of reading a fragment+from cache, it reads an entire query. The only difference between how these two methods are used is+The method accepts a `{ query, variables }` object as the first argument, where `query` may either+Corresponding to [`cache.readFragment`](#readfragments), the `cache.writeFragment` method allows+The arguments for `cache.writeFragment` are identical to [`cache.readFragment`](#readfragment),+however the second argument, `data`, should not only contain properties that are necessary to derive+In the example we can see that the `writeFragment` method returns `undefined`. Furthermore we pass+`id` in our `data` object so that an entity key can be written, but the fragment itself doesn't have+The `cache.updateQuery` method accepts the same `{ query, variables }` object input as its first+accepts an updater function. This function will be called with the query data that is already in the+cache (which may be `null` if the data is uncached) and must return the new data that should be+As we can see, our updater may return `null` to cancel updating any data, which we do in case the+We can also see that data can simply be mutated and doesn't have to be altered immutably. This is+because all data from the cache is already a deep copy and hence we can do to it whatever we want.+Since deleting an entity will lead to some queries containing missing and uncached data, calling+`invalidate` may lead to additional GraphQL requests being sent, unless you're using [_Graphcache_'s+"Schema Awareness" feature](../graphcache/schema-awareness.md), which takes optional fields into+This is a metadata object that is passed to every resolver and updater function. It contains basic+information about the current GraphQL document and query, and also some information on the current+| -------------- | -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |+| parentFieldKey | `string` | The current key's cache key, which is the parent entity's key combined with the current field's key (This is mostly obsolete) |+| fragments | `{ [name: string]: FragmentDefinitionNode }` | A dictionary of fragments from the current GraphQL document |+| partial | `?boolean` | This may be set to `true` at any point in time (by your custom resolver or by _Graphcache_) to indicate that some data is uncached and missing |+| optimistic | `?boolean` | This is only `true` when an optimistic mutation update is running |+> there's no other solution to get to the metadata you need. We don't regard the `Info` API as+The `extras` subpackage is published with _Graphcache_ and contains helpers and utilities that don't+Currently the `extras` subpackage only contains the [pagination resolvers that have been mentioned+Accepts a single object of optional options and returns a resolver that can be inserted into the+| -------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |+| offsetArgument | `?string` | The field arguments's property, as passed to the resolver, that contains the current offset, i.e. the number of items to be skipped. Defaults to `'skip'`. |+| limitArgument | `?string` | The field arguments's property, as passed to the resolver, that contains the current page size limit, i.e. the number of items on each page. Defaults to `'limit'`. |+Once set up, the resulting resolver is able to automatically concatenate all pages of a given field+automatically. Queries to this resolvers will from then on only return the infinite, combined list+Accepts a single object of optional options and returns a resolver that can be inserted into the+| --------- | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |+| mergeMode | `'outwards' \| 'inwards'` | With Relay pagination, pages can be queried forwards and backwards using `after` and `before` cursors. This option defines whether pages that have been quiered backwards should be concatenated before (outwards) or after (inwards) all pages that have been queried forwards. |+Once set up, the resulting resolver is able to automatically concatenate all pages of a given field+automatically. Queries to this resolvers will from then on only return the infinite, combined list
+2
-1
docs/api/preact.md
+97
-128
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/queries.md#pausing-usequery). |-| ------------- | ------------------------ | --------------------------------------------------------------------------------------------------------------------- | -------- |-| query | `string \| DocumentNode` | The query to be executed. Accepts as a plain string query or GraphQL DocumentNode. | Yes |-| requestPolicy | `RequestPolicy` | An optional [request policy](/basics/querying-data#request-policy) that should be used specifying the cache strategy. | No |-| pause | `boolean` | A boolean flag instructing `Query` to pause execution of the subsequent query operation. | No |-| pollInterval | `number` | Every `pollInterval` milliseconds the query will be refetched. | No |+- The `result` is an object with the shape of an [`OperationResult`](./core.md#operationresult) with+an added `fetching: boolean` property, indicating whether the query is currently being fetched.+[`Partial<OperationContext>`](./core.md#operationcontext) and reexecutes the current query when-A tuple is returned with item one being the current query's state object and item two being an `executeQuery` function.+Accepts a single `query` argument of type `string | DocumentNode` and returns a tuple of the shape+- The `result` is an object with the shape of an [`OperationResult`](./core.md#operationresult) with+an added `fetching: boolean` property, indicating whether the mutation is currently being executed.+mutation. It returns a `Promise` resolving to an [`OperationResult`](./core.md#operationresult).-[More information on how to use this hook can be found in the Basics section.](/basics/querying-data#queries)+[Read more about how to use the `useMutation` API on the "Mutations" page.](../basics/mutations.md)+| --------- | ------------------------ | ------------------------------------------------------------------------------------------- |+| 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/queries.md#pausing-usequery). |-A tuple is returned with item one being the current query's state object and item two being an `executeQuery` function.-[More information on how to use this hook can be found in the Basics section.](/basics/mutating-data#mutations)-Accepts an `options` object as the required first parameter, and a second optional parameter that is the subscription's handler function.-| --------- | ------------------------ | ---------------------------------------------------------------------------------- | -------- |-| query | `string \| DocumentNode` | The query to be executed. Accepts as a plain string query or GraphQL DocumentNode. | Yes |+The hook optionally accepts a second argument, which may be a handler function with a type signature+incoming from a subscription event, and may be used to "reduce" the data over time, altering the-The shape of the current state is an [OperationResult Type](/api/core#operationresult-type) without the first `operation` prop.+- The `result` is an object with the shape of an [`OperationResult`](./core.md#operationresult).+[`Partial<OperationContext>`](./core.md#operationcontext) and restarts the current subscription when+it's called. When `pause` is set to `true` this starts the subscription, overriding the otherwise+By default `urql` is not able to start subscriptions, since this requires some additional setup.-| ------------- | -------------------------- | ----------------------------------------------------------------------------------------------------- | -------- |-| pause | `?boolean` | A boolean flag instructing `Query` to pause execution of the subsequent query operation | No |-| pollInterval | `?number` | Every `pollInterval` milliseconds the query will be refetched | No |-| children | `RenderProps => ReactNode` | A function that follows the typical render props pattern. The shape of the render props is as follows | N/A |-| ------------ | ----------------------------------- | ------------------------------------------------------------------------------------------------------- |-| error | `?CombinedError` | The `CombinedError` containing any errors that might've occured |-| extensions | `?Record<string, any>` | Optional extensions that the GraphQL server may have returned. |-| executeQuery | `Partial<OperationContext> => void` | A function that can force the operation to be sent again with the given context (Useful for refetching) |-[More information on how to use this hook can be found in the Basics section.](/basics/querying-data#queries)+The API of the `Query` component mirrors the API of [`useQuery`](#usequery). The props that `<Query>`+A function callback must be passed to `children` that receives the query result and must return a+React element. The second argument of the hook's tuple, `executeQuery` is passed as an added property-| -------- | -------------------------- | ----------------------------------------------------------------------------------------------------- |-| children | `RenderProps => ReactNode` | A function that follows the typical render props pattern. The shape of the render props is as follows |-| --------------- | ------------------------------------------------------------------ | ---------------------------------------------------------------- |-| error | `?CombinedError` | The `CombinedError` containing any errors that might've occured |-| extensions | `?Record<string, any>` | Optional extensions that the GraphQL server may have returned. |-| executeMutation | `(variables: object, context?: Partial<OperationContext>) => void` | A function that accepts variables and starts the mutation |+The `Mutation` component accepts a `query` prop and a function callback must be passed to `children`+`useMutation`'s returned tuple, `executeMutation` is passed as an added property on the mutation-[More information on how to use this hook can be found in the Basics section.](/basics/mutating-data#mutations)+This component is a wrapper around [`useSubscription`](#usesubscription), exposing a [render prop-[More information on how to use this component can be found in the Basics section.](https://formidable.com/open-source/urql/docs/basics#subscriptions)+The API of the `Subscription` component mirrors the API of [`useSubscription`](#usesubscription).+The props that `<Mutation>` accepts are the same as `useSubscription`'s options object, with an+added, optional `handler` prop that may be passed, which for the `useSubscription` hook is instead+A function callback must be passed to `children` that receives the subscription result and must+return a React element. The second argument of the hook's tuple, `executeSubscription` is passed as-| --------- | --------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |-| handler | `undefined \| (prev: R \| undefined, data: T) => R` | The handler that should combine/update the subscription's data with incoming data |-| children | `RenderProps => ReactNode` | A function that follows the typical render props pattern. The shape of the render props is as follows |-| ---------- | ---------------------- | --------------------------------------------------------------- |-| error | `?CombinedError` | The `CombinedError` containing any errors that might've occured |-| extensions | `?Record<string, any>` | Optional extensions that the GraphQL server may have returned. |+To keep examples brief, `urql` creates a default client with the `url` set to `'/graphql'`. This+client will be used when no `Provider` wraps any of `urql`'s hooks. However, to prevent this default+client from being used accidentally, a warning is output in the console for the default client.+However, this hook is also responsible for outputting the default client warning that's mentioned
docs/assets/logos/egghead.png
This is a binary file and will not be displayed.
docs/assets/logos/github.png
This is a binary file and will not be displayed.
docs/assets/logos/tripadvisor.png
This is a binary file and will not be displayed.
+12
-4
docs/basics/README.md
···+In this chapter we'll explain the basics of `urql` and how to get started with using it without any+- **Document Caching** explains the default cache mechanism of `urql`, as opposed to the [Normalized+documentation](../concepts/README.md) as it explains the motivation and architecture that drives
+11
docs/basics/document-caching.md
···This is an aggressive form of cache invalidation. However, it works well for content-driven sites,+The _request policy_ that is defined will alter what the default document cache does. By default the+cache will prefer cached results and will otherwise send a request, which is called `cache-first`,
+29
docs/basics/errors.md
···+When we use a GraphQL API there are two kinds of errors we may encounter: Network Errors and GraphQL+We may encounter a `CombinedError` when using `urql` wherever an `error` may be returned, typically+in results from the API. The `CombinedError` can have one of two properties that describe what went+- The `graphQLErrors` property may be an array that contains [normalized `GraphQLError`s as they+were returned in the `errors` array from a GraphQL API.](https://graphql.org/graphql-js/error/)+`data`. This is because in GraphQL a query can have partially failed but still contain some data.+In that case `CombinedError` will be passed to us with `graphQLErrors`, while `data` may still be
+97
docs/basics/getting-started.md
···+In the ["Introduction"](./README.md) we read how `urql` consists of multiple constituent parts that+make up a GraphQL client. Hence there are multiple packages — one for each framework we officially+This "Getting Started" guide covers how to install and set up `urql` and the Client, for React and+reading the documentation on React, all examples are essentially the same, except that we'll use the+Installing `urql` is as quick as you'd expect and you won't need any other packages to get started+dependency, so that they can adapt to your specific versioning requirements, which is why we'll need+Both the `urql` packages and `graphql` follow [semantic versioning](https://semver.org) and `urql`+packages will define a range of compatible versions of `graphql`. Watch out for breaking changes in+the future however, in which case your package manager may warn you about `graphql` being out of the+The `urql` and `@urql/preact` packages export a method called `createClient` which we can use to+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 be+In the following example we'll add a token to each `fetch` request that our `Client` sends to our+Now every component and element inside and under the `Provider` are able to use GraphQL queries that
-61
docs/basics/mutating-data.md
···-Similar to the `useQuery` output, `useMutation` returns a tuple. The first item in the tuple being our `result`-containing: `fetching`, `error`, and `data`. At this point in time, no mutation has been performed.-To mutate the data we first have to invoke the second item in the tuple - the function here named `updateTodo`.-When calling this `updateTodo` function we have two ways of getting the response from the server,-we can get it from `updateTodoResult` or we can await the promise returned from our mutation trigger function.
+101
docs/basics/mutations.md
···+Sending mutations to our GraphQL API is similar to what we've learned about sending queries to our+Both libraries offer a `useMutation` hook and a `Mutation` component. The latter accepts the same+Similar to the `useQuery` output, `useMutation` returns a tuple. The first item in the tuple again+contains `fetching`, `error`, and `data` — it's identical since this is a common pattern of how+Unlike the `useQuery` hook, the `useMutation` hook doesn't execute automatically. At this point in+our example, no mutation will be performed. To execute our mutation we instead have to call the+When calling our `updateTodo` function we have two ways of getting to the result as it comes back+from our API. We can either use the first value of the returned tuple — our `updateTodoResult` — or+This is useful when your UI has to display progress or results on the mutation, and the returned+There are some more tricks we can use with `useMutation`. [Read more about its API in the API docs for
+189
docs/basics/queries.md
···+Let's get to querying our data! This page will teach us how we can retrieve our data declaratively+For the following examples imagine we are querying data from a GraphQL API that contains todo items+accepts options — in this case we've set `query` to our GraphQL query — and returns a tuple — an+The result contains several properties. The `fetching` field indicates whether we're currently loading+data, `data` contains the actual `data` from the API's result, and `error` is set when either the+Typically we'll also need to pass variables to our queries, for instance What if we are dealing with+pagination? For this purpose the `useQuery` hook also accepts a `variables` option, which we can use+As when we're sending GraphQL queries manually using `fetch`, the variables will be attached to the+the `useQuery` hook changes `fetching` will return to being `true` and a new request will be sent to+instance, we may be building a form and want validation to only take place when a field has been+In the previous example we've defined a query with mandatory arguments. The `$from` and `$limit`+Now whenever the mandatory `$from` or `$limit` variables aren't supplied the query won't be executed.+This also means that `result.data` won't change, which means we'll still have access to our old data+As has become clear in the previous sections of this page, the `useQuery` hook accepts more options+default this is set to `cache-first`, which means that we prefer to get results from our cache, but+- `cache-first` (the default) prefers cached results and falls back to sending an API request when+- `cache-and-network` returns cached results but also always sends an API request, which is perfect+The `cache-and-network` policy is particularly useful, since it allows us to display data instantly+if it has been cached, but also refreshes data in our cache in the background. This means though+that `fetching` will be `false` for cached results although an API request may still be ongoing in+For this reason there's another field on results, `result.stale`, which indicates that the cached+`variables` change, but in some cases we may find that we need to programmatically trigger a new+query. This is the purpose of the `reexecuteQuery` function which is the second item in the tuple+Triggering a query programmatically may be useful in a couple of cases. It can for instance be used+Calling `refresh` in the above example will execute the query again forcefully, and will skip the+Furthermore the `reexecuteQuery` function can also be used to programmatically start a query even+There are some more tricks we can use with `useQuery`. [Read more about its API in the API docs for
-107
docs/basics/querying-data.md
···-As you can see we are enforcing `from` and `limit` as mandatory (notice the "!" after the `Int` type)-this means that if we don't supply them this query will fail, we need some way of pausing this query-this property tells the client how you want to get the result for your query, there are four values:-- `cache-first` (default), this means we want to first look in our cache and see if the result is there, if not-- `cache-and-network`, here we'll go to the cache and see if there's a result if there's not we fetch it, if there-- `cache-only`, here we'll look for your data in the cache, if it's there you'll get the data returned, if not
-81
docs/basics/setting-up-the-client.md
···
-6
docs/common-questions.md
+20
docs/concepts/README.md
···+In this chapter we'll learn about the motivation behind `urql`, the architecture that drives it, the+inner workings of the `Client`, and how to write extensions and addons, also known as _Exchanges_.+- **Philosophy** gives a quick overview of the different aspects of GraphQL clients and `urql` in+- **Stream Pattern** explains the inner working of `urql`, which is _stream-based_, also known as+- **Core Package** defines why a shared package exists that contains the main logic of `urql`, and+- **Exchanges** finally introduces _Exchanges_ and how to write extensions or addons and use them+Caching"](../graphcache/normalized-caching.md). It's advisable to read this chapter before moving on
+30
-34
docs/concepts/core-package.md
···-Previously, [the "Philosophy" page](./philosophy.md) explained how `urql` solves different aspects+_Exchanges_. These are the shared, default parts of `urql` that we will be using no matter which+[`Client`](../api/core.md#client) — and the package that we need to know about if we're either integrating `urql` with a new+The ["Philosophy"](./philosophy.md) page explains how `urql` solves some of problems encountered when different aspectsof having a GraphQL client handle declarative querying and being a central point of extensibiliy.By extension there are three parts of `urql` you'll come in contact with when you add it to your- the framework integration that allows you to declaratively write queries and mutations in your-On this page we'll learn about the latter two points, which is shared logic that isn't specific to-_Exchanges_. These are the shared, default parts of `urql` that we will be using no matter which-`Client` — and the package that we need to know about if we're either integrating `urql` with a newThe largest part of `urql` itself and the core package is the aforementioned `Client`. It's often-Patterns".](./stream-patterns.md) However, the `Client` also has plenty of convenience methods that+Patterns](./stream-patterns.md). However, the [`Client`](../api/core.md#client) also has plenty of······-`client.executeQuery` but unsubscribes immediately. If a result is available in the cache it will be-resolved synchronosuly before we immediately unsubscribe, otherwise this will cause no request to be+`client.executeQuery` and unsubscribes immediately. If a result is available in the cache it will be+resolved synchronosuly prior to the unsubscribe. If not, the query is cancelled and no request will be sent to the GraphQL API.The `@urql/core` package contains other utilities that are shared between multiple addon packages.-- `createRequest`, a utility function to create a request from a query and some variables (which+- [`CombinedError`](../api/core.md#combinederror) - our abstraction to combine one or more `GraphQLError`(s) and a `NetworkError`+- [`createRequest`](../api/core.md#createrequest) - a utility function to create a request from a query and some variables (which+There are other utilities not mentioned here. Read more about the `@urql/core` API in the [API docs](../api/core.md).
+65
-67
docs/concepts/exchanges.md
···-As we've learned [on the "Stream Patterns" page](./stream-patterns.md), `urql`'s `Client` structures+As we've learned on the [Stream Patterns](./stream-patterns.md) page, `urql`'s `Client` structures+`Client` to provide a result. These results then come from an output stream of operation results.-responsibility of _Exchanges_. _Exchanges_ are handler functions that deal with these input and-caching, fetching, deduplicating requests, and more. In other words, _Exchanges_ are handlers that+_Exchanges_ are responsible for performing the important transform from the operations (input) stream to the results stream. Exchanges are handler functions that deal with these input and+output streams. They're one of `urql`'s key components, and are needed to implement vital pieces of logic such as+caching, fetching, deduplicating requests, and more. In other words, Exchanges are handlers that-The default exchanges that `@urql/core` contains and applies by default to a `Client` without custom- `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-Their signature is a function that receives a `forward` function, which is the next _Exchange_ in a-chain of them and returns the `ExchangeIO` function, which accepts the source of _Operations_ and+The first parameter to an exchange is a `forward` function that refers to the next Exchange in the+chain. The second second parameter is the `Client` being used. Exchanges always return an `ExchangeIO`-The `Client` accepts an `exchanges` option which is by default the list of default exchanges, as-discussed above. When we pass a custom list of exchanges the `Client` uses the `composeExchanges`+The `Client` accepts an `exchanges` option that defaults to the three default exchanges mentioned above. When we pass a custom list of exchanges the `Client` uses the `composeExchanges`In essence these exchanges build a pipeline that runs in the order they're passed; _Operations_ flow-**Third,** operations are sent to the API and the result is normalized. The result then travels+**Third,** operations are sent to the API and the result is normalized. The normalized result then travels-Before we can start writing some exchanges, there are a couple of patterns and limitations that-always remain the same when writing an exchange. We call these the "rules of _Exchanges_", which+Before we can start writing some exchanges, there are a couple of consistent patterns and limitations that···This exchange does nothing else than forward all operations and return all results. Hence, it'sWhen you create a `Client` and pass it an array of exchanges, `urql` composes them left-to-right.-If we look at our previous `noopExchange` example in context, we can track what it does if it sat+If we look at our previous `noopExchange` example in context, we can track what it does if it is located between the `dedupExchange` and the `fetchExchange`.···-When writing an _Exchange_ we have to be careful not to "split" the stream into multiple ones by-subscribing multiple times. Streams are lazy and immutable by default. Every time you use them, you-create a new chain of streaming operators, but since _Exchanges_ are side-effects, we don't want to+When writing an Exchange we have to be careful not to _split_ the stream into multiple ones by+subscribing multiple times. Streams are lazy and immutable by default. Every time you use them, a new chain of streaming operators is created; since Exchanges are technically side-effects, we don't want to-Your `ExchangeIO` function receives an `operations$` stream, and you must be careful to either only+The `ExchangeIO` function receives an `operations$` stream. It's important to be careful to either only·········use Wonka's [`share`](https://wonka.kitten.sh/api/operators#share) operator, to share the underlying······+If operations are grouped and/or filtered by what the exchange is handling, then it's also important to-Or this could happen because your exchange inherently does something asynchronous, like fetching some+This can also happen because the exchange inherently does something asynchronous, like fetching some+to be _synchronous_ first. This is very helpful for suspense mode and allowing components receive cached data on their initial···
+29
-33
docs/concepts/philosophy.md
···+configuration. `urql` is designed to be a client that grows with you. As you go from building your first+GraphQL app to a utilising the full functionality, the toopls are available to extend and customize `urql` based on-In this guide, we will walkthrough how `urql` is set up internally and how all pieces of the puzzle+In this guide, we will walk through how `urql` is set up internally and how all pieces of the puzzle···-You may have worked on a GraphQL API previously and noticed that using GraphQL in your app can be+You may have worked with a GraphQL API previously and noticed that using GraphQL in your app can be···-This all happens in the background while you just declare that you'd like to have data for a given+This all happens in the background, allowing you to simply declare that you'd like to have data for a givenWhen we use GraphQL queries and mutations declaratively with `urql`, we expect them to interact-Furthermore, we don't wish to send more requests for a query, when we've done so before. We'd like-to instead cache results in-memory and notify other parts of an app when these results chane or+Furthermore, when we've already received the results from a query, we may not wish to send another request. To solve this, results can be cached in-memory and notifications can be sent to other parts of an app when the results change or-GraphQL clients have access to some amount of type information for any GraphQL API and can hencecache the results of queries automatically. In `urql` the `Client` can be extended with several-cache implementations, but all of them mean that you'll never mix your declarative query or mutation+cache implementations; all of them allow you to prevent mixing your declarative query or mutation[how you may store data in Redux.](https://redux.js.org/recipes/structuring-reducers/normalizing-state-shape/)···in the cache and structures it in a graph, which leads to more shared data, and hence more shared-[Read more about how to add "Normalized Caching" to an app.](../graphcache/normalized-caching.md)-For instance, you may want to add authentication, retry-logic for failed requests, or a global+With any kind of API there can be concerns outside of caching and state mangagement. For example,+the global behavior or business logic of your application. For instance, you may want to add authentication, retry-logic for failed requests, or a global-`urql` provides a concept of _Exchanges_ to abstract the details of how the `Client` interacts with+`urql` introduces the concept of _Exchanges_ in order to abstract the details of how the `Client` interacts with[middleware in Redux](https://redux.js.org/advanced/middleware) and have access to all operations+streams of operations and results allow us to implement complex behaviour in addition to allowing deep customisation over how the operations/results are handled. We'll learn more about this in the next section - [the Core Package](./core-package.md).
+29
-25
docs/concepts/stream-patterns.md
···-As we've learned [on the last page](./philosophy.md), `urql`'s main way of handling GraphQL requests+As we've learned in the previous section on [philosophy](./philosophy.md), `urql`'s main way of handling GraphQL requests-Mainly, the client abstracts GraphQL requests as _Operations_, descriptions of the GraphQL request,-its query and variables, and also additional information that is configured on the `Client`, likeInternally the `Client` is an event hub. It defines a stream of operations as inputs, sends them-through a layer that will ultimately send GraphQL requests to an API, and then sends the results+through a layer that will ultimately send GraphQL requests to an API, and then send the corresponding results+As a user working with framewrk code we never interact with these streams directly, but it's helpful to know that they describe+every interaction between the declarative queries we write and the way that `urql` fulfills them.Generally we refer to _streams_ as abstractions that allow us to program with asynchronous streams ofand [Reactive Programming with Observables.](http://reactivex.io/documentation/observable.html)···methods on arrays, so you're likely to see `map` and `filter` — amongst other utlities — in those`urql` utilises the [Wonka](https://github.com/kitten/wonka) library for its streams. It has a-- It's predictable and also an iterable toolchain, emitting synchronous events whenever possible.···+In Wonka, like with Observables, streams are cancellable by calling the `unsubscribe` method that aconvenience wrappers around `executeRequestOperation` that create an operation and return a stream.There are also convenience wrappers around the "execute" methods that are useful when using `urql`···There are several of these convenience methods in `urql` that make it easier to work with the
+77
-1
docs/graphcache/README.md
···+In `urql`, caching is fully configurable via [_Exchanges_](../concepts/exchanges.md) and the default+complex it's likely that the data and state that `urql` manages, will also grow more complex and+To solve this problem most GraphQL clients resort to caching data in a normalized format, similar to+The following pages introduce different features in _Graphcache_ which together make it a compelling+alternative to the standard [document cache](../basics/document-caching.md) that `urql` uses by+- 🔁 [**Fully reactive, normalized caching.**](./normalized-caching.md) _Graphcache_ stores data in+a normalized data structure. Query, mutation, and subscription results may update one another if+they share data, and the app will rerender or refetch data accordingly. This often allows your app+- 💾 [**Custom cache resolvers**](./computed-queries.md) Since all queries are fully resolved in the+cache before and after they're sent, you can add custom resolvers that enable you to format data,+- 💭 [**Subscription and Mutation updates**](./custom-updates.md) You can implement update functions+that tell _Graphcache_ how to update its data after a mutation has been executed, or whenever a+subscription sends a new event. This allows the cache to reactively update itself without queries+- 🏃 [**Optimistic mutation updates**](./custom-updates.md) When implemented, optimistic updates can+provide the data that the GraphQL API is expected to send back before the request succeeds, which+- 🧠 [**Opt-in schema awareness**](./schema-awareness.md) _Graphcache_ also optionally accepts your+entire schema, which allows it to resolve _partial data_ before making a request to the GraphQL+API, allowing an app to render everything that's cached before receiving all missing data. It also+allows _Graphcache_ to output more helpful warnings and to handle interfaces and enums correctly+- 📡 **Offline support** (work in progress) _Graphcache_ can persist and rehydrate its entire state,+[Bundlephobia](https://bundlephobia.com/result?p=@urql/exchange-graphcache) may suggest, since it+shares the dependency on `wonka` and `@urql/core` with the framework bindings package, e.g. `urql`+The package exports the `cacheExchange` which replaces the default `cacheExchange` in `@urql/core`.+_Graphcache_ as introduced in the ["Features" section above.](#features) Howver, you can get started+_Graphcache_ already does what you'd expect it to do without any additional configuration. We'll
+58
-29
docs/graphcache/computed-queries.md
···-- `cache` – This is the normalized cache. The cache provides us with `resolve`, `readQuery` and `readFragment` methods;+- `cache` – This is the normalized cache. The cache provides us with `resolve`, `readQuery` and `readFragment` methods,- `info` – This contains the fragments used in the query and the field arguments in the query.············+When graphcache isn't [aware of your schema](./schema-awareness.md) it won't show partial data.···+> [graphql-tag](https://github.com/apollographql/graphql-tag) because `writeFragment` only acceptsGiven you have a schema that uses some form of `offset` and `limit` based pagination you can use the`simplePagination` exported from `@urql/exchange-graphcache/extras` to achieve an endless scroller.···Given you have a [relay-compatible schema](https://facebook.github.io/relay/graphql/connections.htm)···
+147
-90
docs/graphcache/custom-updates.md
···+but sometimes this isn't possible. While it will update all normalized entities that it finds in+those results, it can't for instance tell whether a new item should be appended or removed from a+Specifically, a normalized cache can't automatically assume that unrelated links have changed due to+The `updates` configuration is similar to our `resolvers` configuration that we've [previously looked+at on the "Computed Queries" page.](./computed-queries.md) We pass a resolver-like function into the+configuration that receives cache-specific arguments. Instead of the `parent` argument we'll however+Query"](./computed-queries.md) to read from the cached data, we can also use other `cache` methods to+The first we'll look at is `cache.updateQuery`. This method accepts a `{ query, variables }` object+as the first argument and an updater callback as the second. The updater function receives the query+Note that we don't have to update the query data immutably. _Graphcache_ never returns raw data and+will instead always return copies of data. This means that we can also mutate query data inside the···+In the above example, we add an updater configuration for `Mutation.addTodo`. Whenever a mutation's+Inside the updater we use `cache.updateQuery` to update a list of todos with the new todo that has+With this configuration any query that requests `Query.todos` will automatically update and contain+It's worth noting that it doesn't matter whether the `TodosQuery` is the same one that you use in+Similar to `cache.updateQuery`, we can also update data for a fragment using `cache.writeFragment`,+instead of an entire query. This method accepts a GraphQL fragment instead of an entire GraphQL+fragment. The second argument is the data that should be written to the cache. This data object must···+> [graphql-tag](https://github.com/apollographql/graphql-tag) because `writeFragment` only accepts+This can be useful for instance if we have a mutation that doesn't return the type that the GraphQL+API will alter in the background. Suppose we had a `updateTodoText` mutation that doesn't allow us+to access the updated `Todo`. In such a case `cache.writeFragment` allows us to make the change+In this example we haven't used `result` at all, but have written to a `Todo` fragment using the+arguments (`args`) that have been supplied to `Mutation.updateTodoText`. This can also be used in+combination with `cache.readFragment` or `cache.resolve` if we need to retrieve arbitrary data from+The `cache.invalidate` method is useful for evicting a single entity from the cache. When a user+logs out or a mutation deletes an item from a list it can be tedious to update every link in our+normalized data to said entity, instead the `cache.invalidate` method can be used to quickly remove+Note that this may lead to an additional request to the GraphQL API, unless you're making use of the+The above example deletes a `Todo` with a given `id` from the arguments, when `Mutation.deleteTodo`+If we know what result a mutation may return, why wait for the GraphQL API to fulfill our mutations?+The _Optimistic Updates_ configuration allows us to set up "temporary" results for mutations, which+will be applied immediately. This is a great solution to reduce the waiting time for the user.+This technique is often used with one-off mutations that are assumed to succeed, like starring a+repository, or liking a tweet. In such cases it's often desirable to make the interaction feel+`Mutation` fields that must return some data. When said mutation is then executed, _Graphcache_+The `optimistic` functions receive the same arguments as `resolvers` functions, except for `parent`:+- `cache` – The cache we've already seen in [resolvers](./computed-queries.md) and in the previous+examples on this page. In optimistic updates it's useful to retrieve more data from the cache.+Since we return an assumed result in our `optimistic` configuration, `Mutation.favoriteTodo` will be+automatically applied and `favorite` will seemingly flip to `true` instantly for the queries that
+1
-6
docs/graphcache/help.md
exchanges/graphcache/help.md
······-> You need to pass in a valid key (__typename:id) or an object with the "__typename" property and an "id" or "_id" property.+> You need to pass in a valid key (**typename:id) or an object with the "**typename" property and an "id" or "\_id" property.You probably have called `cache.invalidate` with data that the cache can't generate a key for.
+75
-33
docs/graphcache/normalized-caching.md
···+`__typename` information and `id` fields on entities to create a normalized table of data. Since+GraphQL deals with connected data in a tree structure, each entity may link to other entities or+even lists of entities, which we call "links". The scalar fields on entities like numbers, strings,+Caching"](../basics/document-caching.md), _Graphcache_ flattens all data it receives automatically.+If we looked at doing this manually on the following piece of data, we'd separate each object into a+This is vewry similar to how we'd go about creating a state management store manually, except that+_Graphcache_ can use the GraphQL document and the `__typename` field to perform this normalization+The interesting part of normalization starts when we read from the cache instead of writing to it.+Multiple results may refer to the same piece of data — a mutation for instance may update `"Todo:1"`+later on in the app. This would automatically cause _Graphcache_ to update any related queries in+combining the `__typename` of a piece of data with the `id` or `_id` fields, if they're present. For+_Graphcache_ will log a warning when these fields weren't requested as part of a query's selection+set or aren't present in the data. This can be useful if we forget to include them in our queries.+In general, _Graphcache_ will always output warnings in development when it assumes that something+However, in your schema you may have types that don't have an `id` or `_id` field, say maybe some+types have a `key` field instead. In such cases the custom `keys` configuration comes into play+This will cause our cache to generate a key from `__typename` and `name` instead if an entity's type+Similarly some pieces of data shouldn't be normalized at all. If _Graphcache_ can't find the `id` or+`_id` fields it will log a warning and _embed the data_ instead. Embedding the data means that it+won't be normalized because the generated key is `null` and will instead only be referenced by the+You can force this behaviour and silence the warning by making a `keys` function that returns `null`
+16
-2
docs/graphcache/schema-awareness.md
············+Let's approach this with the example from [Computed queries](./computed-queries.md#resolve) we have+our `TodosQuery` result (a list) and now we want to get a specific `Todo` we wire these up through+`resolve` but we are missing an optional field for this, without a schema we don't know this is optional+and we will not show you the partial result. Now that we have a schema we can check if this is allowed to
+30
docs/showcase.md
···+- [Egghead Course](https://egghead.io/lessons/graphql-set-up-an-urql-graphql-provider-in-react?pl=introduction-to-urql-a-react-graphql-client-faaa2bf5)+- [`reason-urql`](https://github.com/FormidableLabs/reason-urql): The official Reason bindings for+- [`urql-computed-queries`](https://github.com/Drawbotics/urql-computed-exchange): An exchange to
+8
-4
packages/site/package.json
·········
+60
packages/site/scripts/deploy/aws.js
···
+42
packages/site/scripts/deploy/surge.js
···
+6
-7
packages/site/src/app.js
···
+2
-2
packages/site/src/components/header.js
···
+85
packages/site/src/components/loading.js
···
+106
-16
packages/site/src/components/mdx.js
··················
+1
-1
packages/site/src/components/section-title.js
+34
-21
packages/site/src/screens/docs/article.js
···············
+7
-10
packages/site/src/screens/docs/header.js
···
+4
-8
packages/site/src/screens/docs/index.js
·········
+3
-7
packages/site/src/screens/home/hero.js
··················
+1
-1
packages/site/src/styles/global.js
+5
-4
packages/site/src/styles/theme.js
·········
+7
-1
packages/site/static.config.js
·········
+3
-3
scripts/rollup/build.js
···
+317
-37
yarn.lock
···resolved "https://registry.yarnpkg.com/@kristoferbaxter/estree-walker/-/estree-walker-2.0.0.tgz#52ee40f9f8b59bbf00cac477a777aeb830ea5952"-resolved "https://registry.yarnpkg.com/@mdx-js/loader/-/loader-1.5.5.tgz#b658534153b3faab8f93ffc790c868dacc5b43d3"-integrity sha512-2/2WX73qj79Kv2cYk14kQsN/aypAH3RPzuNMx1gxwZjj77G0N6tzhM9WFkEDM/SXjasWep03ZmSRb9d//b2D8w==resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-1.5.5.tgz#09dc8932af84e5baf5add2625ad0250a117c3363"···resolved "https://registry.yarnpkg.com/async-sema/-/async-sema-3.0.0.tgz#9e22d6783f0ab66a1cf330e21a905e39b3b3a975"integrity sha512-zyCMBDl4m71feawrxYcVbHxv/UUkqm4nKJiLu3+l9lfiQha6jQ/9dxhrXLnzzBXVFqCTDwiUkZOz9XFbdEGQsg==+resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1"resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff"···resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683"+resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a"···resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.2.0.tgz#e8b988d9206c692302d8ee834e7a85c0144d8f77"integrity sha512-tgU3fKwzYjiLEQgPMD9Jt+JjHVL9kW93FiIMX/l7rivvOD4/LL0Mf7gda3+4U2KJBloybwgj5KEoQgGRioMiKQ==+resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202"+integrity sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574"···+resolved "https://registry.yarnpkg.com/colors/-/colors-0.6.2.tgz#2423fe6678ac0c5dae8852e5d0e5be08c997abcc"resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"+resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"+integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==···+resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2"resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9"···resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c"+resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.0.1.tgz#fc12bbd6850e93212f21344748682ccc5a8813cf"+integrity sha512-7Et6r6XfNW61CPPCIYfm1YPGSmh6+CliYeL4km7GWJcpX5LTAflGF8drLLR+MZX+2P3NZfAfSduutBbSWqER4g==···+es-abstract@^1.16.3, es-abstract@^1.17.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.4:resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.4.tgz#e3aedf19706b20e7c2594c35fc0d57605a79e184"···+resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.0.tgz#bb98ad9d6d63b31aacdc8f89d5d0ee57bcb5b4c8"+integrity sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ==resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a"···resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"+resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0"resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"···resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.2.tgz#4c0a1fb34bc68e543b4b82a9ec392bfbda840805"+resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045"+integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"···+resolved "https://registry.yarnpkg.com/i/-/i-0.3.6.tgz#d96c92732076f072711b6b10fd7d4f65ad8ee23d"resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"···-inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3:+inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3:resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"···resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca"···resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03"+resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.0.tgz#73da8c33208d00f130e9b5e15d23eac9215601c4"+integrity sha512-t5mGUXC/xRheCK431ylNiSkGGpBp8bHENBcENTkDT6ppwPzEVxNGZRvgvmOEfbWkFhA7D2GEuE2mmQTr78sl2g==resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898"···resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.1.tgz#10edc0900dd127697a92f6f9807c7617d68ac48e"integrity sha512-TqZuVwa/sppcrhUCAYkGBk7w0yxfQQnxq28fjkO53tnK9FQXmdwz2JS5+GjsWQ6RByES1K40nI+yDic5c9/aAQ==···resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.0.0.tgz#2cb0df0e75e2d064fe1864c37cdeacb7b2dcf25b"integrity sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==+resolved "https://registry.yarnpkg.com/is-domain/-/is-domain-0.0.1.tgz#7ffb288d5cced6b07c4f2df91c9be9153511348e"resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"···resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7"+resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.1.tgz#520dafc4307bb8ebc33b813de5ce7c9400d644a1"+integrity sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw==resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591"···resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8"resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.4.tgz#36ac95e741cf18b283fc1ddf5e83da798e3ec197"integrity sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==···resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4"+resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.1.tgz#d1604afdab1724986d30091575f54945da7e5f43"+integrity sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA==resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"···resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3"resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6"···resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"+resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2"+integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==+resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.1.tgz#e9a0af88dbd751589f5e50d80f4c98b780884f83"+integrity sha512-pi4vhbhVHGLxohUw7PhGsueT4vRGFoXhP7+RGN0jKIv9+8PWYCQTqtADngrxOm2g46hoH0+g8uZZBzMrvVGDmw==resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz#0858edd94a95594c7c9dd0b5c174ec6e45ee4aa7"···resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e"+resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723"+integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"···resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"···resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7"+integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==···resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"···resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"+resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.1.1.tgz#1bc2bc71658cdca5712475684363615b0b4f695b"···resolved "https://registry.yarnpkg.com/mixme/-/mixme-0.3.5.tgz#304652cdaf24a3df0487205e61ac6162c6906ddd"resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"+resolved "https://registry.yarnpkg.com/moniker/-/moniker-0.1.2.tgz#872dfba575dcea8fa04a5135b13d5f24beccc97e"···resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"···resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"+resolved "https://registry.yarnpkg.com/ncp/-/ncp-0.4.2.tgz#abcc6cbd3ec2ed2a729ff6e7c1fa8f01784a8574"resolved "https://registry.yarnpkg.com/nearley/-/nearley-2.19.1.tgz#4af4006e16645ff800e9f993c3af039857d9dbdc"···resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c"+resolved "https://registry.yarnpkg.com/netrc/-/netrc-0.1.4.tgz#6be94fcaca8d77ade0a9670dc460914c94472444"···+resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.3.1.tgz#5b29f6a81f70717142e09e765bbeab97b4f81e21"+resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.4.1.tgz#b5418ef0439de5425fc4995042dced14fb2a84ff"resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942"···resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"+resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be"resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"···+resolved "https://registry.yarnpkg.com/prompt/-/prompt-0.2.14.tgz#57754f64f543fd7b0845707c818ece618f05ffdc"···-resolved "https://registry.yarnpkg.com/react-static-plugin-md-pages/-/react-static-plugin-md-pages-0.1.1.tgz#7cb19dad439eb81e820d17f48e11a948b248bb93"-integrity sha512-g374YtRDgPK6dIMRXaRbFuOYwXta/kASUVAY3rc+z7/YIiCqyjkS1Dkt/pyBAaTaXGsrXI4wZcIUxgN5Z0Fz3w==+resolved "https://registry.yarnpkg.com/react-static-plugin-md-pages/-/react-static-plugin-md-pages-0.1.3.tgz#2c019e9e5e407b5d7701669b9b4581d506662ab5"+integrity sha512-aONsWlmeZECJgAz5Er7Jw83RlGLXgf08OFMmn2e3+BADhbheKp7ZWvC50l3AP8jwRr6wslxCO/2kwx99GC0u6A==···-resolved "https://registry.yarnpkg.com/react-static-plugin-mdx/-/react-static-plugin-mdx-7.2.2.tgz#c90884103ea1c6007a502bf0efadd18e4be4f4a7"-integrity sha512-f0T/vq5cryIRvztt2tjpp3AjNdvR1krxl9ADR27AVK2StnFk2T20HraVsTdFDa1FUDrYwRP07JczUZV9gcFtzw==···+resolved "https://registry.yarnpkg.com/read/-/read-1.0.5.tgz#007a3d169478aa710a491727e453effb92e76203"+resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4""readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6:resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"···resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b"+resolved "https://registry.yarnpkg.com/revalidator/-/revalidator-0.1.8.tgz#fece61bfa0c1b52a206bd6b18198184bdd523a3b"resolved "https://registry.yarnpkg.com/rework-visit/-/rework-visit-1.0.0.tgz#9945b2803f219e2f7aca00adb8bc9f640f842c9a"···resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3"-resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"+resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"-resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"+resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"···resolved "https://registry.yarnpkg.com/shorthash/-/shorthash-0.0.2.tgz#59b268eecbde59038b30da202bcfbddeb2c4a4eb"resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.2.tgz#df5d1abadb4e4bf4af1cd8852bf132d2f7876947"···+resolved "https://registry.yarnpkg.com/split/-/split-0.3.1.tgz#cebcf142bf61bbb64b141628e6db482a2914654c"resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9"···resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf"+resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0"resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8"···+resolved "https://registry.yarnpkg.com/surge-fstream-ignore/-/surge-fstream-ignore-1.0.6.tgz#e30efce95574b91fd571b5b02f32a611ea829731"+integrity sha512-hNN52cz2fYCAzhlHmWPn4aE3bFbpBt01AkWFLljrtSzFvxlipLAeLuLtQ3t4f0RKoUkjzXWCAFK13WoET2iM1A==+resolved "https://registry.yarnpkg.com/surge-ignore/-/surge-ignore-0.2.0.tgz#5a7f8a20a71188cf9e75a2cfe8eb182de90daf3b"+resolved "https://registry.yarnpkg.com/surge/-/surge-0.21.3.tgz#8abfba77bac551d0db9bae0fc14a450874fd9e8d"+integrity sha512-2rTlyC6ku3alrMAyI/8xexCZeiQu0X11rc3Sg8k2SC+9+V+X2dsohCnsTgFbDANZzlL2WojzxmnzLsJFEu/WIQ==resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.18.1.tgz#db0f82cc46394ca8c9a9d183995e1ebfeea3bdd0"···+resolved "https://registry.yarnpkg.com/tarr/-/tarr-1.1.0.tgz#d7a9532ce97f08f5200b78ae0a82a6883173c8c8"+integrity sha512-tENbQ43IQckay71stp1p1lljRhoEZpZk10FzEZKW2tJcMcnLwV3CfZdxBAERlH6nwnFvnHMS9eJOJl6IzSsG0g==···+resolved "https://registry.yarnpkg.com/url-parse-as-address/-/url-parse-as-address-1.0.0.tgz#fb80901883f338b3cbed3538f5faa26adaf7f2e7"resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c"···resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c"+resolved "https://registry.yarnpkg.com/utile/-/utile-0.2.1.tgz#930c88e99098d6220834c356cbd9a770522d90d7"resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"···+resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.1.tgz#cbe8f838ebe91ba2471bb69e9edbda67ab5a5ec1"+integrity sha512-7BT4TwISdDGBgaemWU0N0OU7FeAEJ9Oo2P1PHRm/FCWoEi2VLWC9b6xvxAA3C/NMpxg3HXVgi0sMmGbNUbNepQ==+resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906"+integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"···resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc"+resolved "https://registry.yarnpkg.com/winston/-/winston-0.8.3.tgz#64b6abf4cd01adcaefd5009393b1d8e8bec19db0"