{"version":3,"file":"index.browser.esm.js","sources":["../../src/util/promise.ts","../../src/core/aggregate.ts","../../src/remote/backoff.ts","../../src/lite-api/aggregate_types.ts","../../src/lite-api/aggregate.ts","../../src/lite-api/write_batch.ts","../../src/core/transaction.ts","../../src/core/transaction_options.ts","../../src/core/transaction_runner.ts","../../src/platform/browser/dom.ts","../../src/util/async_queue.ts","../../src/util/async_queue_impl.ts","../../src/local/simple_db.ts","../../src/lite-api/transaction.ts","../../lite/register.ts","../../lite/index.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport interface Resolver<R> {\n  (value: R | Promise<R>): void;\n}\n\nexport interface Rejecter {\n  (reason?: Error): void;\n}\n\nexport class Deferred<R = void> {\n  promise: Promise<R>;\n  // Assigned synchronously in constructor by Promise constructor callback.\n  resolve!: Resolver<R>;\n  reject!: Rejecter;\n\n  constructor() {\n    this.promise = new Promise((resolve: Resolver<R>, reject: Rejecter) => {\n      this.resolve = resolve;\n      this.reject = reject;\n    });\n  }\n}\n\n/**\n * Takes an array of values and a function from a value to a Promise. The function is run on each\n * value sequentially, waiting for the previous promise to resolve before starting the next one.\n * The returned promise resolves once the function has been run on all values.\n */\nexport function sequence<T>(\n  values: T[],\n  fn: (value: T) => Promise<void>\n): Promise<void> {\n  let p = Promise.resolve();\n  for (const value of values) {\n    p = p.then(() => fn(value));\n  }\n  return p;\n}\n","/**\n * @license\n * Copyright 2023 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FieldPath } from '../model/path';\n\n/**\n * Union type representing the aggregate type to be performed.\n */\nexport type AggregateType = 'count' | 'avg' | 'sum';\n\n/**\n * Represents an Aggregate to be performed over a query result set.\n */\nexport interface Aggregate {\n  readonly fieldPath?: FieldPath;\n  readonly alias: string;\n  readonly aggregateType: AggregateType;\n}\n\n/**\n * Concrete implementation of the Aggregate type.\n */\nexport class AggregateImpl implements Aggregate {\n  constructor(\n    readonly alias: string,\n    readonly aggregateType: AggregateType,\n    readonly fieldPath?: FieldPath\n  ) {}\n}\n","/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AsyncQueue, DelayedOperation, TimerId } from '../util/async_queue';\nimport { logDebug } from '../util/log';\n\nconst LOG_TAG = 'ExponentialBackoff';\n\n/**\n * Initial backoff time in milliseconds after an error.\n * Set to 1s according to https://cloud.google.com/apis/design/errors.\n */\nconst DEFAULT_BACKOFF_INITIAL_DELAY_MS = 1000;\n\nconst DEFAULT_BACKOFF_FACTOR = 1.5;\n\n/** Maximum backoff time in milliseconds */\nconst DEFAULT_BACKOFF_MAX_DELAY_MS = 60 * 1000;\n\n/**\n * A helper for running delayed tasks following an exponential backoff curve\n * between attempts.\n *\n * Each delay is made up of a \"base\" delay which follows the exponential\n * backoff curve, and a +/- 50% \"jitter\" that is calculated and added to the\n * base delay. This prevents clients from accidentally synchronizing their\n * delays causing spikes of load to the backend.\n */\nexport class ExponentialBackoff {\n  private currentBaseMs: number = 0;\n  private timerPromise: DelayedOperation<void> | null = null;\n  /** The last backoff attempt, as epoch milliseconds. */\n  private lastAttemptTime = Date.now();\n\n  constructor(\n    /**\n     * The AsyncQueue to run backoff operations on.\n     */\n    private readonly queue: AsyncQueue,\n    /**\n     * The ID to use when scheduling backoff operations on the AsyncQueue.\n     */\n    private readonly timerId: TimerId,\n    /**\n     * The initial delay (used as the base delay on the first retry attempt).\n     * Note that jitter will still be applied, so the actual delay could be as\n     * little as 0.5*initialDelayMs.\n     */\n    private readonly initialDelayMs: number = DEFAULT_BACKOFF_INITIAL_DELAY_MS,\n    /**\n     * The multiplier to use to determine the extended base delay after each\n     * attempt.\n     */\n    private readonly backoffFactor: number = DEFAULT_BACKOFF_FACTOR,\n    /**\n     * The maximum base delay after which no further backoff is performed.\n     * Note that jitter will still be applied, so the actual delay could be as\n     * much as 1.5*maxDelayMs.\n     */\n    private readonly maxDelayMs: number = DEFAULT_BACKOFF_MAX_DELAY_MS\n  ) {\n    this.reset();\n  }\n\n  /**\n   * Resets the backoff delay.\n   *\n   * The very next backoffAndWait() will have no delay. If it is called again\n   * (i.e. due to an error), initialDelayMs (plus jitter) will be used, and\n   * subsequent ones will increase according to the backoffFactor.\n   */\n  reset(): void {\n    this.currentBaseMs = 0;\n  }\n\n  /**\n   * Resets the backoff delay to the maximum delay (e.g. for use after a\n   * RESOURCE_EXHAUSTED error).\n   */\n  resetToMax(): void {\n    this.currentBaseMs = this.maxDelayMs;\n  }\n\n  /**\n   * Returns a promise that resolves after currentDelayMs, and increases the\n   * delay for any subsequent attempts. If there was a pending backoff operation\n   * already, it will be canceled.\n   */\n  backoffAndRun(op: () => Promise<void>): void {\n    // Cancel any pending backoff operation.\n    this.cancel();\n\n    // First schedule using the current base (which may be 0 and should be\n    // honored as such).\n    const desiredDelayWithJitterMs = Math.floor(\n      this.currentBaseMs + this.jitterDelayMs()\n    );\n\n    // Guard against lastAttemptTime being in the future due to a clock change.\n    const delaySoFarMs = Math.max(0, Date.now() - this.lastAttemptTime);\n\n    // Guard against the backoff delay already being past.\n    const remainingDelayMs = Math.max(\n      0,\n      desiredDelayWithJitterMs - delaySoFarMs\n    );\n\n    if (remainingDelayMs > 0) {\n      logDebug(\n        LOG_TAG,\n        `Backing off for ${remainingDelayMs} ms ` +\n          `(base delay: ${this.currentBaseMs} ms, ` +\n          `delay with jitter: ${desiredDelayWithJitterMs} ms, ` +\n          `last attempt: ${delaySoFarMs} ms ago)`\n      );\n    }\n\n    this.timerPromise = this.queue.enqueueAfterDelay(\n      this.timerId,\n      remainingDelayMs,\n      () => {\n        this.lastAttemptTime = Date.now();\n        return op();\n      }\n    );\n\n    // Apply backoff factor to determine next delay and ensure it is within\n    // bounds.\n    this.currentBaseMs *= this.backoffFactor;\n    if (this.currentBaseMs < this.initialDelayMs) {\n      this.currentBaseMs = this.initialDelayMs;\n    }\n    if (this.currentBaseMs > this.maxDelayMs) {\n      this.currentBaseMs = this.maxDelayMs;\n    }\n  }\n\n  skipBackoff(): void {\n    if (this.timerPromise !== null) {\n      this.timerPromise.skipDelay();\n      this.timerPromise = null;\n    }\n  }\n\n  cancel(): void {\n    if (this.timerPromise !== null) {\n      this.timerPromise.cancel();\n      this.timerPromise = null;\n    }\n  }\n\n  /** Returns a random value in the range [-currentBaseMs/2, currentBaseMs/2] */\n  private jitterDelayMs(): number {\n    return (Math.random() - 0.5) * this.currentBaseMs;\n  }\n}\n","/**\n * @license\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AggregateType } from '../core/aggregate';\nimport { ObjectValue } from '../model/object_value';\nimport { FieldPath as InternalFieldPath } from '../model/path';\nimport {\n  ApiClientObjectMap,\n  firestoreV1ApiClientInterfaces,\n  Value\n} from '../protos/firestore_proto_api';\n\nimport { average, count, sum } from './aggregate';\nimport { DocumentData, Query } from './reference';\nimport { AbstractUserDataWriter } from './user_data_writer';\n\nexport { AggregateType };\n\n/**\n * Represents an aggregation that can be performed by Firestore.\n */\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport class AggregateField<T> {\n  /** A type string to uniquely identify instances of this class. */\n  readonly type = 'AggregateField';\n\n  /** Indicates the aggregation operation of this AggregateField. */\n  readonly aggregateType: AggregateType;\n\n  /**\n   * Create a new AggregateField<T>\n   * @param aggregateType - Specifies the type of aggregation operation to perform.\n   * @param _internalFieldPath - Optionally specifies the field that is aggregated.\n   * @internal\n   */\n  constructor(\n    aggregateType: AggregateType = 'count',\n    readonly _internalFieldPath?: InternalFieldPath\n  ) {\n    this.aggregateType = aggregateType;\n  }\n}\n\n/**\n * The union of all `AggregateField` types that are supported by Firestore.\n */\nexport type AggregateFieldType =\n  | ReturnType<typeof sum>\n  | ReturnType<typeof average>\n  | ReturnType<typeof count>;\n\n/**\n * Specifies a set of aggregations and their aliases.\n */\nexport interface AggregateSpec {\n  [field: string]: AggregateFieldType;\n}\n\n/**\n * A type whose keys are taken from an `AggregateSpec`, and whose values are the\n * result of the aggregation performed by the corresponding `AggregateField`\n * from the input `AggregateSpec`.\n */\nexport type AggregateSpecData<T extends AggregateSpec> = {\n  [P in keyof T]: T[P] extends AggregateField<infer U> ? U : never;\n};\n\n/**\n * The results of executing an aggregation query.\n */\nexport class AggregateQuerySnapshot<\n  AggregateSpecType extends AggregateSpec,\n  AppModelType = DocumentData,\n  DbModelType extends DocumentData = DocumentData\n> {\n  /** A type string to uniquely identify instances of this class. */\n  readonly type = 'AggregateQuerySnapshot';\n\n  /**\n   * The underlying query over which the aggregations recorded in this\n   * `AggregateQuerySnapshot` were performed.\n   */\n  readonly query: Query<AppModelType, DbModelType>;\n\n  /** @hideconstructor */\n  constructor(\n    query: Query<AppModelType, DbModelType>,\n    private readonly _userDataWriter: AbstractUserDataWriter,\n    private readonly _data: ApiClientObjectMap<Value>\n  ) {\n    this.query = query;\n  }\n\n  /**\n   * Returns the results of the aggregations performed over the underlying\n   * query.\n   *\n   * The keys of the returned object will be the same as those of the\n   * `AggregateSpec` object specified to the aggregation method, and the values\n   * will be the corresponding aggregation result.\n   *\n   * @returns The results of the aggregations performed over the underlying\n   * query.\n   */\n  data(): AggregateSpecData<AggregateSpecType> {\n    return this._userDataWriter.convertObjectMap(\n      this._data\n    ) as AggregateSpecData<AggregateSpecType>;\n  }\n\n  /**\n   * @internal\n   * @private\n   *\n   * Retrieves all fields in the snapshot as a proto value.\n   *\n   * @returns An `Object` containing all fields in the snapshot.\n   */\n  _fieldsProto(): { [key: string]: firestoreV1ApiClientInterfaces.Value } {\n    // Wrap data in an ObjectValue to clone it.\n    const dataClone = new ObjectValue({\n      mapValue: { fields: this._data }\n    }).clone();\n\n    // Return the cloned value to prevent manipulation of the Snapshot's data\n    return dataClone.value.mapValue.fields!;\n  }\n}\n","/**\n * @license\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { deepEqual } from '@firebase/util';\n\nimport { AggregateImpl } from '../core/aggregate';\nimport { ApiClientObjectMap, Value } from '../protos/firestore_proto_api';\nimport { invokeRunAggregationQueryRpc } from '../remote/datastore';\nimport { cast } from '../util/input_validation';\nimport { mapToArray } from '../util/obj';\n\nimport {\n  AggregateField,\n  AggregateQuerySnapshot,\n  AggregateSpec\n} from './aggregate_types';\nimport { getDatastore } from './components';\nimport { Firestore } from './database';\nimport { FieldPath } from './field_path';\nimport { DocumentData, Query, queryEqual } from './reference';\nimport { LiteUserDataWriter } from './reference_impl';\nimport { fieldPathFromArgument } from './user_data_reader';\n\n/**\n * Calculates the number of documents in the result set of the given query\n * without actually downloading the documents.\n *\n * Using this function to count the documents is efficient because only the\n * final count, not the documents' data, is downloaded. This function can\n * count the documents in cases where the result set is prohibitively large to\n * download entirely (thousands of documents).\n *\n * @param query - The query whose result set size is calculated.\n * @returns A Promise that will be resolved with the count; the count can be\n * retrieved from `snapshot.data().count`, where `snapshot` is the\n * `AggregateQuerySnapshot` to which the returned Promise resolves.\n */\nexport function getCount<AppModelType, DbModelType extends DocumentData>(\n  query: Query<AppModelType, DbModelType>\n): Promise<\n  AggregateQuerySnapshot<\n    { count: AggregateField<number> },\n    AppModelType,\n    DbModelType\n  >\n> {\n  const countQuerySpec: { count: AggregateField<number> } = {\n    count: count()\n  };\n\n  return getAggregate(query, countQuerySpec);\n}\n\n/**\n * Calculates the specified aggregations over the documents in the result\n * set of the given query without actually downloading the documents.\n *\n * Using this function to perform aggregations is efficient because only the\n * final aggregation values, not the documents' data, are downloaded. This\n * function can perform aggregations of the documents in cases where the result\n * set is prohibitively large to download entirely (thousands of documents).\n *\n * @param query - The query whose result set is aggregated over.\n * @param aggregateSpec - An `AggregateSpec` object that specifies the aggregates\n * to perform over the result set. The AggregateSpec specifies aliases for each\n * aggregate, which can be used to retrieve the aggregate result.\n * @example\n * ```typescript\n * const aggregateSnapshot = await getAggregate(query, {\n *   countOfDocs: count(),\n *   totalHours: sum('hours'),\n *   averageScore: average('score')\n * });\n *\n * const countOfDocs: number = aggregateSnapshot.data().countOfDocs;\n * const totalHours: number = aggregateSnapshot.data().totalHours;\n * const averageScore: number | null = aggregateSnapshot.data().averageScore;\n * ```\n */\nexport function getAggregate<\n  AggregateSpecType extends AggregateSpec,\n  AppModelType,\n  DbModelType extends DocumentData\n>(\n  query: Query<AppModelType, DbModelType>,\n  aggregateSpec: AggregateSpecType\n): Promise<\n  AggregateQuerySnapshot<AggregateSpecType, AppModelType, DbModelType>\n> {\n  const firestore = cast(query.firestore, Firestore);\n  const datastore = getDatastore(firestore);\n\n  const internalAggregates = mapToArray(aggregateSpec, (aggregate, alias) => {\n    return new AggregateImpl(\n      alias,\n      aggregate.aggregateType,\n      aggregate._internalFieldPath\n    );\n  });\n\n  // Run the aggregation and convert the results\n  return invokeRunAggregationQueryRpc(\n    datastore,\n    query._query,\n    internalAggregates\n  ).then(aggregateResult =>\n    convertToAggregateQuerySnapshot(firestore, query, aggregateResult)\n  );\n}\n\nfunction convertToAggregateQuerySnapshot<\n  AggregateSpecType extends AggregateSpec,\n  AppModelType,\n  DbModelType extends DocumentData\n>(\n  firestore: Firestore,\n  query: Query<AppModelType, DbModelType>,\n  aggregateResult: ApiClientObjectMap<Value>\n): AggregateQuerySnapshot<AggregateSpecType, AppModelType, DbModelType> {\n  const userDataWriter = new LiteUserDataWriter(firestore);\n  const querySnapshot = new AggregateQuerySnapshot<\n    AggregateSpecType,\n    AppModelType,\n    DbModelType\n  >(query, userDataWriter, aggregateResult);\n  return querySnapshot;\n}\n\n/**\n * Create an AggregateField object that can be used to compute the sum of\n * a specified field over a range of documents in the result set of a query.\n * @param field - Specifies the field to sum across the result set.\n */\nexport function sum(field: string | FieldPath): AggregateField<number> {\n  return new AggregateField('sum', fieldPathFromArgument('sum', field));\n}\n\n/**\n * Create an AggregateField object that can be used to compute the average of\n * a specified field over a range of documents in the result set of a query.\n * @param field - Specifies the field to average across the result set.\n */\nexport function average(\n  field: string | FieldPath\n): AggregateField<number | null> {\n  return new AggregateField('avg', fieldPathFromArgument('average', field));\n}\n\n/**\n * Create an AggregateField object that can be used to compute the count of\n * documents in the result set of a query.\n */\nexport function count(): AggregateField<number> {\n  return new AggregateField('count');\n}\n\n/**\n * Compares two 'AggregateField` instances for equality.\n *\n * @param left - Compare this AggregateField to the `right`.\n * @param right - Compare this AggregateField to the `left`.\n */\nexport function aggregateFieldEqual(\n  left: AggregateField<unknown>,\n  right: AggregateField<unknown>\n): boolean {\n  return (\n    left instanceof AggregateField &&\n    right instanceof AggregateField &&\n    left.aggregateType === right.aggregateType &&\n    left._internalFieldPath?.canonicalString() ===\n      right._internalFieldPath?.canonicalString()\n  );\n}\n\n/**\n * Compares two `AggregateQuerySnapshot` instances for equality.\n *\n * Two `AggregateQuerySnapshot` instances are considered \"equal\" if they have\n * underlying queries that compare equal, and the same data.\n *\n * @param left - The first `AggregateQuerySnapshot` to compare.\n * @param right - The second `AggregateQuerySnapshot` to compare.\n *\n * @returns `true` if the objects are \"equal\", as defined above, or `false`\n * otherwise.\n */\nexport function aggregateQuerySnapshotEqual<\n  AggregateSpecType extends AggregateSpec,\n  AppModelType,\n  DbModelType extends DocumentData\n>(\n  left: AggregateQuerySnapshot<AggregateSpecType, AppModelType, DbModelType>,\n  right: AggregateQuerySnapshot<AggregateSpecType, AppModelType, DbModelType>\n): boolean {\n  return (\n    queryEqual(left.query, right.query) && deepEqual(left.data(), right.data())\n  );\n}\n","/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Compat, getModularInstance } from '@firebase/util';\n\nimport { DeleteMutation, Mutation, Precondition } from '../model/mutation';\nimport { invokeCommitRpc } from '../remote/datastore';\nimport { Code, FirestoreError } from '../util/error';\nimport { cast } from '../util/input_validation';\n\nimport { getDatastore } from './components';\nimport { Firestore } from './database';\nimport { FieldPath } from './field_path';\nimport {\n  DocumentData,\n  DocumentReference,\n  PartialWithFieldValue,\n  SetOptions,\n  UpdateData,\n  WithFieldValue\n} from './reference';\nimport { applyFirestoreDataConverter } from './reference_impl';\nimport {\n  newUserDataReader,\n  parseSetData,\n  parseUpdateData,\n  parseUpdateVarargs,\n  UserDataReader\n} from './user_data_reader';\n\n/**\n * A write batch, used to perform multiple writes as a single atomic unit.\n *\n * A `WriteBatch` object can be acquired by calling {@link writeBatch}. It\n * provides methods for adding writes to the write batch. None of the writes\n * will be committed (or visible locally) until {@link WriteBatch.commit} is\n * called.\n */\nexport class WriteBatch {\n  // This is the lite version of the WriteBatch API used in the legacy SDK. The\n  // class is a close copy but takes different input types.\n\n  private readonly _dataReader: UserDataReader;\n  private _mutations = [] as Mutation[];\n  private _committed = false;\n\n  /** @hideconstructor */\n  constructor(\n    private readonly _firestore: Firestore,\n    private readonly _commitHandler: (m: Mutation[]) => Promise<void>\n  ) {\n    this._dataReader = newUserDataReader(_firestore);\n  }\n\n  /**\n   * Writes to the document referred to by the provided {@link\n   * DocumentReference}. If the document does not exist yet, it will be created.\n   *\n   * @param documentRef - A reference to the document to be set.\n   * @param data - An object of the fields and values for the document.\n   * @returns This `WriteBatch` instance. Used for chaining method calls.\n   */\n  set<AppModelType, DbModelType extends DocumentData>(\n    documentRef: DocumentReference<AppModelType, DbModelType>,\n    data: WithFieldValue<AppModelType>\n  ): WriteBatch;\n  /**\n   * Writes to the document referred to by the provided {@link\n   * DocumentReference}. If the document does not exist yet, it will be created.\n   * If you provide `merge` or `mergeFields`, the provided data can be merged\n   * into an existing document.\n   *\n   * @param documentRef - A reference to the document to be set.\n   * @param data - An object of the fields and values for the document.\n   * @param options - An object to configure the set behavior.\n   * @throws Error - If the provided input is not a valid Firestore document.\n   * @returns This `WriteBatch` instance. Used for chaining method calls.\n   */\n  set<AppModelType, DbModelType extends DocumentData>(\n    documentRef: DocumentReference<AppModelType, DbModelType>,\n    data: PartialWithFieldValue<AppModelType>,\n    options: SetOptions\n  ): WriteBatch;\n  set<AppModelType, DbModelType extends DocumentData>(\n    documentRef: DocumentReference<AppModelType, DbModelType>,\n    data: WithFieldValue<AppModelType> | PartialWithFieldValue<AppModelType>,\n    options?: SetOptions\n  ): WriteBatch {\n    this._verifyNotCommitted();\n    const ref = validateReference(documentRef, this._firestore);\n\n    const convertedValue = applyFirestoreDataConverter(\n      ref.converter,\n      data,\n      options\n    );\n    const parsed = parseSetData(\n      this._dataReader,\n      'WriteBatch.set',\n      ref._key,\n      convertedValue,\n      ref.converter !== null,\n      options\n    );\n    this._mutations.push(parsed.toMutation(ref._key, Precondition.none()));\n    return this;\n  }\n\n  /**\n   * Updates fields in the document referred to by the provided {@link\n   * DocumentReference}. The update will fail if applied to a document that does\n   * not exist.\n   *\n   * @param documentRef - A reference to the document to be updated.\n   * @param data - An object containing the fields and values with which to\n   * update the document. Fields can contain dots to reference nested fields\n   * within the document.\n   * @throws Error - If the provided input is not valid Firestore data.\n   * @returns This `WriteBatch` instance. Used for chaining method calls.\n   */\n  update<AppModelType, DbModelType extends DocumentData>(\n    documentRef: DocumentReference<AppModelType, DbModelType>,\n    data: UpdateData<DbModelType>\n  ): WriteBatch;\n  /**\n   * Updates fields in the document referred to by this {@link\n   * DocumentReference}. The update will fail if applied to a document that does\n   * not exist.\n   *\n   * Nested fields can be update by providing dot-separated field path strings\n   * or by providing `FieldPath` objects.\n   *\n   * @param documentRef - A reference to the document to be updated.\n   * @param field - The first field to update.\n   * @param value - The first value.\n   * @param moreFieldsAndValues - Additional key value pairs.\n   * @throws Error - If the provided input is not valid Firestore data.\n   * @returns This `WriteBatch` instance. Used for chaining method calls.\n   */\n  update<AppModelType, DbModelType extends DocumentData>(\n    documentRef: DocumentReference<AppModelType, DbModelType>,\n    field: string | FieldPath,\n    value: unknown,\n    ...moreFieldsAndValues: unknown[]\n  ): WriteBatch;\n  update<AppModelType, DbModelType extends DocumentData>(\n    documentRef: DocumentReference<AppModelType, DbModelType>,\n    fieldOrUpdateData: string | FieldPath | UpdateData<DbModelType>,\n    value?: unknown,\n    ...moreFieldsAndValues: unknown[]\n  ): WriteBatch {\n    this._verifyNotCommitted();\n    const ref = validateReference(documentRef, this._firestore);\n\n    // For Compat types, we have to \"extract\" the underlying types before\n    // performing validation.\n    fieldOrUpdateData = getModularInstance(fieldOrUpdateData);\n\n    let parsed;\n    if (\n      typeof fieldOrUpdateData === 'string' ||\n      fieldOrUpdateData instanceof FieldPath\n    ) {\n      parsed = parseUpdateVarargs(\n        this._dataReader,\n        'WriteBatch.update',\n        ref._key,\n        fieldOrUpdateData,\n        value,\n        moreFieldsAndValues\n      );\n    } else {\n      parsed = parseUpdateData(\n        this._dataReader,\n        'WriteBatch.update',\n        ref._key,\n        fieldOrUpdateData\n      );\n    }\n\n    this._mutations.push(\n      parsed.toMutation(ref._key, Precondition.exists(true))\n    );\n    return this;\n  }\n\n  /**\n   * Deletes the document referred to by the provided {@link DocumentReference}.\n   *\n   * @param documentRef - A reference to the document to be deleted.\n   * @returns This `WriteBatch` instance. Used for chaining method calls.\n   */\n  delete<AppModelType, DbModelType extends DocumentData>(\n    documentRef: DocumentReference<AppModelType, DbModelType>\n  ): WriteBatch {\n    this._verifyNotCommitted();\n    const ref = validateReference(documentRef, this._firestore);\n    this._mutations = this._mutations.concat(\n      new DeleteMutation(ref._key, Precondition.none())\n    );\n    return this;\n  }\n\n  /**\n   * Commits all of the writes in this write batch as a single atomic unit.\n   *\n   * The result of these writes will only be reflected in document reads that\n   * occur after the returned promise resolves. If the client is offline, the\n   * write fails. If you would like to see local modifications or buffer writes\n   * until the client is online, use the full Firestore SDK.\n   *\n   * @returns A `Promise` resolved once all of the writes in the batch have been\n   * successfully written to the backend as an atomic unit (note that it won't\n   * resolve while you're offline).\n   */\n  commit(): Promise<void> {\n    this._verifyNotCommitted();\n    this._committed = true;\n    if (this._mutations.length > 0) {\n      return this._commitHandler(this._mutations);\n    }\n\n    return Promise.resolve();\n  }\n\n  private _verifyNotCommitted(): void {\n    if (this._committed) {\n      throw new FirestoreError(\n        Code.FAILED_PRECONDITION,\n        'A write batch can no longer be used after commit() ' +\n          'has been called.'\n      );\n    }\n  }\n}\n\nexport function validateReference<\n  AppModelType,\n  DbModelType extends DocumentData\n>(\n  documentRef:\n    | DocumentReference<AppModelType, DbModelType>\n    | Compat<DocumentReference<AppModelType, DbModelType>>,\n  firestore: Firestore\n): DocumentReference<AppModelType, DbModelType> {\n  documentRef = getModularInstance(documentRef);\n\n  if (documentRef.firestore !== firestore) {\n    throw new FirestoreError(\n      Code.INVALID_ARGUMENT,\n      'Provided document reference is from a different Firestore instance.'\n    );\n  } else {\n    return documentRef as DocumentReference<AppModelType, DbModelType>;\n  }\n}\n\n/**\n * Creates a write batch, used for performing multiple writes as a single\n * atomic operation. The maximum number of writes allowed in a single WriteBatch\n * is 500.\n *\n * The result of these writes will only be reflected in document reads that\n * occur after the returned promise resolves. If the client is offline, the\n * write fails. If you would like to see local modifications or buffer writes\n * until the client is online, use the full Firestore SDK.\n *\n * @returns A `WriteBatch` that can be used to atomically execute multiple\n * writes.\n */\nexport function writeBatch(firestore: Firestore): WriteBatch {\n  firestore = cast(firestore, Firestore);\n  const datastore = getDatastore(firestore);\n  return new WriteBatch(firestore, writes =>\n    invokeCommitRpc(datastore, writes)\n  );\n}\n","/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ParsedSetData, ParsedUpdateData } from '../lite-api/user_data_reader';\nimport { Document } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport {\n  DeleteMutation,\n  Mutation,\n  Precondition,\n  VerifyMutation\n} from '../model/mutation';\nimport {\n  Datastore,\n  invokeBatchGetDocumentsRpc,\n  invokeCommitRpc\n} from '../remote/datastore';\nimport { fail, debugAssert } from '../util/assert';\nimport { Code, FirestoreError } from '../util/error';\n\nimport { SnapshotVersion } from './snapshot_version';\n\n/**\n * Internal transaction object responsible for accumulating the mutations to\n * perform and the base versions for any documents read.\n */\nexport class Transaction {\n  // The version of each document that was read during this transaction.\n  private readVersions = new Map</* path */ string, SnapshotVersion>();\n  private mutations: Mutation[] = [];\n  private committed = false;\n\n  /**\n   * A deferred usage error that occurred previously in this transaction that\n   * will cause the transaction to fail once it actually commits.\n   */\n  private lastTransactionError: FirestoreError | null = null;\n\n  /**\n   * Set of documents that have been written in the transaction.\n   *\n   * When there's more than one write to the same key in a transaction, any\n   * writes after the first are handled differently.\n   */\n  private writtenDocs: Set</* path= */ string> = new Set();\n\n  constructor(private datastore: Datastore) {}\n\n  async lookup(keys: DocumentKey[]): Promise<Document[]> {\n    this.ensureCommitNotCalled();\n\n    if (this.mutations.length > 0) {\n      this.lastTransactionError = new FirestoreError(\n        Code.INVALID_ARGUMENT,\n        'Firestore transactions require all reads to be executed before all writes.'\n      );\n      throw this.lastTransactionError;\n    }\n    const docs = await invokeBatchGetDocumentsRpc(this.datastore, keys);\n    docs.forEach(doc => this.recordVersion(doc));\n    return docs;\n  }\n\n  set(key: DocumentKey, data: ParsedSetData): void {\n    this.write(data.toMutation(key, this.precondition(key)));\n    this.writtenDocs.add(key.toString());\n  }\n\n  update(key: DocumentKey, data: ParsedUpdateData): void {\n    try {\n      this.write(data.toMutation(key, this.preconditionForUpdate(key)));\n    } catch (e) {\n      this.lastTransactionError = e as FirestoreError | null;\n    }\n    this.writtenDocs.add(key.toString());\n  }\n\n  delete(key: DocumentKey): void {\n    this.write(new DeleteMutation(key, this.precondition(key)));\n    this.writtenDocs.add(key.toString());\n  }\n\n  async commit(): Promise<void> {\n    this.ensureCommitNotCalled();\n\n    if (this.lastTransactionError) {\n      throw this.lastTransactionError;\n    }\n    const unwritten = this.readVersions;\n    // For each mutation, note that the doc was written.\n    this.mutations.forEach(mutation => {\n      unwritten.delete(mutation.key.toString());\n    });\n    // For each document that was read but not written to, we want to perform\n    // a `verify` operation.\n    unwritten.forEach((_, path) => {\n      const key = DocumentKey.fromPath(path);\n      this.mutations.push(new VerifyMutation(key, this.precondition(key)));\n    });\n    await invokeCommitRpc(this.datastore, this.mutations);\n    this.committed = true;\n  }\n\n  private recordVersion(doc: Document): void {\n    let docVersion: SnapshotVersion;\n\n    if (doc.isFoundDocument()) {\n      docVersion = doc.version;\n    } else if (doc.isNoDocument()) {\n      // Represent a deleted doc using SnapshotVersion.min().\n      docVersion = SnapshotVersion.min();\n    } else {\n      throw fail(0xc542, 'Document in a transaction was a ', {\n        documentName: doc.constructor.name\n      });\n    }\n\n    const existingVersion = this.readVersions.get(doc.key.toString());\n    if (existingVersion) {\n      if (!docVersion.isEqual(existingVersion)) {\n        // This transaction will fail no matter what.\n        throw new FirestoreError(\n          Code.ABORTED,\n          'Document version changed between two reads.'\n        );\n      }\n    } else {\n      this.readVersions.set(doc.key.toString(), docVersion);\n    }\n  }\n\n  /**\n   * Returns the version of this document when it was read in this transaction,\n   * as a precondition, or no precondition if it was not read.\n   */\n  private precondition(key: DocumentKey): Precondition {\n    const version = this.readVersions.get(key.toString());\n    if (!this.writtenDocs.has(key.toString()) && version) {\n      if (version.isEqual(SnapshotVersion.min())) {\n        return Precondition.exists(false);\n      } else {\n        return Precondition.updateTime(version);\n      }\n    } else {\n      return Precondition.none();\n    }\n  }\n\n  /**\n   * Returns the precondition for a document if the operation is an update.\n   */\n  private preconditionForUpdate(key: DocumentKey): Precondition {\n    const version = this.readVersions.get(key.toString());\n    // The first time a document is written, we want to take into account the\n    // read time and existence\n    if (!this.writtenDocs.has(key.toString()) && version) {\n      if (version.isEqual(SnapshotVersion.min())) {\n        // The document doesn't exist, so fail the transaction.\n\n        // This has to be validated locally because you can't send a\n        // precondition that a document does not exist without changing the\n        // semantics of the backend write to be an insert. This is the reverse\n        // of what we want, since we want to assert that the document doesn't\n        // exist but then send the update and have it fail. Since we can't\n        // express that to the backend, we have to validate locally.\n\n        // Note: this can change once we can send separate verify writes in the\n        // transaction.\n        throw new FirestoreError(\n          Code.INVALID_ARGUMENT,\n          \"Can't update a document that doesn't exist.\"\n        );\n      }\n      // Document exists, base precondition on document update time.\n      return Precondition.updateTime(version);\n    } else {\n      // Document was not read, so we just use the preconditions for a blind\n      // update.\n      return Precondition.exists(true);\n    }\n  }\n\n  private write(mutation: Mutation): void {\n    this.ensureCommitNotCalled();\n    this.mutations.push(mutation);\n  }\n\n  private ensureCommitNotCalled(): void {\n    debugAssert(\n      !this.committed,\n      'A transaction object cannot be used after its update callback has been invoked.'\n    );\n  }\n}\n","/**\n * @license\n * Copyright 2022 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Code, FirestoreError } from '../util/error';\n\nexport const DEFAULT_TRANSACTION_OPTIONS: TransactionOptions = {\n  maxAttempts: 5\n};\n\n/**\n * Options to customize transaction behavior.\n */\nexport declare interface TransactionOptions {\n  /** Maximum number of attempts to commit, after which transaction fails. Default is 5. */\n  readonly maxAttempts: number;\n}\n\nexport function validateTransactionOptions(options: TransactionOptions): void {\n  if (options.maxAttempts < 1) {\n    throw new FirestoreError(\n      Code.INVALID_ARGUMENT,\n      'Max attempts must be at least 1'\n    );\n  }\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ExponentialBackoff } from '../remote/backoff';\nimport { Datastore } from '../remote/datastore';\nimport { isPermanentError } from '../remote/rpc_error';\nimport { AsyncQueue, TimerId } from '../util/async_queue';\nimport { FirestoreError } from '../util/error';\nimport { Deferred } from '../util/promise';\nimport { isNullOrUndefined } from '../util/types';\n\nimport { Transaction } from './transaction';\nimport { TransactionOptions } from './transaction_options';\n\n/**\n * TransactionRunner encapsulates the logic needed to run and retry transactions\n * with backoff.\n */\nexport class TransactionRunner<T> {\n  private attemptsRemaining: number;\n  private backoff: ExponentialBackoff;\n\n  constructor(\n    private readonly asyncQueue: AsyncQueue,\n    private readonly datastore: Datastore,\n    private readonly options: TransactionOptions,\n    private readonly updateFunction: (transaction: Transaction) => Promise<T>,\n    private readonly deferred: Deferred<T>\n  ) {\n    this.attemptsRemaining = options.maxAttempts;\n    this.backoff = new ExponentialBackoff(\n      this.asyncQueue,\n      TimerId.TransactionRetry\n    );\n  }\n\n  /** Runs the transaction and sets the result on deferred. */\n  run(): void {\n    this.attemptsRemaining -= 1;\n    this.runWithBackOff();\n  }\n\n  private runWithBackOff(): void {\n    this.backoff.backoffAndRun(async () => {\n      const transaction = new Transaction(this.datastore);\n      const userPromise = this.tryRunUpdateFunction(transaction);\n      if (userPromise) {\n        userPromise\n          .then(result => {\n            this.asyncQueue.enqueueAndForget(() => {\n              return transaction\n                .commit()\n                .then(() => {\n                  this.deferred.resolve(result);\n                })\n                .catch(commitError => {\n                  this.handleTransactionError(commitError);\n                });\n            });\n          })\n          .catch(userPromiseError => {\n            this.handleTransactionError(userPromiseError);\n          });\n      }\n    });\n  }\n\n  private tryRunUpdateFunction(transaction: Transaction): Promise<T> | null {\n    try {\n      const userPromise = this.updateFunction(transaction);\n      if (\n        isNullOrUndefined(userPromise) ||\n        !userPromise.catch ||\n        !userPromise.then\n      ) {\n        this.deferred.reject(\n          Error('Transaction callback must return a Promise')\n        );\n        return null;\n      }\n      return userPromise;\n    } catch (error) {\n      // Do not retry errors thrown by user provided updateFunction.\n      this.deferred.reject(error as Error);\n      return null;\n    }\n  }\n\n  private handleTransactionError(error: Error): void {\n    if (this.attemptsRemaining > 0 && this.isRetryableTransactionError(error)) {\n      this.attemptsRemaining -= 1;\n      this.asyncQueue.enqueueAndForget(() => {\n        this.runWithBackOff();\n        return Promise.resolve();\n      });\n    } else {\n      this.deferred.reject(error);\n    }\n  }\n\n  private isRetryableTransactionError(error: Error | undefined): boolean {\n    if (error?.name === 'FirebaseError') {\n      // In transactions, the backend will fail outdated reads with FAILED_PRECONDITION and\n      // non-matching document versions with ABORTED. These errors should be retried.\n      const code = (error as FirestoreError).code;\n      return (\n        code === 'aborted' ||\n        code === 'failed-precondition' ||\n        code === 'already-exists' ||\n        !isPermanentError(code)\n      );\n    }\n    return false;\n  }\n}\n","/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/** The Platform's 'window' implementation or null if not available. */\nexport function getWindow(): Window | null {\n  // `window` is not always available, e.g. in ReactNative and WebWorkers.\n  // eslint-disable-next-line no-restricted-globals\n  return typeof window !== 'undefined' ? window : null;\n}\n\n/** The Platform's 'document' implementation or null if not available. */\nexport function getDocument(): Document | null {\n  // `document` is not always available, e.g. in ReactNative and WebWorkers.\n  // eslint-disable-next-line no-restricted-globals\n  return typeof document !== 'undefined' ? document : null;\n}\n","/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { isIndexedDbTransactionError } from '../local/simple_db';\n\nimport { Code, FirestoreError } from './error';\nimport { logError } from './log';\nimport { Deferred } from './promise';\n\nconst LOG_TAG = 'AsyncQueue';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype TimerHandle = any;\n\n/**\n * Wellknown \"timer\" IDs used when scheduling delayed operations on the\n * AsyncQueue. These IDs can then be used from tests to check for the presence\n * of operations or to run them early.\n *\n * The string values are used when encoding these timer IDs in JSON spec tests.\n */\nexport const enum TimerId {\n  /** All can be used with runDelayedOperationsEarly() to run all timers. */\n  All = 'all',\n\n  /**\n   * The following 5 timers are used in persistent_stream.ts for the listen and\n   * write streams. The \"Idle\" timer is used to close the stream due to\n   * inactivity. The \"ConnectionBackoff\" timer is used to restart a stream once\n   * the appropriate backoff delay has elapsed. The health check is used to mark\n   * a stream healthy if it has not received an error during its initial setup.\n   */\n  ListenStreamIdle = 'listen_stream_idle',\n  ListenStreamConnectionBackoff = 'listen_stream_connection_backoff',\n  WriteStreamIdle = 'write_stream_idle',\n  WriteStreamConnectionBackoff = 'write_stream_connection_backoff',\n  HealthCheckTimeout = 'health_check_timeout',\n\n  /**\n   * A timer used in online_state_tracker.ts to transition from\n   * OnlineState.Unknown to Offline after a set timeout, rather than waiting\n   * indefinitely for success or failure.\n   */\n  OnlineStateTimeout = 'online_state_timeout',\n\n  /**\n   * A timer used to update the client metadata in IndexedDb, which is used\n   * to determine the primary leaseholder.\n   */\n  ClientMetadataRefresh = 'client_metadata_refresh',\n\n  /** A timer used to periodically attempt LRU Garbage collection */\n  LruGarbageCollection = 'lru_garbage_collection',\n\n  /**\n   * A timer used to retry transactions. Since there can be multiple concurrent\n   * transactions, multiple of these may be in the queue at a given time.\n   */\n  TransactionRetry = 'transaction_retry',\n\n  /**\n   * A timer used to retry operations scheduled via retryable AsyncQueue\n   * operations.\n   */\n  AsyncQueueRetry = 'async_queue_retry',\n\n  /**\n   *  A timer used to periodically attempt index backfill.\n   */\n  IndexBackfill = 'index_backfill'\n}\n\n/**\n * Represents an operation scheduled to be run in the future on an AsyncQueue.\n *\n * It is created via DelayedOperation.createAndSchedule().\n *\n * Supports cancellation (via cancel()) and early execution (via skipDelay()).\n *\n * Note: We implement `PromiseLike` instead of `Promise`, as the `Promise` type\n * in newer versions of TypeScript defines `finally`, which is not available in\n * IE.\n */\nexport class DelayedOperation<T extends unknown> implements PromiseLike<T> {\n  // handle for use with clearTimeout(), or null if the operation has been\n  // executed or canceled already.\n  private timerHandle: TimerHandle | null;\n\n  private readonly deferred = new Deferred<T>();\n\n  private constructor(\n    private readonly asyncQueue: AsyncQueue,\n    readonly timerId: TimerId,\n    readonly targetTimeMs: number,\n    private readonly op: () => Promise<T>,\n    private readonly removalCallback: (op: DelayedOperation<T>) => void\n  ) {\n    // It's normal for the deferred promise to be canceled (due to cancellation)\n    // and so we attach a dummy catch callback to avoid\n    // 'UnhandledPromiseRejectionWarning' log spam.\n    this.deferred.promise.catch(err => {});\n  }\n\n  get promise(): Promise<T> {\n    return this.deferred.promise;\n  }\n\n  /**\n   * Creates and returns a DelayedOperation that has been scheduled to be\n   * executed on the provided asyncQueue after the provided delayMs.\n   *\n   * @param asyncQueue - The queue to schedule the operation on.\n   * @param id - A Timer ID identifying the type of operation this is.\n   * @param delayMs - The delay (ms) before the operation should be scheduled.\n   * @param op - The operation to run.\n   * @param removalCallback - A callback to be called synchronously once the\n   *   operation is executed or canceled, notifying the AsyncQueue to remove it\n   *   from its delayedOperations list.\n   *   PORTING NOTE: This exists to prevent making removeDelayedOperation() and\n   *   the DelayedOperation class public.\n   */\n  static createAndSchedule<R extends unknown>(\n    asyncQueue: AsyncQueue,\n    timerId: TimerId,\n    delayMs: number,\n    op: () => Promise<R>,\n    removalCallback: (op: DelayedOperation<R>) => void\n  ): DelayedOperation<R> {\n    const targetTime = Date.now() + delayMs;\n    const delayedOp = new DelayedOperation(\n      asyncQueue,\n      timerId,\n      targetTime,\n      op,\n      removalCallback\n    );\n    delayedOp.start(delayMs);\n    return delayedOp;\n  }\n\n  /**\n   * Starts the timer. This is called immediately after construction by\n   * createAndSchedule().\n   */\n  private start(delayMs: number): void {\n    this.timerHandle = setTimeout(() => this.handleDelayElapsed(), delayMs);\n  }\n\n  /**\n   * Queues the operation to run immediately (if it hasn't already been run or\n   * canceled).\n   */\n  skipDelay(): void {\n    return this.handleDelayElapsed();\n  }\n\n  /**\n   * Cancels the operation if it hasn't already been executed or canceled. The\n   * promise will be rejected.\n   *\n   * As long as the operation has not yet been run, calling cancel() provides a\n   * guarantee that the operation will not be run.\n   */\n  cancel(reason?: string): void {\n    if (this.timerHandle !== null) {\n      this.clearTimeout();\n      this.deferred.reject(\n        new FirestoreError(\n          Code.CANCELLED,\n          'Operation cancelled' + (reason ? ': ' + reason : '')\n        )\n      );\n    }\n  }\n\n  then = this.deferred.promise.then.bind(this.deferred.promise);\n\n  private handleDelayElapsed(): void {\n    this.asyncQueue.enqueueAndForget(() => {\n      if (this.timerHandle !== null) {\n        this.clearTimeout();\n        return this.op().then(result => {\n          return this.deferred.resolve(result);\n        });\n      } else {\n        return Promise.resolve();\n      }\n    });\n  }\n\n  private clearTimeout(): void {\n    if (this.timerHandle !== null) {\n      this.removalCallback(this);\n      clearTimeout(this.timerHandle);\n      this.timerHandle = null;\n    }\n  }\n}\n\nexport interface AsyncQueue {\n  // Is this AsyncQueue being shut down? If true, this instance will not enqueue\n  // any new operations, Promises from enqueue requests will not resolve.\n  readonly isShuttingDown: boolean;\n\n  /**\n   * Adds a new operation to the queue without waiting for it to complete (i.e.\n   * we ignore the Promise result).\n   */\n  enqueueAndForget<T extends unknown>(op: () => Promise<T>): void;\n\n  /**\n   * Regardless if the queue has initialized shutdown, adds a new operation to the\n   * queue without waiting for it to complete (i.e. we ignore the Promise result).\n   */\n  enqueueAndForgetEvenWhileRestricted<T extends unknown>(\n    op: () => Promise<T>\n  ): void;\n\n  /**\n   * Initialize the shutdown of this queue. Once this method is called, the\n   * only possible way to request running an operation is through\n   * `enqueueEvenWhileRestricted()`.\n   *\n   * @param purgeExistingTasks - Whether already enqueued tasked should be\n   * rejected (unless enqueued with `enqueueEvenWhileRestricted()`). Defaults\n   * to false.\n   */\n  enterRestrictedMode(purgeExistingTasks?: boolean): void;\n\n  /**\n   * Adds a new operation to the queue. Returns a promise that will be resolved\n   * when the promise returned by the new operation is (with its value).\n   */\n  enqueue<T extends unknown>(op: () => Promise<T>): Promise<T>;\n\n  /**\n   * Enqueue a retryable operation.\n   *\n   * A retryable operation is rescheduled with backoff if it fails with a\n   * IndexedDbTransactionError (the error type used by SimpleDb). All\n   * retryable operations are executed in order and only run if all prior\n   * operations were retried successfully.\n   */\n  enqueueRetryable(op: () => Promise<void>): void;\n\n  /**\n   * Schedules an operation to be queued on the AsyncQueue once the specified\n   * `delayMs` has elapsed. The returned DelayedOperation can be used to cancel\n   * or fast-forward the operation prior to its running.\n   */\n  enqueueAfterDelay<T extends unknown>(\n    timerId: TimerId,\n    delayMs: number,\n    op: () => Promise<T>\n  ): DelayedOperation<T>;\n\n  /**\n   * Verifies there's an operation currently in-progress on the AsyncQueue.\n   * Unfortunately we can't verify that the running code is in the promise chain\n   * of that operation, so this isn't a foolproof check, but it should be enough\n   * to catch some bugs.\n   */\n  verifyOperationInProgress(): void;\n}\n\n/**\n * Returns a FirestoreError that can be surfaced to the user if the provided\n * error is an IndexedDbTransactionError. Re-throws the error otherwise.\n */\nexport function wrapInUserErrorIfRecoverable(\n  e: Error,\n  msg: string\n): FirestoreError {\n  logError(LOG_TAG, `${msg}: ${e}`);\n  if (isIndexedDbTransactionError(e)) {\n    return new FirestoreError(Code.UNAVAILABLE, `${msg}: ${e}`);\n  } else {\n    throw e;\n  }\n}\n","/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { isIndexedDbTransactionError } from '../local/simple_db';\nimport { getDocument } from '../platform/dom';\nimport { ExponentialBackoff } from '../remote/backoff';\n\nimport { debugAssert, fail } from './assert';\nimport { AsyncQueue, DelayedOperation, TimerId } from './async_queue';\nimport { FirestoreError } from './error';\nimport { logDebug, logError } from './log';\nimport { Deferred } from './promise';\n\nconst LOG_TAG = 'AsyncQueue';\n\nexport class AsyncQueueImpl implements AsyncQueue {\n  // The last promise in the queue.\n  private tail: Promise<unknown>;\n\n  // A list of retryable operations. Retryable operations are run in order and\n  // retried with backoff.\n  private retryableOps: Array<() => Promise<void>> = [];\n\n  // Is this AsyncQueue being shut down? Once it is set to true, it will not\n  // be changed again.\n  private _isShuttingDown: boolean = false;\n\n  // Operations scheduled to be queued in the future. Operations are\n  // automatically removed after they are run or canceled.\n  private delayedOperations: Array<DelayedOperation<unknown>> = [];\n\n  // visible for testing\n  failure: FirestoreError | null = null;\n\n  // Flag set while there's an outstanding AsyncQueue operation, used for\n  // assertion sanity-checks.\n  private operationInProgress = false;\n\n  // Enabled during shutdown on Safari to prevent future access to IndexedDB.\n  private skipNonRestrictedTasks = false;\n\n  // List of TimerIds to fast-forward delays for.\n  private timerIdsToSkip: TimerId[] = [];\n\n  // Backoff timer used to schedule retries for retryable operations\n  private backoff = new ExponentialBackoff(this, TimerId.AsyncQueueRetry);\n\n  // Visibility handler that triggers an immediate retry of all retryable\n  // operations. Meant to speed up recovery when we regain file system access\n  // after page comes into foreground.\n  private visibilityHandler: () => void = () => {\n    const document = getDocument();\n    if (document) {\n      logDebug(\n        LOG_TAG,\n        'Visibility state changed to ' + document.visibilityState\n      );\n    }\n    this.backoff.skipBackoff();\n  };\n\n  constructor(tail: Promise<unknown> = Promise.resolve()) {\n    this.tail = tail;\n    const document = getDocument();\n    if (document && typeof document.addEventListener === 'function') {\n      document.addEventListener('visibilitychange', this.visibilityHandler);\n    }\n  }\n\n  get isShuttingDown(): boolean {\n    return this._isShuttingDown;\n  }\n\n  /**\n   * Adds a new operation to the queue without waiting for it to complete (i.e.\n   * we ignore the Promise result).\n   */\n  enqueueAndForget<T extends unknown>(op: () => Promise<T>): void {\n    // eslint-disable-next-line @typescript-eslint/no-floating-promises\n    this.enqueue(op);\n  }\n\n  enqueueAndForgetEvenWhileRestricted<T extends unknown>(\n    op: () => Promise<T>\n  ): void {\n    this.verifyNotFailed();\n    // eslint-disable-next-line @typescript-eslint/no-floating-promises\n    this.enqueueInternal(op);\n  }\n\n  enterRestrictedMode(purgeExistingTasks?: boolean): void {\n    if (!this._isShuttingDown) {\n      this._isShuttingDown = true;\n      this.skipNonRestrictedTasks = purgeExistingTasks || false;\n      const document = getDocument();\n      if (document && typeof document.removeEventListener === 'function') {\n        document.removeEventListener(\n          'visibilitychange',\n          this.visibilityHandler\n        );\n      }\n    }\n  }\n\n  enqueue<T extends unknown>(op: () => Promise<T>): Promise<T> {\n    this.verifyNotFailed();\n    if (this._isShuttingDown) {\n      // Return a Promise which never resolves.\n      return new Promise<T>(() => {});\n    }\n\n    // Create a deferred Promise that we can return to the callee. This\n    // allows us to return a \"hanging Promise\" only to the callee and still\n    // advance the queue even when the operation is not run.\n    const task = new Deferred<T>();\n    return this.enqueueInternal<unknown>(() => {\n      if (this._isShuttingDown && this.skipNonRestrictedTasks) {\n        // We do not resolve 'task'\n        return Promise.resolve();\n      }\n\n      op().then(task.resolve, task.reject);\n      return task.promise;\n    }).then(() => task.promise);\n  }\n\n  enqueueRetryable(op: () => Promise<void>): void {\n    this.enqueueAndForget(() => {\n      this.retryableOps.push(op);\n      return this.retryNextOp();\n    });\n  }\n\n  /**\n   * Runs the next operation from the retryable queue. If the operation fails,\n   * reschedules with backoff.\n   */\n  private async retryNextOp(): Promise<void> {\n    if (this.retryableOps.length === 0) {\n      return;\n    }\n\n    try {\n      await this.retryableOps[0]();\n      this.retryableOps.shift();\n      this.backoff.reset();\n    } catch (e) {\n      if (isIndexedDbTransactionError(e as Error)) {\n        logDebug(LOG_TAG, 'Operation failed with retryable error: ' + e);\n      } else {\n        throw e; // Failure will be handled by AsyncQueue\n      }\n    }\n\n    if (this.retryableOps.length > 0) {\n      // If there are additional operations, we re-schedule `retryNextOp()`.\n      // This is necessary to run retryable operations that failed during\n      // their initial attempt since we don't know whether they are already\n      // enqueued. If, for example, `op1`, `op2`, `op3` are enqueued and `op1`\n      // needs to  be re-run, we will run `op1`, `op1`, `op2` using the\n      // already enqueued calls to `retryNextOp()`. `op3()` will then run in the\n      // call scheduled here.\n      // Since `backoffAndRun()` cancels an existing backoff and schedules a\n      // new backoff on every call, there is only ever a single additional\n      // operation in the queue.\n      this.backoff.backoffAndRun(() => this.retryNextOp());\n    }\n  }\n\n  private enqueueInternal<T extends unknown>(op: () => Promise<T>): Promise<T> {\n    const newTail = this.tail.then(() => {\n      this.operationInProgress = true;\n      return op()\n        .catch((error: FirestoreError) => {\n          this.failure = error;\n          this.operationInProgress = false;\n          const message = getMessageOrStack(error);\n          logError('INTERNAL UNHANDLED ERROR: ', message);\n\n          // Re-throw the error so that this.tail becomes a rejected Promise and\n          // all further attempts to chain (via .then) will just short-circuit\n          // and return the rejected Promise.\n          throw error;\n        })\n        .then(result => {\n          this.operationInProgress = false;\n          return result;\n        });\n    });\n    this.tail = newTail;\n    return newTail;\n  }\n\n  enqueueAfterDelay<T extends unknown>(\n    timerId: TimerId,\n    delayMs: number,\n    op: () => Promise<T>\n  ): DelayedOperation<T> {\n    this.verifyNotFailed();\n\n    debugAssert(\n      delayMs >= 0,\n      `Attempted to schedule an operation with a negative delay of ${delayMs}`\n    );\n\n    // Fast-forward delays for timerIds that have been overridden.\n    if (this.timerIdsToSkip.indexOf(timerId) > -1) {\n      delayMs = 0;\n    }\n\n    const delayedOp = DelayedOperation.createAndSchedule<T>(\n      this,\n      timerId,\n      delayMs,\n      op,\n      removedOp =>\n        this.removeDelayedOperation(removedOp as DelayedOperation<unknown>)\n    );\n    this.delayedOperations.push(delayedOp as DelayedOperation<unknown>);\n    return delayedOp;\n  }\n\n  private verifyNotFailed(): void {\n    if (this.failure) {\n      fail(0xb815, 'AsyncQueue is already failed', {\n        messageOrStack: getMessageOrStack(this.failure)\n      });\n    }\n  }\n\n  verifyOperationInProgress(): void {\n    debugAssert(\n      this.operationInProgress,\n      'verifyOpInProgress() called when no op in progress on this queue.'\n    );\n  }\n\n  /**\n   * Waits until all currently queued tasks are finished executing. Delayed\n   * operations are not run.\n   */\n  async drain(): Promise<void> {\n    // Operations in the queue prior to draining may have enqueued additional\n    // operations. Keep draining the queue until the tail is no longer advanced,\n    // which indicates that no more new operations were enqueued and that all\n    // operations were executed.\n    let currentTail: Promise<unknown>;\n    do {\n      currentTail = this.tail;\n      await currentTail;\n    } while (currentTail !== this.tail);\n  }\n\n  /**\n   * For Tests: Determine if a delayed operation with a particular TimerId\n   * exists.\n   */\n  containsDelayedOperation(timerId: TimerId): boolean {\n    for (const op of this.delayedOperations) {\n      if (op.timerId === timerId) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  /**\n   * For Tests: Runs some or all delayed operations early.\n   *\n   * @param lastTimerId - Delayed operations up to and including this TimerId\n   * will be drained. Pass TimerId.All to run all delayed operations.\n   * @returns a Promise that resolves once all operations have been run.\n   */\n  runAllDelayedOperationsUntil(lastTimerId: TimerId): Promise<void> {\n    // Note that draining may generate more delayed ops, so we do that first.\n    return this.drain().then(() => {\n      // Run ops in the same order they'd run if they ran naturally.\n      /* eslint-disable-next-line @typescript-eslint/no-floating-promises */\n      this.delayedOperations.sort((a, b) => a.targetTimeMs - b.targetTimeMs);\n\n      for (const op of this.delayedOperations) {\n        op.skipDelay();\n        if (lastTimerId !== TimerId.All && op.timerId === lastTimerId) {\n          break;\n        }\n      }\n\n      return this.drain();\n    });\n  }\n\n  /**\n   * For Tests: Skip all subsequent delays for a timer id.\n   */\n  skipDelaysForTimerId(timerId: TimerId): void {\n    this.timerIdsToSkip.push(timerId);\n  }\n\n  /** Called once a DelayedOperation is run or canceled. */\n  private removeDelayedOperation(op: DelayedOperation<unknown>): void {\n    // NOTE: indexOf / slice are O(n), but delayedOperations is expected to be small.\n    const index = this.delayedOperations.indexOf(op);\n    debugAssert(index >= 0, 'Delayed operation not found.');\n    /* eslint-disable-next-line @typescript-eslint/no-floating-promises */\n    this.delayedOperations.splice(index, 1);\n  }\n}\n\nexport function newAsyncQueue(): AsyncQueue {\n  return new AsyncQueueImpl();\n}\n\n/**\n * Chrome includes Error.message in Error.stack. Other browsers do not.\n * This returns expected output of message + stack when available.\n * @param error - Error or FirestoreError\n */\nfunction getMessageOrStack(error: Error): string {\n  let message = error.message || '';\n  if (error.stack) {\n    if (error.stack.includes(error.message)) {\n      message = error.stack;\n    } else {\n      message = error.message + '\\n' + error.stack;\n    }\n  }\n  return message;\n}\n","/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getGlobal, getUA, isIndexedDBAvailable } from '@firebase/util';\n\nimport { debugAssert } from '../util/assert';\nimport { Code, FirestoreError } from '../util/error';\nimport { logDebug, logError } from '../util/log';\nimport { Deferred } from '../util/promise';\n\nimport { PersistencePromise } from './persistence_promise';\n\n// References to `indexedDB` are guarded by SimpleDb.isAvailable() and getGlobal()\n/* eslint-disable no-restricted-globals */\n\nconst LOG_TAG = 'SimpleDb';\n\n/**\n * The maximum number of retry attempts for an IndexedDb transaction that fails\n * with a DOMException.\n */\nconst TRANSACTION_RETRY_COUNT = 3;\n\n// The different modes supported by `SimpleDb.runTransaction()`\ntype SimpleDbTransactionMode = 'readonly' | 'readwrite';\n\nexport interface SimpleDbSchemaConverter {\n  createOrUpgrade(\n    db: IDBDatabase,\n    txn: IDBTransaction,\n    fromVersion: number,\n    toVersion: number\n  ): PersistencePromise<void>;\n}\n\n/**\n * Wraps an IDBTransaction and exposes a store() method to get a handle to a\n * specific object store.\n */\nexport class SimpleDbTransaction {\n  private aborted = false;\n\n  /**\n   * A `Promise` that resolves with the result of the IndexedDb transaction.\n   */\n  private readonly completionDeferred = new Deferred<void>();\n\n  static open(\n    db: IDBDatabase,\n    action: string,\n    mode: IDBTransactionMode,\n    objectStoreNames: string[]\n  ): SimpleDbTransaction {\n    try {\n      return new SimpleDbTransaction(\n        action,\n        db.transaction(objectStoreNames, mode)\n      );\n    } catch (e) {\n      throw new IndexedDbTransactionError(action, e as Error);\n    }\n  }\n\n  constructor(\n    private readonly action: string,\n    private readonly transaction: IDBTransaction\n  ) {\n    this.transaction.oncomplete = () => {\n      this.completionDeferred.resolve();\n    };\n    this.transaction.onabort = () => {\n      if (transaction.error) {\n        this.completionDeferred.reject(\n          new IndexedDbTransactionError(action, transaction.error)\n        );\n      } else {\n        this.completionDeferred.resolve();\n      }\n    };\n    this.transaction.onerror = (event: Event) => {\n      const error = checkForAndReportiOSError(\n        (event.target as IDBRequest).error!\n      );\n      this.completionDeferred.reject(\n        new IndexedDbTransactionError(action, error)\n      );\n    };\n  }\n\n  get completionPromise(): Promise<void> {\n    return this.completionDeferred.promise;\n  }\n\n  abort(error?: Error): void {\n    if (error) {\n      this.completionDeferred.reject(error);\n    }\n\n    if (!this.aborted) {\n      logDebug(\n        LOG_TAG,\n        'Aborting transaction:',\n        error ? error.message : 'Client-initiated abort'\n      );\n      this.aborted = true;\n      this.transaction.abort();\n    }\n  }\n\n  maybeCommit(): void {\n    // If the browser supports V3 IndexedDB, we invoke commit() explicitly to\n    // speed up index DB processing if the event loop remains blocks.\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    const maybeV3IndexedDb = this.transaction as any;\n    if (!this.aborted && typeof maybeV3IndexedDb.commit === 'function') {\n      maybeV3IndexedDb.commit();\n    }\n  }\n\n  /**\n   * Returns a SimpleDbStore<KeyType, ValueType> for the specified store. All\n   * operations performed on the SimpleDbStore happen within the context of this\n   * transaction and it cannot be used anymore once the transaction is\n   * completed.\n   *\n   * Note that we can't actually enforce that the KeyType and ValueType are\n   * correct, but they allow type safety through the rest of the consuming code.\n   */\n  store<KeyType extends IDBValidKey, ValueType extends unknown>(\n    storeName: string\n  ): SimpleDbStore<KeyType, ValueType> {\n    const store = this.transaction.objectStore(storeName);\n    debugAssert(!!store, 'Object store not part of transaction: ' + storeName);\n    return new SimpleDbStore<KeyType, ValueType>(store);\n  }\n}\n\n/**\n * Provides a wrapper around IndexedDb with a simplified interface that uses\n * Promise-like return values to chain operations. Real promises cannot be used\n * since .then() continuations are executed asynchronously (e.g. via\n * .setImmediate), which would cause IndexedDB to end the transaction.\n * See PersistencePromise for more details.\n */\nexport class SimpleDb {\n  private db?: IDBDatabase;\n  private lastClosedDbVersion: number | null = null;\n  private versionchangelistener?: (event: IDBVersionChangeEvent) => void;\n\n  /** Deletes the specified database. */\n  static delete(name: string): Promise<void> {\n    logDebug(LOG_TAG, 'Removing database:', name);\n    const globals = getGlobal();\n    return wrapRequest<void>(\n      globals.indexedDB.deleteDatabase(name)\n    ).toPromise();\n  }\n\n  /** Returns true if IndexedDB is available in the current environment. */\n  static isAvailable(): boolean {\n    if (!isIndexedDBAvailable()) {\n      return false;\n    }\n\n    if (SimpleDb.isMockPersistence()) {\n      return true;\n    }\n\n    // We extensively use indexed array values and compound keys,\n    // which IE and Edge do not support. However, they still have indexedDB\n    // defined on the window, so we need to check for them here and make sure\n    // to return that persistence is not enabled for those browsers.\n    // For tracking support of this feature, see here:\n    // https://developer.microsoft.com/en-us/microsoft-edge/platform/status/indexeddbarraysandmultientrysupport/\n\n    // Check the UA string to find out the browser.\n    const ua = getUA();\n\n    // IE 10\n    // ua = 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)';\n\n    // IE 11\n    // ua = 'Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko';\n\n    // Edge\n    // ua = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML,\n    // like Gecko) Chrome/39.0.2171.71 Safari/537.36 Edge/12.0';\n\n    // iOS Safari: Disable for users running iOS version < 10.\n    const iOSVersion = SimpleDb.getIOSVersion(ua);\n    const isUnsupportedIOS = 0 < iOSVersion && iOSVersion < 10;\n\n    // Android browser: Disable for users running version < 4.5.\n    const androidVersion = getAndroidVersion(ua);\n    const isUnsupportedAndroid = 0 < androidVersion && androidVersion < 4.5;\n\n    if (\n      ua.indexOf('MSIE ') > 0 ||\n      ua.indexOf('Trident/') > 0 ||\n      ua.indexOf('Edge/') > 0 ||\n      isUnsupportedIOS ||\n      isUnsupportedAndroid\n    ) {\n      return false;\n    } else {\n      return true;\n    }\n  }\n\n  /**\n   * Returns true if the backing IndexedDB store is the Node IndexedDBShim\n   * (see https://github.com/axemclion/IndexedDBShim).\n   */\n  static isMockPersistence(): boolean {\n    return (\n      typeof process !== 'undefined' &&\n      process.env?.USE_MOCK_PERSISTENCE === 'YES'\n    );\n  }\n\n  /** Helper to get a typed SimpleDbStore from a transaction. */\n  static getStore<KeyType extends IDBValidKey, ValueType extends unknown>(\n    txn: SimpleDbTransaction,\n    store: string\n  ): SimpleDbStore<KeyType, ValueType> {\n    return txn.store<KeyType, ValueType>(store);\n  }\n\n  // visible for testing\n  /** Parse User Agent to determine iOS version. Returns -1 if not found. */\n  static getIOSVersion(ua: string): number {\n    const iOSVersionRegex = ua.match(/i(?:phone|pad|pod) os ([\\d_]+)/i);\n    const version = iOSVersionRegex\n      ? iOSVersionRegex[1].split('_').slice(0, 2).join('.')\n      : '-1';\n    return Number(version);\n  }\n\n  /*\n   * Creates a new SimpleDb wrapper for IndexedDb database `name`.\n   *\n   * Note that `version` must not be a downgrade. IndexedDB does not support\n   * downgrading the schema version. We currently do not support any way to do\n   * versioning outside of IndexedDB's versioning mechanism, as only\n   * version-upgrade transactions are allowed to do things like create\n   * objectstores.\n   */\n  constructor(\n    private readonly name: string,\n    private readonly version: number,\n    private readonly schemaConverter: SimpleDbSchemaConverter\n  ) {\n    debugAssert(\n      SimpleDb.isAvailable(),\n      'IndexedDB not supported in current environment.'\n    );\n\n    const iOSVersion = SimpleDb.getIOSVersion(getUA());\n    // NOTE: According to https://bugs.webkit.org/show_bug.cgi?id=197050, the\n    // bug we're checking for should exist in iOS >= 12.2 and < 13, but for\n    // whatever reason it's much harder to hit after 12.2 so we only proactively\n    // log on 12.2.\n    if (iOSVersion === 12.2) {\n      logError(\n        'Firestore persistence suffers from a bug in iOS 12.2 ' +\n          'Safari that may cause your app to stop working. See ' +\n          'https://stackoverflow.com/q/56496296/110915 for details ' +\n          'and a potential workaround.'\n      );\n    }\n  }\n\n  /**\n   * Opens the specified database, creating or upgrading it if necessary.\n   */\n  async ensureDb(action: string): Promise<IDBDatabase> {\n    if (!this.db) {\n      logDebug(LOG_TAG, 'Opening database:', this.name);\n      this.db = await new Promise<IDBDatabase>((resolve, reject) => {\n        // TODO(mikelehen): Investigate browser compatibility.\n        // https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB\n        // suggests IE9 and older WebKit browsers handle upgrade\n        // differently. They expect setVersion, as described here:\n        // https://developer.mozilla.org/en-US/docs/Web/API/IDBVersionChangeRequest/setVersion\n        const request = indexedDB.open(this.name, this.version);\n\n        request.onsuccess = (event: Event) => {\n          const db = (event.target as IDBOpenDBRequest).result;\n          resolve(db);\n        };\n\n        request.onblocked = () => {\n          reject(\n            new IndexedDbTransactionError(\n              action,\n              'Cannot upgrade IndexedDB schema while another tab is open. ' +\n                'Close all tabs that access Firestore and reload this page to proceed.'\n            )\n          );\n        };\n\n        request.onerror = (event: Event) => {\n          const error: DOMException = (event.target as IDBOpenDBRequest).error!;\n          if (error.name === 'VersionError') {\n            reject(\n              new FirestoreError(\n                Code.FAILED_PRECONDITION,\n                'A newer version of the Firestore SDK was previously used and so the persisted ' +\n                  'data is not compatible with the version of the SDK you are now using. The SDK ' +\n                  'will operate with persistence disabled. If you need persistence, please ' +\n                  're-upgrade to a newer version of the SDK or else clear the persisted IndexedDB ' +\n                  'data for your app to start fresh.'\n              )\n            );\n          } else if (error.name === 'InvalidStateError') {\n            reject(\n              new FirestoreError(\n                Code.FAILED_PRECONDITION,\n                'Unable to open an IndexedDB connection. This could be due to running in a ' +\n                  'private browsing session on a browser whose private browsing sessions do not ' +\n                  'support IndexedDB: ' +\n                  error\n              )\n            );\n          } else {\n            reject(new IndexedDbTransactionError(action, error));\n          }\n        };\n\n        request.onupgradeneeded = (event: IDBVersionChangeEvent) => {\n          logDebug(\n            LOG_TAG,\n            'Database \"' + this.name + '\" requires upgrade from version:',\n            event.oldVersion\n          );\n          const db = (event.target as IDBOpenDBRequest).result;\n          this.schemaConverter\n            .createOrUpgrade(\n              db,\n              request.transaction!,\n              event.oldVersion,\n              this.version\n            )\n            .next(() => {\n              logDebug(\n                LOG_TAG,\n                'Database upgrade to version ' + this.version + ' complete'\n              );\n            });\n        };\n      });\n    }\n\n    if (this.versionchangelistener) {\n      this.db.onversionchange = event => this.versionchangelistener!(event);\n    }\n\n    return this.db;\n  }\n\n  setVersionChangeListener(\n    versionChangeListener: (event: IDBVersionChangeEvent) => void\n  ): void {\n    this.versionchangelistener = versionChangeListener;\n    if (this.db) {\n      this.db.onversionchange = (event: IDBVersionChangeEvent) => {\n        return versionChangeListener(event);\n      };\n    }\n  }\n\n  async runTransaction<T>(\n    action: string,\n    mode: SimpleDbTransactionMode,\n    objectStores: string[],\n    transactionFn: (transaction: SimpleDbTransaction) => PersistencePromise<T>\n  ): Promise<T> {\n    const readonly = mode === 'readonly';\n    let attemptNumber = 0;\n\n    while (true) {\n      ++attemptNumber;\n\n      try {\n        this.db = await this.ensureDb(action);\n\n        const transaction = SimpleDbTransaction.open(\n          this.db,\n          action,\n          readonly ? 'readonly' : 'readwrite',\n          objectStores\n        );\n        const transactionFnResult = transactionFn(transaction)\n          .next(result => {\n            transaction.maybeCommit();\n            return result;\n          })\n          .catch(error => {\n            // Abort the transaction if there was an error.\n            transaction.abort(error);\n            // We cannot actually recover, and calling `abort()` will cause the transaction's\n            // completion promise to be rejected. This in turn means that we won't use\n            // `transactionFnResult` below. We return a rejection here so that we don't add the\n            // possibility of returning `void` to the type of `transactionFnResult`.\n            return PersistencePromise.reject<T>(error);\n          })\n          .toPromise();\n\n        // As noted above, errors are propagated by aborting the transaction. So\n        // we swallow any error here to avoid the browser logging it as unhandled.\n        transactionFnResult.catch(() => {});\n\n        // Wait for the transaction to complete (i.e. IndexedDb's onsuccess event to\n        // fire), but still return the original transactionFnResult back to the\n        // caller.\n        await transaction.completionPromise;\n        return transactionFnResult;\n      } catch (e) {\n        const error = e as Error;\n        // TODO(schmidt-sebastian): We could probably be smarter about this and\n        // not retry exceptions that are likely unrecoverable (such as quota\n        // exceeded errors).\n\n        // Note: We cannot use an instanceof check for FirestoreException, since the\n        // exception is wrapped in a generic error by our async/await handling.\n        const retryable =\n          error.name !== 'FirebaseError' &&\n          attemptNumber < TRANSACTION_RETRY_COUNT;\n        logDebug(\n          LOG_TAG,\n          'Transaction failed with error:',\n          error.message,\n          'Retrying:',\n          retryable\n        );\n\n        this.close();\n\n        if (!retryable) {\n          return Promise.reject(error);\n        }\n      }\n    }\n  }\n\n  close(): void {\n    if (this.db) {\n      this.db.close();\n    }\n    this.db = undefined;\n  }\n}\n\n/** Parse User Agent to determine Android version. Returns -1 if not found. */\nexport function getAndroidVersion(ua: string): number {\n  const androidVersionRegex = ua.match(/Android ([\\d.]+)/i);\n  const version = androidVersionRegex\n    ? androidVersionRegex[1].split('.').slice(0, 2).join('.')\n    : '-1';\n  return Number(version);\n}\n\n/**\n * A controller for iterating over a key range or index. It allows an iterate\n * callback to delete the currently-referenced object, or jump to a new key\n * within the key range or index.\n */\nexport class IterationController {\n  private shouldStop = false;\n  private nextKey: IDBValidKey | null = null;\n\n  constructor(private dbCursor: IDBCursorWithValue) {}\n\n  get isDone(): boolean {\n    return this.shouldStop;\n  }\n\n  get skipToKey(): IDBValidKey | null {\n    return this.nextKey;\n  }\n\n  set cursor(value: IDBCursorWithValue) {\n    this.dbCursor = value;\n  }\n\n  /**\n   * This function can be called to stop iteration at any point.\n   */\n  done(): void {\n    this.shouldStop = true;\n  }\n\n  /**\n   * This function can be called to skip to that next key, which could be\n   * an index or a primary key.\n   */\n  skip(key: IDBValidKey): void {\n    this.nextKey = key;\n  }\n\n  /**\n   * Delete the current cursor value from the object store.\n   *\n   * NOTE: You CANNOT do this with a keysOnly query.\n   */\n  delete(): PersistencePromise<void> {\n    return wrapRequest<void>(this.dbCursor.delete());\n  }\n}\n\n/**\n * Callback used with iterate() method.\n */\nexport type IterateCallback<KeyType, ValueType> = (\n  key: KeyType,\n  value: ValueType,\n  control: IterationController\n) => void | PersistencePromise<void>;\n\n/** Options available to the iterate() method. */\nexport interface IterateOptions {\n  /** Index to iterate over (else primary keys will be iterated) */\n  index?: string;\n\n  /** IndexedDB Range to iterate over (else entire store will be iterated) */\n  range?: IDBKeyRange;\n\n  /** If true, values aren't read while iterating. */\n  keysOnly?: boolean;\n\n  /** If true, iterate over the store in reverse. */\n  reverse?: boolean;\n}\n\n/** An error that wraps exceptions that thrown during IndexedDB execution. */\nexport class IndexedDbTransactionError extends FirestoreError {\n  name = 'IndexedDbTransactionError';\n\n  constructor(actionName: string, cause: Error | string) {\n    super(\n      Code.UNAVAILABLE,\n      `IndexedDB transaction '${actionName}' failed: ${cause}`\n    );\n  }\n}\n\n/** Verifies whether `e` is an IndexedDbTransactionError. */\nexport function isIndexedDbTransactionError(e: Error): boolean {\n  // Use name equality, as instanceof checks on errors don't work with errors\n  // that wrap other errors.\n  return e.name === 'IndexedDbTransactionError';\n}\n\n/**\n * A wrapper around an IDBObjectStore providing an API that:\n *\n * 1) Has generic KeyType / ValueType parameters to provide strongly-typed\n * methods for acting against the object store.\n * 2) Deals with IndexedDB's onsuccess / onerror event callbacks, making every\n * method return a PersistencePromise instead.\n * 3) Provides a higher-level API to avoid needing to do excessive wrapping of\n * intermediate IndexedDB types (IDBCursorWithValue, etc.)\n */\nexport class SimpleDbStore<\n  KeyType extends IDBValidKey,\n  ValueType extends unknown\n> {\n  constructor(private store: IDBObjectStore) {}\n\n  /**\n   * Writes a value into the Object Store.\n   *\n   * @param key - Optional explicit key to use when writing the object, else the\n   * key will be auto-assigned (e.g. via the defined keyPath for the store).\n   * @param value - The object to write.\n   */\n  put(value: ValueType): PersistencePromise<void>;\n  put(key: KeyType, value: ValueType): PersistencePromise<void>;\n  put(\n    keyOrValue: KeyType | ValueType,\n    value?: ValueType\n  ): PersistencePromise<void> {\n    let request;\n    if (value !== undefined) {\n      logDebug(LOG_TAG, 'PUT', this.store.name, keyOrValue, value);\n      request = this.store.put(value, keyOrValue as KeyType);\n    } else {\n      logDebug(LOG_TAG, 'PUT', this.store.name, '<auto-key>', keyOrValue);\n      request = this.store.put(keyOrValue as ValueType);\n    }\n    return wrapRequest<void>(request);\n  }\n\n  /**\n   * Adds a new value into an Object Store and returns the new key. Similar to\n   * IndexedDb's `add()`, this method will fail on primary key collisions.\n   *\n   * @param value - The object to write.\n   * @returns The key of the value to add.\n   */\n  add(value: ValueType): PersistencePromise<KeyType> {\n    logDebug(LOG_TAG, 'ADD', this.store.name, value, value);\n    const request = this.store.add(value as ValueType);\n    return wrapRequest<KeyType>(request);\n  }\n\n  /**\n   * Gets the object with the specified key from the specified store, or null\n   * if no object exists with the specified key.\n   *\n   * @key The key of the object to get.\n   * @returns The object with the specified key or null if no object exists.\n   */\n  get(key: KeyType): PersistencePromise<ValueType | null> {\n    const request = this.store.get(key);\n    // We're doing an unsafe cast to ValueType.\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    return wrapRequest<any>(request).next(result => {\n      // Normalize nonexistence to null.\n      if (result === undefined) {\n        result = null;\n      }\n      logDebug(LOG_TAG, 'GET', this.store.name, key, result);\n      return result;\n    });\n  }\n\n  delete(key: KeyType | IDBKeyRange): PersistencePromise<void> {\n    logDebug(LOG_TAG, 'DELETE', this.store.name, key);\n    const request = this.store.delete(key);\n    return wrapRequest<void>(request);\n  }\n\n  /**\n   * If we ever need more of the count variants, we can add overloads. For now,\n   * all we need is to count everything in a store.\n   *\n   * Returns the number of rows in the store.\n   */\n  count(): PersistencePromise<number> {\n    logDebug(LOG_TAG, 'COUNT', this.store.name);\n    const request = this.store.count();\n    return wrapRequest<number>(request);\n  }\n\n  /** Loads all elements from the object store. */\n  loadAll(): PersistencePromise<ValueType[]>;\n  /** Loads all elements for the index range from the object store. */\n  loadAll(range: IDBKeyRange): PersistencePromise<ValueType[]>;\n  /** Loads all elements ordered by the given index. */\n  loadAll(index: string): PersistencePromise<ValueType[]>;\n  /**\n   * Loads all elements from the object store that fall into the provided in the\n   * index range for the given index.\n   */\n  loadAll(index: string, range: IDBKeyRange): PersistencePromise<ValueType[]>;\n  loadAll(\n    indexOrRange?: string | IDBKeyRange,\n    range?: IDBKeyRange\n  ): PersistencePromise<ValueType[]> {\n    const iterateOptions = this.options(indexOrRange, range);\n    // Use `getAll()` if the browser supports IndexedDB v3, as it is roughly\n    // 20% faster.\n    const store = iterateOptions.index\n      ? this.store.index(iterateOptions.index)\n      : this.store;\n    if (typeof store.getAll === 'function') {\n      const request = store.getAll(iterateOptions.range);\n      return new PersistencePromise((resolve, reject) => {\n        request.onerror = (event: Event) => {\n          reject((event.target as IDBRequest).error!);\n        };\n        request.onsuccess = (event: Event) => {\n          resolve((event.target as IDBRequest).result);\n        };\n      });\n    } else {\n      const cursor = this.cursor(iterateOptions);\n      const results: ValueType[] = [];\n      return this.iterateCursor(cursor, (key, value) => {\n        results.push(value);\n      }).next(() => {\n        return results;\n      });\n    }\n  }\n\n  /**\n   * Loads the first `count` elements from the provided index range. Loads all\n   * elements if no limit is provided.\n   */\n  loadFirst(\n    range: IDBKeyRange,\n    count: number | null\n  ): PersistencePromise<ValueType[]> {\n    const request = this.store.getAll(\n      range,\n      count === null ? undefined : count\n    );\n    return new PersistencePromise((resolve, reject) => {\n      request.onerror = (event: Event) => {\n        reject((event.target as IDBRequest).error!);\n      };\n      request.onsuccess = (event: Event) => {\n        resolve((event.target as IDBRequest).result);\n      };\n    });\n  }\n\n  deleteAll(): PersistencePromise<void>;\n  deleteAll(range: IDBKeyRange): PersistencePromise<void>;\n  deleteAll(index: string, range: IDBKeyRange): PersistencePromise<void>;\n  deleteAll(\n    indexOrRange?: string | IDBKeyRange,\n    range?: IDBKeyRange\n  ): PersistencePromise<void> {\n    logDebug(LOG_TAG, 'DELETE ALL', this.store.name);\n    const options = this.options(indexOrRange, range);\n    options.keysOnly = false;\n    const cursor = this.cursor(options);\n    return this.iterateCursor(cursor, (key, value, control) => {\n      // NOTE: Calling delete() on a cursor is documented as more efficient than\n      // calling delete() on an object store with a single key\n      // (https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore/delete),\n      // however, this requires us *not* to use a keysOnly cursor\n      // (https://developer.mozilla.org/en-US/docs/Web/API/IDBCursor/delete). We\n      // may want to compare the performance of each method.\n      return control.delete();\n    });\n  }\n\n  /**\n   * Iterates over keys and values in an object store.\n   *\n   * @param options - Options specifying how to iterate the objects in the\n   * store.\n   * @param callback - will be called for each iterated object. Iteration can be\n   * canceled at any point by calling the doneFn passed to the callback.\n   * The callback can return a PersistencePromise if it performs async\n   * operations but note that iteration will continue without waiting for them\n   * to complete.\n   * @returns A PersistencePromise that resolves once all PersistencePromises\n   * returned by callbacks resolve.\n   */\n  iterate(\n    callback: IterateCallback<KeyType, ValueType>\n  ): PersistencePromise<void>;\n  iterate(\n    options: IterateOptions,\n    callback: IterateCallback<KeyType, ValueType>\n  ): PersistencePromise<void>;\n  iterate(\n    optionsOrCallback: IterateOptions | IterateCallback<KeyType, ValueType>,\n    callback?: IterateCallback<KeyType, ValueType>\n  ): PersistencePromise<void> {\n    let options;\n    if (!callback) {\n      options = {};\n      callback = optionsOrCallback as IterateCallback<KeyType, ValueType>;\n    } else {\n      options = optionsOrCallback as IterateOptions;\n    }\n    const cursor = this.cursor(options);\n    return this.iterateCursor(cursor, callback);\n  }\n\n  /**\n   * Iterates over a store, but waits for the given callback to complete for\n   * each entry before iterating the next entry. This allows the callback to do\n   * asynchronous work to determine if this iteration should continue.\n   *\n   * The provided callback should return `true` to continue iteration, and\n   * `false` otherwise.\n   */\n  iterateSerial(\n    callback: (k: KeyType, v: ValueType) => PersistencePromise<boolean>\n  ): PersistencePromise<void> {\n    const cursorRequest = this.cursor({});\n    return new PersistencePromise((resolve, reject) => {\n      cursorRequest.onerror = (event: Event) => {\n        const error = checkForAndReportiOSError(\n          (event.target as IDBRequest).error!\n        );\n        reject(error);\n      };\n      cursorRequest.onsuccess = (event: Event) => {\n        const cursor: IDBCursorWithValue = (event.target as IDBRequest).result;\n        if (!cursor) {\n          resolve();\n          return;\n        }\n\n        callback(cursor.primaryKey as KeyType, cursor.value).next(\n          shouldContinue => {\n            if (shouldContinue) {\n              cursor.continue();\n            } else {\n              resolve();\n            }\n          }\n        );\n      };\n    });\n  }\n\n  private iterateCursor(\n    cursorRequest: IDBRequest,\n    fn: IterateCallback<KeyType, ValueType>\n  ): PersistencePromise<void> {\n    const results: Array<PersistencePromise<void>> = [];\n    return new PersistencePromise((resolve, reject) => {\n      cursorRequest.onerror = (event: Event) => {\n        reject((event.target as IDBRequest).error!);\n      };\n      cursorRequest.onsuccess = (event: Event) => {\n        const cursor: IDBCursorWithValue = (event.target as IDBRequest).result;\n        if (!cursor) {\n          resolve();\n          return;\n        }\n        const controller = new IterationController(cursor);\n        const userResult = fn(\n          cursor.primaryKey as KeyType,\n          cursor.value,\n          controller\n        );\n        if (userResult instanceof PersistencePromise) {\n          const userPromise: PersistencePromise<void> = userResult.catch(\n            err => {\n              controller.done();\n              return PersistencePromise.reject(err);\n            }\n          );\n          results.push(userPromise);\n        }\n        if (controller.isDone) {\n          resolve();\n        } else if (controller.skipToKey === null) {\n          cursor.continue();\n        } else {\n          cursor.continue(controller.skipToKey);\n        }\n      };\n    }).next(() => PersistencePromise.waitFor(results));\n  }\n\n  private options(\n    indexOrRange?: string | IDBKeyRange,\n    range?: IDBKeyRange\n  ): IterateOptions {\n    let indexName: string | undefined = undefined;\n    if (indexOrRange !== undefined) {\n      if (typeof indexOrRange === 'string') {\n        indexName = indexOrRange;\n      } else {\n        debugAssert(\n          range === undefined,\n          '3rd argument must not be defined if 2nd is a range.'\n        );\n        range = indexOrRange;\n      }\n    }\n    return { index: indexName, range };\n  }\n\n  private cursor(options: IterateOptions): IDBRequest {\n    let direction: IDBCursorDirection = 'next';\n    if (options.reverse) {\n      direction = 'prev';\n    }\n    if (options.index) {\n      const index = this.store.index(options.index);\n      if (options.keysOnly) {\n        return index.openKeyCursor(options.range, direction);\n      } else {\n        return index.openCursor(options.range, direction);\n      }\n    } else {\n      return this.store.openCursor(options.range, direction);\n    }\n  }\n}\n\n/**\n * Wraps an IDBRequest in a PersistencePromise, using the onsuccess / onerror\n * handlers to resolve / reject the PersistencePromise as appropriate.\n */\nfunction wrapRequest<R>(request: IDBRequest): PersistencePromise<R> {\n  return new PersistencePromise<R>((resolve, reject) => {\n    request.onsuccess = (event: Event) => {\n      const result = (event.target as IDBRequest).result;\n      resolve(result);\n    };\n\n    request.onerror = (event: Event) => {\n      const error = checkForAndReportiOSError(\n        (event.target as IDBRequest).error!\n      );\n      reject(error);\n    };\n  });\n}\n\n// Guard so we only report the error once.\nlet reportedIOSError = false;\nfunction checkForAndReportiOSError(error: DOMException): Error {\n  const iOSVersion = SimpleDb.getIOSVersion(getUA());\n  if (iOSVersion >= 12.2 && iOSVersion < 13) {\n    const IOS_ERROR =\n      'An internal error was encountered in the Indexed Database server';\n    if (error.message.indexOf(IOS_ERROR) >= 0) {\n      // Wrap error in a more descriptive one.\n      const newError = new FirestoreError(\n        'internal',\n        `IOS_INDEXEDDB_BUG1: IndexedDb has thrown '${IOS_ERROR}'. This is likely ` +\n          `due to an unavoidable bug in iOS. See https://stackoverflow.com/q/56496296/110915 ` +\n          `for details and a potential workaround.`\n      );\n      if (!reportedIOSError) {\n        reportedIOSError = true;\n        // Throw a global exception outside of this promise chain, for the user to\n        // potentially catch.\n        setTimeout(() => {\n          throw newError;\n        }, 0);\n      }\n      return newError;\n    }\n  }\n  return error;\n}\n","/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getModularInstance } from '@firebase/util';\n\nimport { Transaction as InternalTransaction } from '../core/transaction';\nimport {\n  DEFAULT_TRANSACTION_OPTIONS,\n  TransactionOptions as TransactionOptionsInternal,\n  validateTransactionOptions\n} from '../core/transaction_options';\nimport { TransactionRunner } from '../core/transaction_runner';\nimport { fail } from '../util/assert';\nimport { newAsyncQueue } from '../util/async_queue_impl';\nimport { cast } from '../util/input_validation';\nimport { Deferred } from '../util/promise';\n\nimport { getDatastore } from './components';\nimport { Firestore } from './database';\nimport { FieldPath } from './field_path';\nimport {\n  DocumentData,\n  DocumentReference,\n  PartialWithFieldValue,\n  SetOptions,\n  UpdateData,\n  WithFieldValue\n} from './reference';\nimport {\n  applyFirestoreDataConverter,\n  LiteUserDataWriter\n} from './reference_impl';\nimport { DocumentSnapshot } from './snapshot';\nimport { TransactionOptions } from './transaction_options';\nimport {\n  newUserDataReader,\n  parseSetData,\n  parseUpdateData,\n  parseUpdateVarargs,\n  UserDataReader\n} from './user_data_reader';\nimport { validateReference } from './write_batch';\n\n// TODO(mrschmidt) Consider using `BaseTransaction` as the base class in the\n// legacy SDK.\n\n/**\n * A reference to a transaction.\n *\n * The `Transaction` object passed to a transaction's `updateFunction` provides\n * the methods to read and write data within the transaction context. See\n * {@link runTransaction}.\n */\nexport class Transaction {\n  // This is the tree-shakeable version of the Transaction class used in the\n  // legacy SDK. The class is a close copy but takes different input and output\n  // types. The firestore-exp SDK further extends this class to return its API\n  // type.\n\n  private readonly _dataReader: UserDataReader;\n\n  /** @hideconstructor */\n  constructor(\n    protected readonly _firestore: Firestore,\n    private readonly _transaction: InternalTransaction\n  ) {\n    this._dataReader = newUserDataReader(_firestore);\n  }\n\n  /**\n   * Reads the document referenced by the provided {@link DocumentReference}.\n   *\n   * @param documentRef - A reference to the document to be read.\n   * @returns A `DocumentSnapshot` with the read data.\n   */\n  get<AppModelType, DbModelType extends DocumentData>(\n    documentRef: DocumentReference<AppModelType, DbModelType>\n  ): Promise<DocumentSnapshot<AppModelType, DbModelType>> {\n    const ref = validateReference(documentRef, this._firestore);\n    const userDataWriter = new LiteUserDataWriter(this._firestore);\n    return this._transaction.lookup([ref._key]).then(docs => {\n      if (!docs || docs.length !== 1) {\n        return fail(0x5de9, 'Mismatch in docs returned from document lookup.');\n      }\n      const doc = docs[0];\n      if (doc.isFoundDocument()) {\n        return new DocumentSnapshot<AppModelType, DbModelType>(\n          this._firestore,\n          userDataWriter,\n          doc.key,\n          doc,\n          ref.converter\n        );\n      } else if (doc.isNoDocument()) {\n        return new DocumentSnapshot<AppModelType, DbModelType>(\n          this._firestore,\n          userDataWriter,\n          ref._key,\n          null,\n          ref.converter\n        );\n      } else {\n        throw fail(\n          0x4801,\n          'BatchGetDocumentsRequest returned unexpected document',\n          {\n            doc\n          }\n        );\n      }\n    });\n  }\n\n  /**\n   * Writes to the document referred to by the provided {@link\n   * DocumentReference}. If the document does not exist yet, it will be created.\n   *\n   * @param documentRef - A reference to the document to be set.\n   * @param data - An object of the fields and values for the document.\n   * @throws Error - If the provided input is not a valid Firestore document.\n   * @returns This `Transaction` instance. Used for chaining method calls.\n   */\n  set<AppModelType, DbModelType extends DocumentData>(\n    documentRef: DocumentReference<AppModelType, DbModelType>,\n    data: WithFieldValue<AppModelType>\n  ): this;\n  /**\n   * Writes to the document referred to by the provided {@link\n   * DocumentReference}. If the document does not exist yet, it will be created.\n   * If you provide `merge` or `mergeFields`, the provided data can be merged\n   * into an existing document.\n   *\n   * @param documentRef - A reference to the document to be set.\n   * @param data - An object of the fields and values for the document.\n   * @param options - An object to configure the set behavior.\n   * @throws Error - If the provided input is not a valid Firestore document.\n   * @returns This `Transaction` instance. Used for chaining method calls.\n   */\n  set<AppModelType, DbModelType extends DocumentData>(\n    documentRef: DocumentReference<AppModelType, DbModelType>,\n    data: PartialWithFieldValue<AppModelType>,\n    options: SetOptions\n  ): this;\n  set<AppModelType, DbModelType extends DocumentData>(\n    documentRef: DocumentReference<AppModelType, DbModelType>,\n    value: PartialWithFieldValue<AppModelType>,\n    options?: SetOptions\n  ): this {\n    const ref = validateReference(documentRef, this._firestore);\n    const convertedValue = applyFirestoreDataConverter(\n      ref.converter,\n      value,\n      options\n    );\n    const parsed = parseSetData(\n      this._dataReader,\n      'Transaction.set',\n      ref._key,\n      convertedValue,\n      ref.converter !== null,\n      options\n    );\n    this._transaction.set(ref._key, parsed);\n    return this;\n  }\n\n  /**\n   * Updates fields in the document referred to by the provided {@link\n   * DocumentReference}. The update will fail if applied to a document that does\n   * not exist.\n   *\n   * @param documentRef - A reference to the document to be updated.\n   * @param data - An object containing the fields and values with which to\n   * update the document. Fields can contain dots to reference nested fields\n   * within the document.\n   * @throws Error - If the provided input is not valid Firestore data.\n   * @returns This `Transaction` instance. Used for chaining method calls.\n   */\n  update<AppModelType, DbModelType extends DocumentData>(\n    documentRef: DocumentReference<AppModelType, DbModelType>,\n    data: UpdateData<DbModelType>\n  ): this;\n  /**\n   * Updates fields in the document referred to by the provided {@link\n   * DocumentReference}. The update will fail if applied to a document that does\n   * not exist.\n   *\n   * Nested fields can be updated by providing dot-separated field path\n   * strings or by providing `FieldPath` objects.\n   *\n   * @param documentRef - A reference to the document to be updated.\n   * @param field - The first field to update.\n   * @param value - The first value.\n   * @param moreFieldsAndValues - Additional key/value pairs.\n   * @throws Error - If the provided input is not valid Firestore data.\n   * @returns This `Transaction` instance. Used for chaining method calls.\n   */\n  update<AppModelType, DbModelType extends DocumentData>(\n    documentRef: DocumentReference<AppModelType, DbModelType>,\n    field: string | FieldPath,\n    value: unknown,\n    ...moreFieldsAndValues: unknown[]\n  ): this;\n  update<AppModelType, DbModelType extends DocumentData>(\n    documentRef: DocumentReference<AppModelType, DbModelType>,\n    fieldOrUpdateData: string | FieldPath | UpdateData<DbModelType>,\n    value?: unknown,\n    ...moreFieldsAndValues: unknown[]\n  ): this {\n    const ref = validateReference(documentRef, this._firestore);\n\n    // For Compat types, we have to \"extract\" the underlying types before\n    // performing validation.\n    fieldOrUpdateData = getModularInstance(fieldOrUpdateData);\n\n    let parsed;\n    if (\n      typeof fieldOrUpdateData === 'string' ||\n      fieldOrUpdateData instanceof FieldPath\n    ) {\n      parsed = parseUpdateVarargs(\n        this._dataReader,\n        'Transaction.update',\n        ref._key,\n        fieldOrUpdateData,\n        value,\n        moreFieldsAndValues\n      );\n    } else {\n      parsed = parseUpdateData(\n        this._dataReader,\n        'Transaction.update',\n        ref._key,\n        fieldOrUpdateData\n      );\n    }\n\n    this._transaction.update(ref._key, parsed);\n    return this;\n  }\n\n  /**\n   * Deletes the document referred to by the provided {@link DocumentReference}.\n   *\n   * @param documentRef - A reference to the document to be deleted.\n   * @returns This `Transaction` instance. Used for chaining method calls.\n   */\n  delete<AppModelType, DbModelType extends DocumentData>(\n    documentRef: DocumentReference<AppModelType, DbModelType>\n  ): this {\n    const ref = validateReference(documentRef, this._firestore);\n    this._transaction.delete(ref._key);\n    return this;\n  }\n}\n\n/**\n * Executes the given `updateFunction` and then attempts to commit the changes\n * applied within the transaction. If any document read within the transaction\n * has changed, Cloud Firestore retries the `updateFunction`. If it fails to\n * commit after 5 attempts, the transaction fails.\n *\n * The maximum number of writes allowed in a single transaction is 500.\n *\n * @param firestore - A reference to the Firestore database to run this\n * transaction against.\n * @param updateFunction - The function to execute within the transaction\n * context.\n * @param options - An options object to configure maximum number of attempts to\n * commit.\n * @returns If the transaction completed successfully or was explicitly aborted\n * (the `updateFunction` returned a failed promise), the promise returned by the\n * `updateFunction `is returned here. Otherwise, if the transaction failed, a\n * rejected promise with the corresponding failure error is returned.\n */\nexport function runTransaction<T>(\n  firestore: Firestore,\n  updateFunction: (transaction: Transaction) => Promise<T>,\n  options?: TransactionOptions\n): Promise<T> {\n  firestore = cast(firestore, Firestore);\n  const datastore = getDatastore(firestore);\n  const optionsWithDefaults: TransactionOptionsInternal = {\n    ...DEFAULT_TRANSACTION_OPTIONS,\n    ...options\n  };\n  validateTransactionOptions(optionsWithDefaults);\n  const deferred = new Deferred<T>();\n  new TransactionRunner<T>(\n    newAsyncQueue(),\n    datastore,\n    optionsWithDefaults,\n    internalTransaction =>\n      updateFunction(new Transaction(firestore, internalTransaction)),\n    deferred\n  ).run();\n  return deferred.promise;\n}\n","/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n  _registerComponent,\n  registerVersion,\n  SDK_VERSION\n} from '@firebase/app';\nimport { Component, ComponentType } from '@firebase/component';\n\nimport { version } from '../package.json';\nimport {\n  LiteAppCheckTokenProvider,\n  LiteAuthCredentialsProvider\n} from '../src/api/credentials';\nimport { databaseIdFromApp } from '../src/core/database_info';\nimport { setSDKVersion } from '../src/core/version';\nimport { Firestore } from '../src/lite-api/database';\n\ndeclare module '@firebase/component' {\n  interface NameServiceMapping {\n    'firestore/lite': Firestore;\n  }\n}\n\nexport function registerFirestore(): void {\n  setSDKVersion(`${SDK_VERSION}_lite`);\n  _registerComponent(\n    new Component(\n      'firestore/lite',\n      (container, { instanceIdentifier: databaseId, options: settings }) => {\n        const app = container.getProvider('app').getImmediate()!;\n        const firestoreInstance = new Firestore(\n          new LiteAuthCredentialsProvider(\n            container.getProvider('auth-internal')\n          ),\n          new LiteAppCheckTokenProvider(\n            app,\n            container.getProvider('app-check-internal')\n          ),\n          databaseIdFromApp(app, databaseId),\n          app\n        );\n        if (settings) {\n          firestoreInstance._setSettings(settings);\n        }\n        return firestoreInstance;\n      },\n      'PUBLIC' as ComponentType.PUBLIC\n    ).setMultipleInstances(true)\n  );\n  // RUNTIME_ENV and BUILD_TARGET are replaced by real values during the compilation\n  registerVersion('firestore-lite', version, '__RUNTIME_ENV__');\n  registerVersion('firestore-lite', version, '__BUILD_TARGET__');\n}\n","/**\n * Firestore Lite\n *\n * @remarks Firestore Lite is a small online-only SDK that allows read\n * and write access to your Firestore database. All operations connect\n * directly to the backend, and `onSnapshot()` APIs are not supported.\n * @packageDocumentation\n */\n\n/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { registerFirestore } from './register';\nregisterFirestore();\n\nexport {\n  aggregateQuerySnapshotEqual,\n  getCount,\n  getAggregate,\n  count,\n  sum,\n  average,\n  aggregateFieldEqual\n} from '../src/lite-api/aggregate';\n\nexport {\n  AggregateField,\n  AggregateFieldType,\n  AggregateSpec,\n  AggregateSpecData,\n  AggregateQuerySnapshot,\n  AggregateType\n} from '../src/lite-api/aggregate_types';\n\nexport { FirestoreSettings as Settings } from '../src/lite-api/settings';\n\nexport {\n  Firestore as Firestore,\n  EmulatorMockTokenOptions,\n  initializeFirestore,\n  getFirestore,\n  terminate,\n  connectFirestoreEmulator\n} from '../src/lite-api/database';\n\nexport {\n  DocumentData,\n  UpdateData,\n  WithFieldValue,\n  PartialWithFieldValue,\n  SetOptions,\n  DocumentReference,\n  Query,\n  CollectionReference,\n  collection,\n  collectionGroup,\n  doc,\n  refEqual,\n  queryEqual\n} from '../src/lite-api/reference';\n\nexport {\n  and,\n  endAt,\n  endBefore,\n  startAt,\n  startAfter,\n  limit,\n  limitToLast,\n  where,\n  or,\n  orderBy,\n  query,\n  QueryConstraint,\n  QueryConstraintType,\n  QueryCompositeFilterConstraint,\n  QueryFilterConstraint,\n  QueryFieldFilterConstraint,\n  QueryOrderByConstraint,\n  QueryLimitConstraint,\n  QueryNonFilterConstraint,\n  QueryStartAtConstraint,\n  QueryEndAtConstraint,\n  OrderByDirection,\n  WhereFilterOp\n} from '../src/lite-api/query';\n\nexport {\n  addDoc,\n  deleteDoc,\n  updateDoc,\n  setDoc,\n  getDoc,\n  getDocs\n} from '../src/lite-api/reference_impl';\n\nexport {\n  Primitive,\n  NestedUpdateFields,\n  ChildUpdateFields,\n  AddPrefixToKeys,\n  UnionToIntersection\n} from '../src/lite-api/types';\n\n// TODO(firestorelite): Add tests when Queries are usable\nexport { FieldPath, documentId } from '../src/lite-api/field_path';\n\n// TODO(firestorelite): Add tests when setDoc() is available\nexport { FieldValue } from '../src/lite-api/field_value';\n\nexport {\n  increment,\n  arrayRemove,\n  arrayUnion,\n  serverTimestamp,\n  deleteField,\n  vector\n} from '../src/lite-api/field_value_impl';\n\nexport {\n  FirestoreDataConverter,\n  DocumentSnapshot,\n  QueryDocumentSnapshot,\n  QuerySnapshot,\n  snapshotEqual\n} from '../src/lite-api/snapshot';\n\nexport { VectorValue } from '../src/lite-api/vector_value';\n\nexport { WriteBatch, writeBatch } from '../src/lite-api/write_batch';\n\nexport { TransactionOptions } from '../src/lite-api/transaction_options';\n\nexport { Transaction, runTransaction } from '../src/lite-api/transaction';\n\nexport { setLogLevel, LogLevelString as LogLevel } from '../src/util/log';\n\nexport { Bytes } from '../src/lite-api/bytes';\n\nexport { GeoPoint } from '../src/lite-api/geo_point';\n\nexport { Timestamp } from '../src/lite-api/timestamp';\n\nexport { FirestoreErrorCode, FirestoreError } from '../src/util/error';\n"],"names":["__PRIVATE_Deferred","constructor","this","promise","Promise","resolve","reject","__PRIVATE_AggregateImpl","alias","aggregateType","fieldPath","__PRIVATE_ExponentialBackoff","__PRIVATE_queue","timerId","__PRIVATE_initialDelayMs","__PRIVATE_backoffFactor","__PRIVATE_maxDelayMs","__PRIVATE_currentBaseMs","__PRIVATE_timerPromise","Date","now","reset","__PRIVATE_resetToMax","__PRIVATE_backoffAndRun","op","cancel","__PRIVATE_desiredDelayWithJitterMs","Math","floor","__PRIVATE_jitterDelayMs","__PRIVATE_delaySoFarMs","max","__PRIVATE_lastAttemptTime","__PRIVATE_remainingDelayMs","__PRIVATE_logDebug","enqueueAfterDelay","__PRIVATE_skipBackoff","skipDelay","random","AggregateField","_internalFieldPath","type","AggregateQuerySnapshot","query","_userDataWriter","_data","data","convertObjectMap","_fieldsProto","ObjectValue","mapValue","fields","clone","value","getCount","getAggregate","count","aggregateSpec","firestore","__PRIVATE_cast","Firestore","datastore","__PRIVATE_getDatastore","__PRIVATE_internalAggregates","__PRIVATE_mapToArray","aggregate","__PRIVATE_invokeRunAggregationQueryRpc","_query","then","__PRIVATE_aggregateResult","__PRIVATE_convertToAggregateQuerySnapshot","userDataWriter","__PRIVATE_LiteUserDataWriter","__PRIVATE_querySnapshot","sum","field","__PRIVATE_fieldPathFromArgument","average","aggregateFieldEqual","left","right","canonicalString","aggregateQuerySnapshotEqual","queryEqual","deepEqual","WriteBatch","_firestore","_commitHandler","_mutations","_committed","_dataReader","__PRIVATE_newUserDataReader","set","documentRef","options","_verifyNotCommitted","ref","__PRIVATE_validateReference","__PRIVATE_convertedValue","__PRIVATE_applyFirestoreDataConverter","converter","__PRIVATE_parsed","__PRIVATE_parseSetData","_key","push","toMutation","Precondition","none","update","__PRIVATE_fieldOrUpdateData","moreFieldsAndValues","getModularInstance","FieldPath","__PRIVATE_parseUpdateVarargs","__PRIVATE_parseUpdateData","exists","concat","__PRIVATE_DeleteMutation","commit","length","FirestoreError","Code","FAILED_PRECONDITION","INVALID_ARGUMENT","writeBatch","writes","__PRIVATE_invokeCommitRpc","Transaction","readVersions","Map","mutations","committed","lastTransactionError","writtenDocs","Set","lookup","keys","ensureCommitNotCalled","docs","__PRIVATE_invokeBatchGetDocumentsRpc","forEach","doc","recordVersion","key","write","precondition","add","toString","preconditionForUpdate","e","__PRIVATE_unwritten","mutation","delete","_","path","DocumentKey","fromPath","__PRIVATE_VerifyMutation","__PRIVATE_docVersion","isFoundDocument","version","isNoDocument","fail","__PRIVATE_documentName","name","SnapshotVersion","min","__PRIVATE_existingVersion","get","isEqual","ABORTED","has","updateTime","__PRIVATE_DEFAULT_TRANSACTION_OPTIONS","maxAttempts","__PRIVATE_TransactionRunner","asyncQueue","updateFunction","deferred","__PRIVATE_attemptsRemaining","__PRIVATE_backoff","__PRIVATE_run","__PRIVATE_runWithBackOff","async","transaction","__PRIVATE_userPromise","__PRIVATE_tryRunUpdateFunction","result","enqueueAndForget","catch","__PRIVATE_commitError","__PRIVATE_handleTransactionError","__PRIVATE_userPromiseError","__PRIVATE_isNullOrUndefined","Error","error","__PRIVATE_isRetryableTransactionError","code","__PRIVATE_isPermanentError","getDocument","document","DelayedOperation","targetTimeMs","removalCallback","bind","err","createAndSchedule","delayMs","__PRIVATE_targetTime","__PRIVATE_delayedOp","start","timerHandle","setTimeout","handleDelayElapsed","reason","clearTimeout","CANCELLED","__PRIVATE_LOG_TAG","__PRIVATE_AsyncQueueImpl","__PRIVATE_tail","__PRIVATE_retryableOps","__PRIVATE__isShuttingDown","__PRIVATE_delayedOperations","__PRIVATE_failure","__PRIVATE_operationInProgress","__PRIVATE_skipNonRestrictedTasks","__PRIVATE_timerIdsToSkip","__PRIVATE_visibilityHandler","visibilityState","addEventListener","isShuttingDown","enqueue","enqueueAndForgetEvenWhileRestricted","__PRIVATE_verifyNotFailed","__PRIVATE_enqueueInternal","enterRestrictedMode","purgeExistingTasks","removeEventListener","task","enqueueRetryable","__PRIVATE_retryNextOp","shift","__PRIVATE_isIndexedDbTransactionError","__PRIVATE_newTail","message","__PRIVATE_getMessageOrStack","__PRIVATE_logError","indexOf","__PRIVATE_removedOp","__PRIVATE_removeDelayedOperation","__PRIVATE_messageOrStack","verifyOperationInProgress","__PRIVATE_drain","__PRIVATE_currentTail","__PRIVATE_containsDelayedOperation","__PRIVATE_runAllDelayedOperationsUntil","__PRIVATE_lastTimerId","sort","a","b","__PRIVATE_skipDelaysForTimerId","index","splice","stack","includes","_transaction","DocumentSnapshot","runTransaction","__PRIVATE_optionsWithDefaults","__PRIVATE_validateTransactionOptions","__PRIVATE_newAsyncQueue","__PRIVATE_internalTransaction","__PRIVATE_registerFirestore","__PRIVATE_setSDKVersion","SDK_VERSION","_registerComponent","Component","container","instanceIdentifier","databaseId","settings","app","getProvider","getImmediate","__PRIVATE_firestoreInstance","__PRIVATE_LiteAuthCredentialsProvider","__PRIVATE_LiteAppCheckTokenProvider","__PRIVATE_databaseIdFromApp","_setSettings","setMultipleInstances","registerVersion"],"mappings":"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"}