@firebase/firestore
Version:
The Cloud Firestore component of the Firebase JS SDK.
271 lines (270 loc) • 12.2 kB
TypeScript
/**
* @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 { SnapshotVersion } from '../core/snapshot_version';
import { Timestamp } from '../lite-api/timestamp';
import { Value as ProtoValue } from '../protos/firestore_proto_api';
import { Document, MutableDocument } from './document';
import { DocumentKey } from './document_key';
import { FieldMask } from './field_mask';
import { ObjectValue } from './object_value';
import { FieldPath } from './path';
import { TransformOperation } from './transform_operation';
/** A field path and the TransformOperation to perform upon it. */
export declare class FieldTransform {
readonly field: FieldPath;
readonly transform: TransformOperation;
constructor(field: FieldPath, transform: TransformOperation);
}
export declare function fieldTransformEquals(left: FieldTransform, right: FieldTransform): boolean;
export declare function fieldTransformsAreEqual(left?: FieldTransform[], right?: FieldTransform[]): boolean;
/** The result of successfully applying a mutation to the backend. */
export declare class MutationResult {
/**
* The version at which the mutation was committed:
*
* - For most operations, this is the updateTime in the WriteResult.
* - For deletes, the commitTime of the WriteResponse (because deletes are
* not stored and have no updateTime).
*
* Note that these versions can be different: No-op writes will not change
* the updateTime even though the commitTime advances.
*/
readonly version: SnapshotVersion;
/**
* The resulting fields returned from the backend after a mutation
* containing field transforms has been committed. Contains one FieldValue
* for each FieldTransform that was in the mutation.
*
* Will be empty if the mutation did not contain any field transforms.
*/
readonly transformResults: Array<ProtoValue | null>;
constructor(
/**
* The version at which the mutation was committed:
*
* - For most operations, this is the updateTime in the WriteResult.
* - For deletes, the commitTime of the WriteResponse (because deletes are
* not stored and have no updateTime).
*
* Note that these versions can be different: No-op writes will not change
* the updateTime even though the commitTime advances.
*/
version: SnapshotVersion,
/**
* The resulting fields returned from the backend after a mutation
* containing field transforms has been committed. Contains one FieldValue
* for each FieldTransform that was in the mutation.
*
* Will be empty if the mutation did not contain any field transforms.
*/
transformResults: Array<ProtoValue | null>);
}
export declare const enum MutationType {
Set = 0,
Patch = 1,
Delete = 2,
Verify = 3
}
/**
* Encodes a precondition for a mutation. This follows the model that the
* backend accepts with the special case of an explicit "empty" precondition
* (meaning no precondition).
*/
export declare class Precondition {
readonly updateTime?: SnapshotVersion | undefined;
readonly exists?: boolean | undefined;
private constructor();
/** Creates a new empty Precondition. */
static none(): Precondition;
/** Creates a new Precondition with an exists flag. */
static exists(exists: boolean): Precondition;
/** Creates a new Precondition based on a version a document exists at. */
static updateTime(version: SnapshotVersion): Precondition;
/** Returns whether this Precondition is empty. */
get isNone(): boolean;
isEqual(other: Precondition): boolean;
}
/** Returns true if the preconditions is valid for the given document. */
export declare function preconditionIsValidForDocument(precondition: Precondition, document: MutableDocument): boolean;
/**
* A mutation describes a self-contained change to a document. Mutations can
* create, replace, delete, and update subsets of documents.
*
* Mutations not only act on the value of the document but also its version.
*
* For local mutations (mutations that haven't been committed yet), we preserve
* the existing version for Set and Patch mutations. For Delete mutations, we
* reset the version to 0.
*
* Here's the expected transition table.
*
* MUTATION APPLIED TO RESULTS IN
*
* SetMutation Document(v3) Document(v3)
* SetMutation NoDocument(v3) Document(v0)
* SetMutation InvalidDocument(v0) Document(v0)
* PatchMutation Document(v3) Document(v3)
* PatchMutation NoDocument(v3) NoDocument(v3)
* PatchMutation InvalidDocument(v0) UnknownDocument(v3)
* DeleteMutation Document(v3) NoDocument(v0)
* DeleteMutation NoDocument(v3) NoDocument(v0)
* DeleteMutation InvalidDocument(v0) NoDocument(v0)
*
* For acknowledged mutations, we use the updateTime of the WriteResponse as
* the resulting version for Set and Patch mutations. As deletes have no
* explicit update time, we use the commitTime of the WriteResponse for
* Delete mutations.
*
* If a mutation is acknowledged by the backend but fails the precondition check
* locally, we transition to an `UnknownDocument` and rely on Watch to send us
* the updated version.
*
* Field transforms are used only with Patch and Set Mutations. We use the
* `updateTransforms` message to store transforms, rather than the `transforms`s
* messages.
*
* ## Subclassing Notes
*
* Every type of mutation needs to implement its own applyToRemoteDocument() and
* applyToLocalView() to implement the actual behavior of applying the mutation
* to some source document (see `setMutationApplyToRemoteDocument()` for an
* example).
*/
export declare abstract class Mutation {
abstract readonly type: MutationType;
abstract readonly key: DocumentKey;
abstract readonly precondition: Precondition;
abstract readonly fieldTransforms: FieldTransform[];
/**
* Returns a `FieldMask` representing the fields that will be changed by
* applying this mutation. Returns `null` if the mutation will overwrite the
* entire document.
*/
abstract getFieldMask(): FieldMask | null;
}
/**
* A utility method to calculate a `Mutation` representing the overlay from the
* final state of the document, and a `FieldMask` representing the fields that
* are mutated by the local mutations.
*/
export declare function calculateOverlayMutation(doc: MutableDocument, mask: FieldMask | null): Mutation | null;
/**
* Applies this mutation to the given document for the purposes of computing a
* new remote document. If the input document doesn't match the expected state
* (e.g. it is invalid or outdated), the document type may transition to
* unknown.
*
* @param mutation - The mutation to apply.
* @param document - The document to mutate. The input document can be an
* invalid document if the client has no knowledge of the pre-mutation state
* of the document.
* @param mutationResult - The result of applying the mutation from the backend.
*/
export declare function mutationApplyToRemoteDocument(mutation: Mutation, document: MutableDocument, mutationResult: MutationResult): void;
/**
* Applies this mutation to the given document for the purposes of computing
* the new local view of a document. If the input document doesn't match the
* expected state, the document is not modified.
*
* @param mutation - The mutation to apply.
* @param document - The document to mutate. The input document can be an
* invalid document if the client has no knowledge of the pre-mutation state
* of the document.
* @param previousMask - The fields that have been updated before applying this mutation.
* @param localWriteTime - A timestamp indicating the local write time of the
* batch this mutation is a part of.
* @returns A `FieldMask` representing the fields that are changed by applying this mutation.
*/
export declare function mutationApplyToLocalView(mutation: Mutation, document: MutableDocument, previousMask: FieldMask | null, localWriteTime: Timestamp): FieldMask | null;
/**
* If this mutation is not idempotent, returns the base value to persist with
* this mutation. If a base value is returned, the mutation is always applied
* to this base value, even if document has already been updated.
*
* The base value is a sparse object that consists of only the document
* fields for which this mutation contains a non-idempotent transformation
* (e.g. a numeric increment). The provided value guarantees consistent
* behavior for non-idempotent transforms and allow us to return the same
* latency-compensated value even if the backend has already applied the
* mutation. The base value is null for idempotent mutations, as they can be
* re-played even if the backend has already applied them.
*
* @returns a base value to store along with the mutation, or null for
* idempotent mutations.
*/
export declare function mutationExtractBaseValue(mutation: Mutation, document: Document): ObjectValue | null;
export declare function mutationEquals(left: Mutation, right: Mutation): boolean;
/**
* A mutation that creates or replaces the document at the given key with the
* object value contents.
*/
export declare class SetMutation extends Mutation {
readonly key: DocumentKey;
readonly value: ObjectValue;
readonly precondition: Precondition;
readonly fieldTransforms: FieldTransform[];
constructor(key: DocumentKey, value: ObjectValue, precondition: Precondition, fieldTransforms?: FieldTransform[]);
readonly type: MutationType;
getFieldMask(): FieldMask | null;
}
/**
* A mutation that modifies fields of the document at the given key with the
* given values. The values are applied through a field mask:
*
* * When a field is in both the mask and the values, the corresponding field
* is updated.
* * When a field is in neither the mask nor the values, the corresponding
* field is unmodified.
* * When a field is in the mask but not in the values, the corresponding field
* is deleted.
* * When a field is not in the mask but is in the values, the values map is
* ignored.
*/
export declare class PatchMutation extends Mutation {
readonly key: DocumentKey;
readonly data: ObjectValue;
readonly fieldMask: FieldMask;
readonly precondition: Precondition;
readonly fieldTransforms: FieldTransform[];
constructor(key: DocumentKey, data: ObjectValue, fieldMask: FieldMask, precondition: Precondition, fieldTransforms?: FieldTransform[]);
readonly type: MutationType;
getFieldMask(): FieldMask | null;
}
/** A mutation that deletes the document at the given key. */
export declare class DeleteMutation extends Mutation {
readonly key: DocumentKey;
readonly precondition: Precondition;
constructor(key: DocumentKey, precondition: Precondition);
readonly type: MutationType;
readonly fieldTransforms: FieldTransform[];
getFieldMask(): FieldMask | null;
}
/**
* A mutation that verifies the existence of the document at the given key with
* the provided precondition.
*
* The `verify` operation is only used in Transactions, and this class serves
* primarily to facilitate serialization into protos.
*/
export declare class VerifyMutation extends Mutation {
readonly key: DocumentKey;
readonly precondition: Precondition;
constructor(key: DocumentKey, precondition: Precondition);
readonly type: MutationType;
readonly fieldTransforms: FieldTransform[];
getFieldMask(): FieldMask | null;
}