Deployed the page to Github Pages.

This commit is contained in:
Batuhan Berk Başoğlu 2024-11-03 21:30:09 -05:00
parent 1d79754e93
commit 2c89899458
Signed by: batuhan-basoglu
SSH key fingerprint: SHA256:kEsnuHX+qbwhxSAXPUQ4ox535wFHu/hIRaa53FzxRpo
62797 changed files with 6551425 additions and 15279 deletions

24
node_modules/@firebase/firestore/README.md generated vendored Normal file
View file

@ -0,0 +1,24 @@
# @firebase/firestore
This is the [Cloud Firestore](https://firebase.google.com/docs/firestore/) component of the
[Firebase JS SDK](https://www.npmjs.com/package/firebase).
**This package is not intended for direct usage, and should only be used via the officially
supported [firebase](https://www.npmjs.com/package/firebase) package.**
If you are developing a Node.js application that requires administrative access to Cloud Firestore,
use the [`@google-cloud/firestore`](https://www.npmjs.com/package/@google-cloud/firestore) Server
SDK with your developer credentials.
## Documentation
For comprehensive documentation please see the [Firebase Reference
Docs][reference-docs].
[reference-docs]: https://firebase.google.com/docs/reference/js/
## Contributing
See [Contributing to the Firebase SDK](../../CONTRIBUTING.md) for general
information about contributing to the firebase-js-sdk repo and
[Contributing to the Cloud Firestore Component](./CONTRIBUTING.md) for
details specific to the Cloud Firestore code and tests.

View file

@ -0,0 +1,29 @@
/**
* Firestore Lite
*
* @remarks Firestore Lite is a small online-only SDK that allows read
* and write access to your Firestore database. All operations connect
* directly to the backend, and `onSnapshot()` APIs are not supported.
* @packageDocumentation
*/
export { aggregateQuerySnapshotEqual, getCount, getAggregate, count, sum, average, aggregateFieldEqual } from '../src/lite-api/aggregate';
export { AggregateField, AggregateFieldType, AggregateSpec, AggregateSpecData, AggregateQuerySnapshot, AggregateType } from '../src/lite-api/aggregate_types';
export { FirestoreSettings as Settings } from '../src/lite-api/settings';
export { Firestore as Firestore, EmulatorMockTokenOptions, initializeFirestore, getFirestore, terminate, connectFirestoreEmulator } from '../src/lite-api/database';
export { DocumentData, UpdateData, WithFieldValue, PartialWithFieldValue, SetOptions, DocumentReference, Query, CollectionReference, collection, collectionGroup, doc, refEqual, queryEqual } from '../src/lite-api/reference';
export { and, endAt, endBefore, startAt, startAfter, limit, limitToLast, where, or, orderBy, query, QueryConstraint, QueryConstraintType, QueryCompositeFilterConstraint, QueryFilterConstraint, QueryFieldFilterConstraint, QueryOrderByConstraint, QueryLimitConstraint, QueryNonFilterConstraint, QueryStartAtConstraint, QueryEndAtConstraint, OrderByDirection, WhereFilterOp } from '../src/lite-api/query';
export { addDoc, deleteDoc, updateDoc, setDoc, getDoc, getDocs } from '../src/lite-api/reference_impl';
export { Primitive, NestedUpdateFields, ChildUpdateFields, AddPrefixToKeys, UnionToIntersection } from '../src/lite-api/types';
export { FieldPath, documentId } from '../src/lite-api/field_path';
export { FieldValue } from '../src/lite-api/field_value';
export { increment, arrayRemove, arrayUnion, serverTimestamp, deleteField, vector } from '../src/lite-api/field_value_impl';
export { FirestoreDataConverter, DocumentSnapshot, QueryDocumentSnapshot, QuerySnapshot, snapshotEqual } from '../src/lite-api/snapshot';
export { VectorValue } from '../src/lite-api/vector_value';
export { WriteBatch, writeBatch } from '../src/lite-api/write_batch';
export { TransactionOptions } from '../src/lite-api/transaction_options';
export { Transaction, runTransaction } from '../src/lite-api/transaction';
export { setLogLevel, LogLevelString as LogLevel } from '../src/util/log';
export { Bytes } from '../src/lite-api/bytes';
export { GeoPoint } from '../src/lite-api/geo_point';
export { Timestamp } from '../src/lite-api/timestamp';
export { FirestoreErrorCode, FirestoreError } from '../src/util/error';

View file

@ -0,0 +1,23 @@
/**
* @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/lite-api/database';
declare module '@firebase/component' {
interface NameServiceMapping {
'firestore/lite': Firestore;
}
}
export declare function registerFirestore(): void;

View file

@ -0,0 +1,65 @@
/**
* @license
* Copyright 2021 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.
*/
export { aggregateFieldEqual, aggregateQuerySnapshotEqual, average, count, getAggregateFromServer, getCountFromServer, sum } from './api/aggregate';
export { AggregateField, AggregateFieldType, AggregateQuerySnapshot, AggregateSpec, AggregateSpecData, AggregateType } from './lite-api/aggregate_types';
export { FirestoreLocalCache, MemoryCacheSettings, MemoryEagerGarbageCollector, memoryEagerGarbageCollector, MemoryGarbageCollector, MemoryLocalCache, memoryLocalCache, MemoryLruGarbageCollector, memoryLruGarbageCollector, PersistentCacheSettings, PersistentLocalCache, persistentLocalCache, PersistentMultipleTabManager, persistentMultipleTabManager, PersistentSingleTabManager, persistentSingleTabManager, PersistentSingleTabManagerSettings, PersistentTabManager } from './api/cache_config';
export { documentId, FieldPath } from './api/field_path';
export { clearIndexedDbPersistence, connectFirestoreEmulator, disableNetwork, EmulatorMockTokenOptions, enableIndexedDbPersistence, enableMultiTabIndexedDbPersistence, enableNetwork, ensureFirestoreConfigured, Firestore, getFirestore, initializeFirestore, loadBundle, namedQuery, terminate, waitForPendingWrites } from './api/database';
export { LoadBundleTask, LoadBundleTaskProgress, TaskState } from './api/bundle';
export { FirestoreSettings, PersistenceSettings } from './api/settings';
export type { PrivateSettings } from './lite-api/settings';
export { ExperimentalLongPollingOptions } from './api/long_polling_options';
export { DocumentChange, DocumentChangeType, DocumentSnapshot, FirestoreDataConverter, QueryDocumentSnapshot, QuerySnapshot, snapshotEqual, SnapshotMetadata, SnapshotOptions } from './api/snapshot';
export { collection, collectionGroup, CollectionReference, doc, DocumentData, DocumentReference, PartialWithFieldValue, Query, queryEqual, refEqual, SetOptions, UpdateData, WithFieldValue } from './api/reference';
export { and, endAt, endBefore, limit, limitToLast, or, orderBy, OrderByDirection, query, QueryCompositeFilterConstraint, QueryConstraint, QueryConstraintType, QueryEndAtConstraint, QueryFieldFilterConstraint, QueryFilterConstraint, QueryLimitConstraint, QueryNonFilterConstraint, QueryOrderByConstraint, QueryStartAtConstraint, startAfter, startAt, where, WhereFilterOp } from './api/filter';
export { ListenSource, SnapshotListenOptions, Unsubscribe } from './api/reference_impl';
export { TransactionOptions } from './api/transaction_options';
export { runTransaction, Transaction } from './api/transaction';
export { addDoc, deleteDoc, executeWrite, getDoc, getDocFromCache, getDocFromServer, getDocs, getDocsFromCache, getDocsFromServer, onSnapshot, onSnapshotsInSync, setDoc, updateDoc } from './api/reference_impl';
export { FieldValue } from './api/field_value';
export { arrayRemove, arrayUnion, deleteField, increment, serverTimestamp, vector } from './api/field_value_impl';
export { VectorValue } from './lite-api/vector_value';
export { LogLevelString as LogLevel, setLogLevel } from './util/log';
export { Bytes } from './api/bytes';
export { WriteBatch, writeBatch } from './api/write_batch';
export { GeoPoint } from './api/geo_point';
export { Timestamp } from './api/timestamp';
export { CACHE_SIZE_UNLIMITED } from './api/database';
export { FirestoreError, FirestoreErrorCode } from './util/error';
export { AbstractUserDataWriter } from './lite-api/user_data_writer';
export { AddPrefixToKeys, ChildUpdateFields, NestedUpdateFields, Primitive, UnionToIntersection } from '../src/lite-api/types';
export { Index, IndexConfiguration, IndexField, setIndexConfiguration } from './api/index_configuration';
export { PersistentCacheIndexManager, getPersistentCacheIndexManager, deleteAllPersistentCacheIndexes, enablePersistentCacheIndexAutoCreation, disablePersistentCacheIndexAutoCreation } from './api/persistent_cache_index_manager';
/**
* Internal exports
*/
export { isBase64Available as _isBase64Available } from './platform/base64';
export { DatabaseId as _DatabaseId } from './core/database_info';
export { _internalQueryToProtoQueryTarget, _internalAggregationQueryToProtoRunAggregationQueryRequest } from './remote/internal_serializer';
export { cast as _cast, validateIsNotUsedTogether as _validateIsNotUsedTogether } from './util/input_validation';
export { DocumentKey as _DocumentKey } from './model/document_key';
export { debugAssert as _debugAssert } from './util/assert';
export { FieldPath as _FieldPath } from './model/path';
export type { ResourcePath as _ResourcePath } from './model/path';
export { ByteString as _ByteString } from './util/byte_string';
export { logWarn as _logWarn } from './util/log';
export { AutoId as _AutoId } from './util/misc';
export type { AuthTokenFactory, FirstPartyCredentialsSettings } from './api/credentials';
export { EmptyAuthCredentialsProvider as _EmptyAuthCredentialsProvider } from './api/credentials';
export { EmptyAppCheckTokenProvider as _EmptyAppCheckTokenProvider } from './api/credentials';
export { ExistenceFilterMismatchCallback as _TestingHooksExistenceFilterMismatchCallback, TestingHooks as _TestingHooks } from './util/testing_hooks';
export { ExistenceFilterMismatchInfo as _TestingHooksExistenceFilterMismatchInfo } from './util/testing_hooks_spi';

View file

@ -0,0 +1,77 @@
/**
* @license
* Copyright 2022 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 { AggregateField, AggregateSpec, DocumentData, Query } from '../api';
import { AggregateQuerySnapshot } from '../lite-api/aggregate_types';
export { aggregateQuerySnapshotEqual, count, sum, average, aggregateFieldEqual } from '../lite-api/aggregate';
/**
* Calculates the number of documents in the result set of the given query
* without actually downloading the documents.
*
* Using this function to count the documents is efficient because only the
* final count, not the documents' data, is downloaded. This function can
* count the documents in cases where the result set is prohibitively large to
* download entirely (thousands of documents).
*
* The result received from the server is presented, unaltered, without
* considering any local state. That is, documents in the local cache are not
* taken into consideration, neither are local modifications not yet
* synchronized with the server. Previously-downloaded results, if any, are not
* used. Every invocation of this function necessarily involves a round trip to
* the server.
*
* @param query The query whose result set size is calculated.
* @returns A Promise that will be resolved with the count; the count can be
* retrieved from `snapshot.data().count`, where `snapshot` is the
* `AggregateQuerySnapshot` to which the returned Promise resolves.
*/
export declare function getCountFromServer<AppModelType, DbModelType extends DocumentData>(query: Query<AppModelType, DbModelType>): Promise<AggregateQuerySnapshot<{
count: AggregateField<number>;
}, AppModelType, DbModelType>>;
/**
* Calculates the specified aggregations over the documents in the result
* set of the given query without actually downloading the documents.
*
* Using this function to perform aggregations is efficient because only the
* final aggregation values, not the documents' data, are downloaded. This
* function can perform aggregations of the documents in cases where the result
* set is prohibitively large to download entirely (thousands of documents).
*
* The result received from the server is presented, unaltered, without
* considering any local state. That is, documents in the local cache are not
* taken into consideration, neither are local modifications not yet
* synchronized with the server. Previously-downloaded results, if any, are not
* used. Every invocation of this function necessarily involves a round trip to
* the server.
*
* @param query The query whose result set is aggregated over.
* @param aggregateSpec An `AggregateSpec` object that specifies the aggregates
* to perform over the result set. The AggregateSpec specifies aliases for each
* aggregate, which can be used to retrieve the aggregate result.
* @example
* ```typescript
* const aggregateSnapshot = await getAggregateFromServer(query, {
* countOfDocs: count(),
* totalHours: sum('hours'),
* averageScore: average('score')
* });
*
* const countOfDocs: number = aggregateSnapshot.data().countOfDocs;
* const totalHours: number = aggregateSnapshot.data().totalHours;
* const averageScore: number | null = aggregateSnapshot.data().averageScore;
* ```
*/
export declare function getAggregateFromServer<AggregateSpecType extends AggregateSpec, AppModelType, DbModelType extends DocumentData>(query: Query<AppModelType, DbModelType>, aggregateSpec: AggregateSpecType): Promise<AggregateQuerySnapshot<AggregateSpecType, AppModelType, DbModelType>>;

View file

@ -0,0 +1,94 @@
/**
* @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 { FirestoreError } from '../util/error';
/**
* Represents the state of bundle loading tasks.
*
* Both 'Error' and 'Success' are sinking state: task will abort or complete and there will
* be no more updates after they are reported.
*/
export declare type TaskState = 'Error' | 'Running' | 'Success';
/**
* Represents a progress update or a final state from loading bundles.
*/
export interface LoadBundleTaskProgress {
/** How many documents have been loaded. */
documentsLoaded: number;
/** How many documents are in the bundle being loaded. */
totalDocuments: number;
/** How many bytes have been loaded. */
bytesLoaded: number;
/** How many bytes are in the bundle being loaded. */
totalBytes: number;
/** Current task state. */
taskState: TaskState;
}
/**
* Represents the task of loading a Firestore bundle. It provides progress of bundle
* loading, as well as task completion and error events.
*
* The API is compatible with `Promise<LoadBundleTaskProgress>`.
*/
export declare class LoadBundleTask implements PromiseLike<LoadBundleTaskProgress> {
private _progressObserver;
private _taskCompletionResolver;
private _lastProgress;
/**
* Registers functions to listen to bundle loading progress events.
* @param next - Called when there is a progress update from bundle loading. Typically `next` calls occur
* each time a Firestore document is loaded from the bundle.
* @param error - Called when an error occurs during bundle loading. The task aborts after reporting the
* error, and there should be no more updates after this.
* @param complete - Called when the loading task is complete.
*/
onProgress(next?: (progress: LoadBundleTaskProgress) => unknown, error?: (err: Error) => unknown, complete?: () => void): void;
/**
* Implements the `Promise<LoadBundleTaskProgress>.catch` interface.
*
* @param onRejected - Called when an error occurs during bundle loading.
*/
catch<R>(onRejected: (a: Error) => R | PromiseLike<R>): Promise<R | LoadBundleTaskProgress>;
/**
* Implements the `Promise<LoadBundleTaskProgress>.then` interface.
*
* @param onFulfilled - Called on the completion of the loading task with a final `LoadBundleTaskProgress` update.
* The update will always have its `taskState` set to `"Success"`.
* @param onRejected - Called when an error occurs during bundle loading.
*/
then<T, R>(onFulfilled?: (a: LoadBundleTaskProgress) => T | PromiseLike<T>, onRejected?: (a: Error) => R | PromiseLike<R>): Promise<T | R>;
/**
* Notifies all observers that bundle loading has completed, with a provided
* `LoadBundleTaskProgress` object.
*
* @private
*/
_completeWith(progress: LoadBundleTaskProgress): void;
/**
* Notifies all observers that bundle loading has failed, with a provided
* `Error` as the reason.
*
* @private
*/
_failWith(error: FirestoreError): void;
/**
* Notifies a progress update of loading a bundle.
* @param progress - The new progress.
*
* @private
*/
_updateProgress(progress: LoadBundleTaskProgress): void;
}

View file

@ -0,0 +1,17 @@
/**
* @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.
*/
export { Bytes } from '../lite-api/bytes';

View file

@ -0,0 +1,222 @@
/**
* @license
* Copyright 2023 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 { OfflineComponentProviderFactory, OnlineComponentProviderFactory } from '../core/component_provider';
/**
* Provides an in-memory cache to the SDK. This is the default cache unless explicitly
* configured otherwise.
*
* To use, create an instance using the factory function {@link memoryLocalCache()}, then
* set the instance to `FirestoreSettings.cache` and call `initializeFirestore` using
* the settings object.
*/
export declare type MemoryLocalCache = {
kind: 'memory';
/**
* @internal
*/
_onlineComponentProvider: OnlineComponentProviderFactory;
/**
* @internal
*/
_offlineComponentProvider: OfflineComponentProviderFactory;
};
/**
* Provides a persistent cache backed by IndexedDb to the SDK.
*
* To use, create an instance using the factory function {@link persistentLocalCache()}, then
* set the instance to `FirestoreSettings.cache` and call `initializeFirestore` using
* the settings object.
*/
export declare type PersistentLocalCache = {
kind: 'persistent';
/**
* @internal
*/
_onlineComponentProvider: OnlineComponentProviderFactory;
/**
* @internal
*/
_offlineComponentProvider: OfflineComponentProviderFactory;
};
/**
* Union type from all supported SDK cache layer.
*/
export declare type FirestoreLocalCache = MemoryLocalCache | PersistentLocalCache;
/**
* Union type from all support garbage collectors for memory local cache.
*/
export declare type MemoryGarbageCollector = MemoryEagerGarbageCollector | MemoryLruGarbageCollector;
/**
* A garbage collector deletes documents whenever they are not part of any
* active queries, and have no local mutations attached to them.
*
* This collector tries to ensure lowest memory footprints from the SDK,
* at the risk of documents not being cached for offline queries or for
* direct queries to the cache.
*
* Use factory function {@link memoryEagerGarbageCollector()} to create an
* instance of this collector.
*/
export declare type MemoryEagerGarbageCollector = {
kind: 'memoryEager';
/**
* @internal
*/
_offlineComponentProvider: OfflineComponentProviderFactory;
};
/**
* A garbage collector deletes Least-Recently-Used documents in multiple
* batches.
*
* This collector is configured with a target size, and will only perform
* collection when the cached documents exceed the target size. It avoids
* querying backend repeated for the same query or document, at the risk
* of having a larger memory footprint.
*
* Use factory function {@link memoryLruGarbageCollector()} to create a
* instance of this collector.
*/
export declare type MemoryLruGarbageCollector = {
kind: 'memoryLru';
/**
* @internal
*/
_offlineComponentProvider: OfflineComponentProviderFactory;
};
/**
* Creates an instance of `MemoryEagerGarbageCollector`. This is also the
* default garbage collector unless it is explicitly specified otherwise.
*/
export declare function memoryEagerGarbageCollector(): MemoryEagerGarbageCollector;
/**
* Creates an instance of `MemoryLruGarbageCollector`.
*
* A target size can be specified as part of the setting parameter. The
* collector will start deleting documents once the cache size exceeds
* the given size. The default cache size is 40MB (40 * 1024 * 1024 bytes).
*/
export declare function memoryLruGarbageCollector(settings?: {
cacheSizeBytes?: number;
}): MemoryLruGarbageCollector;
/**
* An settings object to configure an `MemoryLocalCache` instance.
*/
export declare type MemoryCacheSettings = {
/**
* The garbage collector to use, for the memory cache layer.
* A `MemoryEagerGarbageCollector` is used when this is undefined.
*/
garbageCollector?: MemoryGarbageCollector;
};
/**
* Creates an instance of `MemoryLocalCache`. The instance can be set to
* `FirestoreSettings.cache` to tell the SDK which cache layer to use.
*/
export declare function memoryLocalCache(settings?: MemoryCacheSettings): MemoryLocalCache;
/**
* An settings object to configure an `PersistentLocalCache` instance.
*
* Persistent cache cannot be used in a Node.js environment.
*/
export declare type PersistentCacheSettings = {
/**
* An approximate cache size threshold for the on-disk data. If the cache
* grows beyond this size, Firestore will start removing data that hasn't been
* recently used. The SDK does not guarantee that the cache will stay below
* that size, only that if the cache exceeds the given size, cleanup will be
* attempted.
*
* The default value is 40 MB. The threshold must be set to at least 1 MB, and
* can be set to `CACHE_SIZE_UNLIMITED` to disable garbage collection.
*/
cacheSizeBytes?: number;
/**
* Specifies how multiple tabs/windows will be managed by the SDK.
*/
tabManager?: PersistentTabManager;
};
/**
* Creates an instance of `PersistentLocalCache`. The instance can be set to
* `FirestoreSettings.cache` to tell the SDK which cache layer to use.
*
* Persistent cache cannot be used in a Node.js environment.
*/
export declare function persistentLocalCache(settings?: PersistentCacheSettings): PersistentLocalCache;
/**
* A tab manager supporting only one tab, no synchronization will be
* performed across tabs.
*/
export declare type PersistentSingleTabManager = {
kind: 'persistentSingleTab';
/**
* @internal
*/
_initialize: (settings: Omit<PersistentCacheSettings, 'tabManager'> | undefined) => void;
/**
* @internal
*/
_onlineComponentProvider?: OnlineComponentProviderFactory;
/**
* @internal
*/
_offlineComponentProvider?: OfflineComponentProviderFactory;
};
/**
* A tab manager supporting multiple tabs. SDK will synchronize queries and
* mutations done across all tabs using the SDK.
*/
export declare type PersistentMultipleTabManager = {
kind: 'PersistentMultipleTab';
/**
* @internal
*/
_initialize: (settings: Omit<PersistentCacheSettings, 'tabManager'>) => void;
/**
* @internal
*/
_onlineComponentProvider?: OnlineComponentProviderFactory;
/**
* @internal
*/
_offlineComponentProvider?: OfflineComponentProviderFactory;
};
/**
* A union of all available tab managers.
*/
export declare type PersistentTabManager = PersistentSingleTabManager | PersistentMultipleTabManager;
/**
* Type to configure an `PersistentSingleTabManager` instance.
*/
export declare type PersistentSingleTabManagerSettings = {
/**
* Whether to force-enable persistent (IndexedDB) cache for the client. This
* cannot be used with multi-tab synchronization and is primarily intended for
* use with Web Workers. Setting this to `true` will enable IndexedDB, but cause
* other tabs using IndexedDB cache to fail.
*/
forceOwnership?: boolean;
};
/**
* Creates an instance of `PersistentSingleTabManager`.
*
* @param settings Configures the created tab manager.
*/
export declare function persistentSingleTabManager(settings: PersistentSingleTabManagerSettings | undefined): PersistentSingleTabManager;
/**
* Creates an instance of `PersistentMultipleTabManager`.
*/
export declare function persistentMultipleTabManager(): PersistentMultipleTabManager;

View file

@ -0,0 +1,219 @@
/**
* @license
* Copyright 2017 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 { AppCheckInternalComponentName } from '@firebase/app-check-interop-types';
import { FirebaseAuthInternalName } from '@firebase/auth-interop-types';
import { Provider } from '@firebase/component';
import { User } from '../auth/user';
import { AsyncQueue } from '../util/async_queue';
/**
* @internal
*/
export declare type AuthTokenFactory = () => string;
/**
* @internal
*/
export interface FirstPartyCredentialsSettings {
['type']: 'firstParty';
['sessionIndex']: string;
['iamToken']: string | null;
['authTokenFactory']: AuthTokenFactory | null;
}
export interface ProviderCredentialsSettings {
['type']: 'provider';
['client']: CredentialsProvider<User>;
}
/** Settings for private credentials */
export declare type CredentialsSettings = FirstPartyCredentialsSettings | ProviderCredentialsSettings;
export declare type TokenType = 'OAuth' | 'FirstParty' | 'AppCheck';
export interface Token {
/** Type of token. */
type: TokenType;
/**
* The user with which the token is associated (used for persisting user
* state on disk, etc.).
* This will be null for Tokens of the type 'AppCheck'.
*/
user?: User;
/** Header values to set for this token */
headers: Map<string, string>;
}
export declare class OAuthToken implements Token {
user: User;
type: TokenType;
headers: Map<any, any>;
constructor(value: string, user: User);
}
/**
* A Listener for credential change events. The listener should fetch a new
* token and may need to invalidate other state if the current user has also
* changed.
*/
export declare type CredentialChangeListener<T> = (credential: T) => Promise<void>;
/**
* Provides methods for getting the uid and token for the current user and
* listening for changes.
*/
export interface CredentialsProvider<T> {
/**
* Starts the credentials provider and specifies a listener to be notified of
* credential changes (sign-in / sign-out, token changes). It is immediately
* called once with the initial user.
*
* The change listener is invoked on the provided AsyncQueue.
*/
start(asyncQueue: AsyncQueue, changeListener: CredentialChangeListener<T>): void;
/** Requests a token for the current user. */
getToken(): Promise<Token | null>;
/**
* Marks the last retrieved token as invalid, making the next GetToken request
* force-refresh the token.
*/
invalidateToken(): void;
shutdown(): void;
}
/**
* A CredentialsProvider that always yields an empty token.
* @internal
*/
export declare class EmptyAuthCredentialsProvider implements CredentialsProvider<User> {
getToken(): Promise<Token | null>;
invalidateToken(): void;
start(asyncQueue: AsyncQueue, changeListener: CredentialChangeListener<User>): void;
shutdown(): void;
}
/**
* A CredentialsProvider that always returns a constant token. Used for
* emulator token mocking.
*/
export declare class EmulatorAuthCredentialsProvider implements CredentialsProvider<User> {
private token;
constructor(token: Token);
/**
* Stores the listener registered with setChangeListener()
* This isn't actually necessary since the UID never changes, but we use this
* to verify the listen contract is adhered to in tests.
*/
private changeListener;
getToken(): Promise<Token | null>;
invalidateToken(): void;
start(asyncQueue: AsyncQueue, changeListener: CredentialChangeListener<User>): void;
shutdown(): void;
}
/** Credential provider for the Lite SDK. */
export declare class LiteAuthCredentialsProvider implements CredentialsProvider<User> {
private auth;
constructor(authProvider: Provider<FirebaseAuthInternalName>);
getToken(): Promise<Token | null>;
invalidateToken(): void;
start(asyncQueue: AsyncQueue, changeListener: CredentialChangeListener<User>): void;
shutdown(): void;
}
export declare class FirebaseAuthCredentialsProvider implements CredentialsProvider<User> {
private authProvider;
/**
* The auth token listener registered with FirebaseApp, retained here so we
* can unregister it.
*/
private tokenListener;
/** Tracks the current User. */
private currentUser;
/**
* Counter used to detect if the token changed while a getToken request was
* outstanding.
*/
private tokenCounter;
private forceRefresh;
private auth;
constructor(authProvider: Provider<FirebaseAuthInternalName>);
start(asyncQueue: AsyncQueue, changeListener: CredentialChangeListener<User>): void;
getToken(): Promise<Token | null>;
invalidateToken(): void;
shutdown(): void;
private getUser;
}
export declare class FirstPartyToken implements Token {
private readonly sessionIndex;
private readonly iamToken;
private readonly authTokenFactory;
type: TokenType;
user: User;
private _headers;
constructor(sessionIndex: string, iamToken: string | null, authTokenFactory: AuthTokenFactory | null);
/**
* Gets an authorization token, using a provided factory function, or return
* null.
*/
private getAuthToken;
get headers(): Map<string, string>;
}
export declare class FirstPartyAuthCredentialsProvider implements CredentialsProvider<User> {
private sessionIndex;
private iamToken;
private authTokenFactory;
constructor(sessionIndex: string, iamToken: string | null, authTokenFactory: AuthTokenFactory | null);
getToken(): Promise<Token | null>;
start(asyncQueue: AsyncQueue, changeListener: CredentialChangeListener<User>): void;
shutdown(): void;
invalidateToken(): void;
}
export declare class AppCheckToken implements Token {
private value;
type: TokenType;
headers: Map<any, any>;
constructor(value: string);
}
export declare class FirebaseAppCheckTokenProvider implements CredentialsProvider<string> {
private appCheckProvider;
/**
* The AppCheck token listener registered with FirebaseApp, retained here so
* we can unregister it.
*/
private tokenListener;
private forceRefresh;
private appCheck;
private latestAppCheckToken;
constructor(appCheckProvider: Provider<AppCheckInternalComponentName>);
start(asyncQueue: AsyncQueue, changeListener: CredentialChangeListener<string>): void;
getToken(): Promise<Token | null>;
invalidateToken(): void;
shutdown(): void;
}
/**
* An AppCheck token provider that always yields an empty token.
* @internal
*/
export declare class EmptyAppCheckTokenProvider implements CredentialsProvider<string> {
getToken(): Promise<Token | null>;
invalidateToken(): void;
start(asyncQueue: AsyncQueue, changeListener: CredentialChangeListener<string>): void;
shutdown(): void;
}
/** AppCheck token provider for the Lite SDK. */
export declare class LiteAppCheckTokenProvider implements CredentialsProvider<string> {
private appCheckProvider;
private appCheck;
constructor(appCheckProvider: Provider<AppCheckInternalComponentName>);
getToken(): Promise<Token | null>;
invalidateToken(): void;
start(asyncQueue: AsyncQueue, changeListener: CredentialChangeListener<string>): void;
shutdown(): void;
}
/**
* Builds a CredentialsProvider depending on the type of
* the credentials passed in.
*/
export declare function makeAuthCredentialsProvider(credentials?: CredentialsSettings): CredentialsProvider<User>;

View file

@ -0,0 +1,279 @@
/**
* @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 { FirebaseApp } from '@firebase/app';
import { User } from '../auth/user';
import { OfflineComponentProviderFactory, OnlineComponentProviderFactory } from '../core/component_provider';
import { DatabaseId } from '../core/database_info';
import { FirestoreClient } from '../core/firestore_client';
import { Firestore as LiteFirestore } from '../lite-api/database';
import { Query } from '../lite-api/reference';
import { AsyncQueue } from '../util/async_queue';
import { LoadBundleTask } from './bundle';
import { CredentialsProvider } from './credentials';
import { FirestoreSettings, PersistenceSettings } from './settings';
export { connectFirestoreEmulator, EmulatorMockTokenOptions } from '../lite-api/database';
declare module '@firebase/component' {
interface NameServiceMapping {
'firestore': Firestore;
}
}
/**
* Constant used to indicate the LRU garbage collection should be disabled.
* Set this value as the `cacheSizeBytes` on the settings passed to the
* {@link Firestore} instance.
*/
export declare const CACHE_SIZE_UNLIMITED = -1;
/**
* The Cloud Firestore service interface.
*
* Do not call this constructor directly. Instead, use {@link (getFirestore:1)}.
*/
export declare class Firestore extends LiteFirestore {
/**
* Whether it's a {@link Firestore} or Firestore Lite instance.
*/
type: 'firestore-lite' | 'firestore';
_queue: AsyncQueue;
readonly _persistenceKey: string;
_firestoreClient: FirestoreClient | undefined;
_componentsProvider?: {
_offline: OfflineComponentProviderFactory;
_online: OnlineComponentProviderFactory;
};
/** @hideconstructor */
constructor(authCredentialsProvider: CredentialsProvider<User>, appCheckCredentialsProvider: CredentialsProvider<string>, databaseId: DatabaseId, app?: FirebaseApp);
protected _terminate(): Promise<void>;
}
/**
* Initializes a new instance of {@link Firestore} with the provided settings.
* Can only be called before any other function, including
* {@link (getFirestore:1)}. If the custom settings are empty, this function is
* equivalent to calling {@link (getFirestore:1)}.
*
* @param app - The {@link @firebase/app#FirebaseApp} with which the {@link Firestore} instance will
* be associated.
* @param settings - A settings object to configure the {@link Firestore} instance.
* @param databaseId - The name of the database.
* @returns A newly initialized {@link Firestore} instance.
*/
export declare function initializeFirestore(app: FirebaseApp, settings: FirestoreSettings, databaseId?: string): Firestore;
/**
* Returns the existing default {@link Firestore} instance that is associated with the
* default {@link @firebase/app#FirebaseApp}. If no instance exists, initializes a new
* instance with default settings.
*
* @returns The default {@link Firestore} instance of the default app.
*/
export declare function getFirestore(): Firestore;
/**
* Returns the existing default {@link Firestore} instance that is associated with the
* provided {@link @firebase/app#FirebaseApp}. If no instance exists, initializes a new
* instance with default settings.
*
* @param app - The {@link @firebase/app#FirebaseApp} instance that the returned {@link Firestore}
* instance is associated with.
* @returns The default {@link Firestore} instance of the provided app.
*/
export declare function getFirestore(app: FirebaseApp): Firestore;
/**
* Returns the existing named {@link Firestore} instance that is associated with the
* default {@link @firebase/app#FirebaseApp}. If no instance exists, initializes a new
* instance with default settings.
*
* @param databaseId - The name of the database.
* @returns The named {@link Firestore} instance of the default app.
* @beta
*/
export declare function getFirestore(databaseId: string): Firestore;
/**
* Returns the existing named {@link Firestore} instance that is associated with the
* provided {@link @firebase/app#FirebaseApp}. If no instance exists, initializes a new
* instance with default settings.
*
* @param app - The {@link @firebase/app#FirebaseApp} instance that the returned {@link Firestore}
* instance is associated with.
* @param databaseId - The name of the database.
* @returns The named {@link Firestore} instance of the provided app.
* @beta
*/
export declare function getFirestore(app: FirebaseApp, databaseId: string): Firestore;
/**
* @internal
*/
export declare function ensureFirestoreConfigured(firestore: Firestore): FirestoreClient;
export declare function configureFirestore(firestore: Firestore): void;
/**
* Attempts to enable persistent storage, if possible.
*
* On failure, `enableIndexedDbPersistence()` will reject the promise or
* throw an exception. There are several reasons why this can fail, which can be
* identified by the `code` on the error.
*
* * failed-precondition: The app is already open in another browser tab.
* * unimplemented: The browser is incompatible with the offline persistence
* implementation.
*
* Note that even after a failure, the {@link Firestore} instance will remain
* usable, however offline persistence will be disabled.
*
* Note: `enableIndexedDbPersistence()` must be called before any other functions
* (other than {@link initializeFirestore}, {@link (getFirestore:1)} or
* {@link clearIndexedDbPersistence}.
*
* Persistence cannot be used in a Node.js environment.
*
* @param firestore - The {@link Firestore} instance to enable persistence for.
* @param persistenceSettings - Optional settings object to configure
* persistence.
* @returns A `Promise` that represents successfully enabling persistent storage.
* @deprecated This function will be removed in a future major release. Instead, set
* `FirestoreSettings.localCache` to an instance of `PersistentLocalCache` to
* turn on IndexedDb cache. Calling this function when `FirestoreSettings.localCache`
* is already specified will throw an exception.
*/
export declare function enableIndexedDbPersistence(firestore: Firestore, persistenceSettings?: PersistenceSettings): Promise<void>;
/**
* Attempts to enable multi-tab persistent storage, if possible. If enabled
* across all tabs, all operations share access to local persistence, including
* shared execution of queries and latency-compensated local document updates
* across all connected instances.
*
* On failure, `enableMultiTabIndexedDbPersistence()` will reject the promise or
* throw an exception. There are several reasons why this can fail, which can be
* identified by the `code` on the error.
*
* * failed-precondition: The app is already open in another browser tab and
* multi-tab is not enabled.
* * unimplemented: The browser is incompatible with the offline persistence
* implementation.
*
* Note that even after a failure, the {@link Firestore} instance will remain
* usable, however offline persistence will be disabled.
*
* @param firestore - The {@link Firestore} instance to enable persistence for.
* @returns A `Promise` that represents successfully enabling persistent
* storage.
* @deprecated This function will be removed in a future major release. Instead, set
* `FirestoreSettings.localCache` to an instance of `PersistentLocalCache` to
* turn on indexeddb cache. Calling this function when `FirestoreSettings.localCache`
* is already specified will throw an exception.
*/
export declare function enableMultiTabIndexedDbPersistence(firestore: Firestore): Promise<void>;
/**
* Clears the persistent storage. This includes pending writes and cached
* documents.
*
* Must be called while the {@link Firestore} instance is not started (after the app is
* terminated or when the app is first initialized). On startup, this function
* must be called before other functions (other than {@link
* initializeFirestore} or {@link (getFirestore:1)})). If the {@link Firestore}
* instance is still running, the promise will be rejected with the error code
* of `failed-precondition`.
*
* Note: `clearIndexedDbPersistence()` is primarily intended to help write
* reliable tests that use Cloud Firestore. It uses an efficient mechanism for
* dropping existing data but does not attempt to securely overwrite or
* otherwise make cached data unrecoverable. For applications that are sensitive
* to the disclosure of cached data in between user sessions, we strongly
* recommend not enabling persistence at all.
*
* @param firestore - The {@link Firestore} instance to clear persistence for.
* @returns A `Promise` that is resolved when the persistent storage is
* cleared. Otherwise, the promise is rejected with an error.
*/
export declare function clearIndexedDbPersistence(firestore: Firestore): Promise<void>;
/**
* Waits until all currently pending writes for the active user have been
* acknowledged by the backend.
*
* The returned promise resolves immediately if there are no outstanding writes.
* Otherwise, the promise waits for all previously issued writes (including
* those written in a previous app session), but it does not wait for writes
* that were added after the function is called. If you want to wait for
* additional writes, call `waitForPendingWrites()` again.
*
* Any outstanding `waitForPendingWrites()` promises are rejected during user
* changes.
*
* @returns A `Promise` which resolves when all currently pending writes have been
* acknowledged by the backend.
*/
export declare function waitForPendingWrites(firestore: Firestore): Promise<void>;
/**
* Re-enables use of the network for this {@link Firestore} instance after a prior
* call to {@link disableNetwork}.
*
* @returns A `Promise` that is resolved once the network has been enabled.
*/
export declare function enableNetwork(firestore: Firestore): Promise<void>;
/**
* Disables network usage for this instance. It can be re-enabled via {@link
* enableNetwork}. While the network is disabled, any snapshot listeners,
* `getDoc()` or `getDocs()` calls will return results from cache, and any write
* operations will be queued until the network is restored.
*
* @returns A `Promise` that is resolved once the network has been disabled.
*/
export declare function disableNetwork(firestore: Firestore): Promise<void>;
/**
* Terminates the provided {@link Firestore} instance.
*
* After calling `terminate()` only the `clearIndexedDbPersistence()` function
* may be used. Any other function will throw a `FirestoreError`.
*
* To restart after termination, create a new instance of FirebaseFirestore with
* {@link (getFirestore:1)}.
*
* Termination does not cancel any pending writes, and any promises that are
* awaiting a response from the server will not be resolved. If you have
* persistence enabled, the next time you start this instance, it will resume
* sending these writes to the server.
*
* Note: Under normal circumstances, calling `terminate()` is not required. This
* function is useful only when you want to force this instance to release all
* of its resources or in combination with `clearIndexedDbPersistence()` to
* ensure that all local state is destroyed between test runs.
*
* @returns A `Promise` that is resolved when the instance has been successfully
* terminated.
*/
export declare function terminate(firestore: Firestore): Promise<void>;
/**
* Loads a Firestore bundle into the local cache.
*
* @param firestore - The {@link Firestore} instance to load bundles for.
* @param bundleData - An object representing the bundle to be loaded. Valid
* objects are `ArrayBuffer`, `ReadableStream<Uint8Array>` or `string`.
*
* @returns A `LoadBundleTask` object, which notifies callers with progress
* updates, and completion or error events. It can be used as a
* `Promise<LoadBundleTaskProgress>`.
*/
export declare function loadBundle(firestore: Firestore, bundleData: ReadableStream<Uint8Array> | ArrayBuffer | string): LoadBundleTask;
/**
* Reads a Firestore {@link Query} from local cache, identified by the given
* name.
*
* The named queries are packaged into bundles on the server side (along
* with resulting documents), and loaded to local cache using `loadBundle`. Once
* in local cache, use this method to extract a {@link Query} by name.
*
* @param firestore - The {@link Firestore} instance to read the query from.
* @param name - The name of the query.
* @returns A `Promise` that is resolved with the Query or `null`.
*/
export declare function namedQuery(firestore: Firestore, name: string): Promise<Query | null>;

View file

@ -0,0 +1,17 @@
/**
* @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.
*/
export { FieldPath, documentId } from '../lite-api/field_path';

View file

@ -0,0 +1,17 @@
/**
* @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.
*/
export { FieldValue } from '../lite-api/field_value';

View file

@ -0,0 +1,17 @@
/**
* @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.
*/
export { increment, arrayRemove, arrayUnion, serverTimestamp, deleteField, vector } from '../lite-api/field_value_impl';

View file

@ -0,0 +1,17 @@
/**
* @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.
*/
export { and, endAt, endBefore, startAfter, startAt, limitToLast, limit, or, orderBy, OrderByDirection, where, WhereFilterOp, query, QueryCompositeFilterConstraint, QueryConstraint, QueryConstraintType, QueryFilterConstraint, QueryFieldFilterConstraint, QueryOrderByConstraint, QueryLimitConstraint, QueryStartAtConstraint, QueryEndAtConstraint, QueryNonFilterConstraint } from '../lite-api/query';

View file

@ -0,0 +1,17 @@
/**
* @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.
*/
export { GeoPoint } from '../lite-api/geo_point';

View file

@ -0,0 +1,139 @@
/**
* @license
* Copyright 2021 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 { FieldIndex } from '../model/field_index';
import { Firestore } from './database';
export { connectFirestoreEmulator, EmulatorMockTokenOptions } from '../lite-api/database';
/**
* A single field element in an index configuration.
*
* @deprecated Instead of creating cache indexes manually, consider using
* `enablePersistentCacheIndexAutoCreation()` to let the SDK decide whether to
* create cache indexes for queries running locally.
*
* @beta
*/
export interface IndexField {
/** The field path to index. */
readonly fieldPath: string;
/**
* What type of array index to create. Set to `CONTAINS` for `array-contains`
* and `array-contains-any` indexes.
*
* Only one of `arrayConfig` or `order` should be set;
*/
readonly arrayConfig?: 'CONTAINS';
/**
* What type of array index to create. Set to `ASCENDING` or 'DESCENDING` for
* `==`, `!=`, `<=`, `<=`, `in` and `not-in` filters.
*
* Only one of `arrayConfig` or `order` should be set.
*/
readonly order?: 'ASCENDING' | 'DESCENDING';
[key: string]: unknown;
}
/**
* The SDK definition of a Firestore index.
*
* @deprecated Instead of creating cache indexes manually, consider using
* `enablePersistentCacheIndexAutoCreation()` to let the SDK decide whether to
* create cache indexes for queries running locally.
*
* @beta
*/
export interface Index {
/** The ID of the collection to index. */
readonly collectionGroup: string;
/** A list of fields to index. */
readonly fields?: IndexField[];
[key: string]: unknown;
}
/**
* A list of Firestore indexes to speed up local query execution.
*
* See {@link https://firebase.google.com/docs/reference/firestore/indexes/#json_format | JSON Format}
* for a description of the format of the index definition.
*
* @deprecated Instead of creating cache indexes manually, consider using
* `enablePersistentCacheIndexAutoCreation()` to let the SDK decide whether to
* create cache indexes for queries running locally.
*
* @beta
*/
export interface IndexConfiguration {
/** A list of all Firestore indexes. */
readonly indexes?: Index[];
[key: string]: unknown;
}
/**
* Configures indexing for local query execution. Any previous index
* configuration is overridden. The `Promise` resolves once the index
* configuration has been persisted.
*
* The index entries themselves are created asynchronously. You can continue to
* use queries that require indexing even if the indices are not yet available.
* Query execution will automatically start using the index once the index
* entries have been written.
*
* Indexes are only supported with IndexedDb persistence. If IndexedDb is not
* enabled, any index configuration is ignored.
*
* @param firestore - The {@link Firestore} instance to configure indexes for.
* @param configuration -The index definition.
* @throws FirestoreError if the JSON format is invalid.
* @returns A `Promise` that resolves once all indices are successfully
* configured.
*
* @deprecated Instead of creating cache indexes manually, consider using
* `enablePersistentCacheIndexAutoCreation()` to let the SDK decide whether to
* create cache indexes for queries running locally.
*
* @beta
*/
export declare function setIndexConfiguration(firestore: Firestore, configuration: IndexConfiguration): Promise<void>;
/**
* Configures indexing for local query execution. Any previous index
* configuration is overridden. The `Promise` resolves once the index
* configuration has been persisted.
*
* The index entries themselves are created asynchronously. You can continue to
* use queries that require indexing even if the indices are not yet available.
* Query execution will automatically start using the index once the index
* entries have been written.
*
* Indexes are only supported with IndexedDb persistence. Invoke either
* `enableIndexedDbPersistence()` or `enableMultiTabIndexedDbPersistence()`
* before setting an index configuration. If IndexedDb is not enabled, any
* index configuration is ignored.
*
* The method accepts the JSON format exported by the Firebase CLI (`firebase
* firestore:indexes`). If the JSON format is invalid, this method throws an
* error.
*
* @param firestore - The {@link Firestore} instance to configure indexes for.
* @param json -The JSON format exported by the Firebase CLI.
* @throws FirestoreError if the JSON format is invalid.
* @returns A `Promise` that resolves once all indices are successfully
* configured.
*
* @deprecated Instead of creating cache indexes manually, consider using
* `enablePersistentCacheIndexAutoCreation()` to let the SDK decide whether to
* create cache indexes for queries running locally.
*
* @beta
*/
export declare function setIndexConfiguration(firestore: Firestore, json: string): Promise<void>;
export declare function parseIndexes(jsonOrConfiguration: string | IndexConfiguration): FieldIndex[];

View file

@ -0,0 +1,55 @@
/**
* @license
* Copyright 2023 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.
*/
/**
* Options that configure the SDKs underlying network transport (WebChannel)
* when long-polling is used.
*
* Note: This interface is "experimental" and is subject to change.
*
* See `FirestoreSettings.experimentalAutoDetectLongPolling`,
* `FirestoreSettings.experimentalForceLongPolling`, and
* `FirestoreSettings.experimentalLongPollingOptions`.
*/
export interface ExperimentalLongPollingOptions {
/**
* The desired maximum timeout interval, in seconds, to complete a
* long-polling GET response. Valid values are between 5 and 30, inclusive.
* Floating point values are allowed and will be rounded to the nearest
* millisecond.
*
* By default, when long-polling is used the "hanging GET" request sent by
* the client times out after 30 seconds. To request a different timeout
* from the server, set this setting with the desired timeout.
*
* Changing the default timeout may be useful, for example, if the buffering
* proxy that necessitated enabling long-polling in the first place has a
* shorter timeout for hanging GET requests, in which case setting the
* long-polling timeout to a shorter value, such as 25 seconds, may fix
* prematurely-closed hanging GET requests.
* For example, see https://github.com/firebase/firebase-js-sdk/issues/6987.
*/
timeoutSeconds?: number;
}
/**
* Compares two `ExperimentalLongPollingOptions` objects for equality.
*/
export declare function longPollingOptionsEqual(options1: ExperimentalLongPollingOptions, options2: ExperimentalLongPollingOptions): boolean;
/**
* Creates and returns a new `ExperimentalLongPollingOptions` with the same
* option values as the given instance.
*/
export declare function cloneLongPollingOptions(options: ExperimentalLongPollingOptions): ExperimentalLongPollingOptions;

View file

@ -0,0 +1,29 @@
/**
* @license
* Copyright 2017 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 { FirestoreError } from '../util/error';
/**
* Observer/Subscribe interfaces.
*/
export declare type NextFn<T> = (value: T) => void;
export declare type ErrorFn = (error: FirestoreError) => void;
export declare type CompleteFn = () => void;
export interface PartialObserver<T> {
next?: NextFn<T>;
error?: ErrorFn;
complete?: CompleteFn;
}
export declare function isPartialObserver<T>(obj: unknown): obj is PartialObserver<T>;

View file

@ -0,0 +1,21 @@
/**
* @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 { DatabaseId } from '../core/database_info';
export interface ParseContext {
readonly databaseId: DatabaseId;
readonly ignoreUndefinedProperties: boolean;
}

View file

@ -0,0 +1,59 @@
/**
* @license
* Copyright 2023 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 './database';
/**
* A `PersistentCacheIndexManager` for configuring persistent cache indexes used
* for local query execution.
*
* To use, call `getPersistentCacheIndexManager()` to get an instance.
*/
export declare class PersistentCacheIndexManager {
readonly _firestore: Firestore;
/** A type string to uniquely identify instances of this class. */
readonly type: 'PersistentCacheIndexManager';
/** @hideconstructor */
constructor(_firestore: Firestore);
}
/**
* Returns the PersistentCache Index Manager used by the given `Firestore`
* object.
*
* @return The `PersistentCacheIndexManager` instance, or `null` if local
* persistent storage is not in use.
*/
export declare function getPersistentCacheIndexManager(firestore: Firestore): PersistentCacheIndexManager | null;
/**
* Enables the SDK to create persistent cache indexes automatically for local
* query execution when the SDK believes cache indexes can help improve
* performance.
*
* This feature is disabled by default.
*/
export declare function enablePersistentCacheIndexAutoCreation(indexManager: PersistentCacheIndexManager): void;
/**
* Stops creating persistent cache indexes automatically for local query
* execution. The indexes which have been created by calling
* `enablePersistentCacheIndexAutoCreation()` still take effect.
*/
export declare function disablePersistentCacheIndexAutoCreation(indexManager: PersistentCacheIndexManager): void;
/**
* Removes all persistent cache indexes.
*
* Please note this function will also deletes indexes generated by
* `setIndexConfiguration()`, which is deprecated.
*/
export declare function deleteAllPersistentCacheIndexes(indexManager: PersistentCacheIndexManager): void;

View file

@ -0,0 +1,17 @@
/**
* @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.
*/
export { DocumentReference, CollectionReference, Query, collection, collectionGroup, doc, queryEqual, SetOptions, DocumentData, UpdateData, WithFieldValue, PartialWithFieldValue, refEqual } from '../lite-api/reference';

View file

@ -0,0 +1,385 @@
/**
* @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 { Bytes } from '../lite-api/bytes';
import { FieldPath } from '../lite-api/field_path';
import { CollectionReference, DocumentData, DocumentReference, PartialWithFieldValue, Query, SetOptions, UpdateData, WithFieldValue } from '../lite-api/reference';
import { AbstractUserDataWriter } from '../lite-api/user_data_writer';
import { Mutation } from '../model/mutation';
import { ByteString } from '../util/byte_string';
import { FirestoreError } from '../util/error';
import { Firestore } from './database';
import { DocumentSnapshot, QuerySnapshot } from './snapshot';
/**
* An options object that can be passed to {@link (onSnapshot:1)} and {@link
* QuerySnapshot.docChanges} to control which types of changes to include in the
* result set.
*/
export interface SnapshotListenOptions {
/**
* Include a change even if only the metadata of the query or of a document
* changed. Default is false.
*/
readonly includeMetadataChanges?: boolean;
/**
* Set the source the query listens to. Default to "default", which
* listens to both cache and server.
*/
readonly source?: ListenSource;
}
/**
* Describe the source a query listens to.
*
* Set to `default` to listen to both cache and server changes. Set to `cache`
* to listen to changes in cache only.
*/
export declare type ListenSource = 'default' | 'cache';
/**
* Reads the document referred to by this `DocumentReference`.
*
* Note: `getDoc()` attempts to provide up-to-date data when possible by waiting
* for data from the server, but it may return cached data or fail if you are
* offline and the server cannot be reached. To specify this behavior, invoke
* {@link getDocFromCache} or {@link getDocFromServer}.
*
* @param reference - The reference of the document to fetch.
* @returns A Promise resolved with a `DocumentSnapshot` containing the
* current document contents.
*/
export declare function getDoc<AppModelType, DbModelType extends DocumentData>(reference: DocumentReference<AppModelType, DbModelType>): Promise<DocumentSnapshot<AppModelType, DbModelType>>;
export declare class ExpUserDataWriter extends AbstractUserDataWriter {
protected firestore: Firestore;
constructor(firestore: Firestore);
protected convertBytes(bytes: ByteString): Bytes;
protected convertReference(name: string): DocumentReference;
}
/**
* Reads the document referred to by this `DocumentReference` from cache.
* Returns an error if the document is not currently cached.
*
* @returns A `Promise` resolved with a `DocumentSnapshot` containing the
* current document contents.
*/
export declare function getDocFromCache<AppModelType, DbModelType extends DocumentData>(reference: DocumentReference<AppModelType, DbModelType>): Promise<DocumentSnapshot<AppModelType, DbModelType>>;
/**
* Reads the document referred to by this `DocumentReference` from the server.
* Returns an error if the network is not available.
*
* @returns A `Promise` resolved with a `DocumentSnapshot` containing the
* current document contents.
*/
export declare function getDocFromServer<AppModelType, DbModelType extends DocumentData>(reference: DocumentReference<AppModelType, DbModelType>): Promise<DocumentSnapshot<AppModelType, DbModelType>>;
/**
* Executes the query and returns the results as a `QuerySnapshot`.
*
* Note: `getDocs()` attempts to provide up-to-date data when possible by
* waiting for data from the server, but it may return cached data or fail if
* you are offline and the server cannot be reached. To specify this behavior,
* invoke {@link getDocsFromCache} or {@link getDocsFromServer}.
*
* @returns A `Promise` that will be resolved with the results of the query.
*/
export declare function getDocs<AppModelType, DbModelType extends DocumentData>(query: Query<AppModelType, DbModelType>): Promise<QuerySnapshot<AppModelType, DbModelType>>;
/**
* Executes the query and returns the results as a `QuerySnapshot` from cache.
* Returns an empty result set if no documents matching the query are currently
* cached.
*
* @returns A `Promise` that will be resolved with the results of the query.
*/
export declare function getDocsFromCache<AppModelType, DbModelType extends DocumentData>(query: Query<AppModelType, DbModelType>): Promise<QuerySnapshot<AppModelType, DbModelType>>;
/**
* Executes the query and returns the results as a `QuerySnapshot` from the
* server. Returns an error if the network is not available.
*
* @returns A `Promise` that will be resolved with the results of the query.
*/
export declare function getDocsFromServer<AppModelType, DbModelType extends DocumentData>(query: Query<AppModelType, DbModelType>): Promise<QuerySnapshot<AppModelType, DbModelType>>;
/**
* Writes to the document referred to by this `DocumentReference`. If the
* document does not yet exist, it will be created.
*
* @param reference - A reference to the document to write.
* @param data - A map of the fields and values for the document.
* @returns A `Promise` resolved once the data has been successfully written
* to the backend (note that it won't resolve while you're offline).
*/
export declare function setDoc<AppModelType, DbModelType extends DocumentData>(reference: DocumentReference<AppModelType, DbModelType>, data: WithFieldValue<AppModelType>): Promise<void>;
/**
* Writes to the document referred to by the specified `DocumentReference`. If
* the document does not yet exist, it will be created. If you provide `merge`
* or `mergeFields`, the provided data can be merged into an existing document.
*
* @param reference - A reference to the document to write.
* @param data - A map of the fields and values for the document.
* @param options - An object to configure the set behavior.
* @returns A Promise resolved once the data has been successfully written
* to the backend (note that it won't resolve while you're offline).
*/
export declare function setDoc<AppModelType, DbModelType extends DocumentData>(reference: DocumentReference<AppModelType, DbModelType>, data: PartialWithFieldValue<AppModelType>, options: SetOptions): Promise<void>;
/**
* Updates fields in the document referred to by the specified
* `DocumentReference`. The update will fail if applied to a document that does
* not exist.
*
* @param reference - A reference to the document to update.
* @param data - An object containing the fields and values with which to
* update the document. Fields can contain dots to reference nested fields
* within the document.
* @returns A `Promise` resolved once the data has been successfully written
* to the backend (note that it won't resolve while you're offline).
*/
export declare function updateDoc<AppModelType, DbModelType extends DocumentData>(reference: DocumentReference<AppModelType, DbModelType>, data: UpdateData<DbModelType>): Promise<void>;
/**
* Updates fields in the document referred to by the specified
* `DocumentReference` The update will fail if applied to a document that does
* not exist.
*
* Nested fields can be updated by providing dot-separated field path
* strings or by providing `FieldPath` objects.
*
* @param reference - A reference to the document to update.
* @param field - The first field to update.
* @param value - The first value.
* @param moreFieldsAndValues - Additional key value pairs.
* @returns A `Promise` resolved once the data has been successfully written
* to the backend (note that it won't resolve while you're offline).
*/
export declare function updateDoc<AppModelType, DbModelType extends DocumentData>(reference: DocumentReference<AppModelType, DbModelType>, field: string | FieldPath, value: unknown, ...moreFieldsAndValues: unknown[]): Promise<void>;
/**
* Deletes the document referred to by the specified `DocumentReference`.
*
* @param reference - A reference to the document to delete.
* @returns A Promise resolved once the document has been successfully
* deleted from the backend (note that it won't resolve while you're offline).
*/
export declare function deleteDoc<AppModelType, DbModelType extends DocumentData>(reference: DocumentReference<AppModelType, DbModelType>): Promise<void>;
/**
* Add a new document to specified `CollectionReference` with the given data,
* assigning it a document ID automatically.
*
* @param reference - A reference to the collection to add this document to.
* @param data - An Object containing the data for the new document.
* @returns A `Promise` resolved with a `DocumentReference` pointing to the
* newly created document after it has been written to the backend (Note that it
* won't resolve while you're offline).
*/
export declare function addDoc<AppModelType, DbModelType extends DocumentData>(reference: CollectionReference<AppModelType, DbModelType>, data: WithFieldValue<AppModelType>): Promise<DocumentReference<AppModelType, DbModelType>>;
/**
* A function returned by `onSnapshot()` that removes the listener when invoked.
*/
export interface Unsubscribe {
/** Removes the listener when invoked. */
(): void;
}
/**
* Attaches a listener for `DocumentSnapshot` events. You may either pass
* individual `onNext` and `onError` callbacks or pass a single observer
* object with `next` and `error` callbacks.
*
* NOTE: Although an `onCompletion` callback can be provided, it will
* never be called because the snapshot stream is never-ending.
*
* @param reference - A reference to the document to listen to.
* @param observer - A single object containing `next` and `error` callbacks.
* @returns An unsubscribe function that can be called to cancel
* the snapshot listener.
*/
export declare function onSnapshot<AppModelType, DbModelType extends DocumentData>(reference: DocumentReference<AppModelType, DbModelType>, observer: {
next?: (snapshot: DocumentSnapshot<AppModelType, DbModelType>) => void;
error?: (error: FirestoreError) => void;
complete?: () => void;
}): Unsubscribe;
/**
* Attaches a listener for `DocumentSnapshot` events. You may either pass
* individual `onNext` and `onError` callbacks or pass a single observer
* object with `next` and `error` callbacks.
*
* NOTE: Although an `onCompletion` callback can be provided, it will
* never be called because the snapshot stream is never-ending.
*
* @param reference - A reference to the document to listen to.
* @param options - Options controlling the listen behavior.
* @param observer - A single object containing `next` and `error` callbacks.
* @returns An unsubscribe function that can be called to cancel
* the snapshot listener.
*/
export declare function onSnapshot<AppModelType, DbModelType extends DocumentData>(reference: DocumentReference<AppModelType, DbModelType>, options: SnapshotListenOptions, observer: {
next?: (snapshot: DocumentSnapshot<AppModelType, DbModelType>) => void;
error?: (error: FirestoreError) => void;
complete?: () => void;
}): Unsubscribe;
/**
* Attaches a listener for `DocumentSnapshot` events. You may either pass
* individual `onNext` and `onError` callbacks or pass a single observer
* object with `next` and `error` callbacks.
*
* NOTE: Although an `onCompletion` callback can be provided, it will
* never be called because the snapshot stream is never-ending.
*
* @param reference - A reference to the document to listen to.
* @param onNext - A callback to be called every time a new `DocumentSnapshot`
* is available.
* @param onError - A callback to be called if the listen fails or is
* cancelled. No further callbacks will occur.
* @param onCompletion - Can be provided, but will not be called since streams are
* never ending.
* @returns An unsubscribe function that can be called to cancel
* the snapshot listener.
*/
export declare function onSnapshot<AppModelType, DbModelType extends DocumentData>(reference: DocumentReference<AppModelType, DbModelType>, onNext: (snapshot: DocumentSnapshot<AppModelType, DbModelType>) => void, onError?: (error: FirestoreError) => void, onCompletion?: () => void): Unsubscribe;
/**
* Attaches a listener for `DocumentSnapshot` events. You may either pass
* individual `onNext` and `onError` callbacks or pass a single observer
* object with `next` and `error` callbacks.
*
* NOTE: Although an `onCompletion` callback can be provided, it will
* never be called because the snapshot stream is never-ending.
*
* @param reference - A reference to the document to listen to.
* @param options - Options controlling the listen behavior.
* @param onNext - A callback to be called every time a new `DocumentSnapshot`
* is available.
* @param onError - A callback to be called if the listen fails or is
* cancelled. No further callbacks will occur.
* @param onCompletion - Can be provided, but will not be called since streams are
* never ending.
* @returns An unsubscribe function that can be called to cancel
* the snapshot listener.
*/
export declare function onSnapshot<AppModelType, DbModelType extends DocumentData>(reference: DocumentReference<AppModelType, DbModelType>, options: SnapshotListenOptions, onNext: (snapshot: DocumentSnapshot<AppModelType, DbModelType>) => void, onError?: (error: FirestoreError) => void, onCompletion?: () => void): Unsubscribe;
/**
* Attaches a listener for `QuerySnapshot` events. You may either pass
* individual `onNext` and `onError` callbacks or pass a single observer
* object with `next` and `error` callbacks. The listener can be cancelled by
* calling the function that is returned when `onSnapshot` is called.
*
* NOTE: Although an `onCompletion` callback can be provided, it will
* never be called because the snapshot stream is never-ending.
*
* @param query - The query to listen to.
* @param observer - A single object containing `next` and `error` callbacks.
* @returns An unsubscribe function that can be called to cancel
* the snapshot listener.
*/
export declare function onSnapshot<AppModelType, DbModelType extends DocumentData>(query: Query<AppModelType, DbModelType>, observer: {
next?: (snapshot: QuerySnapshot<AppModelType, DbModelType>) => void;
error?: (error: FirestoreError) => void;
complete?: () => void;
}): Unsubscribe;
/**
* Attaches a listener for `QuerySnapshot` events. You may either pass
* individual `onNext` and `onError` callbacks or pass a single observer
* object with `next` and `error` callbacks. The listener can be cancelled by
* calling the function that is returned when `onSnapshot` is called.
*
* NOTE: Although an `onCompletion` callback can be provided, it will
* never be called because the snapshot stream is never-ending.
*
* @param query - The query to listen to.
* @param options - Options controlling the listen behavior.
* @param observer - A single object containing `next` and `error` callbacks.
* @returns An unsubscribe function that can be called to cancel
* the snapshot listener.
*/
export declare function onSnapshot<AppModelType, DbModelType extends DocumentData>(query: Query<AppModelType, DbModelType>, options: SnapshotListenOptions, observer: {
next?: (snapshot: QuerySnapshot<AppModelType, DbModelType>) => void;
error?: (error: FirestoreError) => void;
complete?: () => void;
}): Unsubscribe;
/**
* Attaches a listener for `QuerySnapshot` events. You may either pass
* individual `onNext` and `onError` callbacks or pass a single observer
* object with `next` and `error` callbacks. The listener can be cancelled by
* calling the function that is returned when `onSnapshot` is called.
*
* NOTE: Although an `onCompletion` callback can be provided, it will
* never be called because the snapshot stream is never-ending.
*
* @param query - The query to listen to.
* @param onNext - A callback to be called every time a new `QuerySnapshot`
* is available.
* @param onCompletion - Can be provided, but will not be called since streams are
* never ending.
* @param onError - A callback to be called if the listen fails or is
* cancelled. No further callbacks will occur.
* @returns An unsubscribe function that can be called to cancel
* the snapshot listener.
*/
export declare function onSnapshot<AppModelType, DbModelType extends DocumentData>(query: Query<AppModelType, DbModelType>, onNext: (snapshot: QuerySnapshot<AppModelType, DbModelType>) => void, onError?: (error: FirestoreError) => void, onCompletion?: () => void): Unsubscribe;
/**
* Attaches a listener for `QuerySnapshot` events. You may either pass
* individual `onNext` and `onError` callbacks or pass a single observer
* object with `next` and `error` callbacks. The listener can be cancelled by
* calling the function that is returned when `onSnapshot` is called.
*
* NOTE: Although an `onCompletion` callback can be provided, it will
* never be called because the snapshot stream is never-ending.
*
* @param query - The query to listen to.
* @param options - Options controlling the listen behavior.
* @param onNext - A callback to be called every time a new `QuerySnapshot`
* is available.
* @param onCompletion - Can be provided, but will not be called since streams are
* never ending.
* @param onError - A callback to be called if the listen fails or is
* cancelled. No further callbacks will occur.
* @returns An unsubscribe function that can be called to cancel
* the snapshot listener.
*/
export declare function onSnapshot<AppModelType, DbModelType extends DocumentData>(query: Query<AppModelType, DbModelType>, options: SnapshotListenOptions, onNext: (snapshot: QuerySnapshot<AppModelType, DbModelType>) => void, onError?: (error: FirestoreError) => void, onCompletion?: () => void): Unsubscribe;
/**
* Attaches a listener for a snapshots-in-sync event. The snapshots-in-sync
* event indicates that all listeners affected by a given change have fired,
* even if a single server-generated change affects multiple listeners.
*
* NOTE: The snapshots-in-sync event only indicates that listeners are in sync
* with each other, but does not relate to whether those snapshots are in sync
* with the server. Use SnapshotMetadata in the individual listeners to
* determine if a snapshot is from the cache or the server.
*
* @param firestore - The instance of Firestore for synchronizing snapshots.
* @param observer - A single object containing `next` and `error` callbacks.
* @returns An unsubscribe function that can be called to cancel the snapshot
* listener.
*/
export declare function onSnapshotsInSync(firestore: Firestore, observer: {
next?: (value: void) => void;
error?: (error: FirestoreError) => void;
complete?: () => void;
}): Unsubscribe;
/**
* Attaches a listener for a snapshots-in-sync event. The snapshots-in-sync
* event indicates that all listeners affected by a given change have fired,
* even if a single server-generated change affects multiple listeners.
*
* NOTE: The snapshots-in-sync event only indicates that listeners are in sync
* with each other, but does not relate to whether those snapshots are in sync
* with the server. Use `SnapshotMetadata` in the individual listeners to
* determine if a snapshot is from the cache or the server.
*
* @param firestore - The `Firestore` instance for synchronizing snapshots.
* @param onSync - A callback to be called every time all snapshot listeners are
* in sync with each other.
* @returns An unsubscribe function that can be called to cancel the snapshot
* listener.
*/
export declare function onSnapshotsInSync(firestore: Firestore, onSync: () => void): Unsubscribe;
/**
* Locally writes `mutations` on the async queue.
* @internal
*/
export declare function executeWrite(firestore: Firestore, mutations: Mutation[]): Promise<void>;

View file

@ -0,0 +1,108 @@
/**
* @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 { FirestoreSettings as LiteSettings } from '../lite-api/settings';
import { FirestoreLocalCache } from './cache_config';
import { ExperimentalLongPollingOptions } from './long_polling_options';
export { DEFAULT_HOST } from '../lite-api/settings';
/**
* Settings that can be passed to `enableIndexedDbPersistence()` to configure
* Firestore persistence.
*
* Persistence cannot be used in a Node.js environment.
*/
export interface PersistenceSettings {
/**
* Whether to force enable persistence for the client. This cannot be used
* with multi-tab synchronization and is primarily intended for use with Web
* Workers. Setting this to `true` will enable persistence, but cause other
* tabs using persistence to fail.
*/
forceOwnership?: boolean;
}
/**
* Specifies custom configurations for your Cloud Firestore instance.
* You must set these before invoking any other methods.
*/
export interface FirestoreSettings extends LiteSettings {
/**
* NOTE: This field will be deprecated in a future major release. Use `cache` field
* instead to specify cache size, and other cache configurations.
*
* An approximate cache size threshold for the on-disk data. If the cache
* grows beyond this size, Firestore will start removing data that hasn't been
* recently used. The size is not a guarantee that the cache will stay below
* that size, only that if the cache exceeds the given size, cleanup will be
* attempted.
*
* The default value is 40 MB. The threshold must be set to at least 1 MB, and
* can be set to `CACHE_SIZE_UNLIMITED` to disable garbage collection.
*/
cacheSizeBytes?: number;
/**
* Specifies the cache used by the SDK. Available options are `MemoryLocalCache`
* and `PersistentLocalCache`, each with different configuration options.
*
* When unspecified, `MemoryLocalCache` will be used by default.
*
* NOTE: setting this field and `cacheSizeBytes` at the same time will throw
* exception during SDK initialization. Instead, using the configuration in
* the `FirestoreLocalCache` object to specify the cache size.
*/
localCache?: FirestoreLocalCache;
/**
* Forces the SDKs underlying network transport (WebChannel) to use
* long-polling. Each response from the backend will be closed immediately
* after the backend sends data (by default responses are kept open in
* case the backend has more data to send). This avoids incompatibility
* issues with certain proxies, antivirus software, etc. that incorrectly
* buffer traffic indefinitely. Use of this option will cause some
* performance degradation though.
*
* This setting cannot be used with `experimentalAutoDetectLongPolling` and
* may be removed in a future release. If you find yourself using it to
* work around a specific network reliability issue, please tell us about
* it in https://github.com/firebase/firebase-js-sdk/issues/1674.
*
* This setting cannot be used in a Node.js environment.
*/
experimentalForceLongPolling?: boolean;
/**
* Configures the SDK's underlying transport (WebChannel) to automatically
* detect if long-polling should be used. This is very similar to
* `experimentalForceLongPolling`, but only uses long-polling if required.
*
* After having had a default value of `false` since its inception in 2019,
* the default value of this setting was changed in May 2023 to `true` in
* v9.22.0 of the Firebase JavaScript SDK. That is, auto-detection of long
* polling is now enabled by default. To disable it, set this setting to
* `false`, and please open a GitHub issue to share the problems that
* motivated you disabling long-polling auto-detection.
*
* This setting cannot be used in a Node.js environment.
*/
experimentalAutoDetectLongPolling?: boolean;
/**
* Options that configure the SDKs underlying network transport (WebChannel)
* when long-polling is used.
*
* These options are only used if `experimentalForceLongPolling` is true or if
* `experimentalAutoDetectLongPolling` is true and the auto-detection
* determined that long-polling was needed. Otherwise, these options have no
* effect.
*/
experimentalLongPollingOptions?: ExperimentalLongPollingOptions;
}

View file

@ -0,0 +1,479 @@
/**
* @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 { ChangeType, ViewSnapshot } from '../core/view_snapshot';
import { FieldPath } from '../lite-api/field_path';
import { DocumentData, PartialWithFieldValue, Query, SetOptions, WithFieldValue } from '../lite-api/reference';
import { DocumentSnapshot as LiteDocumentSnapshot, FirestoreDataConverter as LiteFirestoreDataConverter } from '../lite-api/snapshot';
import { UntypedFirestoreDataConverter } from '../lite-api/user_data_reader';
import { AbstractUserDataWriter } from '../lite-api/user_data_writer';
import { Document } from '../model/document';
import { DocumentKey } from '../model/document_key';
import { Firestore } from './database';
import { SnapshotListenOptions } from './reference_impl';
/**
* Converter used by `withConverter()` to transform user objects of type
* `AppModelType` into Firestore data of type `DbModelType`.
*
* Using the converter allows you to specify generic type arguments when
* storing and retrieving objects from Firestore.
*
* In this context, an "AppModel" is a class that is used in an application to
* package together related information and functionality. Such a class could,
* for example, have properties with complex, nested data types, properties used
* for memoization, properties of types not supported by Firestore (such as
* `symbol` and `bigint`), and helper functions that perform compound
* operations. Such classes are not suitable and/or possible to store into a
* Firestore database. Instead, instances of such classes need to be converted
* to "plain old JavaScript objects" (POJOs) with exclusively primitive
* properties, potentially nested inside other POJOs or arrays of POJOs. In this
* context, this type is referred to as the "DbModel" and would be an object
* suitable for persisting into Firestore. For convenience, applications can
* implement `FirestoreDataConverter` and register the converter with Firestore
* objects, such as `DocumentReference` or `Query`, to automatically convert
* `AppModel` to `DbModel` when storing into Firestore, and convert `DbModel`
* to `AppModel` when retrieving from Firestore.
*
* @example
*
* Simple Example
*
* ```typescript
* const numberConverter = {
* toFirestore(value: WithFieldValue<number>) {
* return { value };
* },
* fromFirestore(snapshot: QueryDocumentSnapshot, options: SnapshotOptions) {
* return snapshot.data(options).value as number;
* }
* };
*
* async function simpleDemo(db: Firestore): Promise<void> {
* const documentRef = doc(db, 'values/value123').withConverter(numberConverter);
*
* // converters are used with `setDoc`, `addDoc`, and `getDoc`
* await setDoc(documentRef, 42);
* const snapshot1 = await getDoc(documentRef);
* assertEqual(snapshot1.data(), 42);
*
* // converters are not used when writing data with `updateDoc`
* await updateDoc(documentRef, { value: 999 });
* const snapshot2 = await getDoc(documentRef);
* assertEqual(snapshot2.data(), 999);
* }
* ```
*
* Advanced Example
*
* ```typescript
* // The Post class is a model that is used by our application.
* // This class may have properties and methods that are specific
* // to our application execution, which do not need to be persisted
* // to Firestore.
* class Post {
* constructor(
* readonly title: string,
* readonly author: string,
* readonly lastUpdatedMillis: number
* ) {}
* toString(): string {
* return `${this.title} by ${this.author}`;
* }
* }
*
* // The PostDbModel represents how we want our posts to be stored
* // in Firestore. This DbModel has different properties (`ttl`,
* // `aut`, and `lut`) from the Post class we use in our application.
* interface PostDbModel {
* ttl: string;
* aut: { firstName: string; lastName: string };
* lut: Timestamp;
* }
*
* // The `PostConverter` implements `FirestoreDataConverter` and specifies
* // how the Firestore SDK can convert `Post` objects to `PostDbModel`
* // objects and vice versa.
* class PostConverter implements FirestoreDataConverter<Post, PostDbModel> {
* toFirestore(post: WithFieldValue<Post>): WithFieldValue<PostDbModel> {
* return {
* ttl: post.title,
* aut: this._autFromAuthor(post.author),
* lut: this._lutFromLastUpdatedMillis(post.lastUpdatedMillis)
* };
* }
*
* fromFirestore(snapshot: QueryDocumentSnapshot, options: SnapshotOptions): Post {
* const data = snapshot.data(options) as PostDbModel;
* const author = `${data.aut.firstName} ${data.aut.lastName}`;
* return new Post(data.ttl, author, data.lut.toMillis());
* }
*
* _autFromAuthor(
* author: string | FieldValue
* ): { firstName: string; lastName: string } | FieldValue {
* if (typeof author !== 'string') {
* // `author` is a FieldValue, so just return it.
* return author;
* }
* const [firstName, lastName] = author.split(' ');
* return {firstName, lastName};
* }
*
* _lutFromLastUpdatedMillis(
* lastUpdatedMillis: number | FieldValue
* ): Timestamp | FieldValue {
* if (typeof lastUpdatedMillis !== 'number') {
* // `lastUpdatedMillis` must be a FieldValue, so just return it.
* return lastUpdatedMillis;
* }
* return Timestamp.fromMillis(lastUpdatedMillis);
* }
* }
*
* async function advancedDemo(db: Firestore): Promise<void> {
* // Create a `DocumentReference` with a `FirestoreDataConverter`.
* const documentRef = doc(db, 'posts/post123').withConverter(new PostConverter());
*
* // The `data` argument specified to `setDoc()` is type checked by the
* // TypeScript compiler to be compatible with `Post`. Since the `data`
* // argument is typed as `WithFieldValue<Post>` rather than just `Post`,
* // this allows properties of the `data` argument to also be special
* // Firestore values that perform server-side mutations, such as
* // `arrayRemove()`, `deleteField()`, and `serverTimestamp()`.
* await setDoc(documentRef, {
* title: 'My Life',
* author: 'Foo Bar',
* lastUpdatedMillis: serverTimestamp()
* });
*
* // The TypeScript compiler will fail to compile if the `data` argument to
* // `setDoc()` is _not_ compatible with `WithFieldValue<Post>`. This
* // type checking prevents the caller from specifying objects with incorrect
* // properties or property values.
* // @ts-expect-error "Argument of type { ttl: string; } is not assignable
* // to parameter of type WithFieldValue<Post>"
* await setDoc(documentRef, { ttl: 'The Title' });
*
* // When retrieving a document with `getDoc()` the `DocumentSnapshot`
* // object's `data()` method returns a `Post`, rather than a generic object,
* // which would have been returned if the `DocumentReference` did _not_ have a
* // `FirestoreDataConverter` attached to it.
* const snapshot1: DocumentSnapshot<Post> = await getDoc(documentRef);
* const post1: Post = snapshot1.data()!;
* if (post1) {
* assertEqual(post1.title, 'My Life');
* assertEqual(post1.author, 'Foo Bar');
* }
*
* // The `data` argument specified to `updateDoc()` is type checked by the
* // TypeScript compiler to be compatible with `PostDbModel`. Note that
* // unlike `setDoc()`, whose `data` argument must be compatible with `Post`,
* // the `data` argument to `updateDoc()` must be compatible with
* // `PostDbModel`. Similar to `setDoc()`, since the `data` argument is typed
* // as `WithFieldValue<PostDbModel>` rather than just `PostDbModel`, this
* // allows properties of the `data` argument to also be those special
* // Firestore values, like `arrayRemove()`, `deleteField()`, and
* // `serverTimestamp()`.
* await updateDoc(documentRef, {
* 'aut.firstName': 'NewFirstName',
* lut: serverTimestamp()
* });
*
* // The TypeScript compiler will fail to compile if the `data` argument to
* // `updateDoc()` is _not_ compatible with `WithFieldValue<PostDbModel>`.
* // This type checking prevents the caller from specifying objects with
* // incorrect properties or property values.
* // @ts-expect-error "Argument of type { title: string; } is not assignable
* // to parameter of type WithFieldValue<PostDbModel>"
* await updateDoc(documentRef, { title: 'New Title' });
* const snapshot2: DocumentSnapshot<Post> = await getDoc(documentRef);
* const post2: Post = snapshot2.data()!;
* if (post2) {
* assertEqual(post2.title, 'My Life');
* assertEqual(post2.author, 'NewFirstName Bar');
* }
* }
* ```
*/
export interface FirestoreDataConverter<AppModelType, DbModelType extends DocumentData = DocumentData> extends LiteFirestoreDataConverter<AppModelType, DbModelType> {
/**
* Called by the Firestore SDK to convert a custom model object of type
* `AppModelType` into a plain JavaScript object (suitable for writing
* directly to the Firestore database) of type `DbModelType`. To use `set()`
* with `merge` and `mergeFields`, `toFirestore()` must be defined with
* `PartialWithFieldValue<AppModelType>`.
*
* The `WithFieldValue<T>` type extends `T` to also allow FieldValues such as
* {@link (deleteField:1)} to be used as property values.
*/
toFirestore(modelObject: WithFieldValue<AppModelType>): WithFieldValue<DbModelType>;
/**
* Called by the Firestore SDK to convert a custom model object of type
* `AppModelType` into a plain JavaScript object (suitable for writing
* directly to the Firestore database) of type `DbModelType`. Used with
* {@link (setDoc:1)}, {@link (WriteBatch.set:1)} and
* {@link (Transaction.set:1)} with `merge:true` or `mergeFields`.
*
* The `PartialWithFieldValue<T>` type extends `Partial<T>` to allow
* FieldValues such as {@link (arrayUnion:1)} to be used as property values.
* It also supports nested `Partial` by allowing nested fields to be
* omitted.
*/
toFirestore(modelObject: PartialWithFieldValue<AppModelType>, options: SetOptions): PartialWithFieldValue<DbModelType>;
/**
* Called by the Firestore SDK to convert Firestore data into an object of
* type `AppModelType`. You can access your data by calling:
* `snapshot.data(options)`.
*
* Generally, the data returned from `snapshot.data()` can be cast to
* `DbModelType`; however, this is not guaranteed because Firestore does not
* enforce a schema on the database. For example, writes from a previous
* version of the application or writes from another client that did not use a
* type converter could have written data with different properties and/or
* property types. The implementation will need to choose whether to
* gracefully recover from non-conforming data or throw an error.
*
* To override this method, see {@link (FirestoreDataConverter.fromFirestore:1)}.
*
* @param snapshot - A `QueryDocumentSnapshot` containing your data and metadata.
* @param options - The `SnapshotOptions` from the initial call to `data()`.
*/
fromFirestore(snapshot: QueryDocumentSnapshot<DocumentData, DocumentData>, options?: SnapshotOptions): AppModelType;
}
/**
* Options that configure how data is retrieved from a `DocumentSnapshot` (for
* example the desired behavior for server timestamps that have not yet been set
* to their final value).
*/
export interface SnapshotOptions {
/**
* If set, controls the return value for server timestamps that have not yet
* been set to their final value.
*
* By specifying 'estimate', pending server timestamps return an estimate
* based on the local clock. This estimate will differ from the final value
* and cause these values to change once the server result becomes available.
*
* By specifying 'previous', pending timestamps will be ignored and return
* their previous value instead.
*
* If omitted or set to 'none', `null` will be returned by default until the
* server value becomes available.
*/
readonly serverTimestamps?: 'estimate' | 'previous' | 'none';
}
/**
* Metadata about a snapshot, describing the state of the snapshot.
*/
export declare class SnapshotMetadata {
/**
* True if the snapshot contains the result of local writes (for example
* `set()` or `update()` calls) that have not yet been committed to the
* backend. If your listener has opted into metadata updates (via
* `SnapshotListenOptions`) you will receive another snapshot with
* `hasPendingWrites` equal to false once the writes have been committed to
* the backend.
*/
readonly hasPendingWrites: boolean;
/**
* True if the snapshot was created from cached data rather than guaranteed
* up-to-date server data. If your listener has opted into metadata updates
* (via `SnapshotListenOptions`) you will receive another snapshot with
* `fromCache` set to false once the client has received up-to-date data from
* the backend.
*/
readonly fromCache: boolean;
/** @hideconstructor */
constructor(hasPendingWrites: boolean, fromCache: boolean);
/**
* Returns true if this `SnapshotMetadata` is equal to the provided one.
*
* @param other - The `SnapshotMetadata` to compare against.
* @returns true if this `SnapshotMetadata` is equal to the provided one.
*/
isEqual(other: SnapshotMetadata): boolean;
}
/**
* The type of a `DocumentChange` may be 'added', 'removed', or 'modified'.
*/
export declare type DocumentChangeType = 'added' | 'removed' | 'modified';
/**
* A `DocumentChange` represents a change to the documents matching a query.
* It contains the document affected and the type of change that occurred.
*/
export interface DocumentChange<AppModelType = DocumentData, DbModelType extends DocumentData = DocumentData> {
/** The type of change ('added', 'modified', or 'removed'). */
readonly type: DocumentChangeType;
/** The document affected by this change. */
readonly doc: QueryDocumentSnapshot<AppModelType, DbModelType>;
/**
* The index of the changed document in the result set immediately prior to
* this `DocumentChange` (i.e. supposing that all prior `DocumentChange` objects
* have been applied). Is `-1` for 'added' events.
*/
readonly oldIndex: number;
/**
* The index of the changed document in the result set immediately after
* this `DocumentChange` (i.e. supposing that all prior `DocumentChange`
* objects and the current `DocumentChange` object have been applied).
* Is -1 for 'removed' events.
*/
readonly newIndex: number;
}
/**
* A `DocumentSnapshot` contains data read from a document in your Firestore
* database. The data can be extracted with `.data()` or `.get(<field>)` to
* get a specific field.
*
* For a `DocumentSnapshot` that points to a non-existing document, any data
* access will return 'undefined'. You can use the `exists()` method to
* explicitly verify a document's existence.
*/
export declare class DocumentSnapshot<AppModelType = DocumentData, DbModelType extends DocumentData = DocumentData> extends LiteDocumentSnapshot<AppModelType, DbModelType> {
readonly _firestore: Firestore;
private readonly _firestoreImpl;
/**
* Metadata about the `DocumentSnapshot`, including information about its
* source and local modifications.
*/
readonly metadata: SnapshotMetadata;
/** @hideconstructor protected */
constructor(_firestore: Firestore, userDataWriter: AbstractUserDataWriter, key: DocumentKey, document: Document | null, metadata: SnapshotMetadata, converter: UntypedFirestoreDataConverter<AppModelType, DbModelType> | null);
/**
* Returns whether or not the data exists. True if the document exists.
*/
exists(): this is QueryDocumentSnapshot<AppModelType, DbModelType>;
/**
* Retrieves all fields in the document as an `Object`. Returns `undefined` if
* the document doesn't exist.
*
* By default, `serverTimestamp()` values that have not yet been
* set to their final value will be returned as `null`. You can override
* this by passing an options object.
*
* @param options - An options object to configure how data is retrieved from
* the snapshot (for example the desired behavior for server timestamps that
* have not yet been set to their final value).
* @returns An `Object` containing all fields in the document or `undefined` if
* the document doesn't exist.
*/
data(options?: SnapshotOptions): AppModelType | undefined;
/**
* Retrieves the field specified by `fieldPath`. Returns `undefined` if the
* document or field doesn't exist.
*
* By default, a `serverTimestamp()` that has not yet been set to
* its final value will be returned as `null`. You can override this by
* passing an options object.
*
* @param fieldPath - The path (for example 'foo' or 'foo.bar') to a specific
* field.
* @param options - An options object to configure how the field is retrieved
* from the snapshot (for example the desired behavior for server timestamps
* that have not yet been set to their final value).
* @returns The data at the specified field location or undefined if no such
* field exists in the document.
*/
get(fieldPath: string | FieldPath, options?: SnapshotOptions): any;
}
/**
* A `QueryDocumentSnapshot` contains data read from a document in your
* Firestore database as part of a query. The document is guaranteed to exist
* and its data can be extracted with `.data()` or `.get(<field>)` to get a
* specific field.
*
* A `QueryDocumentSnapshot` offers the same API surface as a
* `DocumentSnapshot`. Since query results contain only existing documents, the
* `exists` property will always be true and `data()` will never return
* 'undefined'.
*/
export declare class QueryDocumentSnapshot<AppModelType = DocumentData, DbModelType extends DocumentData = DocumentData> extends DocumentSnapshot<AppModelType, DbModelType> {
/**
* Retrieves all fields in the document as an `Object`.
*
* By default, `serverTimestamp()` values that have not yet been
* set to their final value will be returned as `null`. You can override
* this by passing an options object.
*
* @override
* @param options - An options object to configure how data is retrieved from
* the snapshot (for example the desired behavior for server timestamps that
* have not yet been set to their final value).
* @returns An `Object` containing all fields in the document.
*/
data(options?: SnapshotOptions): AppModelType;
}
/**
* A `QuerySnapshot` contains zero or more `DocumentSnapshot` objects
* representing the results of a query. The documents can be accessed as an
* array via the `docs` property or enumerated using the `forEach` method. The
* number of documents can be determined via the `empty` and `size`
* properties.
*/
export declare class QuerySnapshot<AppModelType = DocumentData, DbModelType extends DocumentData = DocumentData> {
readonly _firestore: Firestore;
readonly _userDataWriter: AbstractUserDataWriter;
readonly _snapshot: ViewSnapshot;
/**
* Metadata about this snapshot, concerning its source and if it has local
* modifications.
*/
readonly metadata: SnapshotMetadata;
/**
* The query on which you called `get` or `onSnapshot` in order to get this
* `QuerySnapshot`.
*/
readonly query: Query<AppModelType, DbModelType>;
private _cachedChanges?;
private _cachedChangesIncludeMetadataChanges?;
/** @hideconstructor */
constructor(_firestore: Firestore, _userDataWriter: AbstractUserDataWriter, query: Query<AppModelType, DbModelType>, _snapshot: ViewSnapshot);
/** An array of all the documents in the `QuerySnapshot`. */
get docs(): Array<QueryDocumentSnapshot<AppModelType, DbModelType>>;
/** The number of documents in the `QuerySnapshot`. */
get size(): number;
/** True if there are no documents in the `QuerySnapshot`. */
get empty(): boolean;
/**
* Enumerates all of the documents in the `QuerySnapshot`.
*
* @param callback - A callback to be called with a `QueryDocumentSnapshot` for
* each document in the snapshot.
* @param thisArg - The `this` binding for the callback.
*/
forEach(callback: (result: QueryDocumentSnapshot<AppModelType, DbModelType>) => void, thisArg?: unknown): void;
/**
* Returns an array of the documents changes since the last snapshot. If this
* is the first snapshot, all documents will be in the list as 'added'
* changes.
*
* @param options - `SnapshotListenOptions` that control whether metadata-only
* changes (i.e. only `DocumentSnapshot.metadata` changed) should trigger
* snapshot events.
*/
docChanges(options?: SnapshotListenOptions): Array<DocumentChange<AppModelType, DbModelType>>;
}
/** Calculates the array of `DocumentChange`s for a given `ViewSnapshot`. */
export declare function changesFromSnapshot<AppModelType, DbModelType extends DocumentData>(querySnapshot: QuerySnapshot<AppModelType, DbModelType>, includeMetadataChanges: boolean): Array<DocumentChange<AppModelType, DbModelType>>;
export declare function resultChangeType(type: ChangeType): DocumentChangeType;
/**
* Returns true if the provided snapshots are equal.
*
* @param left - A snapshot to compare.
* @param right - A snapshot to compare.
* @returns true if the snapshots are equal.
*/
export declare function snapshotEqual<AppModelType, DbModelType extends DocumentData>(left: DocumentSnapshot<AppModelType, DbModelType> | QuerySnapshot<AppModelType, DbModelType>, right: DocumentSnapshot<AppModelType, DbModelType> | QuerySnapshot<AppModelType, DbModelType>): boolean;

View file

@ -0,0 +1,17 @@
/**
* @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.
*/
export { Timestamp } from '../lite-api/timestamp';

View file

@ -0,0 +1,61 @@
/**
* @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 { Transaction as InternalTransaction } from '../core/transaction';
import { DocumentData, DocumentReference } from '../lite-api/reference';
import { Transaction as LiteTransaction } from '../lite-api/transaction';
import { Firestore } from './database';
import { DocumentSnapshot } from './snapshot';
import { TransactionOptions } from './transaction_options';
/**
* A reference to a transaction.
*
* The `Transaction` object passed to a transaction's `updateFunction` provides
* the methods to read and write data within the transaction context. See
* {@link runTransaction}.
*/
export declare class Transaction extends LiteTransaction {
protected readonly _firestore: Firestore;
/** @hideconstructor */
constructor(_firestore: Firestore, _transaction: InternalTransaction);
/**
* Reads the document referenced by the provided {@link DocumentReference}.
*
* @param documentRef - A reference to the document to be read.
* @returns A `DocumentSnapshot` with the read data.
*/
get<AppModelType, DbModelType extends DocumentData>(documentRef: DocumentReference<AppModelType, DbModelType>): Promise<DocumentSnapshot<AppModelType, DbModelType>>;
}
/**
* Executes the given `updateFunction` and then attempts to commit the changes
* applied within the transaction. If any document read within the transaction
* has changed, Cloud Firestore retries the `updateFunction`. If it fails to
* commit after 5 attempts, the transaction fails.
*
* The maximum number of writes allowed in a single transaction is 500.
*
* @param firestore - A reference to the Firestore database to run this
* transaction against.
* @param updateFunction - The function to execute within the transaction
* context.
* @param options - An options object to configure maximum number of attempts to
* commit.
* @returns If the transaction completed successfully or was explicitly aborted
* (the `updateFunction` returned a failed promise), the promise returned by the
* `updateFunction `is returned here. Otherwise, if the transaction failed, a
* rejected promise with the corresponding failure error is returned.
*/
export declare function runTransaction<T>(firestore: Firestore, updateFunction: (transaction: Transaction) => Promise<T>, options?: TransactionOptions): Promise<T>;

View file

@ -0,0 +1,17 @@
/**
* @license
* Copyright 2022 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.
*/
export { TransactionOptions } from '../lite-api/transaction_options';

View file

@ -0,0 +1,31 @@
/**
* @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 { WriteBatch } from '../lite-api/write_batch';
import { Firestore } from './database';
export { WriteBatch };
/**
* Creates a write batch, used for performing multiple writes as a single
* atomic operation. The maximum number of writes allowed in a single {@link WriteBatch}
* is 500.
*
* Unlike transactions, write batches are persisted offline and therefore are
* preferable when you don't need to condition your writes on read data.
*
* @returns A {@link WriteBatch} that can be used to atomically execute multiple
* writes.
*/
export declare function writeBatch(firestore: Firestore): WriteBatch;

View file

@ -0,0 +1,36 @@
/**
* @license
* Copyright 2017 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.
*/
/**
* Simple wrapper around a nullable UID. Mostly exists to make code more
* readable.
*/
export declare class User {
readonly uid: string | null;
/** A user with a null UID. */
static readonly UNAUTHENTICATED: User;
static readonly GOOGLE_CREDENTIALS: User;
static readonly FIRST_PARTY: User;
static readonly MOCK_USER: User;
constructor(uid: string | null);
isAuthenticated(): boolean;
/**
* Returns a key representing this user, suitable for inclusion in a
* dictionary.
*/
toKey(): string;
isEqual(otherUser: User): boolean;
}

View file

@ -0,0 +1,38 @@
/**
* @license
* Copyright 2023 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 { FieldPath } from '../model/path';
/**
* Union type representing the aggregate type to be performed.
*/
export declare type AggregateType = 'count' | 'avg' | 'sum';
/**
* Represents an Aggregate to be performed over a query result set.
*/
export interface Aggregate {
readonly fieldPath?: FieldPath;
readonly alias: string;
readonly aggregateType: AggregateType;
}
/**
* Concrete implementation of the Aggregate type.
*/
export declare class AggregateImpl implements Aggregate {
readonly alias: string;
readonly aggregateType: AggregateType;
readonly fieldPath?: FieldPath | undefined;
constructor(alias: string, aggregateType: AggregateType, fieldPath?: FieldPath | undefined);
}

View file

@ -0,0 +1,49 @@
/**
* @license
* Copyright 2022 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 { Document } from '../model/document';
import { Value as ProtoValue } from '../protos/firestore_proto_api';
import { OrderBy } from './order_by';
/**
* Represents a bound of a query.
*
* The bound is specified with the given components representing a position and
* whether it's just before or just after the position (relative to whatever the
* query order is).
*
* The position represents a logical index position for a query. It's a prefix
* of values for the (potentially implicit) order by clauses of a query.
*
* Bound provides a function to determine whether a document comes before or
* after a bound. This is influenced by whether the position is just before or
* just after the provided values.
*/
export declare class Bound {
readonly position: ProtoValue[];
readonly inclusive: boolean;
constructor(position: ProtoValue[], inclusive: boolean);
}
/**
* Returns true if a document sorts after a bound using the provided sort
* order.
*/
export declare function boundSortsAfterDocument(bound: Bound, orderBy: OrderBy[], doc: Document): boolean;
/**
* Returns true if a document sorts before a bound using the provided sort
* order.
*/
export declare function boundSortsBeforeDocument(bound: Bound, orderBy: OrderBy[], doc: Document): boolean;
export declare function boundEquals(left: Bound | null, right: Bound | null): boolean;

View file

@ -0,0 +1,80 @@
/**
* @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 { LoadBundleTaskProgress } from '@firebase/firestore-types';
import { DocumentMap } from '../model/collections';
import { MutableDocument } from '../model/document';
import { DocumentKey } from '../model/document_key';
import { BundledDocumentMetadata as ProtoBundledDocumentMetadata } from '../protos/firestore_bundle_proto';
import { Document as ApiDocument, Timestamp as ApiTimestamp } from '../protos/firestore_proto_api';
import { Query } from './query';
import { SnapshotVersion } from './snapshot_version';
/**
* Represents a bundled document, including the metadata and the document
* itself, if it exists.
*/
export interface BundledDocument {
metadata: ProtoBundledDocumentMetadata;
document?: ApiDocument;
}
/**
* An array of `BundledDocument`.
*/
export declare type BundledDocuments = BundledDocument[];
export interface BundleLoadResult {
readonly progress: LoadBundleTaskProgress;
readonly changedCollectionGroups: Set<string>;
readonly changedDocs: DocumentMap;
}
/**
* Represents a Firestore bundle saved by the SDK in its local storage.
*/
export interface BundleMetadata {
/**
* 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;
}
/**
* Helper to convert objects from bundles to model objects in the SDK.
*/
export interface BundleConverter {
toDocumentKey(name: string): DocumentKey;
/**
* Converts a BundleDocument to a MutableDocument.
*/
toMutableDocument(bundledDoc: BundledDocument): MutableDocument;
toSnapshotVersion(time: ApiTimestamp): SnapshotVersion;
}

View file

@ -0,0 +1,79 @@
/**
* @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 { LoadBundleTaskProgress } from '@firebase/firestore-types';
import { LocalStore } from '../local/local_store';
import { MutableDocument } from '../model/document';
import { DocumentKey } from '../model/document_key';
import { BundleMetadata as ProtoBundleMetadata } from '../protos/firestore_bundle_proto';
import { Timestamp as ApiTimestamp } from '../protos/firestore_proto_api';
import { JsonProtoSerializer } from '../remote/serializer';
import { SizedBundleElement } from '../util/bundle_reader';
import { BundleConverter, BundledDocument, BundleLoadResult } from './bundle';
import { SnapshotVersion } from './snapshot_version';
/**
* Helper to convert objects from bundles to model objects in the SDK.
*/
export declare class BundleConverterImpl implements BundleConverter {
private readonly serializer;
constructor(serializer: JsonProtoSerializer);
toDocumentKey(name: string): DocumentKey;
/**
* Converts a BundleDocument to a MutableDocument.
*/
toMutableDocument(bundledDoc: BundledDocument): MutableDocument;
toSnapshotVersion(time: ApiTimestamp): SnapshotVersion;
}
/**
* A class to process the elements from a bundle, load them into local
* storage and provide progress update while loading.
*/
export declare class BundleLoader {
private bundleMetadata;
private localStore;
private serializer;
/** The current progress of loading */
private progress;
/** Batched queries to be saved into storage */
private queries;
/** Batched documents to be saved into storage */
private documents;
/** The collection groups affected by this bundle. */
private collectionGroups;
constructor(bundleMetadata: ProtoBundleMetadata, localStore: LocalStore, serializer: JsonProtoSerializer);
/**
* Adds an element from the bundle to the loader.
*
* Returns a new progress if adding the element leads to a new progress,
* otherwise returns null.
*/
addSizedElement(element: SizedBundleElement): LoadBundleTaskProgress | null;
private getQueryDocumentMapping;
/**
* Update the progress to 'Success' and return the updated progress.
*/
complete(): Promise<BundleLoadResult>;
}
/**
* Returns a `LoadBundleTaskProgress` representing the initial progress of
* loading a bundle.
*/
export declare function bundleInitialProgress(metadata: ProtoBundleMetadata): LoadBundleTaskProgress;
/**
* Returns a `LoadBundleTaskProgress` representing the progress that the loading
* has succeeded.
*/
export declare function bundleSuccessProgress(metadata: ProtoBundleMetadata): LoadBundleTaskProgress;

View file

@ -0,0 +1,146 @@
/**
* @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 { CredentialsProvider } from '../api/credentials';
import { User } from '../auth/user';
import { IndexedDbPersistence } from '../local/indexeddb_persistence';
import { LocalStore } from '../local/local_store';
import { Scheduler, Persistence } from '../local/persistence';
import { ClientId, SharedClientState } from '../local/shared_client_state';
import { Datastore } from '../remote/datastore';
import { RemoteStore } from '../remote/remote_store';
import { JsonProtoSerializer } from '../remote/serializer';
import { AsyncQueue } from '../util/async_queue';
import { DatabaseInfo } from './database_info';
import { EventManager } from './event_manager';
import { SyncEngine } from './sync_engine';
declare type Kind = 'memory' | 'persistent';
export interface ComponentConfiguration {
asyncQueue: AsyncQueue;
databaseInfo: DatabaseInfo;
authCredentials: CredentialsProvider<User>;
appCheckCredentials: CredentialsProvider<string>;
clientId: ClientId;
initialUser: User;
maxConcurrentLimboResolutions: number;
}
export interface OfflineComponentProviderFactory {
build(onlineComponents: OnlineComponentProvider): OfflineComponentProvider;
}
/**
* Initializes and wires components that are needed to interface with the local
* cache. Implementations override `initialize()` to provide all components.
*/
export interface OfflineComponentProvider {
readonly kind: Kind;
persistence: Persistence;
sharedClientState: SharedClientState;
localStore: LocalStore;
gcScheduler: Scheduler | null;
indexBackfillerScheduler: Scheduler | null;
synchronizeTabs: boolean;
initialize(cfg: ComponentConfiguration): Promise<void>;
terminate(): Promise<void>;
}
/**
* Provides all components needed for Firestore with in-memory persistence.
* Uses EagerGC garbage collection.
*/
export declare class MemoryOfflineComponentProvider implements OfflineComponentProvider {
kind: Kind;
static readonly provider: OfflineComponentProviderFactory;
persistence: Persistence;
sharedClientState: SharedClientState;
localStore: LocalStore;
gcScheduler: Scheduler | null;
indexBackfillerScheduler: Scheduler | null;
synchronizeTabs: boolean;
serializer: JsonProtoSerializer;
initialize(cfg: ComponentConfiguration): Promise<void>;
createGarbageCollectionScheduler(cfg: ComponentConfiguration, localStore: LocalStore): Scheduler | null;
createIndexBackfillerScheduler(cfg: ComponentConfiguration, localStore: LocalStore): Scheduler | null;
createLocalStore(cfg: ComponentConfiguration): LocalStore;
createPersistence(cfg: ComponentConfiguration): Persistence;
createSharedClientState(cfg: ComponentConfiguration): SharedClientState;
terminate(): Promise<void>;
}
export declare class LruGcMemoryOfflineComponentProvider extends MemoryOfflineComponentProvider {
protected readonly cacheSizeBytes: number | undefined;
constructor(cacheSizeBytes: number | undefined);
createGarbageCollectionScheduler(cfg: ComponentConfiguration, localStore: LocalStore): Scheduler | null;
createPersistence(cfg: ComponentConfiguration): Persistence;
}
/**
* Provides all components needed for Firestore with IndexedDB persistence.
*/
export declare class IndexedDbOfflineComponentProvider extends MemoryOfflineComponentProvider {
protected readonly onlineComponentProvider: OnlineComponentProvider;
protected readonly cacheSizeBytes: number | undefined;
protected readonly forceOwnership: boolean | undefined;
kind: Kind;
persistence: IndexedDbPersistence;
sharedClientState: SharedClientState;
localStore: LocalStore;
gcScheduler: Scheduler | null;
indexBackfillerScheduler: Scheduler | null;
synchronizeTabs: boolean;
constructor(onlineComponentProvider: OnlineComponentProvider, cacheSizeBytes: number | undefined, forceOwnership: boolean | undefined);
initialize(cfg: ComponentConfiguration): Promise<void>;
createLocalStore(cfg: ComponentConfiguration): LocalStore;
createGarbageCollectionScheduler(cfg: ComponentConfiguration, localStore: LocalStore): Scheduler | null;
createIndexBackfillerScheduler(cfg: ComponentConfiguration, localStore: LocalStore): Scheduler | null;
createPersistence(cfg: ComponentConfiguration): IndexedDbPersistence;
createSharedClientState(cfg: ComponentConfiguration): SharedClientState;
}
/**
* Provides all components needed for Firestore with multi-tab IndexedDB
* persistence.
*
* In the legacy client, this provider is used to provide both multi-tab and
* non-multi-tab persistence since we cannot tell at build time whether
* `synchronizeTabs` will be enabled.
*/
export declare class MultiTabOfflineComponentProvider extends IndexedDbOfflineComponentProvider {
protected readonly onlineComponentProvider: OnlineComponentProvider;
protected readonly cacheSizeBytes: number | undefined;
synchronizeTabs: boolean;
constructor(onlineComponentProvider: OnlineComponentProvider, cacheSizeBytes: number | undefined);
initialize(cfg: ComponentConfiguration): Promise<void>;
createSharedClientState(cfg: ComponentConfiguration): SharedClientState;
}
export interface OnlineComponentProviderFactory {
build(): OnlineComponentProvider;
}
/**
* Initializes and wires the components that are needed to interface with the
* network.
*/
export declare class OnlineComponentProvider {
static readonly provider: OnlineComponentProviderFactory;
protected localStore: LocalStore;
protected sharedClientState: SharedClientState;
datastore: Datastore;
eventManager: EventManager;
remoteStore: RemoteStore;
syncEngine: SyncEngine;
initialize(offlineComponentProvider: OfflineComponentProvider, cfg: ComponentConfiguration): Promise<void>;
createEventManager(cfg: ComponentConfiguration): EventManager;
createDatastore(cfg: ComponentConfiguration): Datastore;
createRemoteStore(cfg: ComponentConfiguration): RemoteStore;
createSyncEngine(cfg: ComponentConfiguration, startAsPrimary: boolean): SyncEngine;
terminate(): Promise<void>;
}
export {};

View file

@ -0,0 +1,63 @@
import { FirebaseApp } from '@firebase/app';
import { ExperimentalLongPollingOptions } from '../api/long_polling_options';
/**
* @license
* Copyright 2017 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.
*/
export declare class DatabaseInfo {
readonly databaseId: DatabaseId;
readonly appId: string;
readonly persistenceKey: string;
readonly host: string;
readonly ssl: boolean;
readonly forceLongPolling: boolean;
readonly autoDetectLongPolling: boolean;
readonly longPollingOptions: ExperimentalLongPollingOptions;
readonly useFetchStreams: boolean;
/**
* Constructs a DatabaseInfo using the provided host, databaseId and
* persistenceKey.
*
* @param databaseId - The database to use.
* @param appId - The Firebase App Id.
* @param persistenceKey - A unique identifier for this Firestore's local
* storage (used in conjunction with the databaseId).
* @param host - The Firestore backend host to connect to.
* @param ssl - Whether to use SSL when connecting.
* @param forceLongPolling - Whether to use the forceLongPolling option
* when using WebChannel as the network transport.
* @param autoDetectLongPolling - Whether to use the detectBufferingProxy
* option when using WebChannel as the network transport.
* @param longPollingOptions Options that configure long-polling.
* @param useFetchStreams Whether to use the Fetch API instead of
* XMLHTTPRequest
*/
constructor(databaseId: DatabaseId, appId: string, persistenceKey: string, host: string, ssl: boolean, forceLongPolling: boolean, autoDetectLongPolling: boolean, longPollingOptions: ExperimentalLongPollingOptions, useFetchStreams: boolean);
}
/** The default database name for a project. */
export declare const DEFAULT_DATABASE_NAME = "(default)";
/**
* Represents the database ID a Firestore client is associated with.
* @internal
*/
export declare class DatabaseId {
readonly projectId: string;
readonly database: string;
constructor(projectId: string, database?: string);
static empty(): DatabaseId;
get isDefaultDatabase(): boolean;
isEqual(other: {}): boolean;
}
export declare function databaseIdFromApp(app: FirebaseApp, database?: string): DatabaseId;

View file

@ -0,0 +1,133 @@
/**
* @license
* Copyright 2017 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 { FirestoreError } from '../util/error';
import { EventHandler } from '../util/misc';
import { ObjectMap } from '../util/obj_map';
import { Query } from './query';
import { OnlineState } from './types';
import { ViewSnapshot } from './view_snapshot';
/**
* Holds the listeners and the last received ViewSnapshot for a query being
* tracked by EventManager.
*/
declare class QueryListenersInfo {
viewSnap: ViewSnapshot | undefined;
listeners: QueryListener[];
hasRemoteListeners(): boolean;
}
/**
* Interface for handling events from the EventManager.
*/
export interface Observer<T> {
next: EventHandler<T>;
error: EventHandler<FirestoreError>;
}
/**
* EventManager is responsible for mapping queries to query event emitters.
* It handles "fan-out". -- Identical queries will re-use the same watch on the
* backend.
*
* PORTING NOTE: On Web, EventManager `onListen` and `onUnlisten` need to be
* assigned to SyncEngine's `listen()` and `unlisten()` API before usage. This
* allows users to tree-shake the Watch logic.
*/
export interface EventManager {
onListen?: (query: Query, enableRemoteListen: boolean) => Promise<ViewSnapshot>;
onUnlisten?: (query: Query, disableRemoteListen: boolean) => Promise<void>;
onFirstRemoteStoreListen?: (query: Query) => Promise<void>;
onLastRemoteStoreUnlisten?: (query: Query) => Promise<void>;
terminate(): void;
}
export declare function newEventManager(): EventManager;
export declare class EventManagerImpl implements EventManager {
queries: ObjectMap<Query, QueryListenersInfo>;
onlineState: OnlineState;
snapshotsInSyncListeners: Set<Observer<void>>;
/** Callback invoked when a Query is first listen to. */
onListen?: (query: Query, enableRemoteListen: boolean) => Promise<ViewSnapshot>;
/** Callback invoked once all listeners to a Query are removed. */
onUnlisten?: (query: Query, disableRemoteListen: boolean) => Promise<void>;
/**
* Callback invoked when a Query starts listening to the remote store, while
* already listening to the cache.
*/
onFirstRemoteStoreListen?: (query: Query) => Promise<void>;
/**
* Callback invoked when a Query stops listening to the remote store, while
* still listening to the cache.
*/
onLastRemoteStoreUnlisten?: (query: Query) => Promise<void>;
terminate(): void;
}
export declare function eventManagerListen(eventManager: EventManager, listener: QueryListener): Promise<void>;
export declare function eventManagerUnlisten(eventManager: EventManager, listener: QueryListener): Promise<void>;
export declare function eventManagerOnWatchChange(eventManager: EventManager, viewSnaps: ViewSnapshot[]): void;
export declare function eventManagerOnWatchError(eventManager: EventManager, query: Query, error: FirestoreError): void;
export declare function eventManagerOnOnlineStateChange(eventManager: EventManager, onlineState: OnlineState): void;
export declare function addSnapshotsInSyncListener(eventManager: EventManager, observer: Observer<void>): void;
export declare function removeSnapshotsInSyncListener(eventManager: EventManager, observer: Observer<void>): void;
export declare enum ListenerDataSource {
/** Listen to both cache and server changes */
Default = "default",
/** Listen to changes in cache only */
Cache = "cache"
}
export interface ListenOptions {
/** Raise events even when only the metadata changes */
readonly includeMetadataChanges?: boolean;
/**
* Wait for a sync with the server when online, but still raise events while
* offline.
*/
readonly waitForSyncWhenOnline?: boolean;
/** Set the source events raised from. */
readonly source?: ListenerDataSource;
}
/**
* QueryListener takes a series of internal view snapshots and determines
* when to raise the event.
*
* It uses an Observer to dispatch events.
*/
export declare class QueryListener {
readonly query: Query;
private queryObserver;
/**
* Initial snapshots (e.g. from cache) may not be propagated to the wrapped
* observer. This flag is set to true once we've actually raised an event.
*/
private raisedInitialEvent;
private options;
private snap;
private onlineState;
constructor(query: Query, queryObserver: Observer<ViewSnapshot>, options?: ListenOptions);
/**
* Applies the new ViewSnapshot to this listener, raising a user-facing event
* if applicable (depending on what changed, whether the user has opted into
* metadata-only changes, etc.). Returns true if a user-facing event was
* indeed raised.
*/
onViewSnapshot(snap: ViewSnapshot): boolean;
onError(error: FirestoreError): void;
/** Returns whether a snapshot was raised. */
applyOnlineStateChange(onlineState: OnlineState): boolean;
private shouldRaiseInitialEvent;
private shouldRaiseEvent;
private raiseInitialEvent;
listensToRemoteStore(): boolean;
}
export {};

View file

@ -0,0 +1,130 @@
/**
* @license
* Copyright 2022 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 { Document } from '../model/document';
import { FieldPath } from '../model/path';
import { Value as ProtoValue } from '../protos/firestore_proto_api';
export declare const enum Operator {
LESS_THAN = "<",
LESS_THAN_OR_EQUAL = "<=",
EQUAL = "==",
NOT_EQUAL = "!=",
GREATER_THAN = ">",
GREATER_THAN_OR_EQUAL = ">=",
ARRAY_CONTAINS = "array-contains",
IN = "in",
NOT_IN = "not-in",
ARRAY_CONTAINS_ANY = "array-contains-any"
}
export declare const enum CompositeOperator {
OR = "or",
AND = "and"
}
export declare abstract class Filter {
abstract matches(doc: Document): boolean;
abstract getFlattenedFilters(): readonly FieldFilter[];
abstract getFilters(): Filter[];
}
export declare class FieldFilter extends Filter {
readonly field: FieldPath;
readonly op: Operator;
readonly value: ProtoValue;
protected constructor(field: FieldPath, op: Operator, value: ProtoValue);
/**
* Creates a filter based on the provided arguments.
*/
static create(field: FieldPath, op: Operator, value: ProtoValue): FieldFilter;
private static createKeyFieldInFilter;
matches(doc: Document): boolean;
protected matchesComparison(comparison: number): boolean;
isInequality(): boolean;
getFlattenedFilters(): readonly FieldFilter[];
getFilters(): Filter[];
}
export declare class CompositeFilter extends Filter {
readonly filters: readonly Filter[];
readonly op: CompositeOperator;
private memoizedFlattenedFilters;
protected constructor(filters: readonly Filter[], op: CompositeOperator);
/**
* Creates a filter based on the provided arguments.
*/
static create(filters: Filter[], op: CompositeOperator): CompositeFilter;
matches(doc: Document): boolean;
getFlattenedFilters(): readonly FieldFilter[];
getFilters(): Filter[];
}
export declare function compositeFilterIsConjunction(compositeFilter: CompositeFilter): boolean;
export declare function compositeFilterIsDisjunction(compositeFilter: CompositeFilter): boolean;
/**
* Returns true if this filter is a conjunction of field filters only. Returns false otherwise.
*/
export declare function compositeFilterIsFlatConjunction(compositeFilter: CompositeFilter): boolean;
/**
* Returns true if this filter does not contain any composite filters. Returns false otherwise.
*/
export declare function compositeFilterIsFlat(compositeFilter: CompositeFilter): boolean;
export declare function canonifyFilter(filter: Filter): string;
export declare function filterEquals(f1: Filter, f2: Filter): boolean;
export declare function fieldFilterEquals(f1: FieldFilter, f2: Filter): boolean;
export declare function compositeFilterEquals(f1: CompositeFilter, f2: Filter): boolean;
/**
* Returns a new composite filter that contains all filter from
* `compositeFilter` plus all the given filters in `otherFilters`.
*/
export declare function compositeFilterWithAddedFilters(compositeFilter: CompositeFilter, otherFilters: Filter[]): CompositeFilter;
/** Returns a debug description for `filter`. */
export declare function stringifyFilter(filter: Filter): string;
export declare function stringifyCompositeFilter(filter: CompositeFilter): string;
export declare function stringifyFieldFilter(filter: FieldFilter): string;
/** Filter that matches on key fields (i.e. '__name__'). */
export declare class KeyFieldFilter extends FieldFilter {
private readonly key;
constructor(field: FieldPath, op: Operator, value: ProtoValue);
matches(doc: Document): boolean;
}
/** Filter that matches on key fields within an array. */
export declare class KeyFieldInFilter extends FieldFilter {
private readonly keys;
constructor(field: FieldPath, value: ProtoValue);
matches(doc: Document): boolean;
}
/** Filter that matches on key fields not present within an array. */
export declare class KeyFieldNotInFilter extends FieldFilter {
private readonly keys;
constructor(field: FieldPath, value: ProtoValue);
matches(doc: Document): boolean;
}
/** A Filter that implements the array-contains operator. */
export declare class ArrayContainsFilter extends FieldFilter {
constructor(field: FieldPath, value: ProtoValue);
matches(doc: Document): boolean;
}
/** A Filter that implements the IN operator. */
export declare class InFilter extends FieldFilter {
constructor(field: FieldPath, value: ProtoValue);
matches(doc: Document): boolean;
}
/** A Filter that implements the not-in operator. */
export declare class NotInFilter extends FieldFilter {
constructor(field: FieldPath, value: ProtoValue);
matches(doc: Document): boolean;
}
/** A Filter that implements the array-contains-any operator. */
export declare class ArrayContainsAnyFilter extends FieldFilter {
constructor(field: FieldPath, value: ProtoValue);
matches(doc: Document): boolean;
}

View file

@ -0,0 +1,134 @@
/**
* @license
* Copyright 2017 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 { GetOptions } from '@firebase/firestore-types';
import { LoadBundleTask } from '../api/bundle';
import { CredentialsProvider } from '../api/credentials';
import { User } from '../auth/user';
import { LocalStore } from '../local/local_store';
import { Document } from '../model/document';
import { DocumentKey } from '../model/document_key';
import { FieldIndex } from '../model/field_index';
import { Mutation } from '../model/mutation';
import { ApiClientObjectMap, Value } from '../protos/firestore_proto_api';
import { AsyncQueue } from '../util/async_queue';
import { FirestoreError } from '../util/error';
import { Aggregate } from './aggregate';
import { NamedQuery } from './bundle';
import { ComponentConfiguration, OfflineComponentProvider, OnlineComponentProvider } from './component_provider';
import { DatabaseId, DatabaseInfo } from './database_info';
import { EventManager, ListenOptions, Observer } from './event_manager';
import { Query } from './query';
import { SyncEngine } from './sync_engine';
import { Transaction } from './transaction';
import { TransactionOptions } from './transaction_options';
import { ViewSnapshot } from './view_snapshot';
export declare const MAX_CONCURRENT_LIMBO_RESOLUTIONS = 100;
/**
* FirestoreClient is a top-level class that constructs and owns all of the //
* pieces of the client SDK architecture. It is responsible for creating the //
* async queue that is shared by all of the other components in the system. //
*/
export declare class FirestoreClient {
private authCredentials;
private appCheckCredentials;
/**
* Asynchronous queue responsible for all of our internal processing. When
* we get incoming work from the user (via public API) or the network
* (incoming GRPC messages), we should always schedule onto this queue.
* This ensures all of our work is properly serialized (e.g. we don't
* start processing a new operation while the previous one is waiting for
* an async I/O to complete).
*/
asyncQueue: AsyncQueue;
private databaseInfo;
private user;
private readonly clientId;
private authCredentialListener;
private appCheckCredentialListener;
_uninitializedComponentsProvider?: {
_offline: OfflineComponentProvider;
_online: OnlineComponentProvider;
};
_offlineComponents?: OfflineComponentProvider;
_onlineComponents?: OnlineComponentProvider;
constructor(authCredentials: CredentialsProvider<User>, appCheckCredentials: CredentialsProvider<string>,
/**
* Asynchronous queue responsible for all of our internal processing. When
* we get incoming work from the user (via public API) or the network
* (incoming GRPC messages), we should always schedule onto this queue.
* This ensures all of our work is properly serialized (e.g. we don't
* start processing a new operation while the previous one is waiting for
* an async I/O to complete).
*/
asyncQueue: AsyncQueue, databaseInfo: DatabaseInfo, componentProvider?: {
_offline: OfflineComponentProvider;
_online: OnlineComponentProvider;
});
get configuration(): ComponentConfiguration;
setCredentialChangeListener(listener: (user: User) => Promise<void>): void;
setAppCheckTokenChangeListener(listener: (appCheckToken: string, user: User) => Promise<void>): void;
terminate(): Promise<void>;
}
export declare function setOfflineComponentProvider(client: FirestoreClient, offlineComponentProvider: OfflineComponentProvider): Promise<void>;
export declare function setOnlineComponentProvider(client: FirestoreClient, onlineComponentProvider: OnlineComponentProvider): Promise<void>;
/**
* Decides whether the provided error allows us to gracefully disable
* persistence (as opposed to crashing the client).
*/
export declare function canFallbackFromIndexedDbError(error: FirestoreError | DOMException): boolean;
export declare function getLocalStore(client: FirestoreClient): Promise<LocalStore>;
export declare function getSyncEngine(client: FirestoreClient): Promise<SyncEngine>;
export declare function getEventManager(client: FirestoreClient): Promise<EventManager>;
/** Enables the network connection and re-enqueues all pending operations. */
export declare function firestoreClientEnableNetwork(client: FirestoreClient): Promise<void>;
/** Disables the network connection. Pending operations will not complete. */
export declare function firestoreClientDisableNetwork(client: FirestoreClient): Promise<void>;
/**
* Returns a Promise that resolves when all writes that were pending at the time
* this method was called received server acknowledgement. An acknowledgement
* can be either acceptance or rejection.
*/
export declare function firestoreClientWaitForPendingWrites(client: FirestoreClient): Promise<void>;
export declare function firestoreClientListen(client: FirestoreClient, query: Query, options: ListenOptions, observer: Partial<Observer<ViewSnapshot>>): () => void;
export declare function firestoreClientGetDocumentFromLocalCache(client: FirestoreClient, docKey: DocumentKey): Promise<Document | null>;
export declare function firestoreClientGetDocumentViaSnapshotListener(client: FirestoreClient, key: DocumentKey, options?: GetOptions): Promise<ViewSnapshot>;
export declare function firestoreClientGetDocumentsFromLocalCache(client: FirestoreClient, query: Query): Promise<ViewSnapshot>;
export declare function firestoreClientGetDocumentsViaSnapshotListener(client: FirestoreClient, query: Query, options?: GetOptions): Promise<ViewSnapshot>;
export declare function firestoreClientRunAggregateQuery(client: FirestoreClient, query: Query, aggregates: Aggregate[]): Promise<ApiClientObjectMap<Value>>;
export declare function firestoreClientWrite(client: FirestoreClient, mutations: Mutation[]): Promise<void>;
export declare function firestoreClientAddSnapshotsInSyncListener(client: FirestoreClient, observer: Partial<Observer<void>>): () => void;
/**
* Takes an updateFunction in which a set of reads and writes can be performed
* atomically. In the updateFunction, the client can read and write values
* using the supplied transaction object. After the updateFunction, all
* changes will be committed. If a retryable error occurs (ex: some other
* client has changed any of the data referenced), then the updateFunction
* will be called again after a backoff. If the updateFunction still fails
* after all retries, then the transaction will be rejected.
*
* The transaction object passed to the updateFunction contains methods for
* accessing documents and collections. Unlike other datastore access, data
* accessed with the transaction will not reflect local changes that have not
* been committed. For this reason, it is required that all reads are
* performed before any writes. Transactions must be performed while online.
*/
export declare function firestoreClientTransaction<T>(client: FirestoreClient, updateFunction: (transaction: Transaction) => Promise<T>, options: TransactionOptions): Promise<T>;
export declare function firestoreClientLoadBundle(client: FirestoreClient, databaseId: DatabaseId, data: ReadableStream<Uint8Array> | ArrayBuffer | string, resultTask: LoadBundleTask): void;
export declare function firestoreClientGetNamedQuery(client: FirestoreClient, queryName: string): Promise<NamedQuery | undefined>;
export declare function firestoreClientSetIndexConfiguration(client: FirestoreClient, indexes: FieldIndex[]): Promise<void>;
export declare function firestoreClientSetPersistentCacheIndexAutoCreationEnabled(client: FirestoreClient, isEnabled: boolean): Promise<void>;
export declare function firestoreClientDeleteAllFieldIndexes(client: FirestoreClient): Promise<void>;

View file

@ -0,0 +1,39 @@
/**
* @license
* Copyright 2018 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 { ListenSequenceNumber } from './types';
/**
* `SequenceNumberSyncer` defines the methods required to keep multiple instances of a
* `ListenSequence` in sync.
*/
export interface SequenceNumberSyncer {
writeSequenceNumber(sequenceNumber: ListenSequenceNumber): void;
sequenceNumberHandler: ((sequenceNumber: ListenSequenceNumber) => void) | null;
}
/**
* `ListenSequence` is a monotonic sequence. It is initialized with a minimum value to
* exceed. All subsequent calls to next will return increasing values. If provided with a
* `SequenceNumberSyncer`, it will additionally bump its next value when told of a new value, as
* well as write out sequence numbers that it produces via `next()`.
*/
export declare class ListenSequence {
private previousValue;
static readonly INVALID: ListenSequenceNumber;
private writeNewSequenceNumber?;
constructor(previousValue: ListenSequenceNumber, sequenceNumberSyncer?: SequenceNumberSyncer);
private setPreviousValue;
next(): ListenSequenceNumber;
}

View file

@ -0,0 +1,35 @@
/**
* @license
* Copyright 2022 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 { FieldPath } from '../model/path';
/**
* The direction of sorting in an order by.
*/
export declare const enum Direction {
ASCENDING = "asc",
DESCENDING = "desc"
}
/**
* An ordering on a field, in some Direction. Direction defaults to ASCENDING.
*/
export declare class OrderBy {
readonly field: FieldPath;
readonly dir: Direction;
constructor(field: FieldPath, dir?: Direction);
}
export declare function canonifyOrderBy(orderBy: OrderBy): string;
export declare function stringifyOrderBy(orderBy: OrderBy): string;
export declare function orderByEquals(left: OrderBy, right: OrderBy): boolean;

View file

@ -0,0 +1,142 @@
/**
* @license
* Copyright 2017 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 { Document } from '../model/document';
import { FieldPath, ResourcePath } from '../model/path';
import { SortedSet } from '../util/sorted_set';
import { Bound } from './bound';
import { Filter } from './filter';
import { OrderBy } from './order_by';
import { Target } from './target';
export declare const enum LimitType {
First = "F",
Last = "L"
}
/**
* The Query interface defines all external properties of a query.
*
* QueryImpl implements this interface to provide memoization for `queryNormalizedOrderBy`
* and `queryToTarget`.
*/
export interface Query {
readonly path: ResourcePath;
readonly collectionGroup: string | null;
readonly explicitOrderBy: OrderBy[];
readonly filters: Filter[];
readonly limit: number | null;
readonly limitType: LimitType;
readonly startAt: Bound | null;
readonly endAt: Bound | null;
}
/**
* Query encapsulates all the query attributes we support in the SDK. It can
* be run against the LocalStore, as well as be converted to a `Target` to
* query the RemoteStore results.
*
* Visible for testing.
*/
export declare class QueryImpl implements Query {
readonly path: ResourcePath;
readonly collectionGroup: string | null;
readonly explicitOrderBy: OrderBy[];
readonly filters: Filter[];
readonly limit: number | null;
readonly limitType: LimitType;
readonly startAt: Bound | null;
readonly endAt: Bound | null;
memoizedNormalizedOrderBy: OrderBy[] | null;
memoizedTarget: Target | null;
memoizedAggregateTarget: Target | null;
/**
* Initializes a Query with a path and optional additional query constraints.
* Path must currently be empty if this is a collection group query.
*/
constructor(path: ResourcePath, collectionGroup?: string | null, explicitOrderBy?: OrderBy[], filters?: Filter[], limit?: number | null, limitType?: LimitType, startAt?: Bound | null, endAt?: Bound | null);
}
/** Creates a new Query instance with the options provided. */
export declare function newQuery(path: ResourcePath, collectionGroup: string | null, explicitOrderBy: OrderBy[], filters: Filter[], limit: number | null, limitType: LimitType, startAt: Bound | null, endAt: Bound | null): Query;
/** Creates a new Query for a query that matches all documents at `path` */
export declare function newQueryForPath(path: ResourcePath): Query;
/**
* Helper to convert a collection group query into a collection query at a
* specific path. This is used when executing collection group queries, since
* we have to split the query into a set of collection queries at multiple
* paths.
*/
export declare function asCollectionQueryAtPath(query: Query, path: ResourcePath): Query;
/**
* Returns true if this query does not specify any query constraints that
* could remove results.
*/
export declare function queryMatchesAllDocuments(query: Query): boolean;
export declare function getInequalityFilterFields(query: Query): SortedSet<FieldPath>;
/**
* Creates a new Query for a collection group query that matches all documents
* within the provided collection group.
*/
export declare function newQueryForCollectionGroup(collectionId: string): Query;
/**
* Returns whether the query matches a single document by path (rather than a
* collection).
*/
export declare function isDocumentQuery(query: Query): boolean;
/**
* Returns whether the query matches a collection group rather than a specific
* collection.
*/
export declare function isCollectionGroupQuery(query: Query): boolean;
/**
* Returns the normalized order-by constraint that is used to execute the Query,
* which can be different from the order-by constraints the user provided (e.g.
* the SDK and backend always orders by `__name__`). The normalized order-by
* includes implicit order-bys in addition to the explicit user provided
* order-bys.
*/
export declare function queryNormalizedOrderBy(query: Query): OrderBy[];
/**
* Converts this `Query` instance to its corresponding `Target` representation.
*/
export declare function queryToTarget(query: Query): Target;
/**
* Converts this `Query` instance to its corresponding `Target` representation,
* for use within an aggregate query. Unlike targets for non-aggregate queries,
* aggregate query targets do not contain normalized order-bys, they only
* contain explicit order-bys.
*/
export declare function queryToAggregateTarget(query: Query): Target;
export declare function queryWithAddedFilter(query: Query, filter: Filter): Query;
export declare function queryWithAddedOrderBy(query: Query, orderBy: OrderBy): Query;
export declare function queryWithLimit(query: Query, limit: number | null, limitType: LimitType): Query;
export declare function queryWithStartAt(query: Query, bound: Bound): Query;
export declare function queryWithEndAt(query: Query, bound: Bound): Query;
export declare function queryEquals(left: Query, right: Query): boolean;
export declare function canonifyQuery(query: Query): string;
export declare function stringifyQuery(query: Query): string;
/** Returns whether `doc` matches the constraints of `query`. */
export declare function queryMatches(query: Query, doc: Document): boolean;
/**
* Returns the collection group that this query targets.
*
* PORTING NOTE: This is only used in the Web SDK to facilitate multi-tab
* synchronization for query results.
*/
export declare function queryCollectionGroup(query: Query): string;
/**
* Returns a new comparator function that can be used to compare two documents
* based on the Query's ordering constraint.
*/
export declare function newQueryComparator(query: Query): (d1: Document, d2: Document) => number;
export declare function compareDocs(orderBy: OrderBy, d1: Document, d2: Document): number;

View file

@ -0,0 +1,34 @@
/**
* @license
* Copyright 2017 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 { Timestamp } from '../lite-api/timestamp';
/**
* A version of a document in Firestore. This corresponds to the version
* timestamp, such as update_time or read_time.
*/
export declare class SnapshotVersion {
private timestamp;
static fromTimestamp(value: Timestamp): SnapshotVersion;
static min(): SnapshotVersion;
static max(): SnapshotVersion;
private constructor();
compareTo(other: SnapshotVersion): number;
isEqual(other: SnapshotVersion): boolean;
/** Returns a number representation of the version for use in spec tests. */
toMicroseconds(): number;
toString(): string;
toTimestamp(): Timestamp;
}

View file

@ -0,0 +1,37 @@
/**
* @license
* Copyright 2017 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.
*/
/**
* SyncEngine is the central controller in the client SDK architecture. It is
* the glue code between the EventManager, LocalStore, and RemoteStore. Some of
* SyncEngine's responsibilities include:
* 1. Coordinating client requests and remote events between the EventManager
* and the local and remote data stores.
* 2. Managing a View object for each query, providing the unified view between
* the local and remote data stores.
* 3. Notifying the RemoteStore when the LocalStore has new mutations in its
* queue that need sending to the backend.
*
* The SyncEngines methods should only ever be called by methods running in the
* global async queue.
*
* PORTING NOTE: On Web, SyncEngine does not have an explicit subscribe()
* function. Instead, it directly depends on EventManager's tree-shakeable API
* (via `ensureWatchStream()`).
*/
export interface SyncEngine {
isPrimaryClient: boolean;
}

View file

@ -0,0 +1,255 @@
/**
* @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 { LoadBundleTask } from '../api/bundle';
import { User } from '../auth/user';
import { LocalStore } from '../local/local_store';
import { ReferenceSet } from '../local/reference_set';
import { ClientId, SharedClientState } from '../local/shared_client_state';
import { QueryTargetState } from '../local/shared_client_state_syncer';
import { DocumentKeySet, DocumentMap } from '../model/collections';
import { DocumentKey } from '../model/document_key';
import { Mutation } from '../model/mutation';
import { MutationBatchResult } from '../model/mutation_batch';
import { RemoteEvent } from '../remote/remote_event';
import { RemoteStore } from '../remote/remote_store';
import { BundleReader } from '../util/bundle_reader';
import { FirestoreError } from '../util/error';
import { ObjectMap } from '../util/obj_map';
import { Deferred } from '../util/promise';
import { SortedMap } from '../util/sorted_map';
import { EventManager } from './event_manager';
import { Query } from './query';
import { SyncEngine } from './sync_engine';
import { TargetIdGenerator } from './target_id_generator';
import { BatchId, MutationBatchState, OnlineState, OnlineStateSource, TargetId } from './types';
import { View } from './view';
import { ViewSnapshot } from './view_snapshot';
/**
* QueryView contains all of the data that SyncEngine needs to keep track of for
* a particular query.
*/
declare class QueryView {
/**
* The query itself.
*/
query: Query;
/**
* The target number created by the client that is used in the watch
* stream to identify this query.
*/
targetId: TargetId;
/**
* The view is responsible for computing the final merged truth of what
* docs are in the query. It gets notified of local and remote changes,
* and applies the query filters and limits to determine the most correct
* possible results.
*/
view: View;
constructor(
/**
* The query itself.
*/
query: Query,
/**
* The target number created by the client that is used in the watch
* stream to identify this query.
*/
targetId: TargetId,
/**
* The view is responsible for computing the final merged truth of what
* docs are in the query. It gets notified of local and remote changes,
* and applies the query filters and limits to determine the most correct
* possible results.
*/
view: View);
}
/** Tracks a limbo resolution. */
declare class LimboResolution {
key: DocumentKey;
constructor(key: DocumentKey);
/**
* Set to true once we've received a document. This is used in
* getRemoteKeysForTarget() and ultimately used by WatchChangeAggregator to
* decide whether it needs to manufacture a delete event for the target once
* the target is CURRENT.
*/
receivedDocument: boolean;
}
/**
* A function that updates a QueryView with a set of document changes (and a
* remote event if applicable).
*/
declare type ApplyDocChangesHandler = (queryView: QueryView, changes: DocumentMap, remoteEvent?: RemoteEvent) => Promise<ViewSnapshot | undefined>;
/**
* Callbacks implemented by EventManager to handle notifications from
* SyncEngine.
*/
interface SyncEngineListener {
/** Handles new view snapshots. */
onWatchChange?(snapshots: ViewSnapshot[]): void;
/** Handles the failure of a query. */
onWatchError?(query: Query, error: FirestoreError): void;
}
/**
* An implementation of `SyncEngine` coordinating with other parts of SDK.
*
* The parts of SyncEngine that act as a callback to RemoteStore need to be
* registered individually. This is done in `syncEngineWrite()` and
* `syncEngineListen()` (as well as `applyPrimaryState()`) as these methods
* serve as entry points to RemoteStore's functionality.
*
* Note: some field defined in this class might have public access level, but
* the class is not exported so they are only accessible from this module.
* This is useful to implement optional features (like bundles) in free
* functions, such that they are tree-shakeable.
*/
declare class SyncEngineImpl implements SyncEngine {
readonly localStore: LocalStore;
readonly remoteStore: RemoteStore;
readonly eventManager: EventManager;
readonly sharedClientState: SharedClientState;
currentUser: User;
readonly maxConcurrentLimboResolutions: number;
syncEngineListener: SyncEngineListener;
/**
* A callback that updates the QueryView based on the provided change.
*
* PORTING NOTE: On other platforms, this logic lives in
* `emitNewSnapshotsAndNotifyLocalStore()`, but on Web it is extracted to
* ensure that all view logic only exists in bundles that include views.
*/
applyDocChanges?: ApplyDocChangesHandler;
queryViewsByQuery: ObjectMap<Query, QueryView>;
queriesByTarget: Map<number, Query[]>;
/**
* The keys of documents that are in limbo for which we haven't yet started a
* limbo resolution query. The strings in this set are the result of calling
* `key.path.canonicalString()` where `key` is a `DocumentKey` object.
*
* The `Set` type was chosen because it provides efficient lookup and removal
* of arbitrary elements and it also maintains insertion order, providing the
* desired queue-like FIFO semantics.
*/
enqueuedLimboResolutions: Set<string>;
/**
* Keeps track of the target ID for each document that is in limbo with an
* active target.
*/
activeLimboTargetsByKey: SortedMap<DocumentKey, number>;
/**
* Keeps track of the information about an active limbo resolution for each
* active target ID that was started for the purpose of limbo resolution.
*/
activeLimboResolutionsByTarget: Map<number, LimboResolution>;
limboDocumentRefs: ReferenceSet;
/** Stores user completion handlers, indexed by User and BatchId. */
mutationUserCallbacks: {
[uidKey: string]: SortedMap<number, Deferred<void>>;
};
/** Stores user callbacks waiting for all pending writes to be acknowledged. */
pendingWritesCallbacks: Map<number, Deferred<void>[]>;
limboTargetIdGenerator: TargetIdGenerator;
onlineState: OnlineState;
_isPrimaryClient: undefined | boolean;
constructor(localStore: LocalStore, remoteStore: RemoteStore, eventManager: EventManager, sharedClientState: SharedClientState, currentUser: User, maxConcurrentLimboResolutions: number);
get isPrimaryClient(): boolean;
}
export declare function newSyncEngine(localStore: LocalStore, remoteStore: RemoteStore, eventManager: EventManager, sharedClientState: SharedClientState, currentUser: User, maxConcurrentLimboResolutions: number, isPrimary: boolean): SyncEngine;
/**
* Initiates the new listen, resolves promise when listen enqueued to the
* server. All the subsequent view snapshots or errors are sent to the
* subscribed handlers. Returns the initial snapshot.
*/
export declare function syncEngineListen(syncEngine: SyncEngine, query: Query, shouldListenToRemote?: boolean): Promise<ViewSnapshot>;
/** Query has been listening to the cache, and tries to initiate the remote store listen */
export declare function triggerRemoteStoreListen(syncEngine: SyncEngine, query: Query): Promise<void>;
/** Stops listening to the query. */
export declare function syncEngineUnlisten(syncEngine: SyncEngine, query: Query, shouldUnlistenToRemote: boolean): Promise<void>;
/** Unlistens to the remote store while still listening to the cache. */
export declare function triggerRemoteStoreUnlisten(syncEngine: SyncEngine, query: Query): Promise<void>;
/**
* Initiates the write of local mutation batch which involves adding the
* writes to the mutation queue, notifying the remote store about new
* mutations and raising events for any changes this write caused.
*
* The promise returned by this call is resolved when the above steps
* have completed, *not* when the write was acked by the backend. The
* userCallback is resolved once the write was acked/rejected by the
* backend (or failed locally for any other reason).
*/
export declare function syncEngineWrite(syncEngine: SyncEngine, batch: Mutation[], userCallback: Deferred<void>): Promise<void>;
/**
* Applies one remote event to the sync engine, notifying any views of the
* changes, and releasing any pending mutation batches that would become
* visible because of the snapshot version the remote event contains.
*/
export declare function syncEngineApplyRemoteEvent(syncEngine: SyncEngine, remoteEvent: RemoteEvent): Promise<void>;
/**
* Applies an OnlineState change to the sync engine and notifies any views of
* the change.
*/
export declare function syncEngineApplyOnlineStateChange(syncEngine: SyncEngine, onlineState: OnlineState, source: OnlineStateSource): void;
/**
* Rejects the listen for the given targetID. This can be triggered by the
* backend for any active target.
*
* @param syncEngine - The sync engine implementation.
* @param targetId - The targetID corresponds to one previously initiated by the
* user as part of TargetData passed to listen() on RemoteStore.
* @param err - A description of the condition that has forced the rejection.
* Nearly always this will be an indication that the user is no longer
* authorized to see the data matching the target.
*/
export declare function syncEngineRejectListen(syncEngine: SyncEngine, targetId: TargetId, err: FirestoreError): Promise<void>;
export declare function syncEngineApplySuccessfulWrite(syncEngine: SyncEngine, mutationBatchResult: MutationBatchResult): Promise<void>;
export declare function syncEngineRejectFailedWrite(syncEngine: SyncEngine, batchId: BatchId, error: FirestoreError): Promise<void>;
/**
* Registers a user callback that resolves when all pending mutations at the moment of calling
* are acknowledged .
*/
export declare function syncEngineRegisterPendingWritesCallback(syncEngine: SyncEngine, callback: Deferred<void>): Promise<void>;
export declare function syncEngineGetActiveLimboDocumentResolutions(syncEngine: SyncEngine): SortedMap<DocumentKey, TargetId>;
export declare function syncEngineGetEnqueuedLimboDocumentResolutions(syncEngine: SyncEngine): Set<string>;
export declare function syncEngineEmitNewSnapsAndNotifyLocalStore(syncEngine: SyncEngine, changes: DocumentMap, remoteEvent?: RemoteEvent): Promise<void>;
export declare function syncEngineHandleCredentialChange(syncEngine: SyncEngine, user: User): Promise<void>;
export declare function syncEngineGetRemoteKeysForTarget(syncEngine: SyncEngine, targetId: TargetId): DocumentKeySet;
/**
* Retrieves newly changed documents from remote document cache and raises
* snapshots if needed.
*/
export declare function syncEngineSynchronizeWithChangedDocuments(syncEngine: SyncEngine, collectionGroup: string): Promise<void>;
/** Applies a mutation state to an existing batch. */
export declare function syncEngineApplyBatchState(syncEngine: SyncEngine, batchId: BatchId, batchState: MutationBatchState, error?: FirestoreError): Promise<void>;
/** Applies a query target change from a different tab. */
export declare function syncEngineApplyPrimaryState(syncEngine: SyncEngine, isPrimary: boolean): Promise<void>;
/** Returns the IDs of the clients that are currently active. */
export declare function syncEngineGetActiveClients(syncEngine: SyncEngine): Promise<ClientId[]>;
/** Applies a query target change from a different tab. */
export declare function syncEngineApplyTargetState(syncEngine: SyncEngine, targetId: TargetId, state: QueryTargetState, error?: FirestoreError): Promise<void>;
/** Adds or removes Watch targets for queries from different tabs. */
export declare function syncEngineApplyActiveTargetsChange(syncEngine: SyncEngine, added: TargetId[], removed: TargetId[]): Promise<void>;
export declare function syncEngineEnsureWriteCallbacks(syncEngine: SyncEngine): SyncEngineImpl;
/**
* Loads a Firestore bundle into the SDK. The returned promise resolves when
* the bundle finished loading.
*
* @param syncEngine - SyncEngine to use.
* @param bundleReader - Bundle to load into the SDK.
* @param task - LoadBundleTask used to update the loading progress to public API.
*/
export declare function syncEngineLoadBundle(syncEngine: SyncEngine, bundleReader: BundleReader, task: LoadBundleTask): void;
export {};

View file

@ -0,0 +1,89 @@
/**
* @license
* Copyright 2019 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 { FieldIndex } from '../model/field_index';
import { FieldPath, ResourcePath } from '../model/path';
import { Value as ProtoValue } from '../protos/firestore_proto_api';
import { Bound } from './bound';
import { Filter, FieldFilter } from './filter';
import { OrderBy } from './order_by';
/**
* A Target represents the WatchTarget representation of a Query, which is used
* by the LocalStore and the RemoteStore to keep track of and to execute
* backend queries. While a Query can represent multiple Targets, each Targets
* maps to a single WatchTarget in RemoteStore and a single TargetData entry
* in persistence.
*/
export interface Target {
readonly path: ResourcePath;
readonly collectionGroup: string | null;
readonly orderBy: OrderBy[];
readonly filters: Filter[];
readonly limit: number | null;
readonly startAt: Bound | null;
readonly endAt: Bound | null;
}
export declare class TargetImpl implements Target {
readonly path: ResourcePath;
readonly collectionGroup: string | null;
readonly orderBy: OrderBy[];
readonly filters: Filter[];
readonly limit: number | null;
readonly startAt: Bound | null;
readonly endAt: Bound | null;
memoizedCanonicalId: string | null;
constructor(path: ResourcePath, collectionGroup?: string | null, orderBy?: OrderBy[], filters?: Filter[], limit?: number | null, startAt?: Bound | null, endAt?: Bound | null);
}
/**
* Initializes a Target with a path and optional additional query constraints.
* Path must currently be empty if this is a collection group query.
*
* NOTE: you should always construct `Target` from `Query.toTarget` instead of
* using this factory method, because `Query` provides an implicit `orderBy`
* property.
*/
export declare function newTarget(path: ResourcePath, collectionGroup?: string | null, orderBy?: OrderBy[], filters?: Filter[], limit?: number | null, startAt?: Bound | null, endAt?: Bound | null): Target;
export declare function canonifyTarget(target: Target): string;
export declare function stringifyTarget(target: Target): string;
export declare function targetEquals(left: Target, right: Target): boolean;
export declare function targetIsDocumentTarget(target: Target): boolean;
/** Returns the field filters that target the given field path. */
export declare function targetGetFieldFiltersForPath(target: Target, path: FieldPath): FieldFilter[];
/**
* Returns the values that are used in ARRAY_CONTAINS or ARRAY_CONTAINS_ANY
* filters. Returns `null` if there are no such filters.
*/
export declare function targetGetArrayValues(target: Target, fieldIndex: FieldIndex): ProtoValue[] | null;
/**
* Returns the list of values that are used in != or NOT_IN filters. Returns
* `null` if there are no such filters.
*/
export declare function targetGetNotInValues(target: Target, fieldIndex: FieldIndex): ProtoValue[] | null;
/**
* Returns a lower bound of field values that can be used as a starting point to
* scan the index defined by `fieldIndex`. Returns `MIN_VALUE` if no lower bound
* exists.
*/
export declare function targetGetLowerBound(target: Target, fieldIndex: FieldIndex): Bound;
/**
* Returns an upper bound of field values that can be used as an ending point
* when scanning the index defined by `fieldIndex`. Returns `MAX_VALUE` if no
* upper bound exists.
*/
export declare function targetGetUpperBound(target: Target, fieldIndex: FieldIndex): Bound;
/** Returns the number of segments of a perfect index for this target. */
export declare function targetGetSegmentCount(target: Target): number;
export declare function targetHasLimit(target: Target): boolean;

View file

@ -0,0 +1,38 @@
/**
* @license
* Copyright 2017 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 { TargetId } from './types';
/**
* Generates monotonically increasing target IDs for sending targets to the
* watch stream.
*
* The client constructs two generators, one for the target cache, and one for
* for the sync engine (to generate limbo documents targets). These
* generators produce non-overlapping IDs (by using even and odd IDs
* respectively).
*
* By separating the target ID space, the query cache can generate target IDs
* that persist across client restarts, while sync engine can independently
* generate in-memory target IDs that are transient and can be reused after a
* restart.
*/
export declare class TargetIdGenerator {
private lastId;
constructor(lastId: number);
next(): TargetId;
static forTargetCache(): TargetIdGenerator;
static forSyncEngine(): TargetIdGenerator;
}

View file

@ -0,0 +1,60 @@
/**
* @license
* Copyright 2017 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 { ParsedSetData, ParsedUpdateData } from '../lite-api/user_data_reader';
import { Document } from '../model/document';
import { DocumentKey } from '../model/document_key';
import { Datastore } from '../remote/datastore';
/**
* Internal transaction object responsible for accumulating the mutations to
* perform and the base versions for any documents read.
*/
export declare class Transaction {
private datastore;
private readVersions;
private mutations;
private committed;
/**
* A deferred usage error that occurred previously in this transaction that
* will cause the transaction to fail once it actually commits.
*/
private lastTransactionError;
/**
* Set of documents that have been written in the transaction.
*
* When there's more than one write to the same key in a transaction, any
* writes after the first are handled differently.
*/
private writtenDocs;
constructor(datastore: Datastore);
lookup(keys: DocumentKey[]): Promise<Document[]>;
set(key: DocumentKey, data: ParsedSetData): void;
update(key: DocumentKey, data: ParsedUpdateData): void;
delete(key: DocumentKey): void;
commit(): Promise<void>;
private recordVersion;
/**
* Returns the version of this document when it was read in this transaction,
* as a precondition, or no precondition if it was not read.
*/
private precondition;
/**
* Returns the precondition for a document if the operation is an update.
*/
private preconditionForUpdate;
private write;
private ensureCommitNotCalled;
}

View file

@ -0,0 +1,25 @@
/**
* @license
* Copyright 2022 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.
*/
export declare const DEFAULT_TRANSACTION_OPTIONS: TransactionOptions;
/**
* Options to customize transaction behavior.
*/
export declare interface TransactionOptions {
/** Maximum number of attempts to commit, after which transaction fails. Default is 5. */
readonly maxAttempts: number;
}
export declare function validateTransactionOptions(options: TransactionOptions): void;

View file

@ -0,0 +1,41 @@
/**
* @license
* Copyright 2019 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 { Datastore } from '../remote/datastore';
import { AsyncQueue } from '../util/async_queue';
import { Deferred } from '../util/promise';
import { Transaction } from './transaction';
import { TransactionOptions } from './transaction_options';
/**
* TransactionRunner encapsulates the logic needed to run and retry transactions
* with backoff.
*/
export declare class TransactionRunner<T> {
private readonly asyncQueue;
private readonly datastore;
private readonly options;
private readonly updateFunction;
private readonly deferred;
private attemptsRemaining;
private backoff;
constructor(asyncQueue: AsyncQueue, datastore: Datastore, options: TransactionOptions, updateFunction: (transaction: Transaction) => Promise<T>, deferred: Deferred<T>);
/** Runs the transaction and sets the result on deferred. */
run(): void;
private runWithBackOff;
private tryRunUpdateFunction;
private handleTransactionError;
private isRetryableTransactionError;
}

View file

@ -0,0 +1,65 @@
/**
* @license
* Copyright 2017 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.
*/
/**
* BatchID is a locally assigned ID for a batch of mutations that have been
* applied.
*/
export declare type BatchId = number;
/**
* A locally-assigned ID used to refer to a target being watched via the
* Watch service.
*/
export declare type TargetId = number;
export declare type ListenSequenceNumber = number;
/** The different states of a mutation batch. */
export declare type MutationBatchState = 'pending' | 'acknowledged' | 'rejected';
/**
* Describes the online state of the Firestore client. Note that this does not
* indicate whether or not the remote store is trying to connect or not. This is
* primarily used by the View / EventManager code to change their behavior while
* offline (e.g. get() calls shouldn't wait for data from the server and
* snapshot events should set metadata.isFromCache=true).
*
* The string values should not be changed since they are persisted in
* WebStorage.
*/
export declare const enum OnlineState {
/**
* The Firestore client is in an unknown online state. This means the client
* is either not actively trying to establish a connection or it is currently
* trying to establish a connection, but it has not succeeded or failed yet.
* Higher-level components should not operate in offline mode.
*/
Unknown = "Unknown",
/**
* The client is connected and the connections are healthy. This state is
* reached after a successful connection and there has been at least one
* successful message received from the backends.
*/
Online = "Online",
/**
* The client is either trying to establish a connection but failing, or it
* has been explicitly marked offline via a call to disableNetwork().
* Higher-level components should operate in offline mode.
*/
Offline = "Offline"
}
/** The source of an online state event. */
export declare const enum OnlineStateSource {
RemoteStore = 0,
SharedClientState = 1
}

View file

@ -0,0 +1,18 @@
/**
* @license
* Copyright 2017 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.
*/
export declare let SDK_VERSION: string;
export declare function setSDKVersion(version: string): void;

View file

@ -0,0 +1,152 @@
/**
* @license
* Copyright 2017 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 { QueryResult } from '../local/local_store_impl';
import { DocumentKeySet, DocumentMap } from '../model/collections';
import { DocumentKey } from '../model/document_key';
import { DocumentSet } from '../model/document_set';
import { TargetChange } from '../remote/remote_event';
import { Query } from './query';
import { OnlineState } from './types';
import { DocumentChangeSet, ViewSnapshot } from './view_snapshot';
export declare type LimboDocumentChange = AddedLimboDocument | RemovedLimboDocument;
export declare class AddedLimboDocument {
key: DocumentKey;
constructor(key: DocumentKey);
}
export declare class RemovedLimboDocument {
key: DocumentKey;
constructor(key: DocumentKey);
}
/** The result of applying a set of doc changes to a view. */
export interface ViewDocumentChanges {
/** The new set of docs that should be in the view. */
documentSet: DocumentSet;
/** The diff of these docs with the previous set of docs. */
changeSet: DocumentChangeSet;
/**
* Whether the set of documents passed in was not sufficient to calculate the
* new state of the view and there needs to be another pass based on the
* local cache.
*/
needsRefill: boolean;
mutatedKeys: DocumentKeySet;
}
export interface ViewChange {
snapshot?: ViewSnapshot;
limboChanges: LimboDocumentChange[];
}
/**
* View is responsible for computing the final merged truth of what docs are in
* a query. It gets notified of local and remote changes to docs, and applies
* the query filters and limits to determine the most correct possible results.
*/
export declare class View {
private query;
/** Documents included in the remote target */
private _syncedDocuments;
private syncState;
private hasCachedResults;
/**
* A flag whether the view is current with the backend. A view is considered
* current after it has seen the current flag from the backend and did not
* lose consistency within the watch stream (e.g. because of an existence
* filter mismatch).
*/
private current;
private documentSet;
/** Documents in the view but not in the remote target */
private limboDocuments;
/** Document Keys that have local changes */
private mutatedKeys;
/** Query comparator that defines the document order in this view. */
private docComparator;
constructor(query: Query,
/** Documents included in the remote target */
_syncedDocuments: DocumentKeySet);
/**
* The set of remote documents that the server has told us belongs to the target associated with
* this view.
*/
get syncedDocuments(): DocumentKeySet;
/**
* Iterates over a set of doc changes, applies the query limit, and computes
* what the new results should be, what the changes were, and whether we may
* need to go back to the local cache for more results. Does not make any
* changes to the view.
* @param docChanges - The doc changes to apply to this view.
* @param previousChanges - If this is being called with a refill, then start
* with this set of docs and changes instead of the current view.
* @returns a new set of docs, changes, and refill flag.
*/
computeDocChanges(docChanges: DocumentMap, previousChanges?: ViewDocumentChanges): ViewDocumentChanges;
private shouldWaitForSyncedDocument;
/**
* Updates the view with the given ViewDocumentChanges and optionally updates
* limbo docs and sync state from the provided target change.
* @param docChanges - The set of changes to make to the view's docs.
* @param limboResolutionEnabled - Whether to update limbo documents based on
* this change.
* @param targetChange - A target change to apply for computing limbo docs and
* sync state.
* @param targetIsPendingReset - Whether the target is pending to reset due to
* existence filter mismatch. If not explicitly specified, it is treated
* equivalently to `false`.
* @returns A new ViewChange with the given docs, changes, and sync state.
*/
applyChanges(docChanges: ViewDocumentChanges, limboResolutionEnabled: boolean, targetChange?: TargetChange, targetIsPendingReset?: boolean): ViewChange;
/**
* Applies an OnlineState change to the view, potentially generating a
* ViewChange if the view's syncState changes as a result.
*/
applyOnlineStateChange(onlineState: OnlineState): ViewChange;
/**
* Returns whether the doc for the given key should be in limbo.
*/
private shouldBeInLimbo;
/**
* Updates syncedDocuments, current, and limbo docs based on the given change.
* Returns the list of changes to which docs are in limbo.
*/
private applyTargetChange;
private updateLimboDocuments;
/**
* Update the in-memory state of the current view with the state read from
* persistence.
*
* We update the query view whenever a client's primary status changes:
* - When a client transitions from primary to secondary, it can miss
* LocalStorage updates and its query views may temporarily not be
* synchronized with the state on disk.
* - For secondary to primary transitions, the client needs to update the list
* of `syncedDocuments` since secondary clients update their query views
* based purely on synthesized RemoteEvents.
*
* @param queryResult.documents - The documents that match the query according
* to the LocalStore.
* @param queryResult.remoteKeys - The keys of the documents that match the
* query according to the backend.
*
* @returns The ViewChange that resulted from this synchronization.
*/
synchronizeWithPersistedState(queryResult: QueryResult): ViewChange;
/**
* Returns a view snapshot as if this query was just listened to. Contains
* a document add for every existing document and the `fromCache` and
* `hasPendingWrites` status of the already established view.
*/
computeInitialSnapshot(): ViewSnapshot;
}

View file

@ -0,0 +1,59 @@
/**
* @license
* Copyright 2017 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 { DocumentKeySet } from '../model/collections';
import { Document } from '../model/document';
import { DocumentSet } from '../model/document_set';
import { Query } from './query';
export declare const enum ChangeType {
Added = 0,
Removed = 1,
Modified = 2,
Metadata = 3
}
export interface DocumentViewChange {
type: ChangeType;
doc: Document;
}
export declare const enum SyncState {
Local = 0,
Synced = 1
}
/**
* DocumentChangeSet keeps track of a set of changes to docs in a query, merging
* duplicate events for the same doc.
*/
export declare class DocumentChangeSet {
private changeMap;
track(change: DocumentViewChange): void;
getChanges(): DocumentViewChange[];
}
export declare class ViewSnapshot {
readonly query: Query;
readonly docs: DocumentSet;
readonly oldDocs: DocumentSet;
readonly docChanges: DocumentViewChange[];
readonly mutatedKeys: DocumentKeySet;
readonly fromCache: boolean;
readonly syncStateChanged: boolean;
readonly excludesMetadataChanges: boolean;
readonly hasCachedResults: boolean;
constructor(query: Query, docs: DocumentSet, oldDocs: DocumentSet, docChanges: DocumentViewChange[], mutatedKeys: DocumentKeySet, fromCache: boolean, syncStateChanged: boolean, excludesMetadataChanges: boolean, hasCachedResults: boolean);
/** Returns a view snapshot as if all documents in the snapshot were added. */
static fromInitialDocuments(query: Query, documents: DocumentSet, mutatedKeys: DocumentKeySet, fromCache: boolean, hasCachedResults: boolean): ViewSnapshot;
get hasPendingWrites(): boolean;
isEqual(other: ViewSnapshot): boolean;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,28 @@
/**
* Cloud Firestore
*
* @packageDocumentation
*/
/**
* @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 './api/database';
export * from './api';
declare module '@firebase/component' {
interface NameServiceMapping {
'firestore': Firestore;
}
}

View file

@ -0,0 +1,17 @@
/**
* @license
* Copyright 2021 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.
*/
export * from './api';

View file

@ -0,0 +1,17 @@
/**
* @license
* Copyright 2021 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.
*/
export * from './api';

View file

@ -0,0 +1,24 @@
/**
* @license
* Copyright 2021 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 { ByteString } from '../util/byte_string';
/** An index value encoder. */
export interface DirectionalIndexByteEncoder {
writeBytes(value: ByteString): void;
writeString(value: string): void;
writeNumber(value: number): void;
writeInfinity(): void;
}

View file

@ -0,0 +1,34 @@
/**
* @license
* Copyright 2021 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 { Value } from '../protos/firestore_proto_api';
import { DirectionalIndexByteEncoder } from './directional_index_byte_encoder';
/** Firestore index value writer. */
export declare class FirestoreIndexValueWriter {
static INSTANCE: FirestoreIndexValueWriter;
private constructor();
/** Writes an index value. */
writeIndexValue(value: Value, encoder: DirectionalIndexByteEncoder): void;
private writeIndexValueAux;
private writeIndexString;
private writeUnlabeledIndexString;
private writeIndexMap;
private writeIndexVector;
private writeIndexArray;
private writeIndexEntityRef;
private writeValueTypeLabel;
private writeTruncationMarker;
}

View file

@ -0,0 +1,31 @@
/**
* @license
* Copyright 2021 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 { IndexKind } from '../model/field_index';
import { DirectionalIndexByteEncoder } from './directional_index_byte_encoder';
/**
* Implements `DirectionalIndexByteEncoder` using `OrderedCodeWriter` for the
* actual encoding.
*/
export declare class IndexByteEncoder {
private orderedCode;
private ascending;
private descending;
seed(encodedBytes: Uint8Array): void;
forKind(kind: IndexKind): DirectionalIndexByteEncoder;
encodedBytes(): Uint8Array;
reset(): void;
}

View file

@ -0,0 +1,32 @@
/**
* @license
* Copyright 2022 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 { DocumentKey } from '../model/document_key';
/** Represents an index entry saved by the SDK in persisted storage. */
export declare class IndexEntry {
readonly indexId: number;
readonly documentKey: DocumentKey;
readonly arrayValue: Uint8Array;
readonly directionalValue: Uint8Array;
constructor(indexId: number, documentKey: DocumentKey, arrayValue: Uint8Array, directionalValue: Uint8Array);
/**
* Returns an IndexEntry entry that sorts immediately after the current
* directional value.
*/
successor(): IndexEntry;
}
export declare function indexEntryComparator(left: IndexEntry, right: IndexEntry): number;
export declare function compareByteArrays(left: Uint8Array, right: Uint8Array): number;

View file

@ -0,0 +1,60 @@
import { ByteString } from '../util/byte_string';
/**
* Counts the number of zeros in a byte.
*
* Visible for testing.
*/
export declare function numberOfLeadingZerosInByte(x: number): number;
/**
* OrderedCodeWriter is a minimal-allocation implementation of the writing
* behavior defined by the backend.
*
* The code is ported from its Java counterpart.
*/
export declare class OrderedCodeWriter {
buffer: Uint8Array;
position: number;
writeBytesAscending(value: ByteString): void;
writeBytesDescending(value: ByteString): void;
/** Writes utf8 bytes into this byte sequence, ascending. */
writeUtf8Ascending(sequence: string): void;
/** Writes utf8 bytes into this byte sequence, descending */
writeUtf8Descending(sequence: string): void;
writeNumberAscending(val: number): void;
writeNumberDescending(val: number): void;
/**
* Writes the "infinity" byte sequence that sorts after all other byte
* sequences written in ascending order.
*/
writeInfinityAscending(): void;
/**
* Writes the "infinity" byte sequence that sorts before all other byte
* sequences written in descending order.
*/
writeInfinityDescending(): void;
/**
* Resets the buffer such that it is the same as when it was newly
* constructed.
*/
reset(): void;
seed(encodedBytes: Uint8Array): void;
/** Makes a copy of the encoded bytes in this buffer. */
encodedBytes(): Uint8Array;
/**
* Encodes `val` into an encoding so that the order matches the IEEE 754
* floating-point comparison results with the following exceptions:
* -0.0 < 0.0
* all non-NaN < NaN
* NaN = NaN
*/
private toOrderedBits;
/** Writes a single byte ascending to the buffer. */
private writeByteAscending;
/** Writes a single byte descending to the buffer. */
private writeByteDescending;
private writeSeparatorAscending;
private writeSeparatorDescending;
private writeEscapedByteAscending;
private writeEscapedByteDescending;
private ensureAvailable;
}

View file

@ -0,0 +1,100 @@
/**
* @license
* Copyright 2022 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 { AggregateField, AggregateQuerySnapshot, AggregateSpec } from './aggregate_types';
import { FieldPath } from './field_path';
import { DocumentData, Query } from './reference';
/**
* Calculates the number of documents in the result set of the given query
* without actually downloading the documents.
*
* Using this function to count the documents is efficient because only the
* final count, not the documents' data, is downloaded. This function can
* count the documents in cases where the result set is prohibitively large to
* download entirely (thousands of documents).
*
* @param query The query whose result set size is calculated.
* @returns A Promise that will be resolved with the count; the count can be
* retrieved from `snapshot.data().count`, where `snapshot` is the
* `AggregateQuerySnapshot` to which the returned Promise resolves.
*/
export declare function getCount<AppModelType, DbModelType extends DocumentData>(query: Query<AppModelType, DbModelType>): Promise<AggregateQuerySnapshot<{
count: AggregateField<number>;
}, AppModelType, DbModelType>>;
/**
* Calculates the specified aggregations over the documents in the result
* set of the given query without actually downloading the documents.
*
* Using this function to perform aggregations is efficient because only the
* final aggregation values, not the documents' data, are downloaded. This
* function can perform aggregations of the documents in cases where the result
* set is prohibitively large to download entirely (thousands of documents).
*
* @param query The query whose result set is aggregated over.
* @param aggregateSpec An `AggregateSpec` object that specifies the aggregates
* to perform over the result set. The AggregateSpec specifies aliases for each
* aggregate, which can be used to retrieve the aggregate result.
* @example
* ```typescript
* const aggregateSnapshot = await getAggregate(query, {
* countOfDocs: count(),
* totalHours: sum('hours'),
* averageScore: average('score')
* });
*
* const countOfDocs: number = aggregateSnapshot.data().countOfDocs;
* const totalHours: number = aggregateSnapshot.data().totalHours;
* const averageScore: number | null = aggregateSnapshot.data().averageScore;
* ```
*/
export declare function getAggregate<AggregateSpecType extends AggregateSpec, AppModelType, DbModelType extends DocumentData>(query: Query<AppModelType, DbModelType>, aggregateSpec: AggregateSpecType): Promise<AggregateQuerySnapshot<AggregateSpecType, AppModelType, DbModelType>>;
/**
* Create an AggregateField object that can be used to compute the sum of
* a specified field over a range of documents in the result set of a query.
* @param field Specifies the field to sum across the result set.
*/
export declare function sum(field: string | FieldPath): AggregateField<number>;
/**
* Create an AggregateField object that can be used to compute the average of
* a specified field over a range of documents in the result set of a query.
* @param field Specifies the field to average across the result set.
*/
export declare function average(field: string | FieldPath): AggregateField<number | null>;
/**
* Create an AggregateField object that can be used to compute the count of
* documents in the result set of a query.
*/
export declare function count(): AggregateField<number>;
/**
* Compares two 'AggregateField` instances for equality.
*
* @param left Compare this AggregateField to the `right`.
* @param right Compare this AggregateField to the `left`.
*/
export declare function aggregateFieldEqual(left: AggregateField<unknown>, right: AggregateField<unknown>): boolean;
/**
* Compares two `AggregateQuerySnapshot` instances for equality.
*
* Two `AggregateQuerySnapshot` instances are considered "equal" if they have
* underlying queries that compare equal, and the same data.
*
* @param left - The first `AggregateQuerySnapshot` to compare.
* @param right - The second `AggregateQuerySnapshot` to compare.
*
* @returns `true` if the objects are "equal", as defined above, or `false`
* otherwise.
*/
export declare function aggregateQuerySnapshotEqual<AggregateSpecType extends AggregateSpec, AppModelType, DbModelType extends DocumentData>(left: AggregateQuerySnapshot<AggregateSpecType, AppModelType, DbModelType>, right: AggregateQuerySnapshot<AggregateSpecType, AppModelType, DbModelType>): boolean;

View file

@ -0,0 +1,86 @@
/**
* @license
* Copyright 2022 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 { AggregateType } from '../core/aggregate';
import { FieldPath as InternalFieldPath } from '../model/path';
import { ApiClientObjectMap, Value } from '../protos/firestore_proto_api';
import { average, count, sum } from './aggregate';
import { DocumentData, Query } from './reference';
import { AbstractUserDataWriter } from './user_data_writer';
export { AggregateType };
/**
* Represents an aggregation that can be performed by Firestore.
*/
export declare class AggregateField<T> {
readonly _internalFieldPath?: InternalFieldPath | undefined;
/** A type string to uniquely identify instances of this class. */
readonly type = "AggregateField";
/** Indicates the aggregation operation of this AggregateField. */
readonly aggregateType: AggregateType;
/**
* Create a new AggregateField<T>
* @param aggregateType Specifies the type of aggregation operation to perform.
* @param _internalFieldPath Optionally specifies the field that is aggregated.
* @internal
*/
constructor(aggregateType?: AggregateType, _internalFieldPath?: InternalFieldPath | undefined);
}
/**
* The union of all `AggregateField` types that are supported by Firestore.
*/
export declare type AggregateFieldType = ReturnType<typeof sum> | ReturnType<typeof average> | ReturnType<typeof count>;
/**
* Specifies a set of aggregations and their aliases.
*/
export interface AggregateSpec {
[field: string]: AggregateFieldType;
}
/**
* A type whose keys are taken from an `AggregateSpec`, and whose values are the
* result of the aggregation performed by the corresponding `AggregateField`
* from the input `AggregateSpec`.
*/
export declare type AggregateSpecData<T extends AggregateSpec> = {
[P in keyof T]: T[P] extends AggregateField<infer U> ? U : never;
};
/**
* The results of executing an aggregation query.
*/
export declare class AggregateQuerySnapshot<AggregateSpecType extends AggregateSpec, AppModelType = DocumentData, DbModelType extends DocumentData = DocumentData> {
private readonly _userDataWriter;
private readonly _data;
/** A type string to uniquely identify instances of this class. */
readonly type = "AggregateQuerySnapshot";
/**
* The underlying query over which the aggregations recorded in this
* `AggregateQuerySnapshot` were performed.
*/
readonly query: Query<AppModelType, DbModelType>;
/** @hideconstructor */
constructor(query: Query<AppModelType, DbModelType>, _userDataWriter: AbstractUserDataWriter, _data: ApiClientObjectMap<Value>);
/**
* Returns the results of the aggregations performed over the underlying
* query.
*
* The keys of the returned object will be the same as those of the
* `AggregateSpec` object specified to the aggregation method, and the values
* will be the corresponding aggregation result.
*
* @returns The results of the aggregations performed over the underlying
* query.
*/
data(): AggregateSpecData<AggregateSpecType>;
}

View file

@ -0,0 +1,63 @@
/**
* @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 { ByteString } from '../util/byte_string';
/**
* An immutable object representing an array of bytes.
*/
export declare class Bytes {
_byteString: ByteString;
/** @hideconstructor */
constructor(byteString: ByteString);
/**
* Creates a new `Bytes` object from the given Base64 string, converting it to
* bytes.
*
* @param base64 - The Base64 string used to create the `Bytes` object.
*/
static fromBase64String(base64: string): Bytes;
/**
* Creates a new `Bytes` object from the given Uint8Array.
*
* @param array - The Uint8Array used to create the `Bytes` object.
*/
static fromUint8Array(array: Uint8Array): Bytes;
/**
* Returns the underlying bytes as a Base64-encoded string.
*
* @returns The Base64-encoded string created from the `Bytes` object.
*/
toBase64(): string;
/**
* Returns the underlying bytes in a new `Uint8Array`.
*
* @returns The Uint8Array created from the `Bytes` object.
*/
toUint8Array(): Uint8Array;
/**
* Returns a string representation of the `Bytes` object.
*
* @returns A string representation of the `Bytes` object.
*/
toString(): string;
/**
* Returns true if this `Bytes` object is equal to the provided one.
*
* @param other - The `Bytes` object to compare against.
* @returns true if this `Bytes` object is equal to the provided one.
*/
isEqual(other: Bytes): boolean;
}

View file

@ -0,0 +1,49 @@
/**
* @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 { _FirebaseService } from '@firebase/app';
import { CredentialsProvider } from '../api/credentials';
import { User } from '../auth/user';
import { DatabaseId, DatabaseInfo } from '../core/database_info';
import { Datastore } from '../remote/datastore';
import { FirestoreSettingsImpl } from './settings';
export declare const LOG_TAG = "ComponentProvider";
/**
* An interface implemented by FirebaseFirestore that provides compatibility
* with the usage in this file.
*
* This interface mainly exists to remove a cyclic dependency.
*/
export interface FirestoreService extends _FirebaseService {
_authCredentials: CredentialsProvider<User>;
_appCheckCredentials: CredentialsProvider<string>;
_persistenceKey: string;
_databaseId: DatabaseId;
_terminated: boolean;
_freezeSettings(): FirestoreSettingsImpl;
}
/**
* Returns an initialized and started Datastore for the given Firestore
* instance. Callers must invoke removeComponents() when the Firestore
* instance is terminated.
*/
export declare function getDatastore(firestore: FirestoreService): Datastore;
/**
* Removes all components associated with the provided instance. Must be called
* when the `Firestore` instance is terminated.
*/
export declare function removeComponents(firestore: FirestoreService): void;
export declare function makeDatabaseInfo(databaseId: DatabaseId, appId: string, persistenceKey: string, settings: FirestoreSettingsImpl): DatabaseInfo;

View file

@ -0,0 +1,175 @@
/**
* @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 { FirebaseApp } from '@firebase/app';
import { EmulatorMockTokenOptions } from '@firebase/util';
import { CredentialsProvider } from '../api/credentials';
import { User } from '../auth/user';
import { DatabaseId } from '../core/database_info';
import { FirestoreService } from './components';
import { FirestoreSettingsImpl, PrivateSettings, FirestoreSettings } from './settings';
export { EmulatorMockTokenOptions } from '@firebase/util';
declare module '@firebase/component' {
interface NameServiceMapping {
'firestore/lite': Firestore;
}
}
/**
* The Cloud Firestore service interface.
*
* Do not call this constructor directly. Instead, use {@link (getFirestore:1)}.
*/
export declare class Firestore implements FirestoreService {
_authCredentials: CredentialsProvider<User>;
_appCheckCredentials: CredentialsProvider<string>;
readonly _databaseId: DatabaseId;
readonly _app?: FirebaseApp | undefined;
/**
* Whether it's a Firestore or Firestore Lite instance.
*/
type: 'firestore-lite' | 'firestore';
readonly _persistenceKey: string;
private _settings;
private _settingsFrozen;
private _terminateTask;
/** @hideconstructor */
constructor(_authCredentials: CredentialsProvider<User>, _appCheckCredentials: CredentialsProvider<string>, _databaseId: DatabaseId, _app?: FirebaseApp | undefined);
/**
* The {@link @firebase/app#FirebaseApp} associated with this `Firestore` service
* instance.
*/
get app(): FirebaseApp;
get _initialized(): boolean;
get _terminated(): boolean;
_setSettings(settings: PrivateSettings): void;
_getSettings(): FirestoreSettingsImpl;
_freezeSettings(): FirestoreSettingsImpl;
_delete(): Promise<void>;
_restart(): Promise<void>;
/** Returns a JSON-serializable representation of this `Firestore` instance. */
toJSON(): object;
/**
* Terminates all components used by this client. Subclasses can override
* this method to clean up their own dependencies, but must also call this
* method.
*
* Only ever called once.
*/
protected _terminate(): Promise<void>;
}
/**
* Initializes a new instance of Cloud Firestore with the provided settings.
* Can only be called before any other functions, including
* {@link (getFirestore:1)}. If the custom settings are empty, this function is
* equivalent to calling {@link (getFirestore:1)}.
*
* @param app - The {@link @firebase/app#FirebaseApp} with which the `Firestore` instance will
* be associated.
* @param settings - A settings object to configure the `Firestore` instance.
* @returns A newly initialized `Firestore` instance.
*/
export declare function initializeFirestore(app: FirebaseApp, settings: FirestoreSettings): Firestore;
/**
* Initializes a new instance of Cloud Firestore with the provided settings.
* Can only be called before any other functions, including
* {@link (getFirestore:1)}. If the custom settings are empty, this function is
* equivalent to calling {@link (getFirestore:1)}.
*
* @param app - The {@link @firebase/app#FirebaseApp} with which the `Firestore` instance will
* be associated.
* @param settings - A settings object to configure the `Firestore` instance.
* @param databaseId - The name of the database.
* @returns A newly initialized `Firestore` instance.
* @beta
*/
export declare function initializeFirestore(app: FirebaseApp, settings: FirestoreSettings, databaseId?: string): Firestore;
/**
* Returns the existing default {@link Firestore} instance that is associated with the
* default {@link @firebase/app#FirebaseApp}. If no instance exists, initializes a new
* instance with default settings.
*
* @returns The {@link Firestore} instance of the provided app.
*/
export declare function getFirestore(): Firestore;
/**
* Returns the existing default {@link Firestore} instance that is associated with the
* provided {@link @firebase/app#FirebaseApp}. If no instance exists, initializes a new
* instance with default settings.
*
* @param app - The {@link @firebase/app#FirebaseApp} instance that the returned {@link Firestore}
* instance is associated with.
* @returns The {@link Firestore} instance of the provided app.
*/
export declare function getFirestore(app: FirebaseApp): Firestore;
/**
* Returns the existing {@link Firestore} instance that is associated with the
* default {@link @firebase/app#FirebaseApp}. If no instance exists, initializes a new
* instance with default settings.
*
* @param databaseId - The name of the database.
* @returns The {@link Firestore} instance of the provided app.
* @beta
*/
export declare function getFirestore(databaseId: string): Firestore;
/**
* Returns the existing {@link Firestore} instance that is associated with the
* provided {@link @firebase/app#FirebaseApp}. If no instance exists, initializes a new
* instance with default settings.
*
* @param app - The {@link @firebase/app#FirebaseApp} instance that the returned {@link Firestore}
* instance is associated with.
* @param databaseId - The name of the database.
* @returns The {@link Firestore} instance of the provided app.
* @beta
*/
export declare function getFirestore(app: FirebaseApp, databaseId: string): Firestore;
/**
* Modify this instance to communicate with the Cloud Firestore emulator.
*
* Note: This must be called before this instance has been used to do any
* operations.
*
* @param firestore - The `Firestore` instance to configure to connect to the
* emulator.
* @param host - the emulator host (ex: localhost).
* @param port - the emulator port (ex: 9000).
* @param options.mockUserToken - the mock auth token to use for unit testing
* Security Rules.
*/
export declare function connectFirestoreEmulator(firestore: Firestore, host: string, port: number, options?: {
mockUserToken?: EmulatorMockTokenOptions | string;
}): void;
/**
* Terminates the provided `Firestore` instance.
*
* After calling `terminate()` only the `clearIndexedDbPersistence()` functions
* may be used. Any other function will throw a `FirestoreError`. Termination
* does not cancel any pending writes, and any promises that are awaiting a
* response from the server will not be resolved.
*
* To restart after termination, create a new instance of `Firestore` with
* {@link (getFirestore:1)}.
*
* Note: Under normal circumstances, calling `terminate()` is not required. This
* function is useful only when you want to force this instance to release all of
* its resources or in combination with {@link clearIndexedDbPersistence} to
* ensure that all local state is destroyed between test runs.
*
* @param firestore - The `Firestore` instance to terminate.
* @returns A `Promise` that is resolved when the instance has been successfully
* terminated.
*/
export declare function terminate(firestore: Firestore): Promise<void>;

View file

@ -0,0 +1,48 @@
/**
* @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 { FieldPath as InternalFieldPath } from '../model/path';
/**
* A `FieldPath` refers to a field in a document. The path may consist of a
* single field name (referring to a top-level field in the document), or a
* list of field names (referring to a nested field in the document).
*
* Create a `FieldPath` by providing field names. If more than one field
* name is provided, the path will point to a nested field in a document.
*/
export declare class FieldPath {
/** Internal representation of a Firestore field path. */
readonly _internalPath: InternalFieldPath;
/**
* Creates a `FieldPath` from the provided field names. If more than one field
* name is provided, the path will point to a nested field in a document.
*
* @param fieldNames - A list of field names.
*/
constructor(...fieldNames: string[]);
/**
* Returns true if this `FieldPath` is equal to the provided one.
*
* @param other - The `FieldPath` to compare against.
* @returns true if this `FieldPath` is equal to the provided one.
*/
isEqual(other: FieldPath): boolean;
}
/**
* Returns a special sentinel `FieldPath` to refer to the ID of a document.
* It can be used in queries to sort or filter by the document ID.
*/
export declare function documentId(): FieldPath;

View file

@ -0,0 +1,33 @@
/**
* @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 { ParseContext } from '../api/parse_context';
import { FieldTransform } from '../model/mutation';
/**
* Sentinel values that can be used when writing document fields with `set()`
* or `update()`.
*/
export declare abstract class FieldValue {
_methodName: string;
/**
* @param _methodName - The public API endpoint that returns this class.
* @hideconstructor
*/
constructor(_methodName: string);
/** Compares `FieldValue`s for equality. */
abstract isEqual(other: FieldValue): boolean;
abstract _toFieldTransform(context: ParseContext): FieldTransform | null;
}

View file

@ -0,0 +1,81 @@
/**
* @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 { FieldValue } from './field_value';
import { VectorValue } from './vector_value';
/**
* Returns a sentinel for use with {@link @firebase/firestore/lite#(updateDoc:1)} or
* {@link @firebase/firestore/lite#(setDoc:1)} with `{merge: true}` to mark a field for deletion.
*/
export declare function deleteField(): FieldValue;
/**
* Returns a sentinel used with {@link @firebase/firestore/lite#(setDoc:1)} or {@link @firebase/firestore/lite#(updateDoc:1)} to
* include a server-generated timestamp in the written data.
*/
export declare function serverTimestamp(): FieldValue;
/**
* Returns a special value that can be used with {@link @firebase/firestore/lite#(setDoc:1)} or {@link
* @firebase/firestore/lite#(updateDoc:1)} that tells the server to union the given elements with any array
* value that already exists on the server. Each specified element that doesn't
* already exist in the array will be added to the end. If the field being
* modified is not already an array it will be overwritten with an array
* containing exactly the specified elements.
*
* @param elements - The elements to union into the array.
* @returns The `FieldValue` sentinel for use in a call to `setDoc()` or
* `updateDoc()`.
*/
export declare function arrayUnion(...elements: unknown[]): FieldValue;
/**
* Returns a special value that can be used with {@link (setDoc:1)} or {@link
* updateDoc:1} that tells the server to remove the given elements from any
* array value that already exists on the server. All instances of each element
* specified will be removed from the array. If the field being modified is not
* already an array it will be overwritten with an empty array.
*
* @param elements - The elements to remove from the array.
* @returns The `FieldValue` sentinel for use in a call to `setDoc()` or
* `updateDoc()`
*/
export declare function arrayRemove(...elements: unknown[]): FieldValue;
/**
* Returns a special value that can be used with {@link @firebase/firestore/lite#(setDoc:1)} or {@link
* @firebase/firestore/lite#(updateDoc:1)} that tells the server to increment the field's current value by
* the given value.
*
* If either the operand or the current field value uses floating point
* precision, all arithmetic follows IEEE 754 semantics. If both values are
* integers, values outside of JavaScript's safe number range
* (`Number.MIN_SAFE_INTEGER` to `Number.MAX_SAFE_INTEGER`) are also subject to
* precision loss. Furthermore, once processed by the Firestore backend, all
* integer operations are capped between -2^63 and 2^63-1.
*
* If the current field value is not of type `number`, or if the field does not
* yet exist, the transformation sets the field to the given value.
*
* @param n - The value to increment by.
* @returns The `FieldValue` sentinel for use in a call to `setDoc()` or
* `updateDoc()`
*/
export declare function increment(n: number): FieldValue;
/**
* Creates a new `VectorValue` constructed with a copy of the given array of numbers.
*
* @param values - Create a `VectorValue` instance with a copy of this array of numbers.
*
* @returns A new `VectorValue` constructed with a copy of the given array of numbers.
*/
export declare function vector(values?: number[]): VectorValue;

View file

@ -0,0 +1,59 @@
/**
* @license
* Copyright 2017 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.
*/
/**
* An immutable object representing a geographic location in Firestore. The
* location is represented as latitude/longitude pair.
*
* Latitude values are in the range of [-90, 90].
* Longitude values are in the range of [-180, 180].
*/
export declare class GeoPoint {
private _lat;
private _long;
/**
* Creates a new immutable `GeoPoint` object with the provided latitude and
* longitude values.
* @param latitude - The latitude as number between -90 and 90.
* @param longitude - The longitude as number between -180 and 180.
*/
constructor(latitude: number, longitude: number);
/**
* The latitude of this `GeoPoint` instance.
*/
get latitude(): number;
/**
* The longitude of this `GeoPoint` instance.
*/
get longitude(): number;
/**
* Returns true if this `GeoPoint` is equal to the provided one.
*
* @param other - The `GeoPoint` to compare against.
* @returns true if this `GeoPoint` is equal to the provided one.
*/
isEqual(other: GeoPoint): boolean;
/** Returns a JSON-serializable representation of this GeoPoint. */
toJSON(): {
latitude: number;
longitude: number;
};
/**
* Actually private to JS consumers of our API, so this function is prefixed
* with an underscore.
*/
_compareTo(other: GeoPoint): number;
}

View file

@ -0,0 +1,404 @@
/**
* @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 { Bound } from '../core/bound';
import { DatabaseId } from '../core/database_info';
import { CompositeOperator, FieldFilter, Filter, Operator } from '../core/filter';
import { Direction, OrderBy } from '../core/order_by';
import { LimitType, Query as InternalQuery } from '../core/query';
import { Document } from '../model/document';
import { FieldPath as InternalFieldPath } from '../model/path';
import { FieldPath } from './field_path';
import { DocumentData, Query } from './reference';
import { DocumentSnapshot } from './snapshot';
import { UserDataReader } from './user_data_reader';
export declare function validateHasExplicitOrderByForLimitToLast(query: InternalQuery): void;
/** Describes the different query constraints available in this SDK. */
export declare type QueryConstraintType = 'where' | 'orderBy' | 'limit' | 'limitToLast' | 'startAt' | 'startAfter' | 'endAt' | 'endBefore';
/**
* An `AppliableConstraint` is an abstraction of a constraint that can be applied
* to a Firestore query.
*/
export declare abstract class AppliableConstraint {
/**
* Takes the provided {@link Query} and returns a copy of the {@link Query} with this
* {@link AppliableConstraint} applied.
*/
abstract _apply<AppModelType, DbModelType extends DocumentData>(query: Query<AppModelType, DbModelType>): Query<AppModelType, DbModelType>;
}
/**
* A `QueryConstraint` is used to narrow the set of documents returned by a
* Firestore query. `QueryConstraint`s are created by invoking {@link where},
* {@link orderBy}, {@link (startAt:1)}, {@link (startAfter:1)}, {@link
* (endBefore:1)}, {@link (endAt:1)}, {@link limit}, {@link limitToLast} and
* can then be passed to {@link (query:1)} to create a new query instance that
* also contains this `QueryConstraint`.
*/
export declare abstract class QueryConstraint extends AppliableConstraint {
/** The type of this query constraint */
abstract readonly type: QueryConstraintType;
/**
* Takes the provided {@link Query} and returns a copy of the {@link Query} with this
* {@link AppliableConstraint} applied.
*/
abstract _apply<AppModelType, DbModelType extends DocumentData>(query: Query<AppModelType, DbModelType>): Query<AppModelType, DbModelType>;
}
/**
* Creates a new immutable instance of {@link Query} that is extended to also
* include additional query constraints.
*
* @param query - The {@link Query} instance to use as a base for the new
* constraints.
* @param compositeFilter - The {@link QueryCompositeFilterConstraint} to
* apply. Create {@link QueryCompositeFilterConstraint} using {@link and} or
* {@link or}.
* @param queryConstraints - Additional {@link QueryNonFilterConstraint}s to
* apply (e.g. {@link orderBy}, {@link limit}).
* @throws if any of the provided query constraints cannot be combined with the
* existing or new constraints.
*/
export declare function query<AppModelType, DbModelType extends DocumentData>(query: Query<AppModelType, DbModelType>, compositeFilter: QueryCompositeFilterConstraint, ...queryConstraints: QueryNonFilterConstraint[]): Query<AppModelType, DbModelType>;
/**
* Creates a new immutable instance of {@link Query} that is extended to also
* include additional query constraints.
*
* @param query - The {@link Query} instance to use as a base for the new
* constraints.
* @param queryConstraints - The list of {@link QueryConstraint}s to apply.
* @throws if any of the provided query constraints cannot be combined with the
* existing or new constraints.
*/
export declare function query<AppModelType, DbModelType extends DocumentData>(query: Query<AppModelType, DbModelType>, ...queryConstraints: QueryConstraint[]): Query<AppModelType, DbModelType>;
/**
* A `QueryFieldFilterConstraint` is used to narrow the set of documents returned by
* a Firestore query by filtering on one or more document fields.
* `QueryFieldFilterConstraint`s are created by invoking {@link where} and can then
* be passed to {@link (query:1)} to create a new query instance that also contains
* this `QueryFieldFilterConstraint`.
*/
export declare class QueryFieldFilterConstraint extends QueryConstraint {
private readonly _field;
private _op;
private _value;
/** The type of this query constraint */
readonly type = "where";
/**
* @internal
*/
protected constructor(_field: InternalFieldPath, _op: Operator, _value: unknown);
static _create(_field: InternalFieldPath, _op: Operator, _value: unknown): QueryFieldFilterConstraint;
_apply<AppModelType, DbModelType extends DocumentData>(query: Query<AppModelType, DbModelType>): Query<AppModelType, DbModelType>;
_parse<AppModelType, DbModelType extends DocumentData>(query: Query<AppModelType, DbModelType>): FieldFilter;
}
/**
* Filter conditions in a {@link where} clause are specified using the
* strings '&lt;', '&lt;=', '==', '!=', '&gt;=', '&gt;', 'array-contains', 'in',
* 'array-contains-any', and 'not-in'.
*/
export declare type WhereFilterOp = '<' | '<=' | '==' | '!=' | '>=' | '>' | 'array-contains' | 'in' | 'array-contains-any' | 'not-in';
/**
* Creates a {@link QueryFieldFilterConstraint} that enforces that documents
* must contain the specified field and that the value should satisfy the
* relation constraint provided.
*
* @param fieldPath - The path to compare
* @param opStr - The operation string (e.g "&lt;", "&lt;=", "==", "&lt;",
* "&lt;=", "!=").
* @param value - The value for comparison
* @returns The created {@link QueryFieldFilterConstraint}.
*/
export declare function where(fieldPath: string | FieldPath, opStr: WhereFilterOp, value: unknown): QueryFieldFilterConstraint;
/**
* A `QueryCompositeFilterConstraint` is used to narrow the set of documents
* returned by a Firestore query by performing the logical OR or AND of multiple
* {@link QueryFieldFilterConstraint}s or {@link QueryCompositeFilterConstraint}s.
* `QueryCompositeFilterConstraint`s are created by invoking {@link or} or
* {@link and} and can then be passed to {@link (query:1)} to create a new query
* instance that also contains the `QueryCompositeFilterConstraint`.
*/
export declare class QueryCompositeFilterConstraint extends AppliableConstraint {
/** The type of this query constraint */
readonly type: 'or' | 'and';
private readonly _queryConstraints;
/**
* @internal
*/
protected constructor(
/** The type of this query constraint */
type: 'or' | 'and', _queryConstraints: QueryFilterConstraint[]);
static _create(type: 'or' | 'and', _queryConstraints: QueryFilterConstraint[]): QueryCompositeFilterConstraint;
_parse<AppModelType, DbModelType extends DocumentData>(query: Query<AppModelType, DbModelType>): Filter;
_apply<AppModelType, DbModelType extends DocumentData>(query: Query<AppModelType, DbModelType>): Query<AppModelType, DbModelType>;
_getQueryConstraints(): readonly AppliableConstraint[];
_getOperator(): CompositeOperator;
}
/**
* `QueryNonFilterConstraint` is a helper union type that represents
* QueryConstraints which are used to narrow or order the set of documents,
* but that do not explicitly filter on a document field.
* `QueryNonFilterConstraint`s are created by invoking {@link orderBy},
* {@link (startAt:1)}, {@link (startAfter:1)}, {@link (endBefore:1)}, {@link (endAt:1)},
* {@link limit} or {@link limitToLast} and can then be passed to {@link (query:1)}
* to create a new query instance that also contains the `QueryConstraint`.
*/
export declare type QueryNonFilterConstraint = QueryOrderByConstraint | QueryLimitConstraint | QueryStartAtConstraint | QueryEndAtConstraint;
/**
* `QueryFilterConstraint` is a helper union type that represents
* {@link QueryFieldFilterConstraint} and {@link QueryCompositeFilterConstraint}.
*/
export declare type QueryFilterConstraint = QueryFieldFilterConstraint | QueryCompositeFilterConstraint;
/**
* Creates a new {@link QueryCompositeFilterConstraint} that is a disjunction of
* the given filter constraints. A disjunction filter includes a document if it
* satisfies any of the given filters.
*
* @param queryConstraints - Optional. The list of
* {@link QueryFilterConstraint}s to perform a disjunction for. These must be
* created with calls to {@link where}, {@link or}, or {@link and}.
* @returns The newly created {@link QueryCompositeFilterConstraint}.
*/
export declare function or(...queryConstraints: QueryFilterConstraint[]): QueryCompositeFilterConstraint;
/**
* Creates a new {@link QueryCompositeFilterConstraint} that is a conjunction of
* the given filter constraints. A conjunction filter includes a document if it
* satisfies all of the given filters.
*
* @param queryConstraints - Optional. The list of
* {@link QueryFilterConstraint}s to perform a conjunction for. These must be
* created with calls to {@link where}, {@link or}, or {@link and}.
* @returns The newly created {@link QueryCompositeFilterConstraint}.
*/
export declare function and(...queryConstraints: QueryFilterConstraint[]): QueryCompositeFilterConstraint;
/**
* A `QueryOrderByConstraint` is used to sort the set of documents returned by a
* Firestore query. `QueryOrderByConstraint`s are created by invoking
* {@link orderBy} and can then be passed to {@link (query:1)} to create a new query
* instance that also contains this `QueryOrderByConstraint`.
*
* Note: Documents that do not contain the orderBy field will not be present in
* the query result.
*/
export declare class QueryOrderByConstraint extends QueryConstraint {
private readonly _field;
private _direction;
/** The type of this query constraint */
readonly type = "orderBy";
/**
* @internal
*/
protected constructor(_field: InternalFieldPath, _direction: Direction);
static _create(_field: InternalFieldPath, _direction: Direction): QueryOrderByConstraint;
_apply<AppModelType, DbModelType extends DocumentData>(query: Query<AppModelType, DbModelType>): Query<AppModelType, DbModelType>;
}
/**
* The direction of a {@link orderBy} clause is specified as 'desc' or 'asc'
* (descending or ascending).
*/
export declare type OrderByDirection = 'desc' | 'asc';
/**
* Creates a {@link QueryOrderByConstraint} that sorts the query result by the
* specified field, optionally in descending order instead of ascending.
*
* Note: Documents that do not contain the specified field will not be present
* in the query result.
*
* @param fieldPath - The field to sort by.
* @param directionStr - Optional direction to sort by ('asc' or 'desc'). If
* not specified, order will be ascending.
* @returns The created {@link QueryOrderByConstraint}.
*/
export declare function orderBy(fieldPath: string | FieldPath, directionStr?: OrderByDirection): QueryOrderByConstraint;
/**
* A `QueryLimitConstraint` is used to limit the number of documents returned by
* a Firestore query.
* `QueryLimitConstraint`s are created by invoking {@link limit} or
* {@link limitToLast} and can then be passed to {@link (query:1)} to create a new
* query instance that also contains this `QueryLimitConstraint`.
*/
export declare class QueryLimitConstraint extends QueryConstraint {
/** The type of this query constraint */
readonly type: 'limit' | 'limitToLast';
private readonly _limit;
private readonly _limitType;
/**
* @internal
*/
protected constructor(
/** The type of this query constraint */
type: 'limit' | 'limitToLast', _limit: number, _limitType: LimitType);
static _create(type: 'limit' | 'limitToLast', _limit: number, _limitType: LimitType): QueryLimitConstraint;
_apply<AppModelType, DbModelType extends DocumentData>(query: Query<AppModelType, DbModelType>): Query<AppModelType, DbModelType>;
}
/**
* Creates a {@link QueryLimitConstraint} that only returns the first matching
* documents.
*
* @param limit - The maximum number of items to return.
* @returns The created {@link QueryLimitConstraint}.
*/
export declare function limit(limit: number): QueryLimitConstraint;
/**
* Creates a {@link QueryLimitConstraint} that only returns the last matching
* documents.
*
* You must specify at least one `orderBy` clause for `limitToLast` queries,
* otherwise an exception will be thrown during execution.
*
* @param limit - The maximum number of items to return.
* @returns The created {@link QueryLimitConstraint}.
*/
export declare function limitToLast(limit: number): QueryLimitConstraint;
/**
* A `QueryStartAtConstraint` is used to exclude documents from the start of a
* result set returned by a Firestore query.
* `QueryStartAtConstraint`s are created by invoking {@link (startAt:1)} or
* {@link (startAfter:1)} and can then be passed to {@link (query:1)} to create a
* new query instance that also contains this `QueryStartAtConstraint`.
*/
export declare class QueryStartAtConstraint extends QueryConstraint {
/** The type of this query constraint */
readonly type: 'startAt' | 'startAfter';
private readonly _docOrFields;
private readonly _inclusive;
/**
* @internal
*/
protected constructor(
/** The type of this query constraint */
type: 'startAt' | 'startAfter', _docOrFields: Array<unknown | DocumentSnapshot<unknown>>, _inclusive: boolean);
static _create(type: 'startAt' | 'startAfter', _docOrFields: Array<unknown | DocumentSnapshot<unknown>>, _inclusive: boolean): QueryStartAtConstraint;
_apply<AppModelType, DbModelType extends DocumentData>(query: Query<AppModelType, DbModelType>): Query<AppModelType, DbModelType>;
}
/**
* Creates a {@link QueryStartAtConstraint} that modifies the result set to
* start at the provided document (inclusive). The starting position is relative
* to the order of the query. The document must contain all of the fields
* provided in the `orderBy` of this query.
*
* @param snapshot - The snapshot of the document to start at.
* @returns A {@link QueryStartAtConstraint} to pass to `query()`.
*/
export declare function startAt<AppModelType, DbModelType extends DocumentData>(snapshot: DocumentSnapshot<AppModelType, DbModelType>): QueryStartAtConstraint;
/**
* Creates a {@link QueryStartAtConstraint} that modifies the result set to
* start at the provided fields relative to the order of the query. The order of
* the field values must match the order of the order by clauses of the query.
*
* @param fieldValues - The field values to start this query at, in order
* of the query's order by.
* @returns A {@link QueryStartAtConstraint} to pass to `query()`.
*/
export declare function startAt(...fieldValues: unknown[]): QueryStartAtConstraint;
/**
* Creates a {@link QueryStartAtConstraint} that modifies the result set to
* start after the provided document (exclusive). The starting position is
* relative to the order of the query. The document must contain all of the
* fields provided in the orderBy of the query.
*
* @param snapshot - The snapshot of the document to start after.
* @returns A {@link QueryStartAtConstraint} to pass to `query()`
*/
export declare function startAfter<AppModelType, DbModelType extends DocumentData>(snapshot: DocumentSnapshot<AppModelType, DbModelType>): QueryStartAtConstraint;
/**
* Creates a {@link QueryStartAtConstraint} that modifies the result set to
* start after the provided fields relative to the order of the query. The order
* of the field values must match the order of the order by clauses of the query.
*
* @param fieldValues - The field values to start this query after, in order
* of the query's order by.
* @returns A {@link QueryStartAtConstraint} to pass to `query()`
*/
export declare function startAfter(...fieldValues: unknown[]): QueryStartAtConstraint;
/**
* A `QueryEndAtConstraint` is used to exclude documents from the end of a
* result set returned by a Firestore query.
* `QueryEndAtConstraint`s are created by invoking {@link (endAt:1)} or
* {@link (endBefore:1)} and can then be passed to {@link (query:1)} to create a new
* query instance that also contains this `QueryEndAtConstraint`.
*/
export declare class QueryEndAtConstraint extends QueryConstraint {
/** The type of this query constraint */
readonly type: 'endBefore' | 'endAt';
private readonly _docOrFields;
private readonly _inclusive;
/**
* @internal
*/
protected constructor(
/** The type of this query constraint */
type: 'endBefore' | 'endAt', _docOrFields: Array<unknown | DocumentSnapshot<unknown>>, _inclusive: boolean);
static _create(type: 'endBefore' | 'endAt', _docOrFields: Array<unknown | DocumentSnapshot<unknown>>, _inclusive: boolean): QueryEndAtConstraint;
_apply<AppModelType, DbModelType extends DocumentData>(query: Query<AppModelType, DbModelType>): Query<AppModelType, DbModelType>;
}
/**
* Creates a {@link QueryEndAtConstraint} that modifies the result set to end
* before the provided document (exclusive). The end position is relative to the
* order of the query. The document must contain all of the fields provided in
* the orderBy of the query.
*
* @param snapshot - The snapshot of the document to end before.
* @returns A {@link QueryEndAtConstraint} to pass to `query()`
*/
export declare function endBefore<AppModelType, DbModelType extends DocumentData>(snapshot: DocumentSnapshot<AppModelType, DbModelType>): QueryEndAtConstraint;
/**
* Creates a {@link QueryEndAtConstraint} that modifies the result set to end
* before the provided fields relative to the order of the query. The order of
* the field values must match the order of the order by clauses of the query.
*
* @param fieldValues - The field values to end this query before, in order
* of the query's order by.
* @returns A {@link QueryEndAtConstraint} to pass to `query()`
*/
export declare function endBefore(...fieldValues: unknown[]): QueryEndAtConstraint;
/**
* Creates a {@link QueryEndAtConstraint} that modifies the result set to end at
* the provided document (inclusive). The end position is relative to the order
* of the query. The document must contain all of the fields provided in the
* orderBy of the query.
*
* @param snapshot - The snapshot of the document to end at.
* @returns A {@link QueryEndAtConstraint} to pass to `query()`
*/
export declare function endAt<AppModelType, DbModelType extends DocumentData>(snapshot: DocumentSnapshot<AppModelType, DbModelType>): QueryEndAtConstraint;
/**
* Creates a {@link QueryEndAtConstraint} that modifies the result set to end at
* the provided fields relative to the order of the query. The order of the field
* values must match the order of the order by clauses of the query.
*
* @param fieldValues - The field values to end this query at, in order
* of the query's order by.
* @returns A {@link QueryEndAtConstraint} to pass to `query()`
*/
export declare function endAt(...fieldValues: unknown[]): QueryEndAtConstraint;
export declare function newQueryFilter(query: InternalQuery, methodName: string, dataReader: UserDataReader, databaseId: DatabaseId, fieldPath: InternalFieldPath, op: Operator, value: unknown): FieldFilter;
export declare function newQueryOrderBy(query: InternalQuery, fieldPath: InternalFieldPath, direction: Direction): OrderBy;
/**
* Create a `Bound` from a query and a document.
*
* Note that the `Bound` will always include the key of the document
* and so only the provided document will compare equal to the returned
* position.
*
* Will throw if the document does not contain all fields of the order by
* of the query or if any of the fields in the order by are an uncommitted
* server timestamp.
*/
export declare function newQueryBoundFromDocument(query: InternalQuery, databaseId: DatabaseId, methodName: string, doc: Document | null, inclusive: boolean): Bound;
/**
* Converts a list of field values to a `Bound` for the given query.
*/
export declare function newQueryBoundFromFields(query: InternalQuery, databaseId: DatabaseId, dataReader: UserDataReader, methodName: string, values: unknown[], inclusive: boolean): Bound;
export declare function validateQueryFilterConstraint(functionName: string, queryConstraint: AppliableConstraint): void;

View file

@ -0,0 +1,329 @@
/**
* @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 { Query as InternalQuery } from '../core/query';
import { DocumentKey } from '../model/document_key';
import { ResourcePath } from '../model/path';
import { Firestore } from './database';
import { FieldPath } from './field_path';
import { FieldValue } from './field_value';
import { FirestoreDataConverter } from './snapshot';
import { NestedUpdateFields, Primitive } from './types';
/**
* Document data (for use with {@link @firebase/firestore/lite#(setDoc:1)}) consists of fields mapped to
* values.
*/
export interface DocumentData {
/** A mapping between a field and its value. */
[field: string]: any;
}
/**
* Similar to TypeScript's `Partial<T>`, but allows nested fields to be
* omitted and FieldValues to be passed in as property values.
*/
export declare type PartialWithFieldValue<T> = Partial<T> | (T extends Primitive ? T : T extends {} ? {
[K in keyof T]?: PartialWithFieldValue<T[K]> | FieldValue;
} : never);
/**
* Allows FieldValues to be passed in as a property value while maintaining
* type safety.
*/
export declare type WithFieldValue<T> = T | (T extends Primitive ? T : T extends {} ? {
[K in keyof T]: WithFieldValue<T[K]> | FieldValue;
} : never);
/**
* Update data (for use with {@link (updateDoc:1)}) that consists of field paths
* (e.g. 'foo' or 'foo.baz') mapped to values. Fields that contain dots
* reference nested fields within the document. FieldValues can be passed in
* as property values.
*/
export declare type UpdateData<T> = T extends Primitive ? T : T extends {} ? {
[K in keyof T]?: UpdateData<T[K]> | FieldValue;
} & NestedUpdateFields<T> : Partial<T>;
/**
* An options object that configures the behavior of {@link @firebase/firestore/lite#(setDoc:1)}, {@link
* @firebase/firestore/lite#(WriteBatch.set:1)} and {@link @firebase/firestore/lite#(Transaction.set:1)} calls. These calls can be
* configured to perform granular merges instead of overwriting the target
* documents in their entirety by providing a `SetOptions` with `merge: true`.
*
* @param merge - Changes the behavior of a `setDoc()` call to only replace the
* values specified in its data argument. Fields omitted from the `setDoc()`
* call remain untouched. If your input sets any field to an empty map, all
* nested fields are overwritten.
* @param mergeFields - Changes the behavior of `setDoc()` calls to only replace
* the specified field paths. Any field path that is not specified is ignored
* and remains untouched. If your input sets any field to an empty map, all
* nested fields are overwritten.
*/
export declare type SetOptions = {
readonly merge?: boolean;
} | {
readonly mergeFields?: Array<string | FieldPath>;
};
/**
* A `Query` refers to a query which you can read or listen to. You can also
* construct refined `Query` objects by adding filters and ordering.
*/
export declare class Query<AppModelType = DocumentData, DbModelType extends DocumentData = DocumentData> {
/**
* If provided, the `FirestoreDataConverter` associated with this instance.
*/
readonly converter: FirestoreDataConverter<AppModelType, DbModelType> | null;
readonly _query: InternalQuery;
/** The type of this Firestore reference. */
readonly type: 'query' | 'collection';
/**
* The `Firestore` instance for the Firestore database (useful for performing
* transactions, etc.).
*/
readonly firestore: Firestore;
/** @hideconstructor protected */
constructor(firestore: Firestore,
/**
* If provided, the `FirestoreDataConverter` associated with this instance.
*/
converter: FirestoreDataConverter<AppModelType, DbModelType> | null, _query: InternalQuery);
/**
* Removes the current converter.
*
* @param converter - `null` removes the current converter.
* @returns A `Query<DocumentData, DocumentData>` that does not use a
* converter.
*/
withConverter(converter: null): Query<DocumentData, DocumentData>;
/**
* Applies a custom data converter to this query, allowing you to use your own
* custom model objects with Firestore. When you call {@link getDocs} with
* the returned query, the provided converter will convert between Firestore
* data of type `NewDbModelType` and your custom type `NewAppModelType`.
*
* @param converter - Converts objects to and from Firestore.
* @returns A `Query` that uses the provided converter.
*/
withConverter<NewAppModelType, NewDbModelType extends DocumentData = DocumentData>(converter: FirestoreDataConverter<NewAppModelType, NewDbModelType>): Query<NewAppModelType, NewDbModelType>;
}
/**
* A `DocumentReference` refers to a document location in a Firestore database
* and can be used to write, read, or listen to the location. The document at
* the referenced location may or may not exist.
*/
export declare class DocumentReference<AppModelType = DocumentData, DbModelType extends DocumentData = DocumentData> {
/**
* If provided, the `FirestoreDataConverter` associated with this instance.
*/
readonly converter: FirestoreDataConverter<AppModelType, DbModelType> | null;
readonly _key: DocumentKey;
/** The type of this Firestore reference. */
readonly type = "document";
/**
* The {@link Firestore} instance the document is in.
* This is useful for performing transactions, for example.
*/
readonly firestore: Firestore;
/** @hideconstructor */
constructor(firestore: Firestore,
/**
* If provided, the `FirestoreDataConverter` associated with this instance.
*/
converter: FirestoreDataConverter<AppModelType, DbModelType> | null, _key: DocumentKey);
get _path(): ResourcePath;
/**
* The document's identifier within its collection.
*/
get id(): string;
/**
* A string representing the path of the referenced document (relative
* to the root of the database).
*/
get path(): string;
/**
* The collection this `DocumentReference` belongs to.
*/
get parent(): CollectionReference<AppModelType, DbModelType>;
/**
* Applies a custom data converter to this `DocumentReference`, allowing you
* to use your own custom model objects with Firestore. When you call {@link
* @firebase/firestore/lite#(setDoc:1)}, {@link @firebase/firestore/lite#getDoc}, etc. with the returned `DocumentReference`
* instance, the provided converter will convert between Firestore data of
* type `NewDbModelType` and your custom type `NewAppModelType`.
*
* @param converter - Converts objects to and from Firestore.
* @returns A `DocumentReference` that uses the provided converter.
*/
withConverter<NewAppModelType, NewDbModelType extends DocumentData = DocumentData>(converter: FirestoreDataConverter<NewAppModelType, NewDbModelType>): DocumentReference<NewAppModelType, NewDbModelType>;
/**
* Removes the current converter.
*
* @param converter - `null` removes the current converter.
* @returns A `DocumentReference<DocumentData, DocumentData>` that does not
* use a converter.
*/
withConverter(converter: null): DocumentReference<DocumentData, DocumentData>;
}
/**
* A `CollectionReference` object can be used for adding documents, getting
* document references, and querying for documents (using {@link (query:1)}).
*/
export declare class CollectionReference<AppModelType = DocumentData, DbModelType extends DocumentData = DocumentData> extends Query<AppModelType, DbModelType> {
readonly _path: ResourcePath;
/** The type of this Firestore reference. */
readonly type = "collection";
/** @hideconstructor */
constructor(firestore: Firestore, converter: FirestoreDataConverter<AppModelType, DbModelType> | null, _path: ResourcePath);
/** The collection's identifier. */
get id(): string;
/**
* A string representing the path of the referenced collection (relative
* to the root of the database).
*/
get path(): string;
/**
* A reference to the containing `DocumentReference` if this is a
* subcollection. If this isn't a subcollection, the reference is null.
*/
get parent(): DocumentReference<DocumentData, DocumentData> | null;
/**
* Applies a custom data converter to this `CollectionReference`, allowing you
* to use your own custom model objects with Firestore. When you call {@link
* addDoc} with the returned `CollectionReference` instance, the provided
* converter will convert between Firestore data of type `NewDbModelType` and
* your custom type `NewAppModelType`.
*
* @param converter - Converts objects to and from Firestore.
* @returns A `CollectionReference` that uses the provided converter.
*/
withConverter<NewAppModelType, NewDbModelType extends DocumentData = DocumentData>(converter: FirestoreDataConverter<NewAppModelType, NewDbModelType>): CollectionReference<NewAppModelType, NewDbModelType>;
/**
* Removes the current converter.
*
* @param converter - `null` removes the current converter.
* @returns A `CollectionReference<DocumentData, DocumentData>` that does not
* use a converter.
*/
withConverter(converter: null): CollectionReference<DocumentData, DocumentData>;
}
/**
* Gets a `CollectionReference` instance that refers to the collection at
* the specified absolute path.
*
* @param firestore - A reference to the root `Firestore` instance.
* @param path - A slash-separated path to a collection.
* @param pathSegments - Additional path segments to apply relative to the first
* argument.
* @throws If the final path has an even number of segments and does not point
* to a collection.
* @returns The `CollectionReference` instance.
*/
export declare function collection(firestore: Firestore, path: string, ...pathSegments: string[]): CollectionReference<DocumentData, DocumentData>;
/**
* Gets a `CollectionReference` instance that refers to a subcollection of
* `reference` at the specified relative path.
*
* @param reference - A reference to a collection.
* @param path - A slash-separated path to a collection.
* @param pathSegments - Additional path segments to apply relative to the first
* argument.
* @throws If the final path has an even number of segments and does not point
* to a collection.
* @returns The `CollectionReference` instance.
*/
export declare function collection<AppModelType, DbModelType extends DocumentData>(reference: CollectionReference<AppModelType, DbModelType>, path: string, ...pathSegments: string[]): CollectionReference<DocumentData, DocumentData>;
/**
* Gets a `CollectionReference` instance that refers to a subcollection of
* `reference` at the specified relative path.
*
* @param reference - A reference to a Firestore document.
* @param path - A slash-separated path to a collection.
* @param pathSegments - Additional path segments that will be applied relative
* to the first argument.
* @throws If the final path has an even number of segments and does not point
* to a collection.
* @returns The `CollectionReference` instance.
*/
export declare function collection<AppModelType, DbModelType extends DocumentData>(reference: DocumentReference<AppModelType, DbModelType>, path: string, ...pathSegments: string[]): CollectionReference<DocumentData, DocumentData>;
/**
* Creates and returns a new `Query` instance that includes all documents in the
* database that are contained in a collection or subcollection with the
* given `collectionId`.
*
* @param firestore - A reference to the root `Firestore` instance.
* @param collectionId - Identifies the collections to query over. Every
* collection or subcollection with this ID as the last segment of its path
* will be included. Cannot contain a slash.
* @returns The created `Query`.
*/
export declare function collectionGroup(firestore: Firestore, collectionId: string): Query<DocumentData, DocumentData>;
/**
* Gets a `DocumentReference` instance that refers to the document at the
* specified absolute path.
*
* @param firestore - A reference to the root `Firestore` instance.
* @param path - A slash-separated path to a document.
* @param pathSegments - Additional path segments that will be applied relative
* to the first argument.
* @throws If the final path has an odd number of segments and does not point to
* a document.
* @returns The `DocumentReference` instance.
*/
export declare function doc(firestore: Firestore, path: string, ...pathSegments: string[]): DocumentReference<DocumentData, DocumentData>;
/**
* Gets a `DocumentReference` instance that refers to a document within
* `reference` at the specified relative path. If no path is specified, an
* automatically-generated unique ID will be used for the returned
* `DocumentReference`.
*
* @param reference - A reference to a collection.
* @param path - A slash-separated path to a document. Has to be omitted to use
* auto-generated IDs.
* @param pathSegments - Additional path segments that will be applied relative
* to the first argument.
* @throws If the final path has an odd number of segments and does not point to
* a document.
* @returns The `DocumentReference` instance.
*/
export declare function doc<AppModelType, DbModelType extends DocumentData>(reference: CollectionReference<AppModelType, DbModelType>, path?: string, ...pathSegments: string[]): DocumentReference<AppModelType, DbModelType>;
/**
* Gets a `DocumentReference` instance that refers to a document within
* `reference` at the specified relative path.
*
* @param reference - A reference to a Firestore document.
* @param path - A slash-separated path to a document.
* @param pathSegments - Additional path segments that will be applied relative
* to the first argument.
* @throws If the final path has an odd number of segments and does not point to
* a document.
* @returns The `DocumentReference` instance.
*/
export declare function doc<AppModelType, DbModelType extends DocumentData>(reference: DocumentReference<AppModelType, DbModelType>, path: string, ...pathSegments: string[]): DocumentReference<DocumentData, DocumentData>;
/**
* Returns true if the provided references are equal.
*
* @param left - A reference to compare.
* @param right - A reference to compare.
* @returns true if the references point to the same location in the same
* Firestore database.
*/
export declare function refEqual<AppModelType, DbModelType extends DocumentData>(left: DocumentReference<AppModelType, DbModelType> | CollectionReference<AppModelType, DbModelType>, right: DocumentReference<AppModelType, DbModelType> | CollectionReference<AppModelType, DbModelType>): boolean;
/**
* Returns true if the provided queries point to the same collection and apply
* the same constraints.
*
* @param left - A `Query` to compare.
* @param right - A `Query` to compare.
* @returns true if the references point to the same location in the same
* Firestore database.
*/
export declare function queryEqual<AppModelType, DbModelType extends DocumentData>(left: Query<AppModelType, DbModelType>, right: Query<AppModelType, DbModelType>): boolean;

View file

@ -0,0 +1,172 @@
/**
* @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 { DocumentData as PublicDocumentData, SetOptions as PublicSetOptions } from '@firebase/firestore-types';
import { ByteString } from '../util/byte_string';
import { Bytes } from './bytes';
import { Firestore } from './database';
import { FieldPath } from './field_path';
import { CollectionReference, DocumentData, DocumentReference, PartialWithFieldValue, Query, SetOptions, UpdateData, WithFieldValue } from './reference';
import { DocumentSnapshot, QuerySnapshot } from './snapshot';
import { UntypedFirestoreDataConverter } from './user_data_reader';
import { AbstractUserDataWriter } from './user_data_writer';
/**
* Converts custom model object of type T into `DocumentData` by applying the
* converter if it exists.
*
* This function is used when converting user objects to `DocumentData`
* because we want to provide the user with a more specific error message if
* their `set()` or fails due to invalid data originating from a `toFirestore()`
* call.
*/
export declare function applyFirestoreDataConverter<T>(converter: UntypedFirestoreDataConverter<T> | null, value: WithFieldValue<T> | PartialWithFieldValue<T>, options?: PublicSetOptions): PublicDocumentData;
export declare class LiteUserDataWriter extends AbstractUserDataWriter {
protected firestore: Firestore;
constructor(firestore: Firestore);
protected convertBytes(bytes: ByteString): Bytes;
protected convertReference(name: string): DocumentReference;
}
/**
* Reads the document referred to by the specified document reference.
*
* All documents are directly fetched from the server, even if the document was
* previously read or modified. Recent modifications are only reflected in the
* retrieved `DocumentSnapshot` if they have already been applied by the
* backend. If the client is offline, the read fails. If you like to use
* caching or see local modifications, please use the full Firestore SDK.
*
* @param reference - The reference of the document to fetch.
* @returns A Promise resolved with a `DocumentSnapshot` containing the current
* document contents.
*/
export declare function getDoc<AppModelType, DbModelType extends DocumentData>(reference: DocumentReference<AppModelType, DbModelType>): Promise<DocumentSnapshot<AppModelType, DbModelType>>;
/**
* Executes the query and returns the results as a {@link QuerySnapshot}.
*
* All queries are executed directly by the server, even if the query was
* previously executed. Recent modifications are only reflected in the retrieved
* results if they have already been applied by the backend. If the client is
* offline, the operation fails. To see previously cached result and local
* modifications, use the full Firestore SDK.
*
* @param query - The `Query` to execute.
* @returns A Promise that will be resolved with the results of the query.
*/
export declare function getDocs<AppModelType, DbModelType extends DocumentData>(query: Query<AppModelType, DbModelType>): Promise<QuerySnapshot<AppModelType, DbModelType>>;
/**
* Writes to the document referred to by the specified `DocumentReference`. If
* the document does not yet exist, it will be created.
*
* The result of this write will only be reflected in document reads that occur
* after the returned promise resolves. If the client is offline, the
* write fails. If you would like to see local modifications or buffer writes
* until the client is online, use the full Firestore SDK.
*
* @param reference - A reference to the document to write.
* @param data - A map of the fields and values for the document.
* @throws Error - If the provided input is not a valid Firestore document.
* @returns A `Promise` resolved once the data has been successfully written
* to the backend.
*/
export declare function setDoc<AppModelType, DbModelType extends DocumentData>(reference: DocumentReference<AppModelType, DbModelType>, data: WithFieldValue<AppModelType>): Promise<void>;
/**
* Writes to the document referred to by the specified `DocumentReference`. If
* the document does not yet exist, it will be created. If you provide `merge`
* or `mergeFields`, the provided data can be merged into an existing document.
*
* The result of this write will only be reflected in document reads that occur
* after the returned promise resolves. If the client is offline, the
* write fails. If you would like to see local modifications or buffer writes
* until the client is online, use the full Firestore SDK.
*
* @param reference - A reference to the document to write.
* @param data - A map of the fields and values for the document.
* @param options - An object to configure the set behavior.
* @throws Error - If the provided input is not a valid Firestore document.
* @returns A `Promise` resolved once the data has been successfully written
* to the backend.
*/
export declare function setDoc<AppModelType, DbModelType extends DocumentData>(reference: DocumentReference<AppModelType, DbModelType>, data: PartialWithFieldValue<AppModelType>, options: SetOptions): Promise<void>;
/**
* Updates fields in the document referred to by the specified
* `DocumentReference`. The update will fail if applied to a document that does
* not exist.
*
* The result of this update will only be reflected in document reads that occur
* after the returned promise resolves. If the client is offline, the
* update fails. If you would like to see local modifications or buffer writes
* until the client is online, use the full Firestore SDK.
*
* @param reference - A reference to the document to update.
* @param data - An object containing the fields and values with which to
* update the document. Fields can contain dots to reference nested fields
* within the document.
* @throws Error - If the provided input is not valid Firestore data.
* @returns A `Promise` resolved once the data has been successfully written
* to the backend.
*/
export declare function updateDoc<AppModelType, DbModelType extends DocumentData>(reference: DocumentReference<AppModelType, DbModelType>, data: UpdateData<DbModelType>): Promise<void>;
/**
* Updates fields in the document referred to by the specified
* `DocumentReference` The update will fail if applied to a document that does
* not exist.
*
* Nested fields can be updated by providing dot-separated field path
* strings or by providing `FieldPath` objects.
*
* The result of this update will only be reflected in document reads that occur
* after the returned promise resolves. If the client is offline, the
* update fails. If you would like to see local modifications or buffer writes
* until the client is online, use the full Firestore SDK.
*
* @param reference - A reference to the document to update.
* @param field - The first field to update.
* @param value - The first value.
* @param moreFieldsAndValues - Additional key value pairs.
* @throws Error - If the provided input is not valid Firestore data.
* @returns A `Promise` resolved once the data has been successfully written
* to the backend.
*/
export declare function updateDoc<AppModelType, DbModelType extends DocumentData>(reference: DocumentReference<AppModelType, DbModelType>, field: string | FieldPath, value: unknown, ...moreFieldsAndValues: unknown[]): Promise<void>;
/**
* Deletes the document referred to by the specified `DocumentReference`.
*
* The deletion will only be reflected in document reads that occur after the
* returned promise resolves. If the client is offline, the
* delete fails. If you would like to see local modifications or buffer writes
* until the client is online, use the full Firestore SDK.
*
* @param reference - A reference to the document to delete.
* @returns A `Promise` resolved once the document has been successfully
* deleted from the backend.
*/
export declare function deleteDoc<AppModelType, DbModelType extends DocumentData>(reference: DocumentReference<AppModelType, DbModelType>): Promise<void>;
/**
* Add a new document to specified `CollectionReference` with the given data,
* assigning it a document ID automatically.
*
* The result of this write will only be reflected in document reads that occur
* after the returned promise resolves. If the client is offline, the
* write fails. If you would like to see local modifications or buffer writes
* until the client is online, use the full Firestore SDK.
*
* @param reference - A reference to the collection to add this document to.
* @param data - An Object containing the data for the new document.
* @throws Error - If the provided input is not a valid Firestore document.
* @returns A `Promise` resolved with a `DocumentReference` pointing to the
* newly created document after it has been written to the backend.
*/
export declare function addDoc<AppModelType, DbModelType extends DocumentData>(reference: CollectionReference<AppModelType, DbModelType>, data: WithFieldValue<AppModelType>): Promise<DocumentReference<AppModelType, DbModelType>>;

View file

@ -0,0 +1,72 @@
/**
* @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 { FirestoreLocalCache } from '../api/cache_config';
import { CredentialsSettings } from '../api/credentials';
import { ExperimentalLongPollingOptions } from '../api/long_polling_options';
export declare const DEFAULT_HOST = "firestore.googleapis.com";
export declare const DEFAULT_SSL = true;
/**
* Specifies custom configurations for your Cloud Firestore instance.
* You must set these before invoking any other methods.
*/
export interface FirestoreSettings {
/** The hostname to connect to. */
host?: string;
/** Whether to use SSL when connecting. */
ssl?: boolean;
/**
* Whether to skip nested properties that are set to `undefined` during
* object serialization. If set to `true`, these properties are skipped
* and not written to Firestore. If set to `false` or omitted, the SDK
* throws an exception when it encounters properties of type `undefined`.
*/
ignoreUndefinedProperties?: boolean;
}
/**
* @internal
* Undocumented, private additional settings not exposed in our public API.
*/
export interface PrivateSettings extends FirestoreSettings {
credentials?: CredentialsSettings;
cacheSizeBytes?: number;
experimentalForceLongPolling?: boolean;
experimentalAutoDetectLongPolling?: boolean;
experimentalLongPollingOptions?: ExperimentalLongPollingOptions;
useFetchStreams?: boolean;
localCache?: FirestoreLocalCache;
}
/**
* A concrete type describing all the values that can be applied via a
* user-supplied `FirestoreSettings` object. This is a separate type so that
* defaults can be supplied and the value can be checked for equality.
*/
export declare class FirestoreSettingsImpl {
/** The hostname to connect to. */
readonly host: string;
/** Whether to use SSL when connecting. */
readonly ssl: boolean;
readonly cacheSizeBytes: number;
readonly experimentalForceLongPolling: boolean;
readonly experimentalAutoDetectLongPolling: boolean;
readonly experimentalLongPollingOptions: ExperimentalLongPollingOptions;
readonly ignoreUndefinedProperties: boolean;
readonly useFetchStreams: boolean;
readonly localCache?: FirestoreLocalCache;
credentials?: any;
constructor(settings: PrivateSettings);
isEqual(other: FirestoreSettingsImpl): boolean;
}

View file

@ -0,0 +1,367 @@
/**
* @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 { Compat } from '@firebase/util';
import { Document } from '../model/document';
import { DocumentKey } from '../model/document_key';
import { FieldPath as InternalFieldPath } from '../model/path';
import { Firestore } from './database';
import { FieldPath } from './field_path';
import { DocumentData, DocumentReference, PartialWithFieldValue, Query, SetOptions, WithFieldValue } from './reference';
import { UntypedFirestoreDataConverter } from './user_data_reader';
import { AbstractUserDataWriter } from './user_data_writer';
/**
* Converter used by `withConverter()` to transform user objects of type
* `AppModelType` into Firestore data of type `DbModelType`.
*
* Using the converter allows you to specify generic type arguments when
* storing and retrieving objects from Firestore.
*
* In this context, an "AppModel" is a class that is used in an application to
* package together related information and functionality. Such a class could,
* for example, have properties with complex, nested data types, properties used
* for memoization, properties of types not supported by Firestore (such as
* `symbol` and `bigint`), and helper functions that perform compound
* operations. Such classes are not suitable and/or possible to store into a
* Firestore database. Instead, instances of such classes need to be converted
* to "plain old JavaScript objects" (POJOs) with exclusively primitive
* properties, potentially nested inside other POJOs or arrays of POJOs. In this
* context, this type is referred to as the "DbModel" and would be an object
* suitable for persisting into Firestore. For convenience, applications can
* implement `FirestoreDataConverter` and register the converter with Firestore
* objects, such as `DocumentReference` or `Query`, to automatically convert
* `AppModel` to `DbModel` when storing into Firestore, and convert `DbModel`
* to `AppModel` when retrieving from Firestore.
*
* @example
*
* Simple Example
*
* ```typescript
* const numberConverter = {
* toFirestore(value: WithFieldValue<number>) {
* return { value };
* },
* fromFirestore(snapshot: QueryDocumentSnapshot, options: SnapshotOptions) {
* return snapshot.data(options).value as number;
* }
* };
*
* async function simpleDemo(db: Firestore): Promise<void> {
* const documentRef = doc(db, 'values/value123').withConverter(numberConverter);
*
* // converters are used with `setDoc`, `addDoc`, and `getDoc`
* await setDoc(documentRef, 42);
* const snapshot1 = await getDoc(documentRef);
* assertEqual(snapshot1.data(), 42);
*
* // converters are not used when writing data with `updateDoc`
* await updateDoc(documentRef, { value: 999 });
* const snapshot2 = await getDoc(documentRef);
* assertEqual(snapshot2.data(), 999);
* }
* ```
*
* Advanced Example
*
* ```typescript
* // The Post class is a model that is used by our application.
* // This class may have properties and methods that are specific
* // to our application execution, which do not need to be persisted
* // to Firestore.
* class Post {
* constructor(
* readonly title: string,
* readonly author: string,
* readonly lastUpdatedMillis: number
* ) {}
* toString(): string {
* return `${this.title} by ${this.author}`;
* }
* }
*
* // The PostDbModel represents how we want our posts to be stored
* // in Firestore. This DbModel has different properties (`ttl`,
* // `aut`, and `lut`) from the Post class we use in our application.
* interface PostDbModel {
* ttl: string;
* aut: { firstName: string; lastName: string };
* lut: Timestamp;
* }
*
* // The `PostConverter` implements `FirestoreDataConverter` and specifies
* // how the Firestore SDK can convert `Post` objects to `PostDbModel`
* // objects and vice versa.
* class PostConverter implements FirestoreDataConverter<Post, PostDbModel> {
* toFirestore(post: WithFieldValue<Post>): WithFieldValue<PostDbModel> {
* return {
* ttl: post.title,
* aut: this._autFromAuthor(post.author),
* lut: this._lutFromLastUpdatedMillis(post.lastUpdatedMillis)
* };
* }
*
* fromFirestore(snapshot: QueryDocumentSnapshot, options: SnapshotOptions): Post {
* const data = snapshot.data(options) as PostDbModel;
* const author = `${data.aut.firstName} ${data.aut.lastName}`;
* return new Post(data.ttl, author, data.lut.toMillis());
* }
*
* _autFromAuthor(
* author: string | FieldValue
* ): { firstName: string; lastName: string } | FieldValue {
* if (typeof author !== 'string') {
* // `author` is a FieldValue, so just return it.
* return author;
* }
* const [firstName, lastName] = author.split(' ');
* return {firstName, lastName};
* }
*
* _lutFromLastUpdatedMillis(
* lastUpdatedMillis: number | FieldValue
* ): Timestamp | FieldValue {
* if (typeof lastUpdatedMillis !== 'number') {
* // `lastUpdatedMillis` must be a FieldValue, so just return it.
* return lastUpdatedMillis;
* }
* return Timestamp.fromMillis(lastUpdatedMillis);
* }
* }
*
* async function advancedDemo(db: Firestore): Promise<void> {
* // Create a `DocumentReference` with a `FirestoreDataConverter`.
* const documentRef = doc(db, 'posts/post123').withConverter(new PostConverter());
*
* // The `data` argument specified to `setDoc()` is type checked by the
* // TypeScript compiler to be compatible with `Post`. Since the `data`
* // argument is typed as `WithFieldValue<Post>` rather than just `Post`,
* // this allows properties of the `data` argument to also be special
* // Firestore values that perform server-side mutations, such as
* // `arrayRemove()`, `deleteField()`, and `serverTimestamp()`.
* await setDoc(documentRef, {
* title: 'My Life',
* author: 'Foo Bar',
* lastUpdatedMillis: serverTimestamp()
* });
*
* // The TypeScript compiler will fail to compile if the `data` argument to
* // `setDoc()` is _not_ compatible with `WithFieldValue<Post>`. This
* // type checking prevents the caller from specifying objects with incorrect
* // properties or property values.
* // @ts-expect-error "Argument of type { ttl: string; } is not assignable
* // to parameter of type WithFieldValue<Post>"
* await setDoc(documentRef, { ttl: 'The Title' });
*
* // When retrieving a document with `getDoc()` the `DocumentSnapshot`
* // object's `data()` method returns a `Post`, rather than a generic object,
* // which would have been returned if the `DocumentReference` did _not_ have a
* // `FirestoreDataConverter` attached to it.
* const snapshot1: DocumentSnapshot<Post> = await getDoc(documentRef);
* const post1: Post = snapshot1.data()!;
* if (post1) {
* assertEqual(post1.title, 'My Life');
* assertEqual(post1.author, 'Foo Bar');
* }
*
* // The `data` argument specified to `updateDoc()` is type checked by the
* // TypeScript compiler to be compatible with `PostDbModel`. Note that
* // unlike `setDoc()`, whose `data` argument must be compatible with `Post`,
* // the `data` argument to `updateDoc()` must be compatible with
* // `PostDbModel`. Similar to `setDoc()`, since the `data` argument is typed
* // as `WithFieldValue<PostDbModel>` rather than just `PostDbModel`, this
* // allows properties of the `data` argument to also be those special
* // Firestore values, like `arrayRemove()`, `deleteField()`, and
* // `serverTimestamp()`.
* await updateDoc(documentRef, {
* 'aut.firstName': 'NewFirstName',
* lut: serverTimestamp()
* });
*
* // The TypeScript compiler will fail to compile if the `data` argument to
* // `updateDoc()` is _not_ compatible with `WithFieldValue<PostDbModel>`.
* // This type checking prevents the caller from specifying objects with
* // incorrect properties or property values.
* // @ts-expect-error "Argument of type { title: string; } is not assignable
* // to parameter of type WithFieldValue<PostDbModel>"
* await updateDoc(documentRef, { title: 'New Title' });
* const snapshot2: DocumentSnapshot<Post> = await getDoc(documentRef);
* const post2: Post = snapshot2.data()!;
* if (post2) {
* assertEqual(post2.title, 'My Life');
* assertEqual(post2.author, 'NewFirstName Bar');
* }
* }
* ```
*/
export interface FirestoreDataConverter<AppModelType, DbModelType extends DocumentData = DocumentData> {
/**
* Called by the Firestore SDK to convert a custom model object of type
* `AppModelType` into a plain JavaScript object (suitable for writing
* directly to the Firestore database) of type `DbModelType`. Used with
* {@link @firebase/firestore/lite#(setDoc:1)},
* {@link @firebase/firestore/lite#(WriteBatch.set:1)} and
* {@link @firebase/firestore/lite#(Transaction.set:1)}.
*
* The `WithFieldValue<T>` type extends `T` to also allow FieldValues such as
* {@link (deleteField:1)} to be used as property values.
*/
toFirestore(modelObject: WithFieldValue<AppModelType>): WithFieldValue<DbModelType>;
/**
* Called by the Firestore SDK to convert a custom model object of type
* `AppModelType` into a plain JavaScript object (suitable for writing
* directly to the Firestore database) of type `DbModelType`. Used with
* {@link @firebase/firestore/lite#(setDoc:1)},
* {@link @firebase/firestore/lite#(WriteBatch.set:1)} and
* {@link @firebase/firestore/lite#(Transaction.set:1)} with `merge:true`
* or `mergeFields`.
*
* The `PartialWithFieldValue<T>` type extends `Partial<T>` to allow
* FieldValues such as {@link (arrayUnion:1)} to be used as property values.
* It also supports nested `Partial` by allowing nested fields to be
* omitted.
*/
toFirestore(modelObject: PartialWithFieldValue<AppModelType>, options: SetOptions): PartialWithFieldValue<DbModelType>;
/**
* Called by the Firestore SDK to convert Firestore data into an object of
* type `AppModelType`. You can access your data by calling:
* `snapshot.data()`.
*
*
* Generally, the data returned from `snapshot.data()` can be cast to
* `DbModelType`; however, this is not guaranteed because Firestore does not
* enforce a schema on the database. For example, writes from a previous
* version of the application or writes from another client that did not use a
* type converter could have written data with different properties and/or
* property types. The implementation will need to choose whether to
* gracefully recover from non-conforming data or throw an error.
*
* @param snapshot - A `QueryDocumentSnapshot` containing your data and
* metadata.
*/
fromFirestore(snapshot: QueryDocumentSnapshot<DocumentData, DocumentData>): AppModelType;
}
/**
* A `DocumentSnapshot` contains data read from a document in your Firestore
* database. The data can be extracted with `.data()` or `.get(<field>)` to
* get a specific field.
*
* For a `DocumentSnapshot` that points to a non-existing document, any data
* access will return 'undefined'. You can use the `exists()` method to
* explicitly verify a document's existence.
*/
export declare class DocumentSnapshot<AppModelType = DocumentData, DbModelType extends DocumentData = DocumentData> {
_firestore: Firestore;
_userDataWriter: AbstractUserDataWriter;
_key: DocumentKey;
_document: Document | null;
_converter: UntypedFirestoreDataConverter<AppModelType, DbModelType> | null;
/** @hideconstructor protected */
constructor(_firestore: Firestore, _userDataWriter: AbstractUserDataWriter, _key: DocumentKey, _document: Document | null, _converter: UntypedFirestoreDataConverter<AppModelType, DbModelType> | null);
/** Property of the `DocumentSnapshot` that provides the document's ID. */
get id(): string;
/**
* The `DocumentReference` for the document included in the `DocumentSnapshot`.
*/
get ref(): DocumentReference<AppModelType, DbModelType>;
/**
* Signals whether or not the document at the snapshot's location exists.
*
* @returns true if the document exists.
*/
exists(): this is QueryDocumentSnapshot<AppModelType, DbModelType>;
/**
* Retrieves all fields in the document as an `Object`. Returns `undefined` if
* the document doesn't exist.
*
* @returns An `Object` containing all fields in the document or `undefined`
* if the document doesn't exist.
*/
data(): AppModelType | undefined;
/**
* Retrieves the field specified by `fieldPath`. Returns `undefined` if the
* document or field doesn't exist.
*
* @param fieldPath - The path (for example 'foo' or 'foo.bar') to a specific
* field.
* @returns The data at the specified field location or undefined if no such
* field exists in the document.
*/
get(fieldPath: string | FieldPath): any;
}
/**
* A `QueryDocumentSnapshot` contains data read from a document in your
* Firestore database as part of a query. The document is guaranteed to exist
* and its data can be extracted with `.data()` or `.get(<field>)` to get a
* specific field.
*
* A `QueryDocumentSnapshot` offers the same API surface as a
* `DocumentSnapshot`. Since query results contain only existing documents, the
* `exists` property will always be true and `data()` will never return
* 'undefined'.
*/
export declare class QueryDocumentSnapshot<AppModelType = DocumentData, DbModelType extends DocumentData = DocumentData> extends DocumentSnapshot<AppModelType, DbModelType> {
/**
* Retrieves all fields in the document as an `Object`.
*
* @override
* @returns An `Object` containing all fields in the document.
*/
data(): AppModelType;
}
/**
* A `QuerySnapshot` contains zero or more `DocumentSnapshot` objects
* representing the results of a query. The documents can be accessed as an
* array via the `docs` property or enumerated using the `forEach` method. The
* number of documents can be determined via the `empty` and `size`
* properties.
*/
export declare class QuerySnapshot<AppModelType = DocumentData, DbModelType extends DocumentData = DocumentData> {
readonly _docs: Array<QueryDocumentSnapshot<AppModelType, DbModelType>>;
/**
* The query on which you called {@link getDocs} in order to get this
* `QuerySnapshot`.
*/
readonly query: Query<AppModelType, DbModelType>;
/** @hideconstructor */
constructor(_query: Query<AppModelType, DbModelType>, _docs: Array<QueryDocumentSnapshot<AppModelType, DbModelType>>);
/** An array of all the documents in the `QuerySnapshot`. */
get docs(): Array<QueryDocumentSnapshot<AppModelType, DbModelType>>;
/** The number of documents in the `QuerySnapshot`. */
get size(): number;
/** True if there are no documents in the `QuerySnapshot`. */
get empty(): boolean;
/**
* Enumerates all of the documents in the `QuerySnapshot`.
*
* @param callback - A callback to be called with a `QueryDocumentSnapshot` for
* each document in the snapshot.
* @param thisArg - The `this` binding for the callback.
*/
forEach(callback: (result: QueryDocumentSnapshot<AppModelType, DbModelType>) => void, thisArg?: unknown): void;
}
/**
* Returns true if the provided snapshots are equal.
*
* @param left - A snapshot to compare.
* @param right - A snapshot to compare.
* @returns true if the snapshots are equal.
*/
export declare function snapshotEqual<AppModelType, DbModelType extends DocumentData>(left: DocumentSnapshot<AppModelType, DbModelType> | QuerySnapshot<AppModelType, DbModelType>, right: DocumentSnapshot<AppModelType, DbModelType> | QuerySnapshot<AppModelType, DbModelType>): boolean;
/**
* Helper that calls `fromDotSeparatedString()` but wraps any error thrown.
*/
export declare function fieldPathFromArgument(methodName: string, arg: string | FieldPath | Compat<FieldPath>): InternalFieldPath;

View file

@ -0,0 +1,120 @@
/**
* @license
* Copyright 2017 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.
*/
/**
* A `Timestamp` represents a point in time independent of any time zone or
* calendar, represented as seconds and fractions of seconds at nanosecond
* resolution in UTC Epoch time.
*
* It is encoded using the Proleptic Gregorian Calendar which extends the
* Gregorian calendar backwards to year one. It is encoded assuming all minutes
* are 60 seconds long, i.e. leap seconds are "smeared" so that no leap second
* table is needed for interpretation. Range is from 0001-01-01T00:00:00Z to
* 9999-12-31T23:59:59.999999999Z.
*
* For examples and further specifications, refer to the
* {@link https://github.com/google/protobuf/blob/master/src/google/protobuf/timestamp.proto | Timestamp definition}.
*/
export declare class Timestamp {
/**
* The number of seconds of UTC time since Unix epoch 1970-01-01T00:00:00Z.
*/
readonly seconds: number;
/**
* The fractions of a second at nanosecond resolution.*
*/
readonly nanoseconds: number;
/**
* Creates a new timestamp with the current date, with millisecond precision.
*
* @returns a new timestamp representing the current date.
*/
static now(): Timestamp;
/**
* Creates a new timestamp from the given date.
*
* @param date - The date to initialize the `Timestamp` from.
* @returns A new `Timestamp` representing the same point in time as the given
* date.
*/
static fromDate(date: Date): Timestamp;
/**
* Creates a new timestamp from the given number of milliseconds.
*
* @param milliseconds - Number of milliseconds since Unix epoch
* 1970-01-01T00:00:00Z.
* @returns A new `Timestamp` representing the same point in time as the given
* number of milliseconds.
*/
static fromMillis(milliseconds: number): Timestamp;
/**
* Creates a new timestamp.
*
* @param seconds - The number of seconds of UTC time since Unix epoch
* 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
* 9999-12-31T23:59:59Z inclusive.
* @param nanoseconds - The non-negative fractions of a second at nanosecond
* resolution. Negative second values with fractions must still have
* non-negative nanoseconds values that count forward in time. Must be
* from 0 to 999,999,999 inclusive.
*/
constructor(
/**
* The number of seconds of UTC time since Unix epoch 1970-01-01T00:00:00Z.
*/
seconds: number,
/**
* The fractions of a second at nanosecond resolution.*
*/
nanoseconds: number);
/**
* Converts a `Timestamp` to a JavaScript `Date` object. This conversion
* causes a loss of precision since `Date` objects only support millisecond
* precision.
*
* @returns JavaScript `Date` object representing the same point in time as
* this `Timestamp`, with millisecond precision.
*/
toDate(): Date;
/**
* Converts a `Timestamp` to a numeric timestamp (in milliseconds since
* epoch). This operation causes a loss of precision.
*
* @returns The point in time corresponding to this timestamp, represented as
* the number of milliseconds since Unix epoch 1970-01-01T00:00:00Z.
*/
toMillis(): number;
_compareTo(other: Timestamp): number;
/**
* Returns true if this `Timestamp` is equal to the provided one.
*
* @param other - The `Timestamp` to compare against.
* @returns true if this `Timestamp` is equal to the provided one.
*/
isEqual(other: Timestamp): boolean;
/** Returns a textual representation of this `Timestamp`. */
toString(): string;
/** Returns a JSON-serializable representation of this `Timestamp`. */
toJSON(): {
seconds: number;
nanoseconds: number;
};
/**
* Converts this object to a primitive string, which allows `Timestamp` objects
* to be compared using the `>`, `<=`, `>=` and `>` operators.
*/
valueOf(): string;
}

View file

@ -0,0 +1,122 @@
/**
* @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 { Transaction as InternalTransaction } from '../core/transaction';
import { Firestore } from './database';
import { FieldPath } from './field_path';
import { DocumentData, DocumentReference, PartialWithFieldValue, SetOptions, UpdateData, WithFieldValue } from './reference';
import { DocumentSnapshot } from './snapshot';
import { TransactionOptions } from './transaction_options';
/**
* A reference to a transaction.
*
* The `Transaction` object passed to a transaction's `updateFunction` provides
* the methods to read and write data within the transaction context. See
* {@link runTransaction}.
*/
export declare class Transaction {
protected readonly _firestore: Firestore;
private readonly _transaction;
private readonly _dataReader;
/** @hideconstructor */
constructor(_firestore: Firestore, _transaction: InternalTransaction);
/**
* Reads the document referenced by the provided {@link DocumentReference}.
*
* @param documentRef - A reference to the document to be read.
* @returns A `DocumentSnapshot` with the read data.
*/
get<AppModelType, DbModelType extends DocumentData>(documentRef: DocumentReference<AppModelType, DbModelType>): Promise<DocumentSnapshot<AppModelType, DbModelType>>;
/**
* Writes to the document referred to by the provided {@link
* DocumentReference}. If the document does not exist yet, it will be created.
*
* @param documentRef - A reference to the document to be set.
* @param data - An object of the fields and values for the document.
* @throws Error - If the provided input is not a valid Firestore document.
* @returns This `Transaction` instance. Used for chaining method calls.
*/
set<AppModelType, DbModelType extends DocumentData>(documentRef: DocumentReference<AppModelType, DbModelType>, data: WithFieldValue<AppModelType>): this;
/**
* Writes to the document referred to by the provided {@link
* DocumentReference}. If the document does not exist yet, it will be created.
* If you provide `merge` or `mergeFields`, the provided data can be merged
* into an existing document.
*
* @param documentRef - A reference to the document to be set.
* @param data - An object of the fields and values for the document.
* @param options - An object to configure the set behavior.
* @throws Error - If the provided input is not a valid Firestore document.
* @returns This `Transaction` instance. Used for chaining method calls.
*/
set<AppModelType, DbModelType extends DocumentData>(documentRef: DocumentReference<AppModelType, DbModelType>, data: PartialWithFieldValue<AppModelType>, options: SetOptions): this;
/**
* Updates fields in the document referred to by the provided {@link
* DocumentReference}. The update will fail if applied to a document that does
* not exist.
*
* @param documentRef - A reference to the document to be updated.
* @param data - An object containing the fields and values with which to
* update the document. Fields can contain dots to reference nested fields
* within the document.
* @throws Error - If the provided input is not valid Firestore data.
* @returns This `Transaction` instance. Used for chaining method calls.
*/
update<AppModelType, DbModelType extends DocumentData>(documentRef: DocumentReference<AppModelType, DbModelType>, data: UpdateData<DbModelType>): this;
/**
* Updates fields in the document referred to by the provided {@link
* DocumentReference}. The update will fail if applied to a document that does
* not exist.
*
* Nested fields can be updated by providing dot-separated field path
* strings or by providing `FieldPath` objects.
*
* @param documentRef - A reference to the document to be updated.
* @param field - The first field to update.
* @param value - The first value.
* @param moreFieldsAndValues - Additional key/value pairs.
* @throws Error - If the provided input is not valid Firestore data.
* @returns This `Transaction` instance. Used for chaining method calls.
*/
update<AppModelType, DbModelType extends DocumentData>(documentRef: DocumentReference<AppModelType, DbModelType>, field: string | FieldPath, value: unknown, ...moreFieldsAndValues: unknown[]): this;
/**
* Deletes the document referred to by the provided {@link DocumentReference}.
*
* @param documentRef - A reference to the document to be deleted.
* @returns This `Transaction` instance. Used for chaining method calls.
*/
delete<AppModelType, DbModelType extends DocumentData>(documentRef: DocumentReference<AppModelType, DbModelType>): this;
}
/**
* Executes the given `updateFunction` and then attempts to commit the changes
* applied within the transaction. If any document read within the transaction
* has changed, Cloud Firestore retries the `updateFunction`. If it fails to
* commit after 5 attempts, the transaction fails.
*
* The maximum number of writes allowed in a single transaction is 500.
*
* @param firestore - A reference to the Firestore database to run this
* transaction against.
* @param updateFunction - The function to execute within the transaction
* context.
* @param options - An options object to configure maximum number of attempts to
* commit.
* @returns If the transaction completed successfully or was explicitly aborted
* (the `updateFunction` returned a failed promise), the promise returned by the
* `updateFunction `is returned here. Otherwise, if the transaction failed, a
* rejected promise with the corresponding failure error is returned.
*/
export declare function runTransaction<T>(firestore: Firestore, updateFunction: (transaction: Transaction) => Promise<T>, options?: TransactionOptions): Promise<T>;

View file

@ -0,0 +1,23 @@
/**
* @license
* Copyright 2022 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.
*/
/**
* Options to customize transaction behavior.
*/
export declare interface TransactionOptions {
/** Maximum number of attempts to commit, after which transaction fails. Default is 5. */
readonly maxAttempts?: number;
}

View file

@ -0,0 +1,61 @@
/**
* @license
* Copyright 2021 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 { UpdateData } from './reference';
/**
* These types primarily exist to support the `UpdateData`,
* `WithFieldValue`, and `PartialWithFieldValue` types and are not consumed
* directly by the end developer.
*/
/** Primitive types. */
export declare type Primitive = string | number | boolean | undefined | null;
/**
* For each field (e.g. 'bar'), find all nested keys (e.g. {'bar.baz': T1,
* 'bar.qux': T2}). Intersect them together to make a single map containing
* all possible keys that are all marked as optional
*/
export declare type NestedUpdateFields<T extends Record<string, unknown>> = UnionToIntersection<{
[K in keyof T & string]: ChildUpdateFields<K, T[K]>;
}[keyof T & string]>;
/**
* Helper for calculating the nested fields for a given type T1. This is needed
* to distribute union types such as `undefined | {...}` (happens for optional
* props) or `{a: A} | {b: B}`.
*
* In this use case, `V` is used to distribute the union types of `T[K]` on
* `Record`, since `T[K]` is evaluated as an expression and not distributed.
*
* See https://www.typescriptlang.org/docs/handbook/advanced-types.html#distributive-conditional-types
*/
export declare type ChildUpdateFields<K extends string, V> = V extends Record<string, unknown> ? AddPrefixToKeys<K, UpdateData<V>> : never;
/**
* Returns a new map where every key is prefixed with the outer key appended
* to a dot.
*/
export declare type AddPrefixToKeys<Prefix extends string, T extends Record<string, unknown>> = {
[K in keyof T & string as `${Prefix}.${K}`]+?: string extends K ? any : T[K];
};
/**
* Given a union type `U = T1 | T2 | ...`, returns an intersected type
* `(T1 & T2 & ...)`.
*
* Uses distributive conditional types and inference from conditional types.
* This works because multiple candidates for the same type variable in
* contra-variant positions causes an intersection type to be inferred.
* https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-inference-in-conditional-types
* https://stackoverflow.com/questions/50374908/transform-union-type-to-intersection-type
*/
export declare type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends (k: infer I) => void ? I : never;

View file

@ -0,0 +1,220 @@
/**
* @license
* Copyright 2017 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 { DocumentData, FieldPath as PublicFieldPath, SetOptions } from '@firebase/firestore-types';
import { Compat } from '@firebase/util';
import { ParseContext } from '../api/parse_context';
import { DatabaseId } from '../core/database_info';
import { DocumentKey } from '../model/document_key';
import { FieldMask } from '../model/field_mask';
import { FieldTransform, Mutation, Precondition } from '../model/mutation';
import { ObjectValue } from '../model/object_value';
import { FieldPath as InternalFieldPath } from '../model/path';
import { Value as ProtoValue } from '../protos/firestore_proto_api';
import { JsonProtoSerializer } from '../remote/serializer';
import { FirestoreError } from '../util/error';
import { Firestore } from './database';
import { FieldValue } from './field_value';
import { PartialWithFieldValue, WithFieldValue } from './reference';
import { VectorValue } from './vector_value';
/**
* An untyped Firestore Data Converter interface that is shared between the
* lite, firestore-exp and classic SDK.
*/
export interface UntypedFirestoreDataConverter<AppModelType, DbModelType extends DocumentData = DocumentData> {
toFirestore(modelObject: WithFieldValue<AppModelType>): WithFieldValue<DbModelType>;
toFirestore(modelObject: PartialWithFieldValue<AppModelType>, options: SetOptions): PartialWithFieldValue<DbModelType>;
fromFirestore(snapshot: unknown, options?: unknown): AppModelType;
}
/** The result of parsing document data (e.g. for a setData call). */
export declare class ParsedSetData {
readonly data: ObjectValue;
readonly fieldMask: FieldMask | null;
readonly fieldTransforms: FieldTransform[];
constructor(data: ObjectValue, fieldMask: FieldMask | null, fieldTransforms: FieldTransform[]);
toMutation(key: DocumentKey, precondition: Precondition): Mutation;
}
/** The result of parsing "update" data (i.e. for an updateData call). */
export declare class ParsedUpdateData {
readonly data: ObjectValue;
readonly fieldMask: FieldMask;
readonly fieldTransforms: FieldTransform[];
constructor(data: ObjectValue, fieldMask: FieldMask, fieldTransforms: FieldTransform[]);
toMutation(key: DocumentKey, precondition: Precondition): Mutation;
}
export declare const enum UserDataSource {
Set = 0,
Update = 1,
MergeSet = 2,
/**
* Indicates the source is a where clause, cursor bound, arrayUnion()
* element, etc. Of note, isWrite(source) will return false.
*/
Argument = 3,
/**
* Indicates that the source is an Argument that may directly contain nested
* arrays (e.g. the operand of an `in` query).
*/
ArrayArgument = 4
}
/** Contains the settings that are mutated as we parse user data. */
interface ContextSettings {
/** Indicates what kind of API method this data came from. */
readonly dataSource: UserDataSource;
/** The name of the method the user called to create the ParseContext. */
readonly methodName: string;
/** The document the user is attempting to modify, if that applies. */
readonly targetDoc?: DocumentKey;
/**
* A path within the object being parsed. This could be an empty path (in
* which case the context represents the root of the data being parsed), or a
* nonempty path (indicating the context represents a nested location within
* the data).
*/
readonly path?: InternalFieldPath;
/**
* Whether or not this context corresponds to an element of an array.
* If not set, elements are treated as if they were outside of arrays.
*/
readonly arrayElement?: boolean;
/**
* Whether or not a converter was specified in this context. If true, error
* messages will reference the converter when invalid data is provided.
*/
readonly hasConverter?: boolean;
}
/** A "context" object passed around while parsing user data. */
declare class ParseContextImpl implements ParseContext {
readonly settings: ContextSettings;
readonly databaseId: DatabaseId;
readonly serializer: JsonProtoSerializer;
readonly ignoreUndefinedProperties: boolean;
readonly fieldTransforms: FieldTransform[];
readonly fieldMask: InternalFieldPath[];
/**
* Initializes a ParseContext with the given source and path.
*
* @param settings - The settings for the parser.
* @param databaseId - The database ID of the Firestore instance.
* @param serializer - The serializer to use to generate the Value proto.
* @param ignoreUndefinedProperties - Whether to ignore undefined properties
* rather than throw.
* @param fieldTransforms - A mutable list of field transforms encountered
* while parsing the data.
* @param fieldMask - A mutable list of field paths encountered while parsing
* the data.
*
* TODO(b/34871131): We don't support array paths right now, so path can be
* null to indicate the context represents any location within an array (in
* which case certain features will not work and errors will be somewhat
* compromised).
*/
constructor(settings: ContextSettings, databaseId: DatabaseId, serializer: JsonProtoSerializer, ignoreUndefinedProperties: boolean, fieldTransforms?: FieldTransform[], fieldMask?: InternalFieldPath[]);
get path(): InternalFieldPath | undefined;
get dataSource(): UserDataSource;
/** Returns a new context with the specified settings overwritten. */
contextWith(configuration: Partial<ContextSettings>): ParseContextImpl;
childContextForField(field: string): ParseContextImpl;
childContextForFieldPath(field: InternalFieldPath): ParseContextImpl;
childContextForArray(index: number): ParseContextImpl;
createError(reason: string): FirestoreError;
/** Returns 'true' if 'fieldPath' was traversed when creating this context. */
contains(fieldPath: InternalFieldPath): boolean;
private validatePath;
private validatePathSegment;
}
/**
* Helper for parsing raw user input (provided via the API) into internal model
* classes.
*/
export declare class UserDataReader {
private readonly databaseId;
private readonly ignoreUndefinedProperties;
private readonly serializer;
constructor(databaseId: DatabaseId, ignoreUndefinedProperties: boolean, serializer?: JsonProtoSerializer);
/** Creates a new top-level parse context. */
createContext(dataSource: UserDataSource, methodName: string, targetDoc?: DocumentKey, hasConverter?: boolean): ParseContextImpl;
}
export declare function newUserDataReader(firestore: Firestore): UserDataReader;
/** Parse document data from a set() call. */
export declare function parseSetData(userDataReader: UserDataReader, methodName: string, targetDoc: DocumentKey, input: unknown, hasConverter: boolean, options?: SetOptions): ParsedSetData;
export declare class DeleteFieldValueImpl extends FieldValue {
_toFieldTransform(context: ParseContextImpl): null;
isEqual(other: FieldValue): boolean;
}
export declare class ServerTimestampFieldValueImpl extends FieldValue {
_toFieldTransform(context: ParseContextImpl): FieldTransform;
isEqual(other: FieldValue): boolean;
}
export declare class ArrayUnionFieldValueImpl extends FieldValue {
private readonly _elements;
constructor(methodName: string, _elements: unknown[]);
_toFieldTransform(context: ParseContextImpl): FieldTransform;
isEqual(other: FieldValue): boolean;
}
export declare class ArrayRemoveFieldValueImpl extends FieldValue {
private readonly _elements;
constructor(methodName: string, _elements: unknown[]);
_toFieldTransform(context: ParseContextImpl): FieldTransform;
isEqual(other: FieldValue): boolean;
}
export declare class NumericIncrementFieldValueImpl extends FieldValue {
private readonly _operand;
constructor(methodName: string, _operand: number);
_toFieldTransform(context: ParseContextImpl): FieldTransform;
isEqual(other: FieldValue): boolean;
}
/** Parse update data from an update() call. */
export declare function parseUpdateData(userDataReader: UserDataReader, methodName: string, targetDoc: DocumentKey, input: unknown): ParsedUpdateData;
/** Parse update data from a list of field/value arguments. */
export declare function parseUpdateVarargs(userDataReader: UserDataReader, methodName: string, targetDoc: DocumentKey, field: string | PublicFieldPath | Compat<PublicFieldPath>, value: unknown, moreFieldsAndValues: unknown[]): ParsedUpdateData;
/**
* Parse a "query value" (e.g. value in a where filter or a value in a cursor
* bound).
*
* @param allowArrays - Whether the query value is an array that may directly
* contain additional arrays (e.g. the operand of an `in` query).
*/
export declare function parseQueryValue(userDataReader: UserDataReader, methodName: string, input: unknown, allowArrays?: boolean): ProtoValue;
/**
* Parses user data to Protobuf Values.
*
* @param input - Data to be parsed.
* @param context - A context object representing the current path being parsed,
* the source of the data being parsed, etc.
* @returns The parsed value, or null if the value was a FieldValue sentinel
* that should not be included in the resulting parsed data.
*/
export declare function parseData(input: unknown, context: ParseContextImpl): ProtoValue | null;
/**
* Creates a new VectorValue proto value (using the internal format).
*/
export declare function parseVectorValue(value: VectorValue, context: ParseContextImpl): ProtoValue;
/**
* Helper that calls fromDotSeparatedString() but wraps any error thrown.
*/
export declare function fieldPathFromArgument(methodName: string, path: string | PublicFieldPath | Compat<PublicFieldPath>, targetDoc?: DocumentKey): InternalFieldPath;
/**
* Wraps fromDotSeparatedString with an error message about the method that
* was thrown.
* @param methodName - The publicly visible method name
* @param path - The dot-separated string form of a field path which will be
* split on dots.
* @param targetDoc - The document against which the field path will be
* evaluated.
*/
export declare function fieldPathFromDotSeparatedString(methodName: string, path: string, targetDoc?: DocumentKey): InternalFieldPath;
export {};

View file

@ -0,0 +1,48 @@
/**
* @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 { DocumentData } from '@firebase/firestore-types';
import { DatabaseId } from '../core/database_info';
import { DocumentKey } from '../model/document_key';
import { ApiClientObjectMap, MapValue as ProtoMapValue, Value, Value as ProtoValue } from '../protos/firestore_proto_api';
import { ByteString } from '../util/byte_string';
import { VectorValue } from './vector_value';
export declare type ServerTimestampBehavior = 'estimate' | 'previous' | 'none';
/**
* Converts Firestore's internal types to the JavaScript types that we expose
* to the user.
*
* @internal
*/
export declare abstract class AbstractUserDataWriter {
convertValue(value: ProtoValue, serverTimestampBehavior?: ServerTimestampBehavior): unknown;
private convertObject;
/**
* @internal
*/
convertObjectMap(fields: ApiClientObjectMap<Value> | undefined, serverTimestampBehavior?: ServerTimestampBehavior): DocumentData;
/**
* @internal
*/
convertVectorValue(mapValue: ProtoMapValue): VectorValue;
private convertGeoPoint;
private convertArray;
private convertServerTimestamp;
private convertTimestamp;
protected convertDocumentKey(name: string, expectedDatabaseId: DatabaseId): DocumentKey;
protected abstract convertReference(name: string): unknown;
protected abstract convertBytes(bytes: ByteString): unknown;
}

View file

@ -0,0 +1,38 @@
/**
* @license
* Copyright 2024 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.
*/
/**
* Represents a vector type in Firestore documents.
* Create an instance with {@link FieldValue.vector}.
*
* @class VectorValue
*/
export declare class VectorValue {
private readonly _values;
/**
* @private
* @internal
*/
constructor(values: number[] | undefined);
/**
* Returns a copy of the raw number array form of the vector.
*/
toArray(): number[];
/**
* Returns `true` if the two VectorValue has the same raw number arrays, returns `false` otherwise.
*/
isEqual(other: VectorValue): boolean;
}

View file

@ -0,0 +1,125 @@
/**
* @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 { Compat } from '@firebase/util';
import { Mutation } from '../model/mutation';
import { Firestore } from './database';
import { FieldPath } from './field_path';
import { DocumentData, DocumentReference, PartialWithFieldValue, SetOptions, UpdateData, WithFieldValue } from './reference';
/**
* A write batch, used to perform multiple writes as a single atomic unit.
*
* A `WriteBatch` object can be acquired by calling {@link writeBatch}. It
* provides methods for adding writes to the write batch. None of the writes
* will be committed (or visible locally) until {@link WriteBatch.commit} is
* called.
*/
export declare class WriteBatch {
private readonly _firestore;
private readonly _commitHandler;
private readonly _dataReader;
private _mutations;
private _committed;
/** @hideconstructor */
constructor(_firestore: Firestore, _commitHandler: (m: Mutation[]) => Promise<void>);
/**
* Writes to the document referred to by the provided {@link
* DocumentReference}. If the document does not exist yet, it will be created.
*
* @param documentRef - A reference to the document to be set.
* @param data - An object of the fields and values for the document.
* @returns This `WriteBatch` instance. Used for chaining method calls.
*/
set<AppModelType, DbModelType extends DocumentData>(documentRef: DocumentReference<AppModelType, DbModelType>, data: WithFieldValue<AppModelType>): WriteBatch;
/**
* Writes to the document referred to by the provided {@link
* DocumentReference}. If the document does not exist yet, it will be created.
* If you provide `merge` or `mergeFields`, the provided data can be merged
* into an existing document.
*
* @param documentRef - A reference to the document to be set.
* @param data - An object of the fields and values for the document.
* @param options - An object to configure the set behavior.
* @throws Error - If the provided input is not a valid Firestore document.
* @returns This `WriteBatch` instance. Used for chaining method calls.
*/
set<AppModelType, DbModelType extends DocumentData>(documentRef: DocumentReference<AppModelType, DbModelType>, data: PartialWithFieldValue<AppModelType>, options: SetOptions): WriteBatch;
/**
* Updates fields in the document referred to by the provided {@link
* DocumentReference}. The update will fail if applied to a document that does
* not exist.
*
* @param documentRef - A reference to the document to be updated.
* @param data - An object containing the fields and values with which to
* update the document. Fields can contain dots to reference nested fields
* within the document.
* @throws Error - If the provided input is not valid Firestore data.
* @returns This `WriteBatch` instance. Used for chaining method calls.
*/
update<AppModelType, DbModelType extends DocumentData>(documentRef: DocumentReference<AppModelType, DbModelType>, data: UpdateData<DbModelType>): WriteBatch;
/**
* Updates fields in the document referred to by this {@link
* DocumentReference}. The update will fail if applied to a document that does
* not exist.
*
* Nested fields can be update by providing dot-separated field path strings
* or by providing `FieldPath` objects.
*
* @param documentRef - A reference to the document to be updated.
* @param field - The first field to update.
* @param value - The first value.
* @param moreFieldsAndValues - Additional key value pairs.
* @throws Error - If the provided input is not valid Firestore data.
* @returns This `WriteBatch` instance. Used for chaining method calls.
*/
update<AppModelType, DbModelType extends DocumentData>(documentRef: DocumentReference<AppModelType, DbModelType>, field: string | FieldPath, value: unknown, ...moreFieldsAndValues: unknown[]): WriteBatch;
/**
* Deletes the document referred to by the provided {@link DocumentReference}.
*
* @param documentRef - A reference to the document to be deleted.
* @returns This `WriteBatch` instance. Used for chaining method calls.
*/
delete<AppModelType, DbModelType extends DocumentData>(documentRef: DocumentReference<AppModelType, DbModelType>): WriteBatch;
/**
* Commits all of the writes in this write batch as a single atomic unit.
*
* The result of these writes will only be reflected in document reads that
* occur after the returned promise resolves. If the client is offline, the
* write fails. If you would like to see local modifications or buffer writes
* until the client is online, use the full Firestore SDK.
*
* @returns A `Promise` resolved once all of the writes in the batch have been
* successfully written to the backend as an atomic unit (note that it won't
* resolve while you're offline).
*/
commit(): Promise<void>;
private _verifyNotCommitted;
}
export declare function validateReference<AppModelType, DbModelType extends DocumentData>(documentRef: DocumentReference<AppModelType, DbModelType> | Compat<DocumentReference<AppModelType, DbModelType>>, firestore: Firestore): DocumentReference<AppModelType, DbModelType>;
/**
* Creates a write batch, used for performing multiple writes as a single
* atomic operation. The maximum number of writes allowed in a single WriteBatch
* is 500.
*
* The result of these writes will only be reflected in document reads that
* occur after the returned promise resolves. If the client is offline, the
* write fails. If you would like to see local modifications or buffer writes
* until the client is online, use the full Firestore SDK.
*
* @returns A `WriteBatch` that can be used to atomically execute multiple
* writes.
*/
export declare function writeBatch(firestore: Firestore): WriteBatch;

View file

@ -0,0 +1,44 @@
/**
* @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 { BundleMetadata, NamedQuery } from '../core/bundle';
import { NamedQuery as ProtoNamedQuery, BundleMetadata as ProtoBundleMetadata } from '../protos/firestore_bundle_proto';
import { PersistencePromise } from './persistence_promise';
import { PersistenceTransaction } from './persistence_transaction';
/**
* Provides interfaces to save and read Firestore bundles.
*/
export interface BundleCache {
/**
* Gets the saved `BundleMetadata` for a given `bundleId`, returns undefined
* if no bundle metadata is found under the given id.
*/
getBundleMetadata(transaction: PersistenceTransaction, bundleId: string): PersistencePromise<BundleMetadata | undefined>;
/**
* Saves a `BundleMetadata` from a bundle into local storage, using its id as
* the persistent key.
*/
saveBundleMetadata(transaction: PersistenceTransaction, metadata: ProtoBundleMetadata): PersistencePromise<void>;
/**
* Gets a saved `NamedQuery` for the given query name. Returns undefined if
* no queries are found under the given name.
*/
getNamedQuery(transaction: PersistenceTransaction, queryName: string): PersistencePromise<NamedQuery | undefined>;
/**
* Saves a `NamedQuery` from a bundle, using its name as the persistent key.
*/
saveNamedQuery(transaction: PersistenceTransaction, query: ProtoNamedQuery): PersistencePromise<void>;
}

View file

@ -0,0 +1,76 @@
/**
* @license
* Copyright 2022 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 { DocumentKeySet, MutationMap, OverlayMap } from '../model/collections';
import { DocumentKey } from '../model/document_key';
import { Overlay } from '../model/overlay';
import { ResourcePath } from '../model/path';
import { PersistencePromise } from './persistence_promise';
import { PersistenceTransaction } from './persistence_transaction';
/**
* Provides methods to read and write document overlays.
*
* An overlay is a saved mutation, that gives a local view of a document when
* applied to the remote version of the document.
*
* Each overlay stores the largest batch ID that is included in the overlay,
* which allows us to remove the overlay once all batches leading up to it have
* been acknowledged.
*/
export interface DocumentOverlayCache {
/**
* Gets the saved overlay mutation for the given document key.
* Returns null if there is no overlay for that key.
*/
getOverlay(transaction: PersistenceTransaction, key: DocumentKey): PersistencePromise<Overlay | null>;
/**
* Gets the saved overlay mutation for the given document keys. Skips keys for
* which there are no overlays.
*/
getOverlays(transaction: PersistenceTransaction, keys: DocumentKey[]): PersistencePromise<OverlayMap>;
/**
* Saves the given document mutation map to persistence as overlays.
* All overlays will have their largest batch id set to `largestBatchId`.
*/
saveOverlays(transaction: PersistenceTransaction, largestBatchId: number, overlays: MutationMap): PersistencePromise<void>;
/** Removes overlays for the given document keys and batch ID. */
removeOverlaysForBatchId(transaction: PersistenceTransaction, documentKeys: DocumentKeySet, batchId: number): PersistencePromise<void>;
/**
* Returns all saved overlays for the given collection.
*
* @param transaction - The persistence transaction to use for this operation.
* @param collection - The collection path to get the overlays for.
* @param sinceBatchId - The minimum batch ID to filter by (exclusive).
* Only overlays that contain a change past `sinceBatchId` are returned.
* @returns Mapping of each document key in the collection to its overlay.
*/
getOverlaysForCollection(transaction: PersistenceTransaction, collection: ResourcePath, sinceBatchId: number): PersistencePromise<OverlayMap>;
/**
* Returns `count` overlays with a batch ID higher than `sinceBatchId` for the
* provided collection group, processed by ascending batch ID. The method
* always returns all overlays for a batch even if the last batch contains
* more documents than the remaining limit.
*
* @param transaction - The persistence transaction used for this operation.
* @param collectionGroup - The collection group to get the overlays for.
* @param sinceBatchId - The minimum batch ID to filter by (exclusive).
* Only overlays that contain a change past `sinceBatchId` are returned.
* @param count - The number of overlays to return. Can be exceeded if the last
* batch contains more entries.
* @return Mapping of each document key in the collection group to its overlay.
*/
getOverlaysForCollectionGroup(transaction: PersistenceTransaction, collectionGroup: string, sinceBatchId: number, count: number): PersistencePromise<OverlayMap>;
}

View file

@ -0,0 +1,73 @@
/**
* @license
* Copyright 2017 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 { ResourcePath } from '../model/path';
/**
* Helpers for dealing with resource paths stored in IndexedDB.
*
* Resource paths in their canonical string form do not sort as the server
* sorts them. Specifically the server splits paths into segments first and then
* sorts, putting end-of-segment before any character. In a UTF-8 string
* encoding the slash ('/') that denotes the end-of-segment naturally comes
* after other characters so the intent here is to encode the path delimiters in
* such a way that the resulting strings sort naturally.
*
* Resource paths are also used for prefix scans so it's important to
* distinguish whole segments from any longer segments of which they might be a
* prefix. For example, it's important to make it possible to scan documents in
* a collection "foo" without encountering documents in a collection "foobar".
*
* Separate from the concerns about resource path ordering and separation,
* On Android, SQLite imposes additional restrictions since it does not handle
* keys with embedded NUL bytes particularly well. Rather than change the
* implementation we keep the encoding identical to keep the ports similar.
*
* Taken together this means resource paths when encoded for storage in
* IndexedDB have the following characteristics:
*
* * Segment separators ("/") sort before everything else.
* * All paths have a trailing separator.
* * NUL bytes do not exist in the output, since IndexedDB doesn't treat them
* well.
*
* Therefore resource paths are encoded into string form using the following
* rules:
*
* * '\x01' is used as an escape character.
* * Path separators are encoded as "\x01\x01"
* * NUL bytes are encoded as "\x01\x10"
* * '\x01' is encoded as "\x01\x11"
*
* This encoding leaves some room between path separators and the NUL byte
* just in case we decide to support integer document ids after all.
*
* Note that characters treated specially by the backend ('.', '/', and '~')
* are not treated specially here. This class assumes that any unescaping of
* resource path strings into actual ResourcePath objects will handle these
* characters there.
*/
export declare type EncodedResourcePath = string;
/**
* Encodes a resource path into a IndexedDb-compatible string form.
*/
export declare function encodeResourcePath(path: ResourcePath): EncodedResourcePath;
/**
* Decodes the given IndexedDb-compatible string form of a resource path into
* a ResourcePath instance. Note that this method is not suitable for use with
* decoding resource names from the server; those are One Platform format
* strings.
*/
export declare function decodeResourcePath(path: EncodedResourcePath): ResourcePath;

View file

@ -0,0 +1,39 @@
/**
* @license
* Copyright 2024 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 { ByteString } from '../util/byte_string';
import { PersistencePromise } from './persistence_promise';
import { PersistenceTransaction } from './persistence_transaction';
/**
* General purpose cache for global values.
*
* Global state that cuts across components should be saved here. Following are contained herein:
*
* `sessionToken` tracks server interaction across Listen and Write streams. This facilitates cache
* synchronization and invalidation.
*/
export interface GlobalsCache {
/**
* Gets session token.
*/
getSessionToken(transaction: PersistenceTransaction): PersistencePromise<ByteString>;
/**
* Sets session token.
*
* @param sessionToken - The new session token.
*/
setSessionToken(transaction: PersistenceTransaction, sessionToken: ByteString): PersistencePromise<void>;
}

View file

@ -0,0 +1,44 @@
import { AsyncQueue } from '../util/async_queue';
import { LocalStore } from './local_store';
import { Persistence, Scheduler } from './persistence';
/** This class is responsible for the scheduling of Index Backfiller. */
export declare class IndexBackfillerScheduler implements Scheduler {
private readonly asyncQueue;
private readonly backfiller;
private task;
constructor(asyncQueue: AsyncQueue, backfiller: IndexBackfiller);
start(): void;
stop(): void;
get started(): boolean;
private schedule;
}
/** Implements the steps for backfilling indexes. */
export declare class IndexBackfiller {
/**
* LocalStore provides access to IndexManager and LocalDocumentView.
* These properties will update when the user changes. Consequently,
* making a local copy of IndexManager and LocalDocumentView will require
* updates over time. The simpler solution is to rely on LocalStore to have
* an up-to-date references to IndexManager and LocalDocumentStore.
*/
private readonly localStore;
private readonly persistence;
constructor(
/**
* LocalStore provides access to IndexManager and LocalDocumentView.
* These properties will update when the user changes. Consequently,
* making a local copy of IndexManager and LocalDocumentView will require
* updates over time. The simpler solution is to rely on LocalStore to have
* an up-to-date references to IndexManager and LocalDocumentStore.
*/
localStore: LocalStore, persistence: Persistence);
backfill(maxDocumentsToProcess?: number): Promise<number>;
/** Writes index entries until the cap is reached. Returns the number of documents processed. */
private writeIndexEntries;
/**
* Writes entries for the provided collection group. Returns the number of documents processed.
*/
private writeEntriesForCollectionGroup;
/** Returns the next offset based on the provided documents. */
private getNewOffset;
}

View file

@ -0,0 +1,124 @@
/**
* @license
* Copyright 2019 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 { Target } from '../core/target';
import { DocumentMap } from '../model/collections';
import { DocumentKey } from '../model/document_key';
import { FieldIndex, IndexOffset } from '../model/field_index';
import { ResourcePath } from '../model/path';
import { PersistencePromise } from './persistence_promise';
import { PersistenceTransaction } from './persistence_transaction';
/** Represents the index state as it relates to a particular target. */
export declare const enum IndexType {
/** Indicates that no index could be found for serving the target. */
NONE = 0,
/**
* Indicates that only a "partial index" could be found for serving the
* target. A partial index is one which does not have a segment for every
* filter/orderBy in the target.
*/
PARTIAL = 1,
/**
* Indicates that a "full index" could be found for serving the target. A full
* index is one which has a segment for every filter/orderBy in the target.
*/
FULL = 2
}
export declare function displayNameForIndexType(indexType: IndexType): string;
/**
* Represents a set of indexes that are used to execute queries efficiently.
*
* Currently the only index is a [collection id] =&gt; [parent path] index, used
* to execute Collection Group queries.
*/
export interface IndexManager {
/**
* Creates an index entry mapping the collectionId (last segment of the path)
* to the parent path (either the containing document location or the empty
* path for root-level collections). Index entries can be retrieved via
* getCollectionParents().
*
* NOTE: Currently we don't remove index entries. If this ends up being an
* issue we can devise some sort of GC strategy.
*/
addToCollectionParentIndex(transaction: PersistenceTransaction, collectionPath: ResourcePath): PersistencePromise<void>;
/**
* Retrieves all parent locations containing the given collectionId, as a
* list of paths (each path being either a document location or the empty
* path for a root-level collection).
*/
getCollectionParents(transaction: PersistenceTransaction, collectionId: string): PersistencePromise<ResourcePath[]>;
/**
* Adds a field path index.
*
* Values for this index are persisted via the index backfill, which runs
* asynchronously in the background. Once the first values are written,
* an index can be used to serve partial results for any matching queries.
* Any unindexed portion of the database will continue to be served via
* collection scons.
*/
addFieldIndex(transaction: PersistenceTransaction, index: FieldIndex): PersistencePromise<void>;
/** Removes the given field index and deletes all index values. */
deleteFieldIndex(transaction: PersistenceTransaction, index: FieldIndex): PersistencePromise<void>;
/** Removes all field indexes and deletes all index values. */
deleteAllFieldIndexes(transaction: PersistenceTransaction): PersistencePromise<void>;
/** Creates a full matched field index which serves the given target. */
createTargetIndexes(transaction: PersistenceTransaction, target: Target): PersistencePromise<void>;
/**
* Returns a list of field indexes that correspond to the specified collection
* group.
*
* @param collectionGroup The collection group to get matching field indexes
* for.
* @return A collection of field indexes for the specified collection group.
*/
getFieldIndexes(transaction: PersistenceTransaction, collectionGroup: string): PersistencePromise<FieldIndex[]>;
/** Returns all configured field indexes. */
getFieldIndexes(transaction: PersistenceTransaction): PersistencePromise<FieldIndex[]>;
/**
* Returns the type of index (if any) that can be used to serve the given
* target.
*/
getIndexType(transaction: PersistenceTransaction, target: Target): PersistencePromise<IndexType>;
/**
* Returns the documents that match the given target based on the provided
* index or `null` if the target does not have a matching index.
*/
getDocumentsMatchingTarget(transaction: PersistenceTransaction, target: Target): PersistencePromise<DocumentKey[] | null>;
/**
* Returns the next collection group to update. Returns `null` if no group
* exists.
*/
getNextCollectionGroupToUpdate(transaction: PersistenceTransaction): PersistencePromise<string | null>;
/**
* Sets the collection group's latest read time.
*
* This method updates the index offset for all field indices for the
* collection group and increments their sequence number. Subsequent calls to
* `getNextCollectionGroupToUpdate()` will return a different collection group
* (unless only one collection group is configured).
*/
updateCollectionGroup(transaction: PersistenceTransaction, collectionGroup: string, offset: IndexOffset): PersistencePromise<void>;
/** Updates the index entries for the provided documents. */
updateIndexEntries(transaction: PersistenceTransaction, documents: DocumentMap): PersistencePromise<void>;
/**
* Iterates over all field indexes that are used to serve the given target,
* and returns the minimum offset of them all.
*/
getMinOffset(transaction: PersistenceTransaction, target: Target): PersistencePromise<IndexOffset>;
/** Returns the minimum offset for the given collection group. */
getMinOffsetFromCollectionGroup(transaction: PersistenceTransaction, collectionGroup: string): PersistencePromise<IndexOffset>;
}

View file

@ -0,0 +1,27 @@
/**
* @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 { BundleMetadata, NamedQuery } from '../core/bundle';
import { BundleMetadata as ProtoBundleMetadata, NamedQuery as ProtoNamedQuery } from '../protos/firestore_bundle_proto';
import { BundleCache } from './bundle_cache';
import { PersistencePromise } from './persistence_promise';
import { PersistenceTransaction } from './persistence_transaction';
export declare class IndexedDbBundleCache implements BundleCache {
getBundleMetadata(transaction: PersistenceTransaction, bundleId: string): PersistencePromise<BundleMetadata | undefined>;
saveBundleMetadata(transaction: PersistenceTransaction, bundleMetadata: ProtoBundleMetadata): PersistencePromise<void>;
getNamedQuery(transaction: PersistenceTransaction, queryName: string): PersistencePromise<NamedQuery | undefined>;
saveNamedQuery(transaction: PersistenceTransaction, query: ProtoNamedQuery): PersistencePromise<void>;
}

View file

@ -0,0 +1,45 @@
/**
* @license
* Copyright 2022 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 { User } from '../auth/user';
import { DocumentKeySet, MutationMap, OverlayMap } from '../model/collections';
import { DocumentKey } from '../model/document_key';
import { Overlay } from '../model/overlay';
import { ResourcePath } from '../model/path';
import { DocumentOverlayCache } from './document_overlay_cache';
import { LocalSerializer } from './local_serializer';
import { PersistencePromise } from './persistence_promise';
import { PersistenceTransaction } from './persistence_transaction';
/**
* Implementation of DocumentOverlayCache using IndexedDb.
*/
export declare class IndexedDbDocumentOverlayCache implements DocumentOverlayCache {
private readonly serializer;
private readonly userId;
/**
* @param serializer - The document serializer.
* @param userId - The userId for which we are accessing overlays.
*/
constructor(serializer: LocalSerializer, userId: string);
static forUser(serializer: LocalSerializer, user: User): IndexedDbDocumentOverlayCache;
getOverlay(transaction: PersistenceTransaction, key: DocumentKey): PersistencePromise<Overlay | null>;
getOverlays(transaction: PersistenceTransaction, keys: DocumentKey[]): PersistencePromise<OverlayMap>;
saveOverlays(transaction: PersistenceTransaction, largestBatchId: number, overlays: MutationMap): PersistencePromise<void>;
removeOverlaysForBatchId(transaction: PersistenceTransaction, documentKeys: DocumentKeySet, batchId: number): PersistencePromise<void>;
getOverlaysForCollection(transaction: PersistenceTransaction, collection: ResourcePath, sinceBatchId: number): PersistencePromise<OverlayMap>;
getOverlaysForCollectionGroup(transaction: PersistenceTransaction, collectionGroup: string, sinceBatchId: number, count: number): PersistencePromise<OverlayMap>;
private saveOverlay;
}

View file

@ -0,0 +1,25 @@
/**
* @license
* Copyright 2024 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 { ByteString } from '../util/byte_string';
import { GlobalsCache } from './globals_cache';
import { PersistencePromise } from './persistence_promise';
import { PersistenceTransaction } from './persistence_transaction';
export declare class IndexedDbGlobalsCache implements GlobalsCache {
private globalsStore;
getSessionToken(txn: PersistenceTransaction): PersistencePromise<ByteString>;
setSessionToken(txn: PersistenceTransaction, sessionToken: ByteString): PersistencePromise<void>;
}

View file

@ -0,0 +1,136 @@
/**
* @license
* Copyright 2019 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 { User } from '../auth/user';
import { DatabaseId } from '../core/database_info';
import { Target } from '../core/target';
import { IndexEntry } from '../index/index_entry';
import { DocumentMap } from '../model/collections';
import { DocumentKey } from '../model/document_key';
import { FieldIndex, IndexOffset } from '../model/field_index';
import { ResourcePath } from '../model/path';
import { IndexManager, IndexType } from './index_manager';
import { PersistencePromise } from './persistence_promise';
import { PersistenceTransaction } from './persistence_transaction';
/**
* A persisted implementation of IndexManager.
*
* PORTING NOTE: Unlike iOS and Android, the Web SDK does not memoize index
* data as it supports multi-tab access.
*/
export declare class IndexedDbIndexManager implements IndexManager {
private readonly databaseId;
/**
* An in-memory copy of the index entries we've already written since the SDK
* launched. Used to avoid re-writing the same entry repeatedly.
*
* This is *NOT* a complete cache of what's in persistence and so can never be
* used to satisfy reads.
*/
private collectionParentsCache;
private readonly uid;
/**
* Maps from a target to its equivalent list of sub-targets. Each sub-target
* contains only one term from the target's disjunctive normal form (DNF).
*/
private targetToDnfSubTargets;
constructor(user: User, databaseId: DatabaseId);
/**
* Adds a new entry to the collection parent index.
*
* Repeated calls for the same collectionPath should be avoided within a
* transaction as IndexedDbIndexManager only caches writes once a transaction
* has been committed.
*/
addToCollectionParentIndex(transaction: PersistenceTransaction, collectionPath: ResourcePath): PersistencePromise<void>;
getCollectionParents(transaction: PersistenceTransaction, collectionId: string): PersistencePromise<ResourcePath[]>;
addFieldIndex(transaction: PersistenceTransaction, index: FieldIndex): PersistencePromise<void>;
deleteFieldIndex(transaction: PersistenceTransaction, index: FieldIndex): PersistencePromise<void>;
deleteAllFieldIndexes(transaction: PersistenceTransaction): PersistencePromise<void>;
createTargetIndexes(transaction: PersistenceTransaction, target: Target): PersistencePromise<void>;
getDocumentsMatchingTarget(transaction: PersistenceTransaction, target: Target): PersistencePromise<DocumentKey[] | null>;
private getSubTargets;
/**
* Constructs a key range query on `DbIndexEntryStore` that unions all
* bounds.
*/
private generateIndexRanges;
/** Generates the lower bound for `arrayValue` and `directionalValue`. */
private generateLowerBound;
/** Generates the upper bound for `arrayValue` and `directionalValue`. */
private generateUpperBound;
private getFieldIndex;
getIndexType(transaction: PersistenceTransaction, target: Target): PersistencePromise<IndexType>;
/**
* Returns the byte encoded form of the directional values in the field index.
* Returns `null` if the document does not have all fields specified in the
* index.
*/
private encodeDirectionalElements;
/** Encodes a single value to the ascending index format. */
private encodeSingleElement;
/**
* Returns an encoded form of the document key that sorts based on the key
* ordering of the field index.
*/
private encodeDirectionalKey;
/**
* Encodes the given field values according to the specification in `target`.
* For IN queries, a list of possible values is returned.
*/
private encodeValues;
/**
* Encodes the given bounds according to the specification in `target`. For IN
* queries, a list of possible values is returned.
*/
private encodeBound;
/** Returns the byte representation for the provided encoders. */
private getEncodedBytes;
/**
* Creates a separate encoder for each element of an array.
*
* The method appends each value to all existing encoders (e.g. filter("a",
* "==", "a1").filter("b", "in", ["b1", "b2"]) becomes ["a1,b1", "a1,b2"]). A
* list of new encoders is returned.
*/
private expandIndexValues;
private isInFilter;
getFieldIndexes(transaction: PersistenceTransaction, collectionGroup?: string): PersistencePromise<FieldIndex[]>;
getNextCollectionGroupToUpdate(transaction: PersistenceTransaction): PersistencePromise<string | null>;
updateCollectionGroup(transaction: PersistenceTransaction, collectionGroup: string, offset: IndexOffset): PersistencePromise<void>;
updateIndexEntries(transaction: PersistenceTransaction, documents: DocumentMap): PersistencePromise<void>;
private addIndexEntry;
private deleteIndexEntry;
private getExistingIndexEntries;
/** Creates the index entries for the given document. */
private computeIndexEntries;
/**
* Updates the index entries for the provided document by deleting entries
* that are no longer referenced in `newEntries` and adding all newly added
* entries.
*/
private updateEntries;
private getNextSequenceNumber;
/**
* Returns a new set of IDB ranges that splits the existing range and excludes
* any values that match the `notInValue` from these ranges. As an example,
* '[foo > 2 && foo != 3]` becomes `[foo > 2 && < 3, foo > 3]`.
*/
private createRange;
isRangeMatchable(lowerBound: IndexEntry, upperBound: IndexEntry): boolean;
getMinOffsetFromCollectionGroup(transaction: PersistenceTransaction, collectionGroup: string): PersistencePromise<IndexOffset>;
getMinOffset(transaction: PersistenceTransaction, target: Target): PersistencePromise<IndexOffset>;
}

View file

@ -0,0 +1,22 @@
/**
* @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 { LruDelegate, LruGarbageCollector } from './lru_garbage_collector';
import { ReferenceDelegate } from './persistence';
/** Provides LRU functionality for IndexedDB persistence. */
export interface IndexedDbLruDelegate extends ReferenceDelegate, LruDelegate {
readonly garbageCollector: LruGarbageCollector;
}

View file

@ -0,0 +1,56 @@
/**
* @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 { ListenSequenceNumber, TargetId } from '../core/types';
import { DocumentKey } from '../model/document_key';
import { IndexedDbLruDelegate } from './indexeddb_lru_delegate';
import { ActiveTargets, LruGarbageCollector, LruParams } from './lru_garbage_collector';
import { Persistence } from './persistence';
import { PersistencePromise } from './persistence_promise';
import { PersistenceTransaction } from './persistence_transaction';
import { TargetData } from './target_data';
/** Provides LRU functionality for IndexedDB persistence. */
export declare class IndexedDbLruDelegateImpl implements IndexedDbLruDelegate {
private readonly db;
readonly garbageCollector: LruGarbageCollector;
constructor(db: Persistence, params: LruParams);
getSequenceNumberCount(txn: PersistenceTransaction): PersistencePromise<number>;
private orphanedDocumentCount;
forEachTarget(txn: PersistenceTransaction, f: (q: TargetData) => void): PersistencePromise<void>;
forEachOrphanedDocumentSequenceNumber(txn: PersistenceTransaction, f: (sequenceNumber: ListenSequenceNumber) => void): PersistencePromise<void>;
addReference(txn: PersistenceTransaction, targetId: TargetId, key: DocumentKey): PersistencePromise<void>;
removeReference(txn: PersistenceTransaction, targetId: TargetId, key: DocumentKey): PersistencePromise<void>;
removeTargets(txn: PersistenceTransaction, upperBound: ListenSequenceNumber, activeTargetIds: ActiveTargets): PersistencePromise<number>;
markPotentiallyOrphaned(txn: PersistenceTransaction, key: DocumentKey): PersistencePromise<void>;
/**
* Returns true if anything would prevent this document from being garbage
* collected, given that the document in question is not present in any
* targets and has a sequence number less than or equal to the upper bound for
* the collection run.
*/
private isPinned;
removeOrphanedDocuments(txn: PersistenceTransaction, upperBound: ListenSequenceNumber): PersistencePromise<number>;
removeTarget(txn: PersistenceTransaction, targetData: TargetData): PersistencePromise<void>;
updateLimboDocument(txn: PersistenceTransaction, key: DocumentKey): PersistencePromise<void>;
/**
* Call provided function for each document in the cache that is 'orphaned'. Orphaned
* means not a part of any target, so the only entry in the target-document index for
* that document will be the sentinel row (targetId 0), which will also have the sequence
* number for the last time the document was accessed.
*/
private forEachOrphanedDocument;
getCacheSize(txn: PersistenceTransaction): PersistencePromise<number>;
}

View file

@ -0,0 +1,35 @@
/**
* @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 { DocumentKey } from '../model/document_key';
import { DbRemoteDocument } from './indexeddb_schema';
import { DbRemoteDocument as DbRemoteDocumentLegacy } from './indexeddb_schema_legacy';
import { PersistencePromise } from './persistence_promise';
import { SimpleDbTransaction } from './simple_db';
/**
* Delete a mutation batch and the associated document mutations.
* @returns A PersistencePromise of the document mutations that were removed.
*/
export declare function removeMutationBatch(txn: SimpleDbTransaction, userId: string, batch: {
batchId: number;
mutations: Array<{
key: DocumentKey;
}>;
}): PersistencePromise<DocumentKey[]>;
/**
* Returns an approximate size for the given document.
*/
export declare function dbDocumentSize(doc: DbRemoteDocument | DbRemoteDocumentLegacy | null): number;

View file

@ -0,0 +1,99 @@
/**
* @license
* Copyright 2017 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 { User } from '../auth/user';
import { Query } from '../core/query';
import { BatchId } from '../core/types';
import { Timestamp } from '../lite-api/timestamp';
import { DocumentKeySet } from '../model/collections';
import { DocumentKey } from '../model/document_key';
import { Mutation } from '../model/mutation';
import { MutationBatch } from '../model/mutation_batch';
import { SortedMap } from '../util/sorted_map';
import { IndexManager } from './index_manager';
import { LocalSerializer } from './local_serializer';
import { MutationQueue } from './mutation_queue';
import { ReferenceDelegate } from './persistence';
import { PersistencePromise } from './persistence_promise';
import { PersistenceTransaction } from './persistence_transaction';
/** A mutation queue for a specific user, backed by IndexedDB. */
export declare class IndexedDbMutationQueue implements MutationQueue {
/**
* The normalized userId (e.g. null UID => "" userId) used to store /
* retrieve mutations.
*/
private userId;
private readonly serializer;
private readonly indexManager;
private readonly referenceDelegate;
/**
* Caches the document keys for pending mutation batches. If the mutation
* has been removed from IndexedDb, the cached value may continue to
* be used to retrieve the batch's document keys. To remove a cached value
* locally, `removeCachedMutationKeys()` should be invoked either directly
* or through `removeMutationBatches()`.
*
* With multi-tab, when the primary client acknowledges or rejects a mutation,
* this cache is used by secondary clients to invalidate the local
* view of the documents that were previously affected by the mutation.
*/
private documentKeysByBatchId;
constructor(
/**
* The normalized userId (e.g. null UID => "" userId) used to store /
* retrieve mutations.
*/
userId: string, serializer: LocalSerializer, indexManager: IndexManager, referenceDelegate: ReferenceDelegate);
/**
* Creates a new mutation queue for the given user.
* @param user - The user for which to create a mutation queue.
* @param serializer - The serializer to use when persisting to IndexedDb.
*/
static forUser(user: User, serializer: LocalSerializer, indexManager: IndexManager, referenceDelegate: ReferenceDelegate): IndexedDbMutationQueue;
checkEmpty(transaction: PersistenceTransaction): PersistencePromise<boolean>;
addMutationBatch(transaction: PersistenceTransaction, localWriteTime: Timestamp, baseMutations: Mutation[], mutations: Mutation[]): PersistencePromise<MutationBatch>;
lookupMutationBatch(transaction: PersistenceTransaction, batchId: BatchId): PersistencePromise<MutationBatch | null>;
/**
* Returns the document keys for the mutation batch with the given batchId.
* For primary clients, this method returns `null` after
* `removeMutationBatches()` has been called. Secondary clients return a
* cached result until `removeCachedMutationKeys()` is invoked.
*/
lookupMutationKeys(transaction: PersistenceTransaction, batchId: BatchId): PersistencePromise<DocumentKeySet | null>;
getNextMutationBatchAfterBatchId(transaction: PersistenceTransaction, batchId: BatchId): PersistencePromise<MutationBatch | null>;
getHighestUnacknowledgedBatchId(transaction: PersistenceTransaction): PersistencePromise<BatchId>;
getAllMutationBatches(transaction: PersistenceTransaction): PersistencePromise<MutationBatch[]>;
getAllMutationBatchesAffectingDocumentKey(transaction: PersistenceTransaction, documentKey: DocumentKey): PersistencePromise<MutationBatch[]>;
getAllMutationBatchesAffectingDocumentKeys(transaction: PersistenceTransaction, documentKeys: SortedMap<DocumentKey, unknown>): PersistencePromise<MutationBatch[]>;
getAllMutationBatchesAffectingQuery(transaction: PersistenceTransaction, query: Query): PersistencePromise<MutationBatch[]>;
private lookupMutationBatches;
removeMutationBatch(transaction: PersistenceTransaction, batch: MutationBatch): PersistencePromise<void>;
/**
* Clears the cached keys for a mutation batch. This method should be
* called by secondary clients after they process mutation updates.
*
* Note that this method does not have to be called from primary clients as
* the corresponding cache entries are cleared when an acknowledged or
* rejected batch is removed from the mutation queue.
*/
removeCachedMutationKeys(batchId: BatchId): void;
performConsistencyCheck(txn: PersistenceTransaction): PersistencePromise<void>;
containsKey(txn: PersistenceTransaction, key: DocumentKey): PersistencePromise<boolean>;
/** Returns the mutation queue's metadata from IndexedDb. */
private getMutationQueueMetadata;
}
/** Returns true if any mutation queue contains the given document. */
export declare function mutationQueuesContainKey(txn: PersistenceTransaction, docKey: DocumentKey): PersistencePromise<boolean>;

View file

@ -0,0 +1,270 @@
/**
* @license
* Copyright 2017 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 { User } from '../auth/user';
import { DatabaseId } from '../core/database_info';
import { SequenceNumberSyncer } from '../core/listen_sequence';
import { JsonProtoSerializer } from '../remote/serializer';
import { AsyncQueue } from '../util/async_queue';
import { DocumentLike, WindowLike } from '../util/types';
import { BundleCache } from './bundle_cache';
import { DocumentOverlayCache } from './document_overlay_cache';
import { GlobalsCache } from './globals_cache';
import { IndexManager } from './index_manager';
import { IndexedDbLruDelegateImpl } from './indexeddb_lru_delegate_impl';
import { IndexedDbMutationQueue } from './indexeddb_mutation_queue';
import { IndexedDbRemoteDocumentCache } from './indexeddb_remote_document_cache';
import { IndexedDbTargetCache } from './indexeddb_target_cache';
import { LruParams } from './lru_garbage_collector';
import { Persistence, PrimaryStateListener } from './persistence';
import { PersistencePromise } from './persistence_promise';
import { PersistenceTransaction, PersistenceTransactionMode } from './persistence_transaction';
import { ClientId } from './shared_client_state';
/**
* The name of the main (and currently only) IndexedDB database. This name is
* appended to the prefix provided to the IndexedDbPersistence constructor.
*/
export declare const MAIN_DATABASE = "main";
/**
* An IndexedDB-backed instance of Persistence. Data is stored persistently
* across sessions.
*
* On Web only, the Firestore SDKs support shared access to its persistence
* layer. This allows multiple browser tabs to read and write to IndexedDb and
* to synchronize state even without network connectivity. Shared access is
* currently optional and not enabled unless all clients invoke
* `enablePersistence()` with `{synchronizeTabs:true}`.
*
* In multi-tab mode, if multiple clients are active at the same time, the SDK
* will designate one client as the primary client. An effort is made to pick
* a visible, network-connected and active client, and this client is
* responsible for letting other clients know about its presence. The primary
* client writes a unique client-generated identifier (the client ID) to
* IndexedDbs owner store every 4 seconds. If the primary client fails to
* update this entry, another client can acquire the lease and take over as
* primary.
*
* Some persistence operations in the SDK are designated as primary-client only
* operations. This includes the acknowledgment of mutations and all updates of
* remote documents. The effects of these operations are written to persistence
* and then broadcast to other tabs via LocalStorage (see
* `WebStorageSharedClientState`), which then refresh their state from
* persistence.
*
* Similarly, the primary client listens to notifications sent by secondary
* clients to discover persistence changes written by secondary clients, such as
* the addition of new mutations and query targets.
*
* If multi-tab is not enabled and another tab already obtained the primary
* lease, IndexedDbPersistence enters a failed state and all subsequent
* operations will automatically fail.
*
* Additionally, there is an optimization so that when a tab is closed, the
* primary lease is released immediately (this is especially important to make
* sure that a refreshed tab is able to immediately re-acquire the primary
* lease). Unfortunately, IndexedDB cannot be reliably used in window.unload
* since it is an asynchronous API. So in addition to attempting to give up the
* lease, the leaseholder writes its client ID to a "zombiedClient" entry in
* LocalStorage which acts as an indicator that another tab should go ahead and
* take the primary lease immediately regardless of the current lease timestamp.
*
* TODO(b/114226234): Remove `synchronizeTabs` section when multi-tab is no
* longer optional.
*/
export declare class IndexedDbPersistence implements Persistence {
/**
* Whether to synchronize the in-memory state of multiple tabs and share
* access to local persistence.
*/
private readonly allowTabSynchronization;
private readonly persistenceKey;
private readonly clientId;
private readonly queue;
private readonly window;
private readonly document;
private readonly sequenceNumberSyncer;
/**
* If set to true, forcefully obtains database access. Existing tabs will
* no longer be able to access IndexedDB.
*/
private readonly forceOwningTab;
private readonly schemaVersion;
private simpleDb;
private listenSequence;
private _started;
private isPrimary;
private networkEnabled;
private dbName;
/** Our window.unload handler, if registered. */
private windowUnloadHandler;
private inForeground;
private serializer;
/** Our 'visibilitychange' listener if registered. */
private documentVisibilityHandler;
/** The client metadata refresh task. */
private clientMetadataRefresher;
/** The last time we garbage collected the client metadata object store. */
private lastGarbageCollectionTime;
/** A listener to notify on primary state changes. */
private primaryStateListener;
private readonly globalsCache;
private readonly targetCache;
private readonly remoteDocumentCache;
private readonly bundleCache;
private readonly webStorage;
readonly referenceDelegate: IndexedDbLruDelegateImpl;
constructor(
/**
* Whether to synchronize the in-memory state of multiple tabs and share
* access to local persistence.
*/
allowTabSynchronization: boolean, persistenceKey: string, clientId: ClientId, lruParams: LruParams, queue: AsyncQueue, window: WindowLike | null, document: DocumentLike | null, serializer: JsonProtoSerializer, sequenceNumberSyncer: SequenceNumberSyncer,
/**
* If set to true, forcefully obtains database access. Existing tabs will
* no longer be able to access IndexedDB.
*/
forceOwningTab: boolean, schemaVersion?: number);
/**
* Attempt to start IndexedDb persistence.
*
* @returns Whether persistence was enabled.
*/
start(): Promise<void>;
/**
* Registers a listener that gets called when the primary state of the
* instance changes. Upon registering, this listener is invoked immediately
* with the current primary state.
*
* PORTING NOTE: This is only used for Web multi-tab.
*/
setPrimaryStateListener(primaryStateListener: PrimaryStateListener): Promise<void>;
/**
* Registers a listener that gets called when the database receives a
* version change event indicating that it has deleted.
*
* PORTING NOTE: This is only used for Web multi-tab.
*/
setDatabaseDeletedListener(databaseDeletedListener: () => Promise<void>): void;
/**
* Adjusts the current network state in the client's metadata, potentially
* affecting the primary lease.
*
* PORTING NOTE: This is only used for Web multi-tab.
*/
setNetworkEnabled(networkEnabled: boolean): void;
/**
* Updates the client metadata in IndexedDb and attempts to either obtain or
* extend the primary lease for the local client. Asynchronously notifies the
* primary state listener if the client either newly obtained or released its
* primary lease.
*/
private updateClientMetadataAndTryBecomePrimary;
private verifyPrimaryLease;
private removeClientMetadata;
/**
* If the garbage collection threshold has passed, prunes the
* RemoteDocumentChanges and the ClientMetadata store based on the last update
* time of all clients.
*/
private maybeGarbageCollectMultiClientState;
/**
* Schedules a recurring timer to update the client metadata and to either
* extend or acquire the primary lease if the client is eligible.
*/
private scheduleClientMetadataAndPrimaryLeaseRefreshes;
/** Checks whether `client` is the local client. */
private isLocalClient;
/**
* Evaluate the state of all active clients and determine whether the local
* client is or can act as the holder of the primary lease. Returns whether
* the client is eligible for the lease, but does not actually acquire it.
* May return 'false' even if there is no active leaseholder and another
* (foreground) client should become leaseholder instead.
*/
private canActAsPrimary;
shutdown(): Promise<void>;
/**
* Returns clients that are not zombied and have an updateTime within the
* provided threshold.
*/
private filterActiveClients;
/**
* Returns the IDs of the clients that are currently active. If multi-tab
* is not supported, returns an array that only contains the local client's
* ID.
*
* PORTING NOTE: This is only used for Web multi-tab.
*/
getActiveClients(): Promise<ClientId[]>;
get started(): boolean;
getGlobalsCache(): GlobalsCache;
getMutationQueue(user: User, indexManager: IndexManager): IndexedDbMutationQueue;
getTargetCache(): IndexedDbTargetCache;
getRemoteDocumentCache(): IndexedDbRemoteDocumentCache;
getIndexManager(user: User): IndexManager;
getDocumentOverlayCache(user: User): DocumentOverlayCache;
getBundleCache(): BundleCache;
runTransaction<T>(action: string, mode: PersistenceTransactionMode, transactionOperation: (transaction: PersistenceTransaction) => PersistencePromise<T>): Promise<T>;
/**
* Verifies that the current tab is the primary leaseholder or alternatively
* that the leaseholder has opted into multi-tab synchronization.
*/
private verifyAllowTabSynchronization;
/**
* Obtains or extends the new primary lease for the local client. This
* method does not verify that the client is eligible for this lease.
*/
private acquireOrExtendPrimaryLease;
static isAvailable(): boolean;
/** Checks the primary lease and removes it if we are the current primary. */
private releasePrimaryLeaseIfHeld;
/** Verifies that `updateTimeMs` is within `maxAgeMs`. */
private isWithinAge;
private attachVisibilityHandler;
private detachVisibilityHandler;
/**
* Attaches a window.unload handler that will synchronously write our
* clientId to a "zombie client id" location in LocalStorage. This can be used
* by tabs trying to acquire the primary lease to determine that the lease
* is no longer valid even if the timestamp is recent. This is particularly
* important for the refresh case (so the tab correctly re-acquires the
* primary lease). LocalStorage is used for this rather than IndexedDb because
* it is a synchronous API and so can be used reliably from an unload
* handler.
*/
private attachWindowUnloadHook;
private detachWindowUnloadHook;
/**
* Returns whether a client is "zombied" based on its LocalStorage entry.
* Clients become zombied when their tab closes without running all of the
* cleanup logic in `shutdown()`.
*/
private isClientZombied;
/**
* Record client as zombied (a client that had its tab closed). Zombied
* clients are ignored during primary tab selection.
*/
private markClientZombied;
/** Removes the zombied client entry if it exists. */
private removeClientZombiedEntry;
private zombiedClientLocalStorageKey;
}
/**
* Generates a string used as a prefix when storing data in IndexedDB and
* LocalStorage.
*/
export declare function indexedDbStoragePrefix(databaseId: DatabaseId, persistenceKey: string): string;
export declare function indexedDbClearPersistence(persistenceKey: string): Promise<void>;

View file

@ -0,0 +1,36 @@
/**
* @license
* Copyright 2017 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 { MutableDocument } from '../model/document';
import { DocumentKey } from '../model/document_key';
import { LocalSerializer } from './local_serializer';
import { RemoteDocumentCache } from './remote_document_cache';
export interface DocumentSizeEntry {
document: MutableDocument;
size: number;
}
export interface IndexedDbRemoteDocumentCache extends RemoteDocumentCache {
}
/** Creates a new IndexedDbRemoteDocumentCache. */
export declare function newIndexedDbRemoteDocumentCache(serializer: LocalSerializer): IndexedDbRemoteDocumentCache;
/**
* Comparator that compares document keys according to the primary key sorting
* used by the `DbRemoteDocumentDocument` store (by prefix path, collection id
* and then document ID).
*
* Visible for testing.
*/
export declare function dbKeyComparator(l: DocumentKey, r: DocumentKey): number;

Some files were not shown because too many files have changed in this diff Show more