Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into rfc/1005-operation-kind
Browse files Browse the repository at this point in the history
  • Loading branch information
kitten committed Oct 28, 2020
2 parents a673c32 + 677d669 commit 687bfa4
Show file tree
Hide file tree
Showing 26 changed files with 356 additions and 150 deletions.
1 change: 1 addition & 0 deletions .codesandbox/ci.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"exchanges/graphcache",
"exchanges/multipart-fetch",
"exchanges/persisted-fetch",
"exchanges/auth",
"exchanges/retry",
"exchanges/suspense",
"exchanges/execute"
Expand Down
75 changes: 42 additions & 33 deletions docs/comparison.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ All features are marked to indicate the following:
| Persisted Queries |`@urql/exchange-persisted-fetch` |`apollo-link-persisted-queries` ||
| Batched Queries | 🛑 |`apollo-link-batch-http` | 🟡 `react-relay-network-layer` |
| Live Queries | 🛑 | 🛑 ||
| Prefer `GET` method ||| 🟡 `react-relay-network-layer` |
| Defer & Stream Directives | 🛑 | 🛑 ||
| Switching to `GET` method ||| 🟡 `react-relay-network-layer` |
| File Uploads |`@urql/exchange-multipart-fetch` | 🟡 `apollo-upload-client` | 🛑 |
| Retrying Failed Queries |`@urql/exchange-retry` |`apollo-link-retry` |`DefaultNetworkLayer` |
| Easy Authentication Flows |`@urql/exchange-auth` | 🛑 (no docs for refresh-based authentication) | 🟡 `react-relay-network-layer` |
Expand All @@ -78,16 +79,18 @@ hoisting all necessary data requirements to a page-wide query.

### Framework Bindings

| | urql | Apollo | Relay |
| ----------------------------- | -------------------------------- | ------------------ | ----------------- |
| React Bindings ||||
| React Hooks Support ||| ✅ (experimental) |
| React Suspense (Experimental) | ✅ (experimental on client-side) | 🛑 ||
| Next.js Integration |`next-urql` | 🟡 | 🔶 |
| Preact Support || 🔶 | 🔶 |
| Svelte Bindings || 🟡 `svelte-apollo` | 🛑 |
| Vue Bindings | 🛑 (planned) | 🟡 `vue-apollo` | 🟡 `vue-relay` |
| Initial Data on mount ||||
| | urql | Apollo | Relay |
| ------------------------------ | -------------------------------- | ------------------- | ------------------ |
| React Bindings ||||
| React Concurrent Hooks Support || 🛑 | ✅ (experimental) |
| React Legacy Hooks Support ||| 🟡 `relay-hooks` |
| React Suspense (Experimental) | ✅ (experimental on client-side) | 🛑 ||
| Next.js Integration |`next-urql` | 🟡 | 🔶 |
| Preact Support || 🔶 | 🔶 |
| Svelte Bindings || 🟡 `svelte-apollo` | 🟡 `svelte-relay` |
| Vue Bindings | 🛑 (planned) | 🟡 `vue-apollo` | 🟡 `vue-relay` |
| Angular Bindings | 🛑 | 🟡 `apollo-angular` | 🟡 `relay-angular` |
| Initial Data on mount ||||

Interestingly all three libraries heavily support React as they were all started from the React
community outwards, but Apollo and Vue benefit from community bindings for different frameworks a
Expand All @@ -102,36 +105,42 @@ for instance.

### Caching and State

