UNPKG

@magnetarjs/plugin-firestore

Version:
67 lines (66 loc) 3.2 kB
import { getFirestoreCollectionPath, getFirestoreDocPath, } from '@magnetarjs/utils-firestore'; import { doc, onSnapshot } from 'firebase/firestore'; import { docSnapshotToDocMetadata, getQueryInstance } from '../helpers/getFirestore.js'; export function streamActionFactory(firestorePluginOptions) { return function ({ payload, collectionPath, docId, pluginModuleConfig, mustExecuteOnRead, }) { const { added, modified, removed } = mustExecuteOnRead; const { db, debug } = firestorePluginOptions; let resolveStream; let rejectStream; const streaming = new Promise((resolve, reject) => { resolveStream = resolve; rejectStream = reject; }); let closeStream; // in case of a doc module if (docId) { const documentPath = getFirestoreDocPath(collectionPath, docId, pluginModuleConfig, firestorePluginOptions); // prettier-ignore closeStream = onSnapshot(doc(db, documentPath), (docSnapshot) => { // even if `docSnapshot.metadata.hasPendingWrites` // we should always execute `added/modified` // because `core` handles overlapping calls for us // do nothing if the doc doesn't exist if (!docSnapshot.exists()) return; // serverChanges only const docData = docSnapshot.data(); const docMetadata = docSnapshotToDocMetadata(docSnapshot); if (docData) added(docData, docMetadata); }, rejectStream); } // in case of a collection module else if (!docId) { const _collectionPath = getFirestoreCollectionPath(collectionPath, pluginModuleConfig, firestorePluginOptions); // prettier-ignore const query = getQueryInstance(_collectionPath, pluginModuleConfig, db, debug); closeStream = onSnapshot(query, (querySnapshot) => { // even if `docSnapshot.metadata.hasPendingWrites` // we should always execute `added/modified` // because `core` handles overlapping calls for us // serverChanges only querySnapshot .docChanges() .forEach((docChange) => { const docSnapshot = docChange.doc; const docData = docSnapshot.data(); const docMetadata = docSnapshotToDocMetadata(docSnapshot); if (docChange.type === 'added' && docData) { added(docData, docMetadata); } if (docChange.type === 'modified' && docData) { modified(docData, docMetadata); } if (docChange.type === 'removed') { removed(docData, docMetadata); } }); }, rejectStream); } function stop() { if (resolveStream) resolveStream(); closeStream(); } return { stop, streaming }; }; }