@@ -65,12 +65,16 @@ export interface BaseWatchOptions<Immediate = boolean> extends DebuggerOptions {
6565 deep ?: boolean
6666 once ?: boolean
6767 scheduler ?: Scheduler
68- handlerError ?: HandleError
69- handlerWarn ?: HandleWarn
68+ handleError ?: HandleError
69+ handleWarn ?: HandleWarn
7070}
7171
7272export type WatchStopHandle = ( ) => void
7373
74+ export interface WatchInstance extends WatchStopHandle {
75+ effect ?: ReactiveEffect
76+ }
77+
7478// initial value for watchers to trigger on undefined initial values
7579const INITIAL_WATCHER_VALUE = { }
7680
@@ -112,20 +116,12 @@ export function baseWatch(
112116 onTrack,
113117 onTrigger,
114118 scheduler = DEFAULT_SCHEDULER ,
115- handlerError = DEFAULT_HANDLE_ERROR ,
116- handlerWarn = warn
119+ handleError : handleError = DEFAULT_HANDLE_ERROR ,
120+ handleWarn : handleWarn = warn
117121 } : 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 {
127123 const warnInvalidSource = ( s : unknown ) => {
128- handlerWarn (
124+ handleWarn (
129125 `Invalid watch source: ` ,
130126 s ,
131127 `A watch source can only be a getter/effect function, a ref, ` +
@@ -155,7 +151,7 @@ export function baseWatch(
155151 } else if ( isFunction ( s ) ) {
156152 return callWithErrorHandling (
157153 s ,
158- handlerError ,
154+ handleError ,
159155 BaseWatchErrorCodes . WATCH_GETTER
160156 )
161157 } else {
@@ -168,16 +164,12 @@ export function baseWatch(
168164 getter = ( ) =>
169165 callWithErrorHandling (
170166 source ,
171- handlerError ,
167+ handleError ,
172168 BaseWatchErrorCodes . WATCH_GETTER
173169 )
174170 } else {
175171 // no cb -> simple effect
176172 getter = ( ) => {
177- // TODO: move to scheduler
178- // if (instance && instance.isUnmounted) {
179- // return
180- // }
181173 if ( cleanup ) {
182174 cleanup ( )
183175 }
@@ -186,7 +178,7 @@ export function baseWatch(
186178 try {
187179 return callWithAsyncErrorHandling (
188180 source ,
189- handlerError ,
181+ handleError ,
190182 BaseWatchErrorCodes . WATCH_CALLBACK ,
191183 [ onEffectCleanup ]
192184 )
@@ -205,29 +197,26 @@ export function baseWatch(
205197 getter = ( ) => traverse ( baseGetter ( ) )
206198 }
207199
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+ }
231220
232221 let oldValue : any = isMultiSource
233222 ? new Array ( ( source as [ ] ) . length ) . fill ( INITIAL_WATCHER_VALUE )
@@ -255,7 +244,7 @@ export function baseWatch(
255244 try {
256245 callWithAsyncErrorHandling (
257246 cb ,
258- handlerError ,
247+ handleError ,
259248 BaseWatchErrorCodes . WATCH_CALLBACK ,
260249 [
261250 newValue ,
@@ -295,18 +284,21 @@ export function baseWatch(
295284 const cleanup = ( effect . onStop = ( ) => {
296285 const cleanups = cleanupMap . get ( effect )
297286 if ( cleanups ) {
298- cleanups . forEach ( cleanup => cleanup ( ) )
287+ cleanups . forEach ( cleanup =>
288+ callWithErrorHandling (
289+ cleanup ,
290+ handleError ,
291+ BaseWatchErrorCodes . WATCH_CLEANUP
292+ )
293+ )
299294 cleanupMap . delete ( effect )
300295 }
301296 } )
302297
303- const unwatch = ( ) => {
298+ const unwatch : WatchInstance = ( ) => {
304299 effect . stop ( )
305- // TODO: move to doWatch
306- // if (instance && instance.scope) {
307- // remove(instance.scope.effects!, effect)
308- // }
309300 }
301+ unwatch . effect = effect
310302
311303 if ( __DEV__ ) {
312304 effect . onTrack = onTrack
0 commit comments