Skip to content

Commit 9f0ec87

Browse files
committed
tree: as → field
1 parent 8221c27 commit 9f0ec87

File tree

1 file changed

+81
-75
lines changed

1 file changed

+81
-75
lines changed

src/tree/ArSyncStore.ts

Lines changed: 81 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)