1+ import { observable } from '../observable'
12import {
23 registerRunningReactionForOperation ,
3- queueReactionsForOperation
4+ queueReactionsForOperation ,
5+ hasRunningReaction
46} from '../reactionRunner'
5- import { proxyToRaw } from '../internals'
7+ import { proxyToRaw , rawToProxy } from '../internals'
68
79const hasOwnProperty = Object . prototype . hasOwnProperty
810
11+ function findObservable ( obj ) {
12+ const observableObj = rawToProxy . get ( obj )
13+ if ( hasRunningReaction ( ) && typeof obj === 'object' && obj !== null ) {
14+ if ( observableObj ) {
15+ return observableObj
16+ }
17+ return observable ( obj )
18+ }
19+ return observableObj || obj
20+ }
21+
22+ function patchIterator ( iterator , isEntries ) {
23+ const originalNext = iterator . next
24+ iterator . next = ( ) => {
25+ let { done, value } = originalNext . call ( iterator )
26+ if ( ! done ) {
27+ if ( isEntries ) {
28+ value [ 1 ] = findObservable ( value [ 1 ] )
29+ } else {
30+ value = findObservable ( value )
31+ }
32+ }
33+ return { done, value }
34+ }
35+ return iterator
36+ }
37+
938const instrumentations = {
10- has ( key ) {
39+ has ( key ) {
1140 const target = proxyToRaw . get ( this )
1241 const proto = Reflect . getPrototypeOf ( this )
1342 registerRunningReactionForOperation ( { target, key, type : 'has' } )
1443 return proto . has . apply ( target , arguments )
1544 } ,
16- get ( key ) {
45+ get ( key ) {
1746 const target = proxyToRaw . get ( this )
1847 const proto = Reflect . getPrototypeOf ( this )
1948 registerRunningReactionForOperation ( { target, key, type : 'get' } )
20- return proto . get . apply ( target , arguments )
49+ return findObservable ( proto . get . apply ( target , arguments ) )
2150 } ,
22- add ( key ) {
51+ add ( key ) {
2352 const target = proxyToRaw . get ( this )
2453 const proto = Reflect . getPrototypeOf ( this )
2554 const hadKey = proto . has . call ( target , key )
@@ -30,7 +59,7 @@ const instrumentations = {
3059 }
3160 return result
3261 } ,
33- set ( key , value ) {
62+ set ( key , value ) {
3463 const target = proxyToRaw . get ( this )
3564 const proto = Reflect . getPrototypeOf ( this )
3665 const hadKey = proto . has . call ( target , key )
@@ -44,7 +73,7 @@ const instrumentations = {
4473 }
4574 return result
4675 } ,
47- delete ( key ) {
76+ delete ( key ) {
4877 const target = proxyToRaw . get ( this )
4978 const proto = Reflect . getPrototypeOf ( this )
5079 const hadKey = proto . has . call ( target , key )
@@ -56,7 +85,7 @@ const instrumentations = {
5685 }
5786 return result
5887 } ,
59- clear ( ) {
88+ clear ( ) {
6089 const target = proxyToRaw . get ( this )
6190 const proto = Reflect . getPrototypeOf ( this )
6291 const hadItems = target . size !== 0
@@ -68,37 +97,43 @@ const instrumentations = {
6897 }
6998 return result
7099 } ,
71- forEach ( ) {
100+ forEach ( cb , ... args ) {
72101 const target = proxyToRaw . get ( this )
73102 const proto = Reflect . getPrototypeOf ( this )
74103 registerRunningReactionForOperation ( { target, type : 'iterate' } )
75- return proto . forEach . apply ( target , arguments )
104+ // swap out the raw values with their observable pairs
105+ // before passing them to the callback
106+ const wrappedCb = ( value , ...rest ) => cb ( findObservable ( value ) , ...rest )
107+ return proto . forEach . call ( target , wrappedCb , ...args )
76108 } ,
77- keys ( ) {
109+ keys ( ) {
78110 const target = proxyToRaw . get ( this )
79111 const proto = Reflect . getPrototypeOf ( this )
80112 registerRunningReactionForOperation ( { target, type : 'iterate' } )
81113 return proto . keys . apply ( target , arguments )
82114 } ,
83- values ( ) {
115+ values ( ) {
84116 const target = proxyToRaw . get ( this )
85117 const proto = Reflect . getPrototypeOf ( this )
86118 registerRunningReactionForOperation ( { target, type : 'iterate' } )
87- return proto . values . apply ( target , arguments )
119+ const iterator = proto . values . apply ( target , arguments )
120+ return patchIterator ( iterator , false )
88121 } ,
89- entries ( ) {
122+ entries ( ) {
90123 const target = proxyToRaw . get ( this )
91124 const proto = Reflect . getPrototypeOf ( this )
92125 registerRunningReactionForOperation ( { target, type : 'iterate' } )
93- return proto . entries . apply ( target , arguments )
126+ const iterator = proto . entries . apply ( target , arguments )
127+ return patchIterator ( iterator , true )
94128 } ,
95- [ Symbol . iterator ] ( ) {
129+ [ Symbol . iterator ] ( ) {
96130 const target = proxyToRaw . get ( this )
97131 const proto = Reflect . getPrototypeOf ( this )
98132 registerRunningReactionForOperation ( { target, type : 'iterate' } )
99- return proto [ Symbol . iterator ] . apply ( target , arguments )
133+ const iterator = proto [ Symbol . iterator ] . apply ( target , arguments )
134+ return patchIterator ( iterator , target instanceof Map )
100135 } ,
101- get size ( ) {
136+ get size ( ) {
102137 const target = proxyToRaw . get ( this )
103138 const proto = Reflect . getPrototypeOf ( this )
104139 registerRunningReactionForOperation ( { target, type : 'iterate' } )
@@ -107,7 +142,7 @@ const instrumentations = {
107142}
108143
109144export default {
110- get ( target , key , receiver ) {
145+ get ( target , key , receiver ) {
111146 // instrument methods and property accessors to be reactive
112147 target = hasOwnProperty . call ( instrumentations , key )
113148 ? instrumentations
0 commit comments