@@ -189,104 +189,110 @@ export default class ArSyncStore {
189189 return this . batchUpdate ( [ patch ] )
190190 }
191191 _slicePatch ( patchData , request ) {
192- const obj = { }
193- for ( const key in patchData ) {
194- if ( key === 'id' || request . query [ '*' ] ) {
195- obj [ key ] = patchData [ key ]
196- } else {
197- const subq = request . query [ key ]
198- if ( subq ) {
199- obj [ subq . column || key ] = patchData [ key ]
200- }
201- }
192+ const obj = request . query && request . query [ '*' ] ? { ...patchData } : { }
193+ for ( const key in request ) {
194+ const fieldQuery = request [ key ]
195+ const field = ( fieldQuery && fieldQuery . field ) || key
196+ if ( field in patchData ) obj [ key ] = patchData [ field ]
202197 }
198+ if ( patchData . id ) obj . id = patchData . id
203199 return obj
204200 }
205- _applyPatch ( data , accessKeys , actualPath , updator , request , patchData ) {
201+ _applyPatch ( data , accessKeys , actualPath , updator , query , patchData ) {
206202 for ( const key in patchData ) {
207- const subq = request . query [ key ]
208- const value = patchData [ key ]
209- if ( subq || request . query [ '*' ] ) {
210- const subcol = ( subq && subq . column ) || key
211- if ( data [ subcol ] !== value ) {
212- this . data = updator . add ( this . data , accessKeys , actualPath , subcol , value )
203+ const subq = query [ key ]
204+ const value = patchData [ ( subq && subq . field ) || key ]
205+ if ( subq || query [ '*' ] ) {
206+ if ( data [ key ] !== value ) {
207+ this . data = updator . add ( this . data , accessKeys , actualPath , key , value )
213208 }
214209 }
215210 }
216211 }
217- _update ( patch , updator , events ) {
212+ _update ( patch : { action : string ; path : ( string | number ) [ ] ; ordering ; data } , updator , events ) {
218213 const { action, path } = patch
219214 const patchData = patch . data
220215 let request = this . request
221216 let data = this . data
222- const actualPath : ( string | number ) [ ] = [ ]
223- const accessKeys : ( string | number ) [ ] = [ ]
224- for ( let i = 0 ; i < path . length - 1 ; i ++ ) {
217+ const trace = ( i : number , actualPath : ( string | number ) [ ] , accessKeys : ( string | number ) [ ] , query , data ) => {
225218 const nameOrId = path [ i ]
219+ const lastStep = i === path . length - 1
226220 if ( typeof ( nameOrId ) === 'number' ) {
227221 const idx = data . findIndex ( o => o . id === nameOrId )
228- if ( idx < 0 ) return
229- actualPath . push ( nameOrId )
230- accessKeys . push ( idx )
231- data = data [ idx ]
222+ if ( lastStep ) {
223+ apply ( accessKeys , actualPath , query , null , idx , data [ idx ] )
224+ } else {
225+ if ( idx < 0 ) return
226+ actualPath . push ( nameOrId )
227+ accessKeys . push ( idx )
228+ const data2 = data [ idx ]
229+ trace ( i + 1 , actualPath , accessKeys , query , data2 )
230+ }
232231 } else {
233- const { query } = request
234- if ( ! query [ nameOrId ] ) return
235- const column = query [ nameOrId ] . column || nameOrId
236- request = query [ nameOrId ]
237- actualPath . push ( column )
238- accessKeys . push ( column )
239- data = data [ column ]
232+ const matchedKeys : string [ ] = [ ]
233+ for ( const key in query ) {
234+ const field = query [ key ] . field || key
235+ if ( field === nameOrId ) matchedKeys . push ( key )
236+ }
237+ const fork = matchedKeys . length > 1
238+ for ( const key of matchedKeys ) {
239+ const queryField = query [ key ]
240+ if ( lastStep ) {
241+ if ( ! queryField ) return
242+ apply ( accessKeys , actualPath , query [ key ] , key , null , data [ key ] )
243+ } else {
244+ const data2 = data [ key ]
245+ if ( ! data2 ) return
246+ const actualPath2 = fork ? [ ...actualPath ] : actualPath
247+ const accessKeys2 = fork ? [ ...accessKeys ] : accessKeys
248+ actualPath2 . push ( key )
249+ accessKeys2 . push ( key )
250+ trace ( i + 1 , actualPath2 , accessKeys2 , queryField . query , data2 )
251+ }
252+ }
240253 }
241- if ( ! data ) return
242- }
243- const nameOrId = path [ path . length - 1 ]
244- let id , idx , column , target = data
245- if ( typeof ( nameOrId ) === 'number' ) {
246- id = nameOrId
247- idx = data . findIndex ( o => o . id === id )
248- target = data [ idx ]
249- } else if ( nameOrId ) {
250- const { query } = request
251- if ( ! query [ nameOrId ] ) return
252- column = query [ nameOrId ] . column || nameOrId
253- request = query [ nameOrId ]
254- target = data [ column ]
255254 }
256- if ( action === 'create' ) {
257- const obj = this . _slicePatch ( patchData , request )
258- if ( column ) {
259- this . data = updator . add ( this . data , accessKeys , actualPath , column , obj )
260- } else if ( ! target ) {
261- const ordering = Object . assign ( { } , patch . ordering )
262- const limitOverride = request . params && request . params . limit
263- ordering . order = request . params && request . params . order || ordering . order
264- if ( ordering . limit == null || limitOverride != null && limitOverride < ordering . limit ) ordering . limit = limitOverride
265- this . data = updator . add ( this . data , accessKeys , actualPath , data . length , obj , ordering )
255+ const apply = ( accessKeys : ( string | number ) [ ] , actualPath : ( string | number ) [ ] , query , column : string | null , idx : number | null , target ) => {
256+ if ( action === 'create' ) {
257+ const obj = this . _slicePatch ( patchData , query )
258+ if ( column ) {
259+ this . data = updator . add ( this . data , accessKeys , actualPath , column , obj )
260+ } else if ( ! target ) {
261+ const ordering = Object . assign ( { } , patch . ordering )
262+ const limitOverride = request . params && request . params . limit
263+ ordering . order = request . params && request . params . order || ordering . order
264+ if ( ordering . limit == null || limitOverride != null && limitOverride < ordering . limit ) ordering . limit = limitOverride
265+ this . data = updator . add ( this . data , accessKeys , actualPath , data . length , obj , ordering )
266+ }
267+ return
266268 }
267- return
268- }
269- if ( action === 'destroy' ) {
269+ if ( action === 'destroy' ) {
270+ if ( column ) {
271+ this . data = updator . remove ( this . data , accessKeys , actualPath , column )
272+ } else if ( idx != null ) {
273+ this . data = updator . remove ( this . data , accessKeys , actualPath , idx )
274+ }
275+ return
276+ }
277+ if ( ! target ) return
270278 if ( column ) {
271- this . data = updator . remove ( this . data , accessKeys , actualPath , column )
272- } else if ( idx >= 0 ) {
273- this . data = updator . remove ( this . data , accessKeys , actualPath , idx )
279+ actualPath . push ( column )
280+ accessKeys . push ( column )
281+ } else if ( idx != null && patchData . id ) {
282+ actualPath . push ( patchData . id )
283+ accessKeys . push ( idx )
284+ }
285+ if ( action === 'update' ) {
286+ this . _applyPatch ( target , accessKeys , actualPath , updator , query , patchData )
287+ } else {
288+ const eventData = { target, path : actualPath , data : patchData . data }
289+ events . push ( { type : patchData . type , data : eventData } )
274290 }
275- return
276- }
277- if ( ! target ) return
278- if ( column ) {
279- actualPath . push ( column )
280- accessKeys . push ( column )
281- } else if ( id ) {
282- actualPath . push ( id )
283- accessKeys . push ( idx )
284291 }
285- if ( action === 'update' ) {
286- this . _applyPatch ( target , accessKeys , actualPath , updator , request , patchData )
292+ if ( patch . path . length === 0 ) {
293+ apply ( [ ] , [ ] , request . query , null , null , data )
287294 } else {
288- const eventData = { target, path : actualPath , data : patchData . data }
289- events . push ( { type : patchData . type , data : eventData } )
295+ trace ( 0 , [ ] , [ ] , request . query , data )
290296 }
291297 }
292298}
0 commit comments