Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge React Apollo hooks into Apollo Client #5357

Merged
merged 29 commits into from
Sep 24, 2019
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
2c03a0f
Remove specific test matching
hwillson Sep 16, 2019
eca59fe
Dependency updates (peer/dep/devDep) in preparation of RA merge
hwillson Sep 16, 2019
d0eca93
Modernize `OperationVariables` using `Record`
hwillson Sep 16, 2019
c5d872b
TS config changes in preparation of React Apollo being merged in
hwillson Sep 16, 2019
191065c
Bring in React Apollo source
hwillson Sep 16, 2019
d6ef803
Re-export React functionality
hwillson Sep 16, 2019
0f962e0
Typing changes to clear implicit any type errors
hwillson Sep 16, 2019
2e2cb07
Add new global dep exemptions for rollup bundling
hwillson Sep 16, 2019
2418a46
Bundlesize increase to accommodate React code
hwillson Sep 16, 2019
5a102b2
Update all React tests to use async instead of done callbacks
hwillson Sep 17, 2019
6ebacef
Create a new testing bundle
hwillson Sep 19, 2019
a241e09
Remove duplicated `MutationFetchResult`
hwillson Sep 19, 2019
dcf1602
Revert "Create a new testing bundle"
hwillson Sep 21, 2019
0f96dff
Stop building UMD bundles
hwillson Sep 21, 2019
ceedde9
Rollup bundling changes
hwillson Sep 21, 2019
4ecd8e1
Be explicit about root named React exports
hwillson Sep 21, 2019
87c410b
Doc updates to reflect new Apollo Client React API
hwillson Sep 23, 2019
08a2b1e
Merge branch 'release-3.0' into hello-react-apollo
hwillson Sep 23, 2019
68195a9
Pin optimism to 0.11.1
hwillson Sep 23, 2019
c3283dc
Fix TS source links; Exclude API from link checker
hwillson Sep 23, 2019
378bef0
Update all docs deps
hwillson Sep 23, 2019
a36780d
Update fetchOptions to point to new location
hwillson Sep 23, 2019
e6e268c
Revert "Pin optimism to 0.11.1"
benjamn Sep 23, 2019
7ee82b5
`react-dom` no longer needs to be a peer dep
hwillson Sep 23, 2019
b6ab68d
Remove unnecessary `await`s in tests
hwillson Sep 23, 2019
f973610
.npmignore is no longer necessary
hwillson Sep 24, 2019
ef6db11
Change compiled source location from "lib" to "dist"
hwillson Sep 24, 2019
4c7af4e
Adjust publish process to use "dist" as the project root
hwillson Sep 24, 2019
d7db78e
Copy LICENSE into dist during predeploy
hwillson Sep 24, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion config/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ module.exports = {
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'json'],
testURL: 'http://localhost',
testMatch: ['<rootDir>/src/**/__tests__/**/*.ts'],
testPathIgnorePatterns: [
'/node_modules/',
'/lib/'
Expand Down
2 changes: 2 additions & 0 deletions config/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ const defaultGlobals = {
'graphql/language/visitor': 'visitor',
'fast-json-stable-stringify': 'stringify',
'@wry/equality': 'wryEquality',
graphql: 'graphql',
react: 'React'
};

function rollup({
Expand Down
89 changes: 89 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 7 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@
"maxSize": "16.9 kB"
}
],
"peerDependencies": {
"@types/react": "^16.8.0",
"graphql": "^14.5.4",
"react": "^16.8.0",
"react-dom": "^16.8.0"
},
"dependencies": {
"@types/zen-observable": "^0.8.0",
"@wry/equality": "^0.1.9",
Expand All @@ -59,13 +65,11 @@
"tslib": "^1.10.0",
"zen-observable": "^0.8.14"
},
"peerDependencies": {
"graphql": "^14.5.4"
},
"devDependencies": {
"@babel/core": "7.6.0",
"@babel/plugin-transform-modules-commonjs": "7.6.0",
"@babel/plugin-transform-modules-umd": "7.2.0",
"@testing-library/react": "^9.1.4",
"@types/fast-json-stable-stringify": "^2.0.0",
"@types/isomorphic-fetch": "0.0.35",
"@types/jest": "24.0.18",
Expand Down
2 changes: 1 addition & 1 deletion src/core/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export type QueryListener = (
forceResolvers?: boolean,
) => void;

export type OperationVariables = { [key: string]: any };
export type OperationVariables = Record<string, any>;

export type PureQueryOptions = {
query: DocumentNode;
Expand Down
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,5 @@ export default ApolloClient;

export * from './cache/core';
export * from './cache/inmemory';

export * from './react';
25 changes: 25 additions & 0 deletions src/react/context/ApolloConsumer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import { invariant } from 'ts-invariant';

import ApolloClient from '../../ApolloClient';
import { getApolloContext } from './ApolloContext';

export interface ApolloConsumerProps {
children: (client: ApolloClient<object>) => React.ReactChild | null;
}

export const ApolloConsumer: React.FC<ApolloConsumerProps> = props => {
const ApolloContext = getApolloContext();
return (
<ApolloContext.Consumer>
{(context: any) => {
invariant(
context && context.client,
'Could not find "client" in the context of ApolloConsumer. ' +
'Wrap the root component in an <ApolloProvider>.'
);
return props.children(context.client);
}}
</ApolloContext.Consumer>
);
};
21 changes: 21 additions & 0 deletions src/react/context/ApolloContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';

import ApolloClient from '../../ApolloClient';

export interface ApolloContextValue {
client?: ApolloClient<object>;
renderPromises?: Record<any, any>;
}

let apolloContext: React.Context<ApolloContextValue>;

export function getApolloContext() {
if (!apolloContext) {
apolloContext = React.createContext<ApolloContextValue>({});
}
return apolloContext;
}

export function resetApolloContext() {
apolloContext = React.createContext<ApolloContextValue>({});
}
38 changes: 38 additions & 0 deletions src/react/context/ApolloProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react';
import { invariant } from 'ts-invariant';

import ApolloClient from '../../ApolloClient';
import { getApolloContext } from './ApolloContext';

export interface ApolloProviderProps<TCache> {
client: ApolloClient<TCache>;
children: React.ReactNode | React.ReactNode[] | null;
}

export const ApolloProvider: React.FC<ApolloProviderProps<any>> = ({
client,
children
}) => {
const ApolloContext = getApolloContext();
return (
<ApolloContext.Consumer>
{(context = {}) => {
if (client && context.client !== client) {
context = Object.assign({}, context, { client });
}

invariant(
context.client,
'ApolloProvider was not passed a client instance. Make ' +
'sure you pass in your client via the "client" prop.'
);

return (
<ApolloContext.Provider value={context}>
{children}
</ApolloContext.Provider>
);
}}
</ApolloContext.Consumer>
);
};
67 changes: 67 additions & 0 deletions src/react/context/__tests__/ApolloConsumer.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import React from 'react';
import { ApolloLink } from 'apollo-link';
import { render, cleanup } from '@testing-library/react';

import ApolloClient from '../../../ApolloClient';
import { InMemoryCache as Cache } from '../../../cache/inmemory/inMemoryCache';
import { ApolloProvider } from '../ApolloProvider';
import { ApolloConsumer } from '../ApolloConsumer';
import { getApolloContext } from '../ApolloContext';

const client = new ApolloClient({
cache: new Cache(),
link: new ApolloLink((o, f) => (f ? f(o) : null))
});

describe('<ApolloConsumer /> component', () => {
afterEach(cleanup);

it('has a render prop', done => {
render(
<ApolloProvider client={client}>
<ApolloConsumer>
{clientRender => {
try {
expect(clientRender).toBe(client);
done();
} catch (e) {
done.fail(e);
}
return null;
}}
</ApolloConsumer>
</ApolloProvider>
);
});

it('renders the content in the children prop', () => {
const { getByText } = render(
<ApolloProvider client={client}>
<ApolloConsumer>{() => <div>Test</div>}</ApolloConsumer>
</ApolloProvider>
);

expect(getByText('Test')).toBeTruthy();
});

it('errors if there is no client in the context', () => {
// Prevent Error about missing context type from appearing in the console.
const errorLogger = console.error;
console.error = () => {};
expect(() => {
// We're wrapping the `ApolloConsumer` component in a
// `ApolloContext.Provider` component, to reset the context before
// testing.
const ApolloContext = getApolloContext();
render(
<ApolloContext.Provider value={{}}>
<ApolloConsumer>{() => null}</ApolloConsumer>
</ApolloContext.Provider>
);
}).toThrowError(
'Could not find "client" in the context of ApolloConsumer. Wrap the root component in an <ApolloProvider>'
);

console.error = errorLogger;
});
});
Loading