@@ -24,22 +24,31 @@ import com.apollographql.apollo3.api.ApolloResponse
2424import com.apollographql.apollo3.api.Mutation
2525import com.apollographql.apollo3.api.Operation
2626import com.apollographql.apollo3.api.Query
27+ import com.apollographql.apollo3.api.Subscription
28+ import com.apollographql.apollo3.api.http.HttpHeader
29+ import com.apollographql.apollo3.api.http.withHttpHeader
30+ import com.apollographql.apollo3.api.http.withHttpHeaders
2731import com.apollographql.apollo3.api.variables
2832import com.apollographql.apollo3.interceptor.ApolloInterceptor
2933import com.apollographql.apollo3.interceptor.ApolloInterceptorChain
34+ import com.apollographql.apollo3.network.NetworkTransport
3035import com.apollographql.apollo3.network.http.BearerTokenInterceptor
3136import com.apollographql.apollo3.network.http.HttpNetworkTransport
3237import com.apollographql.apollo3.network.http.TokenProvider
3338import com.apollographql.apollo3.network.ws.WebSocketNetworkTransport
3439import kotlinx.coroutines.CoroutineDispatcher
3540import kotlinx.coroutines.flow.Flow
3641import kotlinx.coroutines.flow.firstOrNull
42+ import kotlinx.coroutines.flow.flow
3743import kotlinx.coroutines.flow.map
44+ import kotlinx.coroutines.sync.Mutex
45+ import kotlinx.coroutines.sync.withLock
3846import tech.alexib.yaba.data.domain.AuthTokenProvider
3947import tech.alexib.yaba.data.domain.DataResult
4048import tech.alexib.yaba.data.domain.ErrorResult
4149import tech.alexib.yaba.data.domain.Success
42- import yaba.schema.type.Types
50+ import yaba.schema.type.LocalDate
51+ import yaba.schema.type.UUID
4352import kotlin.time.DurationUnit
4453import kotlin.time.measureTimedValue
4554
@@ -60,6 +69,15 @@ interface YabaApolloClient {
6069 mutationData : Mutation <T >,
6170 ): Flow <ApolloResponse <T >>
6271
72+ fun <T : Subscription .Data > subscribe (
73+ subscriptionData : Subscription <T >
74+ ): Flow <ApolloResponse <T >>
75+
76+ fun <T : Subscription .Data , R > subscribe (
77+ subscriptionData : Subscription <T >,
78+ mapper : (T ) -> R
79+ ): Flow <DataResult <R >>
80+
6381 class Impl (
6482 serverUrl : String ,
6583 log : Kermit ,
@@ -76,25 +94,39 @@ interface YabaApolloClient {
7694
7795 private val apolloClient: ApolloClient by lazy {
7896
97+ // val netTransport = HttpNetworkTransport(
98+ // serverUrl = serverUrl,
99+ //
100+ // interceptors = listOf(BearerTokenInterceptor(this))
101+ // )
102+ // val wsTransport = WebSocketNetworkTransport(
103+ // serverUrl = serverUrl.replace("graphql", "subscriptions").replace("http", "ws"),
104+ //
105+ // )
106+ // val netInterceptor = NetworkInterceptor(netTransport, wsTransport)
79107 ApolloClient (
80108 networkTransport = HttpNetworkTransport (
81109 serverUrl = serverUrl,
82- headers = mutableMapOf (
83- " Accept" to " application/json" ,
84- " Content-Type" to " application/json" ,
85- ),
110+
86111 interceptors = listOf (BearerTokenInterceptor (this ))
87112 ),
88113 subscriptionNetworkTransport = WebSocketNetworkTransport (
89- serverUrl = serverUrl,
114+ serverUrl = serverUrl.replace( " graphql " , " subscriptions " ).replace( " http " , " ws " ) ,
90115
91116 ),
92117 customScalarAdapters = customScalarTypeAdapters,
93118 interceptors = listOf (
94119 MyLoggingInterceptor (log)
95120 )
96- ).withCustomScalarAdapter(Types .UUID , uuidAdapter)
97- .withCustomScalarAdapter(Types .LocalDate , LocalDateAdapter )
121+ )
122+ .withCustomScalarAdapter(UUID .type, uuidAdapter)
123+ .withCustomScalarAdapter(LocalDate .type, LocalDateAdapter )
124+ .withHttpHeaders(
125+ listOf (
126+ HttpHeader (" Accept" , " application/json" ),
127+ HttpHeader (" Content-Type" , " application/json" )
128+ )
129+ )
98130 }
99131
100132 override suspend fun currentToken (): String = authTokenProvider.token().firstOrNull() ? : " "
@@ -119,6 +151,19 @@ interface YabaApolloClient {
119151 return apolloClient.mutateAsFlow(ApolloRequest (mutationData))
120152 }
121153
154+ override fun <T : Subscription .Data > subscribe (
155+ subscriptionData : Subscription <T >
156+ ): Flow <ApolloResponse <T >> = apolloClient.subscribe(
157+ ApolloRequest (subscriptionData)
158+ )
159+
160+ override fun <T : Subscription .Data , R > subscribe (
161+ subscriptionData : Subscription <T >,
162+ mapper : (T ) -> R
163+ ): Flow <DataResult <R >> = apolloClient.subscribe(
164+ ApolloRequest (subscriptionData)
165+ ).map(checkResponse(mapper))
166+
122167 private fun <T : Operation .Data , R > checkResponse (mapper : (T ) -> R ): suspend (
123168 ApolloResponse <T >
124169 ) ->
@@ -157,3 +202,30 @@ internal class MyLoggingInterceptor(private val log: Kermit) : ApolloInterceptor
157202 return response
158203 }
159204}
205+
206+ class NInt (
207+ private val networkTransport : NetworkTransport ,
208+ private val subscriptionNetworkTransport : NetworkTransport ,
209+ private val tokenProvider : TokenProvider
210+ ) : ApolloInterceptor {
211+ private val mutex = Mutex ()
212+ override fun <D : Operation .Data > intercept (
213+ request : ApolloRequest <D >,
214+ chain : ApolloInterceptorChain
215+ ): Flow <ApolloResponse <D >> {
216+
217+ return flow {
218+ val token = mutex.withLock { tokenProvider.currentToken() }
219+ when (request.operation) {
220+ is Query <* > -> networkTransport.execute(request = request)
221+ is Mutation <* > -> networkTransport.execute(request = request)
222+ is Subscription <* > -> subscriptionNetworkTransport.execute(
223+ request = request.withHttpHeader(
224+ HttpHeader (" Authorization" , " Bearer $token " )
225+ )
226+ )
227+ else -> error(" " )
228+ }
229+ }
230+ }
231+ }
0 commit comments