(subTree, startingPath, oldPaths, events)
| 23 | */ |
| 24 | |
| 25 | export function computePaths(subTree, startingPath, oldPaths, events) { |
| 26 | const {strs: oldStrs, objs: oldObjs} = oldPaths || {strs: {}, objs: {}}; |
| 27 | |
| 28 | const diffHead = path => startingPath.some((v, i) => path[i] !== v); |
| 29 | |
| 30 | const spLen = startingPath.length; |
| 31 | // if we're updating a subtree, clear out all of the existing items |
| 32 | const strs = spLen ? filter(diffHead, oldStrs) : {}; |
| 33 | const objs = {}; |
| 34 | if (spLen) { |
| 35 | forEachObjIndexed((oldValPaths, oldKeys) => { |
| 36 | const newVals = filter(({path}) => diffHead(path), oldValPaths); |
| 37 | if (newVals.length) { |
| 38 | objs[oldKeys] = newVals; |
| 39 | } |
| 40 | }, oldObjs); |
| 41 | } |
| 42 | |
| 43 | crawlLayout(subTree, (child, itempath) => { |
| 44 | const id = path(['props', 'id'], child); |
| 45 | if (id) { |
| 46 | if (typeof id === 'object') { |
| 47 | const keys = Object.keys(id).sort(); |
| 48 | const values = props(keys, id); |
| 49 | const keyStr = keys.join(','); |
| 50 | const paths = (objs[keyStr] = objs[keyStr] || []); |
| 51 | const oldie = oldObjs[keyStr] || []; |
| 52 | const item = {values, path: concat(startingPath, itempath)}; |
| 53 | const index = indexOf(item, oldie); |
| 54 | if (index === -1) { |
| 55 | paths.push(item); |
| 56 | } else { |
| 57 | objs[keyStr] = insert(index, item, paths); |
| 58 | } |
| 59 | } else { |
| 60 | strs[id] = concat(startingPath, itempath); |
| 61 | } |
| 62 | } |
| 63 | }); |
| 64 | |
| 65 | // We include an event emitter here because it will be used along with |
| 66 | // paths to determine when the app is ready for callbacks. |
| 67 | return {strs, objs, events: events || oldPaths.events}; |
| 68 | } |
| 69 | |
| 70 | export function getPath(paths, id) { |
| 71 | if (typeof id === 'object') { |
no test coverage detected
searching dependent graphs…