1- import { isObject , toRawType } from '@vue/shared'
1+ import { isObject , toRawType , def } from '@vue/shared'
22import {
33 mutableHandlers ,
44 readonlyHandlers ,
@@ -13,25 +13,38 @@ import { UnwrapRef, Ref } from './ref'
1313import { makeMap } from '@vue/shared'
1414
1515// WeakMaps that store {raw <-> observed} pairs.
16- const rawToReactive = new WeakMap < any , any > ( )
17- const reactiveToRaw = new WeakMap < any , any > ( )
18- const rawToReadonly = new WeakMap < any , any > ( )
19- const readonlyToRaw = new WeakMap < any , any > ( )
16+ // const rawToReactive = new WeakMap<any, any>()
17+ // const reactiveToRaw = new WeakMap<any, any>()
18+ // const rawToReadonly = new WeakMap<any, any>()
19+ // const readonlyToRaw = new WeakMap<any, any>()
2020
21- // WeakSets for values that are marked readonly or non-reactive during
22- // observable creation.
23- const rawValues = new WeakSet < any > ( )
21+ export const enum ReactiveFlags {
22+ skip = '__v_skip' ,
23+ isReactive = '__v_isReactive' ,
24+ isReadonly = '__v_isReadonly' ,
25+ raw = '__v_raw' ,
26+ reactive = '__v_reactive' ,
27+ readonly = '__v_readonly'
28+ }
29+
30+ interface Target {
31+ __v_skip ?: boolean
32+ __v_isReactive ?: boolean
33+ __v_isReadonly ?: boolean
34+ __v_raw ?: any
35+ __v_reactive ?: any
36+ __v_readonly ?: any
37+ }
2438
2539const collectionTypes = new Set < Function > ( [ Set , Map , WeakMap , WeakSet ] )
2640const isObservableType = /*#__PURE__*/ makeMap (
2741 'Object,Array,Map,Set,WeakMap,WeakSet'
2842)
2943
30- const canObserve = ( value : any ) : boolean => {
44+ const canObserve = ( value : Target ) : boolean => {
3145 return (
32- ! value . _isVNode &&
46+ ! value . __v_skip &&
3347 isObservableType ( toRawType ( value ) ) &&
34- ! rawValues . has ( value ) &&
3548 ! Object . isFrozen ( value )
3649 )
3750}
@@ -42,13 +55,12 @@ type UnwrapNestedRefs<T> = T extends Ref ? T : UnwrapRef<T>
4255export function reactive < T extends object > ( target : T ) : UnwrapNestedRefs < T >
4356export function reactive ( target : object ) {
4457 // if trying to observe a readonly proxy, return the readonly version.
45- if ( readonlyToRaw . has ( target ) ) {
58+ if ( target && ( target as Target ) . __v_isReadonly ) {
4659 return target
4760 }
4861 return createReactiveObject (
4962 target ,
50- rawToReactive ,
51- reactiveToRaw ,
63+ false ,
5264 mutableHandlers ,
5365 mutableCollectionHandlers
5466 )
@@ -60,8 +72,7 @@ export function reactive(target: object) {
6072export function shallowReactive < T extends object > ( target : T ) : T {
6173 return createReactiveObject (
6274 target ,
63- rawToReactive ,
64- reactiveToRaw ,
75+ false ,
6576 shallowReactiveHandlers ,
6677 mutableCollectionHandlers
6778 )
@@ -72,8 +83,7 @@ export function readonly<T extends object>(
7283) : Readonly < UnwrapNestedRefs < T > > {
7384 return createReactiveObject (
7485 target ,
75- rawToReadonly ,
76- readonlyToRaw ,
86+ true ,
7787 readonlyHandlers ,
7888 readonlyCollectionHandlers
7989 )
@@ -88,17 +98,15 @@ export function shallowReadonly<T extends object>(
8898) : Readonly < { [ K in keyof T ] : UnwrapNestedRefs < T [ K ] > } > {
8999 return createReactiveObject (
90100 target ,
91- rawToReadonly ,
92- readonlyToRaw ,
101+ true ,
93102 shallowReadonlyHandlers ,
94103 readonlyCollectionHandlers
95104 )
96105}
97106
98107function createReactiveObject (
99- target : unknown ,
100- toProxy : WeakMap < any , any > ,
101- toRaw : WeakMap < any , any > ,
108+ target : Target ,
109+ isReadonly : boolean ,
102110 baseHandlers : ProxyHandler < any > ,
103111 collectionHandlers : ProxyHandler < any >
104112) {
@@ -108,15 +116,16 @@ function createReactiveObject(
108116 }
109117 return target
110118 }
119+ // target is already a Proxy, return it.
120+ // excpetion: calling readonly() on a reactive object
121+ if ( target . __v_raw && ! ( isReadonly && target . __v_isReactive ) ) {
122+ return target
123+ }
111124 // target already has corresponding Proxy
112- let observed = toProxy . get ( target )
125+ let observed = isReadonly ? target . __v_readonly : target . __v_reactive
113126 if ( observed !== void 0 ) {
114127 return observed
115128 }
116- // target is already a Proxy
117- if ( toRaw . has ( target ) ) {
118- return target
119- }
120129 // only a whitelist of value types can be observed.
121130 if ( ! canObserve ( target ) ) {
122131 return target
@@ -125,30 +134,34 @@ function createReactiveObject(
125134 ? collectionHandlers
126135 : baseHandlers
127136 observed = new Proxy ( target , handlers )
128- toProxy . set ( target , observed )
129- toRaw . set ( observed , target )
137+ def (
138+ target ,
139+ isReadonly ? ReactiveFlags . readonly : ReactiveFlags . reactive ,
140+ observed
141+ )
130142 return observed
131143}
132144
133145export function isReactive ( value : unknown ) : boolean {
134- value = readonlyToRaw . get ( value ) || value
135- return reactiveToRaw . has ( value )
146+ if ( isReadonly ( value ) ) {
147+ return isReactive ( ( value as Target ) . __v_raw )
148+ }
149+ return ! ! ( value && ( value as Target ) . __v_isReactive )
136150}
137151
138152export function isReadonly ( value : unknown ) : boolean {
139- return readonlyToRaw . has ( value )
153+ return ! ! ( value && ( value as Target ) . __v_isReadonly )
140154}
141155
142156export function isProxy ( value : unknown ) : boolean {
143- return readonlyToRaw . has ( value ) || reactiveToRaw . has ( value )
157+ return isReactive ( value ) || isReadonly ( value )
144158}
145159
146160export function toRaw < T > ( observed : T ) : T {
147- observed = readonlyToRaw . get ( observed ) || observed
148- return reactiveToRaw . get ( observed ) || observed
161+ return ( observed && toRaw ( ( observed as Target ) . __v_raw ) ) || observed
149162}
150163
151164export function markRaw < T extends object > ( value : T ) : T {
152- rawValues . add ( value )
165+ def ( value , ReactiveFlags . skip , true )
153166 return value
154167}
0 commit comments