Skip to content
This repository has been archived by the owner on Nov 20, 2020. It is now read-only.

Make compatible with GraphQL PPX 1.0 beta #117

Draft
wants to merge 14 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion bsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@
}
],
"suffix": ".bs.js",
"bs-dependencies": ["reason-react", "reason-apollo"],
"bs-dependencies": ["reason-react"],
"refmt": 3
}
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@
"@apollo/react-hooks": "^3.0.0",
"@commitlint/cli": "^8.2.0",
"@commitlint/config-conventional": "^8.2.0",
"bs-platform": "^7.0.1",
"bs-platform": "^7.2.0",
"bsdoc": "6.0.1-alpha",
"husky": "^3.0.5",
"lint-staged": "^9.4.0",
"reason-apollo": "^0.18.0",
"reason-react": ">=0.7.0"
},
"peerDependencies": {
Expand Down
146 changes: 146 additions & 0 deletions src/ApolloClient.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
open ReasonApolloTypes;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be amazing if this would be moved to another package so reason-apollo and reason-apollo-hooks could share the same ApolloClient definitions

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably better to have a single package, because the hooks are now also part of the same @apollo/client package.


type queryObj('raw_t_variables) = {
query: ReasonApolloTypes.queryString,
variables: 'raw_t_variables,
};

type opaqueQueryObj;
external toOpaqueQueryObj: queryObj('raw_t_variables) => opaqueQueryObj =
"%identity";

type mutationObj('raw_t_variables) = {
mutation: ReasonApolloTypes.queryString,
variables: 'raw_t_variables,
};

type updateQueryOptions('raw_t, 'raw_t_variables) = {
fetchMoreResult: option('raw_t),
variables: option('raw_t_variables),
};

type onErrorT;
type updateQueryT('raw_t, 'raw_t_variables) =
('raw_t, updateQueryOptions('raw_t, 'raw_t_variables)) => 'raw_t;

type updateSubscriptionOptions = {
subscriptionData: option(Js.Json.t),
variables: option(Js.Json.t),
};
type updateQuerySubscriptionT =
(Js.Json.t, updateSubscriptionOptions) => Js.Json.t;

type subscribeToMoreOptions = {
document: queryString,
variables: option(Js.Json.t),
updateQuery: option(updateQuerySubscriptionT),
onError: option(onErrorT),
};

type fetchMoreOptions('raw_t, 'raw_t_variables) = {
variables: option('raw_t_variables),
updateQuery: updateQueryT('raw_t, 'raw_t_variables),
};

type queryResult('raw_t, 'raw_t_variables) = {
loading: bool,
data: Js.Nullable.t('raw_t),
error: Js.Nullable.t(apolloError),
refetch:
Js.Null_undefined.t('raw_t) =>
Js.Promise.t(queryResult('raw_t, 'raw_t_variables)),
networkStatus: Js.Nullable.t(int),
variables: Js.Null_undefined.t(Js.Json.t),
fetchMore:
fetchMoreOptions('raw_t, 'raw_t_variables) => Js.Promise.t(unit),
subscribeToMore: subscribeToMoreOptions => unit,
};

type mutationResult('raw_t) = {
loading: bool,
called: bool,
data: Js.Nullable.t('raw_t),
error: Js.Nullable.t(apolloError),
networkStatus: Js.Nullable.t(int),
variables: Js.Null_undefined.t(Js.Json.t),
};

type t;

[@bs.send]
external query:
(t, queryObj('raw_t_variables)) =>
Js.Promise.t(queryResult('raw_t, 'raw_t_variables)) =
"query";

[@bs.send]
external mutate:
(t, mutationObj('raw_t_variables)) => Js.Promise.t(mutationResult('raw_t)) =
"mutate";
[@bs.send] external resetStore: t => Js.Promise.t(unit) = "resetStore";

type apolloClientObjectParam = {
link: apolloLink,
cache: apolloCache,
ssrMode: option(bool),
ssrForceFetchDelay: option(int),
connectToDevTools: option(bool),
queryDeduplication: option(bool),
};

[@bs.module "@apollo/client"] [@bs.new]
external createApolloClientJS: apolloClientObjectParam => t = "ApolloClient";

[@bs.module "graphql-tag"] external gql: ReasonApolloTypes.gql = "default";

module ReadQuery = (Config: ReasonApolloTypes.Config) => {
type readQueryOptions = {
query: ReasonApolloTypes.queryString,
variables: Js.Nullable.t(Config.Raw.t_variables),
};
type response = option(Config.t);
[@bs.send]
external readQuery: (t, readQueryOptions) => Js.Nullable.t(Config.Raw.t) =
"readQuery";

let graphqlQueryAST = gql(. Config.query);
let apolloDataToRecord: Js.Nullable.t(Config.Raw.t) => response =
apolloData =>
Js.Nullable.toOption(apolloData)->(Belt.Option.map(Config.parse));

let make = (~client, ~variables: option(Config.Raw.t_variables)=?, ()) =>
readQuery(
client,
{query: graphqlQueryAST, variables: Js.Nullable.fromOption(variables)},
)
->apolloDataToRecord;
};

module WriteQuery = (Config: ReasonApolloTypes.Config) => {
type writeQueryOptions = {
query: ReasonApolloTypes.queryString,
variables: Js.Nullable.t(Config.Raw.t_variables),
data: Config.t,
};

[@bs.send]
external writeQuery: (t, writeQueryOptions) => unit = "writeQuery";

let graphqlQueryAST = gql(. Config.query);

let make =
(
~client,
~variables: option(Config.Raw.t_variables)=?,
~data: Config.t,
(),
) =>
writeQuery(
client,
{
query: graphqlQueryAST,
variables: Js.Nullable.fromOption(variables),
data,
},
);
};
20 changes: 15 additions & 5 deletions src/ApolloHooks.re
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,22 @@ let useQuery = Query.useQuery;
*/
let useMutation = Mutation.useMutation;

let toReadQueryOptions = result => {
"query": ApolloClient.gql(. result##query),
"variables": Js.Nullable.fromOption(Some(result##variables)),
};

/** useSubscription bindings */
let useSubscription = Subscription.useSubscription;

/** Helper to generate the shape of a query for [refetchQueries] mutation param. Take a look in examples/persons/src/EditPerson.re for a more complete demo of usage. */
let toQueryObj = result =>
ApolloClient.{
query: ApolloClient.gql(. result##query),
variables: result##variables,
};
let toQueryObj:
(string, 'raw_t_variables) => ApolloClient.queryObj('raw_t_variables) =
(theQuery, variables) =>
ApolloClient.{query: ApolloClient.gql(. theQuery), variables};

let toOpaqueQueryObj: (string, 'raw_t_variables) => ApolloClient.opaqueQueryObj =
(theQuery, variables) =>
ApolloClient.toOpaqueQueryObj(
ApolloClient.{query: ApolloClient.gql(. theQuery), variables},
);
54 changes: 54 additions & 0 deletions src/ApolloHooksClient.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
open ApolloHooksTypes;

type queryError = {. "message": string};
type queryResult('a) = {
data: option('a),
errors: option(array(queryError)),
loading: bool,
networkStatus: ApolloHooksTypes.networkStatus,
stale: bool,
};

[@bs.module "graphql-tag"] external gql: ReasonApolloTypes.gql = "default";

type options('data);
[@bs.obj]
external doMakeOptions:
(
~query: ReasonApolloTypes.queryString,
~variables: 'raw_t_variables=?,
~notifyOnNetworkStatusChange: bool=?,
~fetchPolicy: string=?,
~errorPolicy: string=?,
~pollInterval: int=?,
unit
) =>
options('data);

let makeOptions =
(
~variables: 'raw_t_variables=?,
~notifyOnNetworkStatusChange=?,
~fetchPolicy=?,
~errorPolicy=?,
~pollInterval=?,
(_, query, _): graphqlDefinition('data, _),
) => {
doMakeOptions(
~query=gql(. query),
~variables?,
~notifyOnNetworkStatusChange?,
~fetchPolicy=?fetchPolicy->Belt.Option.map(f => fetchPolicyToJs(f)),
~errorPolicy=?errorPolicy->Belt.Option.map(e => errorPolicyToJs(e)),
~pollInterval?,
(),
);
};

[@bs.send]
external query:
(ApolloClient.t, options('data)) => Js.Promise.t(queryResult('data)) =
"query";

[@bs.module "../../../apolloClient"]
external client: ApolloClient.t = "default";
Loading