@@ -18,6 +18,7 @@ const AVAILABLE_CONST_OPTIONS = [
1818 'comparator' ,
1919 'params' ,
2020 'repository' ,
21+ 'linkRelations' ,
2122] ;
2223
2324export default class Store {
@@ -38,6 +39,7 @@ export default class Store {
3839 Model = null ;
3940 api = null ;
4041 __repository ;
42+ __linkRelations ;
4143 static backendResourceName = '' ;
4244
4345 url ( ) {
@@ -81,6 +83,11 @@ export default class Store {
8183 ) ;
8284 } ) ;
8385 this . __repository = options . repository ;
86+ this . __linkRelations = options . linkRelations || 'tree' ;
87+ invariant (
88+ [ 'tree' , 'graph' ] . includes ( this . __linkRelations ) ,
89+ `Unknown relation linking method: ${ this . __linkRelations } ` ,
90+ ) ;
8491 if ( options . relations ) {
8592 this . __parseRelations ( options . relations ) ;
8693 }
@@ -113,33 +120,52 @@ export default class Store {
113120 }
114121
115122 @action
116- fromBackend ( { data, repos, relMapping, reverseRelMapping } ) {
123+ fromBackend ( { data, repos, relMapping, reverseRelMapping, relCache = { } , relPath = 'root' } ) {
117124 invariant (
118125 data ,
119126 'Backend error. Data is not set. HINT: DID YOU FORGET THE M2M again?'
120127 ) ;
121128
122129 this . models . replace (
123130 data . map ( record => {
131+ const relCacheKey = `${ relPath } :${ record . id } `
132+
133+ if ( this . __linkRelations === 'graph' ) {
134+ const model = relCache [ relCacheKey ] ;
135+ if ( model !== undefined ) {
136+ return model ;
137+ }
138+ }
139+
124140 // TODO: I'm not happy at all about how this looks.
125141 // We'll need to finetune some things, but hey, for now it works.
126- const model = this . _newModel ( ) ;
142+
143+ const model = this . _newModel ( null ) ;
127144 model . fromBackend ( {
128145 data : record ,
129146 repos,
130147 relMapping,
131148 reverseRelMapping,
149+ relCache,
150+ relPath,
132151 } ) ;
152+
153+ if ( this . __linkRelations === 'graph' ) {
154+ relCache [ relCacheKey ] = model ;
155+ }
156+
133157 return model ;
134158 } )
135159 ) ;
136160 this . sort ( ) ;
137161 }
138162
139- _newModel ( model = null ) {
163+ _newModel ( model = null , options = { } ) {
140164 return new this . Model ( model , {
165+ ...options ,
141166 store : this ,
142167 relations : this . __activeRelations ,
168+ linkRelations : this . __linkRelations ,
143169 } ) ;
144170 }
145171
@@ -170,7 +196,7 @@ export default class Store {
170196 ) ;
171197 // Parse does not mutate __setChanged, as it is used in
172198 // fromBackend in the model...
173- this . models . replace ( models . map ( this . _newModel . bind ( this ) ) ) ;
199+ this . models . replace ( models . map ( ( data ) => this . _newModel ( data ) ) ) ;
174200 this . sort ( ) ;
175201
176202 return this ;
@@ -193,7 +219,7 @@ export default class Store {
193219 const singular = ! isArray ( models ) ;
194220 models = singular ? [ models ] : models . slice ( ) ;
195221
196- const modelInstances = models . map ( this . _newModel . bind ( this ) ) ;
222+ const modelInstances = models . map ( ( data ) => this . _newModel ( data ) ) ;
197223
198224 modelInstances . forEach ( modelInstance => {
199225 const primaryValue = modelInstance [ this . Model . primaryKey ] ;
0 commit comments