Repository: FormidableLabs/urql
Pull request #388 (2019-08-13 08:20:19)

(chore) - remove latency handling from fetchExchange
Related: https://github.com/FormidableLabs/urql-devtools-exchange/pull/2


Patch:
diff --git a/README.md b/README.md
index 870ed3f0..14d2e94f 100644
--- a/README.md
+++ b/README.md
@@ -22,6 +22,9 @@
   <a href="https://github.com/FormidableLabs/urql#maintenance-status">
     <img alt="Maintenance Status" src="https://img.shields.io/badge/maintenance-active-green.svg" />
   </a>
+  <a href="https://spectrum.chat/urql">
+    <img alt="Spectrum badge" src="https://withspectrum.github.io/badge/badge.svg" />
+  </a>
 
   <br />
   <br />
diff --git a/docs/api.md b/docs/api.md
index 00c3bb69..3ab2e460 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -1,8 +1,15 @@
+---
+title: API
+order: 6
+---
+
+<a name="api"></a>
+
 # API
 
 ## React components and hooks
 
-### `useQuery` (hook)
+### useQuery (hook)
 
 Accepts a single options object as input:
 
@@ -12,6 +19,7 @@ interface UseQueryArgs {
   variables?: any;
   requestPolicy?: RequestPolicy;
   pause?: boolean;
+  pollInterval?: number;
   context?: Partial<OperationContext>;
 }
 ```
@@ -33,9 +41,9 @@ interface UseQueryState<T> {
 And the `executeQuery` function optionally
 accepts a partial `OperationContext`.
 
-[More information on how to use this hook can be found in the Getting Started section.](getting-started.md#writing-queries)
+[More information on how to use this hook can be found in the Getting Started section.](https://formidable.com/open-source/urql/docs/getting-started#writing-queries)
 
-### `useMutation` (hook)
+### useMutation (hook)
 
 Accepts a single `query` argument of type `string`. And returns the
 current mutation's state and an `executeMutation` function in a tuple. The
@@ -58,9 +66,9 @@ interface UseMutationState<T> {
 The `executeMutation` function accepts the `variables` of type `object` and
 an optional `context` variable of type `Partial<OperationContext>`.
 
-[More information on how to use this hook can be found in the Getting Started section.](getting-started.md#writing-mutations)
+[More information on how to use this hook can be found in the Getting Started section.](https://formidable.com/open-source/urql/docs/getting-started#writing-mutations)
 
-### `useSubscription` (hook)
+### useSubscription (hook)
 
 Accepts an options argument as its first input, and a second optional argument that is
 the subscription handler function.
@@ -94,11 +102,11 @@ interface UseSubscriptionState<T> {
 }
 ```
 