| | urql | Apollo | Relay |
| ------------------------------------------------------- | --------------------------------------------------------------------- | ------------------ | ---------------------------------------------- |
| Caching Strategy | Document Caching, Normalized Caching with `@urql/exchange-graphcache` | Normalized Caching | Normalized Caching (schema restrictions apply) |
| Added Bundle Size | +6.5kB (with Graphcache) | +0 (default) | +0 (default) |
| Automatic Garbage Collection || 🔶 ||
| Local State Management | 🛑 |||
| Pagination Support | 🔶 | 🔶 ||
| Optimistic Updates ||||
| Local Updates ||||
| Out-of-band Cache Updates | 🛑 (stays true to server data) |||
| Local Resolvers and Redirects ||| 🛑 (not needed) |
| Complex Resolvers (nested non-normalized return values) || 🛑 | 🛑 (not needed) |
| Commutativity Guarantees || 🛑 | 🛑 |
| Partial Results ||| 🛑 |
| Safe Partial Results (schema-based) || 🛑 | 🛑 |
| Offline Support || 🛑 | 🛑 |
| | urql | Apollo | Relay |
| ------------------------------------------------------- | --------------------------------------------------------------------- | ------------------------- | ---------------------------------------------- |
| Caching Strategy | Document Caching, Normalized Caching with `@urql/exchange-graphcache` | Normalized Caching | Normalized Caching (schema restrictions apply) |
| Added Bundle Size | +6.5kB (with Graphcache) | +0 (default) | +0 (default) |
| Automatic Garbage Collection || 🔶 ||
| Local State Management | 🛑 |||
| Pagination Support | 🔶 | 🔶 ||
| Optimistic Updates ||||
| Local Updates ||||
| Out-of-band Cache Updates | 🛑 (stays true to server data) |||
| Local Resolvers and Redirects ||| 🛑 (not needed) |
| Complex Resolvers (nested non-normalized return values) || 🛑 | 🛑 (not needed) |
| Commutativity Guarantees || 🛑 ||
| Partial Results ||| 🛑 |
| Safe Partial Results (schema-based) || 🛑 | 🛑 |
| Persistence Support ||`apollo-cache-persist` | 🟡 `@wora/relay-store` |
| Offline Support || 🛑 | 🟡 `@wora/relay-offline` |

`urql` is the only of the three clients that doesn't pick [normalized
caching](./graphcache/normalized-caching.md) as its default caching strategy. Typically this is seen
by users as easier and quicker to get started with.
by users as easier and quicker to get started with. All entries in this table for `urql` typically
refer to the optional `@urql/exchange-graphcache` package.

Once you need the same features that you'll find in Relay and Apollo, it's possible to migrate to
Graphcache. Graphcache is also slightly different from Apollo's cache and more opinionated as it
doesn't allow arbitrary cache updates to be made.

`urql` is also the only library that provides [Offline Support](./graphcache/offline.md) and
[Commutativity Guarantees](./graphcache/under-the-hood.md) out of the box as part of Graphcache's
feature set. There are a number of options for Apollo and Relay including writing your own logic for
offline caching, which can be particularly successful in Relay, but for `@urql/exchange-graphcache`
we chose to include it as a feature since it also strengthened other guarantees that the cache makes.
`urql` is also the only library that provides [Offline Support](./graphcache/offline.md) out of the
box as part of Graphcache's feature set. There are a number of options for Apollo and Relay including
writing your own logic for offline caching, which can be particularly successful in Relay, but for
`@urql/exchange-graphcache` we chose to include it as a feature since it also strengthened other
guarantees that the cache makes.

