Skip to content

Commit

Permalink
feat: add QueryCache.watchQuery (#1058)
Browse files Browse the repository at this point in the history
  • Loading branch information
boschni authored Sep 18, 2020
1 parent 6b15ae0 commit 5d05464
Show file tree
Hide file tree
Showing 5 changed files with 211 additions and 88 deletions.
6 changes: 6 additions & 0 deletions src/core/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@ export function getResolvedQueryConfig<TResult, TError>(
return resolvedConfig
}

export function isResolvedQueryConfig<TResult, TError>(
config: any
): config is ResolvedQueryConfig<TResult, TError> {
return Boolean(config.queryHash)
}

export function getResolvedMutationConfig<
TResult,
TError,
Expand Down
9 changes: 9 additions & 0 deletions src/core/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,9 @@ export class Query<TResult, TError> {
this.continue()
}

/**
* @deprectated
*/
subscribe(
listener?: UpdateListener<TResult, TError>
): QueryObserver<TResult, TError> {
Expand Down Expand Up @@ -319,6 +322,9 @@ export class Query<TResult, TError> {
}
}

/**
* @deprectated
*/
refetch(
options?: RefetchOptions,
config?: ResolvedQueryConfig<TResult, TError>
Expand All @@ -332,6 +338,9 @@ export class Query<TResult, TError> {
return promise
}

/**
* @deprectated
*/
fetchMore(
fetchMoreVariable?: unknown,
options?: FetchMoreOptions,
Expand Down
31 changes: 31 additions & 0 deletions src/core/queryCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
ResolvedQueryConfig,
} from './types'
import { notifyManager } from './notifyManager'
import { QueryObserver } from './queryObserver'

// TYPES

Expand Down Expand Up @@ -455,6 +456,36 @@ export class QueryCache {
return promise
}

// Parameter syntax
watchQuery<TResult = unknown, TError = unknown>(
queryKey: QueryKey,
queryConfig?: QueryConfig<TResult, TError>
): QueryObserver<TResult, TError>

// Parameter syntax with query function
watchQuery<TResult, TError, TArgs extends TypedQueryFunctionArgs>(
queryKey: QueryKey,
queryFn: TypedQueryFunction<TResult, TArgs>,
queryConfig?: QueryConfig<TResult, TError>
): QueryObserver<TResult, TError>

watchQuery<TResult = unknown, TError = unknown>(
queryKey: QueryKey,
queryFn: QueryFunction<TResult>,
queryConfig?: QueryConfig<TResult, TError>
): QueryObserver<TResult, TError>

// Implementation
watchQuery<TResult, TError>(
arg1: any,
arg2?: any,
arg3?: any
): QueryObserver<TResult, TError> {
const [queryKey, config] = getQueryArgs<TResult, TError>(arg1, arg2, arg3)
const resolvedConfig = this.getResolvedQueryConfig(queryKey, config)
return new QueryObserver(resolvedConfig)
}

setQueryData<TResult, TError = unknown>(
queryKey: QueryKey,
updater: Updater<TResult | undefined, TResult>,
Expand Down
114 changes: 65 additions & 49 deletions src/core/queryObserver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import {
noop,
} from './utils'
import { notifyManager } from './notifyManager'
import type { QueryResult, ResolvedQueryConfig } from './types'
import type { QueryConfig, QueryResult, ResolvedQueryConfig } from './types'
import type { Query, Action, FetchMoreOptions, RefetchOptions } from './query'
import { DEFAULT_CONFIG, isResolvedQueryConfig } from './config'

export type UpdateListener<TResult, TError> = (
result: QueryResult<TResult, TError>
Expand Down Expand Up @@ -41,13 +42,14 @@ export class QueryObserver<TResult, TError> {
this.remove = this.remove.bind(this)
this.refetch = this.refetch.bind(this)
this.fetchMore = this.fetchMore.bind(this)
this.unsubscribe = this.unsubscribe.bind(this)

// Subscribe to the query
this.updateQuery()
}

subscribe(listener?: UpdateListener<TResult, TError>): () => void {
this.listener = listener
this.listener = listener || noop
this.currentQuery.subscribeObserver(this)

if (
Expand All @@ -60,7 +62,8 @@ export class QueryObserver<TResult, TError> {
}

this.updateTimers()
return this.unsubscribe.bind(this)

return this.unsubscribe
}

unsubscribe(): void {
Expand All @@ -69,11 +72,19 @@ export class QueryObserver<TResult, TError> {
this.currentQuery.unsubscribeObserver(this)
}

updateConfig(config: ResolvedQueryConfig<TResult, TError>): void {
updateConfig(
config: QueryConfig<TResult, TError> | ResolvedQueryConfig<TResult, TError>
): void {
const prevConfig = this.config
const prevQuery = this.currentQuery

this.config = config
this.config = isResolvedQueryConfig(config)
? config
: this.config.queryCache.getResolvedQueryConfig(
this.config.queryKey,
config
)

this.updateQuery()

// Take no further actions if there is no subscriber
Expand Down Expand Up @@ -143,6 +154,11 @@ export class QueryObserver<TResult, TError> {
}

fetch(): Promise<TResult | undefined> {
// Never try to fetch if no query function has been set
if (this.config.queryFn === DEFAULT_CONFIG.queries?.queryFn) {
return Promise.resolve(this.currentResult.data)
}

return this.currentQuery.fetch(undefined, this.config).catch(noop)
}

Expand All @@ -157,50 +173,6 @@ export class QueryObserver<TResult, TError> {
}
}

private notify(options: NotifyOptions): void {
const { config, currentResult, currentQuery, listener } = this
const { onSuccess, onSettled, onError } = config

notifyManager.batch(() => {
// First trigger the configuration callbacks
if (options.onSuccess) {
if (onSuccess) {
notifyManager.schedule(() => {
onSuccess(currentResult.data!)
})
}
if (onSettled) {
notifyManager.schedule(() => {
onSettled(currentResult.data!, null)
})
}
} else if (options.onError) {
if (onError) {
notifyManager.schedule(() => {
onError(currentResult.error!)
})
}
if (onSettled) {
notifyManager.schedule(() => {
onSettled(undefined, currentResult.error!)
})
}
}

// Then trigger the listener
if (options.listener && listener) {
notifyManager.schedule(() => {
listener(currentResult)
})
}

// Then the global listeners
if (options.globalListeners) {
config.queryCache.notifyGlobalListeners(currentQuery)
}
})
}

private updateStaleTimeout(): void {
if (isServer) {
return
Expand Down Expand Up @@ -393,4 +365,48 @@ export class QueryObserver<TResult, TError> {

this.notify(notifyOptions)
}

private notify(options: NotifyOptions): void {
const { config, currentResult, currentQuery, listener } = this
const { onSuccess, onSettled, onError } = config

notifyManager.batch(() => {
// First trigger the configuration callbacks
if (options.onSuccess) {
if (onSuccess) {
notifyManager.schedule(() => {
onSuccess(currentResult.data!)
})
}
if (onSettled) {
notifyManager.schedule(() => {
onSettled(currentResult.data!, null)
})
}
} else if (options.onError) {
if (onError) {
notifyManager.schedule(() => {
onError(currentResult.error!)
})
}
if (onSettled) {
notifyManager.schedule(() => {
onSettled(undefined, currentResult.error!)
})
}
}

// Then trigger the listener
if (options.listener && listener) {
notifyManager.schedule(() => {
listener(currentResult)
})
}

// Then the global listeners
if (options.globalListeners) {
config.queryCache.notifyGlobalListeners(currentQuery)
}
})
}
}
Loading

0 comments on commit 5d05464

Please sign in to comment.