export function docChanges()

in src/compat/firestore/collection/changes.ts [11:45]


export function docChanges<T>(query: Query, scheduler?: SchedulerLike): Observable<DocumentChangeAction<T>[]> {
  return fromCollectionRef(query, scheduler)
    .pipe(
      startWith<Action<QuerySnapshot<firebase.firestore.DocumentData>>, undefined>(undefined),
      pairwise(),
      map(([priorAction, action]) => {
        const docChanges = action.payload.docChanges();
        const actions = docChanges.map(change => ({ type: change.type, payload: change }));
        // the metadata has changed from the prior emission
        if (priorAction && JSON.stringify(priorAction.payload.metadata) !== JSON.stringify(action.payload.metadata)) {
          // go through all the docs in payload and figure out which ones changed
          action.payload.docs.forEach((currentDoc, currentIndex) => {
            const docChange = docChanges.find(d => d.doc.ref.isEqual(currentDoc.ref));
            const priorDoc = priorAction?.payload.docs.find(d => d.ref.isEqual(currentDoc.ref));
            if (docChange && JSON.stringify(docChange.doc.metadata) === JSON.stringify(currentDoc.metadata) ||
              !docChange && priorDoc && JSON.stringify(priorDoc.metadata) === JSON.stringify(currentDoc.metadata)) {
              // document doesn't appear to have changed, don't log another action
            } else {
              // since the actions are processed in order just push onto the array
              actions.push({
                type: 'modified',
                payload: {
                  oldIndex: currentIndex,
                  newIndex: currentIndex,
                  type: 'modified',
                  doc: currentDoc
                }
              });
            }
          });
        }
        return actions as DocumentChangeAction<T>[];
      }),
  );
}