@dereekb/firebase 13.0.5 → 13.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.cjs.js CHANGED
@@ -662,31 +662,33 @@ function extendFirestoreCollectionWithSingleDocumentAccessor(x, singleItemIdenti
662
662
  }
663
663
 
664
664
  /**
665
- * Creates an array of new FirestoreDocument instances without creating them in Firestore.
665
+ * Creates an array of new {@link FirestoreDocument} instances without persisting them to Firestore.
666
666
  *
667
- * @template T - The document data type
668
- * @template D - The FirestoreDocument implementation type
669
- * @param documentAccessor - The document accessor to use for creating document instances
670
- * @param count - The number of document instances to create
671
- * @returns An array of new document instances
667
+ * Each document is allocated a unique auto-generated ID via {@link FirestoreDocumentAccessor.newDocument},
668
+ * but no data is written to the database. Useful for preparing document references in bulk before
669
+ * deciding what data to write.
670
+ *
671
+ * @param documentAccessor - Accessor that provides the `newDocument()` factory method
672
+ * @param count - Number of document instances to create
673
+ * @returns Array of `count` new document instances, each with a unique auto-generated ID
672
674
  */
673
675
  function newDocuments(documentAccessor, count) {
674
676
  return util.makeWithFactory(() => documentAccessor.newDocument(), count);
675
677
  }
676
678
  /**
677
- * Creates multiple documents in Firestore and returns the document instances.
679
+ * Creates and optionally persists multiple Firestore documents in sequence.
678
680
  *
679
- * For each document, this function:
680
- * 1. Creates a new document instance using the specified or default factory
681
- * 2. Calls the init function with the document instance
682
- * 3. If init returns data, creates the document in Firestore
683
- * 4. Returns all document instances, whether they were created in Firestore or not
681
+ * Uses {@link performMakeLoop} to iterate `count` times. For each iteration:
682
+ * 1. A new document instance is created (via `make.newDocument` or the default factory)
683
+ * 2. `make.init(i, document)` is awaited to produce initial data
684
+ * 3. If init returns non-nullish data, `document.accessor.create(data)` persists it
685
+ * 4. The document instance is collected regardless of whether it was persisted
684
686
  *
685
- * @template T - The document data type
686
- * @template D - The FirestoreDocument implementation type
687
- * @param documentAccessor - The document accessor to use for creating document instances
688
- * @param make - Parameters for document creation and initialization
689
- * @returns A promise that resolves to an array of document instances
687
+ * Documents are created sequentially (not in parallel) to allow index-dependent logic.
688
+ *
689
+ * @param documentAccessor - Accessor providing the document factory and collection context
690
+ * @param make - Configuration controlling count, factory, and initialization
691
+ * @returns Promise resolving to all created document instances (length === `make.count`)
690
692
  */
691
693
  function makeDocuments(documentAccessor, make) {
692
694
  const newDocumentFn = make.newDocument ?? (() => documentAccessor.newDocument());
@@ -703,65 +705,52 @@ function makeDocuments(documentAccessor, make) {
703
705
  });
704
706
  }
705
707
  /**
706
- * Retrieves DocumentSnapshots for an array of documents in parallel.
708
+ * Fetches {@link DocumentSnapshot}s for multiple documents in parallel using {@link runAsyncTasksForValues}.
707
709
  *
708
- * This is useful for fetching the current state of multiple documents at once.
710
+ * Each document's `accessor.get()` is called concurrently. The returned array preserves
711
+ * the same ordering as the input `documents` array.
709
712
  *
710
- * @template D - The FirestoreDocument implementation type
711
- * @param documents - Array of document instances to get snapshots for
712
- * @returns Promise that resolves to an array of DocumentSnapshots in the same order as the input documents
713
+ * @param documents - Documents to fetch snapshots for
714
+ * @returns Snapshots in the same order as the input array
713
715
  */
714
716
  function getDocumentSnapshots(documents) {
715
717
  return util.runAsyncTasksForValues(documents, (x) => x.accessor.get());
716
718
  }