-[More information on how to use this hook can be found in the Basics section.](basics.md#subscriptions)
+[More information on how to use this hook can be found in the Basics section.](https://formidable.com/open-source/urql/docs/basics#subscriptions)
 
-### `Query` (component)
+### Query (component)
 
-[More information on how to use this component can be found in the Getting Started section.](getting-started.md#writing-queries)
+[More information on how to use this component can be found in the Getting Started section.](https://formidable.com/open-source/urql/docs/getting-started#writing-queries)
 
 #### Props
 
@@ -109,6 +117,7 @@ interface UseSubscriptionState<T> {
 | context       | `?object`                  | The GraphQL request's context                                                                         |
 | requestPolicy | `?RequestPolicy`           | An optional request policy that should be used                                                        |
 | pause         | `?boolean`                 | A boolean flag instructing `Query` to pause execution of the subsequent query operation               |
+| pollInterval  | `?number`                  | Every `pollInterval` milliseconds the query will be refetched                                         |
 | children      | `RenderProps => ReactNode` | A function that follows the typical render props pattern. The shape of the render props is as follows |
 
 #### Render Props
@@ -121,9 +130,9 @@ interface UseSubscriptionState<T> {
 | 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) |
 
-### `Mutation` (component)
+### Mutation (component)
 
-[More information on how to use this component can be found in the Getting Started section.](getting-started.md#writing-mutations)
+[More information on how to use this component can be found in the Getting Started section.](https://formidable.com/open-source/urql/docs/getting-started#writing-mutations)
 
 #### Props
 
@@ -142,9 +151,9 @@ interface UseSubscriptionState<T> {
 | 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        |
 
-### `Subscription` (component)
+### Subscription (component)
 
-[More information on how to use this component can be found in the Basics section.](basics.md#subscriptions)
+[More information on how to use this component can be found in the Basics section.](https://formidable.com/open-source/urql/docs/basics#subscriptions)
 
 #### Props
 
@@ -173,7 +182,7 @@ be used in combination with the `useContext` hook.
 
 ## The Client and related types
 
-### `Client` (class)
+### Client (class)
 
 The client manages all operations and ongoing requests to the exchange pipeline.
 It accepts a bunch of inputs when it's created
@@ -188,7 +197,7 @@ It accepts a bunch of inputs when it's created
 
 `urql` also exposes `createClient()` that is just a convenient alternative to calling `new Client()`.
 
-#### `.executeQuery()`, `.executeSubscription()`, and `.executeMutation()`
+#### .executeQuery(), .executeSubscription(), and .executeMutation()
 
 These methods are used by `<Query>` & `useQuery()`, `<Subscription>` & `useSubscription()`,
 and `<Mutation>` & `useMutation()` respectively.
@@ -200,7 +209,7 @@ Internally they then create an `Operation` and call `.executeRequestOperation()`
 the `Operation`. This then returns a `Source<OperationResult>`, i.e. a stream of
 `OperationResult`s.
 
-#### `.executeRequestOperation()`
+#### .executeRequestOperation()
 
 This method accepts an `Operation` and handles the flow of said `Operation`. Every `Operation`
 that is executed must pass through this method.
@@ -227,7 +236,7 @@ is dispatched.
 
 The return value is the filtered `Source<OperationResult>`.
 
-#### `.reexecuteOperation()`
+#### .reexecuteOperation()
 
 This method accepts an `Operation` and will dispatch this `Operation` if there
 are any subscriptions from `executeRequestOperation`'s `Source<OperationResult>`
@@ -236,7 +245,7 @@ to this particular `Operation`.
 This is called by `cacheExchange` when an `Operation`'s `OperationResult` is
 invalidated in the cache.
 
-#### `.createRequestOperation()`
+#### .createRequestOperation()
 
 This is called by the `executeQuery`, `executeSubscription` and `executeMutation`
 methods to create `Operation`s. It accepts:
@@ -247,7 +256,7 @@ methods to create `Operation`s. It accepts:
 
 It returns an `Operation`.
 
-#### `.dispatchOperation()`
+#### .dispatchOperation()
 
 This method dispatches an `Operation` to the exchange pipeline. This is only
 used directly by the Client and shouldn't normally be called externally, except
@@ -256,7 +265,7 @@ when the tracking logic of active `Operation`s needs to be bypassed.
 These `Operation`s are streamed from the `operations$: Source<Operation>` stream.
 The results of all exchanges are similarly output to `results$: Source<OperationResult>`.
 
-### `OperationType` (type)
+### OperationType (type)
 
 This determines what _kind of operation_ the exchanges need to perform.
 This can either be:
@@ -270,7 +279,7 @@ The `'teardown'` operation is special in that it instructs exchanges to cancel
 any ongoing operations with the same key as the `'teardown'` operation that is
 received.
 
-### `RequestPolicy` (type)
+### RequestPolicy (type)
 
 This determines the strategy that a cache exchange should use to fulfill an operation.
 When you implement a custom cache exchange it's recommended that these policies are
@@ -281,7 +290,7 @@ handled.
 - `'network-only'`
 - `'cache-and-network'`
 
-### `GraphQLRequest` (type)
+### GraphQLRequest (type)
 
 This often comes up as the **input** for every GraphQL request.
 It consists of `query` and optional `variables`.
@@ -298,7 +307,7 @@ As can be seen it also carries a `key` property. This property
 is a hash of both the `query` and the `variables`, to uniquely
 identify the request.
 
-### `OperationContext` (type)
+### OperationContext (type)
 
 This type is used to give an operation additional metadata and information.
 
@@ -315,7 +324,7 @@ It contains a lot of the above mentioned Client options and also `requestPolicy`
 It accepts additional, untyped parameters that can be used to send more
 information to custom exchanges.
 
-### `Operation` (type)
+### Operation (type)
 
 The input for every exchange that informs GraphQL requests.
 it's essentially an extension of the `GraphQLRequest`.
@@ -333,7 +342,7 @@ type Operation = {
 The `key` value is a "hash" of `query` and `variables` or another string that
 unique identifies the combination of the two.
 
-### `OperationResult` (type)
+### OperationResult (type)
 
 The result of every GraphQL request, i.e. an `Operation`.
 It's very similar to what comes back from a typical GraphQL API, but
@@ -348,7 +357,7 @@ type OperationResult = {
 };
 ```
 
-### `CombinedError` (class)
+### CombinedError (class)
 
 | Input         | Type                             | Description                                                                       |
 | ------------- | -------------------------------- | --------------------------------------------------------------------------------- |
@@ -364,7 +373,7 @@ that a GraphQL result might have normally.
 
 ## Exchanges and their utilities
 
-### `ExchangeInput` (type)
+### ExchangeInput (type)
 
 ```js
 type ExchangeInput = {
@@ -373,7 +382,7 @@ type ExchangeInput = {
 };
 ```
 
-### `ExchangeIO` (type)
+### ExchangeIO (type)
 
 A function that receives a stream of operations and must return a stream
 of results.
@@ -382,7 +391,7 @@ of results.
 type ExchangeIO = (Source<Operation>) => Source<OperationResult>;
 ```
 
-### `Exchange` (type)
+### Exchange (type)
 
 Similar to `redux-observable`'s epics, kind of related to Apollo's links,
 also somehow similar to Express' middleware.
@@ -396,7 +405,7 @@ Exchanges can therefore be chained. They can alter and filter `Operation`s
 that go into the next exchange, and they can alter, filter, or return
 `OperationResult`s that are returned.
 
-### `composeExchanges` (function)
+### composeExchanges (function)
 
 This utility accepts multiple exchanges and composes them into a single one.
 It chains them in the order that they're given, left to right.
@@ -408,23 +417,23 @@ function composeExchanges(Exchange[]): Exchange;
 This can be used to combine some exchanges and is also used by `Client`
 to handle the `exchanges` input.
 
-### `cacheExchange` (Exchange)
+### cacheExchange (Exchange)
 
-The `cacheExchange` as [described in the Basics section](basics.md#cacheexchange).
+The `cacheExchange` as [described in the Basics section](https://formidable.com/open-source/urql/docs/basics#cacheexchange).
 It's of type `Exchange`.
 
-### `subscriptionExchange` (Exchange factory)
+### subscriptionExchange (Exchange factory)
 
-The `subscriptionExchange` as [described in the Basics section](basics.md#subscriptions).
+The `subscriptionExchange` as [described in the Basics section](https://formidable.com/open-source/urql/docs/basics#subscriptions).
 It's of type `Options => Exchange`.
 
 It accepts a single input: `{ forwardSubscription }`. This is a function that
 receives an enriched operation and must return an Observable-like object that
 streams `GraphQLResult`s with `data` and `errors`.
 
-### `ssrExchange` (Exchange factory)
+### ssrExchange (Exchange factory)
 
-The `ssrExchange` as [described in the Basics section](basics.md#server-side-rendering).
+The `ssrExchange` as [described in the Basics section](https://formidable.com/open-source/urql/docs/basics#server-side-rendering).
 It's of type `Options => Exchange`.
 
 It accepts two inputs, `initialState` which is completely
@@ -454,39 +463,39 @@ Basically, the `ssrExchange` is a small cache that collects data
 during the server-side rendering pass, and allows you to populate
 the cache on the client-side with the same data.
 
-During React rehydration this cache will be emptied,
-becomes inactive, and won't change the results of queries after
+During React rehydration this cache will be emptied and it will
+become inactive and won't change the results of queries after
 rehydration.
 
 It needs to be used _after_ other caching Exchanges like the
 `cacheExchange`, but before any _asynchronous_ Exchange like
 the `fetchExchange`.
 
-### `debugExchange` (Exchange)
+### debugExchange (Exchange)
 
 An exchange that writes incoming `Operation`s to `console.log` and
 writes completed `OperationResult`s to `console.log`.
 
-### `dedupExchange` (Exchange)
+### dedupExchange (Exchange)
 
 An exchange that keeps track of ongoing `Operation`s that haven't returned had
 a corresponding `OperationResult` yet. Any duplicate `Operation` that it
 receives is filtered out if the same `Operation` has already been received
 and is still waiting for a result.
 
-### `fallbackExchangeIO` (ExchangeIO)
+### fallbackExchangeIO (ExchangeIO)
 
 This is an `ExchangeIO` function that the `Client` adds on after all
 exchanges. This function is responsible from filtering `teardown` operations
 out of the output and also warns you of unhandled `operationName`s which
 can occur when a subscription is used without adding a `subscriptionExchange`.
 
-### `fetchExchange` (Exchange)
+### fetchExchange (Exchange)
 
-The `fetchExchange` as [described in the Basics section](basics.md#fetchexchange).
+The `fetchExchange` as [described in the Basics section](https://formidable.com/open-source/urql/docs/basics#fetchexchange).
 It's of type `Exchange`.
 
-### `defaultExchanges` (Exchange[])
+### defaultExchanges (Exchange[])
 
 An array of the default exchanges that the `Client` uses when it wasn't passed
 an `exchanges` option.
diff --git a/docs/architecture.md b/docs/architecture.md
index f2fe79ad..e16d0e55 100644
--- a/docs/architecture.md
+++ b/docs/architecture.md
@@ -1,3 +1,10 @@
+---
+title: architecture
+order: 1
+---
+
+<a name="architecture"></a>
+
 # Architecture
 
 Much of `urql` is about being flexible and customizable.
diff --git a/docs/basics.md b/docs/basics.md
index c7214383..3db80cbf 100644
--- a/docs/basics.md
+++ b/docs/basics.md
@@ -1,5 +1,14 @@
+---
+title: Basics
+order: 2
+---
+
+<a name="basics"></a>
+
 # Basics
 
+<a name="main-file"></a>
+
 As mentioned before, `urql`'s core logic is split into exchanges.
 To that end, `urql`'s behavior is completely defined by the exchanges
 you pass to it or that are the default ones.
@@ -21,7 +30,9 @@ const client = new Client({
 This list of default exchanges is also exported as `defaultExchanges`
 however.
 
-## `fetchExchange`
+## fetchExchange
+
+<a name="fetchexchange"></a>
 
 The `fetchExchange` handles `query` and `mutation` operations and uses `fetch`
 to send GraphQL API requests.
@@ -63,7 +74,9 @@ allow `response.status >= 300` when `redirect` is set to `'manual'`.
 **In summary:** `fetchExchange` is a simple request handler that takes
 operations and sends `POST` requests using `fetch`.
 
-## `cacheExchange`
+## cacheExchange
+
+<a name="cacheexchange"></a>
 
 The default caching behavior that `urql` uses is defined by the `cacheExchange`
 unlike Apollo's `Cache` or `InMemoryCache`, caching behavior is handled as
@@ -113,7 +126,7 @@ respond with the types that are invalidated.
 Given an `addTodo` mutation for example, you will need to send
 back at least one `TodoItem` for the invalidation to happen.
 
-A **document cache** also doesn't normalise at all, which means
+A **document cache** also doesn't normalize at all, which means
 that after fetching a list of items, fetching a single item
 will never be fulfilled by this cache.
 
@@ -146,16 +159,16 @@ result may be displayed that is then updated with fresh data
 from the API.
 
 > _Note:_ `'network-only'` and `'cache-and-network'` are extremely valuable
-> given the limitations of the default cache. The can be used to ensure
+> given the limitations of the default cache. They can be used to ensure
 > that data skips the cache, if it's clear to you that the result will
 > need to be up-to-date.
 
 ### Customization
 
-The idea of `urql` is that you can customise the caching behavior amongst
+The idea of `urql` is that you can customize the caching behavior amongst
 other things yourself, if needed.
 
-[Read more about customising `urql` in the "Extending & Experimenting" section.](extending-and-experimenting.md)
+[Read more about customizing `urql` in the "Extending & Experimenting" section.](https://formidable.com/open-source/urql/docs/extending-&-experimenting)
 
 ## Server-side rendering
 
@@ -180,7 +193,7 @@ it to prefetch data on the server-side. For this reason we have a companion
 library, [`react-ssr-prepass`](https://github.com/FormidableLabs/react-ssr-prepass), which can be used to run a "prepass"
 that fetches all suspended data it finds in a React element tree.
 
-### Setting up the `Client`
+### Setting up the Client
 
 When you set up the `Client` for server-side rendering, on the server
 you will need to set `suspense` to `true` and on the client to `false`,
@@ -328,7 +341,7 @@ up [have a look at our SSR + next.js example project](https://github.com/Formida
 ## Subscriptions
 
 One feature of `urql` that was not mentioned in the
-["Getting Started" section](getting-started.md) is `urql`'s
+["Getting Started" section](https://formidable.com/open-source/urql/docs/getting-started) is `urql`'s
 APIs and ability to handle subscriptions.
 
 To add support for subscriptions there's the `subscriptionExchange`.
diff --git a/docs/exchanges.md b/docs/exchanges.md
index 584d1f83..37e33b23 100644
--- a/docs/exchanges.md
+++ b/docs/exchanges.md
@@ -1,3 +1,10 @@
+---
+title: Exchanges
+order: 3
+---
+
+<a name="exchanges"></a>
+
 # Exchanges
 
 ## Packages
diff --git a/docs/extending-and-experimenting.md b/docs/extending-and-experimenting.md
index 72cd533e..89e152b4 100644
--- a/docs/extending-and-experimenting.md
+++ b/docs/extending-and-experimenting.md
@@ -1,7 +1,14 @@
+---
+title: extending-&-experimenting
+order: 4
+---
+
+<a name="extending-&-experimenting"></a>
+
 # Extending & Experimenting
 
-Hopefully you have read the sections on `urql`'s [Architecture](architecture.md)
-and its [Basics](basics.md). This section will introduce you to hacking
+Hopefully you have read the sections on `urql`'s [Architecture](https://formidable.com/open-source/urql/docs/architecture)
+and its [Basics](https://formidable.com/open-source/urql/docs/basics). This section will introduce you to hacking
 with `urql`.
 
 `urql` comes with some very functional defaults, but its standard component APIs,
@@ -19,7 +26,7 @@ and hooks or even React at all.
 
 The Client is structured so that it can easily be reused to create different
 APIs or integrate `urql` with other libraries and frameworks than React.
-[Have a look at the API docs to see a full list of the client's methods.](api.md#client-class)
+[Have a look at the API docs to see a full list of the client's methods.](https://formidable.com/open-source/urql/docs/api#client-class)
 
 While it's possible to write new APIs outside of React or new components
 quite easily, this section will only focus on hooks, for illustrative
diff --git a/docs/getting-started.md b/docs/getting-started.md
index a428529c..9de7598a 100644
--- a/docs/getting-started.md
+++ b/docs/getting-started.md
@@ -1,3 +1,10 @@
+---
+title: Getting Started
+order: 0
+---
+
+<a name="getting-started"></a>
+
 # Getting Started
 
 ## Installation
@@ -73,7 +80,7 @@ const getTodos = `
   }
 `;
 
-const TodoList = ({ limit = 10 }) => {
+const TodoList = ({ limit = 10 }) => (
   <Query query={getTodos} variables={{ limit }}>
     {({ fetching, data, error, extensions }) => {
       if (fetching) {
@@ -91,7 +98,7 @@ const TodoList = ({ limit = 10 }) => {
       );
     }}
   </Query>;
-};
+);
 ```
 
 When this component is mounted it will send the `query` and `variables`
@@ -109,7 +116,7 @@ is not the plural `errors`. `urql` wraps any network error or GraphQL
 errors in a `CombinedError` which is more convenient to handle and
 observe.
 
-[Read more about the result's API in the Architecture's Results section.](architecture.md#operation-results)
+[Read more about the result's API in the Architecture's Results section.](https://formidable.com/open-source/urql/docs/architecture#operation-results)
 
 ### Using hooks
 
@@ -162,16 +169,16 @@ as soon as it's mounted and will rerun it when the query or variables change.
 > A tutorial on the `useQuery` hook is also available as a
 > [screencast on egghead](https://egghead.io/lessons/graphql-query-graphql-data-with-urql-using-react-hooks?pl=introduction-to-urql-a-react-graphql-client-faaa2bf5).
 
-[Read more about the result's API in the Architecture's Results section.](architecture.md#operation-results)
+[Read more about the result's API in the Architecture's Results section.](https://formidable.com/open-source/urql/docs/architecture#operation-results)
 
-### Using `graphql-tag`
+### Using graphql-tag
 
 You're not limited to just passing in strings as queries. You can also
 pass in a fully parsed AST in the form of `DocumentNode` instead.
 For this purpose you can use `graphql-tag`.
 
 This can be extremely helpful, since it enables syntax highlighting
-in some editors. It also can be used to pre-parse the GraphQL query
+in some editors. It also can be used to preparse the GraphQL query
 using `babel-plugin-graphql-tag` or the included Webpack loader.
 
 You only have to make a small adjustment. Install `graphql-tag` and
@@ -353,7 +360,7 @@ cached completely. When the same query and variables are requested again,
 result is also invalidated when a mutation with similar `__typename`s was
 sent.
 
-[You can find out more about the default caching behavior in the Basics' `cacheExchange` section.](basics.md#cacheexchange)
+[You can find out more about the default caching behavior in the Basics' `cacheExchange` section.](https://formidable.com/open-source/urql/docs/basics#cacheexchange)
 
 Using `urql`'s default behavior this means we sometimes need a way to refetch
 data from the GraphQL API and skip the cache, if we need fresh data.
@@ -382,15 +389,15 @@ Including `'cache-and-network'` there are four request policies in total:
 - `cache-and-network`: As stated above, this returns the cached result and then also
   sends a request to the API.
 
-[You can find out more about how the default cache behaves when it receives these request policies in the Basics' `cacheExchange` section.](basics.md#request-policies)
+[You can find out more about how the default cache behaves when it receives these request policies in the Basics' `cacheExchange` section.](https://formidable.com/open-source/urql/docs/basics#request-policies)
 
 Next, we can take a look at how to use `'network-only'` to force a refetch
 imperatively. In our previous example this would come in handy to refresh the
 list of todos.
 
 ```jsx
-import React from 'react';
-import { Query } from 'urql';
+import React from "react";
+import { Query } from "urql";
 
 const getTodos = `
   query GetTodos {
@@ -402,7 +409,7 @@ const getTodos = `
   }
 `;
 
-const TodoList = () => {
+const TodoList = () => (
   <Query query={getTodos}>
     {({ executeQuery, data }) => {
       if (!data) {
@@ -426,7 +433,7 @@ const TodoList = () => {
       );
     }}
   </Query>;
-};
+);
 ```
 
 As can be seen, the `<Query>` render props also expose an `executeQuery` method, which
diff --git a/docs/guides.md b/docs/guides.md
index 43e283ed..2519428d 100644
--- a/docs/guides.md
+++ b/docs/guides.md
@@ -1,3 +1,10 @@
+---
+title: guides
+order: 4
+---
+
+<a name="guides"></a>
+
 # Guides
 
 In `urql`, all queries and requests start as "operations". A stream
@@ -9,7 +16,7 @@ They're not unlike middleware in an HTTP server implementation like
 Express. They have the ability to forward operations to the next
 exchange and to return the stream of results from the next exchange.
 
-[You can read more about this structure in our "Architecture" section](./architecture.md)
+[You can read more about this structure in our "Architecture" section](https://formidable.com/open-source/urql/docs/architecture)
 
 These guides are not intended as best practices or specific instructions for
 writing exchanges. Rather they teach you how to get started on creating
@@ -81,7 +88,7 @@ const noopExchange = ({ client, forward }) => {
 };
 ```
 
-In this form it doesn't do anything yet.
+In this form the exchange doesn't do anything yet.
 When you create a client and pass it an array of exchanges, all exchanges
 will be composed together into a single one. They will each be called with
 an object that contains the `client` itself, and a `forward` function which
diff --git a/docs/urql-outside-react.md b/docs/urql-outside-react.md
new file mode 100644
index 00000000..770b943e
--- /dev/null
+++ b/docs/urql-outside-react.md
@@ -0,0 +1,159 @@
+---
+title: urql outside of react
+order: 5
+---
+
+<a name="urql-outside-of-react"></a>
+
+# urql Outside of React
+
+While `urql` is a GraphQL client that's mainly targeting React, apart from our React-specific APIs (i.e. the hooks and components), all other elements of the library function the same outside of a React context. In this guide, we'll take a look at using `urql` in environments other than React, including NodeJS and Vue.
+
+The most useful element for using `urql` outside of React is the `Client`, the library's central orchestrator. The `Client` handles all outgoing requests and incoming responses in `urql`, and comes along with a variety of methods to help you orchestrate communication with your GraphQL API. The most useful of these are the `execute*` methods (`executeQuery`, `executeMutation`, and `executeSubscription`).
+
+The `execute*` methods all accept an instance of a `GraphQLRequest`, which can be created by using `urql`'s `createRequest` function. `createRequest` will create a unique hash used to identify the GraphQL operation, which is used internally to track it for things like deduplication and caching.
+
+```javascript
+// load dependencies
+require('isomorphic-fetch');
+const { createClient, createRequest } = require('urql');
+const gql = require('graphql-tag');
+
+// create the urql Client
+const client = createClient({
+  url: 'https://graphbrainz.herokuapp.com/graphql',
+});
+
+// define your GraphQL query
+const query = gql`
+  query SearchArtist($search: String!) {
+    search {
+      artists(query: $search, first: 1) {
+        edges {
+          node {
+            name
+            country
+            releases(first: 10) {
+              edges {
+                node {
+                  title
+                  date
+                  media {
+                    format
+                    trackCount
+                    tracks {
+                      title
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+`;
+
+// create the urql request object
+const request = createRequest(query, { search: 'Courtney Barnett' });
+```
+
+Once you've created your request, all that's left is to execute it! When you execute a query, mutation, or subscription, `urql` returns you [a `wonka` Source](https://wonka.kitten.sh/api/sources) containing the `data` and `error` states of that request. You can use [`wonka`'s Sinks](https://wonka.kitten.sh/api/sinks) to access these like so:
+
+```javascript
+const { pipe, subscribe } = require('wonka');
+
+pipe(
+  client.executeQuery(request),
+  subscribe(({ data, error }) => {
+    if (error) {
+      console.log('Error', error);
+    }
+
+    console.log('Data', data);
+  })
+);
+```
+
+Awesome, we've successfully executed a GraphQL query on the server in NodeJS! In practice, this is more useful for writing small Node scripts or a simple CLI for interacting with a GraphQL API. But it does show off the flexibility that `urql`'s `Client` gives us!
+
+See the full CodeSandbox example [here](https://codesandbox.io/s/urql-node-1jhj8).
+
+## Doing More with the Client
+
+The `Client` comes with more methods than just the `execute*` methods. While the use cases for these additional methods are fairly specific to `urql`'s implementation, they do give you more direct control over the `Client`. Let's say, for example, that you want to reexecute an operation on a predefined interval (a form of long polling). This is fairly trivial to do by calling `Client.reexecuteOperation` with the request's `Operation` object. To create the `Operation` object, use `Client.createOperation`, passing the operation type as the first argument (`"query"`, `"mutation"`, `"subscription"`, or `"teardown"`).
+
+```javascript
+require('isomorphic-fetch');
+const { createClient, createRequest } = require('urql');
+const gql = require('graphql-tag');
+const { pipe, subscribe, interval, take } = require('wonka');
+
+const client = createClient({
+  url: 'https://graphbrainz.herokuapp.com/graphql',
+});
+
+const query = gql`
+  query SearchArtist($search: String!) {
+    search {
+      artists(query: $search, first: 1) {
+        edges {
+          node {
+            name
+            country
+            releases(first: 10) {
+              edges {
+                node {
+                  title
+                  date
+                  media {
+                    format
+                    trackCount
+                    tracks {
+                      title
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+`;
+
+const request = createRequest(query, { search: 'Courtney Barnett' });
+
+pipe(
+  client.executeQuery(request),
+  subscribe(({ data, error }) => {
+    if (error) {
+      console.log('Error', error);
+    }
+
+    console.log('Data', data);
+  })
+);
+
+pipe(
+  interval(2000),
+  take(10),
+  subscribe(n => {
+    // Call client.createRequest operation to create the Operation object.
+    // The optional third argument is a partial operation context, which allows you
+    // to change the operation's request policy or fetch options.
+    const operation = client.createRequestOperation('query', request, {
+      requestPolicy: 'network-only',
+    });
+
+    // Reexecute the operation. Active subscribers will receive updates.
+    client.reexecuteOperation(operation);
+  })
+);
+```
+
+Awesome, we've got basic long polling working, where our `Client` is reexecuting the initial request every 2 seconds. By passing `{ requestPolicy: 'network-only' }` as the third argument to `reexecuteOperation`, we ensure that the `Client` issues a new request to the GraphQL API every time rather than pulling results from the cache. You'll notice in this example we use `wonka`'s `take` operator to limit the number of times we call `reexecuteOperation` – in true long polling, you wouldn't do this.
+
+See the full CodeSanbox example [here](https://codesandbox.io/s/urql-node-polling-erkwe).
diff --git a/examples/3-ssr-with-nextjs/package.json b/examples/3-ssr-with-nextjs/package.json
index 74669652..0e2a6e60 100644
--- a/examples/3-ssr-with-nextjs/package.json
+++ b/examples/3-ssr-with-nextjs/package.json
@@ -17,7 +17,7 @@
     "graphql": "^14.1.1",
     "graphql-tag": "^2.10.1",
     "isomorphic-unfetch": "^3.0.0",
-    "next": "^8.1.0",
+    "next": "latest",
     "react": "^16.8.6",
     "react-dom": "^16.8.6",
     "react-is": "^16.8.6",
diff --git a/examples/3-ssr-with-nextjs/pages/_app.js b/examples/3-ssr-with-nextjs/pages/_app.js
index 52ce3e16..f4b1804a 100644
--- a/examples/3-ssr-with-nextjs/pages/_app.js
+++ b/examples/3-ssr-with-nextjs/pages/_app.js
@@ -1,4 +1,4 @@
-import App, { Container } from 'next/app';
+import App from 'next/app';
 import React from 'react';
 
 import withUrqlClient from '../src/with-urql-client';
@@ -8,11 +8,9 @@ class MyApp extends App {
   render() {
     const { Component, pageProps, urqlClient } = this.props;
     return (
-      <Container>
         <Provider value={urqlClient}>
           <Component {...pageProps} />
         </Provider>
-      </Container>
     );
   }
 }
diff --git a/examples/3-ssr-with-nextjs/src/with-urql-client.js b/examples/3-ssr-with-nextjs/src/with-urql-client.js
index a8af6181..798b035f 100644
--- a/examples/3-ssr-with-nextjs/src/with-urql-client.js
+++ b/examples/3-ssr-with-nextjs/src/with-urql-client.js
@@ -6,7 +6,7 @@ import initUrqlClient from './init-urql-client';
 const withUrqlClient = App => {
   return class WithUrql extends React.Component {
     static async getInitialProps(ctx) {
-      const { Component, router } = ctx;
+      const { AppTree } = ctx;
 
       // Run the wrapped component's getInitialProps function
       let appProps = {};
@@ -25,10 +25,8 @@ const withUrqlClient = App => {
 
       // Run suspense and hence all urql queries
       await ssrPrepass(
-        <App
+        <AppTree
           {...appProps}
-          Component={Component}
-          router={router}
           urqlClient={urqlClient}
         />
       );
diff --git a/src/client.ts b/src/client.ts
index 23e354c2..970d3d74 100755
--- a/src/client.ts
+++ b/src/client.ts
@@ -8,6 +8,10 @@ import {
   share,
   Source,
   take,
+  merge,
+  interval,
+  fromValue,
+  switchMap,
 } from 'wonka';
 
 import {
@@ -197,7 +201,17 @@ export class Client {
     opts?: Partial<OperationContext>
   ): Source<OperationResult> => {
     const operation = this.createRequestOperation('query', query, opts);
-    return this.executeRequestOperation(operation);
+    const response$ = this.executeRequestOperation(operation);
+    const { pollInterval } = operation.context;
+
+    if (pollInterval) {
+      return pipe(
+        merge([fromValue(0), interval(pollInterval)]),
+        switchMap(() => response$)
+      );
+    } else {
+      return response$;
+    }
   };
 
   executeSubscription = (
diff --git a/src/exchanges/fetch.ts b/src/exchanges/fetch.ts
index c2238105..6e31800d 100755
--- a/src/exchanges/fetch.ts
+++ b/src/exchanges/fetch.ts
@@ -2,7 +2,7 @@
 import { print } from 'graphql';
 import { filter, make, merge, mergeMap, pipe, share, takeUntil } from 'wonka';
 import { Exchange, Operation, OperationResult } from '../types';
-import { addMetadata, makeResult, makeErrorResult } from '../utils';
+import { makeResult, makeErrorResult } from '../utils';
 
 /** A default exchange for fetching GraphQL requests. */
 export const fetchExchange: Exchange = ({ forward }) => {
@@ -78,20 +78,9 @@ const createFetchSource = (operation: Operation) => {
         abortController !== undefined ? abortController.signal : undefined,
     };
 
-    const startTime = Date.now();
-
     executeFetch(operation, fetchOptions).then(result => {
       if (result !== undefined) {
-        if (process.env.NODE_ENV !== 'production') {
-          next({
-            ...result,
-            operation: addMetadata(result.operation, {
-              networkLatency: Date.now() - startTime,
-            }),
-          });
-        } else {
-          next(result);
-        }
+        next(result);
       }
 
       complete();
diff --git a/src/hooks/index.ts b/src/hooks/index.ts
index f7c86247..58b57faa 100644
--- a/src/hooks/index.ts
+++ b/src/hooks/index.ts
@@ -1,4 +1,3 @@
 export * from './useMutation';
 export * from './useQuery';
 export * from './useSubscription';
-export * from './useDevtoolsContext';
diff --git a/src/hooks/useDevtoolsContext.ts b/src/hooks/useDevtoolsContext.ts
deleted file mode 100644
index dc257953..00000000
--- a/src/hooks/useDevtoolsContext.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-import * as React from 'react';
-import { OperationContext } from '../types';
-
-const {
-  ReactCurrentOwner: CurrentOwner,
-} = (React as any).__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
-
-// Is the Fiber a FunctionComponent, ClassComponent, or IndeterminateComponent
-const isComponentFiber = (fiber: void | { tag: number }) =>
-  fiber && (fiber.tag === 0 || fiber.tag === 1 || fiber.tag === 2);
-
-// Is the component one of ours (just a heuristic to avoid circular dependencies or flags)
-const isInternalComponent = (Component: { name: string }) =>
-  Component.name === 'Query' ||
-  Component.name === 'Mutation' ||
-  Component.name === 'Subscription';
-
-const useDevtoolsContextImpl = (): Partial<OperationContext> => {
-  return React.useMemo(() => {
-    let source = 'Component';
-
-    // Check whether the CurrentOwner is set
-    const owner = CurrentOwner.current;
-    if (owner !== null && isComponentFiber(owner)) {
-      let Component = owner.type;
-
-      // If this is one of our own components then check the parent
-      if (
-        isInternalComponent(Component) &&
-        isComponentFiber(owner._debugOwner)
-      ) {
-        Component = owner._debugOwner.type;
-      }
-
-      // Get the Component's name if it has one
-      if (typeof Component === 'function') {
-        source = Component.displayName || Component.name || source;
-      }
-    }
-
-    return { meta: { source } };
-  }, []);
-};
-
-/** Creates additional context values for serving metadata to devtools. */
-export const useDevtoolsContext: () => Partial<OperationContext> | undefined =
-  // NOTE: We check for CurrentOwner in case it'll be unexpectedly changed in React's source
-  process.env.NODE_ENV !== 'production' && !!CurrentOwner
-    ? useDevtoolsContextImpl
-    : () => undefined;
diff --git a/src/hooks/useMutation.ts b/src/hooks/useMutation.ts
index 63f2abea..b4c83cb7 100644
--- a/src/hooks/useMutation.ts
+++ b/src/hooks/useMutation.ts
@@ -5,7 +5,6 @@ import { Context } from '../context';
 import { OperationResult, OperationContext } from '../types';
 import { CombinedError, createRequest } from '../utils';
 import { useImmediateState } from './useImmediateState';
-import { useDevtoolsContext } from './useDevtoolsContext';
 
 export interface UseMutationState<T> {
   fetching: boolean;
@@ -22,7 +21,6 @@ export type UseMutationResponse<T, V> = [
 export const useMutation = <T = any, V = object>(
   query: DocumentNode | string
 ): UseMutationResponse<T, V> => {
-  const devtoolsContext = useDevtoolsContext();
   const client = useContext(Context);
   const [state, setState] = useImmediateState<UseMutationState<T>>({
     fetching: false,
@@ -43,7 +41,7 @@ export const useMutation = <T = any, V = object>(
       const request = createRequest(query, variables as any);
 
       return pipe(
-        client.executeMutation(request, { ...devtoolsContext, ...context }),
+        client.executeMutation(request, context || {}),
         toPromise
       ).then(result => {
         const { data, error, extensions } = result;
@@ -51,7 +49,7 @@ export const useMutation = <T = any, V = object>(
         return result;
       });
     },
-    [client, devtoolsContext, query, setState]
+    [client, query, setState]
   );
 
   return [state, executeMutation];
diff --git a/src/hooks/useQuery.spec.ts b/src/hooks/useQuery.spec.ts
index 8236254d..00f3442e 100644
--- a/src/hooks/useQuery.spec.ts
+++ b/src/hooks/useQuery.spec.ts
@@ -80,7 +80,6 @@ describe('useQuery', () => {
         variables: mockVariables,
       },
       {
-        meta: { source: 'TestHook' },
         requestPolicy: undefined,
         url: 'test',
       }
diff --git a/src/hooks/useQuery.ts b/src/hooks/useQuery.ts
index 767247be..03bb45dd 100644
--- a/src/hooks/useQuery.ts
+++ b/src/hooks/useQuery.ts
@@ -4,7 +4,6 @@ import { pipe, subscribe } from 'wonka';
 import { Context } from '../context';
 import { OperationContext, RequestPolicy } from '../types';
 import { CombinedError, noop } from '../utils';
-import { useDevtoolsContext } from './useDevtoolsContext';
 import { useRequest } from './useRequest';
 import { useImmediateEffect } from './useImmediateEffect';
 import { useImmediateState } from './useImmediateState';
@@ -13,6 +12,7 @@ export interface UseQueryArgs<V> {
   query: string | DocumentNode;
   variables?: V;
   requestPolicy?: RequestPolicy;
+  pollInterval?: number;
   context?: Partial<OperationContext>;
   pause?: boolean;
 }
@@ -32,7 +32,6 @@ export type UseQueryResponse<T> = [
 export const useQuery = <T = any, V = object>(
   args: UseQueryArgs<V>
 ): UseQueryResponse<T> => {
-  const devtoolsContext = useDevtoolsContext();
   const unsubscribe = useRef(noop);
   const client = useContext(Context);
 
@@ -58,9 +57,9 @@ export const useQuery = <T = any, V = object>(
       [unsubscribe.current] = pipe(
         client.executeQuery(request, {
           requestPolicy: args.requestPolicy,
+          pollInterval: args.pollInterval,
           ...args.context,
           ...opts,
-          ...devtoolsContext,
         }),
         subscribe(({ data, error, extensions }) => {
           setState({ fetching: false, data, error, extensions });
@@ -70,8 +69,8 @@ export const useQuery = <T = any, V = object>(
     [
       args.context,
       args.requestPolicy,
+      args.pollInterval,
       client,
-      devtoolsContext,
       request,
       setState,
     ]
diff --git a/src/hooks/useSubscription.ts b/src/hooks/useSubscription.ts
index 25ea6843..8562c414 100644
--- a/src/hooks/useSubscription.ts
+++ b/src/hooks/useSubscription.ts
@@ -3,7 +3,6 @@ import { useCallback, useContext, useEffect, useRef } from 'react';
 import { pipe, subscribe } from 'wonka';
 import { Context } from '../context';
 import { CombinedError, noop } from '../utils';
-import { useDevtoolsContext } from './useDevtoolsContext';
 import { useRequest } from './useRequest';
 import { useImmediateState } from './useImmediateState';
 import { OperationContext } from '../types';
@@ -29,7 +28,6 @@ export const useSubscription = <T = any, R = T, V = object>(
   args: UseSubscriptionArgs<V>,
   handler?: SubscriptionHandler<T, R>
 ): UseSubscriptionResponse<R> => {
-  const devtoolsContext = useDevtoolsContext();
   const unsubscribe = useRef(noop);
   const client = useContext(Context);
 
@@ -48,10 +46,7 @@ export const useSubscription = <T = any, R = T, V = object>(
     unsubscribe.current();
 
     [unsubscribe.current] = pipe(
-      client.executeSubscription(request, {
-        ...devtoolsContext,
-        ...args.context,
-      }),
+      client.executeSubscription(request, args.context || {}),
       subscribe(({ data, error, extensions }) => {
         setState(s => ({
           fetching: true,
@@ -61,7 +56,7 @@ export const useSubscription = <T = any, R = T, V = object>(
         }));
       })
     );
-  }, [client, devtoolsContext, handler, request, setState, args.context]);
+  }, [client, handler, request, setState, args.context]);
 
   // Trigger subscription on query change
   // We don't use useImmediateEffect here as we have no way of
diff --git a/src/types.ts b/src/types.ts
index 2a8da684..fbb320bf 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -34,6 +34,7 @@ export interface OperationDebugMeta {
   source?: string;
   cacheOutcome?: CacheOutcome;
   networkLatency?: number;
+  startTime?: number;
 }
 
 /** Additional metadata passed to [exchange]{@link Exchange} functions. */
@@ -42,6 +43,7 @@ export interface OperationContext {
   fetchOptions?: RequestInit | (() => RequestInit);
   requestPolicy: RequestPolicy;
   url: string;
+  pollInterval?: number;
   meta?: OperationDebugMeta;
 }
 
diff --git a/src/utils/typenames.ts b/src/utils/typenames.ts
index d4979b5b..6fde1d11 100755
--- a/src/utils/typenames.ts
+++ b/src/utils/typenames.ts
@@ -2,7 +2,7 @@ import {
   DocumentNode,
   FieldNode,
   InlineFragmentNode,
-  OperationDefinitionNode,
+  Kind,
   visit,
 } from 'graphql';
 
@@ -35,9 +35,7 @@ const collectTypes = (obj: EntityLike | EntityLike[], types: string[] = []) => {
 export const collectTypesFromResponse = (response: object) =>
   collectTypes(response as EntityLike).filter((v, i, a) => a.indexOf(v) === i);
 
-const formatNode = (
-  n: FieldNode | InlineFragmentNode | OperationDefinitionNode
-) => {
+const formatNode = (n: FieldNode | InlineFragmentNode) => {
   if (n.selectionSet === undefined) {
     return false;
   }
@@ -57,9 +55,9 @@ const formatNode = (
       selections: [
         ...n.selectionSet.selections,
         {
-          kind: 'Field',
+          kind: Kind.FIELD,
           name: {
-            kind: 'Name',
+            kind: Kind.NAME,
             value: '__typename',
           },
         },
@@ -72,5 +70,4 @@ export const formatDocument = (astNode: DocumentNode) =>
   visit(astNode, {
     Field: formatNode,
     InlineFragment: formatNode,
-    OperationDefinition: formatNode,
   });


Test patch:
diff --git a/src/client.test.ts b/src/client.test.ts
index 7552c29f..6bc46e00 100755
--- a/src/client.test.ts
+++ b/src/client.test.ts
@@ -125,6 +125,21 @@ describe('executeQuery', () => {
 
     expect(receivedOps[0]).toHaveProperty('context.url', url);
   });
+
+  it('polls when pollInterval is specified', () => {
+    jest.useFakeTimers();
+    pipe(
+      client.executeQuery(query, { pollInterval: 10000 }),
+      subscribe(x => x)
+    );
+
+    expect(receivedOps.length).toEqual(1);
+    jest.runOnlyPendingTimers();
+    expect(receivedOps.length).toEqual(3);
+    expect(receivedOps[0].operationName).toEqual('query');
+    expect(receivedOps[1].operationName).toEqual('teardown');
+    expect(receivedOps[2].operationName).toEqual('query');
+  });
 });
 
 describe('executeMutation', () => {
diff --git a/src/exchanges/__snapshots__/fetch.test.ts.snap b/src/exchanges/__snapshots__/fetch.test.ts.snap
index f855e6f7..dbd02bd0 100644
--- a/src/exchanges/__snapshots__/fetch.test.ts.snap
+++ b/src/exchanges/__snapshots__/fetch.test.ts.snap
@@ -10,9 +10,6 @@ Object {
       "fetchOptions": Object {
         "method": "POST",
       },
-      "meta": Object {
-        "networkLatency": 100,
-      },
       "requestPolicy": "cache-first",
       "url": "http://localhost:3000/graphql",
     },
@@ -152,9 +149,6 @@ Object {
           },
         ],
       },
-      "meta": Object {
-        "networkLatency": 100,
-      },
       "requestPolicy": "cache-first",
       "url": "http://localhost:3000/graphql",
     },
@@ -296,9 +290,6 @@ Object {
           },
         ],
       },
-      "meta": Object {
-        "networkLatency": 100,
-      },
       "requestPolicy": "cache-first",
       "url": "http://localhost:3000/graphql",
     },
diff --git a/src/exchanges/fetch.test.ts b/src/exchanges/fetch.test.ts
index f6142c3e..162a34d9 100755
--- a/src/exchanges/fetch.test.ts
+++ b/src/exchanges/fetch.test.ts
@@ -71,21 +71,6 @@ describe('on success', () => {
     expect(data).toMatchSnapshot();
     expect(fetchOptions).toHaveBeenCalled();
   });
-
-  it('adds latency info to the context', async () => {
-    const data = await pipe(
-      fromValue({
-        ...queryOperation,
-        context: {
-          ...queryOperation.context,
-        },
-      }),
-      fetchExchange(exchangeArgs),
-      toPromise
-    );
-
-    expect(data.operation.context).toHaveProperty('meta.networkLatency', 100);
-  });
 });
 
 describe('on error', () => {
@@ -111,16 +96,6 @@ describe('on error', () => {
     expect(data).toMatchSnapshot();
   });
 
-  it('returns error data', async () => {
-    const data = await pipe(
-      fromValue(queryOperation),
-      fetchExchange(exchangeArgs),
-      toPromise
-    );
-
-    expect(data.operation.context).toHaveProperty('meta.networkLatency', 100);
-  });
-
   it('returns error data with status 400 and manual redirect mode', async () => {
     const fetchOptions = jest.fn().mockReturnValue({ redirect: 'manual' });
 
diff --git a/src/hooks/useDevtoolsContext.test.ts b/src/hooks/useDevtoolsContext.test.ts
deleted file mode 100644
index 6d2eebca..00000000
--- a/src/hooks/useDevtoolsContext.test.ts
+++ /dev/null
@@ -1,117 +0,0 @@
-import React, { Component } from 'react';
-import renderer from 'react-test-renderer';
-import { useDevtoolsContext } from './useDevtoolsContext';
-
-it('retrieves the component name for function components', () => {
-  let hookResult;
-
-  const TestFunComponent = () => {
-    hookResult = useDevtoolsContext();
-    return null;
-  };
-
-  renderer.create(React.createElement(TestFunComponent));
-
-  expect(hookResult).toEqual({
-    meta: {
-      source: 'TestFunComponent',
-    },
-  });
-});
-
-it('prefers displayNames', () => {
-  let hookResult;
-
-  const TestFunComponent = () => {
-    hookResult = useDevtoolsContext();
-    return null;
-  };
-
-  TestFunComponent.displayName = 'TestFun';
-
-  renderer.create(React.createElement(TestFunComponent));
-
-  expect(hookResult).toEqual({
-    meta: {
-      source: 'TestFun',
-    },
-  });
-});
-
-it('retrieves the component name for function components using Query', () => {
-  let hookResult;
-
-  // We're not using the actual query component here but one with the _same name_
-  const Query = () => {
-    hookResult = useDevtoolsContext();
-    return null;
-  };
-
-  const OuterFunComponent = () => {
-    return React.createElement(Query);
-  };
-
-  renderer.create(React.createElement(OuterFunComponent));
-
-  expect(hookResult).toEqual({
-    meta: {
-      source: 'OuterFunComponent',
-    },
-  });
-});
-
-it('retrieves the component name for class components using Query', () => {
-  let hookResult;
-
-  // We're not using the actual query component here but one with the _same name_
-  const Query = () => {
-    hookResult = useDevtoolsContext();
-    return null;
-  };
-
-  class OuterClassComponent extends Component {
-    render() {
-      return React.createElement(Query);
-    }
-  }
-
-  renderer.create(React.createElement(OuterClassComponent));
-
-  expect(hookResult).toEqual({
-    meta: {
-      source: 'OuterClassComponent',
-    },
-  });
-});
-
-it('looks at the parent component, not the parent fiber', () => {
-  let hookResult;
-
-  // A context consumer/provider has a different Fiber type
-  const TestContext = React.createContext('');
-
-  // We're not using the actual query component here but one with the _same name_
-  const Query = () => {
-    hookResult = useDevtoolsContext();
-    return null;
-  };
-
-  class OuterClassComponent extends Component {
-    render() {
-      // Basically put one element "in the middle" of OuterClassComponent and Query
-      return React.createElement(
-        TestContext.Provider,
-        { value: 'test' },
-        React.createElement(Query)
-      );
-    }
-  }
-
-  renderer.create(React.createElement(OuterClassComponent));
-
-  expect(hookResult).toEqual({
-    meta: {
-      source: 'OuterClassComponent',
-    },
-  });
-});
diff --git a/src/hooks/useMutation.test.tsx b/src/hooks/useMutation.test.tsx
index 235add9d..f6732d85 100644
--- a/src/hooks/useMutation.test.tsx
+++ b/src/hooks/useMutation.test.tsx
@@ -107,16 +107,6 @@ describe('on execute', () => {
     );
   });
 
-  it('calls executeMutation with source component info', () => {
-    renderer.create(<MutationUser {...props} />);
-    act(() => {
-      execute(vars);
-    });
-    expect(client.executeMutation.mock.calls[0][1]).toHaveProperty('meta', {
-      source: 'MutationUser',
-    });
-  });
-
   it('can adjust context in executeMutation', () => {
     renderer.create(<MutationUser {...props} />);
     act(() => {
diff --git a/src/hooks/useQuery.test.tsx b/src/hooks/useQuery.test.tsx
index cd03726b..2740be19 100644
--- a/src/hooks/useQuery.test.tsx
+++ b/src/hooks/useQuery.test.tsx
@@ -88,19 +88,6 @@ describe('on initial useEffect', () => {
       })
     );
   });
-
-  it('passes source component name to executeQuery', () => {
-    renderer.create(<QueryUser {...props} />);
-
-    expect(client.executeQuery).toBeCalledWith(
-      expect.any(Object),
-      expect.objectContaining({
-        meta: {
-          source: 'QueryUser',
-        },
-      })
-    );
-  });
 });
 
 describe('on subscription', () => {
diff --git a/src/hooks/useSubscription.test.tsx b/src/hooks/useSubscription.test.tsx
index 6d043069..2a1db21f 100644
--- a/src/hooks/useSubscription.test.tsx
+++ b/src/hooks/useSubscription.test.tsx
@@ -62,14 +62,6 @@ describe('on initial useEffect', () => {
       expect.any(Object)
     );
   });
-
-  it('passes source component info to executeSubscription', () => {
-    renderer.create(<SubscriptionUser q={query} />);
-    expect(client.executeSubscription).toBeCalledWith(
-      expect.any(Object),
-      expect.objectContaining({ meta: { source: 'SubscriptionUser' } })
-    );
-  });
 });
 
 it('should support setting context in useSubscription params', () => {
@@ -85,7 +77,6 @@ it('should support setting context in useSubscription params', () => {
     },
     {
       url: 'test',
-      meta: { source: 'SubscriptionUser' },
     }
   );
 });
diff --git a/src/utils/typenames.test.ts b/src/utils/typenames.test.ts
index aadf1403..48a10591 100755
--- a/src/utils/typenames.test.ts
+++ b/src/utils/typenames.test.ts
@@ -14,7 +14,6 @@ describe('formatTypeNames', () => {
           id
           __typename
         }
-        __typename
       }
       "
     `);
@@ -29,15 +28,15 @@ describe('formatTypeNames', () => {
       __typename
     }`)
     ).toMatchInlineSnapshot(`
-            "{
-              todos {
-                id
-                __typename
-              }
-              __typename
-            }
-            "
-        `);
+                  "{
+                    todos {
+                      id
+                      __typename
+                    }
+                    __typename
+                  }
+                  "
+            `);
   });
 });