diff --git a/packages/firebase/index.d.ts b/packages/firebase/index.d.ts index b922fcff0e5..8274fe81492 100644 --- a/packages/firebase/index.d.ts +++ b/packages/firebase/index.d.ts @@ -15,6 +15,8 @@ * limitations under the License. */ +import { DocumentData, LoadBundleTask, Query } from '@firebase/firestore-types'; + /** * firebase is a global namespace from which all Firebase * services are accessed. @@ -8289,12 +8291,45 @@ declare namespace firebase.firestore { */ terminate(): Promise; + loadBundle( + bundleData: ArrayBuffer | ReadableStream | string + ): LoadBundleTask; + + namedQuery(name: string): Promise | null>; + /** * @hidden */ INTERNAL: { delete: () => Promise }; } + export interface LoadBundleTask { + onProgress( + next?: (progress: LoadBundleTaskProgress) => any, + error?: (error: Error) => any, + complete?: () => void + ): void; + + then( + onFulfilled?: (a: LoadBundleTaskProgress) => T | PromiseLike, + onRejected?: (a: Error) => R | PromiseLike + ): Promise; + + catch( + onRejected: (a: Error) => R | PromiseLike + ): Promise; + } + + export interface LoadBundleTaskProgress { + documentsLoaded: number; + totalDocuments: number; + bytesLoaded: number; + totalBytes: number; + taskState: TaskState; + } + + export type TaskState = 'Error' | 'Running' | 'Success'; + /** * An immutable object representing a geo point in Firestore. The geo point * is represented as latitude/longitude pair. diff --git a/packages/firestore-types/index.d.ts b/packages/firestore-types/index.d.ts index 2c94ea2842f..b76b5143488 100644 --- a/packages/firestore-types/index.d.ts +++ b/packages/firestore-types/index.d.ts @@ -96,9 +96,42 @@ export class FirebaseFirestore { terminate(): Promise; + loadBundle( + bundleData: ArrayBuffer | ReadableStream | string + ): LoadBundleTask; + + namedQuery(name: string): Promise | null>; + INTERNAL: { delete: () => Promise }; } +export interface LoadBundleTask { + onProgress( + next?: (progress: LoadBundleTaskProgress) => any, + error?: (error: Error) => any, + complete?: () => void + ): void; + + then( + onFulfilled?: (a: LoadBundleTaskProgress) => T | PromiseLike, + onRejected?: (a: Error) => R | PromiseLike + ): Promise; + + catch( + onRejected: (a: Error) => R | PromiseLike + ): Promise; +} + +export interface LoadBundleTaskProgress { + documentsLoaded: number; + totalDocuments: number; + bytesLoaded: number; + totalBytes: number; + taskState: TaskState; +} + +export type TaskState = 'Error' | 'Running' | 'Success'; + export class GeoPoint { constructor(latitude: number, longitude: number); diff --git a/packages/firestore/exp-types/index.d.ts b/packages/firestore/exp-types/index.d.ts index 5c1bb7f2b68..19994191aab 100644 --- a/packages/firestore/exp-types/index.d.ts +++ b/packages/firestore/exp-types/index.d.ts @@ -516,6 +516,43 @@ export function snapshotEqual( right: DocumentSnapshot | QuerySnapshot ): boolean; +export interface LoadBundleTask { + onProgress( + next?: (progress: LoadBundleTaskProgress) => any, + error?: (error: Error) => any, + complete?: () => void + ): void; + + then( + onFulfilled?: (a: LoadBundleTaskProgress) => T | PromiseLike, + onRejected?: (a: Error) => R | PromiseLike + ): Promise; + + catch( + onRejected: (a: Error) => R | PromiseLike + ): Promise; +} + +export interface LoadBundleTaskProgress { + documentsLoaded: number; + totalDocuments: number; + bytesLoaded: number; + totalBytes: number; + taskState: TaskState; +} + +export type TaskState = 'Error' | 'Running' | 'Success'; + +export function loadBundle( + firestore: FirebaseFirestore, + bundleData: ArrayBuffer | ReadableStream | string +): LoadBundleTask; + +export function namedQuery( + firestore: FirebaseFirestore, + name: string +): Promise | null>; + export type FirestoreErrorCode = | 'cancelled' | 'unknown' diff --git a/packages/firestore/index.bundle.ts b/packages/firestore/index.bundle.ts new file mode 100644 index 00000000000..a88771a6e7c --- /dev/null +++ b/packages/firestore/index.bundle.ts @@ -0,0 +1,39 @@ +/** + * @license + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Firestore } from './src/api/database'; +import { loadBundle, namedQuery } from './src/api/bundle'; + +/** + * Registers Firestore bundle loading features with the components framework. + */ +export function registerBundle(instance: typeof Firestore): void { + instance.prototype.loadBundle = function ( + this: Firestore, + data: ArrayBuffer | ReadableStream | string + ) { + return loadBundle(this, data); + }; + instance.prototype.namedQuery = function ( + this: Firestore, + queryName: string + ) { + return namedQuery(this, queryName); + }; +} + +registerBundle(Firestore); diff --git a/packages/firestore/src/api/bundle.ts b/packages/firestore/src/api/bundle.ts index 3f73589aced..a5240d8a584 100644 --- a/packages/firestore/src/api/bundle.ts +++ b/packages/firestore/src/api/bundle.ts @@ -15,46 +15,27 @@ * limitations under the License. */ +import { + LoadBundleTask as ApiLoadBundleTask, + LoadBundleTaskProgress +} from '@firebase/firestore-types'; import { Deferred } from '../util/promise'; import { PartialObserver } from './observer'; import { debugAssert } from '../util/assert'; import { FirestoreError } from '../util/error'; - -export interface ApiLoadBundleTask { - onProgress( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - next?: (progress: ApiLoadBundleTaskProgress) => any, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - error?: (error: Error) => any, - complete?: () => void - ): void; - - then( - onFulfilled?: (a: ApiLoadBundleTaskProgress) => T | PromiseLike, - onRejected?: (a: Error) => R | PromiseLike - ): Promise; - - catch( - onRejected: (a: Error) => R | PromiseLike - ): Promise; -} - -export interface ApiLoadBundleTaskProgress { - documentsLoaded: number; - totalDocuments: number; - bytesLoaded: number; - totalBytes: number; - taskState: TaskState; -} - -export type TaskState = 'Error' | 'Running' | 'Success'; +import { ensureFirestoreConfigured, Query, Firestore } from './database'; +import { Query as ExpQuery } from '../../exp/src/api/reference'; +import { + firestoreClientGetNamedQuery, + firestoreClientLoadBundle +} from '../core/firestore_client'; export class LoadBundleTask - implements ApiLoadBundleTask, PromiseLike { - private _progressObserver: PartialObserver = {}; - private _taskCompletionResolver = new Deferred(); + implements ApiLoadBundleTask, PromiseLike { + private _progressObserver: PartialObserver = {}; + private _taskCompletionResolver = new Deferred(); - private _lastProgress: ApiLoadBundleTaskProgress = { + private _lastProgress: LoadBundleTaskProgress = { taskState: 'Running', totalBytes: 0, totalDocuments: 0, @@ -63,7 +44,7 @@ export class LoadBundleTask }; onProgress( - next?: (progress: ApiLoadBundleTaskProgress) => unknown, + next?: (progress: LoadBundleTaskProgress) => unknown, error?: (err: Error) => unknown, complete?: () => void ): void { @@ -76,12 +57,12 @@ export class LoadBundleTask catch( onRejected: (a: Error) => R | PromiseLike - ): Promise { + ): Promise { return this._taskCompletionResolver.promise.catch(onRejected); } then( - onFulfilled?: (a: ApiLoadBundleTaskProgress) => T | PromiseLike, + onFulfilled?: (a: LoadBundleTaskProgress) => T | PromiseLike, onRejected?: (a: Error) => R | PromiseLike ): Promise { return this._taskCompletionResolver.promise.then(onFulfilled, onRejected); @@ -91,7 +72,7 @@ export class LoadBundleTask * Notifies all observers that bundle loading has completed, with a provided * `LoadBundleTaskProgress` object. */ - _completeWith(progress: ApiLoadBundleTaskProgress): void { + _completeWith(progress: LoadBundleTaskProgress): void { debugAssert( progress.taskState === 'Success', 'Task is not completed with Success.' @@ -126,7 +107,7 @@ export class LoadBundleTask * Notifies a progress update of loading a bundle. * @param progress - The new progress. */ - _updateProgress(progress: ApiLoadBundleTaskProgress): void { + _updateProgress(progress: LoadBundleTaskProgress): void { debugAssert( this._lastProgress.taskState === 'Running', 'Cannot update progress on a completed or failed task' @@ -138,3 +119,30 @@ export class LoadBundleTask } } } + +export function loadBundle( + db: Firestore, + bundleData: ArrayBuffer | ReadableStream | string +): LoadBundleTask { + const resultTask = new LoadBundleTask(); + firestoreClientLoadBundle( + ensureFirestoreConfigured(db._delegate), + db._databaseId, + bundleData, + resultTask + ); + return resultTask; +} + +export function namedQuery(db: Firestore, name: string): Promise { + return firestoreClientGetNamedQuery( + ensureFirestoreConfigured(db._delegate), + name + ).then(namedQuery => { + if (!namedQuery) { + return null; + } + + return new Query(db, new ExpQuery(db._delegate, null, namedQuery.query)); + }); +} diff --git a/packages/firestore/src/api/database.ts b/packages/firestore/src/api/database.ts index 215e4d119c4..009c593659b 100644 --- a/packages/firestore/src/api/database.ts +++ b/packages/firestore/src/api/database.ts @@ -18,11 +18,7 @@ import { FirebaseApp } from '@firebase/app-types'; import { _FirebaseApp, FirebaseService } from '@firebase/app-types/private'; import { DatabaseId } from '../core/database_info'; -import { - FirestoreClient, - firestoreClientGetNamedQuery, - firestoreClientLoadBundle -} from '../core/firestore_client'; +import { FirestoreClient } from '../core/firestore_client'; import { DocumentKey } from '../model/document_key'; import { FieldPath, ResourcePath } from '../model/path'; import { debugAssert } from '../util/assert'; @@ -94,7 +90,7 @@ import { } from '../../exp/src/api/reference'; import { LRU_COLLECTION_DISABLED } from '../local/lru_garbage_collector'; import { Compat } from '../compat/compat'; -import { ApiLoadBundleTask, LoadBundleTask } from './bundle'; +import { LoadBundleTask } from './bundle'; import { makeDatabaseInfo } from '../../lite/src/api/database'; import { DEFAULT_HOST } from '../../lite/src/api/components'; import { WriteBatch as ExpWriteBatch } from '../../exp/src/api/write_batch'; @@ -107,6 +103,7 @@ import { CollectionReference as PublicCollectionReference, DocumentChange as PublicDocumentChange, DocumentChangeType as PublicDocumentChangeType, + DocumentData, DocumentData as PublicDocumentData, DocumentReference as PublicDocumentReference, DocumentSnapshot as PublicDocumentSnapshot, @@ -368,6 +365,22 @@ export class Firestore ) ); } + + loadBundle( + bundleData: ArrayBuffer | ReadableStream | string + ): LoadBundleTask { + throw new FirestoreError( + Code.FAILED_PRECONDITION, + '"loadBundle()" does not exist, have you imported "firebase/firestore/bundle"?' + ); + } + + namedQuery(name: string): Promise | null> { + throw new FirestoreError( + Code.FAILED_PRECONDITION, + '"namedQuery()" does not exist, have you imported "firebase/firestore/bundle"?' + ); + } } export function ensureFirestoreConfigured( @@ -404,35 +417,6 @@ export function setLogLevel(level: PublicLogLevel): void { setClientLogLevel(level); } -export function loadBundle( - db: Firestore, - bundleData: ArrayBuffer | ReadableStream | string -): ApiLoadBundleTask { - const resultTask = new LoadBundleTask(); - // eslint-disable-next-line @typescript-eslint/no-floating-promises - firestoreClientLoadBundle( - ensureFirestoreConfigured(db._delegate), - bundleData, - resultTask - ); - return resultTask; -} - -export function namedQuery( - db: Firestore, - name: string -): Promise { - return firestoreClientGetNamedQuery( - ensureFirestoreConfigured(db._delegate), - name - ).then(namedQuery => { - if (!namedQuery) { - return null; - } - return new Query(db, new ExpQuery(db._delegate, null, namedQuery.query)); - }); -} - /** * A reference to a transaction. */ diff --git a/packages/firestore/src/core/bundle.ts b/packages/firestore/src/core/bundle.ts index 4dc59427a6a..8c3ed6345c1 100644 --- a/packages/firestore/src/core/bundle.ts +++ b/packages/firestore/src/core/bundle.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { Query } from './query'; +import { LoadBundleTaskProgress } from '@firebase/firestore-types'; import { SnapshotVersion } from './snapshot_version'; import { fromDocument, @@ -24,9 +24,9 @@ import { JsonProtoSerializer } from '../remote/serializer'; import { - NamedQuery as ProtoNamedQuery, + BundledDocumentMetadata as ProtoBundledDocumentMetadata, BundleMetadata as ProtoBundleMetadata, - BundledDocumentMetadata as ProtoBundledDocumentMetadata + NamedQuery as ProtoNamedQuery } from '../protos/firestore_bundle_proto'; import * as api from '../protos/firestore_proto_api'; import { DocumentKey } from '../model/document_key'; @@ -43,30 +43,6 @@ import { DocumentKeySet, MaybeDocumentMap } from '../model/collections'; -import { ApiLoadBundleTaskProgress } from '../api/bundle'; - -/** - * Represents a Firestore bundle saved by the SDK in its local storage. - */ -export interface Bundle { - readonly id: string; - readonly version: number; - /** - * Set to the snapshot version of the bundle if created by the Server SDKs. - * Otherwise set to SnapshotVersion.MIN. - */ - readonly createTime: SnapshotVersion; -} - -/** - * Represents a Query saved by the SDK in its local storage. - */ -export interface NamedQuery { - readonly name: string; - readonly query: Query; - /** The time at which the results for this query were read. */ - readonly readTime: SnapshotVersion; -} /** * Represents a bundled document, including the metadata and the document @@ -121,7 +97,7 @@ export class BundleConverter { */ export function bundleInitialProgress( metadata: ProtoBundleMetadata -): ApiLoadBundleTaskProgress { +): LoadBundleTaskProgress { return { taskState: 'Running', documentsLoaded: 0, @@ -137,7 +113,7 @@ export function bundleInitialProgress( */ export function bundleSuccessProgress( metadata: ProtoBundleMetadata -): ApiLoadBundleTaskProgress { +): LoadBundleTaskProgress { return { taskState: 'Success', documentsLoaded: metadata.totalDocuments!, @@ -149,7 +125,7 @@ export function bundleSuccessProgress( export class BundleLoadResult { constructor( - readonly progress: ApiLoadBundleTaskProgress, + readonly progress: LoadBundleTaskProgress, readonly changedDocs: MaybeDocumentMap ) {} } @@ -160,7 +136,7 @@ export class BundleLoadResult { */ export class BundleLoader { /** The current progress of loading */ - private progress: ApiLoadBundleTaskProgress; + private progress: LoadBundleTaskProgress; /** Batched queries to be saved into storage */ private queries: ProtoNamedQuery[] = []; /** Batched documents to be saved into storage */ @@ -180,9 +156,7 @@ export class BundleLoader { * Returns a new progress if adding the element leads to a new progress, * otherwise returns null. */ - addSizedElement( - element: SizedBundleElement - ): ApiLoadBundleTaskProgress | null { + addSizedElement(element: SizedBundleElement): LoadBundleTaskProgress | null { debugAssert(!element.isBundleMetadata(), 'Unexpected bundle metadata.'); this.progress.bytesLoaded += element.byteLength; diff --git a/packages/firestore/src/core/bundle_types.ts b/packages/firestore/src/core/bundle_types.ts new file mode 100644 index 00000000000..35cd5b98677 --- /dev/null +++ b/packages/firestore/src/core/bundle_types.ts @@ -0,0 +1,55 @@ +/** + * @license + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// This is a separate file because rollup (or typescript) treat it as circular +// dependency when it was in `./bundle.ts`, which breaks the bundle's module +// build. + +import { Query } from './query'; +import { SnapshotVersion } from './snapshot_version'; + +/** + * Represents a Firestore bundle saved by the SDK in its local storage. + */ +export interface Bundle { + /** + * Id of the bundle. It is used together with `createTime` to determine if a + * bundle has been loaded by the SDK. + */ + readonly id: string; + + /** Schema version of the bundle. */ + readonly version: number; + + /** + * Set to the snapshot version of the bundle if created by the Server SDKs. + * Otherwise set to SnapshotVersion.MIN. + */ + readonly createTime: SnapshotVersion; +} + +/** + * Represents a Query saved by the SDK in its local storage. + */ +export interface NamedQuery { + /** The name of the query. */ + readonly name: string; + /** The underlying query associated with `name`. */ + readonly query: Query; + /** The time at which the results for this query were read. */ + readonly readTime: SnapshotVersion; +} diff --git a/packages/firestore/src/core/firestore_client.ts b/packages/firestore/src/core/firestore_client.ts index 43912db19fc..7f0585a7143 100644 --- a/packages/firestore/src/core/firestore_client.ts +++ b/packages/firestore/src/core/firestore_client.ts @@ -23,8 +23,8 @@ import { } from '../api/credentials'; import { User } from '../auth/user'; import { - getNamedQuery, executeQuery, + getNamedQuery, handleUserChange, LocalStore, readLocalDocument @@ -60,7 +60,7 @@ import { syncEngineWrite } from './sync_engine'; import { View } from './view'; -import { DatabaseInfo } from './database_info'; +import { DatabaseId, DatabaseInfo } from './database_info'; import { newQueryForPath, Query } from './query'; import { Transaction } from './transaction'; import { ViewSnapshot } from './view_snapshot'; @@ -77,12 +77,12 @@ import { logDebug } from '../util/log'; import { AutoId } from '../util/misc'; import { Persistence } from '../local/persistence'; import { Datastore } from '../remote/datastore'; -import { BundleReader } from '../util/bundle_reader'; import { LoadBundleTask } from '../api/bundle'; import { newSerializer, newTextEncoder } from '../platform/serializer'; -import { toByteStreamReader } from '../platform/byte_stream_reader'; -import { NamedQuery } from './bundle'; import { JsonProtoSerializer } from '../remote/serializer'; +import { BundleReader } from '../util/bundle_reader'; +import { toByteStreamReader } from '../platform/byte_stream_reader'; +import { NamedQuery } from './bundle_types'; const LOG_TAG = 'FirestoreClient'; export const MAX_CONCURRENT_LIMBO_RESOLUTIONS = 100; @@ -276,7 +276,7 @@ function getRemoteStore(client: FirestoreClient): Promise { return ensureOnlineComponents(client).then(c => c.remoteStore); } -function getSyncEngine(client: FirestoreClient): Promise { +export function getSyncEngine(client: FirestoreClient): Promise { return ensureOnlineComponents(client).then(c => c.syncEngine); } @@ -657,15 +657,13 @@ function executeQueryViaSnapshotListener( return eventManagerListen(eventManager, listener); } -export async function firestoreClientLoadBundle( +export function firestoreClientLoadBundle( client: FirestoreClient, + databaseId: DatabaseId, data: ReadableStream | ArrayBuffer | string, resultTask: LoadBundleTask -): Promise { - const reader = createBundleReader( - data, - newSerializer((await client.getConfiguration()).databaseInfo.databaseId) - ); +): void { + const reader = createBundleReader(data, newSerializer(databaseId)); client.asyncQueue.enqueueAndForget(async () => { syncEngineLoadBundle(await getSyncEngine(client), reader, resultTask); }); diff --git a/packages/firestore/src/core/sync_engine.ts b/packages/firestore/src/core/sync_engine.ts index f613cf011bf..d23ca31da9a 100644 --- a/packages/firestore/src/core/sync_engine.ts +++ b/packages/firestore/src/core/sync_engine.ts @@ -17,25 +17,25 @@ import { User } from '../auth/user'; import { - hasNewerBundle, + acknowledgeBatch, + allocateTarget, applyRemoteEventToLocalCache, - getNewDocumentChanges, + executeQuery, + getActiveClientsFromPersistence, getCachedTarget, + getHighestUnacknowledgedBatchId, + getNewDocumentChanges, + handleUserChange, + hasNewerBundle, ignoreIfPrimaryLeaseLoss, LocalStore, - saveBundle, - getActiveClientsFromPersistence, + localWrite, lookupMutationDocuments, - removeCachedMutationBatchMetadata, - allocateTarget, - executeQuery, - releaseTarget, + notifyLocalViewChanges, rejectBatch, - handleUserChange, - localWrite, - acknowledgeBatch, - getHighestUnacknowledgedBatchId, - notifyLocalViewChanges + releaseTarget, + removeCachedMutationBatchMetadata, + saveBundle } from '../local/local_store'; import { LocalViewChanges } from '../local/local_view_changes'; import { ReferenceSet } from '../local/reference_set'; @@ -98,19 +98,19 @@ import { } from './view'; import { ViewSnapshot } from './view_snapshot'; import { wrapInUserErrorIfRecoverable } from '../util/async_queue'; -import { BundleReader } from '../util/bundle_reader'; -import { - BundleLoader, - bundleInitialProgress, - bundleSuccessProgress -} from './bundle'; -import { LoadBundleTask } from '../api/bundle'; import { EventManager, eventManagerOnOnlineStateChange, eventManagerOnWatchChange, eventManagerOnWatchError } from './event_manager'; +import { BundleReader } from '../util/bundle_reader'; +import { LoadBundleTask } from '../api/bundle'; +import { + bundleInitialProgress, + bundleSuccessProgress, + BundleLoader +} from './bundle'; const LOG_TAG = 'SyncEngine'; @@ -1537,8 +1537,8 @@ export function ensureWriteCallbacks(syncEngine: SyncEngine): SyncEngineImpl { * Loads a Firestore bundle into the SDK. The returned promise resolves when * the bundle finished loading. * - * @param bundleReader - Bundle to load into the SDK. - * @param task - LoadBundleTask used to update the loading progress to public API. + * @param bundleReader Bundle to load into the SDK. + * @param task LoadBundleTask used to update the loading progress to public API. */ export function syncEngineLoadBundle( syncEngine: SyncEngine, diff --git a/packages/firestore/src/local/bundle_cache.ts b/packages/firestore/src/local/bundle_cache.ts index c9dadb86e9b..004d91c3053 100644 --- a/packages/firestore/src/local/bundle_cache.ts +++ b/packages/firestore/src/local/bundle_cache.ts @@ -21,7 +21,7 @@ import { NamedQuery as ProtoNamedQuery, BundleMetadata as ProtoBundleMetadata } from '../protos/firestore_bundle_proto'; -import { Bundle, NamedQuery } from '../core/bundle'; +import { Bundle, NamedQuery } from '../core/bundle_types'; /** * Provides interfaces to save and read Firestore bundles. diff --git a/packages/firestore/src/local/indexeddb_bundle_cache.ts b/packages/firestore/src/local/indexeddb_bundle_cache.ts index 341ff75e8c5..b713444761a 100644 --- a/packages/firestore/src/local/indexeddb_bundle_cache.ts +++ b/packages/firestore/src/local/indexeddb_bundle_cache.ts @@ -37,7 +37,7 @@ import { toDbBundle, toDbNamedQuery } from './local_serializer'; -import { Bundle, NamedQuery } from '../core/bundle'; +import { Bundle, NamedQuery } from '../core/bundle_types'; export class IndexedDbBundleCache implements BundleCache { constructor(private serializer: LocalSerializer) {} diff --git a/packages/firestore/src/local/local_serializer.ts b/packages/firestore/src/local/local_serializer.ts index f4b147af8cd..bb1d49525c8 100644 --- a/packages/firestore/src/local/local_serializer.ts +++ b/packages/firestore/src/local/local_serializer.ts @@ -55,13 +55,13 @@ import { DbUnknownDocument } from './indexeddb_schema'; import { TargetData, TargetPurpose } from './target_data'; -import { Bundle, NamedQuery } from '../core/bundle'; import { LimitType, Query, queryWithLimit } from '../core/query'; import { BundleMetadata as ProtoBundleMetadata, NamedQuery as ProtoNamedQuery, BundledQuery as ProtoBundledQuery } from '../protos/firestore_bundle_proto'; +import { Bundle, NamedQuery } from '../core/bundle_types'; /** Serializer for values stored in the LocalStore. */ export class LocalSerializer { diff --git a/packages/firestore/src/local/local_store.ts b/packages/firestore/src/local/local_store.ts index 76db4f85921..94eedc5f033 100644 --- a/packages/firestore/src/local/local_store.ts +++ b/packages/firestore/src/local/local_store.ts @@ -76,15 +76,16 @@ import { import { IndexedDbTargetCache } from './indexeddb_target_cache'; import { extractFieldMask } from '../model/object_value'; import { isIndexedDbTransactionError } from './simple_db'; -import { - NamedQuery as ProtoNamedQuery, - BundleMetadata as ProtoBundleMetadata -} from '../protos/firestore_bundle_proto'; -import { BundleConverter, BundledDocuments, NamedQuery } from '../core/bundle'; import { BundleCache } from './bundle_cache'; import { fromVersion, JsonProtoSerializer } from '../remote/serializer'; +import { + BundleMetadata, + NamedQuery as ProtoNamedQuery +} from '../protos/firestore_bundle_proto'; +import { NamedQuery } from '../core/bundle_types'; import { fromBundledQuery } from './local_serializer'; import { ByteString } from '../util/byte_string'; +import { BundleConverter, BundledDocuments } from '../core/bundle'; import { ResourcePath } from '../model/path'; const LOG_TAG = 'LocalStore'; @@ -1373,7 +1374,7 @@ export async function applyBundleDocuments( */ export function hasNewerBundle( localStore: LocalStore, - bundleMetadata: ProtoBundleMetadata + bundleMetadata: BundleMetadata ): Promise { const localStoreImpl = debugCast(localStore, LocalStoreImpl); const bundleConverter = new BundleConverter(localStoreImpl.serializer); @@ -1394,10 +1395,11 @@ export function hasNewerBundle( /** * Saves the given `BundleMetadata` to local persistence. + * @param bundleMetadata */ export function saveBundle( localStore: LocalStore, - bundleMetadata: ProtoBundleMetadata + bundleMetadata: BundleMetadata ): Promise { const localStoreImpl = debugCast(localStore, LocalStoreImpl); return localStoreImpl.persistence.runTransaction( diff --git a/packages/firestore/src/local/memory_bundle_cache.ts b/packages/firestore/src/local/memory_bundle_cache.ts index f45d2359af4..e7b08144fee 100644 --- a/packages/firestore/src/local/memory_bundle_cache.ts +++ b/packages/firestore/src/local/memory_bundle_cache.ts @@ -22,12 +22,12 @@ import { BundleMetadata as ProtoBundleMetadata } from '../protos/firestore_bundle_proto'; import { BundleCache } from './bundle_cache'; -import { Bundle, NamedQuery } from '../core/bundle'; import { fromBundleMetadata, fromProtoNamedQuery, LocalSerializer } from './local_serializer'; +import { Bundle, NamedQuery } from '../core/bundle_types'; export class MemoryBundleCache implements BundleCache { private bundles = new Map(); diff --git a/packages/firestore/test/integration/util/firebase_export.ts b/packages/firestore/test/integration/util/firebase_export.ts index e841232d12b..5da44345c22 100644 --- a/packages/firestore/test/integration/util/firebase_export.ts +++ b/packages/firestore/test/integration/util/firebase_export.ts @@ -31,6 +31,8 @@ import { Blob } from '../../../src/api/blob'; import { GeoPoint } from '../../../src/api/geo_point'; import { FirebaseApp } from '@firebase/app-types'; import { Firestore } from '../../../src/api/database'; +// Import to trigger prototype patching of bundle loading. +import '../../../index.bundle'; // TODO(dimond): Right now we create a new app and Firestore instance for // every test and never clean them up. We may need to revisit. diff --git a/packages/firestore/test/unit/local/bundle_cache.test.ts b/packages/firestore/test/unit/local/bundle_cache.test.ts index dfc84ee6b90..4c906a13453 100644 --- a/packages/firestore/test/unit/local/bundle_cache.test.ts +++ b/packages/firestore/test/unit/local/bundle_cache.test.ts @@ -35,8 +35,8 @@ import { testIndexedDbPersistence, testMemoryEagerPersistence } from './persistence_test_helpers'; -import { NamedQuery } from '../../../src/core/bundle'; import { toQueryTarget } from '../../../src/remote/serializer'; +import { NamedQuery } from '../../../src/core/bundle_types'; describe('MemoryBundleCache', () => { let cache: TestBundleCache; diff --git a/packages/firestore/test/unit/local/local_store.test.ts b/packages/firestore/test/unit/local/local_store.test.ts index b379a403161..e05d0425b09 100644 --- a/packages/firestore/test/unit/local/local_store.test.ts +++ b/packages/firestore/test/unit/local/local_store.test.ts @@ -34,15 +34,10 @@ import { SnapshotVersion } from '../../../src/core/snapshot_version'; import { IndexFreeQueryEngine } from '../../../src/local/index_free_query_engine'; import { IndexedDbPersistence } from '../../../src/local/indexeddb_persistence'; import { - applyBundleDocuments, - getNamedQuery, - hasNewerBundle, applyRemoteEventToLocalCache, LocalStore, LocalWriteResult, newLocalStore, - saveBundle, - saveNamedQuery, synchronizeLastDocumentChangeReadTime, notifyLocalViewChanges, acknowledgeBatch, @@ -53,7 +48,12 @@ import { releaseTarget, getLocalTargetData, getHighestUnacknowledgedBatchId, - rejectBatch + rejectBatch, + saveNamedQuery, + getNamedQuery, + saveBundle, + hasNewerBundle, + applyBundleDocuments } from '../../../src/local/local_store'; import { LocalViewChanges } from '../../../src/local/local_view_changes'; import { Persistence } from '../../../src/local/persistence'; @@ -114,8 +114,9 @@ import { CountingQueryEngine, QueryEngineType } from './counting_query_engine'; import * as persistenceHelpers from './persistence_test_helpers'; import { JSON_SERIALIZER } from './persistence_test_helpers'; import { ByteString } from '../../../src/util/byte_string'; -import { BundledDocuments, NamedQuery } from '../../../src/core/bundle'; +import { BundledDocuments } from '../../../src/core/bundle'; import { BundleMetadata as ProtoBundleMetadata } from '../../../src/protos/firestore_bundle_proto'; +import { NamedQuery } from '../../../src/core/bundle_types'; export interface LocalStoreComponents { queryEngine: CountingQueryEngine; diff --git a/packages/firestore/test/unit/local/test_bundle_cache.ts b/packages/firestore/test/unit/local/test_bundle_cache.ts index 2ee7badc315..0e9a4a879bc 100644 --- a/packages/firestore/test/unit/local/test_bundle_cache.ts +++ b/packages/firestore/test/unit/local/test_bundle_cache.ts @@ -17,11 +17,11 @@ import { Persistence } from '../../../src/local/persistence'; import { BundleCache } from '../../../src/local/bundle_cache'; -import { Bundle, NamedQuery } from '../../../src/core/bundle'; import { NamedQuery as ProtoNamedQuery, BundleMetadata as ProtoBundleMetadata } from '../../../src/protos/firestore_bundle_proto'; +import { Bundle, NamedQuery } from '../../../src/core/bundle_types'; /** * A wrapper around a BundleCache that automatically creates a diff --git a/packages/firestore/test/unit/specs/spec_test_runner.ts b/packages/firestore/test/unit/specs/spec_test_runner.ts index 099489d6373..258891614e3 100644 --- a/packages/firestore/test/unit/specs/spec_test_runner.ts +++ b/packages/firestore/test/unit/specs/spec_test_runner.ts @@ -42,12 +42,12 @@ import { } from '../../../src/core/query'; import { SnapshotVersion } from '../../../src/core/snapshot_version'; import { - syncEngineLoadBundle, activeLimboDocumentResolutions, enqueuedLimboDocumentResolutions, registerPendingWritesCallback, SyncEngine, syncEngineListen, + syncEngineLoadBundle, syncEngineUnlisten, syncEngineWrite } from '../../../src/core/sync_engine';