Skip to content
This repository has been archived by the owner on May 17, 2019. It is now read-only.

Commit

Permalink
Merge logic from fusion-apollo-universal-client, export multiple plugins
Browse files Browse the repository at this point in the history
#177

Co-authored-by: Giancarlo Anemone <ganemone@uber.com>
  • Loading branch information
2 people authored and fusion-bot[bot] committed Apr 9, 2019
1 parent 6631b1b commit 4897aeb
Show file tree
Hide file tree
Showing 14 changed files with 905 additions and 152 deletions.
86 changes: 63 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ The plugin will perform graphql queries on the server, thereby rendering your ap
- [`ApolloClientToken`](#apolloclienttoken)
- [`GraphQLSchemaToken`](#graphqlschematoken)
- [`GraphQLEndpointToken`](#graphqlendpointtoken)
- [Plugin](#plugin)
- [Provider](#providers)
- [`GetApolloClientCacheToken`](#GetApolloClientCacheToken)
- [`ApolloClientCredentialsToken`](#apolloclientcredentialstoken)
- [`GetApolloClientLinksToken`](#getapolloclientlinkstoken)
- [`ApolloClientResolversToken`](#apolloclientresolverstoken)
= [GQL Macro]($gql)

---

Expand All @@ -41,19 +44,17 @@ import React from 'react';
import App from 'fusion-react';
import {RenderToken} from 'fusion-core';

// New import provided by this plugin
import ApolloPlugin, {
import {
ApolloRenderEnhancer,
ApolloClientPlugin,
ApolloClientToken,
GraphQLSchemaToken,
ApolloClientToken
} from 'fusion-plugin-apollo';

// Plugin which provides an apollo client pre-configured for universal rendering
import ApolloUniversalClient from 'fusion-apollo-universal-client';

export default function() {
const app = new App(<Hello />);
app.register(RenderToken, ApolloPlugin);
app.register(ApolloClientToken, ApolloUniversalClient);
app.enhance(RenderToken, ApolloRenderEnhancer);
app.register(ApolloClientToken, ApolloClientPlugin);
if (__NODE__) {
app.register(GraphQLSchemaToken, YourGraphQLSchema);
}
Expand All @@ -71,20 +72,18 @@ import React from 'react';
import App from 'fusion-react';
import {RenderToken} from 'fusion-core';

// New import provided by this plugin
import ApolloPlugin, {
GraphQLEndpointToken,
ApolloClientToken
import {
ApolloRenderEnhancer,
ApolloClientPlugin,
ApolloClientToken,
GraphQLSchemaToken,
} from 'fusion-plugin-apollo';

// Plugin which provides an apollo client pre-configured for universal rendering
import ApolloUniversalClient from 'fusion-apollo-universal-client';

export default function() {
const app = new App(<Hello />);
app.register(RenderToken, ApolloPlugin);
app.register(ApolloClientToken, ApolloUniversalClient);
app.register(GraphQLEndpointToken, '...');
app.enhance(RenderToken, ApolloRenderEnhancer);
app.register(ApolloClientToken, ApolloClientPlugin);
app.register(GraphQLEndpointToken, 'http://website.com/graphql');
return app;
}
```
Expand Down Expand Up @@ -152,13 +151,54 @@ Optional - the endpoint for serving the graphql API. Defaults to `'/graphql'`. T
type GraphQLEndpoint = string;
```

#### Plugin
##### `GetApolloClientCacheToken`

```js
import {GetApolloClientCacheToken} from 'fusion-apollo-universal-client';
```

Optional - A function that returns an Apollo [cache implementation](https://www.apollographql.com/docs/react/advanced/caching.html).

```js
type GetApolloClientCache = (ctx: Context) => ApolloCache
```

###### Default value

The default cache implementation uses [InMemoryCache](https://github.com/apollographql/apollo-client/tree/master/packages/apollo-cache-inmemory).

##### `ApolloClientCredentialsToken`

```js
import {ApolloClientCredentialsToken} from 'fusion-apollo-universal-client';
```

Optional - A configuration value that provides the value of credentials value passed directly into the [fetch implementation](https://github.com/github/fetch).
The default value is `same-origin`.

```js
type ApolloClientCredentials = 'omit' | 'include' | 'same-origin'
```

##### `GetApolloClientLinksToken`

```js
import {GetApolloClientLinksToken} from 'fusion-apollo-universal-client';
```

Optional - A configuration value that provides a array of [ApolloLinks](https://www.apollographql.com/docs/link/composition.html). The default links are provided as an argument to the provided function.

```js
type GetApolloClientLinks = (Array<ApolloLinkType>) => Array<ApolloLinkType>
```

##### `ApolloClientResolversToken`

```js
import ApolloPlugin from 'fusion-plugin-apollo';
import { ApolloClientResolversToken } from "fusion-apollo-universal-client";
```

A plugin which is responsible for rendering (both virtual DOM and server-side rendering).
Optional - Provides the resolvers for [local state management](https://www.apollographql.com/docs/react/essentials/local-state.html).

#### gql

Expand Down
13 changes: 9 additions & 4 deletions docs/migrations/00159.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
## v2.0.0

The 2.0.0 release also marks a refactor from `fusion-apollo` as an app wrapper into `fusion-plugin-apollo` which is implemented as a plugin to be
registered on the `RenderToken`. We also consolidated the code from `fusion-apollo-universal-server` into this module. The migration looks like this:
The 2.0.0 release also marks a refactor from `fusion-apollo` as an app wrapper into `fusion-plugin-apollo` which is implemented as an enhancer to be
registered on the `RenderToken`. We also consolidated the code from `fusion-apollo-universal-server` and `fusion-apollo-universal-client` into this module.
The migration looks like this:

```diff
+import {RenderToken} from 'fusion-core';
+import App from 'fusion-react';
-import App from 'fusion-apollo';
+import ApolloPlugin from 'fusion-plugin-apollo';
-import ApolloServer from 'fusion-plugin-apollo-server';
-import ApolloClient from 'fusion-apollo-universal-client';
+import {
+ ApolloRenderEnhancer,
+ ApolloClientPlugin,
+}from 'fusion-plugin-apollo';

export default async function main() {
const app = new App();
+ app.register(RenderToken, ApolloPlugin);
+ app.enhance(RenderToken, ApolloRenderEnhancer);
- app.register(ApolloServer); // apollo-server 2.0 now integrated by default
- app.middleware(require('koa-bodyparser')()); // Body parsing for /graphql route is included by default now with apollo-server 2
}
Expand Down
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@
"react-dom": "^16.6.3",
"redux": "^4.0.1",
"tape-cup": "^4.7.1",
"unitest": "^2.1.1"
"unfetch": "^4.1.0",
"unitest": "^2.1.1",
"nyc": "^13.3.0"
},
"peerDependencies": {
"fusion-core": "^1.10.4",
Expand All @@ -74,6 +76,8 @@
"transpile": "npm run clean && cup build",
"build-test": "rm -rf dist-tests && cup build-tests",
"just-test": "node_modules/.bin/unitest --browser=dist-tests/browser.js --node=dist-tests/node.js",
"cover": "npm run build-test && npm run just-cover",
"just-cover": "nyc --reporter=cobertura --reporter=text npm run just-test",
"test": "npm run build-test && npm run just-test",
"prepublish": "npm run transpile"
},
Expand Down
5 changes: 3 additions & 2 deletions src/__tests__/exports.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
* @flow
*/
import test from 'tape-cup';
import plugin, {
import {
ApolloRenderEnhancer,
ApolloContextToken,
GraphQLSchemaToken,
gql,
Expand All @@ -17,7 +18,7 @@ test('fusion-tokens exports', t => {
t.ok(ApolloContextToken, 'exports ApolloContextToken');
t.ok(GraphQLSchemaToken, 'exports GraphQLSchemaToken');
t.ok(GraphQLEndpointToken, 'exports GraphQLSchemaToken');
t.ok(plugin, 'exports plugin');
t.ok(ApolloRenderEnhancer, 'exports plugin');
t.equal(typeof gql, 'function', 'exports a gql function');
t.throws(gql, 'gql function throws an error if executed directly');
t.end();
Expand Down
8 changes: 6 additions & 2 deletions src/__tests__/integration.node.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@
*/
import test from 'tape-cup';
import React from 'react';
import plugin, {GraphQLSchemaToken, ApolloClientToken} from '../index';
import {
ApolloRenderEnhancer,
GraphQLSchemaToken,
ApolloClientToken,
} from '../index';
import gql from 'graphql-tag';
import App from 'fusion-react/dist';
import {RenderToken} from 'fusion-core';
Expand Down Expand Up @@ -36,7 +40,7 @@ async function testApp(el, {typeDefs, resolvers}) {
},
}),
});
app.register(RenderToken, plugin);
app.enhance(RenderToken, ApolloRenderEnhancer);
app.register(GraphQLSchemaToken, schema);
app.register(ApolloClientToken, ctx => {
// $FlowFixMe
Expand Down
24 changes: 8 additions & 16 deletions src/__tests__/server.node.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@
import test from 'tape-cup';
import {getSimulator} from 'fusion-test-utils';
import React from 'react';
import render from '../server';
import plugin, {GraphQLSchemaToken, ApolloClientToken} from '../index';
import {
ApolloRenderEnhancer,
GraphQLSchemaToken,
ApolloClientToken,
} from '../index';
import gql from 'graphql-tag';
import {makeExecutableSchema} from 'graphql-tools';
import {Query} from 'react-apollo';
import App from 'fusion-react/dist';
import App from 'fusion-react';
import {RenderToken} from 'fusion-core';
import {ApolloClient} from 'apollo-client';
import {InMemoryCache} from 'apollo-cache-inmemory';
Expand All @@ -27,7 +30,7 @@ import fetch from 'node-fetch';
function testApp(el, {typeDefs, resolvers}) {
const app = new App(el);
const schema = makeExecutableSchema({typeDefs, resolvers});
app.register(RenderToken, plugin);
app.enhance(RenderToken, ApolloRenderEnhancer);
app.register(GraphQLSchemaToken, schema);
app.register(ApolloClientToken, ctx => {
return new ApolloClient({
Expand All @@ -42,21 +45,10 @@ function testApp(el, {typeDefs, resolvers}) {
return app;
}

test('renders', async t => {
const rendered = await render(
React.createElement('span', null, 'hello'),
// $FlowFixMe
console
);
t.ok(/<span/.test(rendered), 'has right tag');
t.ok(/hello/.test(rendered), 'has right text');
t.end();
});

test('Server renders without schema', async t => {
const el = <div>Hello World</div>;
const app = new App(el);
app.register(RenderToken, plugin);
app.enhance(RenderToken, ApolloRenderEnhancer);
app.register(ApolloClientToken, ctx => {
return new ApolloClient({
ssrMode: true,
Expand Down
27 changes: 27 additions & 0 deletions src/apollo-client/__tests__/exports.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/** Copyright (c) 2018 Uber Technologies, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

import test from 'tape-cup';
import {
ApolloClientPlugin,
GetApolloClientCacheToken,
ApolloClientCredentialsToken,
GetApolloClientLinksToken,
ApolloClientDefaultOptionsToken,
ApolloClientResolversToken,
} from '../index.js';

test('exports', t => {
t.ok(ApolloClientPlugin, 'exports ApolloClientPlugin');
t.ok(GetApolloClientCacheToken, 'exports GetApolloClientCacheToken');
t.ok(ApolloClientCredentialsToken, 'exports ApolloClientCredentialsToken');
t.ok(GetApolloClientLinksToken, 'exports ApolloClientAuthKeyToken');
t.ok(ApolloClientDefaultOptionsToken, 'exports ApolloClientAuthKeyToken');
t.ok(ApolloClientResolversToken, 'exports ApolloClientResolversToken');
t.end();
});
55 changes: 55 additions & 0 deletions src/apollo-client/__tests__/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/** Copyright (c) 2018 Uber Technologies, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

import {InMemoryCache} from 'apollo-cache-inmemory';
import App, {createPlugin} from 'fusion-core';
import {getSimulator} from 'fusion-test-utils';
import {ApolloClientToken} from '../../tokens';
import {ApolloLink} from 'apollo-link';
import {FetchToken} from 'fusion-tokens';
import unfetch from 'unfetch';
import test from 'tape-cup';

import {ApolloClientPlugin, GetApolloClientLinksToken} from '../index.js';

test('ApolloUniveralClient', async t => {
const app = new App('el', el => el);
app.register(GetApolloClientLinksToken, links => [
new ApolloLink(),
...links,
]);
app.register(ApolloClientToken, ApolloClientPlugin);
app.register(FetchToken, unfetch);

const clients = [];
const testPlugin = createPlugin({
deps: {
universalClient: ApolloClientToken,
},
middleware({universalClient}) {
return async (ctx, next) => {
const client = universalClient(ctx, {});
clients.push(client);
t.ok(client.link);
t.ok(client.cache instanceof InMemoryCache);
// memoizes the client on ctx correctly
t.equal(client, universalClient(ctx, {}));
return next();
};
},
});
app.register(testPlugin);

const simulator = getSimulator(app);
await simulator.render('/');
await simulator.render('/');
t.equal(clients.length, 2);
t.notEqual(clients[0], clients[1]);
t.notEqual(clients[0].cache, clients[1].cache);
t.end();
});
Loading

0 comments on commit 4897aeb

Please sign in to comment.