11// Provider class to be subclassed by an actual provider
22
33import Error from './error' ;
4- import Emitter from './events ' ;
4+ import Emitter from './emitter ' ;
55
66// ////////////////////////////////////////////////////////////////////////////
77// CONSTANTS
@@ -71,8 +71,11 @@ export default class Provider extends Emitter {
7171 if ( this . $array ( data ) ) {
7272 changed = true ;
7373 }
74- } else if ( this . $object ( data ) ) {
75- changed = true ;
74+ } else {
75+ const result = this . $object ( data ) ;
76+ if ( result [ 1 ] ) {
77+ changed = true ;
78+ }
7679 }
7780 } )
7881 . then ( ( ) => {
@@ -87,44 +90,65 @@ export default class Provider extends Emitter {
8790 } ) ;
8891 }
8992
93+ static $key ( obj ) {
94+ return typeof obj === 'object' ? obj . key : null ;
95+ }
96+
97+ static $equals ( a , b ) {
98+ return a . $equals ? a . $equals ( b ) : a === b ;
99+ }
100+
90101 $object ( data ) {
91102 const obj = new this . $constructor ( data ) ;
92- const key = typeof obj === 'object' ? obj . key : null ;
93- if ( key ) {
94- if ( this . $objs . has ( key ) ) {
95- const existing = this . $objs . get ( key ) ;
96- this . $objs . set ( key , obj ) ;
97- if ( obj . $equals && obj . $equals ( existing ) === false ) {
98- this . dispatchEvent ( EVENT_CHANGED , this , obj , existing ) ;
99- }
103+ const key = this . constructor . $key ( obj ) ;
104+ let changed = true ;
105+ if ( key && this . $objs . has ( key ) ) {
106+ const existing = this . $objs . get ( key ) ;
107+ this . $objs . set ( key , obj ) ;
108+ if ( this . constructor . $equals ( obj , existing ) === false ) {
109+ this . dispatchEvent ( EVENT_CHANGED , this , obj , existing ) ;
100110 } else {
101- this . $objs . set ( key , obj ) ;
102- this . dispatchEvent ( EVENT_ADDED , this , obj ) ;
111+ changed = false ;
103112 }
104113 } else {
114+ if ( key ) {
115+ this . $objs . set ( key , obj ) ;
116+ }
105117 this . dispatchEvent ( EVENT_ADDED , this , obj ) ;
106118 }
107- return key ;
119+ return [ key , changed ] ;
108120 }
109121
110122 $array ( data ) {
111- const changed = false ;
123+ let changed = false ;
112124 const mark = new Map ( ) ;
125+
126+ // Mark existing objects
113127 this . $objs . forEach ( ( _ , key ) => {
114128 mark . set ( key , true ) ;
115129 } ) ;
130+
131+ // Add and change objects
116132 data . forEach ( ( elem ) => {
117- const key = this . $object ( elem ) ;
118- if ( key ) {
119- mark . delete ( key ) ;
133+ const result = this . $object ( elem ) ;
134+ if ( result [ 0 ] ) {
135+ mark . delete ( result [ 0 ] ) ;
136+ }
137+ if ( result [ 1 ] ) {
138+ changed = true ;
120139 }
121140 } ) ;
141+
142+ // Delete objects which are still marked
122143 this . $objs . forEach ( ( elem , key ) => {
123144 if ( mark . get ( key ) ) {
145+ changed = true ;
124146 this . dispatchEvent ( EVENT_DELETED , this , elem ) ;
125147 this . $objs . delete ( key ) ;
126148 }
127149 } ) ;
150+
151+ // Return true if the items were changed
128152 return changed ;
129153 }
130154
@@ -143,8 +167,8 @@ export default class Provider extends Emitter {
143167 return this . $objs . get ( key ) ;
144168 }
145169
146- // removeAll resets the provider
147- removeAll ( ) {
170+ // clear removes all objects from the provider
171+ clear ( ) {
148172 this . $objs . clear ( ) ;
149173 }
150174}
0 commit comments