export function viewProcessorApplyOperation()

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 };
}