-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
/
vueQueryPlugin.ts
126 lines (108 loc) · 3.36 KB
/
vueQueryPlugin.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import { isVue2 } from 'vue-demi'
import type { QueryClientConfig } from '@tanstack/query-core'
import { QueryClient } from './queryClient'
import { getClientKey } from './utils'
import { setupDevtools } from './devtools/devtools'
import type { MaybeRefDeep } from './types'
declare global {
interface Window {
__VUE_QUERY_CONTEXT__?: QueryClient
}
}
type ClientPersister = (client: QueryClient) => [() => void, Promise<void>]
interface CommonOptions {
queryClientKey?: string
contextSharing?: boolean
clientPersister?: ClientPersister
}
interface ConfigOptions extends CommonOptions {
queryClientConfig?: MaybeRefDeep<QueryClientConfig>
}
interface ClientOptions extends CommonOptions {
queryClient?: QueryClient
}
export type VueQueryPluginOptions = ConfigOptions | ClientOptions
export const VueQueryPlugin = {
install: (app: any, options: VueQueryPluginOptions = {}) => {
const clientKey = getClientKey(options.queryClientKey)
let client: QueryClient
if ('queryClient' in options && options.queryClient) {
client = options.queryClient
} else {
if (options.contextSharing && typeof document !== 'undefined') {
if (!window.__VUE_QUERY_CONTEXT__) {
const clientConfig =
'queryClientConfig' in options
? options.queryClientConfig
: undefined
client = new QueryClient(clientConfig)
window.__VUE_QUERY_CONTEXT__ = client
} else {
client = window.__VUE_QUERY_CONTEXT__
}
} else {
const clientConfig =
'queryClientConfig' in options ? options.queryClientConfig : undefined
client = new QueryClient(clientConfig)
}
}
client.mount()
let persisterUnmount = () => {
// noop
}
if (options.clientPersister) {
client.isRestoring.value = true
const [unmount, promise] = options.clientPersister(client)
persisterUnmount = unmount
promise.then(() => {
client.isRestoring.value = false
})
}
if (process.env.NODE_ENV !== 'production' && options.contextSharing) {
client
.getLogger()
.error(
`The contextSharing option has been deprecated and will be removed in the next major version`,
)
}
const cleanup = () => {
client.unmount()
persisterUnmount()
}
if (app.onUnmount) {
app.onUnmount(cleanup)
} else {
const originalUnmount = app.unmount
app.unmount = function vueQueryUnmount() {
cleanup()
originalUnmount()
}
}
/* istanbul ignore next */
if (isVue2) {
app.mixin({
beforeCreate() {
// HACK: taken from provide(): https://github.com/vuejs/composition-api/blob/master/src/apis/inject.ts#L30
if (!this._provided) {
const provideCache = {}
Object.defineProperty(this, '_provided', {
get: () => provideCache,
set: (v) => Object.assign(provideCache, v),
})
}
this._provided[clientKey] = client
if (process.env.NODE_ENV === 'development') {
if (this === this.$root) {
setupDevtools(this, client)
}
}
},
})
} else {
app.provide(clientKey, client)
if (process.env.NODE_ENV === 'development') {
setupDevtools(app, client)
}
}
},
}