feat: add subscription support for useGQLQuery

This commit is contained in:
Andrew Bastin
2021-10-27 22:41:32 +05:30
parent 4b0d7a6c3d
commit ddd29374ea
4 changed files with 85 additions and 33 deletions

View File

@@ -18,11 +18,13 @@ import {
makeOperation,
GraphQLRequest,
createRequest,
subscriptionExchange,
} from "@urql/core"
import { authExchange } from "@urql/exchange-auth"
import { offlineExchange } from "@urql/exchange-graphcache"
import { makeDefaultStorage } from "@urql/exchange-graphcache/default-storage"
import { devtoolsExchange } from "@urql/devtools"
import { SubscriptionClient } from "subscriptions-transport-ws"
import * as E from "fp-ts/Either"
import * as TE from "fp-ts/TaskEither"
import { pipe, constVoid } from "fp-ts/function"
@@ -33,13 +35,14 @@ import { updatesDef } from "./caching/updates"
import { resolversDef } from "./caching/resolvers"
import schema from "./backend-schema.json"
import {
authIdToken$,
getAuthIDToken,
probableUser$,
waitProbableLoginToConfirm,
} from "~/helpers/fb/auth"
const BACKEND_GQL_URL =
process.env.CONTEXT === "production"
process.env.context === "production"
? "https://api.hoppscotch.io/graphql"
: "https://api.hoppscotch.io/graphql"
@@ -48,6 +51,18 @@ const storage = makeDefaultStorage({
maxAge: 7,
})
const subscriptionClient = new SubscriptionClient(
process.env.context === "production"
? "wss://api.hoppscotch.io/graphql"
: "wss://api.hoppscotch.io/graphql",
{
reconnect: true,
connectionParams: () => ({
authorization: `Bearer ${authIdToken$.value}`,
}),
}
)
export const client = createClient({
url: BACKEND_GQL_URL,
exchanges: [
@@ -97,6 +112,9 @@ export const client = createClient({
},
}),
fetchExchange,
subscriptionExchange({
forwardSubscription: (operation) => subscriptionClient.request(operation),
}),
],
})
@@ -106,6 +124,7 @@ type UseQueryOptions<T = any, V = object> = {
query: TypedDocumentNode<T, V>
variables?: MaybeRef<V>
updateSubs?: MaybeRef<GraphQLRequest<any, object>[]>
defer?: boolean
}
@@ -133,6 +152,8 @@ export const useGQLQuery = <DocType, DocVarType, DocErrorType extends string>(
const isStale: Ref<boolean> = ref(true)
const data: Ref<E.Either<GQLError<DocErrorType>, DocType>> = ref() as any
if (!args.updateSubs) set(args, "updateSubs", [])
const isPaused: Ref<boolean> = ref(args.defer ?? false)
const request: Ref<GraphQLRequest<DocType, DocVarType>> = ref(
@@ -178,7 +199,22 @@ export const useGQLQuery = <DocType, DocVarType, DocErrorType extends string>(
loading.value = true
isStale.value = false
onInvalidate(
const invalidateStops = args.updateSubs!.map((sub) => {
console.log("create sub")
return wonkaPipe(
client.executeSubscription(sub),
onEnd(() => {
if (source.value) execute()
}),
subscribe(() => {
console.log("invalidate!")
return execute()
})
).unsubscribe
})
invalidateStops.push(
wonkaPipe(
source.value,
onEnd(() => {
@@ -220,6 +256,8 @@ export const useGQLQuery = <DocType, DocVarType, DocErrorType extends string>(
})
).unsubscribe
)
onInvalidate(() => invalidateStops.forEach((unsub) => unsub()))
}
})

View File

@@ -1,6 +1,44 @@
import { GraphCacheUpdaters, MyTeamsDocument } from "../graphql"
export const updatesDef: GraphCacheUpdaters = {
Subscription: {
teamMemberAdded: (_r, { teamID }, cache, _info) => {
debugger
cache.invalidate(
{
__typename: "Team",
id: teamID,
},
"teamMembers"
)
},
teamMemberUpdated: (_r, { teamID }, cache, _info) => {
cache.invalidate(
{
__typename: "Team",
id: teamID,
},
"teamMembers"
)
cache.invalidate(
{
__typename: "Team",
id: teamID,
},
"myRole"
)
},
teamMemberRemoved: (_r, { teamID }, cache, _info) => {
cache.invalidate(
{
__typename: "Team",
id: teamID,
},
"teamMembers"
)
},
},
Mutation: {
deleteTeam: (_r, { teamID }, cache, _info) => {
cache.updateQuery(

View File

@@ -70,6 +70,7 @@
"socket.io-client": "^4.2.0",
"socketio-wildcard": "^2.0.0",
"splitpanes": "^2.3.8",
"subscriptions-transport-ws": "^0.9.19",
"tern": "^0.24.3",
"vue-apollo": "^3.0.8",
"vue-cli-plugin-apollo": "^0.22.2",