-
Notifications
You must be signed in to change notification settings - Fork 28
Apollo Client 3 Mirroring Exploration #122
Changes from 2 commits
0204b18
0931654
d2e7695
8f82251
b0b09c8
de4d6c3
7c6b257
98675f9
4a69308
7d8fe73
2becb05
872bd30
f03c39f
1a43e5a
9bae5fa
9fdb1ad
12519f1
1d7f963
4a07aa3
e050eab
9ee3077
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// export { default as Observable } from 'zen-observable'; | ||
// export { isReference, makeReference } from './utilities/graphql/storeUtils.js'; | ||
// export { ApolloLink } from './link/core/ApolloLink.js'; | ||
// export { execute } from './link/core/execute.js'; | ||
// export { ApolloError, isApolloError } from './errors/ApolloError.js'; | ||
// export { NetworkStatus } from './core/networkStatus.js'; | ||
// export { FetchType } from './core/types.js'; | ||
// export { ObservableQuery } from './core/ObservableQuery.js'; | ||
// export { serializeFetchParameter } from './link/http/serializeFetchParameter.js'; | ||
// export { selectURI } from './link/http/selectURI.js'; | ||
// export { throwServerError } from './link/utils/throwServerError.js'; | ||
// export { parseAndCheckHttpResponse } from './link/http/parseAndCheckHttpResponse.js'; | ||
// export { checkFetcher } from './link/http/checkFetcher.js'; | ||
// export { fallbackHttpConfig, selectHttpOptionsAndBody } from './link/http/selectHttpOptionsAndBody.js'; | ||
// export { createSignalIfSupported } from './link/http/createSignalIfSupported.js'; | ||
// export { fromError } from './link/utils/fromError.js'; | ||
// export { createHttpLink } from './link/http/createHttpLink.js'; | ||
// export { HttpLink } from './link/http/HttpLink.js'; | ||
// export { ApolloClient } from './ApolloClient.js'; | ||
// export { ApolloCache } from './cache/core/cache.js'; | ||
// export { Cache } from './cache/core/types/Cache.js'; | ||
// export { MissingFieldError } from './cache/core/types/common.js'; | ||
// export { defaultDataIdFromObject } from './cache/inmemory/policies.js'; | ||
// export { InMemoryCache } from './cache/inmemory/inMemoryCache.js'; | ||
// export { empty } from './link/core/empty.js'; | ||
// export { from } from './link/core/from.js'; | ||
// export { split } from './link/core/split.js'; | ||
// export { concat } from './link/core/concat.js'; | ||
// export { toPromise } from './link/utils/toPromise.js'; | ||
// export { fromPromise } from './link/utils/fromPromise.js'; | ||
// export { disableExperimentalFragmentVariables, disableFragmentWarnings, enableExperimentalFragmentVariables, resetCaches } from './core/index.js'; | ||
// export { getApolloContext, resetApolloContext } from './react/context/ApolloContext.js'; | ||
// export { ApolloProvider } from './react/context/ApolloProvider.js'; | ||
// export { ApolloConsumer } from './react/context/ApolloConsumer.js'; | ||
// export { DocumentType, operationName, parser } from './react/parser/parser.js'; | ||
// export { useLazyQuery } from './react/hooks/useLazyQuery.js'; | ||
// export { useMutation } from './react/hooks/useMutation.js'; | ||
// export { useSubscription } from './react/hooks/useSubscription.js'; | ||
// export { useApolloClient } from './react/hooks/useApolloClient.js'; | ||
// export { RenderPromises } from './react/ssr/RenderPromises.js'; | ||
|
||
let useQuery = Apollo_Client__React_UseQuery.useQuery; | ||
|
||
let gql = Apollo_Client__GraphqlTag.gql; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
type t; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
type parse('raw_t, 't) = 'raw_t => 't; | ||
type serialize('t, 'raw_t) = 't => 'raw_t; | ||
type query = string; | ||
|
||
type graphqlDefinition('t, 'raw_t) = ( | ||
parse('raw_t, 't), | ||
query, | ||
serialize('t, 'raw_t), | ||
); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
let useGuaranteedMemo1 = (f, dependency) => { | ||
let value = React.useRef(f()); | ||
let previousDependency = React.useRef(dependency); | ||
|
||
if (dependency !== previousDependency->React.Ref.current) { | ||
value->React.Ref.setCurrent(f()); | ||
previousDependency->React.Ref.setCurrent(dependency); | ||
}; | ||
|
||
value->React.Ref.current; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[@bs.module "graphql-tag"] | ||
external gql: string => Apollo_Client__Graphql_Language.documentNode = | ||
"default"; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
module Error = Apollo_Client__Graphql_Error; | ||
module GraphQLError = Apollo_Client__Graphql_Error_GraphQLError; | ||
module Language = Apollo_Client__Graphql_Language; | ||
module Location = Apollo_Client__Graphql_Location; | ||
|
||
type documentNode; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module GraphQLError = Apollo_Client__Graphql_Error_GraphQLError; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
module Graphql_Location = Apollo_Client__Graphql_Location; | ||
|
||
type t = { | ||
message: string, | ||
locations: Js.nullable(array(Graphql_Location.sourceLocation)), | ||
// Union? https://bucklescript.github.io/blog/2020/02/07/union-types-in-bucklescript | ||
path: Js.nullable(array(string)) // ACTUAL: string | number | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
type documentNode; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
type sourceLocation = { | ||
line: int, | ||
column: int, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module NetworkStatus = Apollo_Client__Core_NetworkStatus; | ||
module Types = Apollo_Client__Core_Types; | ||
module WatchQueryOptions = Apollo_Client__Core_WatchQueryOptions; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
type t = | ||
| Loading | ||
| SetVariables | ||
| FetchMore | ||
| Refetch | ||
| Poll | ||
| Ready | ||
| Error | ||
| Unknown; | ||
|
||
let fromRaw = | ||
fun | ||
| 1 => Loading | ||
| 2 => SetVariables | ||
| 3 => FetchMore | ||
| 4 => Refetch | ||
| 6 => Poll | ||
| 7 => Ready | ||
| 8 => Error | ||
| _ => Unknown; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
module Graphql = Apollo_Client__Graphql; | ||
|
||
module ApolloQueryResult = { | ||
module Raw = { | ||
type t('raw_tData) = { | ||
data: Js.nullable('raw_tData), | ||
errors: Js.nullable(array(Graphql.Error.GraphQLError.t)), | ||
loading: bool, | ||
networkStatus: int, | ||
}; | ||
}; | ||
|
||
type t('tData) = { | ||
data: option('tData), | ||
errors: option(array(Graphql.Error.GraphQLError.t)), | ||
loading: bool, | ||
networkStatus: int, | ||
}; | ||
|
||
let fromRaw = | ||
({data, errors, loading, networkStatus}: Raw.t('raw_tData), ~parse) => { | ||
data: data->Js.toOption->Belt.Option.map(parse), | ||
errors: errors->Js.toOption, | ||
loading, | ||
networkStatus, | ||
}; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
module ErrorPolicy = { | ||
type t = | ||
| None | ||
| Ignore | ||
| All; | ||
|
||
let toRaw = | ||
fun | ||
| None => "none" | ||
| Ignore => "ignore" | ||
| All => "all"; | ||
}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I usually prefer to use bs.deriving for this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice! I prefer this as well, but for some reason I thought There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, nevermind, I got excited and misread the docs. You do indeed need polymorphic variants, but it sounds like that's the direction we want to go (and I agree), so I'll still make the switch. |
||
|
||
module WatchQueryFetchPolicy = { | ||
type t = | ||
| CacheAndNetwork | ||
// ...extends FetchPolicy | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what this means? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's just saying that in typescript |
||
| CacheFirst | ||
| NetworkOnly | ||
| CacheOnly | ||
| NoCache | ||
| Standby; | ||
|
||
let toRaw = | ||
fun | ||
| CacheFirst => "cache-first" | ||
| CacheAndNetwork => "cache-and-network" | ||
| NetworkOnly => "network-only" | ||
| CacheOnly => "cache-only" | ||
| NoCache => "no-cache" | ||
| Standby => "standby"; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
module Graphql = Apollo_Client__Graphql; | ||
|
||
module ApolloError = { | ||
type t = { | ||
extraInfo: Js.Json.t, | ||
graphQLErrors: array(Graphql.Error.GraphQLError.t), | ||
networkError: Js.nullable(Js.Exn.t), | ||
// ...extends Error | ||
name: string, | ||
message: string, | ||
stack: option(string), | ||
}; | ||
// type errorOptions ={ graphQLErrors, networkError, errorMessage, extraInfo}; | ||
// [@bs.new] [@bs.module "@apollo/client"] | ||
// external make: errorOptions => t = "ApolloError"; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
module Types = Apollo_Client__React_Types; | ||
let useQuery = Apollo_Client__React_UseQuery.useQuery; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
module Core = Apollo_Client__Core; | ||
module Errors = Apollo_Client__Errors; | ||
module Graphql = Apollo_Client__Graphql; | ||
module GraphqlTag = Apollo_Client__GraphqlTag; | ||
module React_Types = Apollo_Client__React_Types; | ||
|
||
type simpleQueryResult('a) = | ||
| Data('a) | ||
| Error(Errors.ApolloError.t) | ||
| Loading | ||
| NoData; | ||
|
||
module Raw = { | ||
[@bs.module "@apollo/client"] | ||
external useQuery: | ||
( | ||
~query: Graphql.Language.documentNode, | ||
~options: React_Types.QueryHookOptions.t('raw_tData, 'raw_tVariables)=? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed. |
||
) => | ||
React_Types.QueryResult.Raw.t('raw_tData, 'raw_tVariables) = | ||
"useQuery"; | ||
}; | ||
|
||
let useQuery: | ||
( | ||
~client: Apollo_Client__ApolloClient.t=?, | ||
~context: Js.Json.t=?, | ||
~displayName: string=?, | ||
~errorPolicy: Core.WatchQueryOptions.ErrorPolicy.t=?, | ||
~fetchPolicy: Core.WatchQueryOptions.WatchQueryFetchPolicy.t=?, | ||
~notifyOnNetworkStatusChange: bool=?, | ||
~onCompleted: 'raw_tData => unit=?, | ||
~onError: Errors.ApolloError.t => unit=?, | ||
~partialRefetch: bool=?, | ||
~pollInterval: int=?, | ||
~skip: bool=?, | ||
~ssr: bool=?, | ||
~variables: 'raw_tVariables=?, | ||
Apollo_Client__Types.graphqlDefinition('tData, 'raw_tData) | ||
) => | ||
( | ||
simpleQueryResult('tData), | ||
React_Types.QueryResult.t('tData, 'raw_tVariables), | ||
) = | ||
( | ||
~client=?, | ||
~context=?, | ||
~displayName=?, | ||
~errorPolicy=?, | ||
~fetchPolicy=?, | ||
~notifyOnNetworkStatusChange=?, | ||
~onCompleted=?, | ||
~onError=?, | ||
~partialRefetch=?, | ||
~pollInterval=?, | ||
~skip=?, | ||
~ssr=?, | ||
~variables=?, | ||
(parse, query, serialize), | ||
) => { | ||
let jsQueryResult = | ||
Raw.useQuery( | ||
~query=GraphqlTag.gql(query), | ||
~options={ | ||
client, | ||
context, | ||
displayName, | ||
errorPolicy, | ||
fetchPolicy, | ||
onCompleted, | ||
onError, | ||
notifyOnNetworkStatusChange, | ||
partialRefetch, | ||
pollInterval, | ||
query: None, | ||
skip, | ||
ssr, | ||
variables, | ||
}, | ||
); | ||
|
||
Apollo_Client__Utils.useGuaranteedMemo1( | ||
() => { | ||
let queryResult = | ||
jsQueryResult->React_Types.QueryResult.fromRaw(~parse, ~serialize); | ||
|
||
let simple = | ||
switch (queryResult) { | ||
| {loading: true} => Loading | ||
| {error: Some(error)} => Error(error) | ||
| {data: Some(data)} => Data(data) | ||
| _ => NoData | ||
}; | ||
|
||
(simple, queryResult); | ||
}, | ||
jsQueryResult, | ||
); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this also would be called JS type right? maybe we could add some comments explaining a bit more to help future contributors
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. This would be
JS
orJs_
. Now that you bring this up, I think it's possible it would be clearer to future contributors if there was a clear 1:1Bindings
module rather than mixing this stuff, but who know. I'll try a branch off this PR and see if people like that direction.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Re: explaining a bit more to help future contributors, I think a
CONTRIBUTING.md
with some explanation of patterns used might be a good goal. https://help.github.com/en/github/building-a-strong-community/setting-guidelines-for-repository-contributors