717
719
  /**
718
- * Creates a document-snapshot pair from a document instance.
720
+ * Fetches the current snapshot of a single document and pairs it with the document instance.
719
721
  *
720
- * Fetches the current snapshot of the document and returns both the original
721
- * document instance and the snapshot together.
722
- *
723
- * @template D - The FirestoreDocument implementation type
724
- * @param document - The document instance to get a snapshot for
725
- * @returns Promise that resolves to a document-snapshot pair
722
+ * @param document - The document to fetch
723
+ * @returns A pair containing the document and its snapshot
726
724
  */
727
725
  function getDocumentSnapshotPair(document) {
728
726
  return document.accessor.get().then((snapshot) => ({ document, snapshot }));
729
727
  }
730
728
  /**
731
- * Creates document-snapshot pairs for an array of documents in parallel.
729
+ * Fetches snapshots for multiple documents in parallel and pairs each with its document instance.
732
730
  *
733
- * Fetches the current snapshot of each document and returns pairs containing both
734
- * the original document instances and their snapshots.
735
- *
736
- * @template D - The FirestoreDocument implementation type
737
- * @param documents - Array of document instances to get snapshots for
738
- * @returns Promise that resolves to an array of document-snapshot pairs in the same order as the input documents
731
+ * @param documents - Documents to fetch
732
+ * @returns Pairs in the same order as the input array
739
733
  */
740
734
  function getDocumentSnapshotPairs(documents) {
741
735
  return util.runAsyncTasksForValues(documents, getDocumentSnapshotPair);
742
736
  }
743
737
  /**
744
- * Creates a document-snapshot-data triplet from a document instance.
738
+ * Fetches a document's snapshot, extracts its data with `id`/`key` fields, and returns all three as a triplet.
745
739
  *
746
- * Fetches the current snapshot of the document, extracts its data with ID and key fields,
747
- * and returns all three together in a single object.
748
- *
749
- * @template D - The FirestoreDocument implementation type
750
- * @param document - The document instance to get data for
751
- * @returns Promise that resolves to a document-snapshot-data triplet
740
+ * @param document - The document to fetch
741
+ * @returns A triplet of document, snapshot, and data (data may be `undefined` if the document doesn't exist)
752
742
  */
753
743
  function getDocumentSnapshotDataPair(document) {
754
744
  return document.accessor.get().then((snapshot) => ({ document, snapshot, data: documentDataWithIdAndKey(snapshot) }));
755
745
  }
756
746
  /**
757
- * Creates document-snapshot-data triplets for an array of documents in parallel.
747
+ * Fetches snapshot-data triplets for multiple documents in parallel.
758
748
  *
759
- * Fetches the current snapshot of each document, extracts its data with ID and key fields,
760
- * and returns triplets containing all three components for each document.
749
+ * Processes up to 200 documents concurrently via {@link runAsyncTasksForValues}.
750
+ * The returned array preserves the same ordering as the input.
761
751
  *
762
- * @template D - The FirestoreDocument implementation type
763
- * @param documents - Array of document instances to get data for
764
- * @returns Promise that resolves to an array of document-snapshot-data triplets in the same order as the input documents
752
+ * @param documents - Documents to fetch
753
+ * @returns Triplets in the same order as the input array
765
754
  */
