@@ -65,12 +65,16 @@ export interface BaseWatchOptions<Immediate = boolean> extends DebuggerOptions {
65
65
deep ?: boolean
66
66
once ?: boolean
67
67
scheduler ?: Scheduler
68
- handlerError ?: HandleError
69
- handlerWarn ?: HandleWarn
68
+ handleError ?: HandleError
69
+ handleWarn ?: HandleWarn
70
70
}
71
71
72
72
export type WatchStopHandle = ( ) => void
73
73
74
+ export interface WatchInstance extends WatchStopHandle {
75
+ effect ?: ReactiveEffect
76
+ }
77
+
74
78
// initial value for watchers to trigger on undefined initial values
75
79
const INITIAL_WATCHER_VALUE = { }
76
80
@@ -112,20 +116,12 @@ export function baseWatch(
112
116
onTrack,
113
117
onTrigger,
114
118
scheduler = DEFAULT_SCHEDULER ,
115
- handlerError = DEFAULT_HANDLE_ERROR ,
116
- handlerWarn = warn
119
+ handleError : handleError = DEFAULT_HANDLE_ERROR ,
120
+ handleWarn : handleWarn = warn
117
121
} : BaseWatchOptions = EMPTY_OBJ
118
- ) : WatchStopHandle {
119
- if ( cb && once ) {
120
- const _cb = cb
121
- cb = ( ...args ) => {
122
- _cb ( ...args )
123
- unwatch ( )
124
- }
125
- }
126
-
122
+ ) : WatchInstance {
127
123
const warnInvalidSource = ( s : unknown ) => {
128
- handlerWarn (
124
+ handleWarn (
129
125
`Invalid watch source: ` ,
130
126
s ,
131
127
`A watch source can only be a getter/effect function, a ref, ` +
@@ -155,7 +151,7 @@ export function baseWatch(
155
151
} else if ( isFunction ( s ) ) {
156
152
return callWithErrorHandling (
157
153
s ,
158
- handlerError ,
154
+ handleError ,
159
155
BaseWatchErrorCodes . WATCH_GETTER
160
156
)
161
157
} else {
@@ -168,16 +164,12 @@ export function baseWatch(
168
164
getter = ( ) =>
169
165
callWithErrorHandling (
170
166
source ,
171
- handlerError ,
167
+ handleError ,
172
168
BaseWatchErrorCodes . WATCH_GETTER
173
169
)
174
170
} else {
175
171
// no cb -> simple effect
176
172
getter = ( ) => {
177
- // TODO: move to scheduler
178
- // if (instance && instance.isUnmounted) {
179
- // return
180
- // }
181
173
if ( cleanup ) {
182
174
cleanup ( )
183
175
}
@@ -186,7 +178,7 @@ export function baseWatch(
186
178
try {
187
179
return callWithAsyncErrorHandling (
188
180
source ,
189
- handlerError ,
181
+ handleError ,
190
182
BaseWatchErrorCodes . WATCH_CALLBACK ,
191
183
[ onEffectCleanup ]
192
184
)
@@ -205,29 +197,26 @@ export function baseWatch(
205
197
getter = ( ) => traverse ( baseGetter ( ) )
206
198
}
207
199
208
- // TODO: support SSR
209
- // in SSR there is no need to setup an actual effect, and it should be noop
210
- // unless it's eager or sync flush
211
- // let ssrCleanup: (() => void)[] | undefined
212
- // if (__SSR__ && isInSSRComponentSetup) {
213
- // // we will also not call the invalidate callback (+ runner is not set up)
214
- // onCleanup = NOOP
215
- // if (!cb) {
216
- // getter()
217
- // } else if (immediate) {
218
- // callWithAsyncErrorHandling(cb, handlerError, BaseWatchErrorCodes.WATCH_CALLBACK, [
219
- // getter(),
220
- // isMultiSource ? [] : undefined,
221
- // onCleanup
222
- // ])
223
- // }
224
- // if (flush === 'sync') {
225
- // const ctx = useSSRContext()!
226
- // ssrCleanup = ctx.__watcherHandles || (ctx.__watcherHandles = [])
227
- // } else {
228
- // return NOOP
229
- // }
230
- // }
200
+ if ( once ) {
201
+ if ( ! cb ) {
202
+ getter ( )
203
+ return NOOP
204
+ }
205
+ if ( immediate ) {
206
+ callWithAsyncErrorHandling (
207
+ cb ,
208
+ handleError ,
209
+ BaseWatchErrorCodes . WATCH_CALLBACK ,
210
+ [ getter ( ) , isMultiSource ? [ ] : undefined , onEffectCleanup ]
211
+ )
212
+ return NOOP
213
+ }
214
+ const _cb = cb
215
+ cb = ( ...args ) => {
216
+ _cb ( ...args )
217
+ unwatch ( )
218
+ }
219
+ }
231
220
232
221
let oldValue : any = isMultiSource
233
222
? new Array ( ( source as [ ] ) . length ) . fill ( INITIAL_WATCHER_VALUE )
@@ -255,7 +244,7 @@ export function baseWatch(
255
244
try {
256
245
callWithAsyncErrorHandling (
257
246
cb ,
258
- handlerError ,
247
+ handleError ,
259
248
BaseWatchErrorCodes . WATCH_CALLBACK ,
260
249
[
261
250
newValue ,
@@ -295,18 +284,21 @@ export function baseWatch(
295
284
const cleanup = ( effect . onStop = ( ) => {
296
285
const cleanups = cleanupMap . get ( effect )
297
286
if ( cleanups ) {
298
- cleanups . forEach ( cleanup => cleanup ( ) )
287
+ cleanups . forEach ( cleanup =>
288
+ callWithErrorHandling (
289
+ cleanup ,
290
+ handleError ,
291
+ BaseWatchErrorCodes . WATCH_CLEANUP
292
+ )
293
+ )
299
294
cleanupMap . delete ( effect )
300
295
}
301
296
} )
302
297
303
- const unwatch = ( ) => {
298
+ const unwatch : WatchInstance = ( ) => {
304
299
effect . stop ( )
305
- // TODO: move to doWatch
306
- // if (instance && instance.scope) {
307
- // remove(instance.scope.effects!, effect)
308
- // }
309
300
}
301
+ unwatch . effect = effect
310
302
311
303
if ( __DEV__ ) {
312
304
effect . onTrack = onTrack
0 commit comments