in packages/database/src/core/view/ViewProcessor.ts [774:880]
function viewProcessorRevertUserWrite(
viewProcessor: ViewProcessor,
viewCache: ViewCache,
path: Path,
writesCache: WriteTreeRef,
completeServerCache: Node | null,
accumulator: ChildChangeAccumulator
): ViewCache {
let complete;
if (writeTreeRefShadowingWrite(writesCache, path) != null) {
return viewCache;
} else {
const source = new WriteTreeCompleteChildSource(
writesCache,
viewCache,
completeServerCache
);
const oldEventCache = viewCache.eventCache.getNode();
let newEventCache;
if (pathIsEmpty(path) || pathGetFront(path) === '.priority') {
let newNode;
if (viewCache.serverCache.isFullyInitialized()) {
newNode = writeTreeRefCalcCompleteEventCache(
writesCache,
viewCacheGetCompleteServerSnap(viewCache)
);
} else {
const serverChildren = viewCache.serverCache.getNode();
assert(
serverChildren instanceof ChildrenNode,
'serverChildren would be complete if leaf node'
);
newNode = writeTreeRefCalcCompleteEventChildren(
writesCache,
serverChildren as ChildrenNode
);
}
newNode = newNode as Node;
newEventCache = viewProcessor.filter.updateFullNode(
oldEventCache,
newNode,
accumulator
);
} else {
const childKey = pathGetFront(path);
let newChild = writeTreeRefCalcCompleteChild(
writesCache,
childKey,
viewCache.serverCache
);
if (
newChild == null &&
viewCache.serverCache.isCompleteForChild(childKey)
) {
newChild = oldEventCache.getImmediateChild(childKey);
}
if (newChild != null) {
newEventCache = viewProcessor.filter.updateChild(
oldEventCache,
childKey,
newChild,
pathPopFront(path),
source,
accumulator
);
} else if (viewCache.eventCache.getNode().hasChild(childKey)) {
// No complete child available, delete the existing one, if any
newEventCache = viewProcessor.filter.updateChild(
oldEventCache,
childKey,
ChildrenNode.EMPTY_NODE,
pathPopFront(path),
source,
accumulator
);
} else {
newEventCache = oldEventCache;
}
if (
newEventCache.isEmpty() &&
viewCache.serverCache.isFullyInitialized()
) {
// We might have reverted all child writes. Maybe the old event was a leaf node
complete = writeTreeRefCalcCompleteEventCache(
writesCache,
viewCacheGetCompleteServerSnap(viewCache)
);
if (complete.isLeafNode()) {
newEventCache = viewProcessor.filter.updateFullNode(
newEventCache,
complete,
accumulator
);
}
}
}
complete =
viewCache.serverCache.isFullyInitialized() ||
writeTreeRefShadowingWrite(writesCache, newEmptyPath()) != null;
return viewCacheUpdateEventSnap(
viewCache,
newEventCache,
complete,
viewProcessor.filter.filtersNodes()
);
}
}