diff --git a/Changelog.md b/Changelog.md
index ed284e71e6..e11de1713c 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -2,6 +2,11 @@
Expect active development and potentially significant breaking changes in the `0.x` track. We'll try to be diligent about releasing a `1.0` version in a timely fashion (ideally within 1 or 2 months), so that we can take advantage of SemVer to signify breaking changes from that point on.
+### vNext
+
+### v0.5.1
+
+- Feature: Added link to [recompose](https://github.com/acdlite/recompose) to use the `compose` function. This makes it easy to combine multiple queries on a single component. [#194](https://github.com/apollostack/react-apollo/pull/194)
### v0.5.0
diff --git a/global.d.ts b/global.d.ts
index 7cd4d5ebd2..e14539c351 100644
--- a/global.d.ts
+++ b/global.d.ts
@@ -11,6 +11,10 @@ declare module 'lodash.isequal' {
export = main.isEqual;
}
+declare module 'recompose/compose' {
+ function hoc(component: any): any;
+ export default (...hocs) => hoc;
+}
declare module 'hoist-non-react-statics' {
/**
diff --git a/package.json b/package.json
index c25733dea0..44c423d369 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "react-apollo",
- "version": "0.5.0",
+ "version": "0.5.1",
"description": "React data container for Apollo Client",
"main": "index.js",
"scripts": {
@@ -101,6 +101,7 @@
"lodash.flatten": "^4.2.0",
"lodash.isequal": "^4.1.1",
"lodash.isobject": "^3.0.2",
- "object-assign": "^4.0.1"
+ "object-assign": "^4.0.1",
+ "recompose": "^0.20.2"
}
}
diff --git a/src/index.ts b/src/index.ts
index b44fc4cb58..49fb025bd5 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,4 +1,7 @@
import ApolloProvider from './ApolloProvider';
import graphql, { withApollo } from './graphql';
-export { ApolloProvider, graphql, withApollo };
+// expose easy way to join queries from recompose
+import compose from 'recompose/compose';
+
+export { ApolloProvider, graphql, withApollo, compose };
diff --git a/test/react-web/client/graphql/shared-operations.tsx b/test/react-web/client/graphql/shared-operations.tsx
index 16f9565368..5fab862721 100644
--- a/test/react-web/client/graphql/shared-operations.tsx
+++ b/test/react-web/client/graphql/shared-operations.tsx
@@ -20,6 +20,7 @@ import {
} from '../../../mocks/components';
import graphql, { withApollo } from '../../../../src/graphql';
+import { compose } from '../../../../src/';
describe('shared opertations', () => {
@@ -199,4 +200,39 @@ describe('shared opertations', () => {
}, 25);
});
+ describe('compose', () => {
+ it('binds two queries to props with different syntax', () => {
+ const peopleQuery = gql`query people { allPeople(first: 1) { people { name } } }`;
+ const peopleData = { allPeople: { people: [ { name: 'Luke Skywalker' } ] } };
+
+ const shipsQuery = gql`query ships { allships(first: 1) { ships { name } } }`;
+ const shipsData = { allships: { ships: [ { name: 'Tie Fighter' } ] } };
+
+
+ const networkInterface = mockNetworkInterface(
+ { request: { query: peopleQuery }, result: { data: peopleData } },
+ { request: { query: shipsQuery }, result: { data: shipsData } }
+ );
+ const client = new ApolloClient({ networkInterface });
+
+ const enhanced = compose(
+ graphql(peopleQuery, { name: 'people' }),
+ graphql(shipsQuery, { name: 'ships' })
+ );
+
+ const ContainerWithData = enhanced((props) => {
+ const { people, ships } = props;
+ expect(people).to.exist;
+ expect(people.loading).to.be.true;
+
+ expect(ships).to.exist;
+ expect(ships.loading).to.be.true;
+ return null;
+ });
+
+ const wrapper = mount();
+ (wrapper as any).unmount();
+ });
+ });
+
});
diff --git a/typings/modules/apollo-client/index.d.ts b/typings/modules/apollo-client/index.d.ts
index 3af48d29e3..632c9d8c4e 100644
--- a/typings/modules/apollo-client/index.d.ts
+++ b/typings/modules/apollo-client/index.d.ts
@@ -52,6 +52,10 @@ export interface NetworkInterface {
[others: string]: any;
query(request: Request): Promise;
}
+export interface SubscriptionNetworkInterface extends NetworkInterface {
+ subscribe(request: Request, handler: (error, result) => void): number;
+ unsubscribe(id: Number): void;
+}
export interface BatchedNetworkInterface extends NetworkInterface {
batchQuery(requests: Request[]): Promise;
}
@@ -389,6 +393,14 @@ import { Observer, Subscription } from '~apollo-client/util/Observable';
import { WatchQueryOptions } from '~apollo-client/watchQueryOptions';
import { ObservableQuery } from '~apollo-client/ObservableQuery';
export type QueryListener = (queryStoreValue: QueryStoreValue) => void;
+export interface SubscriptionOptions {
+ query: Document;
+ variables?: {
+ [key: string]: any;
+ };
+ fragments?: FragmentDefinition[];
+ handler: (error: Object, result: Object) => void;
+}
export class QueryManager {
pollingTimers: {
[queryId: string]: NodeJS.Timer | any;
@@ -441,6 +453,7 @@ export class QueryManager {
removeObservableQuery(queryId: string): void;
resetStore(): void;
startQuery(queryId: string, options: WatchQueryOptions, listener: QueryListener): string;
+ startSubscription(options: SubscriptionOptions): number;
stopQuery(queryId: string): void;
getQueryWithPreviousResult(queryId: string, isOptimistic?: boolean): {
previousResult: Object;
@@ -451,7 +464,10 @@ export class QueryManager {
queryFragments: FragmentDefinition[];
};
private collectResultBehaviorsFromUpdateQueries(updateQueries, mutationResult, isOptimistic?);
- private fetchQueryOverInterface(queryId, options, network);
+ private transformQueryDocument(options);
+ private handleDiffQuery({queryDef, rootId, variables, fragmentMap, noFetch});
+ private fetchRequest({requestId, queryId, query, querySS, options, fragmentMap, networkInterface});
+ private fetchQueryOverInterface(queryId, options, networkInterface);
private refetchQueryByName(queryName);
private isDifferentResult(queryId, result);
private broadcastQueries();
@@ -465,7 +481,7 @@ export * from '~apollo-client/QueryManager';
// Generated by typings
// Source: node_modules/apollo-client/ObservableQuery.d.ts
declare module '~apollo-client/ObservableQuery' {
-import { WatchQueryOptions, FetchMoreQueryOptions } from '~apollo-client/watchQueryOptions';
+import { WatchQueryOptions, FetchMoreQueryOptions, GraphQLSubscriptionOptions } from '~apollo-client/watchQueryOptions';
import { Observable } from '~apollo-client/util/Observable';
import { QueryScheduler } from '~apollo-client/scheduler';
import { ApolloQueryResult } from '~apollo-client/index';
@@ -475,9 +491,14 @@ export interface FetchMoreOptions {
queryVariables: Object;
}) => Object;
}
+export interface UpdateQueryOptions {
+ queryVariables: Object;
+}
export class ObservableQuery extends Observable {
refetch: (variables?: any) => Promise;
fetchMore: (options: FetchMoreQueryOptions & FetchMoreOptions) => Promise;
+ startGraphQLSubscription: (options: GraphQLSubscriptionOptions) => number;
+ updateQuery: (mapFn: (previousQueryResult: any, options: UpdateQueryOptions) => any) => void;
stopPolling: () => void;
startPolling: (p: number) => void;
options: WatchQueryOptions;
@@ -517,6 +538,17 @@ export interface FetchMoreQueryOptions {
[key: string]: any;
};
}
+export interface GraphQLSubscriptionOptions {
+ subscription: Document;
+ variables?: {
+ [key: string]: any;
+ };
+ fragments?: FragmentDefinition[];
+ updateQuery: (previousQueryResult: Object, options: {
+ subscriptionResult: Object;
+ queryVariables: Object;
+ }) => Object;
+}
}
declare module 'apollo-client/watchQueryOptions' {
export * from '~apollo-client/watchQueryOptions';
@@ -722,7 +754,7 @@ export * from '~apollo-client/data/mutationResults';
// Source: node_modules/apollo-client/index.d.ts
declare module '~apollo-client/index' {
import { NetworkInterface, createNetworkInterface, addQueryMerging } from '~apollo-client/networkInterface';
-import { Document, FragmentDefinition, SelectionSet } from 'graphql';
+import { Document, FragmentDefinition } from 'graphql';
import { print } from 'graphql-tag/printer';
import { createApolloStore, ApolloStore, createApolloReducer, ApolloReducerConfig } from '~apollo-client/store';
import { QueryManager } from '~apollo-client/QueryManager';
@@ -732,7 +764,7 @@ import { readQueryFromStore, readFragmentFromStore } from '~apollo-client/data/r
import { writeQueryToStore, writeFragmentToStore } from '~apollo-client/data/writeToStore';
import { IdGetter } from '~apollo-client/data/extensions';
import { QueryTransformer, addTypenameToSelectionSet } from '~apollo-client/queries/queryTransform';
-import { MutationBehaviorReducerMap } from '~apollo-client/data/mutationResults';
+import { MutationBehavior, MutationBehaviorReducerMap, MutationQueryReducersMap } from '~apollo-client/data/mutationResults';
export { createNetworkInterface, addQueryMerging, createApolloStore, createApolloReducer, readQueryFromStore, readFragmentFromStore, addTypenameToSelectionSet as addTypename, writeQueryToStore, writeFragmentToStore, print as printAST };
export type ApolloQueryResult = {
data: any;
@@ -770,51 +802,21 @@ export default class ApolloClient {
mutationBehaviorReducers?: MutationBehaviorReducerMap;
batchInterval?: number;
});
- watchQuery: (options: WatchQueryOptions) => ObservableQuery;
- query: (options: WatchQueryOptions) => Promise<{
- data: any;
- loading: boolean;
- }>;
- mutate: (options: {
+ watchQuery(options: WatchQueryOptions): ObservableQuery;
+ query(options: WatchQueryOptions): Promise;
+ mutate(options: {
mutation: Document;
variables?: Object;
- resultBehaviors?: ({
- type: "ARRAY_INSERT";
- resultPath: (string | number)[];
- storePath: (string | number)[];
- where: "PREPEND" | "APPEND";
- } | {
- type: "ARRAY_DELETE";
- storePath: (string | number)[];
- dataId: string;
- } | {
- type: "DELETE";
- dataId: string;
- } | {
- type: "QUERY_RESULT";
- queryVariables: any;
- querySelectionSet: SelectionSet;
- queryFragments: FragmentDefinition[];
- newResult: Object;
- })[];
+ resultBehaviors?: MutationBehavior[];
fragments?: FragmentDefinition[];
optimisticResponse?: Object;
- updateQueries?: {
- [queryName: string]: (previousResult: Object, options: {
- mutationResult: Object;
- queryName: Object;
- queryVariables: Object;
- }) => Object;
- };
+ updateQueries?: MutationQueryReducersMap;
refetchQueries?: string[];
- }) => Promise<{
- data: any;
- loading: boolean;
- }>;
+ }): Promise;
reducer(): Function;
middleware: () => (store: ApolloStore) => (next: any) => (action: any) => any;
initStore(): void;
- private setStore;
+ private setStore(store);
}
}
declare module 'apollo-client/index' {