feat: add subscription support for useGQLQuery
This commit is contained in:
@@ -18,11 +18,13 @@ import {
|
|||||||
makeOperation,
|
makeOperation,
|
||||||
GraphQLRequest,
|
GraphQLRequest,
|
||||||
createRequest,
|
createRequest,
|
||||||
|
subscriptionExchange,
|
||||||
} from "@urql/core"
|
} from "@urql/core"
|
||||||
import { authExchange } from "@urql/exchange-auth"
|
import { authExchange } from "@urql/exchange-auth"
|
||||||
import { offlineExchange } from "@urql/exchange-graphcache"
|
import { offlineExchange } from "@urql/exchange-graphcache"
|
||||||
import { makeDefaultStorage } from "@urql/exchange-graphcache/default-storage"
|
import { makeDefaultStorage } from "@urql/exchange-graphcache/default-storage"
|
||||||
import { devtoolsExchange } from "@urql/devtools"
|
import { devtoolsExchange } from "@urql/devtools"
|
||||||
|
import { SubscriptionClient } from "subscriptions-transport-ws"
|
||||||
import * as E from "fp-ts/Either"
|
import * as E from "fp-ts/Either"
|
||||||
import * as TE from "fp-ts/TaskEither"
|
import * as TE from "fp-ts/TaskEither"
|
||||||
import { pipe, constVoid } from "fp-ts/function"
|
import { pipe, constVoid } from "fp-ts/function"
|
||||||
@@ -33,13 +35,14 @@ import { updatesDef } from "./caching/updates"
|
|||||||
import { resolversDef } from "./caching/resolvers"
|
import { resolversDef } from "./caching/resolvers"
|
||||||
import schema from "./backend-schema.json"
|
import schema from "./backend-schema.json"
|
||||||
import {
|
import {
|
||||||
|
authIdToken$,
|
||||||
getAuthIDToken,
|
getAuthIDToken,
|
||||||
probableUser$,
|
probableUser$,
|
||||||
waitProbableLoginToConfirm,
|
waitProbableLoginToConfirm,
|
||||||
} from "~/helpers/fb/auth"
|
} from "~/helpers/fb/auth"
|
||||||
|
|
||||||
const BACKEND_GQL_URL =
|
const BACKEND_GQL_URL =
|
||||||
process.env.CONTEXT === "production"
|
process.env.context === "production"
|
||||||
? "https://api.hoppscotch.io/graphql"
|
? "https://api.hoppscotch.io/graphql"
|
||||||
: "https://api.hoppscotch.io/graphql"
|
: "https://api.hoppscotch.io/graphql"
|
||||||
|
|
||||||
@@ -48,6 +51,18 @@ const storage = makeDefaultStorage({
|
|||||||
maxAge: 7,
|
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({
|
export const client = createClient({
|
||||||
url: BACKEND_GQL_URL,
|
url: BACKEND_GQL_URL,
|
||||||
exchanges: [
|
exchanges: [
|
||||||
@@ -97,6 +112,9 @@ export const client = createClient({
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
fetchExchange,
|
fetchExchange,
|
||||||
|
subscriptionExchange({
|
||||||
|
forwardSubscription: (operation) => subscriptionClient.request(operation),
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -106,6 +124,7 @@ type UseQueryOptions<T = any, V = object> = {
|
|||||||
query: TypedDocumentNode<T, V>
|
query: TypedDocumentNode<T, V>
|
||||||
variables?: MaybeRef<V>
|
variables?: MaybeRef<V>
|
||||||
|
|
||||||
|
updateSubs?: MaybeRef<GraphQLRequest<any, object>[]>
|
||||||
defer?: boolean
|
defer?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,6 +152,8 @@ export const useGQLQuery = <DocType, DocVarType, DocErrorType extends string>(
|
|||||||
const isStale: Ref<boolean> = ref(true)
|
const isStale: Ref<boolean> = ref(true)
|
||||||
const data: Ref<E.Either<GQLError<DocErrorType>, DocType>> = ref() as any
|
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 isPaused: Ref<boolean> = ref(args.defer ?? false)
|
||||||
|
|
||||||
const request: Ref<GraphQLRequest<DocType, DocVarType>> = ref(
|
const request: Ref<GraphQLRequest<DocType, DocVarType>> = ref(
|
||||||
@@ -178,7 +199,22 @@ export const useGQLQuery = <DocType, DocVarType, DocErrorType extends string>(
|
|||||||
loading.value = true
|
loading.value = true
|
||||||
isStale.value = false
|
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(
|
wonkaPipe(
|
||||||
source.value,
|
source.value,
|
||||||
onEnd(() => {
|
onEnd(() => {
|
||||||
@@ -220,6 +256,8 @@ export const useGQLQuery = <DocType, DocVarType, DocErrorType extends string>(
|
|||||||
})
|
})
|
||||||
).unsubscribe
|
).unsubscribe
|
||||||
)
|
)
|
||||||
|
|
||||||
|
onInvalidate(() => invalidateStops.forEach((unsub) => unsub()))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,44 @@
|
|||||||
import { GraphCacheUpdaters, MyTeamsDocument } from "../graphql"
|
import { GraphCacheUpdaters, MyTeamsDocument } from "../graphql"
|
||||||
|
|
||||||
export const updatesDef: GraphCacheUpdaters = {
|
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: {
|
Mutation: {
|
||||||
deleteTeam: (_r, { teamID }, cache, _info) => {
|
deleteTeam: (_r, { teamID }, cache, _info) => {
|
||||||
cache.updateQuery(
|
cache.updateQuery(
|
||||||
|
|||||||
@@ -70,6 +70,7 @@
|
|||||||
"socket.io-client": "^4.2.0",
|
"socket.io-client": "^4.2.0",
|
||||||
"socketio-wildcard": "^2.0.0",
|
"socketio-wildcard": "^2.0.0",
|
||||||
"splitpanes": "^2.3.8",
|
"splitpanes": "^2.3.8",
|
||||||
|
"subscriptions-transport-ws": "^0.9.19",
|
||||||
"tern": "^0.24.3",
|
"tern": "^0.24.3",
|
||||||
"vue-apollo": "^3.0.8",
|
"vue-apollo": "^3.0.8",
|
||||||
"vue-cli-plugin-apollo": "^0.22.2",
|
"vue-cli-plugin-apollo": "^0.22.2",
|
||||||
|
|||||||
37
pnpm-lock.yaml
generated
37
pnpm-lock.yaml
generated
@@ -105,6 +105,7 @@ importers:
|
|||||||
stylelint: ^13.13.1
|
stylelint: ^13.13.1
|
||||||
stylelint-config-prettier: ^8.0.2
|
stylelint-config-prettier: ^8.0.2
|
||||||
stylelint-config-standard: ^22.0.0
|
stylelint-config-standard: ^22.0.0
|
||||||
|
subscriptions-transport-ws: ^0.9.19
|
||||||
tern: ^0.24.3
|
tern: ^0.24.3
|
||||||
ts-jest: ^27.0.5
|
ts-jest: ^27.0.5
|
||||||
typescript: ^4.4.3
|
typescript: ^4.4.3
|
||||||
@@ -121,7 +122,7 @@ importers:
|
|||||||
worker-loader: ^3.0.8
|
worker-loader: ^3.0.8
|
||||||
yargs-parser: ^20.2.9
|
yargs-parser: ^20.2.9
|
||||||
dependencies:
|
dependencies:
|
||||||
'@apollo/client': 3.4.16_graphql@15.6.1
|
'@apollo/client': 3.4.16_9725b5bd6f8ccdf8972896e366c3daff
|
||||||
'@hoppscotch/js-sandbox': link:../hoppscotch-js-sandbox
|
'@hoppscotch/js-sandbox': link:../hoppscotch-js-sandbox
|
||||||
'@nuxtjs/axios': 5.13.6
|
'@nuxtjs/axios': 5.13.6
|
||||||
'@nuxtjs/composition-api': 0.29.2_nuxt@2.15.8
|
'@nuxtjs/composition-api': 0.29.2_nuxt@2.15.8
|
||||||
@@ -158,6 +159,7 @@ importers:
|
|||||||
socket.io-client: 4.2.0
|
socket.io-client: 4.2.0
|
||||||
socketio-wildcard: 2.0.0
|
socketio-wildcard: 2.0.0
|
||||||
splitpanes: 2.3.8
|
splitpanes: 2.3.8
|
||||||
|
subscriptions-transport-ws: 0.9.19_graphql@15.6.1
|
||||||
tern: 0.24.3
|
tern: 0.24.3
|
||||||
vue-apollo: 3.0.8_graphql-tag@2.12.5
|
vue-apollo: 3.0.8_graphql-tag@2.12.5
|
||||||
vue-cli-plugin-apollo: 0.22.2_typescript@4.4.3
|
vue-cli-plugin-apollo: 0.22.2_typescript@4.4.3
|
||||||
@@ -310,33 +312,6 @@ packages:
|
|||||||
zen-observable-ts: 1.1.0
|
zen-observable-ts: 1.1.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@apollo/client/3.4.16_graphql@15.6.1:
|
|
||||||
resolution: {integrity: sha512-iF4zEYwvebkri0BZQyv8zfavPfVEafsK0wkOofa6eC2yZu50J18uTutKtC174rjHZ2eyxZ8tV7NvAPKRT+OtZw==}
|
|
||||||
peerDependencies:
|
|
||||||
graphql: ^14.0.0 || ^15.0.0
|
|
||||||
react: ^16.8.0 || ^17.0.0
|
|
||||||
subscriptions-transport-ws: ^0.9.0
|
|
||||||
peerDependenciesMeta:
|
|
||||||
react:
|
|
||||||
optional: true
|
|
||||||
subscriptions-transport-ws:
|
|
||||||
optional: true
|
|
||||||
dependencies:
|
|
||||||
'@graphql-typed-document-node/core': 3.1.0_graphql@15.6.1
|
|
||||||
'@wry/context': 0.6.1
|
|
||||||
'@wry/equality': 0.5.2
|
|
||||||
'@wry/trie': 0.3.1
|
|
||||||
graphql: 15.6.1
|
|
||||||
graphql-tag: 2.12.5_graphql@15.6.1
|
|
||||||
hoist-non-react-statics: 3.3.2
|
|
||||||
optimism: 0.16.1
|
|
||||||
prop-types: 15.7.2
|
|
||||||
symbol-observable: 4.0.0
|
|
||||||
ts-invariant: 0.9.3
|
|
||||||
tslib: 2.3.1
|
|
||||||
zen-observable-ts: 1.1.0
|
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@apollo/federation/0.27.0_graphql@15.6.1:
|
/@apollo/federation/0.27.0_graphql@15.6.1:
|
||||||
resolution: {integrity: sha512-hMeRN9IPsIn+5J5SmWof0ODbvRjRj8mBNqbsm9Zjkqjbw6RTlcx90taMk7cYhcd/E+uTyLQt5cOSRVBx53cxbQ==}
|
resolution: {integrity: sha512-hMeRN9IPsIn+5J5SmWof0ODbvRjRj8mBNqbsm9Zjkqjbw6RTlcx90taMk7cYhcd/E+uTyLQt5cOSRVBx53cxbQ==}
|
||||||
engines: {node: '>=12.13.0 <17.0'}
|
engines: {node: '>=12.13.0 <17.0'}
|
||||||
@@ -3058,7 +3033,7 @@ packages:
|
|||||||
form-data: 4.0.0
|
form-data: 4.0.0
|
||||||
graphql: 15.6.1
|
graphql: 15.6.1
|
||||||
graphql-sse: 1.0.4_graphql@15.6.1
|
graphql-sse: 1.0.4_graphql@15.6.1
|
||||||
graphql-ws: 5.5.0_graphql@15.6.1
|
graphql-ws: 5.5.3_graphql@15.6.1
|
||||||
is-promise: 4.0.0
|
is-promise: 4.0.0
|
||||||
isomorphic-ws: 4.0.1_ws@8.2.2
|
isomorphic-ws: 4.0.1_ws@8.2.2
|
||||||
lodash: 4.17.21
|
lodash: 4.17.21
|
||||||
@@ -10432,8 +10407,8 @@ packages:
|
|||||||
graphql: 15.6.1
|
graphql: 15.6.1
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/graphql-ws/5.5.0_graphql@15.6.1:
|
/graphql-ws/5.5.3_graphql@15.6.1:
|
||||||
resolution: {integrity: sha512-WQepPMGQQoqS2VsrI2I3RMLCVz3CW4/6ZqGV6ABDOwH4R62DzjxwMlwZbj6vhSI/7IM3/C911yITwgs77iO/hw==}
|
resolution: {integrity: sha512-Okp3gE3vq9OoeqsYVbmzKvPcvlinKNXrfVajH7D3ul1UdCg2+K2zVYbWKmqxehkAZ+GKVfngK5fzyXSsfpe+pA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
graphql: '>=0.11 <=16'
|
graphql: '>=0.11 <=16'
|
||||||
|
|||||||
Reference in New Issue
Block a user