UNPKG

@firebase/firestore

Version:

The Cloud Firestore component of the Firebase JS SDK.

271 lines (270 loc) • 12.2 kB
/** * @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; }