|
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
|
|
ObservableSubscription,
|
|
|
|
|
TypedDocumentNode,
|
|
|
|
|
ApolloError,
|
|
|
|
|
NetworkStatus
|
|
|
|
|
} from '@apollo/client/core'
|
|
|
|
|
import { throttle, debounce } from 'throttle-debounce'
|
|
|
|
|
import { useApolloClient } from './useApolloClient'
|
|
|
|
@@ -170,45 +171,20 @@ export function useQueryImpl<
|
|
|
|
|
|
|
|
|
|
// SSR
|
|
|
|
|
let firstResolve: (() => void) | undefined
|
|
|
|
|
let firstResolveTriggered = false
|
|
|
|
|
let firstReject: ((apolloError: ApolloError) => void) | undefined
|
|
|
|
|
let firstRejectError: undefined | ApolloError
|
|
|
|
|
|
|
|
|
|
const tryFirstResolve = () => {
|
|
|
|
|
firstResolveTriggered = true
|
|
|
|
|
if (firstResolve) firstResolve()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const tryFirstReject = (apolloError: ApolloError) => {
|
|
|
|
|
firstRejectError = apolloError
|
|
|
|
|
if (firstReject) firstReject(apolloError)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const resetFirstResolveReject = () => {
|
|
|
|
|
firstResolve = undefined
|
|
|
|
|
firstReject = undefined
|
|
|
|
|
firstResolveTriggered = false
|
|
|
|
|
firstRejectError = undefined
|
|
|
|
|
stop()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vm && onServerPrefetch?.(() => {
|
|
|
|
|
if (!isEnabled.value || (isServer && currentOptions.value?.prefetch === false)) return
|
|
|
|
|
|
|
|
|
|
return new Promise<void>((resolve, reject) => {
|
|
|
|
|
firstResolve = () => {
|
|
|
|
|
resetFirstResolveReject()
|
|
|
|
|
resolve()
|
|
|
|
|
firstResolve = undefined
|
|
|
|
|
firstReject = undefined
|
|
|
|
|
}
|
|
|
|
|
firstReject = (apolloError: ApolloError) => {
|
|
|
|
|
resetFirstResolveReject()
|
|
|
|
|
reject(apolloError)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (firstResolveTriggered) {
|
|
|
|
|
firstResolve()
|
|
|
|
|
} else if (firstRejectError) {
|
|
|
|
|
firstReject(firstRejectError)
|
|
|
|
|
firstResolve = undefined
|
|
|
|
|
firstReject = undefined
|
|
|
|
|
}
|
|
|
|
|
}).then(stop).catch(stop)
|
|
|
|
|
})
|
|
|
|
@@ -221,6 +197,7 @@ export function useQueryImpl<
|
|
|
|
|
const query: Ref<ObservableQuery<TResult, TVariables> | null | undefined> = ref()
|
|
|
|
|
let observer: ObservableSubscription | undefined
|
|
|
|
|
let started = false
|
|
|
|
|
let isFirstRun = true
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Starts watching the query
|
|
|
|
@@ -230,7 +207,7 @@ export function useQueryImpl<
|
|
|
|
|
started || !isEnabled.value ||
|
|
|
|
|
(isServer && currentOptions.value?.prefetch === false)
|
|
|
|
|
) {
|
|
|
|
|
tryFirstResolve()
|
|
|
|
|
if (firstResolve) firstResolve()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -258,12 +235,26 @@ export function useQueryImpl<
|
|
|
|
|
addSubscribeToMore(item)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isFirstRun = false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function startQuerySubscription () {
|
|
|
|
|
if (observer && !observer.closed) return
|
|
|
|
|
if (!query.value) return
|
|
|
|
|
|
|
|
|
|
// If hydrating already finished queries, just handle result immediately
|
|
|
|
|
if (!isServer && isFirstRun) {
|
|
|
|
|
const currentResult = query.value.getCurrentResult()
|
|
|
|
|
if (currentResult) {
|
|
|
|
|
if (currentResult.networkStatus === NetworkStatus.ready) {
|
|
|
|
|
onNextResult(currentResult)
|
|
|
|
|
} else if (currentResult.networkStatus === NetworkStatus.error && currentResult.error) {
|
|
|
|
|
onError(currentResult.error)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create subscription
|
|
|
|
|
observer = query.value.subscribe({
|
|
|
|
|
next: onNextResult,
|
|
|
|
@@ -284,7 +275,10 @@ export function useQueryImpl<
|
|
|
|
|
processError(resultErrorsToApolloError(queryResult.errors))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tryFirstResolve()
|
|
|
|
|
if (firstResolve) {
|
|
|
|
|
firstResolve()
|
|
|
|
|
stop()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function processNextResult (queryResult: ApolloQueryResult<TResult>) {
|
|
|
|
@@ -304,7 +298,10 @@ export function useQueryImpl<
|
|
|
|
|
processNextResult((query.value as ObservableQuery<TResult, TVariables>).getCurrentResult())
|
|
|
|
|
}
|
|
|
|
|
processError(apolloError)
|
|
|
|
|
tryFirstReject(apolloError)
|
|
|
|
|
if (firstReject) {
|
|
|
|
|
firstReject(apolloError)
|
|
|
|
|
stop()
|
|
|
|
|
}
|
|
|
|
|
// The observable closes the sub if an error occurs
|
|
|
|
|
resubscribeToQuery()
|
|
|
|
|
}
|
|
|
|
@@ -331,7 +328,7 @@ export function useQueryImpl<
|
|
|
|
|
* Stop watching the query
|
|
|
|
|
*/
|
|
|
|
|
function stop () {
|
|
|
|
|
tryFirstResolve()
|
|
|
|
|
if (firstResolve) firstResolve()
|
|
|
|
|
if (!started) return
|
|
|
|
|
started = false
|
|
|
|
|
loading.value = false
|
|
|
|
|