1- /**
2- * @author Jason Dobry <jason.dobry@gmail.com>
3- * @file angular-data.js
4- * @version 0.8.1 - Homepage <http://angular-data.codetrain.io/>
5- * @copyright (c) 2014 Jason Dobry <https://github.com/jmdobry/>
6- * @license MIT <https://github.com/jmdobry/angular-data/blob/master/LICENSE>
7- *
8- * @overview Data store for Angular.js.
9- */
101require = ( function e ( t , n , r ) { function s ( o , u ) { if ( ! n [ o ] ) { if ( ! t [ o ] ) { var a = typeof require == "function" && require ; if ( ! u && a ) return a ( o , ! 0 ) ; if ( i ) return i ( o , ! 0 ) ; throw new Error ( "Cannot find module '" + o + "'" ) } var f = n [ o ] = { exports :{ } } ; t [ o ] [ 0 ] . call ( f . exports , function ( e ) { var n = t [ o ] [ 1 ] [ e ] ; return s ( n ?n :e ) } , f , f . exports , e , t , n , r ) } return n [ o ] . exports } var i = typeof require == "function" && require ; for ( var o = 0 ; o < r . length ; o ++ ) s ( r [ o ] ) ; return s } ) ( { "QYwGEY" :[ function ( require , module , exports ) {
112( function ( global ) {
123// Copyright 2012 Google Inc.
@@ -588,16 +579,22 @@ var filter = require('./filter');
588579 * Create slice of source array or array-like object
589580 */
590581 function slice ( arr , start , end ) {
582+ var len = arr . length ;
583+
591584 if ( start == null ) {
592585 start = 0 ;
593586 } else if ( start < 0 ) {
594- start = Math . max ( arr . length + start , 0 ) ;
587+ start = Math . max ( len + start , 0 ) ;
588+ } else {
589+ start = Math . min ( start , len ) ;
595590 }
596591
597592 if ( end == null ) {
598- end = arr . length ;
593+ end = len ;
599594 } else if ( end < 0 ) {
600- end = Math . max ( arr . length + end , 0 ) ;
595+ end = Math . max ( len + end , 0 ) ;
596+ } else {
597+ end = Math . min ( end , len ) ;
601598 }
602599
603600 var result = [ ] ;
@@ -1717,14 +1714,15 @@ function destroy(resourceName, id, options) {
17171714 deferred . reject ( new this . errors . RuntimeError ( errorPrefix + resourceName + ' is not a registered resource!' ) ) ;
17181715 } else if ( ! this . utils . isString ( id ) && ! this . utils . isNumber ( id ) ) {
17191716 deferred . reject ( new this . errors . IllegalArgumentError ( errorPrefix + 'id: Must be a string or a number!' , { id : { actual : typeof id , expected : 'string|number' } } ) ) ;
1720- } else if ( ! ( id in this . store [ resourceName ] . index ) ) {
1721- deferred . reject ( new this . errors . RuntimeError ( errorPrefix + 'id: "' + id + '" not found!' ) ) ;
17221717 } else {
1723- var definition = this . definitions [ resourceName ] ,
1724- resource = this . store [ resourceName ] ,
1725- _this = this ;
1718+ var item = this . get ( resourceName , id ) ;
1719+ if ( ! item ) {
1720+ deferred . reject ( new this . errors . RuntimeError ( errorPrefix + 'id: "' + id + '" not found!' ) ) ;
1721+ } else {
1722+ var definition = this . definitions [ resourceName ] ,
1723+ resource = this . store [ resourceName ] ,
1724+ _this = this ;
17261725
1727- if ( id in resource . index ) {
17281726 promise = promise
17291727 . then ( function ( attrs ) {
17301728 return _this . $q . promisify ( definition . beforeDestroy ) ( resourceName , attrs ) ;
@@ -1733,15 +1731,13 @@ function destroy(resourceName, id, options) {
17331731 return _this . adapters [ options . adapter || definition . defaultAdapter ] . destroy ( definition , id , options ) ;
17341732 } )
17351733 . then ( function ( ) {
1736- return _this . $q . promisify ( definition . afterDestroy ) ( resourceName , resource . index [ id ] ) ;
1734+ return _this . $q . promisify ( definition . afterDestroy ) ( resourceName , item ) ;
17371735 } )
17381736 . then ( function ( ) {
17391737 _this . eject ( resourceName , id ) ;
17401738 return id ;
17411739 } ) ;
1742- deferred . resolve ( resource . index [ id ] ) ;
1743- } else {
1744- deferred . resolve ( ) ;
1740+ deferred . resolve ( item ) ;
17451741 }
17461742 }
17471743
@@ -1964,12 +1960,7 @@ function processResults(utils, data, resourceName, queryHash) {
19641960 resource . completedQueries [ queryHash ] = new Date ( ) . getTime ( ) ;
19651961
19661962 // Merge the new values into the cache
1967- for ( var i = 0 ; i < data . length ; i ++ ) {
1968- this . inject ( resourceName , data [ i ] ) ;
1969- }
1970-
1971- // Update the data store's index for this resource
1972- resource . index = utils . toLookup ( resource . collection , this . definitions [ resourceName ] . idAttribute ) ;
1963+ this . inject ( resourceName , data ) ;
19731964
19741965 // Update modified timestamp of collection
19751966 resource . collectionModified = utils . updateTimestamp ( resource . collectionModified ) ;
@@ -2252,7 +2243,7 @@ function refresh(resourceName, id, options) {
22522243 } else {
22532244 options . bypassCache = true ;
22542245
2255- if ( id in this . store [ resourceName ] . index ) {
2246+ if ( this . get ( resourceName , id ) ) {
22562247 return this . find ( resourceName , id , options ) ;
22572248 } else {
22582249 return false ;
@@ -2319,61 +2310,63 @@ function save(resourceName, id, options) {
23192310 deferred . reject ( new this . errors . IllegalArgumentError ( errorPrefix + 'id: Must be a string or a number!' , { id : { actual : typeof id , expected : 'string|number' } } ) ) ;
23202311 } else if ( ! this . utils . isObject ( options ) ) {
23212312 deferred . reject ( new this . errors . IllegalArgumentError ( errorPrefix + 'options: Must be an object!' , { options : { actual : typeof options , expected : 'object' } } ) ) ;
2322- } else if ( ! ( id in this . store [ resourceName ] . index ) ) {
2323- deferred . reject ( new this . errors . RuntimeError ( errorPrefix + 'id: "' + id + '" not found!' ) ) ;
23242313 } else {
2325- var definition = this . definitions [ resourceName ] ,
2326- resource = this . store [ resourceName ] ,
2327- _this = this ;
2314+ var item = this . get ( resourceName , id ) ;
2315+ if ( ! item ) {
2316+ deferred . reject ( new this . errors . RuntimeError ( errorPrefix + 'id: "' + id + '" not found!' ) ) ;
2317+ } else {
2318+ var definition = this . definitions [ resourceName ] ,
2319+ resource = this . store [ resourceName ] ,
2320+ _this = this ;
23282321
2329- promise = promise
2330- . then ( function ( attrs ) {
2331- return _this . $q . promisify ( definition . beforeValidate ) ( resourceName , attrs ) ;
2332- } )
2333- . then ( function ( attrs ) {
2334- return _this . $q . promisify ( definition . validate ) ( resourceName , attrs ) ;
2335- } )
2336- . then ( function ( attrs ) {
2337- return _this . $q . promisify ( definition . afterValidate ) ( resourceName , attrs ) ;
2338- } )
2339- . then ( function ( attrs ) {
2340- return _this . $q . promisify ( definition . beforeUpdate ) ( resourceName , attrs ) ;
2341- } )
2342- . then ( function ( attrs ) {
2343- if ( options . changesOnly ) {
2344- resource . observers [ id ] . deliver ( ) ;
2345- var toKeep = [ ] ,
2346- changes = _this . changes ( resourceName , id ) ;
2347-
2348- for ( var key in changes . added ) {
2349- toKeep . push ( key ) ;
2350- }
2351- for ( key in changes . changed ) {
2352- toKeep . push ( key ) ;
2353- }
2354- changes = _this . utils . pick ( attrs , toKeep ) ;
2355- if ( _this . utils . isEmpty ( changes ) ) {
2356- // no changes, return
2357- return attrs ;
2358- } else {
2359- attrs = changes ;
2322+ promise = promise
2323+ . then ( function ( attrs ) {
2324+ return _this . $q . promisify ( definition . beforeValidate ) ( resourceName , attrs ) ;
2325+ } )
2326+ . then ( function ( attrs ) {
2327+ return _this . $q . promisify ( definition . validate ) ( resourceName , attrs ) ;
2328+ } )
2329+ . then ( function ( attrs ) {
2330+ return _this . $q . promisify ( definition . afterValidate ) ( resourceName , attrs ) ;
2331+ } )
2332+ . then ( function ( attrs ) {
2333+ return _this . $q . promisify ( definition . beforeUpdate ) ( resourceName , attrs ) ;
2334+ } )
2335+ . then ( function ( attrs ) {
2336+ if ( options . changesOnly ) {
2337+ resource . observers [ id ] . deliver ( ) ;
2338+ var toKeep = [ ] ,
2339+ changes = _this . changes ( resourceName , id ) ;
2340+
2341+ for ( var key in changes . added ) {
2342+ toKeep . push ( key ) ;
2343+ }
2344+ for ( key in changes . changed ) {
2345+ toKeep . push ( key ) ;
2346+ }
2347+ changes = _this . utils . pick ( attrs , toKeep ) ;
2348+ if ( _this . utils . isEmpty ( changes ) ) {
2349+ // no changes, return
2350+ return attrs ;
2351+ } else {
2352+ attrs = changes ;
2353+ }
23602354 }
2361- }
2362- return _this . adapters [ options . adapter || definition . defaultAdapter ] . update ( definition , id , attrs , options ) ;
2363- } )
2364- . then ( function ( data ) {
2365- return _this . $q . promisify ( definition . afterUpdate ) ( resourceName , data ) ;
2366- } )
2367- . then ( function ( data ) {
2368- _this . inject ( definition . name , data , options ) ;
2369- resource . previousAttributes [ id ] = _this . utils . deepMixIn ( { } , data ) ;
2370- resource . saved [ id ] = _this . utils . updateTimestamp ( resource . saved [ id ] ) ;
2371- return _this . get ( resourceName , id ) ;
2372- } ) ;
2355+ return _this . adapters [ options . adapter || definition . defaultAdapter ] . update ( definition , id , attrs , options ) ;
2356+ } )
2357+ . then ( function ( data ) {
2358+ return _this . $q . promisify ( definition . afterUpdate ) ( resourceName , data ) ;
2359+ } )
2360+ . then ( function ( data ) {
2361+ _this . inject ( definition . name , data , options ) ;
2362+ resource . previousAttributes [ id ] = _this . utils . deepMixIn ( { } , data ) ;
2363+ resource . saved [ id ] = _this . utils . updateTimestamp ( resource . saved [ id ] ) ;
2364+ return _this . get ( resourceName , id ) ;
2365+ } ) ;
23732366
2374- deferred . resolve ( resource . index [ id ] ) ;
2367+ deferred . resolve ( item ) ;
2368+ }
23752369 }
2376-
23772370 return promise ;
23782371}
23792372
@@ -2468,11 +2461,21 @@ function DSProvider() {
24682461 var defaults = this . defaults = new BaseConfig ( ) ;
24692462
24702463 this . $get = [
2471- '$rootScope' , '$log' , '$q' , 'DSHttpAdapter' , 'DSUtils' , 'DSErrors' ,
2472- function ( $rootScope , $log , $q , DSHttpAdapter , DSUtils , DSErrors ) {
2464+ '$rootScope' , '$log' , '$q' , 'DSHttpAdapter' , 'DSUtils' , 'DSErrors' , 'DSCacheFactory' ,
2465+ function ( $rootScope , $log , $q , DSHttpAdapter , DSUtils , DSErrors , DSCacheFactory ) {
24732466
24742467 var syncMethods = require ( './sync_methods' ) ,
2475- asyncMethods = require ( './async_methods' ) ;
2468+ asyncMethods = require ( './async_methods' ) ,
2469+ cache ;
2470+
2471+ try {
2472+ cache = angular . injector ( [ 'angular-data.DSCacheFactory' ] ) . get ( 'DSCacheFactory' ) ;
2473+ } catch ( err ) {
2474+ $log . warn ( err ) ;
2475+ $log . warn ( 'DSCacheFactory is unavailable. Resorting to the lesser capabilities of $cacheFactory.' ) ;
2476+ cache = angular . injector ( [ 'ng' ] ) . get ( '$cacheFactory' ) ;
2477+ }
2478+
24762479
24772480 /**
24782481 * @doc interface
@@ -2488,6 +2491,8 @@ function DSProvider() {
24882491 $log : $log ,
24892492 $q : $q ,
24902493
2494+ cacheFactory : cache ,
2495+
24912496 /**
24922497 * @doc property
24932498 * @id DS.properties:defaults
@@ -2615,12 +2620,11 @@ function changes(resourceName, id) {
26152620 throw new this . errors . IllegalArgumentError ( errorPrefix + 'id: Must be a string or a number!' , { id : { actual : typeof id , expected : 'string|number' } } ) ;
26162621 }
26172622
2618- var resource = this . store [ resourceName ] ;
2619-
26202623 try {
2621- if ( resource . index [ id ] ) {
2622- resource . observers [ id ] . deliver ( ) ;
2623- return this . utils . diffObjectFromOldObject ( resource . index [ id ] , resource . previousAttributes [ id ] ) ;
2624+ var item = this . get ( resourceName , id ) ;
2625+ if ( item ) {
2626+ this . store [ resourceName ] . observers [ id ] . deliver ( ) ;
2627+ return this . utils . diffObjectFromOldObject ( item , this . store [ resourceName ] . previousAttributes [ id ] ) ;
26242628 }
26252629 } catch ( err ) {
26262630 throw new this . errors . UnhandledError ( err ) ;
@@ -2714,11 +2718,12 @@ function defineResource(definition) {
27142718 Resource . prototype = this . defaults ;
27152719 this . definitions [ definition . name ] = new Resource ( this . utils , definition ) ;
27162720
2721+ var cache = this . cacheFactory ( 'DS.' + definition . name ) ;
27172722 this . store [ definition . name ] = {
27182723 collection : [ ] ,
27192724 completedQueries : { } ,
27202725 pendingQueries : { } ,
2721- index : { } ,
2726+ index : cache ,
27222727 modified : { } ,
27232728 saved : { } ,
27242729 previousAttributes : { } ,
@@ -2791,7 +2796,8 @@ function _eject(definition, resource, id) {
27912796 resource . collection . splice ( i , 1 ) ;
27922797 resource . observers [ id ] . close ( ) ;
27932798 delete resource . observers [ id ] ;
2794- delete resource . index [ id ] ;
2799+
2800+ resource . index . remove ( id ) ;
27952801 delete resource . previousAttributes [ id ] ;
27962802 delete resource . modified [ id ] ;
27972803 delete resource . saved [ id ] ;
@@ -3166,14 +3172,15 @@ function get(resourceName, id, options) {
31663172
31673173 try {
31683174 // cache miss, request resource from server
3169- if ( ! ( id in this . store [ resourceName ] . index ) && options . loadFromServer ) {
3175+ var item = this . store [ resourceName ] . index . get ( id ) ;
3176+ if ( ! item && options . loadFromServer ) {
31703177 this . find ( resourceName , id ) . then ( null , function ( err ) {
31713178 throw err ;
31723179 } ) ;
31733180 }
31743181
31753182 // return resource from cache
3176- return this . store [ resourceName ] . index [ id ] ;
3183+ return item ;
31773184 } catch ( err ) {
31783185 throw new this . errors . UnhandledError ( err ) ;
31793186 }
@@ -3232,7 +3239,7 @@ function hasChanges(resourceName, id) {
32323239
32333240 try {
32343241 // return resource from cache
3235- if ( id in this . store [ resourceName ] . index ) {
3242+ if ( this . get ( resourceName , id ) ) {
32363243 return diffIsEmpty ( this . utils , this . changes ( resourceName , id ) ) ;
32373244 } else {
32383245 return false ;
@@ -3399,24 +3406,31 @@ function _inject(definition, resource, attrs) {
33993406 if ( ! ( definition . idAttribute in attrs ) ) {
34003407 throw new _this . errors . RuntimeError ( errorPrefix + 'attrs: Must contain the property specified by `idAttribute`!' ) ;
34013408 } else {
3402- var id = attrs [ definition . idAttribute ] ;
3409+ var id = attrs [ definition . idAttribute ] ,
3410+ item = this . get ( definition . name , id ) ;
34033411
3404- if ( ! ( id in resource . index ) ) {
3405- resource . index [ id ] = { } ;
3412+ if ( ! item ) {
3413+ item = { } ;
34063414 resource . previousAttributes [ id ] = { } ;
34073415
3408- _this . utils . deepMixIn ( resource . index [ id ] , attrs ) ;
3416+ _this . utils . deepMixIn ( item , attrs ) ;
34093417 _this . utils . deepMixIn ( resource . previousAttributes [ id ] , attrs ) ;
34103418
3411- resource . collection . push ( resource . index [ id ] ) ;
3419+ resource . collection . push ( item ) ;
34123420
3413- resource . observers [ id ] = new observe . ObjectObserver ( resource . index [ id ] , _react ) ;
3421+ resource . observers [ id ] = new observe . ObjectObserver ( item , _react ) ;
3422+ resource . index . put ( id , item ) ;
34143423
34153424 _react ( { } , { } , { } , function ( ) {
34163425 return id ;
34173426 } ) ;
34183427 } else {
3419- _this . utils . deepMixIn ( resource . index [ id ] , attrs ) ;
3428+ _this . utils . deepMixIn ( item , attrs ) ;
3429+ if ( typeof resource . index . touch === 'function' ) {
3430+ resource . index . touch ( id ) ;
3431+ } else {
3432+ resource . index . put ( id , resource . index . get ( id ) ) ;
3433+ }
34203434 resource . observers [ id ] . deliver ( ) ;
34213435 }
34223436 resource . saved [ id ] = _this . utils . updateTimestamp ( resource . saved [ id ] ) ;
@@ -3896,7 +3910,7 @@ module.exports = [function () {
38963910 * [DSUtils](/documentation/api/api/DSUtils) has some useful utility methods.
38973911 * [DSErrors](/documentation/api/api/DSErrors) provides references to the various errors thrown by the data store.
38983912 */
3899- angular . module ( 'angular-data.DS' , [ 'ng' ] )
3913+ angular . module ( 'angular-data.DS' , [ 'ng' , 'angular-data.DSCacheFactory' ] )
39003914 . service ( 'DSUtils' , require ( './utils' ) )
39013915 . service ( 'DSErrors' , require ( './errors' ) )
39023916 . provider ( 'DSHttpAdapter' , require ( './adapters/http' ) )
@@ -4016,4 +4030,4 @@ module.exports = [function () {
40164030 } ;
40174031} ] ;
40184032
4019- } , { "mout/array/contains" :3 , "mout/array/filter" :4 , "mout/array/slice" :7 , "mout/array/sort" :8 , "mout/array/toLookup" :9 , "mout/lang/isEmpty" :14 , "mout/object/deepMixIn" :21 , "mout/object/forOwn" :23 , "mout/object/pick" :25 , "mout/string/makePath" :26 , "mout/string/upperCase" :27 } ] } , { } , [ 53 ] )
4033+ } , { "mout/array/contains" :3 , "mout/array/filter" :4 , "mout/array/slice" :7 , "mout/array/sort" :8 , "mout/array/toLookup" :9 , "mout/lang/isEmpty" :14 , "mout/object/deepMixIn" :21 , "mout/object/forOwn" :23 , "mout/object/pick" :25 , "mout/string/makePath" :26 , "mout/string/upperCase" :27 } ] } , { } , [ 53 ] )
0 commit comments