Skip to content

Commit 15c5c43

Browse files
committed
wip: onTrack debugger option
1 parent 9fb4f7d commit 15c5c43

File tree

13 files changed

+176
-121
lines changed

13 files changed

+176
-121
lines changed

src/core/instance/state.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {
3030
isFunction
3131
} from '../util/index'
3232
import type { Component } from 'typescript/component'
33+
import { TrackOpTypes } from '../../v3'
3334

3435
const sharedPropertyDefinition = {
3536
enumerable: true,
@@ -254,6 +255,14 @@ function createComputedGetter(key) {
254255
watcher.evaluate()
255256
}
256257
if (Dep.target) {
258+
if (__DEV__ && Dep.target.onTrack) {
259+
Dep.target.onTrack({
260+
effect: Dep.target,
261+
target: this,
262+
type: TrackOpTypes.GET,
263+
key
264+
})
265+
}
257266
watcher.depend()
258267
}
259268
return watcher.value

src/core/observer/dep.ts

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,33 @@
11
import { remove } from '../util/index'
22
import config from '../config'
3+
import { TrackOpTypes, TriggerOpTypes } from 'v3'
34

45
let uid = 0
56

6-
export interface DepTarget {
7+
export interface DepTarget extends DebuggerOptions {
78
id: number
89
addDep(dep: Dep): void
910
update(): void
1011
}
1112

13+
export interface DebuggerOptions {
14+
onTrack?: (event: DebuggerEvent) => void
15+
onTrigger?: (event: DebuggerEvent) => void
16+
}
17+
18+
export type DebuggerEvent = {
19+
effect: DepTarget
20+
} & DebuggerEventExtraInfo
21+
22+
export type DebuggerEventExtraInfo = {
23+
target: object
24+
type: TrackOpTypes | TriggerOpTypes
25+
key?: any
26+
newValue?: any
27+
oldValue?: any
28+
oldTarget?: Map<any, any> | Set<any>
29+
}
30+
1231
/**
1332
* A dep is an observable that can have multiple
1433
* directives subscribing to it.
@@ -31,13 +50,19 @@ export default class Dep {
3150
remove(this.subs, sub)
3251
}
3352

34-
depend() {
53+
depend(info?: DebuggerEventExtraInfo) {
3554
if (Dep.target) {
3655
Dep.target.addDep(this)
56+
if (__DEV__ && info && Dep.target.onTrack) {
57+
Dep.target.onTrack({
58+
effect: Dep.target,
59+
...info
60+
})
61+
}
3762
}
3863
}
3964

40-
notify() {
65+
notify(info?: DebuggerEventExtraInfo) {
4166
// stabilize the subscriber list first
4267
const subs = this.subs.slice()
4368
if (__DEV__ && !config.async) {
@@ -47,6 +72,14 @@ export default class Dep {
4772
subs.sort((a, b) => a.id - b.id)
4873
}
4974
for (let i = 0, l = subs.length; i < l; i++) {
75+
if (__DEV__ && info) {
76+
const sub = subs[i]
77+
sub.onTrigger &&
78+
sub.onTrigger({
79+
effect: subs[i],
80+
...info
81+
})
82+
}
5083
subs[i].update()
5184
}
5285
}

src/core/observer/index.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
isServerRendering,
1616
hasChanged
1717
} from '../util/index'
18-
import { isReadonly, isRef } from '../../v3'
18+
import { isReadonly, isRef, TrackOpTypes } from '../../v3'
1919

2020
const arrayKeys = Object.getOwnPropertyNames(arrayMethods)
2121

@@ -165,7 +165,15 @@ export function defineReactive(
165165
get: function reactiveGetter() {
166166
const value = getter ? getter.call(obj) : val
167167
if (Dep.target) {
168-
dep.depend()
168+
if (__DEV__) {
169+
dep.depend({
170+
target: obj,
171+
type: TrackOpTypes.GET,
172+
key
173+
})
174+
} else {
175+
dep.depend()
176+
}
169177
if (childOb) {
170178
childOb.dep.depend()
171179
if (isArray(value)) {
@@ -291,7 +299,9 @@ export function del(target: Array<any> | Object, key: any) {
291299
function dependArray(value: Array<any>) {
292300
for (let e, i = 0, l = value.length; i < l; i++) {
293301
e = value[i]
294-
e && e.__ob__ && e.__ob__.dep.depend()
302+
if (e && e.__ob__) {
303+
e.__ob__.dep.depend()
304+
}
295305
if (isArray(e)) {
296306
dependArray(e)
297307
}

src/core/observer/watcher.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212

1313
import { traverse } from './traverse'
1414
import { queueWatcher } from './scheduler'
15-
import Dep, { pushTarget, popTarget, DepTarget } from './dep'
15+
import Dep, { pushTarget, popTarget, DepTarget, DebuggerEvent } from './dep'
1616

1717
import type { SimpleSet } from '../util/index'
1818
import type { Component } from 'typescript/component'
@@ -49,6 +49,10 @@ export default class Watcher implements DepTarget {
4949
getter: Function
5050
value: any
5151

52+
// dev only
53+
onTrack?: ((event: DebuggerEvent) => void) | undefined
54+
onTrigger?: ((event: DebuggerEvent) => void) | undefined
55+
5256
constructor(
5357
vm: Component | null,
5458
expOrFn: string | (() => any),

src/core/util/debug.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ if (__DEV__) {
1515
str.replace(classifyRE, c => c.toUpperCase()).replace(/[-_]/g, '')
1616

1717
warn = (msg, vm = currentInstance) => {
18-
// TODO get current instance
1918
const trace = vm ? generateComponentTrace(vm) : ''
2019

2120
if (config.warnHandler) {

src/v3/apiWatch.ts

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { currentInstance } from './currentInstance'
1515
import { traverse } from 'core/observer/traverse'
1616
import Watcher from '../core/observer/watcher'
1717
import { queueWatcher } from '../core/observer/scheduler'
18-
import { TrackOpTypes, TriggerOpTypes } from './reactivity/operations'
18+
import { DebuggerOptions } from '../core/observer/dep'
1919

2020
const WATCHER = `watcher`
2121
const WATCHER_CB = `${WATCHER} callback`
@@ -50,24 +50,6 @@ export interface WatchOptionsBase extends DebuggerOptions {
5050
flush?: 'pre' | 'post' | 'sync'
5151
}
5252

53-
export interface DebuggerOptions {
54-
onTrack?: (event: DebuggerEvent) => void
55-
onTrigger?: (event: DebuggerEvent) => void
56-
}
57-
58-
export type DebuggerEvent = {
59-
watcher: Watcher
60-
} & DebuggerEventExtraInfo
61-
62-
export type DebuggerEventExtraInfo = {
63-
target: object
64-
type: TrackOpTypes | TriggerOpTypes
65-
key: any
66-
newValue?: any
67-
oldValue?: any
68-
oldTarget?: Map<any, any> | Set<any>
69-
}
70-
7153
export interface WatchOptions<Immediate = boolean> extends WatchOptionsBase {
7254
immediate?: Immediate
7355
deep?: boolean
@@ -349,11 +331,10 @@ function doWatch(
349331
}
350332
}
351333

352-
// TODO
353-
// if (__DEV__) {
354-
// effect.onTrack = onTrack
355-
// effect.onTrigger = onTrigger
356-
// }
334+
if (__DEV__) {
335+
watcher.onTrack = onTrack
336+
watcher.onTrigger = onTrigger
337+
}
357338

358339
// initial run
359340
if (cb) {
@@ -370,9 +351,5 @@ function doWatch(
370351

371352
return () => {
372353
watcher.teardown()
373-
// TODO
374-
// if (instance && instance.scope) {
375-
// remove(instance.scope.effects!, effect)
376-
// }
377354
}
378355
}

src/v3/index.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,7 @@ export {
5252
WatchOptionsBase,
5353
WatchCallback,
5454
WatchSource,
55-
WatchStopHandle,
56-
DebuggerOptions,
57-
DebuggerEvent
55+
WatchStopHandle
5856
} from './apiWatch'
5957

6058
export {
@@ -64,6 +62,11 @@ export {
6462
getCurrentScope
6563
} from './reactivity/effectScope'
6664

65+
export {
66+
DebuggerOptions,
67+
DebuggerEvent,
68+
DebuggerEventExtraInfo
69+
} from 'core/observer/dep'
6770
export { TrackOpTypes, TriggerOpTypes } from './reactivity/operations'
6871

6972
export { h } from './h'

src/v3/reactivity/computed.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { isServerRendering, noop, warn, def, isFunction } from 'core/util'
22
import { Ref, RefFlag } from './ref'
33
import Watcher from 'core/observer/watcher'
4-
import Dep from 'core/observer/dep'
4+
import Dep, { DebuggerOptions } from 'core/observer/dep'
55
import { currentInstance } from '../currentInstance'
6-
import { DebuggerOptions } from '../apiWatch'
76
import { ReactiveFlags } from './reactive'
7+
import { TrackOpTypes } from './operations'
88

99
declare const ComputedRefSymbol: unique symbol
1010

@@ -35,7 +35,6 @@ export function computed<T>(
3535
): WritableComputedRef<T>
3636
export function computed<T>(
3737
getterOrOptions: ComputedGetter<T> | WritableComputedOptions<T>,
38-
// TODO debug options
3938
debugOptions?: DebuggerOptions
4039
) {
4140
let getter: ComputedGetter<T>
@@ -58,6 +57,11 @@ export function computed<T>(
5857
? null
5958
: new Watcher(currentInstance, getter, noop, { lazy: true })
6059

60+
if (__DEV__ && watcher && debugOptions) {
61+
watcher.onTrack = debugOptions.onTrack
62+
watcher.onTrigger = debugOptions.onTrigger
63+
}
64+
6165
const ref = {
6266
// some libs rely on the presence effect for checking computed refs
6367
// from normal refs, but the implementation doesn't matter
@@ -68,6 +72,14 @@ export function computed<T>(
6872
watcher.evaluate()
6973
}
7074
if (Dep.target) {
75+
if (__DEV__ && Dep.target.onTrack) {
76+
Dep.target.onTrack({
77+
effect: Dep.target,
78+
target: ref,
79+
type: TrackOpTypes.GET,
80+
key: 'value'
81+
})
82+
}
7183
watcher.depend()
7284
}
7385
return watcher.value

src/v3/reactivity/operations.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,11 @@
33

44
export const enum TrackOpTypes {
55
GET = 'get',
6-
HAS = 'has',
7-
ITERATE = 'iterate'
6+
TOUCH = 'touch'
87
}
98

109
export const enum TriggerOpTypes {
1110
SET = 'set',
1211
ADD = 'add',
13-
DELETE = 'delete',
14-
CLEAR = 'clear'
12+
DELETE = 'delete'
1513
}

src/v3/reactivity/reactive.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ export function isShallow(value: unknown): boolean {
9393
}
9494

9595
export function isReadonly(value: unknown): boolean {
96-
// TODO
9796
return !!(value && (value as Target).__v_isReadonly)
9897
}
9998

0 commit comments

Comments
 (0)