Skip to content

Commit

Permalink
fix: sync code changes according to the review in PR vuejs/vue-vapor#82
Browse files Browse the repository at this point in the history
  • Loading branch information
LittleSound committed Jan 5, 2024
1 parent a6eb043 commit 770c21d
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 67 deletions.
4 changes: 2 additions & 2 deletions packages/reactivity/__tests__/baseWatch.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
baseWatch,
onEffectCleanup,
ref,
} from '../src/index'
} from '../src'

const queue: SchedulerJob[] = []

Expand All @@ -15,7 +15,7 @@ let isFlushPending = false
const resolvedPromise = /*#__PURE__*/ Promise.resolve() as Promise<any>
const nextTick = (fn?: () => any) =>
fn ? resolvedPromise.then(fn) : resolvedPromise
const scheduler: Scheduler = ({ job }) => {
const scheduler: Scheduler = job => {
queue.push(job)
flushJobs()
}
Expand Down
44 changes: 15 additions & 29 deletions packages/reactivity/src/baseWatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ import { isReactive, isShallow } from './reactive'
import { type Ref, isRef } from './ref'
import { getCurrentScope } from './effectScope'

// contexts where user provided function may be executed, in addition to
// lifecycle hooks.
// These errors were transferred from `packages/runtime-core/src/errorHandling.ts`
// along with baseWatch to maintain code compatibility. Hence,
// it is essential to keep these values unchanged.
export enum BaseWatchErrorCodes {
WATCH_GETTER = 'BaseWatchErrorCodes_WATCH_GETTER',
WATCH_CALLBACK = 'BaseWatchErrorCodes_WATCH_CALLBACK',
WATCH_CLEANUP = 'BaseWatchErrorCodes_WATCH_CLEANUP',
WATCH_GETTER = 2,
WATCH_CALLBACK,
WATCH_CLEANUP,
}

// TODO move to a scheduler package
Expand Down Expand Up @@ -57,15 +58,12 @@ export interface SchedulerJob extends Function {
}

type WatchEffect = (onCleanup: OnCleanup) => void

type WatchSource<T = any> = Ref<T> | ComputedRef<T> | (() => T)

type WatchCallback<V = any, OV = any> = (
value: V,
oldValue: OV,
onCleanup: OnCleanup,
) => any

type OnCleanup = (cleanupFn: () => void) => void

export interface BaseWatchOptions<Immediate = boolean> extends DebuggerOptions {
Expand All @@ -80,22 +78,19 @@ export interface BaseWatchOptions<Immediate = boolean> extends DebuggerOptions {
// initial value for watchers to trigger on undefined initial values
const INITIAL_WATCHER_VALUE = {}

export type Scheduler = (context: {
effect: ReactiveEffect
job: SchedulerJob
isInit: boolean
}) => void

const DEFAULT_SCHEDULER: Scheduler = ({ job }) => job()

export type Scheduler = (
job: SchedulerJob,
effect: ReactiveEffect,
isInit: boolean,
) => void
export type HandleError = (err: unknown, type: BaseWatchErrorCodes) => void
export type HandleWarn = (msg: string, ...args: any[]) => void

const DEFAULT_SCHEDULER: Scheduler = job => job()
const DEFAULT_HANDLE_ERROR: HandleError = (err: unknown) => {
throw err
}

export type HandleWarn = (msg: string, ...args: any[]) => void

const cleanupMap: WeakMap<ReactiveEffect, (() => void)[]> = new WeakMap()
let activeEffect: ReactiveEffect | undefined = undefined

Expand Down Expand Up @@ -306,12 +301,7 @@ export function baseWatch(
// it is allowed to self-trigger (#1727)
job.allowRecurse = !!cb

let effectScheduler: EffectScheduler = () =>
scheduler({
effect,
job,
isInit: false,
})
let effectScheduler: EffectScheduler = () => scheduler(job, effect, false)

effect = new ReactiveEffect(getter, NOOP, effectScheduler)

Expand Down Expand Up @@ -342,11 +332,7 @@ export function baseWatch(
oldValue = effect.run()
}
} else {
scheduler({
effect,
job,
isInit: true,
})
scheduler(job, effect, true)
}

return effect
Expand Down
2 changes: 1 addition & 1 deletion packages/reactivity/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ export { TrackOpTypes, TriggerOpTypes, ReactiveFlags } from './constants'
export {
baseWatch,
onEffectCleanup,
BaseWatchErrorCodes,
traverse,
BaseWatchErrorCodes,
type BaseWatchOptions,
type Scheduler,
} from './baseWatch'
23 changes: 9 additions & 14 deletions packages/runtime-core/src/apiWatch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import {
getCurrentScope,
} from '@vue/reactivity'
import {
type SchedulerJob,
usePreScheduler,
useSyncScheduler,
type SchedulerFactory,
createPreScheduler,
createSyncScheduler,
} from './scheduler'
import {
EMPTY_OBJ,
Expand All @@ -28,7 +28,7 @@ import {
unsetCurrentInstance,
} from './component'
import { handleError as handleErrorWithInstance } from './errorHandling'
import { usePostRenderScheduler } from './renderer'
import { createPostRenderScheduler } from './renderer'
import { warn } from './warning'
import type { ObjectWatchOptionItem } from './componentOptions'
import { useSSRContext } from './helpers/useSsrContext'
Expand Down Expand Up @@ -156,17 +156,15 @@ export function watch<T = any, Immediate extends Readonly<boolean> = false>(
return doWatch(source as any, cb, options)
}

function getSchedulerByFlushMode(
flush: WatchOptionsBase['flush'],
): SchedulerJob {
function getScheduler(flush: WatchOptionsBase['flush']): SchedulerFactory {
if (flush === 'post') {
return usePostRenderScheduler
return createPostRenderScheduler
}
if (flush === 'sync') {
return useSyncScheduler
return createSyncScheduler
}
// default: 'pre'
return usePreScheduler
return createPreScheduler
}

function doWatch(
Expand Down Expand Up @@ -224,12 +222,9 @@ function doWatch(
}

const instance = currentInstance

extendOptions.onError = (err: unknown, type: BaseWatchErrorCodes) =>
handleErrorWithInstance(err, instance, type)

const scheduler = getSchedulerByFlushMode(flush)({ instance })
extendOptions.scheduler = scheduler
extendOptions.scheduler = getScheduler(flush)(instance)

let effect = baseWatch(source, cb, extend({}, options, extendOptions))

Expand Down
2 changes: 1 addition & 1 deletion packages/runtime-core/src/componentOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -942,7 +942,7 @@ export function createWatcher(
? createPathGetter(publicThis, key)
: () => (publicThis as any)[key]

const options: WatchOptions<false> = {}
const options: WatchOptions = {}
if (__COMPAT__) {
const instance =
getCurrentScope() === currentInstance?.scope ? currentInstance : null
Expand Down
8 changes: 7 additions & 1 deletion packages/runtime-core/src/errorHandling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ import { BaseWatchErrorCodes } from '@vue/reactivity'
export enum ErrorCodes {
SETUP_FUNCTION,
RENDER_FUNCTION,
NATIVE_EVENT_HANDLER,
// The error codes for the watch have been transferred to the reactivity
// package along with baseWatch to maintain code compatibility. Hence,
// it is essential to keep these values unchanged.
// WATCH_GETTER,
// WATCH_CALLBACK,
// WATCH_CLEANUP,
NATIVE_EVENT_HANDLER = 5,
COMPONENT_EVENT_HANDLER,
VNODE_HOOK,
DIRECTIVE_HOOK,
Expand Down
7 changes: 3 additions & 4 deletions packages/runtime-core/src/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import {
isReservedProp,
} from '@vue/shared'
import {
type Scheduler,
type SchedulerFactory,
type SchedulerJob,
flushPostFlushCbs,
flushPreFlushCbs,
Expand Down Expand Up @@ -282,9 +282,8 @@ export const queuePostRenderEffect = __FEATURE_SUSPENSE__
: queueEffectWithSuspense
: queuePostFlushCb

export const usePostRenderScheduler: Scheduler =
({ instance }) =>
({ isInit, effect, job }) => {
export const createPostRenderScheduler: SchedulerFactory =
instance => (job, effect, isInit) => {
if (isInit) {
queuePostRenderEffect(
effect.run.bind(effect),
Expand Down
24 changes: 9 additions & 15 deletions packages/runtime-core/src/scheduler.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ErrorCodes, callWithErrorHandling, handleError } from './errorHandling'
import { type Awaited, NOOP, isArray } from '@vue/shared'
import { type ComponentInternalInstance, getComponentName } from './component'
import type { ReactiveEffect } from '@vue/reactivity'
import type { Scheduler } from '@vue/reactivity'

export interface SchedulerJob extends Function {
id?: number
Expand Down Expand Up @@ -289,27 +289,21 @@ function checkRecursiveUpdates(seen: CountMap, fn: SchedulerJob) {
}
}

export type Scheduler = (options: {
instance: ComponentInternalInstance | null
}) => (context: {
effect: ReactiveEffect
job: SchedulerJob
isInit: boolean
}) => void

export const useSyncScheduler: Scheduler =
({ instance }) =>
({ isInit, effect, job }) => {
export type SchedulerFactory = (
instance: ComponentInternalInstance | null,
) => Scheduler

export const createSyncScheduler: SchedulerFactory =
instance => (job, effect, isInit) => {
if (isInit) {
effect.run()
} else {
job()
}
}

export const usePreScheduler: Scheduler =
({ instance }) =>
({ isInit, effect, job }) => {
export const createPreScheduler: SchedulerFactory =
instance => (job, effect, isInit) => {
if (isInit) {
effect.run()
} else {
Expand Down

0 comments on commit 770c21d

Please sign in to comment.