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
84 changes: 51 additions & 33 deletions src/ApolloClient.re
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
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 = {
type queryObj('raw_t_variables) = {
query: ReasonApolloTypes.queryString,
variables: Js.Json.t,
variables: 'raw_t_variables,
};

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

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

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

type onErrorT;
type updateQueryT = (Js.Json.t, updateQueryOptions) => Js.Json.t;
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),
Expand All @@ -31,19 +37,22 @@ type subscribeToMoreOptions = {
onError: option(onErrorT),
};

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

type queryResult('raw_t) = {
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)),
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 => Js.Promise.t(unit),
fetchMore:
fetchMoreOptions('raw_t, 'raw_t_variables) => Js.Promise.t(unit),
subscribeToMore: subscribeToMoreOptions => unit,
};

Expand All @@ -56,11 +65,19 @@ type mutationResult('raw_t) = {
variables: Js.Null_undefined.t(Js.Json.t),
};

type generatedApolloClient('raw_t) = {
query: [@bs.meth] (queryObj => Js.Promise.t(queryResult('raw_t))),
mutate: [@bs.meth] (mutationObj => Js.Promise.t(mutationResult('raw_t))),
resetStore: [@bs.meth] (unit => Js.Promise.t(unit)),
};
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,
Expand All @@ -72,30 +89,26 @@ type apolloClientObjectParam = {
};

[@bs.module "@apollo/client"] [@bs.new]
external createApolloClientJS:
apolloClientObjectParam => generatedApolloClient('raw_t) =
"ApolloClient";
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(Js.Json.t),
variables: Js.Nullable.t(Config.Raw.t_variables),
};
type response = option(Config.t);
[@bs.send]
external readQuery:
(generatedApolloClient('raw_t), readQueryOptions) =>
Js.Nullable.t('raw_t) =
external readQuery: (t, readQueryOptions) => Js.Nullable.t(Config.Raw.t) =
"readQuery";

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

let make = (~client, ~variables: option(Js.Json.t)=?, ()) =>
let make = (~client, ~variables: option(Config.Raw.t_variables)=?, ()) =>
readQuery(
client,
{query: graphqlQueryAST, variables: Js.Nullable.fromOption(variables)},
Expand All @@ -106,17 +119,22 @@ module ReadQuery = (Config: ReasonApolloTypes.Config) => {
module WriteQuery = (Config: ReasonApolloTypes.Config) => {
type writeQueryOptions = {
query: ReasonApolloTypes.queryString,
variables: Js.Nullable.t(Js.Json.t),
variables: Js.Nullable.t(Config.Raw.t_variables),
data: Config.t,
};

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

let graphqlQueryAST = gql(. Config.query);

let make = (~client, ~variables: option(Js.Json.t)=?, ~data: Config.t, ()) =>
let make =
(
~client,
~variables: option(Config.Raw.t_variables)=?,
~data: Config.t,
(),
) =>
writeQuery(
client,
{
Expand Down
20 changes: 10 additions & 10 deletions src/ApolloHooks.re
Original file line number Diff line number Diff line change
Expand Up @@ -157,17 +157,17 @@ let toReadQueryOptions = result => {
"variables": Js.Nullable.fromOption(Some(result##variables)),
};

external toOptimisticResult: 'a => Mutation.optimisticResult = "%identity";

/** 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 toQueryObj2 = (query, variables) =>
ApolloClient.{query: ApolloClient.gql(. query), 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},
);
11 changes: 5 additions & 6 deletions src/ApolloHooksClient.re
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type options('data);
external doMakeOptions:
(
~query: ReasonApolloTypes.queryString,
~variables: Js.Json.t=?,
~variables: 'raw_t_variables=?,
~notifyOnNetworkStatusChange: bool=?,
~fetchPolicy: string=?,
~errorPolicy: string=?,
Expand All @@ -27,12 +27,12 @@ external doMakeOptions:

let makeOptions =
(
~variables=?,
~variables: 'raw_t_variables=?,
~notifyOnNetworkStatusChange=?,
~fetchPolicy=?,
~errorPolicy=?,
~pollInterval=?,
(_, query, _): graphqlDefinition('data, _, _),
(_, query, _): graphqlDefinition('data, _),
) => {
doMakeOptions(
~query=gql(. query),
Expand All @@ -47,9 +47,8 @@ let makeOptions =

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

[@bs.module "../../../apolloClient"]
external client: ApolloClient.generatedApolloClient('raw_t) = "default";
external client: ApolloClient.t = "default";
70 changes: 38 additions & 32 deletions src/ApolloHooksMutation.re
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module Execution = {
};

type refetchQueries('raw_t) =
jsExecutionResult('raw_t) => array(ApolloClient.queryObj);
jsExecutionResult('raw_t) => array(ApolloClient.opaqueQueryObj);

/* The type that the promise returned by the mutate function resolves to */
type executionResult('a) = {
Expand All @@ -38,8 +38,6 @@ type controlledResult('t) = {
error: option(apolloError),
};

type optimisticResult;

/* The type of the 'simple' result returned by the hook */
type controlledVariantResult('t) =
| Loading
Expand All @@ -53,35 +51,34 @@ type controlledVariantResult('t) =
type mutationResult('raw_t) = {. "data": option('raw_t)};

[@bs.deriving abstract]
type options('raw_t) = {
type options('raw_t, 'raw_t_variables) = {
[@bs.optional]
variables: Js.Json.t,
variables: 'raw_t_variables,
[@bs.optional]
mutation: option(ReasonApolloTypes.queryString),
[@bs.optional]
client: ApolloClient.generatedApolloClient('raw_t),
client: ApolloClient.t,
[@bs.optional]
refetchQueries: Execution.refetchQueries('raw_t),
[@bs.optional]
awaitRefetchQueries: bool,
[@bs.optional]
update:
(ApolloClient.generatedApolloClient('raw_t), mutationResult('raw_t)) =>
unit,
update: (ApolloClient.t, mutationResult('raw_t)) => unit,
[@bs.optional]
optimisticResponse: optimisticResult,
optimisticResponse: 'raw_t,
};

type jsMutate('raw_t) =
(. options('raw_t)) => Js.Promise.t(Execution.jsExecutionResult('raw_t));
type jsMutate('raw_t, 'raw_t_variables) =
(. options('raw_t, 'raw_t_variables)) =>
Js.Promise.t(Execution.jsExecutionResult('raw_t));

type mutation('t, 'raw_t) =
type mutation('t, 'raw_t, 'raw_t_variables) =
(
~variables: Js.Json.t=?,
~client: ApolloClient.generatedApolloClient('raw_t)=?,
~variables: 'raw_t_variables=?,
~client: ApolloClient.t=?,
~refetchQueries: Execution.refetchQueries('raw_t)=?,
~awaitRefetchQueries: bool=?,
~optimisticResponse: optimisticResult=?,
~optimisticResponse: 't=?,
unit
) =>
Js.Promise.t(
Expand All @@ -90,36 +87,35 @@ type mutation('t, 'raw_t) =

[@bs.module "@apollo/client"]
external useMutationJs:
(. ReasonApolloTypes.queryString, options('raw_t)) =>
(jsMutate('raw_t), jsResult('raw_t)) =
(. ReasonApolloTypes.queryString, options('raw_t, 'raw_t_variables)) =>
(jsMutate('raw_t, 'raw_t_variables), jsResult('raw_t)) =
"useMutation";

exception Error(string);

let useMutation:
(
~client: ApolloClient.generatedApolloClient('raw_t)=?,
~variables: Js.Json.t=?,
~client: ApolloClient.t=?,
~variables: 'raw_t_variables=?,
~refetchQueries: Execution.refetchQueries('raw_t)=?,
~awaitRefetchQueries: bool=?,
~update: (
ApolloClient.generatedApolloClient('raw_t),
mutationResult('raw_t)
) =>
unit
=?,
~optimisticResponse: optimisticResult=?,
ApolloHooksTypes.graphqlDefinition('t, 'raw_t, _)
~update: (ApolloClient.t, mutationResult('raw_t)) => unit=?,
~optimisticResponse: 't=?,
ApolloHooksTypes.graphqlDefinition('t, 'raw_t)
) =>
(mutation('t, 'raw_t), controlledVariantResult('t), controlledResult('t)) =
(
mutation('t, 'raw_t, 'raw_t_variables),
controlledVariantResult('t),
controlledResult('t),
) =
(
~client=?,
~variables=?,
~refetchQueries=?,
~awaitRefetchQueries=?,
~update=?,
~optimisticResponse=?,
(parse, query, _),
(parse, query, serialize),
) => {
let (jsMutate, jsResult) =
useMutationJs(.
Expand All @@ -130,7 +126,12 @@ let useMutation:
~refetchQueries?,
~awaitRefetchQueries?,
~update?,
~optimisticResponse?,
~optimisticResponse=?
switch (optimisticResponse) {
| Some(optimisticResponse) =>
Some(serialize(optimisticResponse))
| None => None
},
(),
),
);
Expand All @@ -152,7 +153,12 @@ let useMutation:
~client?,
~refetchQueries?,
~awaitRefetchQueries?,
~optimisticResponse?,
~optimisticResponse=?
switch (optimisticResponse) {
| Some(optimisticResponse) =>
Some(serialize(optimisticResponse))
| None => None
},
(),
),
)
Expand Down
6 changes: 1 addition & 5 deletions src/ApolloHooksProvider.re
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
[@bs.module "@apollo/client"] [@react.component]
external make:
(
~client: ApolloClient.generatedApolloClient('raw_t),
~children: React.element
) =>
React.element =
(~client: ApolloClient.t, ~children: React.element) => React.element =
"ApolloProvider";
Loading