in packages/database/src/core/view/ViewProcessor.ts [91:195]
export function viewProcessorApplyOperation(
viewProcessor: ViewProcessor,
oldViewCache: ViewCache,
operation: Operation,
writesCache: WriteTreeRef,
completeCache: Node | null
): ProcessorResult {
const accumulator = new ChildChangeAccumulator();
let newViewCache, filterServerNode;
if (operation.type === OperationType.OVERWRITE) {
const overwrite = operation as Overwrite;
if (overwrite.source.fromUser) {
newViewCache = viewProcessorApplyUserOverwrite(
viewProcessor,
oldViewCache,
overwrite.path,
overwrite.snap,
writesCache,
completeCache,
accumulator
);
} else {
assert(overwrite.source.fromServer, 'Unknown source.');
// We filter the node if it's a tagged update or the node has been previously filtered and the
// update is not at the root in which case it is ok (and necessary) to mark the node unfiltered
// again
filterServerNode =
overwrite.source.tagged ||
(oldViewCache.serverCache.isFiltered() && !pathIsEmpty(overwrite.path));
newViewCache = viewProcessorApplyServerOverwrite(
viewProcessor,
oldViewCache,
overwrite.path,
overwrite.snap,
writesCache,
completeCache,
filterServerNode,
accumulator
);
}
} else if (operation.type === OperationType.MERGE) {
const merge = operation as Merge;
if (merge.source.fromUser) {
newViewCache = viewProcessorApplyUserMerge(
viewProcessor,
oldViewCache,
merge.path,
merge.children,
writesCache,
completeCache,
accumulator
);
} else {
assert(merge.source.fromServer, 'Unknown source.');
// We filter the node if it's a tagged update or the node has been previously filtered
filterServerNode =
merge.source.tagged || oldViewCache.serverCache.isFiltered();
newViewCache = viewProcessorApplyServerMerge(
viewProcessor,
oldViewCache,
merge.path,
merge.children,
writesCache,
completeCache,
filterServerNode,
accumulator
);
}
} else if (operation.type === OperationType.ACK_USER_WRITE) {
const ackUserWrite = operation as AckUserWrite;
if (!ackUserWrite.revert) {
newViewCache = viewProcessorAckUserWrite(
viewProcessor,
oldViewCache,
ackUserWrite.path,
ackUserWrite.affectedTree,
writesCache,
completeCache,
accumulator
);
} else {
newViewCache = viewProcessorRevertUserWrite(
viewProcessor,
oldViewCache,
ackUserWrite.path,
writesCache,
completeCache,
accumulator
);
}
} else if (operation.type === OperationType.LISTEN_COMPLETE) {
newViewCache = viewProcessorListenComplete(
viewProcessor,
oldViewCache,
operation.path,
writesCache,
accumulator
);
} else {
throw assertionError('Unknown operation type: ' + operation.type);
}
const changes = accumulator.getChanges();
viewProcessorMaybeAddValueEvent(oldViewCache, newViewCache, changes);
return { viewCache: newViewCache, changes };
}