Relay does in fact have similar guarantees as [`urql`'s Commutativity Guarantees](./graphcache/under-the-hood.md)
which are more evident when applying list updates out of order under more complex network
conditions.

## About Bundle Size

Expand Down
2 changes: 1 addition & 1 deletion docs/graphcache/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ default.
- 🔁 [**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
to make less API requests, since data may already be in the cache.
to make fewer API requests, since data may already be in the cache.
- 💾 [**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,
implement pagination, or implement cache redirects.
Expand Down
6 changes: 6 additions & 0 deletions exchanges/auth/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## 0.1.1

### Patch Changes

- ⚠️ Fix an operation that triggers `willAuthError` with a truthy return value being sent off twice, by [@kitten](https://github.com/kitten) (See [#1075](https://github.com/FormidableLabs/urql/pull/1075))

## v0.1.0

**Initial Release**
2 changes: 1 addition & 1 deletion exchanges/auth/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@urql/exchange-auth",
"version": "0.1.0",
"version": "0.1.1",
"description": "An exchange for managing authentication and token refresh in urql",
"sideEffects": false,
"homepage": "https://formidable.com/open-source/urql/docs/",
Expand Down
2 changes: 2 additions & 0 deletions exchanges/auth/src/authExchange.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
fromValue,
filter,
onStart,
empty,
take,
makeSubject,
toPromise,
Expand Down Expand Up @@ -153,6 +154,7 @@ export function authExchange<T>({
willAuthError({ operation, authState })
) {
pendingPromise = refreshAuth(operation);
return empty;
} else if (!pendingPromise) {
return fromValue(addAuthAttemptToOperation(operation, false));
}
Expand Down
18 changes: 18 additions & 0 deletions exchanges/graphcache/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
# @urql/exchange-graphcache

## 3.1.7

### Patch Changes

- Enforce atomic optimistic updates so that optimistic layers are cleared before they're reapplied. This is important for instance when an optimistic update is performed while offline and then reapplied while online, which would previously repeat the optimistic update on top of its past data changes, by [@kitten](https://github.com/kitten) (See [#1080](https://github.com/FormidableLabs/urql/pull/1080))

## 3.1.6

### Patch Changes

- ⚠️ Fix optimistic updates not being allowed to be cumulative and apply on top of each other. Previously in [#866](https://github.com/FormidableLabs/urql/pull/866) we explicitly deemed this as unsafe which isn't correct anymore given that concrete, non-optimistic updates are now never applied on top of optimistic layers, by [@kitten](https://github.com/kitten) (See [#1074](https://github.com/FormidableLabs/urql/pull/1074))

## 3.1.5

### Patch Changes

- Changes some internals of how selections are iterated over and remove some private exports. This will have no effect or fixes on how Graphcache functions, but may improve some minor performance characteristics of large queries, by [@kitten](https://github.com/kitten) (See [#1060](https://github.com/FormidableLabs/urql/pull/1060))

## 3.1.4

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion exchanges/graphcache/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@urql/exchange-graphcache",
"version": "3.1.4",
"version": "3.1.7",
"description": "A normalized and configurable cache exchange for urql",
"sideEffects": false,
"homepage": "https://formidable.com/open-source/urql/docs/graphcache",
Expand Down
21 changes: 11 additions & 10 deletions exchanges/graphcache/src/ast/traversal.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import {
SelectionNode,
DefinitionNode,
DocumentNode,
FragmentDefinitionNode,
OperationDefinitionNode,
valueFromASTUntyped,
Kind,
Expand All @@ -13,9 +11,6 @@ import { getName } from './node';
import { invariant } from '../helpers/help';
import { Fragments, Variables } from '../types';

const isFragmentNode = (node: DefinitionNode): node is FragmentDefinitionNode =>
node.kind === Kind.FRAGMENT_DEFINITION;

/** Returns the main operation's definition */
export const getMainOperation = (
doc: DocumentNode
Expand All @@ -35,11 +30,17 @@ export const getMainOperation = (
};

/** Returns a mapping from fragment names to their selections */
export const getFragments = (doc: DocumentNode): Fragments =>
doc.definitions.filter(isFragmentNode).reduce((map: Fragments, node) => {
map[getName(node)] = node;
return map;
}, {});
export const getFragments = (doc: DocumentNode): Fragments => {
const fragments: Fragments = {};
for (let i = 0; i < doc.definitions.length; i++) {
const node = doc.definitions[i];
if (node.kind === Kind.FRAGMENT_DEFINITION) {
fragments[getName(node)] = node;
}
}

return fragments;
};

export const shouldInclude = (
node: SelectionNode,
Expand Down
4 changes: 2 additions & 2 deletions exchanges/graphcache/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export * from './types';
export { query, write, writeOptimistic } from './operations';
export { Store, noopDataState, reserveLayer } from './store';
export { query, write } from './operations';
export { Store } from './store';
export { cacheExchange } from './cacheExchange';
export { offlineExchange } from './offlineExchange';
Loading

0 comments on commit 687bfa4

Please sign in to comment.