1515 * limitations under the License.
1616 */
1717
18- import { BundleConverterImpl , BundleLoader } from '../core/bundle_impl' ;
18+ import { BundleLoader } from '../core/bundle_impl' ;
1919import { createBundleReaderSync } from '../core/firestore_client' ;
2020import { newQueryComparator } from '../core/query' ;
2121import { ChangeType , ViewSnapshot } from '../core/view_snapshot' ;
@@ -51,6 +51,8 @@ import {
5151 QuerySnapshotBundleData
5252} from '../util/bundle_builder_impl' ;
5353import { Code , FirestoreError } from '../util/error' ;
54+ // API extractor fails importing 'property' unless we also explicitly import 'Property'.
55+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-imports-ts
5456import { Property , property , validateJSON } from '../util/json_validation' ;
5557import { AutoId } from '../util/misc' ;
5658
@@ -554,7 +556,7 @@ export class DocumentSnapshot<
554556 throw new FirestoreError (
555557 Code . FAILED_PRECONDITION ,
556558 'DocumentSnapshot.toJSON() attempted to serialize a document with pending writes. ' +
557- 'Await waitForPendingWrites() before invoking toJSON().'
559+ 'Await waitForPendingWrites() before invoking toJSON().'
558560 ) ;
559561 }
560562 builder . addBundleDocument (
@@ -587,36 +589,39 @@ export class DocumentSnapshot<
587589 converter : FirestoreDataConverter < AppModelType , DbModelType >
588590 ) : DocumentSnapshot < AppModelType , DbModelType > {
589591 if ( validateJSON ( json , DocumentSnapshot . _jsonSchema ) ) {
590- let error : string | undefined = undefined ;
591592 // Parse the bundle data.
592593 const serializer = newSerializer ( db . _databaseId ) ;
593- const elements = createBundleReaderSync (
594- json . bundle ,
594+ const bundleReader = createBundleReaderSync ( json . bundle , serializer ) ;
595+ const elements = bundleReader . getElements ( ) ;
596+ const bundleLoader : BundleLoader = new BundleLoader (
597+ bundleReader . getMetadata ( ) ,
595598 serializer
596- ) . getElements ( ) ;
597- if ( elements . length === 0 ) {
598- error = 'No snapshat data was found in the bundle.' ;
599- } else if (
600- elements . length !== 2 ||
601- ! elements [ 0 ] . payload . documentMetadata ||
602- ! elements [ 1 ] . payload . document
603- ) {
604- error =
605- 'DocumentSnapshot bundle data must contain one metadata and then one document.' ;
599+ ) ;
600+ for ( const element of elements ) {
601+ bundleLoader . addSizedElement ( element ) ;
606602 }
607- if ( error ) {
608- throw new FirestoreError ( Code . INVALID_ARGUMENT , error ) ;
603+
604+ // Ensure that we have the correct number of documents in the bundle.
605+ const bundledDocuments = bundleLoader . documents ;
606+ if ( bundledDocuments . length !== 1 ) {
607+ throw new FirestoreError (
608+ Code . INVALID_ARGUMENT ,
609+ `Expected bundle data to contain 1 document, but it contains ${ bundledDocuments . length } documents.`
610+ ) ;
609611 }
610- // convert bundle data into the types that the DocumentSnapshot constructore requires.
611- const bundleConverter = new BundleConverterImpl ( serializer ) ;
612- const documentSnapshotData =
613- bundleConverter . toDocumentSnapshotData ( elements ) ;
614- const liteUserDataWriter = new LiteUserDataWriter ( db ) ;
612+
613+ // Build out the internal document data.
614+ const document = fromDocument ( serializer , bundledDocuments [ 0 ] . document ! ) ;
615+ const documentKey = new DocumentKey (
616+ ResourcePath . fromString ( json . bundleName )
617+ ) ;
618+
619+ // Return the external facing DocumentSnapshot.
615620 return new DocumentSnapshot (
616621 db ,
617- liteUserDataWriter ,
618- documentSnapshotData . documentKey ,
619- documentSnapshotData . mutableDoc ,
622+ new LiteUserDataWriter ( db ) ,
623+ documentKey ,
624+ document ,
620625 new SnapshotMetadata (
621626 /* hasPendingWrites= */ false ,
622627 /* fromCache= */ false
@@ -770,7 +775,7 @@ export class QuerySnapshot<
770775 throw new FirestoreError (
771776 Code . INVALID_ARGUMENT ,
772777 'To include metadata changes with your document changes, you must ' +
773- 'also pass { includeMetadataChanges:true } to onSnapshot().'
778+ 'also pass { includeMetadataChanges:true } to onSnapshot().'
774779 ) ;
775780 }
776781
@@ -826,7 +831,7 @@ export class QuerySnapshot<
826831 throw new FirestoreError (
827832 Code . FAILED_PRECONDITION ,
828833 'QuerySnapshot.toJSON() attempted to serialize a document with pending writes. ' +
829- 'Await waitForPendingWrites() before invoking toJSON().'
834+ 'Await waitForPendingWrites() before invoking toJSON().'
830835 ) ;
831836 }
832837 docBundleDataArray . push (
@@ -868,24 +873,24 @@ export class QuerySnapshot<
868873 // Parse the bundle data.
869874 const serializer = newSerializer ( db . _databaseId ) ;
870875 const bundleReader = createBundleReaderSync ( json . bundle , serializer ) ;
876+ const elements = bundleReader . getElements ( ) ;
871877 const bundleLoader : BundleLoader = new BundleLoader (
872878 bundleReader . getMetadata ( ) ,
873879 serializer
874880 ) ;
875- const elements = bundleReader . getElements ( ) ;
876881 for ( const element of elements ) {
877882 bundleLoader . addSizedElement ( element ) ;
878883 }
879- const parsedNamedQueries = bundleLoader . queries ;
880- if ( parsedNamedQueries . length !== 1 ) {
884+
885+ if ( bundleLoader . queries . length !== 1 ) {
881886 throw new FirestoreError (
882887 Code . INVALID_ARGUMENT ,
883- `Snapshot data expected 1 query but found ${ parsedNamedQueries . length } queries.`
888+ `Snapshot data expected 1 query but found ${ bundleLoader . queries . length } queries.`
884889 ) ;
885890 }
886891
887892 // Create an internal Query object from the named query in the budnle.
888- const query = fromBundledQuery ( parsedNamedQueries [ 0 ] . bundledQuery ! ) ;
893+ const query = fromBundledQuery ( bundleLoader . queries [ 0 ] . bundledQuery ! ) ;
889894
890895 // Construct the arrays of document data for the query.
891896 const bundledDocuments = bundleLoader . documents ;
@@ -905,12 +910,16 @@ export class QuerySnapshot<
905910 query ,
906911 documentSet ,
907912 documentKeys ,
908- /* fromCache= */ false ,
913+ /* fromCache= */ false ,
909914 /* hasCachedResults= */ false
910915 ) ;
911916
912917 // Create an external Query object, required to construct the QuerySnapshot.
913- const externalQuery = new Query < AppModelType , DbModelType > ( db , null , query ) ;
918+ const externalQuery = new Query < AppModelType , DbModelType > (
919+ db ,
920+ null ,
921+ query
922+ ) ;
914923
915924 // Return a new QuerySnapshot with all of the collected data.
916925 return new QuerySnapshot < AppModelType , DbModelType > (
@@ -947,10 +956,10 @@ export function changesFromSnapshot<
947956 ) ;
948957 debugAssert (
949958 ! lastDoc ||
950- newQueryComparator ( querySnapshot . _snapshot . query ) (
951- lastDoc ,
952- change . doc
953- ) < 0 ,
959+ newQueryComparator ( querySnapshot . _snapshot . query ) (
960+ lastDoc ,
961+ change . doc
962+ ) < 0 ,
954963 'Got added events in wrong order'
955964 ) ;
956965 const doc = new QueryDocumentSnapshot < AppModelType , DbModelType > (
0 commit comments