@@ -50,6 +50,16 @@ export default {
5050 } , merge ( toData , fromData ) )
5151 }
5252
53+ function getResult ( result ) {
54+ if ( result && typeof result . fetch === 'function' ) {
55+ result = result . fetch ( )
56+ }
57+ if ( Vue . config . meteor . freeze ) {
58+ result = Object . freeze ( result )
59+ }
60+ return result
61+ }
62+
5363 function prepare ( ) {
5464 this . _trackerHandles = [ ]
5565 this . _subsAutorun = { }
@@ -75,24 +85,16 @@ export default {
7585
7686 if ( ! isServer || ssr ) {
7787 // Subscriptions
78- if ( meteor . subscribe || meteor . $subscribe ) {
79- const subscribeOptions = Object . assign ( { } , meteor . subscribe , meteor . $subscribe )
80- for ( let key in subscribeOptions ) {
81- this . $addReactiveSub ( key , subscribeOptions [ key ] )
88+ if ( meteor . $subscribe ) {
89+ for ( let key in meteor . $subscribe ) {
90+ this . $subscribe ( key , meteor . $subscribe [ key ] )
8291 }
8392 }
8493
85- const data = Object . assign ( { } , omit ( meteor , [
86- 'subscribe' ,
87- 'data' ,
88- ] ) , meteor . data )
89-
9094 // Reactive data
91- if ( data ) {
92- for ( let key in data ) {
93- if ( key . charAt ( 0 ) !== '$' ) {
94- this . $addMeteorData ( key , data [ key ] )
95- }
95+ for ( let key in meteor ) {
96+ if ( key . charAt ( 0 ) !== '$' ) {
97+ this . $addMeteorData ( key , meteor [ key ] )
9698 }
9799 }
98100 }
@@ -121,14 +123,22 @@ export default {
121123 if ( this . $options . meteor && ! this . $options . meteor . $lazy ) {
122124 launch . call ( this )
123125 }
126+
127+ // Computed props
128+ const computed = this . _computedWatchers
129+ if ( computed ) {
130+ for ( let key in computed ) {
131+ this . $addComputed ( key , computed [ key ] )
132+ }
133+ }
124134 } ,
125135
126136 destroyed : function ( ) {
127137 this . $stopMeteor ( )
128138 } ,
129139
130140 methods : {
131- $subscribe ( ...args ) {
141+ $_subscribe ( ...args ) {
132142 if ( args . length > 0 ) {
133143 const key = args [ 0 ]
134144 const oldSub = this . _subs [ key ]
@@ -160,6 +170,32 @@ export default {
160170 }
161171 } ,
162172
173+ $subscribe ( key , options ) {
174+ let handle , unwatch
175+ let subscribe = params => {
176+ handle = this . $_subscribe ( key , ...params )
177+ }
178+
179+ if ( typeof options === 'function' ) {
180+ if ( isServer ) {
181+ subscribe ( options . bind ( this ) ( ) )
182+ } else {
183+ unwatch = this . $watch ( options , params => {
184+ subscribe ( params )
185+ } , {
186+ immediate : true ,
187+ } )
188+ }
189+ } else {
190+ subscribe ( options )
191+ }
192+
193+ return ( ) => {
194+ if ( unwatch ) unwatch ( )
195+ if ( handle ) this . $stopHandle ( handle )
196+ }
197+ } ,
198+
163199 $autorun ( reactiveFunction ) {
164200 let handle = Tracker . autorun ( reactiveFunction )
165201 this . _trackerHandles . push ( handle )
@@ -193,32 +229,6 @@ export default {
193229 this . _meteorActive = false
194230 } ,
195231
196- $addReactiveSub ( key , options ) {
197- let handle , unwatch
198- let subscribe = params => {
199- handle = this . $subscribe ( key , ...params )
200- }
201-
202- if ( typeof options === 'function' ) {
203- if ( isServer ) {
204- subscribe ( options . bind ( this ) ( ) )
205- } else {
206- unwatch = this . $watch ( options , params => {
207- subscribe ( params )
208- } , {
209- immediate : true ,
210- } )
211- }
212- } else {
213- subscribe ( options )
214- }
215-
216- return ( ) => {
217- if ( unwatch ) unwatch ( )
218- if ( handle ) this . $stopHandle ( handle )
219- }
220- } ,
221-
222232 $addMeteorData ( key , func ) {
223233 if ( typeof func === 'function' ) {
224234 func = func . bind ( this )
@@ -238,12 +248,7 @@ export default {
238248
239249 // Function run
240250 const setResult = result => {
241- if ( result && typeof result . fetch === 'function' ) {
242- result = result . fetch ( )
243- }
244- if ( Vue . config . meteor . freeze ) {
245- result = Object . freeze ( result )
246- }
251+ result = getResult ( result )
247252 set ( this . $data . $meteor . data , key , result )
248253 }
249254
@@ -270,6 +275,38 @@ export default {
270275 unautorun ( )
271276 }
272277 } ,
278+
279+ $addComputed ( key , watcher ) {
280+ let computation , autorunMethod
281+ const autorun = ( cb ) => {
282+ if ( ! computation ) {
283+ // Update from Meteor
284+ let dirty = false
285+ computation = autorunMethod ( computation => {
286+ dirty = true
287+ watcher . value = getResult ( cb . call ( this ) )
288+ watcher . deps . forEach ( dep => dep . notify ( ) )
289+ dirty = false
290+ } )
291+ // Update from Vue (override)
292+ watcher . update = ( ) => {
293+ if ( ! dirty ) {
294+ computation . invalidate ( )
295+ }
296+ }
297+ }
298+ return watcher . value
299+ }
300+ // Override getter to expose $autorun
301+ const func = watcher . getter
302+ watcher . getter = ( ) => {
303+ autorunMethod = this . $autorun
304+ this . $autorun = autorun
305+ const result = func . call ( this , this )
306+ this . $autorun = autorunMethod
307+ return result
308+ }
309+ } ,
273310 } ,
274311 } )
275312
0 commit comments