766
755
  function getDocumentSnapshotDataPairs(documents) {
767
756
  return util.runAsyncTasksForValues(documents, getDocumentSnapshotDataPair, {
@@ -769,18 +758,27 @@ function getDocumentSnapshotDataPairs(documents) {
769
758
  });
770
759
  }
771
760
  /**
772
- * Creates document-snapshot-data triplets for an array of documents and filters out those without data.
761
+ * Fetches snapshot-data triplets for multiple documents and filters out those that don't exist in Firestore.
773
762
  *
774
- * This is a convenience function that fetches data for all documents and then returns
775
- * only the triplets for documents that actually exist in Firestore.
763
+ * Convenience wrapper around {@link getDocumentSnapshotDataPairs} that removes entries where `data` is nullish,
764
+ * returning only {@link FirestoreDocumentSnapshotDataPairWithData} results.
776
765
  *
777
- * @template D - The FirestoreDocument implementation type
778
- * @param documents - Array of document instances to get data for
779
- * @returns Promise that resolves to an array of document-snapshot-data triplets for existing documents only
766
+ * @param documents - Documents to fetch
767
+ * @returns Triplets for documents that exist, in their original relative order
780
768
  */
781
769
  function getDocumentSnapshotDataPairsWithData(documents) {
782
770
  return getDocumentSnapshotDataPairs(documents).then((x) => x.filter((y) => !!y.data));
783
771
  }
772
+ /**
773
+ * Fetches raw snapshot data tuples for multiple documents in parallel.
774
+ *
775
+ * Unlike {@link getDocumentSnapshotDataPairs}, this returns a lightweight `[document, data]` tuple
776
+ * and does not inject `id`/`key` fields onto the data. The `data` value is the raw result of
777
+ * `snapshot.data()` and may be `undefined` for non-existent documents.
778
+ *
779
+ * @param documents - Documents to fetch
780
+ * @returns Tuples in the same order as the input array
781
+ */
784
782
  function getDocumentSnapshotDataTuples(documents) {
785
783
  return util.runAsyncTasksForValues(documents, (document) => document.accessor.get().then((snapshot) => [document, snapshot.data()]));
786
784
  }
@@ -794,33 +792,109 @@ function getDataFromDocumentSnapshots(snapshots, withId = true) {
794
792
  const mapFn = documentDataFunction(withId);
795
793
  return util.filterMaybeArrayValues(snapshots.map(mapFn));
796
794
  }
795
+ /**
796
+ * Creates {@link FirestoreDocument} instances for all documents in a {@link QuerySnapshot}.
797
+ *
798
+ * Maps each document in `snapshots.docs` to a loaded document via `accessor.loadDocument(ref)`.
799
+ * No additional data fetching occurs; the documents are loaded from their existing references.
800
+ *
801
+ * @param accessor - Accessor to load documents with
802
+ * @param snapshots - Query snapshot containing the document references
803
+ * @returns Document instances in the same order as the query results
804
+ */
797
805
  function loadDocumentsForSnapshots(accessor, snapshots) {
798
806
  return snapshots.docs.map((x) => accessor.loadDocument(x.ref));
799
807
  }
808
+ /**
809
+ * Extracts {@link DocumentReference}s from arbitrary values and loads them as {@link FirestoreDocument} instances.
810
+ *
811
+ * Convenience function that maps values through `getRef` then delegates to {@link loadDocumentsForDocumentReferences}.
812
+ *
813
+ * @param accessor - Accessor to load documents with
814
+ * @param values - Source values to extract references from
815
+ * @param getRef - Extracts a document reference from each value
816
+ * @returns Document instances in the same order as the input values
817
+ */
800
818
  function loadDocumentsForDocumentReferencesFromValues(accessor, values, getRef) {
801
819
  return loadDocumentsForDocumentReferences(accessor, values.map(getRef));
802
820
  }
821
+ /**
822
+ * Alias for {@link loadDocumentsForDocumentReferencesFromValues}.
823
+ */
803
824
  const loadDocumentsForValues = loadDocumentsForDocumentReferencesFromValues;
825
+ /**
826
+ * Loads {@link FirestoreDocument} instances from an array of {@link DocumentReference}s.
827
+ *
828
+ * Each reference is passed to `accessor.loadDocument()` to create a document wrapper.
829
+ * No network calls are made; this only creates in-memory document instances bound to the given references.
830
+ *
831
+ * @param accessor - Accessor to load documents with
832
+ * @param refs - Document references to load
833
+ * @returns Document instances in the same order as the input references
834
+ */
804
835
  function loadDocumentsForDocumentReferences(accessor, refs) {
805
836
  return refs.map((x) => accessor.loadDocument(x));
806
837
  }
838
+ /**
839
+ * Extracts {@link FirestoreModelKey}s from arbitrary values and loads them as {@link FirestoreDocument} instances.
840
+ *
841
+ * Convenience function that maps values through `getKey` then delegates to {@link loadDocumentsForKeys}.
842
+ *
843
+ * @param accessor - Accessor to load documents with
844
+ * @param values - Source values to extract keys from
845
+ * @param getKey - Extracts a model key (full Firestore path) from each value
846
+ * @returns Document instances in the same order as the input values
847
+ */
807
848
  function loadDocumentsForKeysFromValues(accessor, values, getKey) {
808
849
  return loadDocumentsForKeys(accessor, values.map(getKey));
809
850
  }
851
+ /**
852
+ * Loads {@link FirestoreDocument} instances from an array of full Firestore document paths (keys).
853
+ *
854
+ * Each key is passed to `accessor.loadDocumentForKey()`. No network calls are made.
855
+ *
856
+ * @param accessor - Accessor to load documents with
857
+ * @param keys - Full Firestore document paths (e.g. `'users/abc123'`)
858
+ * @returns Document instances in the same order as the input keys
859
+ */
810
860
  function loadDocumentsForKeys(accessor, keys) {
811
861
  return keys.map((x) => accessor.loadDocumentForKey(x));
812
862
  }
863
+ /**
864
+ * Extracts {@link FirestoreModelId}s from arbitrary values and loads them as {@link FirestoreDocument} instances.
865
+ *
866
+ * Convenience function that maps values through `getId` then delegates to {@link loadDocumentsForIds}.
867
+ * Requires a full {@link FirestoreDocumentAccessor} (not limited) because loading by ID requires collection context.
868
+ *
869
+ * @param accessor - Accessor to load documents with (must have collection context for ID resolution)
870
+ * @param values - Source values to extract IDs from
871
+ * @param getId - Extracts a model ID from each value
872
+ * @returns Document instances in the same order as the input values
873
+ */
813
874
  function loadDocumentsForIdsFromValues(accessor, values, getId) {
814
875
  return loadDocumentsForIds(accessor, values.map(getId));
815
876
  }
877
+ /**
878
+ * Loads {@link FirestoreDocument} instances from an array of document IDs relative to the accessor's collection.
879
+ *
880
+ * Each ID is passed to `accessor.loadDocumentForId()`. Requires a full {@link FirestoreDocumentAccessor}
881
+ * because ID-based loading needs the collection reference to resolve the full path. No network calls are made.
882
+ *
883
+ * @param accessor - Accessor to load documents with (must have collection context)
884
+ * @param ids - Document IDs within the accessor's collection
885
+ * @returns Document instances in the same order as the input IDs
886
+ */
816
887
  function loadDocumentsForIds(accessor, ids) {
817
888
  return ids.map((x) => accessor.loadDocumentForId(x));
818
889
  }
819
890
  /**
820
- * Used to make a FirestoreDocumentLoader.
891
+ * Creates a {@link FirestoreDocumentLoader} from a {@link LimitedFirestoreDocumentAccessorContextExtension}.
821
892
  *
822
- * @param accessorContext
823
- * @returns
893
+ * The returned loader resolves the appropriate accessor based on whether a transaction is provided,
894
+ * then delegates to {@link loadDocumentsForDocumentReferences}.
895
+ *
896
+ * @param accessorContext - Context that provides accessors for both default and transactional use
897
+ * @returns A loader function that converts document references to document instances
824
898
  */
825
899
  function firestoreDocumentLoader(accessorContext) {
826
900
  return (references, transaction) => {
@@ -829,10 +903,16 @@ function firestoreDocumentLoader(accessorContext) {
829
903
  };
830
904
  }
831
905
  /**
832
- * Used to make a FirestoreDocumentSnapshotPairsLoader.
906
+ * Creates a {@link FirestoreDocumentSnapshotPairsLoader} from a {@link LimitedFirestoreDocumentAccessorContextExtension}.
833
907
  *
834
- * @param accessorContext
835
- * @returns
908
+ * The returned loader resolves the appropriate accessor based on whether a transaction is provided,
909
+ * then maps each snapshot to a {@link FirestoreDocumentSnapshotDataPair} using {@link firestoreDocumentSnapshotPairsLoaderInstance}.
910
+ *
911
+ * Also satisfies the {@link FirestoreQueryDocumentSnapshotPairsLoader} type since the implementation
912
+ * handles both {@link DocumentSnapshot} and {@link QueryDocumentSnapshot} inputs.
913
+ *
914
+ * @param accessorContext - Context that provides accessors for both default and transactional use
915
+ * @returns A loader function that converts snapshots to document-snapshot-data pairs
836
916
  */
837
917
  function firestoreDocumentSnapshotPairsLoader(accessorContext) {
838
918
  return (snapshots, transaction) => {
@@ -842,10 +922,15 @@ function firestoreDocumentSnapshotPairsLoader(accessorContext) {
842
922
  };
843
923
  }
844
924
  /**
845
- * Used to make a FirestoreDocumentSnapshotPairsLoader.
925
+ * Creates a {@link FirestoreDocumentSnapshotPairsLoaderInstance} bound to a specific accessor.
846
926
  *
847
- * @param accessorContext
848
- * @returns
927
+ * The returned function converts a snapshot into a {@link FirestoreDocumentSnapshotDataPair} by:
928
+ * 1. Extracting data with `id`/`key` fields via {@link documentDataWithIdAndKey}
929
+ * 2. Loading the document from the snapshot's reference via `accessor.loadDocument()`
930
+ * 3. Combining all three into a single pair object
931
+ *
932
+ * @param accessor - The accessor to bind for document loading
933
+ * @returns A reusable function that converts snapshots to pairs using the bound accessor
849
934
  */
850
935
  function firestoreDocumentSnapshotPairsLoaderInstance(accessor) {
851
936
  const fn = ((snapshot) => {
@@ -862,10 +947,10 @@ function firestoreDocumentSnapshotPairsLoaderInstance(accessor) {
862
947
  return fn;
863
948
  }
864
949
  /**
865
- * Used to make a FirestoreQueryDocumentSnapshotPairsLoader.
950
+ * Alias for {@link firestoreDocumentSnapshotPairsLoader}, typed specifically as a {@link FirestoreQueryDocumentSnapshotPairsLoader}.
866
951
  *
867
- * @param accessorContext
868
- * @returns
952
+ * Use this when you know all input snapshots are from a query and want the stronger return type
953
+ * that guarantees `data` is non-nullish.
869
954
  */
870
955
  const firestoreQueryDocumentSnapshotPairsLoader = firestoreDocumentSnapshotPairsLoader;
871
956
  function documentData(snapshot, withId = false) {
@@ -887,11 +972,14 @@ function documentDataWithIdAndKey(snapshot) {
887
972
  return data;
888
973
  }
889
974
  /**
890
- * Sets the id and key values from the snapshot onto the input data.
975
+ * Mutates the input data object to include `id` and `key` fields from a {@link DocumentSnapshot}.
891
976
  *
892
- * @param data
893
- * @param snapshot
894
- * @returns
977
+ * Sets `data.id` to `snapshot.id` and `data.key` to `snapshot.ref.path`. The data object
978
+ * is modified in-place and also returned for chaining convenience.
979
+ *
980
+ * @param data - The data object to augment (mutated in-place)
981
+ * @param snapshot - Source of the `id` and `key` values
982
+ * @returns The same data object, now typed as {@link DocumentDataWithIdAndKey}
895
983
  */
896
984
  function setIdAndKeyFromSnapshotOnDocumentData(data, snapshot) {
897
985
  const target = data;
@@ -900,11 +988,15 @@ function setIdAndKeyFromSnapshotOnDocumentData(data, snapshot) {
900
988
  return target;
901
989
  }
902
990
  /**
903
- * Sets the id and key values from the snapshot onto the input data.
991
+ * Mutates the input data object to include `id` and `key` fields from a model reference.
904
992
  *
905
- * @param data
906
- * @param snapshot
907
- * @returns
993
+ * Similar to {@link setIdAndKeyFromSnapshotOnDocumentData}, but sources the values from a
994
+ * {@link FirestoreModelKeyRef} & {@link FirestoreModelIdRef} instead of a snapshot.
995
+ * The data object is modified in-place and also returned for chaining convenience.
996
+ *
997
+ * @param data - The data object to augment (mutated in-place)
998
+ * @param modelRef - Source of the `id` and `key` values
999
+ * @returns The same data object, now typed as {@link DocumentDataWithIdAndKey}
908
1000
  */
909
1001
  function setIdAndKeyFromKeyIdRefOnDocumentData(data, modelRef) {
910
1002
  const target = data;
@@ -913,37 +1005,91 @@ function setIdAndKeyFromKeyIdRefOnDocumentData(data, modelRef) {
913
1005
  return target;
914
1006
  }
915
1007
  /**
916
- * MappedUseAsyncFunction to load a snapshot from the input document and use it.
1008
+ * Fetches a document's snapshot and passes it to a `use` callback, following the {@link UseAsync} pattern.
917
1009
  *
918
- * @param document
919
- * @param use
920
- * @param defaultValue
921
- * @returns
1010
+ * If `document` is nullish, the `use` callback is not invoked and `defaultValue` is returned instead.
1011
+ * If `document` exists but the snapshot is nullish (shouldn't happen in practice), `defaultValue` is also used.
1012
+ *
1013
+ * @param document - The document to fetch, or nullish to skip
1014
+ * @param use - Callback that receives the fetched snapshot and returns a result
1015
+ * @param defaultValue - Fallback value when `document` is nullish or the snapshot is unavailable
1016
+ * @returns The result of `use`, or the default value
922
1017
  */
923
1018
  async function useDocumentSnapshot(document, use, defaultValue) {
924
1019
  const snapshot = await document?.accessor.get();
925
1020
  return util.useAsync(snapshot, use, defaultValue);
926
1021
  }
927
1022
  /**
928
- * MappedUseAsyncFunction to load snapshot data from the input document and use it.
1023
+ * Fetches a document's snapshot data (via `snapshot.data()`) and passes it to a `use` callback.
1024
+ *
1025
+ * Wraps {@link useDocumentSnapshot} with a mapping step that extracts raw data from the snapshot.
1026
+ * If the document doesn't exist (data is `undefined`), the `use` callback is not invoked
1027
+ * and `defaultValue` is returned instead.
1028
+ *
1029
+ * @param document - The document to fetch, or nullish to skip
1030
+ * @param use - Callback that receives the snapshot data and returns a result
1031
+ * @param defaultValue - Fallback value when the document is nullish or doesn't exist
1032
+ * @returns The result of `use`, or the default value
929
1033
  */
930
1034
  const useDocumentSnapshotData = util.wrapUseAsyncFunction(useDocumentSnapshot, (x) => x.data());
931
1035
  // MARK: Key Accessors
1036
+ /**
1037
+ * Extracts the document ID ({@link FirestoreModelId}) from a {@link FirestoreDocument}.
1038
+ *
1039
+ * Useful as a mapper function, e.g. `documents.map(firestoreModelIdFromDocument)`.
1040
+ *
1041
+ * @param document - The document to extract the ID from
1042
+ * @returns The document's ID (the last segment of its Firestore path)
1043
+ */
932
1044
  function firestoreModelIdFromDocument(document) {
933
1045
  return document.id;
934
1046
  }
1047
+ /**
1048
+ * Extracts document IDs from an array of {@link FirestoreDocument}s.
1049
+ *
1050
+ * @param documents - Documents to extract IDs from
1051
+ * @returns Array of document IDs in the same order as the input
1052
+ */
935
1053
  function firestoreModelIdsFromDocuments(documents) {
936
1054
  return documents.map(firestoreModelIdFromDocument);
937
1055
  }
1056
+ /**
1057
+ * Extracts the full Firestore path ({@link FirestoreModelKey}) from a {@link FirestoreDocument}.
1058
+ *
1059
+ * Useful as a mapper function, e.g. `documents.map(firestoreModelKeyFromDocument)`.
1060
+ *
1061
+ * @param document - The document to extract the key from
1062
+ * @returns The document's full Firestore path (e.g. `'users/abc123'`)
1063
+ */
938
1064
  function firestoreModelKeyFromDocument(document) {
939
1065
  return document.key;
940
1066
  }
1067
+ /**
1068
+ * Extracts full Firestore paths from an array of {@link FirestoreDocument}s.
1069
+ *
1070
+ * @param documents - Documents to extract keys from
1071
+ * @returns Array of full Firestore paths in the same order as the input
1072
+ */
941
1073
  function firestoreModelKeysFromDocuments(documents) {
942
1074
  return documents.map(firestoreModelKeyFromDocument);
943
1075
  }
1076
+ /**
1077
+ * Extracts the {@link DocumentReference} from a {@link FirestoreDocument}.
1078
+ *
1079
+ * Useful as a mapper function, e.g. `documents.map(documentReferenceFromDocument)`.
1080
+ *
1081
+ * @param document - The document to extract the reference from
1082
+ * @returns The underlying Firestore document reference
1083
+ */
944
1084
  function documentReferenceFromDocument(document) {
945
1085
  return document.documentRef;
946
1086
  }
1087
+ /**
1088
+ * Extracts {@link DocumentReference}s from an array of {@link FirestoreDocument}s.
1089
+ *
1090
+ * @param documents - Documents to extract references from
1091
+ * @returns Array of document references in the same order as the input
1092
+ */
947
1093
  function documentReferencesFromDocuments(documents) {
948
1094
  return documents.map(documentReferenceFromDocument);
949
1095
  }
@@ -953,7 +1099,7 @@ function documentReferencesFromDocuments(documents) {
953
1099
  *
954
1100
  * This function streams the latest snapshots for each document in the provided array.
955
1101
  * Each time any document in the array changes, a new array containing the latest snapshots
956
- * of all documents is emitted. Results are shared with multiple subscribers through shareReplay.
1102
+ * of all documents is emitted.
957
1103
  *
958
1104
  * If the input array is empty, an Observable that emits an empty array is returned.
959
1105
  *
@@ -962,7 +1108,25 @@ function documentReferencesFromDocuments(documents) {
962
1108
  * @returns Observable that emits arrays of DocumentSnapshots whenever any document changes
963
1109
  */
964
1110
  function latestSnapshotsFromDocuments(documents) {
965
- return documents.length ? rxjs$1.combineLatest(documents.map((x) => x.accessor.stream())).pipe(rxjs$1.shareReplay(1)) : rxjs$1.of([]);
1111
+ return mapLatestSnapshotsFromDocuments(documents, rxjs$1.map(util.MAP_IDENTITY));
1112
+ }
1113
+ /**
1114
+ * Creates an Observable that streams and transforms snapshots for multiple documents using `combineLatest`.
1115
+ *
1116
+ * Pipes each document's `accessor.stream()` through the provided `operator` before combining.
1117
+ * This ensures the transformation runs per-document when only one document changes, rather than
1118
+ * re-mapping all snapshots on every emission.
1119
+ *
1120
+ * {@link latestSnapshotsFromDocuments} delegates to this function with an identity operator.
1121
+ *
1122
+ * Returns `of([])` for an empty input array.
1123
+ *
1124
+ * @param documents - Documents to stream from
1125
+ * @param operator - RxJS operator applied to each document's snapshot stream individually
1126
+ * @returns Observable emitting an array of transformed values whenever any document changes
1127
+ */
1128
+ function mapLatestSnapshotsFromDocuments(documents, operator) {
1129
+ return documents.length ? rxjs$1.combineLatest(documents.map((x) => x.accessor.stream().pipe(operator))) : rxjs$1.of([]);
966
1130
  }
967
1131
  /**
968
1132
  * Creates an Observable that emits arrays of document data for multiple documents.
@@ -970,7 +1134,7 @@ function latestSnapshotsFromDocuments(documents) {
970
1134
  * This function streams the latest data for each document in the provided array.
971
1135
  * Each time any document in the array changes, a new array containing the latest data
972
1136
  * of all documents is emitted. Document data includes both the document content and
973
- * metadata like document ID and key. Results are shared with multiple subscribers.
1137
+ * metadata like document ID and key.
974
1138
  *
975
1139
  * Non-existent documents are filtered out of the results automatically.
976
1140
  *
@@ -979,7 +1143,7 @@ function latestSnapshotsFromDocuments(documents) {
979
1143
  * @returns Observable that emits arrays of document data whenever any document changes
980
1144
  */
981
1145
  function latestDataFromDocuments(documents) {
982
- return latestSnapshotsFromDocuments(documents).pipe(dataFromDocumentSnapshots(), rxjs$1.shareReplay(1));
1146
+ return latestSnapshotsFromDocuments(documents).pipe(dataFromDocumentSnapshots());
983
1147
  }
984
1148
  /**
985
1149
  * Creates an RxJS operator that transforms arrays of DocumentSnapshots into arrays of document data.
@@ -994,6 +1158,48 @@ function latestDataFromDocuments(documents) {
994
1158
  function dataFromDocumentSnapshots() {
995
1159
  return rxjs$1.map((x) => getDataFromDocumentSnapshots(x));
996
1160
  }
1161
+ // MARK: Streaming Document Snapshot Pairs
1162
+ /**
1163
+ * Streams {@link FirestoreDocumentSnapshotDataPair}s for multiple documents using `combineLatest`.
1164
+ *
1165
+ * Each document's `accessor.stream()` is individually piped to produce a `{ document, snapshot, data }` triplet,
1166
+ * then all streams are combined via `combineLatest`. This ensures the mapping only runs for the document
1167
+ * that actually changed. The `data` field has `id` and `key` fields injected via {@link documentDataWithIdAndKey},
1168
+ * and will be `undefined` for documents that don't exist in Firestore.
1169
+ *
1170
+ * Returns `of([])` for an empty input array.
1171
+ *
1172
+ * This is the streaming equivalent of {@link import('./document.utility').getDocumentSnapshotDataPairs}.
1173
+ *
1174
+ * @param documents - Documents to stream snapshot-data pairs for
1175
+ * @returns Observable emitting snapshot-data pairs whenever any document changes
1176
+ */
1177
+ function streamDocumentSnapshotDataPairs(documents) {
1178
+ return documents.length
1179
+ ? rxjs$1.combineLatest(documents.map((document) => document.accessor.stream().pipe(rxjs$1.map((snapshot) => ({
1180
+ document,
1181
+ snapshot,
1182
+ data: documentDataWithIdAndKey(snapshot)
1183
+ })))))
1184
+ : rxjs$1.of([]);
1185
+ }
1186
+ /**
1187
+ * Streams {@link FirestoreDocumentSnapshotDataPairWithData}s for multiple documents, filtering out non-existent documents.
1188
+ *
1189
+ * Builds on {@link streamDocumentSnapshotDataPairs} and filters each emission to include only pairs where
1190
+ * `data` is non-nullish (i.e., the document exists in Firestore). The filtered array may be shorter than
1191
+ * the input `documents` array and may change length over time as documents are created or deleted.
1192
+ *
1193
+ * Returns `of([])` for an empty input array.
1194
+ *
1195
+ * This is the streaming equivalent of {@link import('./document.utility').getDocumentSnapshotDataPairsWithData}.
1196
+ *
1197
+ * @param documents - Documents to stream snapshot-data pairs for
1198
+ * @returns Observable emitting snapshot-data pairs for existing documents only, whenever any document changes
1199
+ */
1200
+ function streamDocumentSnapshotDataPairsWithData(documents) {
1201
+ return streamDocumentSnapshotDataPairs(documents).pipe(rxjs$1.map((pairs) => pairs.filter((pair) => pair.data != null)));
1202
+ }
997
1203
 
998
1204
  // A set of copied types from @google-cloud/firestore and firebase/firestore to allow cross-compatability.
999
1205
  /* eslint-disable */
@@ -9723,6 +9929,7 @@ exports.makeRootSingleItemFirestoreCollection = makeRootSingleItemFirestoreColle
9723
9929
  exports.makeSingleItemFirestoreCollection = makeSingleItemFirestoreCollection;
9724
9930
  exports.mapDataFromSnapshot = mapDataFromSnapshot;
9725
9931
  exports.mapHttpsCallable = mapHttpsCallable;
9932
+ exports.mapLatestSnapshotsFromDocuments = mapLatestSnapshotsFromDocuments;
9726
9933
  exports.mergeNotificationBoxRecipientTemplateConfigRecords = mergeNotificationBoxRecipientTemplateConfigRecords;
9727
9934
  exports.mergeNotificationBoxRecipientTemplateConfigs = mergeNotificationBoxRecipientTemplateConfigs;
9728
9935
  exports.mergeNotificationBoxRecipients = mergeNotificationBoxRecipients;
@@ -9855,6 +10062,8 @@ exports.storageListFilesResultFactory = storageListFilesResultFactory;
9855
10062
  exports.storageListFilesResultHasNoNextError = storageListFilesResultHasNoNextError;
9856
10063
  exports.storagePathFactory = storagePathFactory;
9857
10064
  exports.storedFileReaderFactory = storedFileReaderFactory;
10065
+ exports.streamDocumentSnapshotDataPairs = streamDocumentSnapshotDataPairs;
10066
+ exports.streamDocumentSnapshotDataPairsWithData = streamDocumentSnapshotDataPairsWithData;
9858
10067
  exports.streamFromOnSnapshot = streamFromOnSnapshot;
9859
10068
  exports.systemStateCollectionReference = systemStateCollectionReference;
9860
10069
  exports.systemStateConverter = systemStateConverter;