in packages/database/src/core/view/ViewProcessor.ts [427:514]
function viewProcessorApplyUserOverwrite(
viewProcessor: ViewProcessor,
oldViewCache: ViewCache,
changePath: Path,
changedSnap: Node,
writesCache: WriteTreeRef,
completeCache: Node | null,
accumulator: ChildChangeAccumulator
): ViewCache {
const oldEventSnap = oldViewCache.eventCache;
let newViewCache, newEventCache;
const source = new WriteTreeCompleteChildSource(
writesCache,
oldViewCache,
completeCache
);
if (pathIsEmpty(changePath)) {
newEventCache = viewProcessor.filter.updateFullNode(
oldViewCache.eventCache.getNode(),
changedSnap,
accumulator
);
newViewCache = viewCacheUpdateEventSnap(
oldViewCache,
newEventCache,
true,
viewProcessor.filter.filtersNodes()
);
} else {
const childKey = pathGetFront(changePath);
if (childKey === '.priority') {
newEventCache = viewProcessor.filter.updatePriority(
oldViewCache.eventCache.getNode(),
changedSnap
);
newViewCache = viewCacheUpdateEventSnap(
oldViewCache,
newEventCache,
oldEventSnap.isFullyInitialized(),
oldEventSnap.isFiltered()
);
} else {
const childChangePath = pathPopFront(changePath);
const oldChild = oldEventSnap.getNode().getImmediateChild(childKey);
let newChild;
if (pathIsEmpty(childChangePath)) {
// Child overwrite, we can replace the child
newChild = changedSnap;
} else {
const childNode = source.getCompleteChild(childKey);
if (childNode != null) {
if (
pathGetBack(childChangePath) === '.priority' &&
childNode.getChild(pathParent(childChangePath)).isEmpty()
) {
// This is a priority update on an empty node. If this node exists on the server, the
// server will send down the priority in the update, so ignore for now
newChild = childNode;
} else {
newChild = childNode.updateChild(childChangePath, changedSnap);
}
} else {
// There is no complete child node available
newChild = ChildrenNode.EMPTY_NODE;
}
}
if (!oldChild.equals(newChild)) {
const newEventSnap = viewProcessor.filter.updateChild(
oldEventSnap.getNode(),
childKey,
newChild,
childChangePath,
source,
accumulator
);
newViewCache = viewCacheUpdateEventSnap(
oldViewCache,
newEventSnap,
oldEventSnap.isFullyInitialized(),
viewProcessor.filter.filtersNodes()
);
} else {
newViewCache = oldViewCache;
}
}
}
return newViewCache;
}