+5
.gitignore
+5
.gitignore
···
17
17
# TODO: Figure out how to remove these:
18
18
tmp/
19
19
dist/
20
+
examples/yarn.lock
21
+
examples/pnpm-lock.yaml
22
+
examples/package-lock.json
20
23
examples/*/public
21
24
examples/*/yarn.lock
25
+
examples/*/pnpm-lock.yaml
26
+
examples/*/package-lock.json
22
27
examples/*/ios/
23
28
examples/*/android/
24
29
examples/*/.watchmanconfig
+7
-6
examples/with-apq/package.json
+7
-6
examples/with-apq/package.json
···
6
6
"start": "vite"
7
7
},
8
8
"dependencies": {
9
+
"@urql/core": "^3.2.2",
9
10
"@urql/exchange-persisted-fetch": "^1.3.0",
10
-
"graphql": "^15.5.0",
11
-
"react": "^17.0.2",
12
-
"react-dom": "^17.0.2",
13
-
"urql": "^2.0.2"
11
+
"graphql": "^16.6.0",
12
+
"react": "^18.2.0",
13
+
"react-dom": "^18.2.0",
14
+
"urql": "^3.0.4"
14
15
},
15
16
"devDependencies": {
16
-
"@vitejs/plugin-react-refresh": "^1.3.3",
17
-
"vite": "^2.2.4"
17
+
"@vitejs/plugin-react": "^3.1.0",
18
+
"vite": "^4.2.0"
18
19
}
19
20
}
+4
-4
examples/with-apq/src/App.jsx
+4
-4
examples/with-apq/src/App.jsx
···
1
1
import React from 'react';
2
-
import { createClient, Provider, fetchExchange } from 'urql';
3
-
import { persistedFetchExchange } from '@urql/exchange-persisted-fetch';
2
+
import { Client, Provider, fetchExchange } from 'urql';
3
+
import { persistedExchange } from '@urql/exchange-persisted';
4
4
5
5
import LocationsList from './LocationsList';
6
6
7
-
const client = createClient({
7
+
const client = new Client({
8
8
url: 'https://trygql.formidable.dev/graphql/apq-weather',
9
9
exchanges: [
10
-
persistedFetchExchange({
10
+
persistedExchange({
11
11
preferGetForPersistedQueries: true,
12
12
}),
13
13
fetchExchange,
+2
-7
examples/with-apq/src/index.jsx
+2
-7
examples/with-apq/src/index.jsx
···
1
1
import React from 'react';
2
-
import { render } from 'react-dom';
2
+
import { createRoot } from 'react-dom/client';
3
3
4
4
import App from './App';
5
5
6
-
render(
7
-
<React.StrictMode>
8
-
<App />
9
-
</React.StrictMode>,
10
-
document.getElementById('root')
11
-
);
6
+
createRoot(document.getElementById('root')).render(<App />);
+2
-2
examples/with-apq/vite.config.js
+2
-2
examples/with-apq/vite.config.js
+16
-9
examples/with-defer-stream-directives/package.json
+16
-9
examples/with-defer-stream-directives/package.json
···
8
8
"client": "vite",
9
9
"start": "run-p client server:yoga"
10
10
},
11
+
"pnpm": {
12
+
"peerDependencyRules": {
13
+
"allowedVersions": {
14
+
"graphql": "17"
15
+
}
16
+
}
17
+
},
11
18
"dependencies": {
12
-
"@apollo/server": "^4.4.1",
13
19
"@graphql-yoga/plugin-defer-stream": "^1.7.1",
14
-
"@urql/core": "^3.1.1",
15
-
"@urql/exchange-graphcache": "^5.0.9",
20
+
"@urql/core": "^3.2.2",
21
+
"@urql/exchange-graphcache": "^5.2.0",
16
22
"graphql": "17.0.0-alpha.2",
17
-
"graphql-yoga": "^3.7.1",
18
-
"react": "^17.0.2",
19
-
"react-dom": "^17.0.2",
20
-
"urql": "^3.0.3"
23
+
"react": "^18.2.0",
24
+
"react-dom": "^18.2.0",
25
+
"urql": "^3.0.4"
21
26
},
22
27
"devDependencies": {
23
-
"@vitejs/plugin-react-refresh": "^1.3.6",
28
+
"@apollo/server": "^4.4.1",
29
+
"@vitejs/plugin-react": "^3.1.0",
24
30
"graphql-helix": "^1.13.0",
31
+
"graphql-yoga": "^3.7.1",
25
32
"npm-run-all": "^4.1.5",
26
-
"vite": "^2.9.15"
33
+
"vite": "^4.2.0"
27
34
}
28
35
}
+3
-9
examples/with-defer-stream-directives/src/App.jsx
+3
-9
examples/with-defer-stream-directives/src/App.jsx
···
1
1
import React from 'react';
2
-
import {
3
-
createClient,
4
-
Provider,
5
-
dedupExchange,
6
-
debugExchange,
7
-
fetchExchange,
8
-
} from 'urql';
2
+
import { Client, Provider, fetchExchange } from 'urql';
9
3
10
4
import { cacheExchange } from '@urql/exchange-graphcache';
11
5
···
18
12
},
19
13
});
20
14
21
-
const client = createClient({
15
+
const client = new Client({
22
16
url: 'http://localhost:3004/graphql',
23
-
exchanges: [dedupExchange, cache, debugExchange, fetchExchange],
17
+
exchanges: [cache, fetchExchange],
24
18
});
25
19
26
20
function App() {
+2
-7
examples/with-defer-stream-directives/src/index.jsx
+2
-7
examples/with-defer-stream-directives/src/index.jsx
···
1
1
import React from 'react';
2
-
import { render } from 'react-dom';
2
+
import { createRoot } from 'react-dom/client';
3
3
4
4
import App from './App';
5
5
6
-
render(
7
-
<React.StrictMode>
8
-
<App />
9
-
</React.StrictMode>,
10
-
document.getElementById('root')
11
-
);
6
+
createRoot(document.getElementById('root')).render(<App />);
+2
-2
examples/with-defer-stream-directives/vite.config.js
+2
-2
examples/with-defer-stream-directives/vite.config.js
+8
-7
examples/with-graphcache-pagination/package.json
+8
-7
examples/with-graphcache-pagination/package.json
···
6
6
"start": "vite"
7
7
},
8
8
"dependencies": {
9
-
"@urql/exchange-graphcache": "^4.0.0",
10
-
"graphql": "^15.5.0",
11
-
"react": "^17.0.2",
12
-
"react-dom": "^17.0.2",
13
-
"urql": "^2.0.2"
9
+
"@urql/core": "^3.2.2",
10
+
"@urql/exchange-graphcache": "^5.2.0",
11
+
"graphql": "^16.6.0",
12
+
"react": "^18.2.0",
13
+
"react-dom": "^18.2.0",
14
+
"urql": "^3.0.4"
14
15
},
15
16
"devDependencies": {
16
-
"@vitejs/plugin-react-refresh": "^1.3.3",
17
-
"vite": "^2.2.4"
17
+
"@vitejs/plugin-react": "^3.1.0",
18
+
"vite": "^4.2.0"
18
19
}
19
20
}
+2
-3
examples/with-graphcache-pagination/src/App.jsx
+2
-3
examples/with-graphcache-pagination/src/App.jsx
···
1
1
import React from 'react';
2
-
import { createClient, Provider, dedupExchange, fetchExchange } from 'urql';
2
+
import { Client, Provider, fetchExchange } from 'urql';
3
3
import { cacheExchange } from '@urql/exchange-graphcache';
4
4
import { relayPagination } from '@urql/exchange-graphcache/extras';
5
5
6
6
import PaginatedNpmSearch from './PaginatedNpmSearch';
7
7
8
-
const client = createClient({
8
+
const client = new Client({
9
9
url: 'https://trygql.formidable.dev/graphql/relay-npm',
10
10
exchanges: [
11
-
dedupExchange,
12
11
cacheExchange({
13
12
resolvers: {
14
13
Query: {
+2
-7
examples/with-graphcache-pagination/src/index.jsx
+2
-7
examples/with-graphcache-pagination/src/index.jsx
···
1
1
import React from 'react';
2
-
import { render } from 'react-dom';
2
+
import { createRoot } from 'react-dom/client';
3
3
4
4
import App from './App';
5
5
6
-
render(
7
-
<React.StrictMode>
8
-
<App />
9
-
</React.StrictMode>,
10
-
document.getElementById('root')
11
-
);
6
+
createRoot(document.getElementById('root')).render(<App />);
+2
-2
examples/with-graphcache-pagination/vite.config.js
+2
-2
examples/with-graphcache-pagination/vite.config.js
+9
-8
examples/with-graphcache-updates/package.json
+9
-8
examples/with-graphcache-updates/package.json
···
6
6
"start": "vite"
7
7
},
8
8
"dependencies": {
9
-
"@urql/exchange-auth": "^0.1.2",
10
-
"@urql/exchange-graphcache": "^4.0.0",
11
-
"graphql": "^15.5.0",
12
-
"react": "^17.0.2",
13
-
"react-dom": "^17.0.2",
14
-
"urql": "^2.0.2"
9
+
"@urql/core": "^3.2.2",
10
+
"@urql/exchange-auth": "^2.0.0",
11
+
"@urql/exchange-graphcache": "^5.2.0",
12
+
"graphql": "^16.6.0",
13
+
"react": "^18.2.0",
14
+
"react-dom": "^18.2.0",
15
+
"urql": "^3.0.4"
15
16
},
16
17
"devDependencies": {
17
-
"@vitejs/plugin-react-refresh": "^1.3.3",
18
-
"vite": "^2.2.4"
18
+
"@vitejs/plugin-react": "^3.1.0",
19
+
"vite": "^4.2.0"
19
20
}
20
21
}
+46
-69
examples/with-graphcache-updates/src/client.js
+46
-69
examples/with-graphcache-updates/src/client.js
···
1
-
import { createClient, dedupExchange, fetchExchange, gql } from 'urql';
2
-
import { makeOperation } from '@urql/core';
1
+
import { Client, fetchExchange, gql } from 'urql';
3
2
import { authExchange } from '@urql/exchange-auth';
4
3
import { cacheExchange } from '@urql/exchange-graphcache';
5
4
···
40
39
},
41
40
});
42
41
43
-
const client = createClient({
44
-
url: 'https://trygql.formidable.dev/graphql/web-collections',
45
-
exchanges: [
46
-
dedupExchange,
47
-
cache,
48
-
authExchange({
49
-
getAuth: async ({ authState }) => {
50
-
if (!authState) {
51
-
const token = localStorage.getItem('authToken');
52
-
53
-
if (token) {
54
-
return { token };
55
-
}
42
+
const auth = authExchange(async utilities => {
43
+
let token = localStorage.getItem('authToken');
56
44
57
-
return null;
58
-
}
59
-
45
+
return {
46
+
addAuthToOperation(operation) {
47
+
if (!token) return operation;
48
+
return token
49
+
? utilities.appendHeaders(operation, {
50
+
Authorization: `Bearer ${token}`,
51
+
})
52
+
: operation;
53
+
},
54
+
didAuthError(error) {
55
+
return error.graphQLErrors.some(
56
+
e => e.extensions?.code === 'UNAUTHORIZED'
57
+
);
58
+
},
59
+
willAuthError(operation) {
60
+
if (!token) {
61
+
// Detect our login mutation and let this operation through:
62
+
return (
63
+
operation.kind !== 'mutation' ||
64
+
// Here we find any mutation definition with the "signin" field
65
+
!operation.query.definitions.some(definition => {
66
+
return (
67
+
definition.kind === 'OperationDefinition' &&
68
+
definition.selectionSet.selections.some(node => {
69
+
// The field name is just an example, since register may also be an exception
70
+
return node.kind === 'Field' && node.name.value === 'signin';
71
+
})
72
+
);
73
+
})
74
+
);
75
+
}
76
+
return false;
77
+
},
78
+
async refreshAuth() {
79
+
token = localStorage.getItem('authToken');
80
+
if (!token) {
60
81
// This is where auth has gone wrong and we need to clean up and redirect to a login page
61
82
localStorage.clear();
62
83
window.location.reload();
84
+
}
85
+
},
86
+
};
87
+
});
63
88
64
-
return null;
65
-
},
66
-
addAuthToOperation: ({ authState, operation }) => {
67
-
if (!authState || !authState.token) {
68
-
return operation;
69
-
}
70
-
71
-
const fetchOptions =
72
-
typeof operation.context.fetchOptions === 'function'
73
-
? operation.context.fetchOptions()
74
-
: operation.context.fetchOptions || {};
75
-
76
-
return makeOperation(operation.kind, operation, {
77
-
...operation.context,
78
-
fetchOptions: {
79
-
...fetchOptions,
80
-
headers: {
81
-
...fetchOptions.headers,
82
-
Authorization: `Bearer ${authState.token}`,
83
-
},
84
-
},
85
-
});
86
-
},
87
-
didAuthError: ({ error }) => {
88
-
return error.graphQLErrors.some(
89
-
e => e.extensions?.code === 'UNAUTHORIZED'
90
-
);
91
-
},
92
-
willAuthError: ({ operation, authState }) => {
93
-
if (!authState) {
94
-
// Detect our login mutation and let this operation through:
95
-
return (
96
-
operation.kind !== 'mutation' ||
97
-
// Here we find any mutation definition with the "signin" field
98
-
!operation.query.definitions.some(definition => {
99
-
return (
100
-
definition.kind === 'OperationDefinition' &&
101
-
definition.selectionSet.selections.some(node => {
102
-
// The field name is just an example, since register may also be an exception
103
-
return node.kind === 'Field' && node.name.value === 'signin';
104
-
})
105
-
);
106
-
})
107
-
);
108
-
}
109
-
110
-
return false;
111
-
},
112
-
}),
113
-
fetchExchange,
114
-
],
89
+
const client = new Client({
90
+
url: 'https://trygql.formidable.dev/graphql/web-collections',
91
+
exchanges: [cache, auth, fetchExchange],
115
92
});
116
93
117
94
export default client;
+2
-7
examples/with-graphcache-updates/src/index.jsx
+2
-7
examples/with-graphcache-updates/src/index.jsx
···
1
1
import React from 'react';
2
-
import { render } from 'react-dom';
2
+
import { createRoot } from 'react-dom/client';
3
3
4
4
import App from './App';
5
5
6
-
render(
7
-
<React.StrictMode>
8
-
<App />
9
-
</React.StrictMode>,
10
-
document.getElementById('root')
11
-
);
6
+
createRoot(document.getElementById('root')).render(<App />);
+2
-2
examples/with-graphcache-updates/vite.config.js
+2
-2
examples/with-graphcache-updates/vite.config.js
+7
-7
examples/with-multipart/package.json
+7
-7
examples/with-multipart/package.json
···
6
6
"start": "vite"
7
7
},
8
8
"dependencies": {
9
-
"@urql/exchange-multipart-fetch": "^0.1.11",
10
-
"graphql": "^15.5.0",
11
-
"react": "^17.0.2",
12
-
"react-dom": "^17.0.2",
13
-
"urql": "^2.0.2"
9
+
"@urql/core": "^3.2.2",
10
+
"graphql": "^16.6.0",
11
+
"react": "^18.2.0",
12
+
"react-dom": "^18.2.0",
13
+
"urql": "^3.0.4"
14
14
},
15
15
"devDependencies": {
16
-
"@vitejs/plugin-react-refresh": "^1.3.3",
17
-
"vite": "^2.2.4"
16
+
"@vitejs/plugin-react": "^3.1.0",
17
+
"vite": "^4.2.0"
18
18
}
19
19
}
+3
-4
examples/with-multipart/src/App.jsx
+3
-4
examples/with-multipart/src/App.jsx
···
1
1
import React from 'react';
2
-
import { createClient, Provider } from 'urql';
3
-
import { multipartFetchExchange } from '@urql/exchange-multipart-fetch';
2
+
import { Client, Provider, fetchExchange } from 'urql';
4
3
5
4
import FileUpload from './FileUpload';
6
5
7
-
const client = createClient({
6
+
const client = new Client({
8
7
url: 'https://trygql.formidable.dev/graphql/uploads-mock',
9
-
exchanges: [multipartFetchExchange],
8
+
exchanges: [fetchExchange],
10
9
});
11
10
12
11
function App() {
+2
-7
examples/with-multipart/src/index.jsx
+2
-7
examples/with-multipart/src/index.jsx
···
1
1
import React from 'react';
2
-
import { render } from 'react-dom';
2
+
import { createRoot } from 'react-dom/client';
3
3
4
4
import App from './App';
5
5
6
-
render(
7
-
<React.StrictMode>
8
-
<App />
9
-
</React.StrictMode>,
10
-
document.getElementById('root')
11
-
);
6
+
createRoot(document.getElementById('root')).render(<App />);
+2
-2
examples/with-multipart/vite.config.js
+2
-2
examples/with-multipart/vite.config.js
+7
-6
examples/with-next/package.json
+7
-6
examples/with-next/package.json
···
3
3
"version": "0.0.0",
4
4
"private": true,
5
5
"dependencies": {
6
-
"graphql": "^15.5.0",
7
-
"next": "10.1.2",
8
-
"next-urql": "^3.0.1",
9
-
"react": "^17.0.2",
10
-
"react-dom": "^17.0.2",
11
-
"urql": "^2.0.2"
6
+
"@urql/core": "^3.2.2",
7
+
"graphql": "^16.6.0",
8
+
"next": "13.2.4",
9
+
"next-urql": "^4.0.3",
10
+
"react": "^18.2.0",
11
+
"react-dom": "^18.2.0",
12
+
"urql": "^3.0.4"
12
13
},
13
14
"scripts": {
14
15
"dev": "next dev",
+3
-1
examples/with-next/pages/_app.js
+3
-1
examples/with-next/pages/_app.js
···
1
1
import { withUrqlClient } from 'next-urql';
2
+
import { cacheExchange, fetchExchange } from 'urql';
2
3
3
4
const App = ({ Component, pageProps }) => <Component {...pageProps} />;
4
5
5
6
export default withUrqlClient(
6
-
() => ({
7
+
ssrExchange => ({
7
8
url: 'https://trygql.formidable.dev/graphql/basic-pokedex',
9
+
exchanges: [cacheExchange, ssrExchange, fetchExchange],
8
10
}),
9
11
{ ssr: false }
10
12
)(App);
+3
-2
examples/with-next/pages/index.js
+3
-2
examples/with-next/pages/index.js
···
1
1
import { withUrqlClient } from 'next-urql';
2
-
import { useQuery, gql } from 'urql';
2
+
import { useQuery, cacheExchange, fetchExchange, gql } from 'urql';
3
3
4
4
const POKEMONS_QUERY = gql`
5
5
query {
···
26
26
}
27
27
28
28
export default withUrqlClient(
29
-
() => ({
29
+
ssrExchange => ({
30
30
url: 'https://trygql.formidable.dev/graphql/basic-pokedex',
31
+
exchanges: [cacheExchange, ssrExchange, fetchExchange],
31
32
}),
32
33
{ ssr: true }
33
34
)(Index);
+3
-9
examples/with-next/pages/server.js
+3
-9
examples/with-next/pages/server.js
···
1
1
import { initUrqlClient } from 'next-urql';
2
-
import {
3
-
ssrExchange,
4
-
dedupExchange,
5
-
cacheExchange,
6
-
fetchExchange,
7
-
useQuery,
8
-
gql,
9
-
} from 'urql';
2
+
3
+
import { ssrExchange, cacheExchange, fetchExchange, useQuery, gql } from 'urql';
10
4
11
5
const POKEMONS_QUERY = gql`
12
6
query {
···
37
31
const client = initUrqlClient(
38
32
{
39
33
url: 'https://trygql.formidable.dev/graphql/basic-pokedex',
40
-
exchanges: [dedupExchange, cacheExchange, ssrCache, fetchExchange],
34
+
exchanges: [cacheExchange, ssrCache, fetchExchange],
41
35
},
42
36
false
43
37
);
+3
-9
examples/with-next/pages/static.js
+3
-9
examples/with-next/pages/static.js
···
1
1
import { initUrqlClient } from 'next-urql';
2
-
import {
3
-
ssrExchange,
4
-
dedupExchange,
5
-
cacheExchange,
6
-
fetchExchange,
7
-
useQuery,
8
-
gql,
9
-
} from 'urql';
2
+
3
+
import { ssrExchange, cacheExchange, fetchExchange, useQuery, gql } from 'urql';
10
4
11
5
const POKEMONS_QUERY = gql`
12
6
query {
···
37
31
const client = initUrqlClient(
38
32
{
39
33
url: 'https://trygql.formidable.dev/graphql/basic-pokedex',
40
-
exchanges: [dedupExchange, cacheExchange, ssrCache, fetchExchange],
34
+
exchanges: [cacheExchange, ssrCache, fetchExchange],
41
35
},
42
36
false
43
37
);
+7
-6
examples/with-pagination/package.json
+7
-6
examples/with-pagination/package.json
···
6
6
"start": "vite"
7
7
},
8
8
"dependencies": {
9
-
"graphql": "^15.5.0",
10
-
"react": "^17.0.2",
11
-
"react-dom": "^17.0.2",
12
-
"urql": "^2.0.2"
9
+
"@urql/core": "^3.2.2",
10
+
"graphql": "^16.6.0",
11
+
"react": "^18.2.0",
12
+
"react-dom": "^18.2.0",
13
+
"urql": "^3.0.4"
13
14
},
14
15
"devDependencies": {
15
-
"@vitejs/plugin-react-refresh": "^1.3.3",
16
-
"vite": "^2.2.4"
16
+
"@vitejs/plugin-react": "^3.1.0",
17
+
"vite": "^4.2.0"
17
18
}
18
19
}
+3
-2
examples/with-pagination/src/App.jsx
+3
-2
examples/with-pagination/src/App.jsx
···
1
1
import React from 'react';
2
-
import { createClient, Provider } from 'urql';
2
+
import { Client, Provider, cacheExchange, fetchExchange } from 'urql';
3
3
4
4
import PaginatedNpmSearch from './PaginatedNpmSearch';
5
5
6
-
const client = createClient({
6
+
const client = new Client({
7
7
url: 'https://trygql.formidable.dev/graphql/relay-npm',
8
+
exchanges: [cacheExchange, fetchExchange],
8
9
});
9
10
10
11
function App() {
+2
-7
examples/with-pagination/src/index.jsx
+2
-7
examples/with-pagination/src/index.jsx
···
1
1
import React from 'react';
2
-
import { render } from 'react-dom';
2
+
import { createRoot } from 'react-dom/client';
3
3
4
4
import App from './App';
5
5
6
-
render(
7
-
<React.StrictMode>
8
-
<App />
9
-
</React.StrictMode>,
10
-
document.getElementById('root')
11
-
);
6
+
createRoot(document.getElementById('root')).render(<App />);
+2
-2
examples/with-pagination/vite.config.js
+2
-2
examples/with-pagination/vite.config.js
+3
-2
examples/with-react-native/App.js
+3
-2
examples/with-react-native/App.js
···
1
1
import React from 'react';
2
-
import { createClient, Provider } from 'urql';
2
+
import { Client, Provider, cacheExchange, fetchExchange } from 'urql';
3
3
4
4
import PokemonList from './src/screens/PokemonList';
5
5
6
-
const client = createClient({
6
+
const client = new Client({
7
7
url: 'https://trygql.formidable.dev/graphql/basic-pokedex',
8
+
exchanges: [cacheExchange, fetchExchange],
8
9
});
9
10
10
11
const App = () => {
+7
-6
examples/with-react-native/package.json
+7
-6
examples/with-react-native/package.json
···
8
8
"start": "react-native start"
9
9
},
10
10
"dependencies": {
11
-
"graphql": "^15.5.0",
12
-
"react": "17.0.1",
13
-
"react-native": "0.64.0",
14
-
"urql": "^2.0.2"
11
+
"@urql/core": "^3.2.2",
12
+
"graphql": "^16.6.0",
13
+
"react": "18.2.0",
14
+
"react-native": "0.71.4",
15
+
"urql": "^3.0.4"
15
16
},
16
17
"devDependencies": {
17
18
"@babel/core": "^7.12.9",
19
+
"@babel/preset-env": "^7.20.2",
18
20
"@babel/runtime": "^7.12.5",
19
-
"babel-jest": "^26.6.3",
20
-
"metro-react-native-babel-preset": "^0.64.0"
21
+
"metro-react-native-babel-preset": "^0.76.0"
21
22
}
22
23
}
+7
-6
examples/with-react/package.json
+7
-6
examples/with-react/package.json
···
6
6
"start": "vite"
7
7
},
8
8
"dependencies": {
9
-
"graphql": "^15.5.0",
10
-
"react": "^17.0.2",
11
-
"react-dom": "^17.0.2",
12
-
"urql": "^2.0.2"
9
+
"@urql/core": "^3.2.2",
10
+
"graphql": "^16.6.0",
11
+
"react": "^18.2.0",
12
+
"react-dom": "^18.2.0",
13
+
"urql": "^3.0.4"
13
14
},
14
15
"devDependencies": {
15
-
"@vitejs/plugin-react-refresh": "^1.3.3",
16
-
"vite": "^2.2.4"
16
+
"@vitejs/plugin-react": "^3.1.0",
17
+
"vite": "^4.2.0"
17
18
}
18
19
}
+3
-2
examples/with-react/src/App.jsx
+3
-2
examples/with-react/src/App.jsx
···
1
1
import React from 'react';
2
-
import { createClient, Provider } from 'urql';
2
+
import { Client, Provider, cacheExchange, fetchExchange } from 'urql';
3
3
4
4
import PokemonList from './PokemonList';
5
5
6
-
const client = createClient({
6
+
const client = new Client({
7
7
url: 'https://trygql.formidable.dev/graphql/basic-pokedex',
8
+
exchanges: [cacheExchange, fetchExchange],
8
9
});
9
10
10
11
function App() {
+2
-7
examples/with-react/src/index.jsx
+2
-7
examples/with-react/src/index.jsx
···
1
1
import React from 'react';
2
-
import { render } from 'react-dom';
2
+
import { createRoot } from 'react-dom/client';
3
3
4
4
import App from './App';
5
5
6
-
render(
7
-
<React.StrictMode>
8
-
<App />
9
-
</React.StrictMode>,
10
-
document.getElementById('root')
11
-
);
6
+
createRoot(document.getElementById('root')).render(<App />);
+2
-2
examples/with-react/vite.config.js
+2
-2
examples/with-react/vite.config.js
+8
-7
examples/with-refresh-auth/package.json
+8
-7
examples/with-refresh-auth/package.json
···
6
6
"start": "vite"
7
7
},
8
8
"dependencies": {
9
-
"@urql/exchange-auth": "^0.1.2",
10
-
"graphql": "^15.5.0",
11
-
"react": "^17.0.2",
12
-
"react-dom": "^17.0.2",
13
-
"urql": "^2.0.2"
9
+
"@urql/core": "^3.2.2",
10
+
"@urql/exchange-auth": "^2.0.0",
11
+
"graphql": "^16.6.0",
12
+
"react": "^18.2.0",
13
+
"react-dom": "^18.2.0",
14
+
"urql": "^3.0.4"
14
15
},
15
16
"devDependencies": {
16
-
"@vitejs/plugin-react-refresh": "^1.3.3",
17
-
"vite": "^2.2.4"
17
+
"@vitejs/plugin-react": "^3.1.0",
18
+
"vite": "^4.2.0"
18
19
}
19
20
}
+57
-87
examples/with-refresh-auth/src/client.js
+57
-87
examples/with-refresh-auth/src/client.js
···
1
-
import {
2
-
makeOperation,
3
-
createClient,
4
-
dedupExchange,
5
-
fetchExchange,
6
-
cacheExchange,
7
-
gql,
8
-
} from 'urql';
9
-
1
+
import { Client, fetchExchange, cacheExchange, gql } from 'urql';
10
2
import { authExchange } from '@urql/exchange-auth';
11
3
12
4
import {
···
25
17
}
26
18
`;
27
19
28
-
const client = createClient({
29
-
url: 'https://trygql.formidable.dev/graphql/web-collections',
30
-
exchanges: [
31
-
dedupExchange,
32
-
cacheExchange,
33
-
authExchange({
34
-
async getAuth({ authState, mutate }) {
35
-
if (!authState) {
36
-
const token = getToken();
37
-
const refreshToken = getRefreshToken();
38
-
39
-
if (token && refreshToken) {
40
-
return { token, refreshToken };
41
-
}
20
+
const auth = authExchange(async utilities => {
21
+
let token = getToken();
22
+
let refreshToken = getRefreshToken();
42
23
43
-
return null;
44
-
}
24
+
return {
25
+
addAuthToOperation(operation) {
26
+
return token
27
+
? utilities.appendHeaders(operation, {
28
+
Authorization: `Bearer ${token}`,
29
+
})
30
+
: operation;
31
+
},
32
+
didAuthError(error) {
33
+
return error.graphQLErrors.some(
34
+
e => e.extensions?.code === 'UNAUTHORIZED'
35
+
);
36
+
},
37
+
willAuthError(operation) {
38
+
// Sync tokens on every operation
39
+
token = getToken();
40
+
refreshToken = getRefreshToken();
45
41
46
-
const result = await mutate(REFRESH_TOKEN_MUTATION, {
47
-
refreshToken: authState.refreshToken,
42
+
if (!token) {
43
+
// Detect our login mutation and let this operation through:
44
+
return (
45
+
operation.kind !== 'mutation' ||
46
+
// Here we find any mutation definition with the "signin" field
47
+
!operation.query.definitions.some(definition => {
48
+
return (
49
+
definition.kind === 'OperationDefinition' &&
50
+
definition.selectionSet.selections.some(node => {
51
+
// The field name is just an example, since register may also be an exception
52
+
return node.kind === 'Field' && node.name.value === 'signin';
53
+
})
54
+
);
55
+
})
56
+
);
57
+
}
58
+
return false;
59
+
},
60
+
async refreshAuth() {
61
+
if (refreshToken) {
62
+
const result = await utilities.mutate(REFRESH_TOKEN_MUTATION, {
63
+
refreshToken,
48
64
});
49
65
50
66
if (result.data?.refreshCredentials) {
51
-
saveAuthData(result.data.refreshCredentials);
52
-
53
-
return result.data.refreshCredentials;
54
-
}
55
-
56
-
// This is where auth has gone wrong and we need to clean up and redirect to a login page
57
-
clearStorage();
58
-
window.location.reload();
59
-
60
-
return null;
61
-
},
62
-
63
-
addAuthToOperation({ authState, operation }) {
64
-
if (!authState || !authState.token) {
65
-
return operation;
67
+
token = result.data.refreshCredentials.token;
68
+
refreshToken = result.data.refreshCredentials.refreshToken;
69
+
saveAuthData({ token, refreshToken });
70
+
return;
66
71
}
67
-
68
-
const fetchOptions =
69
-
typeof operation.context.fetchOptions === 'function'
70
-
? operation.context.fetchOptions()
71
-
: operation.context.fetchOptions || {};
72
-
73
-
return makeOperation(operation.kind, operation, {
74
-
...operation.context,
75
-
fetchOptions: {
76
-
...fetchOptions,
77
-
headers: {
78
-
...fetchOptions.headers,
79
-
Authorization: `Bearer ${authState.token}`,
80
-
},
81
-
},
82
-
});
83
-
},
84
-
85
-
didAuthError({ error }) {
86
-
return error.graphQLErrors.some(
87
-
e => e.extensions?.code === 'UNAUTHORIZED'
88
-
);
89
-
},
72
+
}
90
73
91
-
willAuthError({ operation, authState }) {
92
-
if (!authState) {
93
-
// Detect our login mutation and let this operation through:
94
-
return (
95
-
operation.kind !== 'mutation' ||
96
-
// Here we find any mutation definition with the "signin" field
97
-
!operation.query.definitions.some(definition => {
98
-
return (
99
-
definition.kind === 'OperationDefinition' &&
100
-
definition.selectionSet.selections.some(node => {
101
-
// The field name is just an example, since register may also be an exception
102
-
return node.kind === 'Field' && node.name.value === 'signin';
103
-
})
104
-
);
105
-
})
106
-
);
107
-
}
74
+
// This is where auth has gone wrong and we need to clean up and redirect to a login page
75
+
clearStorage();
76
+
window.location.reload();
77
+
},
78
+
};
79
+
});
108
80
109
-
return false;
110
-
},
111
-
}),
112
-
fetchExchange,
113
-
],
81
+
const client = new Client({
82
+
url: 'https://trygql.formidable.dev/graphql/web-collections',
83
+
exchanges: [cacheExchange, auth, fetchExchange],
114
84
});
115
85
116
86
export default client;
+2
-7
examples/with-refresh-auth/src/index.jsx
+2
-7
examples/with-refresh-auth/src/index.jsx
···
1
1
import React from 'react';
2
-
import { render } from 'react-dom';
2
+
import { createRoot } from 'react-dom/client';
3
3
4
4
import App from './App';
5
5
6
-
render(
7
-
<React.StrictMode>
8
-
<App />
9
-
</React.StrictMode>,
10
-
document.getElementById('root')
11
-
);
6
+
createRoot(document.getElementById('root')).render(<App />);
+2
-2
examples/with-refresh-auth/vite.config.js
+2
-2
examples/with-refresh-auth/vite.config.js
+8
-7
examples/with-retry/package.json
+8
-7
examples/with-retry/package.json
···
6
6
"start": "vite"
7
7
},
8
8
"dependencies": {
9
-
"@urql/exchange-retry": "^0.2.0",
10
-
"graphql": "^15.5.0",
11
-
"react": "^17.0.2",
12
-
"react-dom": "^17.0.2",
13
-
"urql": "^2.0.2"
9
+
"@urql/core": "^3.2.2",
10
+
"@urql/exchange-retry": "^1.0.0",
11
+
"graphql": "^16.6.0",
12
+
"react": "^18.2.0",
13
+
"react-dom": "^18.2.0",
14
+
"urql": "^3.0.4"
14
15
},
15
16
"devDependencies": {
16
-
"@vitejs/plugin-react-refresh": "^1.3.3",
17
-
"vite": "^2.2.4"
17
+
"@vitejs/plugin-react": "^3.1.0",
18
+
"vite": "^4.2.0"
18
19
}
19
20
}
+4
-3
examples/with-retry/src/App.jsx
+4
-3
examples/with-retry/src/App.jsx
···
1
1
import React from 'react';
2
-
import { createClient, fetchExchange, Provider } from 'urql';
2
+
import { Client, fetchExchange, Provider } from 'urql';
3
3
import { retryExchange } from '@urql/exchange-retry';
4
4
5
5
import Color from './Color';
6
6
7
-
const client = createClient({
7
+
const client = new Client({
8
8
url: 'https://trygql.formidable.dev/graphql/intermittent-colors',
9
9
exchanges: [
10
10
retryExchange({
11
-
maxNumberAttempts: 5,
11
+
maxNumberAttempts: 10,
12
+
maxDelayMs: 500,
12
13
retryIf: error => {
13
14
// NOTE: With this deemo schema we have a specific random error to look out for:
14
15
return (
+2
-2
examples/with-retry/src/Color.jsx
+2
-2
examples/with-retry/src/Color.jsx
+2
-7
examples/with-retry/src/index.jsx
+2
-7
examples/with-retry/src/index.jsx
···
1
1
import React from 'react';
2
-
import { render } from 'react-dom';
2
+
import { createRoot } from 'react-dom/client';
3
3
4
4
import App from './App';
5
5
6
-
render(
7
-
<React.StrictMode>
8
-
<App />
9
-
</React.StrictMode>,
10
-
document.getElementById('root')
11
-
);
6
+
createRoot(document.getElementById('root')).render(<App />);
+2
-2
examples/with-retry/vite.config.js
+2
-2
examples/with-retry/vite.config.js
+8
-6
examples/with-svelte/package.json
+8
-6
examples/with-svelte/package.json
···
7
7
"build": "vite build",
8
8
"serve": "vite preview"
9
9
},
10
-
"devDependencies": {
11
-
"@sveltejs/vite-plugin-svelte": "^1.0.0-next.44",
12
-
"vite": "^2.2.4"
13
-
},
14
10
"dependencies": {
15
-
"@urql/svelte": "^2.0.0",
16
-
"svelte": "^3.48.0"
11
+
"@urql/core": "^3.2.2",
12
+
"@urql/svelte": "^3.0.4",
13
+
"graphql": "^16.6.0",
14
+
"svelte": "^3.57.0"
15
+
},
16
+
"devDependencies": {
17
+
"@sveltejs/vite-plugin-svelte": "^2.0.3",
18
+
"vite": "^4.2.0"
17
19
}
18
20
}
+4
-3
examples/with-svelte/src/App.svelte
+4
-3
examples/with-svelte/src/App.svelte
···
1
1
<script>
2
-
import { setContextClient, createClient } from "@urql/svelte";
2
+
import { setContextClient, Client, cacheExchange, fetchExchange } from "@urql/svelte";
3
3
import PokemonList from "./PokemonList.svelte";
4
4
5
-
setContextClient(createClient({
6
-
url: "https://trygql.formidable.dev/graphql/basic-pokedex"
5
+
setContextClient(new Client({
6
+
url: "https://trygql.formidable.dev/graphql/basic-pokedex",
7
+
exchanges: [cacheExchange, fetchExchange],
7
8
}));
8
9
</script>
9
10
+6
-5
examples/with-vue3/package.json
+6
-5
examples/with-vue3/package.json
···
8
8
"serve": "vite preview"
9
9
},
10
10
"dependencies": {
11
-
"@urql/vue": "0.3.0",
12
-
"vue": "^3.0.11"
11
+
"@urql/core": "^3.2.2",
12
+
"@urql/vue": "^1.0.5",
13
+
"graphql": "^16.6.0",
14
+
"vue": "^3.2.47"
13
15
},
14
16
"devDependencies": {
15
-
"@vitejs/plugin-vue": "^1.2.2",
16
-
"@vue/compiler-sfc": "^3.0.11",
17
-
"vite": "^2.2.4"
17
+
"@vitejs/plugin-vue": "^4.1.0",
18
+
"vite": "^4.2.0"
18
19
}
19
20
}
+2
-1
examples/with-vue3/src/App.vue
+2
-1
examples/with-vue3/src/App.vue
···
10
10
</template>
11
11
12
12
<script>
13
-
import { provideClient } from '@urql/vue';
13
+
import { provideClient, cacheExchange, fetchExchange } from '@urql/vue';
14
14
import PokemonList from './PokemonList.vue'
15
15
16
16
export default {
···
18
18
setup() {
19
19
provideClient({
20
20
url: 'https://trygql.formidable.dev/graphql/basic-pokedex',
21
+
exchanges: [cacheExchange, fetchExchange],
21
22
});
22
23
},
23
24
components: {
+1
-1
package.json
+1
-1
package.json
···
7
7
"build": "node ./scripts/actions/build-all.mjs",
8
8
"postinstall": "node ./scripts/prepare/postinstall.js",
9
9
"pack": "node ./scripts/actions/pack-all.mjs",
10
-
"changeset:version": "changeset version && pnpm install --lockfile-only",
10
+
"changeset:version": "node ./scripts/changesets/version.mjs",
11
11
"changeset:publish": "changeset publish"
12
12
},
13
13
"eslintConfig": {
+26
scripts/actions/lib/packages.mjs
+26
scripts/actions/lib/packages.mjs
···
1
1
import * as path from 'path';
2
+
import * as fs from 'fs/promises';
2
3
import glob from 'glob';
3
4
4
5
import { workspaceRoot, workspaces, require } from './constants.mjs';
5
6
6
7
const getPackageManifest = (cwd) =>
7
8
require(path.resolve(cwd, 'package.json'));
9
+
10
+
const updatePackageManifest = async (cwd, manifest) => {
11
+
const sortDependencies = (dependencies) => {
12
+
if (dependencies == null)
13
+
return undefined;
14
+
return Object.keys(dependencies).sort().reduce((acc, key) => {
15
+
acc[key] = dependencies[key];
16
+
return acc;
17
+
}, {});
18
+
};
19
+
20
+
try {
21
+
if (!!getPackageManifest(cwd)) {
22
+
manifest.dependencies = sortDependencies(manifest.dependencies);
23
+
manifest.devDependencies = sortDependencies(manifest.devDependencies);
24
+
await fs.writeFile(
25
+
path.resolve(cwd, 'package.json'),
26
+
JSON.stringify(manifest, null, 2) + '\n',
27
+
);
28
+
}
29
+
} catch (_error) {
30
+
throw new Error('package.json does not exist in: ' + cwd);
31
+
}
32
+
};
8
33
9
34
const getPackageArtifact = (cwd) => {
10
35
const pkg = getPackageManifest(cwd);
···
48
73
49
74
export {
50
75
getPackageManifest,
76
+
updatePackageManifest,
51
77
getPackageArtifact,
52
78
listPackages,
53
79
listArtifacts,
+62
scripts/changesets/version.mjs
+62
scripts/changesets/version.mjs
···
1
+
#!/usr/bin/env node
2
+
3
+
import glob from 'glob';
4
+
import { execa } from 'execa';
5
+
6
+
import {
7
+
getPackageManifest,
8
+
updatePackageManifest,
9
+
listPackages
10
+
} from '../actions/lib/packages.mjs';
11
+
12
+
const versionRe = /^\d+\.\d+\.\d+/i;
13
+
const execaOpts = { stdio: 'inherit' };
14
+
15
+
await execa('changeset', ['changeset', 'version'], execaOpts);
16
+
await execa('pnpm', ['install', '--lockfile-only'], execaOpts);
17
+
18
+
const packages = (await listPackages()).reduce((map, dir) => {
19
+
const manifest = getPackageManifest(dir);
20
+
const versionMatch = manifest.version.match(versionRe);
21
+
if (versionMatch) {
22
+
const { name } = manifest;
23
+
const version = `^${versionMatch[0]}`;
24
+
map[name] = version;
25
+
}
26
+
return map;
27
+
}, {});
28
+
29
+
const examples = (await glob('./examples/*/')).filter(x => !/node_modules$/.test(x));
30
+
console.log(`Scope: updating ${examples.length} examples`)
31
+
for (const example of examples) {
32
+
let hadMatch = false;
33
+
34
+
const manifest = getPackageManifest(example);
35
+
36
+
if (manifest.dependencies) {
37
+
for (const name in manifest.dependencies) {
38
+
hadMatch = hadMatch || !!packages[name];
39
+
if (packages[name] && packages[name] !== manifest.dependencies)
40
+
manifest.dependencies[name] = packages[name];
41
+
}
42
+
}
43
+
44
+
if (manifest.devDependencies) {
45
+
for (const name in manifest.devDependencies) {
46
+
hadMatch = hadMatch || !!packages[name];
47
+
if (packages[name] && packages[name] !== manifest.devDependencies)
48
+
manifest.devDependencies[name] = packages[name];
49
+
}
50
+
}
51
+
52
+
if (
53
+
hadMatch &&
54
+
!(manifest.devDependencies || {})['@urql/core'] &&
55
+
!(manifest.dependencies || {})['@urql/core']
56
+
) {
57
+
(manifest.dependencies || manifest.devDependencies || {})['@urql/core']
58
+
= packages['@urql/core'];
59
+
}
60
+
61
+
await updatePackageManifest(example, manifest);
62
+
}