tauri-plugin-graphql
tauri-plugin-graphql copied to clipboard
Links for `@apollo/client`
I wanted to use urql, but due to the lack of useLazyQuery
, wanted to reach for Apollo. Not sure if I will end up using it, but I needed to write some links for it to work, so here you go.
There's two versions:
ApolloLink
This one uses ApolloLink
, which as far as I can tell, is the lowest level of these things.
import { ApolloLink, FetchResult, fromPromise } from '@apollo/client'
import { invoke } from '@tauri-apps/api/tauri'
import { GraphQLError, print } from 'graphql'
const tauriGraphqlApolloLink = new ApolloLink((operation) => {
return fromPromise(
invoke<[string, boolean]>('plugin:graphql|graphql', {
query: print(operation.query),
variables: operation.variables,
})
.then(([responseStr]) => {
const parsed = JSON.parse(responseStr)
return {
data: parsed.data,
errors: parsed.errors,
}
})
.catch((err) => {
return {
errors: [new GraphQLError(String(err))],
context: operation.getContext(),
}
}),
)
})
export default tauriGraphqlApolloLink
HttpLink
This one uses HttpLink
, but replaces fetch
with something that just calls invoke
from tauri.
I'm sure it's "slower", because we need to call JSON.parse
to get an object to pass to tauri-plugin-graphql along with the JSON.parse
that surely happens later on in HttpLink
.
But, @apollo/client
does seem to set the abort signal, and this uses it. So it might have some UX considerations that tauriGraphqlApolloLink
doesn't.
import { createHttpLink } from '@apollo/client'
import { invoke } from '@tauri-apps/api/tauri'
const tauriGraphqlHttpLink = createHttpLink({
fetch: async (_input, init) => {
const [responseStr, isOk] = await invoke<[string, boolean]>(
'plugin:graphql|graphql',
JSON.parse(String(init?.body)),
)
init?.signal?.throwIfAborted()
return new Response(responseStr, {
status: isOk ? 200 : 400,
})
},
})
export default tauriGraphqlHttpLink