1 line
1.5 MiB
1 line
1.5 MiB
{"version":3,"file":"index.node.esm2017.js","sources":["../src/core/version.ts","../src/platform/platform.ts","../src/util/log.ts","../src/util/assert.ts","../src/util/misc.ts","../src/core/database_info.ts","../src/auth/user.ts","../src/core/listen_sequence.ts","../src/util/sorted_map.ts","../src/util/sorted_set.ts","../src/util/error.ts","../src/model/path.ts","../src/model/document_key.ts","../src/model/collections.ts","../src/util/types.ts","../src/local/shared_client_state_schema.ts","../src/local/shared_client_state.ts","../src/api/timestamp.ts","../src/core/snapshot_version.ts","../src/util/obj.ts","../src/util/byte_string.ts","../src/model/server_timestamps.ts","../src/model/values.ts","../src/model/document.ts","../src/model/object_value.ts","../src/model/mutation.ts","../src/model/mutation_batch.ts","../src/util/obj_map.ts","../src/local/persistence_promise.ts","../src/local/local_documents_view.ts","../src/local/persistence.ts","../src/local/target_data.ts","../src/util/promise.ts","../src/local/encoded_resource_path.ts","../src/local/memory_index_manager.ts","../src/local/indexeddb_index_manager.ts","../src/local/remote_document_change_buffer.ts","../src/local/indexeddb_remote_document_cache.ts","../src/core/target_id_generator.ts","../src/local/indexeddb_target_cache.ts","../src/local/local_serializer.ts","../src/local/lru_garbage_collector.ts","../src/local/indexeddb_persistence.ts","../src/local/indexeddb_mutation_queue.ts","../src/local/indexeddb_schema.ts","../src/local/simple_db.ts","../src/local/local_store.ts","../src/local/local_view_changes.ts","../src/local/reference_set.ts","../src/remote/remote_event.ts","../src/core/target.ts","../src/core/query.ts","../src/model/document_set.ts","../src/core/view_snapshot.ts","../src/core/view.ts","../src/remote/backoff.ts","../src/util/async_queue.ts","../src/remote/rpc_error.ts","../src/core/transaction_runner.ts","../src/core/sync_engine.ts","../src/remote/persistent_stream.ts","../src/remote/datastore.ts","../src/core/transaction.ts","../src/remote/online_state_tracker.ts","../src/remote/watch_change.ts","../src/remote/remote_store.ts","../src/core/event_manager.ts","../src/local/index_free_query_engine.ts","../src/local/memory_mutation_queue.ts","../src/local/memory_remote_document_cache.ts","../src/local/memory_target_cache.ts","../src/local/memory_persistence.ts","../src/core/component_provider.ts","../src/core/firestore_client.ts","../src/util/async_observer.ts","../src/util/input_validation.ts","../src/api/field_path.ts","../src/api/credentials.ts","../src/api/observer.ts","../src/api/blob.ts","../src/model/transform_operation.ts","../src/api/field_value.ts","../src/api/geo_point.ts","../src/api/user_data_reader.ts","../src/remote/existence_filter.ts","../src/remote/serializer.ts","../src/api/user_data_writer.ts","../src/api/database.ts","../src/util/api.ts","../src/platform/config.ts","../src/remote/connectivity_monitor_noop.ts","../src/remote/stream_bridge.ts","../src/util/node_api.ts","../src/platform_node/grpc_connection.ts","../src/platform_node/load_protos.ts","../src/platform_node/node_platform.ts","../src/platform_node/node_init.ts","../index.node.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\nimport firebase from '@firebase/app';\n\n/** The semver (www.semver.org) version of the SDK. */\nexport const SDK_VERSION = firebase.SDK_VERSION;\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 { DatabaseId, DatabaseInfo } from '../core/database_info';\nimport { Connection } from '../remote/connection';\nimport { JsonProtoSerializer } from '../remote/serializer';\nimport { fail } from '../util/assert';\nimport { ConnectivityMonitor } from './../remote/connectivity_monitor';\n\n/**\n * Provides a common interface to load anything platform dependent, e.g.\n * the connection implementation.\n *\n * An implementation of this must be provided at compile time for the platform.\n */\n// TODO: Consider only exposing the APIs of 'document' and 'window' that we\n// use in our client.\nexport interface Platform {\n loadConnection(databaseInfo: DatabaseInfo): Promise<Connection>;\n newConnectivityMonitor(): ConnectivityMonitor;\n newSerializer(databaseId: DatabaseId): JsonProtoSerializer;\n\n /** Formats an object as a JSON string, suitable for logging. */\n formatJSON(value: unknown): string;\n\n /** Converts a Base64 encoded string to a binary string. */\n atob(encoded: string): string;\n\n /** Converts a binary string to a Base64 encoded string. */\n btoa(raw: string): string;\n\n /**\n * Generates `nBytes` of random bytes.\n *\n * If `nBytes < 0` , an error will be thrown.\n */\n randomBytes(nBytes: number): Uint8Array;\n\n /** The Platform's 'window' implementation or null if not available. */\n readonly window: Window | null;\n\n /** The Platform's 'document' implementation or null if not available. */\n readonly document: Document | null;\n\n /** True if and only if the Base64 conversion functions are available. */\n readonly base64Available: boolean;\n}\n\n/**\n * Provides singleton helpers where setup code can inject a platform at runtime.\n * setPlatform needs to be set before Firestore is used and must be set exactly\n * once.\n */\nexport class PlatformSupport {\n private static platform: Platform;\n static setPlatform(platform: Platform): void {\n if (PlatformSupport.platform) {\n fail('Platform already defined');\n }\n PlatformSupport.platform = platform;\n }\n\n static getPlatform(): Platform {\n if (!PlatformSupport.platform) {\n fail('Platform not set');\n }\n return PlatformSupport.platform;\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 { Logger, LogLevel } from '@firebase/logger';\nimport { SDK_VERSION } from '../core/version';\nimport { PlatformSupport } from '../platform/platform';\n\nexport { LogLevel };\n\nconst logClient = new Logger('@firebase/firestore');\n\n// Helper methods are needed because variables can't be exported as read/write\nexport function getLogLevel(): LogLevel {\n return logClient.logLevel;\n}\n\nexport function setLogLevel(newLevel: LogLevel): void {\n logClient.logLevel = newLevel;\n}\n\nexport function logDebug(msg: string, ...obj: unknown[]): void {\n if (logClient.logLevel <= LogLevel.DEBUG) {\n const args = obj.map(argToString);\n logClient.debug(`Firestore (${SDK_VERSION}): ${msg}`, ...args);\n }\n}\n\nexport function logError(msg: string, ...obj: unknown[]): void {\n if (logClient.logLevel <= LogLevel.ERROR) {\n const args = obj.map(argToString);\n logClient.error(`Firestore (${SDK_VERSION}): ${msg}`, ...args);\n }\n}\n\n/**\n * Converts an additional log parameter to a string representation.\n */\nfunction argToString(obj: unknown): string | unknown {\n if (typeof obj === 'string') {\n return obj;\n } else {\n const platform = PlatformSupport.getPlatform();\n try {\n return platform.formatJSON(obj);\n } catch (e) {\n // Converting to JSON failed, just log the object directly\n return obj;\n }\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 { SDK_VERSION } from '../core/version';\nimport { logError } from './log';\n\n/**\n * Unconditionally fails, throwing an Error with the given message.\n * Messages are stripped in production builds.\n *\n * Returns `never` and can be used in expressions:\n * @example\n * let futureVar = fail('not implemented yet');\n */\nexport function fail(failure: string = 'Unexpected state'): never {\n // Log the failure in addition to throw an exception, just in case the\n // exception is swallowed.\n const message =\n `FIRESTORE (${SDK_VERSION}) INTERNAL ASSERTION FAILED: ` + failure;\n logError(message);\n\n // NOTE: We don't use FirestoreError here because these are internal failures\n // that cannot be handled by the user. (Also it would create a circular\n // dependency between the error and assert modules which doesn't work.)\n throw new Error(message);\n}\n\n/**\n * Fails if the given assertion condition is false, throwing an Error with the\n * given message if it did.\n *\n * Messages are stripped in production builds.\n */\nexport function hardAssert(\n assertion: boolean,\n message?: string\n): asserts assertion {\n if (!assertion) {\n fail(message);\n }\n}\n\n/**\n * Fails if the given assertion condition is false, throwing an Error with the\n * given message if it did.\n *\n * The code of callsites invoking this function are stripped out in production\n * builds. Any side-effects of code within the debugAssert() invocation will not\n * happen in this case.\n */\nexport function debugAssert(\n assertion: boolean,\n message: string\n): asserts assertion {\n if (!assertion) {\n fail(message);\n }\n}\n\n/**\n * Casts `obj` to `T`. In non-production builds, verifies that `obj` is an\n * instance of `T` before casting.\n */\nexport function debugCast<T>(\n obj: object,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n constructor: { new (...args: any[]): T }\n): T {\n debugAssert(\n obj instanceof constructor,\n `Expected type '${constructor.name}', but was '${obj.constructor.name}'`\n );\n return obj as T;\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 { debugAssert } from './assert';\nimport { PlatformSupport } from '../platform/platform';\n\nexport type EventHandler<E> = (value: E) => void;\nexport interface Indexable {\n [k: string]: unknown;\n}\n\nexport class AutoId {\n static newId(): string {\n // Alphanumeric characters\n const chars =\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n // The largest byte value that is a multiple of `char.length`.\n const maxMultiple = Math.floor(256 / chars.length) * chars.length;\n debugAssert(\n 0 < maxMultiple && maxMultiple < 256,\n `Expect maxMultiple to be (0, 256), but got ${maxMultiple}`\n );\n\n let autoId = '';\n const targetLength = 20;\n while (autoId.length < targetLength) {\n const bytes = PlatformSupport.getPlatform().randomBytes(40);\n for (let i = 0; i < bytes.length; ++i) {\n // Only accept values that are [0, maxMultiple), this ensures they can\n // be evenly mapped to indices of `chars` via a modulo operation.\n if (autoId.length < targetLength && bytes[i] < maxMultiple) {\n autoId += chars.charAt(bytes[i] % chars.length);\n }\n }\n }\n debugAssert(autoId.length === targetLength, 'Invalid auto ID: ' + autoId);\n\n return autoId;\n }\n}\n\nexport function primitiveComparator<T>(left: T, right: T): number {\n if (left < right) {\n return -1;\n }\n if (left > right) {\n return 1;\n }\n return 0;\n}\n\nexport interface Equatable<T> {\n isEqual(other: T): boolean;\n}\n\n/** Helper to compare arrays using isEqual(). */\nexport function arrayEquals<T>(\n left: T[],\n right: T[],\n comparator: (l: T, r: T) => boolean\n): boolean {\n if (left.length !== right.length) {\n return false;\n }\n return left.every((value, index) => comparator(value, right[index]));\n}\n/**\n * Returns the immediate lexicographically-following string. This is useful to\n * construct an inclusive range for indexeddb iterators.\n */\nexport function immediateSuccessor(s: string): string {\n // Return the input string, with an additional NUL byte appended.\n return s + '\\0';\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 { primitiveComparator } from '../util/misc';\n\nexport class DatabaseInfo {\n /**\n * Constructs a DatabaseInfo using the provided host, databaseId and\n * persistenceKey.\n *\n * @param databaseId The database to use.\n * @param persistenceKey A unique identifier for this Firestore's local\n * storage (used in conjunction with the databaseId).\n * @param host The Firestore backend host to connect to.\n * @param ssl Whether to use SSL when connecting.\n * @param forceLongPolling Whether to use the forceLongPolling option\n * when using WebChannel as the network transport.\n */\n constructor(\n readonly databaseId: DatabaseId,\n readonly persistenceKey: string,\n readonly host: string,\n readonly ssl: boolean,\n readonly forceLongPolling: boolean\n ) {}\n}\n\n/** The default database name for a project. */\nconst DEFAULT_DATABASE_NAME = '(default)';\n\n/** Represents the database ID a Firestore client is associated with. */\nexport class DatabaseId {\n readonly database: string;\n constructor(readonly projectId: string, database?: string) {\n this.database = database ? database : DEFAULT_DATABASE_NAME;\n }\n\n get isDefaultDatabase(): boolean {\n return this.database === DEFAULT_DATABASE_NAME;\n }\n\n isEqual(other: {}): boolean {\n return (\n other instanceof DatabaseId &&\n other.projectId === this.projectId &&\n other.database === this.database\n );\n }\n\n compareTo(other: DatabaseId): number {\n return (\n primitiveComparator(this.projectId, other.projectId) ||\n primitiveComparator(this.database, other.database)\n );\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\n/**\n * Simple wrapper around a nullable UID. Mostly exists to make code more\n * readable.\n */\nexport class User {\n /** A user with a null UID. */\n static readonly UNAUTHENTICATED = new User(null);\n\n // TODO(mikelehen): Look into getting a proper uid-equivalent for\n // non-FirebaseAuth providers.\n static readonly GOOGLE_CREDENTIALS = new User('google-credentials-uid');\n static readonly FIRST_PARTY = new User('first-party-uid');\n\n constructor(readonly uid: string | null) {}\n\n isAuthenticated(): boolean {\n return this.uid != null;\n }\n\n /**\n * Returns a key representing this user, suitable for inclusion in a\n * dictionary.\n */\n toKey(): string {\n if (this.isAuthenticated()) {\n return 'uid:' + this.uid;\n } else {\n return 'anonymous-user';\n }\n }\n\n isEqual(otherUser: User): boolean {\n return otherUser.uid === this.uid;\n }\n}\n","/**\n * @license\n * Copyright 2018 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 { ListenSequenceNumber } from './types';\n\n/**\n * `SequenceNumberSyncer` defines the methods required to keep multiple instances of a\n * `ListenSequence` in sync.\n */\nexport interface SequenceNumberSyncer {\n // Notify the syncer that a new sequence number has been used.\n writeSequenceNumber(sequenceNumber: ListenSequenceNumber): void;\n // Setting this property allows the syncer to notify when a sequence number has been used, and\n // and lets the ListenSequence adjust its internal previous value accordingly.\n sequenceNumberHandler:\n | ((sequenceNumber: ListenSequenceNumber) => void)\n | null;\n}\n\n/**\n * `ListenSequence` is a monotonic sequence. It is initialized with a minimum value to\n * exceed. All subsequent calls to next will return increasing values. If provided with a\n * `SequenceNumberSyncer`, it will additionally bump its next value when told of a new value, as\n * well as write out sequence numbers that it produces via `next()`.\n */\nexport class ListenSequence {\n static readonly INVALID: ListenSequenceNumber = -1;\n\n private writeNewSequenceNumber?: (\n newSequenceNumber: ListenSequenceNumber\n ) => void;\n\n constructor(\n private previousValue: ListenSequenceNumber,\n sequenceNumberSyncer?: SequenceNumberSyncer\n ) {\n if (sequenceNumberSyncer) {\n sequenceNumberSyncer.sequenceNumberHandler = sequenceNumber =>\n this.setPreviousValue(sequenceNumber);\n this.writeNewSequenceNumber = sequenceNumber =>\n sequenceNumberSyncer.writeSequenceNumber(sequenceNumber);\n }\n }\n\n private setPreviousValue(\n externalPreviousValue: ListenSequenceNumber\n ): ListenSequenceNumber {\n this.previousValue = Math.max(externalPreviousValue, this.previousValue);\n return this.previousValue;\n }\n\n next(): ListenSequenceNumber {\n const nextValue = ++this.previousValue;\n if (this.writeNewSequenceNumber) {\n this.writeNewSequenceNumber(nextValue);\n }\n return nextValue;\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 { debugAssert, fail } from './assert';\n\n/*\n * Implementation of an immutable SortedMap using a Left-leaning\n * Red-Black Tree, adapted from the implementation in Mugs\n * (http://mads379.github.com/mugs/) by Mads Hartmann Jensen\n * (mads379@gmail.com).\n *\n * Original paper on Left-leaning Red-Black Trees:\n * http://www.cs.princeton.edu/~rs/talks/LLRB/LLRB.pdf\n *\n * Invariant 1: No red node has a red child\n * Invariant 2: Every leaf path has the same number of black nodes\n * Invariant 3: Only the left child can be red (left leaning)\n */\n\nexport type Comparator<K> = (key1: K, key2: K) => number;\n\nexport interface Entry<K, V> {\n key: K;\n value: V;\n}\n\n// An immutable sorted map implementation, based on a Left-leaning Red-Black\n// tree.\nexport class SortedMap<K, V> {\n // visible for testing\n root: LLRBNode<K, V> | LLRBEmptyNode<K, V>;\n\n constructor(\n public comparator: Comparator<K>,\n root?: LLRBNode<K, V> | LLRBEmptyNode<K, V>\n ) {\n this.root = root ? root : LLRBNode.EMPTY;\n }\n\n // Returns a copy of the map, with the specified key/value added or replaced.\n insert(key: K, value: V): SortedMap<K, V> {\n return new SortedMap<K, V>(\n this.comparator,\n this.root\n .insert(key, value, this.comparator)\n .copy(null, null, LLRBNode.BLACK, null, null)\n );\n }\n\n // Returns a copy of the map, with the specified key removed.\n remove(key: K): SortedMap<K, V> {\n return new SortedMap<K, V>(\n this.comparator,\n this.root\n .remove(key, this.comparator)\n .copy(null, null, LLRBNode.BLACK, null, null)\n );\n }\n\n // Returns the value of the node with the given key, or null.\n get(key: K): V | null {\n let node = this.root;\n while (!node.isEmpty()) {\n const cmp = this.comparator(key, node.key);\n if (cmp === 0) {\n return node.value;\n } else if (cmp < 0) {\n node = node.left;\n } else if (cmp > 0) {\n node = node.right;\n }\n }\n return null;\n }\n\n // Returns the index of the element in this sorted map, or -1 if it doesn't\n // exist.\n indexOf(key: K): number {\n // Number of nodes that were pruned when descending right\n let prunedNodes = 0;\n let node = this.root;\n while (!node.isEmpty()) {\n const cmp = this.comparator(key, node.key);\n if (cmp === 0) {\n return prunedNodes + node.left.size;\n } else if (cmp < 0) {\n node = node.left;\n } else {\n // Count all nodes left of the node plus the node itself\n prunedNodes += node.left.size + 1;\n node = node.right;\n }\n }\n // Node not found\n return -1;\n }\n\n isEmpty(): boolean {\n return this.root.isEmpty();\n }\n\n // Returns the total number of nodes in the map.\n get size(): number {\n return this.root.size;\n }\n\n // Returns the minimum key in the map.\n minKey(): K | null {\n return this.root.minKey();\n }\n\n // Returns the maximum key in the map.\n maxKey(): K | null {\n return this.root.maxKey();\n }\n\n // Traverses the map in key order and calls the specified action function\n // for each key/value pair. If action returns true, traversal is aborted.\n // Returns the first truthy value returned by action, or the last falsey\n // value returned by action.\n inorderTraversal<T>(action: (k: K, v: V) => T): T {\n return (this.root as LLRBNode<K, V>).inorderTraversal(action);\n }\n\n forEach(fn: (k: K, v: V) => void): void {\n this.inorderTraversal((k, v) => {\n fn(k, v);\n return false;\n });\n }\n\n toString(): string {\n const descriptions: string[] = [];\n this.inorderTraversal((k, v) => {\n descriptions.push(`${k}:${v}`);\n return false;\n });\n return `{${descriptions.join(', ')}}`;\n }\n\n // Traverses the map in reverse key order and calls the specified action\n // function for each key/value pair. If action returns true, traversal is\n // aborted.\n // Returns the first truthy value returned by action, or the last falsey\n // value returned by action.\n reverseTraversal<T>(action: (k: K, v: V) => T): T {\n return (this.root as LLRBNode<K, V>).reverseTraversal(action);\n }\n\n // Returns an iterator over the SortedMap.\n getIterator(): SortedMapIterator<K, V> {\n return new SortedMapIterator<K, V>(this.root, null, this.comparator, false);\n }\n\n getIteratorFrom(key: K): SortedMapIterator<K, V> {\n return new SortedMapIterator<K, V>(this.root, key, this.comparator, false);\n }\n\n getReverseIterator(): SortedMapIterator<K, V> {\n return new SortedMapIterator<K, V>(this.root, null, this.comparator, true);\n }\n\n getReverseIteratorFrom(key: K): SortedMapIterator<K, V> {\n return new SortedMapIterator<K, V>(this.root, key, this.comparator, true);\n }\n} // end SortedMap\n\n// An iterator over an LLRBNode.\nexport class SortedMapIterator<K, V> {\n private isReverse: boolean;\n private nodeStack: Array<LLRBNode<K, V> | LLRBEmptyNode<K, V>>;\n\n constructor(\n node: LLRBNode<K, V> | LLRBEmptyNode<K, V>,\n startKey: K | null,\n comparator: Comparator<K>,\n isReverse: boolean\n ) {\n this.isReverse = isReverse;\n this.nodeStack = [];\n\n let cmp = 1;\n while (!node.isEmpty()) {\n cmp = startKey ? comparator(node.key, startKey) : 1;\n // flip the comparison if we're going in reverse\n if (isReverse) {\n cmp *= -1;\n }\n\n if (cmp < 0) {\n // This node is less than our start key. ignore it\n if (this.isReverse) {\n node = node.left;\n } else {\n node = node.right;\n }\n } else if (cmp === 0) {\n // This node is exactly equal to our start key. Push it on the stack,\n // but stop iterating;\n this.nodeStack.push(node);\n break;\n } else {\n // This node is greater than our start key, add it to the stack and move\n // to the next one\n this.nodeStack.push(node);\n if (this.isReverse) {\n node = node.right;\n } else {\n node = node.left;\n }\n }\n }\n }\n\n getNext(): Entry<K, V> {\n debugAssert(\n this.nodeStack.length > 0,\n 'getNext() called on iterator when hasNext() is false.'\n );\n\n let node = this.nodeStack.pop()!;\n const result = { key: node.key, value: node.value };\n\n if (this.isReverse) {\n node = node.left;\n while (!node.isEmpty()) {\n this.nodeStack.push(node);\n node = node.right;\n }\n } else {\n node = node.right;\n while (!node.isEmpty()) {\n this.nodeStack.push(node);\n node = node.left;\n }\n }\n\n return result;\n }\n\n hasNext(): boolean {\n return this.nodeStack.length > 0;\n }\n\n peek(): Entry<K, V> | null {\n if (this.nodeStack.length === 0) {\n return null;\n }\n\n const node = this.nodeStack[this.nodeStack.length - 1];\n return { key: node.key, value: node.value };\n }\n} // end SortedMapIterator\n\n// Represents a node in a Left-leaning Red-Black tree.\nexport class LLRBNode<K, V> {\n readonly color: boolean;\n readonly left: LLRBNode<K, V> | LLRBEmptyNode<K, V>;\n readonly right: LLRBNode<K, V> | LLRBEmptyNode<K, V>;\n readonly size: number;\n\n // Empty node is shared between all LLRB trees.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n static EMPTY: LLRBEmptyNode<any, any> = null as any;\n\n static RED = true;\n static BLACK = false;\n\n constructor(\n public key: K,\n public value: V,\n color?: boolean,\n left?: LLRBNode<K, V> | LLRBEmptyNode<K, V>,\n right?: LLRBNode<K, V> | LLRBEmptyNode<K, V>\n ) {\n this.color = color != null ? color : LLRBNode.RED;\n this.left = left != null ? left : LLRBNode.EMPTY;\n this.right = right != null ? right : LLRBNode.EMPTY;\n this.size = this.left.size + 1 + this.right.size;\n }\n\n // Returns a copy of the current node, optionally replacing pieces of it.\n copy(\n key: K | null,\n value: V | null,\n color: boolean | null,\n left: LLRBNode<K, V> | LLRBEmptyNode<K, V> | null,\n right: LLRBNode<K, V> | LLRBEmptyNode<K, V> | null\n ): LLRBNode<K, V> {\n return new LLRBNode<K, V>(\n key != null ? key : this.key,\n value != null ? value : this.value,\n color != null ? color : this.color,\n left != null ? left : this.left,\n right != null ? right : this.right\n );\n }\n\n isEmpty(): boolean {\n return false;\n }\n\n // Traverses the tree in key order and calls the specified action function\n // for each node. If action returns true, traversal is aborted.\n // Returns the first truthy value returned by action, or the last falsey\n // value returned by action.\n inorderTraversal<T>(action: (k: K, v: V) => T): T {\n return (\n (this.left as LLRBNode<K, V>).inorderTraversal(action) ||\n action(this.key, this.value) ||\n (this.right as LLRBNode<K, V>).inorderTraversal(action)\n );\n }\n\n // Traverses the tree in reverse key order and calls the specified action\n // function for each node. If action returns true, traversal is aborted.\n // Returns the first truthy value returned by action, or the last falsey\n // value returned by action.\n reverseTraversal<T>(action: (k: K, v: V) => T): T {\n return (\n (this.right as LLRBNode<K, V>).reverseTraversal(action) ||\n action(this.key, this.value) ||\n (this.left as LLRBNode<K, V>).reverseTraversal(action)\n );\n }\n\n // Returns the minimum node in the tree.\n private min(): LLRBNode<K, V> {\n if (this.left.isEmpty()) {\n return this;\n } else {\n return (this.left as LLRBNode<K, V>).min();\n }\n }\n\n // Returns the maximum key in the tree.\n minKey(): K | null {\n return this.min().key;\n }\n\n // Returns the maximum key in the tree.\n maxKey(): K | null {\n if (this.right.isEmpty()) {\n return this.key;\n } else {\n return this.right.maxKey();\n }\n }\n\n // Returns new tree, with the key/value added.\n insert(key: K, value: V, comparator: Comparator<K>): LLRBNode<K, V> {\n let n: LLRBNode<K, V> = this;\n const cmp = comparator(key, n.key);\n if (cmp < 0) {\n n = n.copy(null, null, null, n.left.insert(key, value, comparator), null);\n } else if (cmp === 0) {\n n = n.copy(null, value, null, null, null);\n } else {\n n = n.copy(\n null,\n null,\n null,\n null,\n n.right.insert(key, value, comparator)\n );\n }\n return n.fixUp();\n }\n\n private removeMin(): LLRBNode<K, V> | LLRBEmptyNode<K, V> {\n if (this.left.isEmpty()) {\n return LLRBNode.EMPTY;\n }\n let n: LLRBNode<K, V> = this;\n if (!n.left.isRed() && !n.left.left.isRed()) {\n n = n.moveRedLeft();\n }\n n = n.copy(null, null, null, (n.left as LLRBNode<K, V>).removeMin(), null);\n return n.fixUp();\n }\n\n // Returns new tree, with the specified item removed.\n remove(\n key: K,\n comparator: Comparator<K>\n ): LLRBNode<K, V> | LLRBEmptyNode<K, V> {\n let smallest: LLRBNode<K, V>;\n let n: LLRBNode<K, V> = this;\n if (comparator(key, n.key) < 0) {\n if (!n.left.isEmpty() && !n.left.isRed() && !n.left.left.isRed()) {\n n = n.moveRedLeft();\n }\n n = n.copy(null, null, null, n.left.remove(key, comparator), null);\n } else {\n if (n.left.isRed()) {\n n = n.rotateRight();\n }\n if (!n.right.isEmpty() && !n.right.isRed() && !n.right.left.isRed()) {\n n = n.moveRedRight();\n }\n if (comparator(key, n.key) === 0) {\n if (n.right.isEmpty()) {\n return LLRBNode.EMPTY;\n } else {\n smallest = (n.right as LLRBNode<K, V>).min();\n n = n.copy(\n smallest.key,\n smallest.value,\n null,\n null,\n (n.right as LLRBNode<K, V>).removeMin()\n );\n }\n }\n n = n.copy(null, null, null, null, n.right.remove(key, comparator));\n }\n return n.fixUp();\n }\n\n isRed(): boolean {\n return this.color;\n }\n\n // Returns new tree after performing any needed rotations.\n private fixUp(): LLRBNode<K, V> {\n let n: LLRBNode<K, V> = this;\n if (n.right.isRed() && !n.left.isRed()) {\n n = n.rotateLeft();\n }\n if (n.left.isRed() && n.left.left.isRed()) {\n n = n.rotateRight();\n }\n if (n.left.isRed() && n.right.isRed()) {\n n = n.colorFlip();\n }\n return n;\n }\n\n private moveRedLeft(): LLRBNode<K, V> {\n let n = this.colorFlip();\n if (n.right.left.isRed()) {\n n = n.copy(\n null,\n null,\n null,\n null,\n (n.right as LLRBNode<K, V>).rotateRight()\n );\n n = n.rotateLeft();\n n = n.colorFlip();\n }\n return n;\n }\n\n private moveRedRight(): LLRBNode<K, V> {\n let n = this.colorFlip();\n if (n.left.left.isRed()) {\n n = n.rotateRight();\n n = n.colorFlip();\n }\n return n;\n }\n\n private rotateLeft(): LLRBNode<K, V> {\n const nl = this.copy(null, null, LLRBNode.RED, null, this.right.left);\n return (this.right as LLRBNode<K, V>).copy(\n null,\n null,\n this.color,\n nl,\n null\n );\n }\n\n private rotateRight(): LLRBNode<K, V> {\n const nr = this.copy(null, null, LLRBNode.RED, this.left.right, null);\n return (this.left as LLRBNode<K, V>).copy(null, null, this.color, null, nr);\n }\n\n private colorFlip(): LLRBNode<K, V> {\n const left = this.left.copy(null, null, !this.left.color, null, null);\n const right = this.right.copy(null, null, !this.right.color, null, null);\n return this.copy(null, null, !this.color, left, right);\n }\n\n // For testing.\n checkMaxDepth(): boolean {\n const blackDepth = this.check();\n if (Math.pow(2.0, blackDepth) <= this.size + 1) {\n return true;\n } else {\n return false;\n }\n }\n\n // In a balanced RB tree, the black-depth (number of black nodes) from root to\n // leaves is equal on both sides. This function verifies that or asserts.\n protected check(): number {\n if (this.isRed() && this.left.isRed()) {\n throw fail('Red node has red child(' + this.key + ',' + this.value + ')');\n }\n if (this.right.isRed()) {\n throw fail('Right child of (' + this.key + ',' + this.value + ') is red');\n }\n const blackDepth = (this.left as LLRBNode<K, V>).check();\n if (blackDepth !== (this.right as LLRBNode<K, V>).check()) {\n throw fail('Black depths differ');\n } else {\n return blackDepth + (this.isRed() ? 0 : 1);\n }\n }\n} // end LLRBNode\n\n// Represents an empty node (a leaf node in the Red-Black Tree).\nexport class LLRBEmptyNode<K, V> {\n get key(): never {\n throw fail('LLRBEmptyNode has no key.');\n }\n get value(): never {\n throw fail('LLRBEmptyNode has no value.');\n }\n get color(): never {\n throw fail('LLRBEmptyNode has no color.');\n }\n get left(): never {\n throw fail('LLRBEmptyNode has no left child.');\n }\n get right(): never {\n throw fail('LLRBEmptyNode has no right child.');\n }\n size = 0;\n\n // Returns a copy of the current node.\n copy(\n key: K | null,\n value: V | null,\n color: boolean | null,\n left: LLRBNode<K, V> | LLRBEmptyNode<K, V> | null,\n right: LLRBNode<K, V> | LLRBEmptyNode<K, V> | null\n ): LLRBEmptyNode<K, V> {\n return this;\n }\n\n // Returns a copy of the tree, with the specified key/value added.\n insert(key: K, value: V, comparator: Comparator<K>): LLRBNode<K, V> {\n return new LLRBNode<K, V>(key, value);\n }\n\n // Returns a copy of the tree, with the specified key removed.\n remove(key: K, comparator: Comparator<K>): LLRBEmptyNode<K, V> {\n return this;\n }\n\n isEmpty(): boolean {\n return true;\n }\n\n inorderTraversal(action: (k: K, v: V) => boolean): boolean {\n return false;\n }\n\n reverseTraversal(action: (k: K, v: V) => boolean): boolean {\n return false;\n }\n\n minKey(): K | null {\n return null;\n }\n\n maxKey(): K | null {\n return null;\n }\n\n isRed(): boolean {\n return false;\n }\n\n // For testing.\n checkMaxDepth(): boolean {\n return true;\n }\n\n protected check(): 0 {\n return 0;\n }\n} // end LLRBEmptyNode\n\nLLRBNode.EMPTY = new LLRBEmptyNode<unknown, unknown>();\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 { SortedMap, SortedMapIterator } from './sorted_map';\n\n/**\n * SortedSet is an immutable (copy-on-write) collection that holds elements\n * in order specified by the provided comparator.\n *\n * NOTE: if provided comparator returns 0 for two elements, we consider them to\n * be equal!\n */\nexport class SortedSet<T> {\n private data: SortedMap<T, boolean>;\n\n constructor(private comparator: (left: T, right: T) => number) {\n this.data = new SortedMap<T, boolean>(this.comparator);\n }\n\n has(elem: T): boolean {\n return this.data.get(elem) !== null;\n }\n\n first(): T | null {\n return this.data.minKey();\n }\n\n last(): T | null {\n return this.data.maxKey();\n }\n\n get size(): number {\n return this.data.size;\n }\n\n indexOf(elem: T): number {\n return this.data.indexOf(elem);\n }\n\n /** Iterates elements in order defined by \"comparator\" */\n forEach(cb: (elem: T) => void): void {\n this.data.inorderTraversal((k: T, v: boolean) => {\n cb(k);\n return false;\n });\n }\n\n /** Iterates over `elem`s such that: range[0] <= elem < range[1]. */\n forEachInRange(range: [T, T], cb: (elem: T) => void): void {\n const iter = this.data.getIteratorFrom(range[0]);\n while (iter.hasNext()) {\n const elem = iter.getNext();\n if (this.comparator(elem.key, range[1]) >= 0) {\n return;\n }\n cb(elem.key);\n }\n }\n\n /**\n * Iterates over `elem`s such that: start <= elem until false is returned.\n */\n forEachWhile(cb: (elem: T) => boolean, start?: T): void {\n let iter: SortedMapIterator<T, boolean>;\n if (start !== undefined) {\n iter = this.data.getIteratorFrom(start);\n } else {\n iter = this.data.getIterator();\n }\n while (iter.hasNext()) {\n const elem = iter.getNext();\n const result = cb(elem.key);\n if (!result) {\n return;\n }\n }\n }\n\n /** Finds the least element greater than or equal to `elem`. */\n firstAfterOrEqual(elem: T): T | null {\n const iter = this.data.getIteratorFrom(elem);\n return iter.hasNext() ? iter.getNext().key : null;\n }\n\n getIterator(): SortedSetIterator<T> {\n return new SortedSetIterator<T>(this.data.getIterator());\n }\n\n getIteratorFrom(key: T): SortedSetIterator<T> {\n return new SortedSetIterator<T>(this.data.getIteratorFrom(key));\n }\n\n /** Inserts or updates an element */\n add(elem: T): SortedSet<T> {\n return this.copy(this.data.remove(elem).insert(elem, true));\n }\n\n /** Deletes an element */\n delete(elem: T): SortedSet<T> {\n if (!this.has(elem)) {\n return this;\n }\n return this.copy(this.data.remove(elem));\n }\n\n isEmpty(): boolean {\n return this.data.isEmpty();\n }\n\n unionWith(other: SortedSet<T>): SortedSet<T> {\n let result: SortedSet<T> = this;\n\n // Make sure `result` always refers to the larger one of the two sets.\n if (result.size < other.size) {\n result = other;\n other = this;\n }\n\n other.forEach(elem => {\n result = result.add(elem);\n });\n return result;\n }\n\n isEqual(other: SortedSet<T>): boolean {\n if (!(other instanceof SortedSet)) {\n return false;\n }\n if (this.size !== other.size) {\n return false;\n }\n\n const thisIt = this.data.getIterator();\n const otherIt = other.data.getIterator();\n while (thisIt.hasNext()) {\n const thisElem = thisIt.getNext().key;\n const otherElem = otherIt.getNext().key;\n if (this.comparator(thisElem, otherElem) !== 0) {\n return false;\n }\n }\n return true;\n }\n\n toArray(): T[] {\n const res: T[] = [];\n this.forEach(targetId => {\n res.push(targetId);\n });\n return res;\n }\n\n toString(): string {\n const result: T[] = [];\n this.forEach(elem => result.push(elem));\n return 'SortedSet(' + result.toString() + ')';\n }\n\n private copy(data: SortedMap<T, boolean>): SortedSet<T> {\n const result = new SortedSet(this.comparator);\n result.data = data;\n return result;\n }\n}\n\nexport class SortedSetIterator<T> {\n constructor(private iter: SortedMapIterator<T, boolean>) {}\n\n getNext(): T {\n return this.iter.getNext().key;\n }\n\n hasNext(): boolean {\n return this.iter.hasNext();\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 * as firestore from '@firebase/firestore-types';\n\n/**\n * Error Codes describing the different ways Firestore can fail. These come\n * directly from GRPC.\n */\nexport type Code = firestore.FirestoreErrorCode;\n\nexport const Code = {\n // Causes are copied from:\n // https://github.com/grpc/grpc/blob/bceec94ea4fc5f0085d81235d8e1c06798dc341a/include/grpc%2B%2B/impl/codegen/status_code_enum.h\n /** Not an error; returned on success. */\n OK: 'ok' as Code,\n\n /** The operation was cancelled (typically by the caller). */\n CANCELLED: 'cancelled' as Code,\n\n /** Unknown error or an error from a different error domain. */\n UNKNOWN: 'unknown' as Code,\n\n /**\n * Client specified an invalid argument. Note that this differs from\n * FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments that are\n * problematic regardless of the state of the system (e.g., a malformed file\n * name).\n */\n INVALID_ARGUMENT: 'invalid-argument' as Code,\n\n /**\n * Deadline expired before operation could complete. For operations that\n * change the state of the system, this error may be returned even if the\n * operation has completed successfully. For example, a successful response\n * from a server could have been delayed long enough for the deadline to\n * expire.\n */\n DEADLINE_EXCEEDED: 'deadline-exceeded' as Code,\n\n /** Some requested entity (e.g., file or directory) was not found. */\n NOT_FOUND: 'not-found' as Code,\n\n /**\n * Some entity that we attempted to create (e.g., file or directory) already\n * exists.\n */\n ALREADY_EXISTS: 'already-exists' as Code,\n\n /**\n * The caller does not have permission to execute the specified operation.\n * PERMISSION_DENIED must not be used for rejections caused by exhausting\n * some resource (use RESOURCE_EXHAUSTED instead for those errors).\n * PERMISSION_DENIED must not be used if the caller can not be identified\n * (use UNAUTHENTICATED instead for those errors).\n */\n PERMISSION_DENIED: 'permission-denied' as Code,\n\n /**\n * The request does not have valid authentication credentials for the\n * operation.\n */\n UNAUTHENTICATED: 'unauthenticated' as Code,\n\n /**\n * Some resource has been exhausted, perhaps a per-user quota, or perhaps the\n * entire file system is out of space.\n */\n RESOURCE_EXHAUSTED: 'resource-exhausted' as Code,\n\n /**\n * Operation was rejected because the system is not in a state required for\n * the operation's execution. For example, directory to be deleted may be\n * non-empty, an rmdir operation is applied to a non-directory, etc.\n *\n * A litmus test that may help a service implementor in deciding\n * between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE:\n * (a) Use UNAVAILABLE if the client can retry just the failing call.\n * (b) Use ABORTED if the client should retry at a higher-level\n * (e.g., restarting a read-modify-write sequence).\n * (c) Use FAILED_PRECONDITION if the client should not retry until\n * the system state has been explicitly fixed. E.g., if an \"rmdir\"\n * fails because the directory is non-empty, FAILED_PRECONDITION\n * should be returned since the client should not retry unless\n * they have first fixed up the directory by deleting files from it.\n * (d) Use FAILED_PRECONDITION if the client performs conditional\n * REST Get/Update/Delete on a resource and the resource on the\n * server does not match the condition. E.g., conflicting\n * read-modify-write on the same resource.\n */\n FAILED_PRECONDITION: 'failed-precondition' as Code,\n\n /**\n * The operation was aborted, typically due to a concurrency issue like\n * sequencer check failures, transaction aborts, etc.\n *\n * See litmus test above for deciding between FAILED_PRECONDITION, ABORTED,\n * and UNAVAILABLE.\n */\n ABORTED: 'aborted' as Code,\n\n /**\n * Operation was attempted past the valid range. E.g., seeking or reading\n * past end of file.\n *\n * Unlike INVALID_ARGUMENT, this error indicates a problem that may be fixed\n * if the system state changes. For example, a 32-bit file system will\n * generate INVALID_ARGUMENT if asked to read at an offset that is not in the\n * range [0,2^32-1], but it will generate OUT_OF_RANGE if asked to read from\n * an offset past the current file size.\n *\n * There is a fair bit of overlap between FAILED_PRECONDITION and\n * OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific error)\n * when it applies so that callers who are iterating through a space can\n * easily look for an OUT_OF_RANGE error to detect when they are done.\n */\n OUT_OF_RANGE: 'out-of-range' as Code,\n\n /** Operation is not implemented or not supported/enabled in this service. */\n UNIMPLEMENTED: 'unimplemented' as Code,\n\n /**\n * Internal errors. Means some invariants expected by underlying System has\n * been broken. If you see one of these errors, Something is very broken.\n */\n INTERNAL: 'internal' as Code,\n\n /**\n * The service is currently unavailable. This is a most likely a transient\n * condition and may be corrected by retrying with a backoff.\n *\n * See litmus test above for deciding between FAILED_PRECONDITION, ABORTED,\n * and UNAVAILABLE.\n */\n UNAVAILABLE: 'unavailable' as Code,\n\n /** Unrecoverable data loss or corruption. */\n DATA_LOSS: 'data-loss' as Code\n};\n\n/**\n * An error class used for Firestore-generated errors. Ideally we should be\n * using FirebaseError, but integrating with it is overly arduous at the moment,\n * so we define our own compatible error class (with a `name` of 'FirebaseError'\n * and compatible `code` and `message` fields.)\n */\nexport class FirestoreError extends Error implements firestore.FirestoreError {\n name = 'FirebaseError';\n stack?: string;\n\n constructor(readonly code: Code, readonly message: string) {\n super(message);\n\n // HACK: We write a toString property directly because Error is not a real\n // class and so inheritance does not work correctly. We could alternatively\n // do the same \"back-door inheritance\" trick that FirebaseError does.\n this.toString = () => `${this.name}: [code=${this.code}]: ${this.message}`;\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 { debugAssert, fail } from '../util/assert';\nimport { Code, FirestoreError } from '../util/error';\n\nexport const DOCUMENT_KEY_NAME = '__name__';\n\n/**\n * Path represents an ordered sequence of string segments.\n */\nabstract class BasePath<B extends BasePath<B>> {\n private segments: string[];\n private offset: number;\n private len: number;\n\n constructor(segments: string[], offset?: number, length?: number) {\n if (offset === undefined) {\n offset = 0;\n } else if (offset > segments.length) {\n fail('offset ' + offset + ' out of range ' + segments.length);\n }\n\n if (length === undefined) {\n length = segments.length - offset;\n } else if (length > segments.length - offset) {\n fail('length ' + length + ' out of range ' + (segments.length - offset));\n }\n this.segments = segments;\n this.offset = offset;\n this.len = length;\n }\n\n /**\n * Abstract constructor method to construct an instance of B with the given\n * parameters.\n */\n protected abstract construct(\n segments: string[],\n offset?: number,\n length?: number\n ): B;\n\n /**\n * Returns a String representation.\n *\n * Implementing classes are required to provide deterministic implementations as\n * the String representation is used to obtain canonical Query IDs.\n */\n abstract toString(): string;\n\n get length(): number {\n return this.len;\n }\n\n isEqual(other: B): boolean {\n return BasePath.comparator(this, other) === 0;\n }\n\n child(nameOrPath: string | B): B {\n const segments = this.segments.slice(this.offset, this.limit());\n if (nameOrPath instanceof BasePath) {\n nameOrPath.forEach(segment => {\n segments.push(segment);\n });\n } else {\n segments.push(nameOrPath);\n }\n return this.construct(segments);\n }\n\n /** The index of one past the last segment of the path. */\n private limit(): number {\n return this.offset + this.length;\n }\n\n popFirst(size?: number): B {\n size = size === undefined ? 1 : size;\n debugAssert(\n this.length >= size,\n \"Can't call popFirst() with less segments\"\n );\n return this.construct(\n this.segments,\n this.offset + size,\n this.length - size\n );\n }\n\n popLast(): B {\n debugAssert(!this.isEmpty(), \"Can't call popLast() on empty path\");\n return this.construct(this.segments, this.offset, this.length - 1);\n }\n\n firstSegment(): string {\n debugAssert(!this.isEmpty(), \"Can't call firstSegment() on empty path\");\n return this.segments[this.offset];\n }\n\n lastSegment(): string {\n return this.get(this.length - 1);\n }\n\n get(index: number): string {\n debugAssert(index < this.length, 'Index out of range');\n return this.segments[this.offset + index];\n }\n\n isEmpty(): boolean {\n return this.length === 0;\n }\n\n isPrefixOf(other: this): boolean {\n if (other.length < this.length) {\n return false;\n }\n\n for (let i = 0; i < this.length; i++) {\n if (this.get(i) !== other.get(i)) {\n return false;\n }\n }\n\n return true;\n }\n\n isImmediateParentOf(potentialChild: this): boolean {\n if (this.length + 1 !== potentialChild.length) {\n return false;\n }\n\n for (let i = 0; i < this.length; i++) {\n if (this.get(i) !== potentialChild.get(i)) {\n return false;\n }\n }\n\n return true;\n }\n\n forEach(fn: (segment: string) => void): void {\n for (let i = this.offset, end = this.limit(); i < end; i++) {\n fn(this.segments[i]);\n }\n }\n\n toArray(): string[] {\n return this.segments.slice(this.offset, this.limit());\n }\n\n static comparator<T extends BasePath<T>>(\n p1: BasePath<T>,\n p2: BasePath<T>\n ): number {\n const len = Math.min(p1.length, p2.length);\n for (let i = 0; i < len; i++) {\n const left = p1.get(i);\n const right = p2.get(i);\n if (left < right) {\n return -1;\n }\n if (left > right) {\n return 1;\n }\n }\n if (p1.length < p2.length) {\n return -1;\n }\n if (p1.length > p2.length) {\n return 1;\n }\n return 0;\n }\n}\n\n/**\n * A slash-separated path for navigating resources (documents and collections)\n * within Firestore.\n */\nexport class ResourcePath extends BasePath<ResourcePath> {\n protected construct(\n segments: string[],\n offset?: number,\n length?: number\n ): ResourcePath {\n return new ResourcePath(segments, offset, length);\n }\n\n canonicalString(): string {\n // NOTE: The client is ignorant of any path segments containing escape\n // sequences (e.g. __id123__) and just passes them through raw (they exist\n // for legacy reasons and should not be used frequently).\n\n return this.toArray().join('/');\n }\n\n toString(): string {\n return this.canonicalString();\n }\n\n /**\n * Creates a resource path from the given slash-delimited string.\n */\n static fromString(path: string): ResourcePath {\n // NOTE: The client is ignorant of any path segments containing escape\n // sequences (e.g. __id123__) and just passes them through raw (they exist\n // for legacy reasons and should not be used frequently).\n\n if (path.indexOf('//') >= 0) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Invalid path (${path}). Paths must not contain // in them.`\n );\n }\n\n // We may still have an empty segment at the beginning or end if they had a\n // leading or trailing slash (which we allow).\n const segments = path.split('/').filter(segment => segment.length > 0);\n\n return new ResourcePath(segments);\n }\n\n static EMPTY_PATH = new ResourcePath([]);\n}\n\nconst identifierRegExp = /^[_a-zA-Z][_a-zA-Z0-9]*$/;\n\n/** A dot-separated path for navigating sub-objects within a document. */\nexport class FieldPath extends BasePath<FieldPath> {\n protected construct(\n segments: string[],\n offset?: number,\n length?: number\n ): FieldPath {\n return new FieldPath(segments, offset, length);\n }\n\n /**\n * Returns true if the string could be used as a segment in a field path\n * without escaping.\n */\n private static isValidIdentifier(segment: string): boolean {\n return identifierRegExp.test(segment);\n }\n\n canonicalString(): string {\n return this.toArray()\n .map(str => {\n str = str.replace('\\\\', '\\\\\\\\').replace('`', '\\\\`');\n if (!FieldPath.isValidIdentifier(str)) {\n str = '`' + str + '`';\n }\n return str;\n })\n .join('.');\n }\n\n toString(): string {\n return this.canonicalString();\n }\n\n /**\n * Returns true if this field references the key of a document.\n */\n isKeyField(): boolean {\n return this.length === 1 && this.get(0) === DOCUMENT_KEY_NAME;\n }\n\n /**\n * The field designating the key of a document.\n */\n static keyField(): FieldPath {\n return new FieldPath([DOCUMENT_KEY_NAME]);\n }\n\n /**\n * Parses a field string from the given server-formatted string.\n *\n * - Splitting the empty string is not allowed (for now at least).\n * - Empty segments within the string (e.g. if there are two consecutive\n * separators) are not allowed.\n *\n * TODO(b/37244157): we should make this more strict. Right now, it allows\n * non-identifier path components, even if they aren't escaped.\n */\n static fromServerFormat(path: string): FieldPath {\n const segments: string[] = [];\n let current = '';\n let i = 0;\n\n const addCurrentSegment = (): void => {\n if (current.length === 0) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Invalid field path (${path}). Paths must not be empty, begin ` +\n `with '.', end with '.', or contain '..'`\n );\n }\n segments.push(current);\n current = '';\n };\n\n let inBackticks = false;\n\n while (i < path.length) {\n const c = path[i];\n if (c === '\\\\') {\n if (i + 1 === path.length) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'Path has trailing escape character: ' + path\n );\n }\n const next = path[i + 1];\n if (!(next === '\\\\' || next === '.' || next === '`')) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'Path has invalid escape sequence: ' + path\n );\n }\n current += next;\n i += 2;\n } else if (c === '`') {\n inBackticks = !inBackticks;\n i++;\n } else if (c === '.' && !inBackticks) {\n addCurrentSegment();\n i++;\n } else {\n current += c;\n i++;\n }\n }\n addCurrentSegment();\n\n if (inBackticks) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'Unterminated ` in path: ' + path\n );\n }\n\n return new FieldPath(segments);\n }\n\n static EMPTY_PATH = new FieldPath([]);\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 { debugAssert } from '../util/assert';\n\nimport { ResourcePath } from './path';\n\nexport class DocumentKey {\n constructor(readonly path: ResourcePath) {\n debugAssert(\n DocumentKey.isDocumentKey(path),\n 'Invalid DocumentKey with an odd number of segments: ' +\n path.toArray().join('/')\n );\n }\n\n static fromName(name: string): DocumentKey {\n return new DocumentKey(ResourcePath.fromString(name).popFirst(5));\n }\n\n /** Returns true if the document is in the specified collectionId. */\n hasCollectionId(collectionId: string): boolean {\n return (\n this.path.length >= 2 &&\n this.path.get(this.path.length - 2) === collectionId\n );\n }\n\n isEqual(other: DocumentKey | null): boolean {\n return (\n other !== null && ResourcePath.comparator(this.path, other.path) === 0\n );\n }\n\n toString(): string {\n return this.path.toString();\n }\n\n static EMPTY = new DocumentKey(new ResourcePath([]));\n\n static comparator(k1: DocumentKey, k2: DocumentKey): number {\n return ResourcePath.comparator(k1.path, k2.path);\n }\n\n static isDocumentKey(path: ResourcePath): boolean {\n return path.length % 2 === 0;\n }\n\n /**\n * Creates and returns a new document key with the given segments.\n *\n * @param segments The segments of the path to the document\n * @return A new instance of DocumentKey\n */\n static fromSegments(segments: string[]): DocumentKey {\n return new DocumentKey(new ResourcePath(segments.slice()));\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 { SnapshotVersion } from '../core/snapshot_version';\nimport { SortedMap } from '../util/sorted_map';\nimport { SortedSet } from '../util/sorted_set';\n\nimport { TargetId } from '../core/types';\nimport { primitiveComparator } from '../util/misc';\nimport { Document, MaybeDocument } from './document';\nimport { DocumentKey } from './document_key';\n\n/** Miscellaneous collection types / constants. */\nexport interface DocumentSizeEntry {\n maybeDocument: MaybeDocument;\n size: number;\n}\n\nexport type MaybeDocumentMap = SortedMap<DocumentKey, MaybeDocument>;\nconst EMPTY_MAYBE_DOCUMENT_MAP = new SortedMap<DocumentKey, MaybeDocument>(\n DocumentKey.comparator\n);\nexport function maybeDocumentMap(): MaybeDocumentMap {\n return EMPTY_MAYBE_DOCUMENT_MAP;\n}\n\nexport type NullableMaybeDocumentMap = SortedMap<\n DocumentKey,\n MaybeDocument | null\n>;\n\nexport function nullableMaybeDocumentMap(): NullableMaybeDocumentMap {\n return maybeDocumentMap();\n}\n\nexport interface DocumentSizeEntries {\n maybeDocuments: NullableMaybeDocumentMap;\n sizeMap: SortedMap<DocumentKey, number>;\n}\n\nexport type DocumentMap = SortedMap<DocumentKey, Document>;\nconst EMPTY_DOCUMENT_MAP = new SortedMap<DocumentKey, Document>(\n DocumentKey.comparator\n);\nexport function documentMap(): DocumentMap {\n return EMPTY_DOCUMENT_MAP;\n}\n\nexport type DocumentVersionMap = SortedMap<DocumentKey, SnapshotVersion>;\nconst EMPTY_DOCUMENT_VERSION_MAP = new SortedMap<DocumentKey, SnapshotVersion>(\n DocumentKey.comparator\n);\nexport function documentVersionMap(): DocumentVersionMap {\n return EMPTY_DOCUMENT_VERSION_MAP;\n}\n\nexport type DocumentKeySet = SortedSet<DocumentKey>;\nconst EMPTY_DOCUMENT_KEY_SET = new SortedSet(DocumentKey.comparator);\nexport function documentKeySet(...keys: DocumentKey[]): DocumentKeySet {\n let set = EMPTY_DOCUMENT_KEY_SET;\n for (const key of keys) {\n set = set.add(key);\n }\n return set;\n}\n\nexport type TargetIdSet = SortedSet<TargetId>;\nconst EMPTY_TARGET_ID_SET = new SortedSet<TargetId>(primitiveComparator);\nexport function targetIdSet(): SortedSet<TargetId> {\n return EMPTY_TARGET_ID_SET;\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\n// An Object whose keys and values are strings.\nexport interface StringMap {\n [key: string]: string;\n}\n\n/**\n * Returns whether a variable is either undefined or null.\n */\nexport function isNullOrUndefined(value: unknown): value is null | undefined {\n return value === null || value === undefined;\n}\n\n/** Returns whether the value represents -0. */\nexport function isNegativeZero(value: number): boolean {\n // Detect if the value is -0.0. Based on polyfill from\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is\n return value === -0 && 1 / value === 1 / -0;\n}\n\n/**\n * Returns whether a value is an integer and in the safe integer range\n * @param value The value to test for being an integer and in the safe range\n */\nexport function isSafeInteger(value: unknown): boolean {\n return (\n typeof value === 'number' &&\n Number.isInteger(value) &&\n !isNegativeZero(value) &&\n value <= Number.MAX_SAFE_INTEGER &&\n value >= Number.MIN_SAFE_INTEGER\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 { BatchId, MutationBatchState, TargetId } from '../core/types';\nimport { QueryTargetState } from './shared_client_state_syncer';\nimport { debugAssert } from '../util/assert';\nimport { ClientId } from './shared_client_state';\nimport { User } from '../auth/user';\n\n// The format of the LocalStorage key that stores the client state is:\n// firestore_clients_<persistence_prefix>_<instance_key>\nexport const CLIENT_STATE_KEY_PREFIX = 'firestore_clients';\n\n/** Assembles the key for a client state in WebStorage */\nexport function createWebStorageClientStateKey(\n persistenceKey: string,\n clientId: ClientId\n): string {\n debugAssert(\n clientId.indexOf('_') === -1,\n `Client key cannot contain '_', but was '${clientId}'`\n );\n\n return `${CLIENT_STATE_KEY_PREFIX}_${persistenceKey}_${clientId}`;\n}\n\n/**\n * The JSON representation of a clients's metadata as used during WebStorage\n * serialization. The ClientId is omitted here as it is encoded as part of the\n * key.\n */\nexport interface ClientStateSchema {\n activeTargetIds: number[];\n updateTimeMs: number;\n}\n\n// The format of the WebStorage key that stores the mutation state is:\n// firestore_mutations_<persistence_prefix>_<batch_id>\n// (for unauthenticated users)\n// or: firestore_mutations_<persistence_prefix>_<batch_id>_<user_uid>\n//\n// 'user_uid' is last to avoid needing to escape '_' characters that it might\n// contain.\nexport const MUTATION_BATCH_KEY_PREFIX = 'firestore_mutations';\n\n/** Assembles the key for a mutation batch in WebStorage */\nexport function createWebStorageMutationBatchKey(\n persistenceKey: string,\n user: User,\n batchId: BatchId\n): string {\n let mutationKey = `${MUTATION_BATCH_KEY_PREFIX}_${persistenceKey}_${batchId}`;\n\n if (user.isAuthenticated()) {\n mutationKey += `_${user.uid}`;\n }\n\n return mutationKey;\n}\n\n/**\n * The JSON representation of a mutation batch's metadata as used during\n * WebStorage serialization. The UserId and BatchId is omitted as it is\n * encoded as part of the key.\n */\nexport interface MutationMetadataSchema {\n state: MutationBatchState;\n error?: { code: string; message: string }; // Only set when state === 'rejected'\n updateTimeMs: number;\n}\n\n// The format of the WebStorage key that stores a query target's metadata is:\n// firestore_targets_<persistence_prefix>_<target_id>\nexport const QUERY_TARGET_KEY_PREFIX = 'firestore_targets';\n\n/** Assembles the key for a query state in WebStorage */\nexport function createWebStorageQueryTargetMetadataKey(\n persistenceKey: string,\n targetId: TargetId\n): string {\n return `${QUERY_TARGET_KEY_PREFIX}_${persistenceKey}_${targetId}`;\n}\n\n/**\n * The JSON representation of a query target's state as used during WebStorage\n * serialization. The TargetId is omitted as it is encoded as part of the key.\n */\nexport interface QueryTargetStateSchema {\n state: QueryTargetState;\n error?: { code: string; message: string }; // Only set when state === 'rejected'\n updateTimeMs: number;\n}\n\n// The WebStorage prefix that stores the primary tab's online state. The\n// format of the key is:\n// firestore_online_state_<persistence_prefix>\nexport const ONLINE_STATE_KEY_PREFIX = 'firestore_online_state';\n\n/** Assembles the key for the online state of the primary tab. */\nexport function createWebStorageOnlineStateKey(persistenceKey: string): string {\n return `${ONLINE_STATE_KEY_PREFIX}_${persistenceKey}`;\n}\n\n/**\n * The JSON representation of the system's online state, as written by the\n * primary client.\n */\nexport interface SharedOnlineStateSchema {\n /**\n * The clientId of the client that wrote this onlineState value. Tracked so\n * that on startup, clients can check if this client is still active when\n * determining whether to apply this value or not.\n */\n readonly clientId: string;\n readonly onlineState: string;\n}\n\n// The WebStorage key prefix for the key that stores the last sequence number allocated. The key\n// looks like 'firestore_sequence_number_<persistence_prefix>'.\nexport const SEQUENCE_NUMBER_KEY_PREFIX = 'firestore_sequence_number';\n\n/** Assembles the key for the current sequence number. */\nexport function createWebStorageSequenceNumberKey(\n persistenceKey: string\n): string {\n return `${SEQUENCE_NUMBER_KEY_PREFIX}_${persistenceKey}`;\n}\n","/**\n * @license\n * Copyright 2018 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 { User } from '../auth/user';\nimport { ListenSequence } from '../core/listen_sequence';\nimport {\n BatchId,\n ListenSequenceNumber,\n MutationBatchState,\n OnlineState,\n TargetId\n} from '../core/types';\nimport { TargetIdSet, targetIdSet } from '../model/collections';\nimport { Platform } from '../platform/platform';\nimport { hardAssert, debugAssert } from '../util/assert';\nimport { AsyncQueue } from '../util/async_queue';\nimport { Code, FirestoreError } from '../util/error';\nimport { logError, logDebug } from '../util/log';\nimport { SortedSet } from '../util/sorted_set';\nimport { SortedMap } from '../util/sorted_map';\nimport { primitiveComparator } from '../util/misc';\nimport { isSafeInteger } from '../util/types';\nimport {\n QueryTargetState,\n SharedClientStateSyncer\n} from './shared_client_state_syncer';\nimport {\n CLIENT_STATE_KEY_PREFIX,\n ClientStateSchema,\n createWebStorageClientStateKey,\n createWebStorageMutationBatchKey,\n createWebStorageOnlineStateKey,\n createWebStorageQueryTargetMetadataKey,\n createWebStorageSequenceNumberKey,\n MUTATION_BATCH_KEY_PREFIX,\n MutationMetadataSchema,\n QUERY_TARGET_KEY_PREFIX,\n QueryTargetStateSchema,\n SharedOnlineStateSchema\n} from './shared_client_state_schema';\n\nconst LOG_TAG = 'SharedClientState';\n\n/**\n * A randomly-generated key assigned to each Firestore instance at startup.\n */\nexport type ClientId = string;\n\n/**\n * A `SharedClientState` keeps track of the global state of the mutations\n * and query targets for all active clients with the same persistence key (i.e.\n * project ID and FirebaseApp name). It relays local changes to other clients\n * and updates its local state as new state is observed.\n *\n * `SharedClientState` is primarily used for synchronization in Multi-Tab\n * environments. Each tab is responsible for registering its active query\n * targets and mutations. `SharedClientState` will then notify the listener\n * assigned to `.syncEngine` for updates to mutations and queries that\n * originated in other clients.\n *\n * To receive notifications, `.syncEngine` and `.onlineStateHandler` has to be\n * assigned before calling `start()`.\n */\nexport interface SharedClientState {\n syncEngine: SharedClientStateSyncer | null;\n onlineStateHandler: ((onlineState: OnlineState) => void) | null;\n sequenceNumberHandler:\n | ((sequenceNumber: ListenSequenceNumber) => void)\n | null;\n\n /** Registers the Mutation Batch ID of a newly pending mutation. */\n addPendingMutation(batchId: BatchId): void;\n\n /**\n * Records that a pending mutation has been acknowledged or rejected.\n * Called by the primary client to notify secondary clients of mutation\n * results as they come back from the backend.\n */\n updateMutationState(\n batchId: BatchId,\n state: 'acknowledged' | 'rejected',\n error?: FirestoreError\n ): void;\n\n /**\n * Associates a new Query Target ID with the local Firestore client. Returns\n * the new query state for the query (which can be 'current' if the query is\n * already associated with another tab).\n *\n * If the target id is already associated with local client, the method simply\n * returns its `QueryTargetState`.\n */\n addLocalQueryTarget(targetId: TargetId): QueryTargetState;\n\n /** Removes the Query Target ID association from the local client. */\n removeLocalQueryTarget(targetId: TargetId): void;\n\n /** Checks whether the target is associated with the local client. */\n isLocalQueryTarget(targetId: TargetId): boolean;\n\n /**\n * Processes an update to a query target.\n *\n * Called by the primary client to notify secondary clients of document\n * changes or state transitions that affect the provided query target.\n */\n updateQueryState(\n targetId: TargetId,\n state: QueryTargetState,\n error?: FirestoreError\n ): void;\n\n /**\n * Removes the target's metadata entry.\n *\n * Called by the primary client when all clients stopped listening to a query\n * target.\n */\n clearQueryState(targetId: TargetId): void;\n\n /**\n * Gets the active Query Targets IDs for all active clients.\n *\n * The implementation for this may require O(n) runtime, where 'n' is the size\n * of the result set.\n */\n // Visible for testing\n getAllActiveQueryTargets(): SortedSet<TargetId>;\n\n /**\n * Checks whether the provided target ID is currently being listened to by\n * any of the active clients.\n *\n * The implementation may require O(n*log m) runtime, where 'n' is the number\n * of clients and 'm' the number of targets.\n */\n isActiveQueryTarget(targetId: TargetId): boolean;\n\n /**\n * Starts the SharedClientState, reads existing client data and registers\n * listeners for updates to new and existing clients.\n */\n start(): Promise<void>;\n\n /** Shuts down the `SharedClientState` and its listeners. */\n shutdown(): void;\n\n /**\n * Changes the active user and removes all existing user-specific data. The\n * user change does not call back into SyncEngine (for example, no mutations\n * will be marked as removed).\n */\n handleUserChange(\n user: User,\n removedBatchIds: BatchId[],\n addedBatchIds: BatchId[]\n ): void;\n\n /** Changes the shared online state of all clients. */\n setOnlineState(onlineState: OnlineState): void;\n\n writeSequenceNumber(sequenceNumber: ListenSequenceNumber): void;\n}\n\n/**\n * Holds the state of a mutation batch, including its user ID, batch ID and\n * whether the batch is 'pending', 'acknowledged' or 'rejected'.\n */\n// Visible for testing\nexport class MutationMetadata {\n constructor(\n readonly user: User,\n readonly batchId: BatchId,\n readonly state: MutationBatchState,\n readonly error?: FirestoreError\n ) {\n debugAssert(\n (error !== undefined) === (state === 'rejected'),\n `MutationMetadata must contain an error iff state is 'rejected'`\n );\n }\n\n /**\n * Parses a MutationMetadata from its JSON representation in WebStorage.\n * Logs a warning and returns null if the format of the data is not valid.\n */\n static fromWebStorageEntry(\n user: User,\n batchId: BatchId,\n value: string\n ): MutationMetadata | null {\n const mutationBatch = JSON.parse(value) as MutationMetadataSchema;\n\n let validData =\n typeof mutationBatch === 'object' &&\n ['pending', 'acknowledged', 'rejected'].indexOf(mutationBatch.state) !==\n -1 &&\n (mutationBatch.error === undefined ||\n typeof mutationBatch.error === 'object');\n\n let firestoreError: FirestoreError | undefined = undefined;\n\n if (validData && mutationBatch.error) {\n validData =\n typeof mutationBatch.error.message === 'string' &&\n typeof mutationBatch.error.code === 'string';\n if (validData) {\n firestoreError = new FirestoreError(\n mutationBatch.error.code as Code,\n mutationBatch.error.message\n );\n }\n }\n\n if (validData) {\n return new MutationMetadata(\n user,\n batchId,\n mutationBatch.state,\n firestoreError\n );\n } else {\n logError(\n LOG_TAG,\n `Failed to parse mutation state for ID '${batchId}': ${value}`\n );\n return null;\n }\n }\n\n toWebStorageJSON(): string {\n const batchMetadata: MutationMetadataSchema = {\n state: this.state,\n updateTimeMs: Date.now() // Modify the existing value to trigger update.\n };\n\n if (this.error) {\n batchMetadata.error = {\n code: this.error.code,\n message: this.error.message\n };\n }\n\n return JSON.stringify(batchMetadata);\n }\n}\n\n/**\n * Holds the state of a query target, including its target ID and whether the\n * target is 'not-current', 'current' or 'rejected'.\n */\n// Visible for testing\nexport class QueryTargetMetadata {\n constructor(\n readonly targetId: TargetId,\n readonly state: QueryTargetState,\n readonly error?: FirestoreError\n ) {\n debugAssert(\n (error !== undefined) === (state === 'rejected'),\n `QueryTargetMetadata must contain an error iff state is 'rejected'`\n );\n }\n\n /**\n * Parses a QueryTargetMetadata from its JSON representation in WebStorage.\n * Logs a warning and returns null if the format of the data is not valid.\n */\n static fromWebStorageEntry(\n targetId: TargetId,\n value: string\n ): QueryTargetMetadata | null {\n const targetState = JSON.parse(value) as QueryTargetStateSchema;\n\n let validData =\n typeof targetState === 'object' &&\n ['not-current', 'current', 'rejected'].indexOf(targetState.state) !==\n -1 &&\n (targetState.error === undefined ||\n typeof targetState.error === 'object');\n\n let firestoreError: FirestoreError | undefined = undefined;\n\n if (validData && targetState.error) {\n validData =\n typeof targetState.error.message === 'string' &&\n typeof targetState.error.code === 'string';\n if (validData) {\n firestoreError = new FirestoreError(\n targetState.error.code as Code,\n targetState.error.message\n );\n }\n }\n\n if (validData) {\n return new QueryTargetMetadata(\n targetId,\n targetState.state,\n firestoreError\n );\n } else {\n logError(\n LOG_TAG,\n `Failed to parse target state for ID '${targetId}': ${value}`\n );\n return null;\n }\n }\n\n toWebStorageJSON(): string {\n const targetState: QueryTargetStateSchema = {\n state: this.state,\n updateTimeMs: Date.now() // Modify the existing value to trigger update.\n };\n\n if (this.error) {\n targetState.error = {\n code: this.error.code,\n message: this.error.message\n };\n }\n\n return JSON.stringify(targetState);\n }\n}\n\n/**\n * Metadata state of a single client denoting the query targets it is actively\n * listening to.\n */\n// Visible for testing.\nexport interface ClientState {\n readonly activeTargetIds: TargetIdSet;\n}\n\n/**\n * This class represents the immutable ClientState for a client read from\n * WebStorage, containing the list of active query targets.\n */\nclass RemoteClientState implements ClientState {\n private constructor(\n readonly clientId: ClientId,\n readonly activeTargetIds: TargetIdSet\n ) {}\n\n /**\n * Parses a RemoteClientState from the JSON representation in WebStorage.\n * Logs a warning and returns null if the format of the data is not valid.\n */\n static fromWebStorageEntry(\n clientId: ClientId,\n value: string\n ): RemoteClientState | null {\n const clientState = JSON.parse(value) as ClientStateSchema;\n\n let validData =\n typeof clientState === 'object' &&\n clientState.activeTargetIds instanceof Array;\n\n let activeTargetIdsSet = targetIdSet();\n\n for (let i = 0; validData && i < clientState.activeTargetIds.length; ++i) {\n validData = isSafeInteger(clientState.activeTargetIds[i]);\n activeTargetIdsSet = activeTargetIdsSet.add(\n clientState.activeTargetIds[i]\n );\n }\n\n if (validData) {\n return new RemoteClientState(clientId, activeTargetIdsSet);\n } else {\n logError(\n LOG_TAG,\n `Failed to parse client data for instance '${clientId}': ${value}`\n );\n return null;\n }\n }\n}\n\n/**\n * This class represents the online state for all clients participating in\n * multi-tab. The online state is only written to by the primary client, and\n * used in secondary clients to update their query views.\n */\nexport class SharedOnlineState {\n constructor(readonly clientId: string, readonly onlineState: OnlineState) {}\n\n /**\n * Parses a SharedOnlineState from its JSON representation in WebStorage.\n * Logs a warning and returns null if the format of the data is not valid.\n */\n static fromWebStorageEntry(value: string): SharedOnlineState | null {\n const onlineState = JSON.parse(value) as SharedOnlineStateSchema;\n\n const validData =\n typeof onlineState === 'object' &&\n ['Unknown', 'Online', 'Offline'].indexOf(onlineState.onlineState) !==\n -1 &&\n typeof onlineState.clientId === 'string';\n\n if (validData) {\n return new SharedOnlineState(\n onlineState.clientId,\n onlineState.onlineState as OnlineState\n );\n } else {\n logError(LOG_TAG, `Failed to parse online state: ${value}`);\n return null;\n }\n }\n}\n\n/**\n * Metadata state of the local client. Unlike `RemoteClientState`, this class is\n * mutable and keeps track of all pending mutations, which allows us to\n * update the range of pending mutation batch IDs as new mutations are added or\n * removed.\n *\n * The data in `LocalClientState` is not read from WebStorage and instead\n * updated via its instance methods. The updated state can be serialized via\n * `toWebStorageJSON()`.\n */\n// Visible for testing.\nexport class LocalClientState implements ClientState {\n activeTargetIds = targetIdSet();\n\n addQueryTarget(targetId: TargetId): void {\n this.activeTargetIds = this.activeTargetIds.add(targetId);\n }\n\n removeQueryTarget(targetId: TargetId): void {\n this.activeTargetIds = this.activeTargetIds.delete(targetId);\n }\n\n /**\n * Converts this entry into a JSON-encoded format we can use for WebStorage.\n * Does not encode `clientId` as it is part of the key in WebStorage.\n */\n toWebStorageJSON(): string {\n const data: ClientStateSchema = {\n activeTargetIds: this.activeTargetIds.toArray(),\n updateTimeMs: Date.now() // Modify the existing value to trigger update.\n };\n return JSON.stringify(data);\n }\n}\n\n/**\n * `WebStorageSharedClientState` uses WebStorage (window.localStorage) as the\n * backing store for the SharedClientState. It keeps track of all active\n * clients and supports modifications of the local client's data.\n */\nexport class WebStorageSharedClientState implements SharedClientState {\n syncEngine: SharedClientStateSyncer | null = null;\n onlineStateHandler: ((onlineState: OnlineState) => void) | null = null;\n sequenceNumberHandler:\n | ((sequenceNumber: ListenSequenceNumber) => void)\n | null = null;\n\n private readonly storage: Storage;\n private readonly localClientStorageKey: string;\n private readonly sequenceNumberKey: string;\n private readonly storageListener = this.handleWebStorageEvent.bind(this);\n private readonly onlineStateKey: string;\n private readonly clientStateKeyRe: RegExp;\n private readonly mutationBatchKeyRe: RegExp;\n private readonly queryTargetKeyRe: RegExp;\n private activeClients = new SortedMap<string, ClientState>(\n primitiveComparator\n );\n private started = false;\n private currentUser: User;\n\n /**\n * Captures WebStorage events that occur before `start()` is called. These\n * events are replayed once `WebStorageSharedClientState` is started.\n */\n private earlyEvents: StorageEvent[] = [];\n\n constructor(\n private readonly queue: AsyncQueue,\n private readonly platform: Platform,\n private readonly persistenceKey: string,\n private readonly localClientId: ClientId,\n initialUser: User\n ) {\n if (!WebStorageSharedClientState.isAvailable(this.platform)) {\n throw new FirestoreError(\n Code.UNIMPLEMENTED,\n 'LocalStorage is not available on this platform.'\n );\n }\n // Escape the special characters mentioned here:\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions\n const escapedPersistenceKey = persistenceKey.replace(\n /[.*+?^${}()|[\\]\\\\]/g,\n '\\\\$&'\n );\n\n this.storage = this.platform.window!.localStorage;\n this.currentUser = initialUser;\n this.localClientStorageKey = createWebStorageClientStateKey(\n this.persistenceKey,\n this.localClientId\n );\n this.sequenceNumberKey = createWebStorageSequenceNumberKey(\n this.persistenceKey\n );\n this.activeClients = this.activeClients.insert(\n this.localClientId,\n new LocalClientState()\n );\n\n this.clientStateKeyRe = new RegExp(\n `^${CLIENT_STATE_KEY_PREFIX}_${escapedPersistenceKey}_([^_]*)$`\n );\n this.mutationBatchKeyRe = new RegExp(\n `^${MUTATION_BATCH_KEY_PREFIX}_${escapedPersistenceKey}_(\\\\d+)(?:_(.*))?$`\n );\n this.queryTargetKeyRe = new RegExp(\n `^${QUERY_TARGET_KEY_PREFIX}_${escapedPersistenceKey}_(\\\\d+)$`\n );\n\n this.onlineStateKey = createWebStorageOnlineStateKey(this.persistenceKey);\n\n // Rather than adding the storage observer during start(), we add the\n // storage observer during initialization. This ensures that we collect\n // events before other components populate their initial state (during their\n // respective start() calls). Otherwise, we might for example miss a\n // mutation that is added after LocalStore's start() processed the existing\n // mutations but before we observe WebStorage events.\n this.platform.window!.addEventListener('storage', this.storageListener);\n }\n\n /** Returns 'true' if WebStorage is available in the current environment. */\n static isAvailable(platform: Platform): boolean {\n return !!(platform.window && platform.window.localStorage != null);\n }\n\n async start(): Promise<void> {\n debugAssert(!this.started, 'WebStorageSharedClientState already started');\n debugAssert(\n this.syncEngine !== null,\n 'syncEngine property must be set before calling start()'\n );\n debugAssert(\n this.onlineStateHandler !== null,\n 'onlineStateHandler property must be set before calling start()'\n );\n\n // Retrieve the list of existing clients to backfill the data in\n // SharedClientState.\n const existingClients = await this.syncEngine!.getActiveClients();\n\n for (const clientId of existingClients) {\n if (clientId === this.localClientId) {\n continue;\n }\n\n const storageItem = this.getItem(\n createWebStorageClientStateKey(this.persistenceKey, clientId)\n );\n if (storageItem) {\n const clientState = RemoteClientState.fromWebStorageEntry(\n clientId,\n storageItem\n );\n if (clientState) {\n this.activeClients = this.activeClients.insert(\n clientState.clientId,\n clientState\n );\n }\n }\n }\n\n this.persistClientState();\n\n // Check if there is an existing online state and call the callback handler\n // if applicable.\n const onlineStateJSON = this.storage.getItem(this.onlineStateKey);\n if (onlineStateJSON) {\n const onlineState = this.fromWebStorageOnlineState(onlineStateJSON);\n if (onlineState) {\n this.handleOnlineStateEvent(onlineState);\n }\n }\n\n for (const event of this.earlyEvents) {\n this.handleWebStorageEvent(event);\n }\n\n this.earlyEvents = [];\n\n // Register a window unload hook to remove the client metadata entry from\n // WebStorage even if `shutdown()` was not called.\n this.platform.window!.addEventListener('unload', () => this.shutdown());\n\n this.started = true;\n }\n\n writeSequenceNumber(sequenceNumber: ListenSequenceNumber): void {\n this.setItem(this.sequenceNumberKey, JSON.stringify(sequenceNumber));\n }\n\n getAllActiveQueryTargets(): TargetIdSet {\n return this.extractActiveQueryTargets(this.activeClients);\n }\n\n isActiveQueryTarget(targetId: TargetId): boolean {\n let found = false;\n this.activeClients.forEach((key, value) => {\n if (value.activeTargetIds.has(targetId)) {\n found = true;\n }\n });\n return found;\n }\n\n addPendingMutation(batchId: BatchId): void {\n this.persistMutationState(batchId, 'pending');\n }\n\n updateMutationState(\n batchId: BatchId,\n state: 'acknowledged' | 'rejected',\n error?: FirestoreError\n ): void {\n this.persistMutationState(batchId, state, error);\n\n // Once a final mutation result is observed by other clients, they no longer\n // access the mutation's metadata entry. Since WebStorage replays events\n // in order, it is safe to delete the entry right after updating it.\n this.removeMutationState(batchId);\n }\n\n addLocalQueryTarget(targetId: TargetId): QueryTargetState {\n let queryState: QueryTargetState = 'not-current';\n\n // Lookup an existing query state if the target ID was already registered\n // by another tab\n if (this.isActiveQueryTarget(targetId)) {\n const storageItem = this.storage.getItem(\n createWebStorageQueryTargetMetadataKey(this.persistenceKey, targetId)\n );\n\n if (storageItem) {\n const metadata = QueryTargetMetadata.fromWebStorageEntry(\n targetId,\n storageItem\n );\n if (metadata) {\n queryState = metadata.state;\n }\n }\n }\n\n this.localClientState.addQueryTarget(targetId);\n this.persistClientState();\n\n return queryState;\n }\n\n removeLocalQueryTarget(targetId: TargetId): void {\n this.localClientState.removeQueryTarget(targetId);\n this.persistClientState();\n }\n\n isLocalQueryTarget(targetId: TargetId): boolean {\n return this.localClientState.activeTargetIds.has(targetId);\n }\n\n clearQueryState(targetId: TargetId): void {\n this.removeItem(\n createWebStorageQueryTargetMetadataKey(this.persistenceKey, targetId)\n );\n }\n\n updateQueryState(\n targetId: TargetId,\n state: QueryTargetState,\n error?: FirestoreError\n ): void {\n this.persistQueryTargetState(targetId, state, error);\n }\n\n handleUserChange(\n user: User,\n removedBatchIds: BatchId[],\n addedBatchIds: BatchId[]\n ): void {\n removedBatchIds.forEach(batchId => {\n this.removeMutationState(batchId);\n });\n this.currentUser = user;\n addedBatchIds.forEach(batchId => {\n this.addPendingMutation(batchId);\n });\n }\n\n setOnlineState(onlineState: OnlineState): void {\n this.persistOnlineState(onlineState);\n }\n\n shutdown(): void {\n if (this.started) {\n this.platform.window!.removeEventListener(\n 'storage',\n this.storageListener\n );\n this.removeItem(this.localClientStorageKey);\n this.started = false;\n }\n }\n\n private getItem(key: string): string | null {\n const value = this.storage.getItem(key);\n logDebug(LOG_TAG, 'READ', key, value);\n return value;\n }\n\n private setItem(key: string, value: string): void {\n logDebug(LOG_TAG, 'SET', key, value);\n this.storage.setItem(key, value);\n }\n\n private removeItem(key: string): void {\n logDebug(LOG_TAG, 'REMOVE', key);\n this.storage.removeItem(key);\n }\n\n private handleWebStorageEvent(event: StorageEvent): void {\n if (event.storageArea === this.storage) {\n logDebug(LOG_TAG, 'EVENT', event.key, event.newValue);\n\n if (event.key === this.localClientStorageKey) {\n logError(\n 'Received WebStorage notification for local change. Another client might have ' +\n 'garbage-collected our state'\n );\n return;\n }\n\n this.queue.enqueueRetryable(async () => {\n if (!this.started) {\n this.earlyEvents.push(event);\n return;\n }\n\n if (event.key === null) {\n return;\n }\n\n if (this.clientStateKeyRe.test(event.key)) {\n if (event.newValue != null) {\n const clientState = this.fromWebStorageClientState(\n event.key,\n event.newValue\n );\n if (clientState) {\n return this.handleClientStateEvent(\n clientState.clientId,\n clientState\n );\n }\n } else {\n const clientId = this.fromWebStorageClientStateKey(event.key)!;\n return this.handleClientStateEvent(clientId, null);\n }\n } else if (this.mutationBatchKeyRe.test(event.key)) {\n if (event.newValue !== null) {\n const mutationMetadata = this.fromWebStorageMutationMetadata(\n event.key,\n event.newValue\n );\n if (mutationMetadata) {\n return this.handleMutationBatchEvent(mutationMetadata);\n }\n }\n } else if (this.queryTargetKeyRe.test(event.key)) {\n if (event.newValue !== null) {\n const queryTargetMetadata = this.fromWebStorageQueryTargetMetadata(\n event.key,\n event.newValue\n );\n if (queryTargetMetadata) {\n return this.handleQueryTargetEvent(queryTargetMetadata);\n }\n }\n } else if (event.key === this.onlineStateKey) {\n if (event.newValue !== null) {\n const onlineState = this.fromWebStorageOnlineState(event.newValue);\n if (onlineState) {\n return this.handleOnlineStateEvent(onlineState);\n }\n }\n } else if (event.key === this.sequenceNumberKey) {\n debugAssert(\n !!this.sequenceNumberHandler,\n 'Missing sequenceNumberHandler'\n );\n const sequenceNumber = fromWebStorageSequenceNumber(event.newValue);\n if (sequenceNumber !== ListenSequence.INVALID) {\n this.sequenceNumberHandler!(sequenceNumber);\n }\n }\n });\n }\n }\n\n private get localClientState(): LocalClientState {\n return this.activeClients.get(this.localClientId) as LocalClientState;\n }\n\n private persistClientState(): void {\n this.setItem(\n this.localClientStorageKey,\n this.localClientState.toWebStorageJSON()\n );\n }\n\n private persistMutationState(\n batchId: BatchId,\n state: MutationBatchState,\n error?: FirestoreError\n ): void {\n const mutationState = new MutationMetadata(\n this.currentUser,\n batchId,\n state,\n error\n );\n const mutationKey = createWebStorageMutationBatchKey(\n this.persistenceKey,\n this.currentUser,\n batchId\n );\n this.setItem(mutationKey, mutationState.toWebStorageJSON());\n }\n\n private removeMutationState(batchId: BatchId): void {\n const mutationKey = createWebStorageMutationBatchKey(\n this.persistenceKey,\n this.currentUser,\n batchId\n );\n this.removeItem(mutationKey);\n }\n\n private persistOnlineState(onlineState: OnlineState): void {\n const entry: SharedOnlineStateSchema = {\n clientId: this.localClientId,\n onlineState\n };\n this.storage.setItem(this.onlineStateKey, JSON.stringify(entry));\n }\n\n private persistQueryTargetState(\n targetId: TargetId,\n state: QueryTargetState,\n error?: FirestoreError\n ): void {\n const targetKey = createWebStorageQueryTargetMetadataKey(\n this.persistenceKey,\n targetId\n );\n const targetMetadata = new QueryTargetMetadata(targetId, state, error);\n this.setItem(targetKey, targetMetadata.toWebStorageJSON());\n }\n\n /**\n * Parses a client state key in WebStorage. Returns null if the key does not\n * match the expected key format.\n */\n private fromWebStorageClientStateKey(key: string): ClientId | null {\n const match = this.clientStateKeyRe.exec(key);\n return match ? match[1] : null;\n }\n\n /**\n * Parses a client state in WebStorage. Returns 'null' if the value could not\n * be parsed.\n */\n private fromWebStorageClientState(\n key: string,\n value: string\n ): RemoteClientState | null {\n const clientId = this.fromWebStorageClientStateKey(key);\n debugAssert(clientId !== null, `Cannot parse client state key '${key}'`);\n return RemoteClientState.fromWebStorageEntry(clientId, value);\n }\n\n /**\n * Parses a mutation batch state in WebStorage. Returns 'null' if the value\n * could not be parsed.\n */\n private fromWebStorageMutationMetadata(\n key: string,\n value: string\n ): MutationMetadata | null {\n const match = this.mutationBatchKeyRe.exec(key);\n debugAssert(match !== null, `Cannot parse mutation batch key '${key}'`);\n\n const batchId = Number(match[1]);\n const userId = match[2] !== undefined ? match[2] : null;\n return MutationMetadata.fromWebStorageEntry(\n new User(userId),\n batchId,\n value\n );\n }\n\n /**\n * Parses a query target state from WebStorage. Returns 'null' if the value\n * could not be parsed.\n */\n private fromWebStorageQueryTargetMetadata(\n key: string,\n value: string\n ): QueryTargetMetadata | null {\n const match = this.queryTargetKeyRe.exec(key);\n debugAssert(match !== null, `Cannot parse query target key '${key}'`);\n\n const targetId = Number(match[1]);\n return QueryTargetMetadata.fromWebStorageEntry(targetId, value);\n }\n\n /**\n * Parses an online state from WebStorage. Returns 'null' if the value\n * could not be parsed.\n */\n private fromWebStorageOnlineState(value: string): SharedOnlineState | null {\n return SharedOnlineState.fromWebStorageEntry(value);\n }\n\n private async handleMutationBatchEvent(\n mutationBatch: MutationMetadata\n ): Promise<void> {\n if (mutationBatch.user.uid !== this.currentUser.uid) {\n logDebug(\n LOG_TAG,\n `Ignoring mutation for non-active user ${mutationBatch.user.uid}`\n );\n return;\n }\n\n return this.syncEngine!.applyBatchState(\n mutationBatch.batchId,\n mutationBatch.state,\n mutationBatch.error\n );\n }\n\n private handleQueryTargetEvent(\n targetMetadata: QueryTargetMetadata\n ): Promise<void> {\n return this.syncEngine!.applyTargetState(\n targetMetadata.targetId,\n targetMetadata.state,\n targetMetadata.error\n );\n }\n\n private handleClientStateEvent(\n clientId: ClientId,\n clientState: RemoteClientState | null\n ): Promise<void> {\n const updatedClients = clientState\n ? this.activeClients.insert(clientId, clientState)\n : this.activeClients.remove(clientId);\n\n const existingTargets = this.extractActiveQueryTargets(this.activeClients);\n const newTargets = this.extractActiveQueryTargets(updatedClients);\n\n const addedTargets: TargetId[] = [];\n const removedTargets: TargetId[] = [];\n\n newTargets.forEach(targetId => {\n if (!existingTargets.has(targetId)) {\n addedTargets.push(targetId);\n }\n });\n\n existingTargets.forEach(targetId => {\n if (!newTargets.has(targetId)) {\n removedTargets.push(targetId);\n }\n });\n\n return this.syncEngine!.applyActiveTargetsChange(\n addedTargets,\n removedTargets\n ).then(() => {\n this.activeClients = updatedClients;\n });\n }\n\n private handleOnlineStateEvent(onlineState: SharedOnlineState): void {\n // We check whether the client that wrote this online state is still active\n // by comparing its client ID to the list of clients kept active in\n // IndexedDb. If a client does not update their IndexedDb client state\n // within 5 seconds, it is considered inactive and we don't emit an online\n // state event.\n if (this.activeClients.get(onlineState.clientId)) {\n this.onlineStateHandler!(onlineState.onlineState);\n }\n }\n\n private extractActiveQueryTargets(\n clients: SortedMap<string, ClientState>\n ): SortedSet<TargetId> {\n let activeTargets = targetIdSet();\n clients.forEach((kev, value) => {\n activeTargets = activeTargets.unionWith(value.activeTargetIds);\n });\n return activeTargets;\n }\n}\n\nfunction fromWebStorageSequenceNumber(\n seqString: string | null\n): ListenSequenceNumber {\n let sequenceNumber = ListenSequence.INVALID;\n if (seqString != null) {\n try {\n const parsed = JSON.parse(seqString);\n hardAssert(\n typeof parsed === 'number',\n 'Found non-numeric sequence number'\n );\n sequenceNumber = parsed;\n } catch (e) {\n logError(LOG_TAG, 'Failed to read sequence number from WebStorage', e);\n }\n }\n return sequenceNumber;\n}\n\n/**\n * `MemorySharedClientState` is a simple implementation of SharedClientState for\n * clients using memory persistence. The state in this class remains fully\n * isolated and no synchronization is performed.\n */\nexport class MemorySharedClientState implements SharedClientState {\n private localState = new LocalClientState();\n private queryState: { [targetId: number]: QueryTargetState } = {};\n\n syncEngine: SharedClientStateSyncer | null = null;\n onlineStateHandler: ((onlineState: OnlineState) => void) | null = null;\n sequenceNumberHandler:\n | ((sequenceNumber: ListenSequenceNumber) => void)\n | null = null;\n\n addPendingMutation(batchId: BatchId): void {\n // No op.\n }\n\n updateMutationState(\n batchId: BatchId,\n state: 'acknowledged' | 'rejected',\n error?: FirestoreError\n ): void {\n // No op.\n }\n\n addLocalQueryTarget(targetId: TargetId): QueryTargetState {\n this.localState.addQueryTarget(targetId);\n return this.queryState[targetId] || 'not-current';\n }\n\n updateQueryState(\n targetId: TargetId,\n state: QueryTargetState,\n error?: FirestoreError\n ): void {\n this.queryState[targetId] = state;\n }\n\n removeLocalQueryTarget(targetId: TargetId): void {\n this.localState.removeQueryTarget(targetId);\n }\n\n isLocalQueryTarget(targetId: TargetId): boolean {\n return this.localState.activeTargetIds.has(targetId);\n }\n\n clearQueryState(targetId: TargetId): void {\n delete this.queryState[targetId];\n }\n\n getAllActiveQueryTargets(): TargetIdSet {\n return this.localState.activeTargetIds;\n }\n\n isActiveQueryTarget(targetId: TargetId): boolean {\n return this.localState.activeTargetIds.has(targetId);\n }\n\n start(): Promise<void> {\n this.localState = new LocalClientState();\n return Promise.resolve();\n }\n\n handleUserChange(\n user: User,\n removedBatchIds: BatchId[],\n addedBatchIds: BatchId[]\n ): void {\n // No op.\n }\n\n setOnlineState(onlineState: OnlineState): void {\n // No op.\n }\n\n shutdown(): void {}\n\n writeSequenceNumber(sequenceNumber: ListenSequenceNumber): void {}\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 { Code, FirestoreError } from '../util/error';\nimport { primitiveComparator } from '../util/misc';\n\n// The earlist date supported by Firestore timestamps (0001-01-01T00:00:00Z).\nconst MIN_SECONDS = -62135596800;\n\nexport class Timestamp {\n static now(): Timestamp {\n return Timestamp.fromMillis(Date.now());\n }\n\n static fromDate(date: Date): Timestamp {\n return Timestamp.fromMillis(date.getTime());\n }\n\n static fromMillis(milliseconds: number): Timestamp {\n const seconds = Math.floor(milliseconds / 1000);\n const nanos = (milliseconds - seconds * 1000) * 1e6;\n return new Timestamp(seconds, nanos);\n }\n\n constructor(readonly seconds: number, readonly nanoseconds: number) {\n if (nanoseconds < 0) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'Timestamp nanoseconds out of range: ' + nanoseconds\n );\n }\n if (nanoseconds >= 1e9) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'Timestamp nanoseconds out of range: ' + nanoseconds\n );\n }\n if (seconds < MIN_SECONDS) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'Timestamp seconds out of range: ' + seconds\n );\n }\n // This will break in the year 10,000.\n if (seconds >= 253402300800) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'Timestamp seconds out of range: ' + seconds\n );\n }\n }\n\n toDate(): Date {\n return new Date(this.toMillis());\n }\n\n toMillis(): number {\n return this.seconds * 1000 + this.nanoseconds / 1e6;\n }\n\n _compareTo(other: Timestamp): number {\n if (this.seconds === other.seconds) {\n return primitiveComparator(this.nanoseconds, other.nanoseconds);\n }\n return primitiveComparator(this.seconds, other.seconds);\n }\n\n isEqual(other: Timestamp): boolean {\n return (\n other.seconds === this.seconds && other.nanoseconds === this.nanoseconds\n );\n }\n\n toString(): string {\n return (\n 'Timestamp(seconds=' +\n this.seconds +\n ', nanoseconds=' +\n this.nanoseconds +\n ')'\n );\n }\n\n valueOf(): string {\n // This method returns a string of the form <seconds>.<nanoseconds> where <seconds> is\n // translated to have a non-negative value and both <seconds> and <nanoseconds> are left-padded\n // with zeroes to be a consistent length. Strings with this format then have a lexiographical\n // ordering that matches the expected ordering. The <seconds> translation is done to avoid\n // having a leading negative sign (i.e. a leading '-' character) in its string representation,\n // which would affect its lexiographical ordering.\n const adjustedSeconds = this.seconds - MIN_SECONDS;\n // Note: Up to 12 decimal digits are required to represent all valid 'seconds' values.\n const formattedSeconds = String(adjustedSeconds).padStart(12, '0');\n const formattedNanoseconds = String(this.nanoseconds).padStart(9, '0');\n return formattedSeconds + '.' + formattedNanoseconds;\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 { Timestamp } from '../api/timestamp';\n\n/**\n * A version of a document in Firestore. This corresponds to the version\n * timestamp, such as update_time or read_time.\n */\nexport class SnapshotVersion {\n static fromTimestamp(value: Timestamp): SnapshotVersion {\n return new SnapshotVersion(value);\n }\n\n static min(): SnapshotVersion {\n return new SnapshotVersion(new Timestamp(0, 0));\n }\n\n private constructor(private timestamp: Timestamp) {}\n\n compareTo(other: SnapshotVersion): number {\n return this.timestamp._compareTo(other.timestamp);\n }\n\n isEqual(other: SnapshotVersion): boolean {\n return this.timestamp.isEqual(other.timestamp);\n }\n\n /** Returns a number representation of the version for use in spec tests. */\n toMicroseconds(): number {\n // Convert to microseconds.\n return this.timestamp.seconds * 1e6 + this.timestamp.nanoseconds / 1000;\n }\n\n toString(): string {\n return 'SnapshotVersion(' + this.timestamp.toString() + ')';\n }\n\n toTimestamp(): Timestamp {\n return this.timestamp;\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 { debugAssert } from './assert';\n\nexport interface Dict<V> {\n [stringKey: string]: V;\n}\n\nexport function objectSize<V>(obj: object): number {\n let count = 0;\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n count++;\n }\n }\n return count;\n}\n\nexport function forEach<V>(\n obj: Dict<V>,\n fn: (key: string, val: V) => void\n): void {\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n fn(key, obj[key]);\n }\n }\n}\n\nexport function isEmpty<V>(obj: Dict<V>): boolean {\n debugAssert(\n obj != null && typeof obj === 'object',\n 'isEmpty() expects object parameter.'\n );\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n return false;\n }\n }\n return true;\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 { PlatformSupport } from '../platform/platform';\nimport { primitiveComparator } from './misc';\n\n/**\n * Immutable class that represents a \"proto\" byte string.\n *\n * Proto byte strings can either be Base64-encoded strings or Uint8Arrays when\n * sent on the wire. This class abstracts away this differentiation by holding\n * the proto byte string in a common class that must be converted into a string\n * before being sent as a proto.\n */\nexport class ByteString {\n static readonly EMPTY_BYTE_STRING = new ByteString('');\n\n private constructor(private readonly binaryString: string) {}\n\n static fromBase64String(base64: string): ByteString {\n const binaryString = PlatformSupport.getPlatform().atob(base64);\n return new ByteString(binaryString);\n }\n\n static fromUint8Array(array: Uint8Array): ByteString {\n const binaryString = binaryStringFromUint8Array(array);\n return new ByteString(binaryString);\n }\n\n toBase64(): string {\n return PlatformSupport.getPlatform().btoa(this.binaryString);\n }\n\n toUint8Array(): Uint8Array {\n return uint8ArrayFromBinaryString(this.binaryString);\n }\n\n approximateByteSize(): number {\n return this.binaryString.length * 2;\n }\n\n compareTo(other: ByteString): number {\n return primitiveComparator(this.binaryString, other.binaryString);\n }\n\n isEqual(other: ByteString): boolean {\n return this.binaryString === other.binaryString;\n }\n}\n\n/**\n * Helper function to convert an Uint8array to a binary string.\n */\nexport function binaryStringFromUint8Array(array: Uint8Array): string {\n let binaryString = '';\n for (let i = 0; i < array.length; ++i) {\n binaryString += String.fromCharCode(array[i]);\n }\n return binaryString;\n}\n\n/**\n * Helper function to convert a binary string to an Uint8Array.\n */\nexport function uint8ArrayFromBinaryString(binaryString: string): Uint8Array {\n const buffer = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n buffer[i] = binaryString.charCodeAt(i);\n }\n return buffer;\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 * as api from '../protos/firestore_proto_api';\nimport { Timestamp } from '../api/timestamp';\nimport { normalizeTimestamp } from './values';\n\n/**\n * Represents a locally-applied ServerTimestamp.\n *\n * Server Timestamps are backed by MapValues that contain an internal field\n * `__type__` with a value of `server_timestamp`. The previous value and local\n * write time are stored in its `__previous_value__` and `__local_write_time__`\n * fields respectively.\n *\n * Notes:\n * - ServerTimestampValue instances are created as the result of applying a\n * TransformMutation (see TransformMutation.applyTo()). They can only exist in\n * the local view of a document. Therefore they do not need to be parsed or\n * serialized.\n * - When evaluated locally (e.g. for snapshot.data()), they by default\n * evaluate to `null`. This behavior can be configured by passing custom\n * FieldValueOptions to value().\n * - With respect to other ServerTimestampValues, they sort by their\n * localWriteTime.\n */\n\nconst SERVER_TIMESTAMP_SENTINEL = 'server_timestamp';\nconst TYPE_KEY = '__type__';\nconst PREVIOUS_VALUE_KEY = '__previous_value__';\nconst LOCAL_WRITE_TIME_KEY = '__local_write_time__';\n\nexport function isServerTimestamp(value: api.Value | null): boolean {\n const type = (value?.mapValue?.fields || {})[TYPE_KEY]?.stringValue;\n return type === SERVER_TIMESTAMP_SENTINEL;\n}\n\n/**\n * Creates a new ServerTimestamp proto value (using the internal format).\n */\nexport function serverTimestamp(\n localWriteTime: Timestamp,\n previousValue: api.Value | null\n): api.Value {\n const mapValue: api.MapValue = {\n fields: {\n [TYPE_KEY]: {\n stringValue: SERVER_TIMESTAMP_SENTINEL\n },\n [LOCAL_WRITE_TIME_KEY]: {\n timestampValue: {\n seconds: localWriteTime.seconds,\n nanos: localWriteTime.nanoseconds\n }\n }\n }\n };\n\n if (previousValue) {\n mapValue.fields![PREVIOUS_VALUE_KEY] = previousValue;\n }\n\n return { mapValue };\n}\n\n/**\n * Returns the value of the field before this ServerTimestamp was set.\n *\n * Preserving the previous values allows the user to display the last resoled\n * value until the backend responds with the timestamp.\n */\nexport function getPreviousValue(value: api.Value): api.Value | null {\n const previousValue = value.mapValue!.fields![PREVIOUS_VALUE_KEY];\n\n if (isServerTimestamp(previousValue)) {\n return getPreviousValue(previousValue);\n }\n return previousValue;\n}\n\n/**\n * Returns the local time at which this timestamp was first set.\n */\nexport function getLocalWriteTime(value: api.Value): Timestamp {\n const localWriteTime = normalizeTimestamp(\n value.mapValue!.fields![LOCAL_WRITE_TIME_KEY].timestampValue!\n );\n return new Timestamp(localWriteTime.seconds, localWriteTime.nanos);\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 * as api from '../protos/firestore_proto_api';\n\nimport { TypeOrder } from './object_value';\nimport { fail, hardAssert } from '../util/assert';\nimport { forEach, objectSize } from '../util/obj';\nimport { ByteString } from '../util/byte_string';\nimport { isNegativeZero } from '../util/types';\nimport { DocumentKey } from './document_key';\nimport { arrayEquals, primitiveComparator } from '../util/misc';\nimport { DatabaseId } from '../core/database_info';\nimport {\n getLocalWriteTime,\n getPreviousValue,\n isServerTimestamp\n} from './server_timestamps';\n\n// A RegExp matching ISO 8601 UTC timestamps with optional fraction.\nconst ISO_TIMESTAMP_REG_EXP = new RegExp(\n /^\\d{4}-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\d(?:\\.(\\d+))?Z$/\n);\n\n/** Extracts the backend's type order for the provided value. */\nexport function typeOrder(value: api.Value): TypeOrder {\n if ('nullValue' in value) {\n return TypeOrder.NullValue;\n } else if ('booleanValue' in value) {\n return TypeOrder.BooleanValue;\n } else if ('integerValue' in value || 'doubleValue' in value) {\n return TypeOrder.NumberValue;\n } else if ('timestampValue' in value) {\n return TypeOrder.TimestampValue;\n } else if ('stringValue' in value) {\n return TypeOrder.StringValue;\n } else if ('bytesValue' in value) {\n return TypeOrder.BlobValue;\n } else if ('referenceValue' in value) {\n return TypeOrder.RefValue;\n } else if ('geoPointValue' in value) {\n return TypeOrder.GeoPointValue;\n } else if ('arrayValue' in value) {\n return TypeOrder.ArrayValue;\n } else if ('mapValue' in value) {\n if (isServerTimestamp(value)) {\n return TypeOrder.ServerTimestampValue;\n }\n return TypeOrder.ObjectValue;\n } else {\n return fail('Invalid value type: ' + JSON.stringify(value));\n }\n}\n\n/** Tests `left` and `right` for equality based on the backend semantics. */\nexport function valueEquals(left: api.Value, right: api.Value): boolean {\n const leftType = typeOrder(left);\n const rightType = typeOrder(right);\n if (leftType !== rightType) {\n return false;\n }\n\n switch (leftType) {\n case TypeOrder.NullValue:\n return true;\n case TypeOrder.BooleanValue:\n return left.booleanValue === right.booleanValue;\n case TypeOrder.ServerTimestampValue:\n return getLocalWriteTime(left).isEqual(getLocalWriteTime(right));\n case TypeOrder.TimestampValue:\n return timestampEquals(left, right);\n case TypeOrder.StringValue:\n return left.stringValue === right.stringValue;\n case TypeOrder.BlobValue:\n return blobEquals(left, right);\n case TypeOrder.RefValue:\n return left.referenceValue === right.referenceValue;\n case TypeOrder.GeoPointValue:\n return geoPointEquals(left, right);\n case TypeOrder.NumberValue:\n return numberEquals(left, right);\n case TypeOrder.ArrayValue:\n return arrayEquals(\n left.arrayValue!.values || [],\n right.arrayValue!.values || [],\n valueEquals\n );\n case TypeOrder.ObjectValue:\n return objectEquals(left, right);\n default:\n return fail('Unexpected value type: ' + JSON.stringify(left));\n }\n}\n\nfunction timestampEquals(left: api.Value, right: api.Value): boolean {\n if (\n typeof left.timestampValue === 'string' &&\n typeof right.timestampValue === 'string' &&\n left.timestampValue.length === right.timestampValue.length\n ) {\n // Use string equality for ISO 8601 timestamps\n return left.timestampValue === right.timestampValue;\n }\n\n const leftTimestamp = normalizeTimestamp(left.timestampValue!);\n const rightTimestamp = normalizeTimestamp(right.timestampValue!);\n return (\n leftTimestamp.seconds === rightTimestamp.seconds &&\n leftTimestamp.nanos === rightTimestamp.nanos\n );\n}\n\nfunction geoPointEquals(left: api.Value, right: api.Value): boolean {\n return (\n normalizeNumber(left.geoPointValue!.latitude) ===\n normalizeNumber(right.geoPointValue!.latitude) &&\n normalizeNumber(left.geoPointValue!.longitude) ===\n normalizeNumber(right.geoPointValue!.longitude)\n );\n}\n\nfunction blobEquals(left: api.Value, right: api.Value): boolean {\n return normalizeByteString(left.bytesValue!).isEqual(\n normalizeByteString(right.bytesValue!)\n );\n}\n\nexport function numberEquals(left: api.Value, right: api.Value): boolean {\n if ('integerValue' in left && 'integerValue' in right) {\n return (\n normalizeNumber(left.integerValue) === normalizeNumber(right.integerValue)\n );\n } else if ('doubleValue' in left && 'doubleValue' in right) {\n const n1 = normalizeNumber(left.doubleValue!);\n const n2 = normalizeNumber(right.doubleValue!);\n\n if (n1 === n2) {\n return isNegativeZero(n1) === isNegativeZero(n2);\n } else {\n return isNaN(n1) && isNaN(n2);\n }\n }\n\n return false;\n}\n\nfunction objectEquals(left: api.Value, right: api.Value): boolean {\n const leftMap = left.mapValue!.fields || {};\n const rightMap = right.mapValue!.fields || {};\n\n if (objectSize(leftMap) !== objectSize(rightMap)) {\n return false;\n }\n\n for (const key in leftMap) {\n if (leftMap.hasOwnProperty(key)) {\n if (\n rightMap[key] === undefined ||\n !valueEquals(leftMap[key], rightMap[key])\n ) {\n return false;\n }\n }\n }\n return true;\n}\n\n/** Returns true if the ArrayValue contains the specified element. */\nexport function arrayValueContains(\n haystack: api.ArrayValue,\n needle: api.Value\n): boolean {\n return (\n (haystack.values || []).find(v => valueEquals(v, needle)) !== undefined\n );\n}\n\nexport function valueCompare(left: api.Value, right: api.Value): number {\n const leftType = typeOrder(left);\n const rightType = typeOrder(right);\n\n if (leftType !== rightType) {\n return primitiveComparator(leftType, rightType);\n }\n\n switch (leftType) {\n case TypeOrder.NullValue:\n return 0;\n case TypeOrder.BooleanValue:\n return primitiveComparator(left.booleanValue!, right.booleanValue!);\n case TypeOrder.NumberValue:\n return compareNumbers(left, right);\n case TypeOrder.TimestampValue:\n return compareTimestamps(left.timestampValue!, right.timestampValue!);\n case TypeOrder.ServerTimestampValue:\n return compareTimestamps(\n getLocalWriteTime(left),\n getLocalWriteTime(right)\n );\n case TypeOrder.StringValue:\n return primitiveComparator(left.stringValue!, right.stringValue!);\n case TypeOrder.BlobValue:\n return compareBlobs(left.bytesValue!, right.bytesValue!);\n case TypeOrder.RefValue:\n return compareReferences(left.referenceValue!, right.referenceValue!);\n case TypeOrder.GeoPointValue:\n return compareGeoPoints(left.geoPointValue!, right.geoPointValue!);\n case TypeOrder.ArrayValue:\n return compareArrays(left.arrayValue!, right.arrayValue!);\n case TypeOrder.ObjectValue:\n return compareMaps(left.mapValue!, right.mapValue!);\n default:\n throw fail('Invalid value type: ' + leftType);\n }\n}\n\nfunction compareNumbers(left: api.Value, right: api.Value): number {\n const leftNumber = normalizeNumber(left.integerValue || left.doubleValue);\n const rightNumber = normalizeNumber(right.integerValue || right.doubleValue);\n\n if (leftNumber < rightNumber) {\n return -1;\n } else if (leftNumber > rightNumber) {\n return 1;\n } else if (leftNumber === rightNumber) {\n return 0;\n } else {\n // one or both are NaN.\n if (isNaN(leftNumber)) {\n return isNaN(rightNumber) ? 0 : -1;\n } else {\n return 1;\n }\n }\n}\n\nfunction compareTimestamps(left: api.Timestamp, right: api.Timestamp): number {\n if (\n typeof left === 'string' &&\n typeof right === 'string' &&\n left.length === right.length\n ) {\n return primitiveComparator(left, right);\n }\n\n const leftTimestamp = normalizeTimestamp(left);\n const rightTimestamp = normalizeTimestamp(right);\n\n const comparison = primitiveComparator(\n leftTimestamp.seconds,\n rightTimestamp.seconds\n );\n if (comparison !== 0) {\n return comparison;\n }\n return primitiveComparator(leftTimestamp.nanos, rightTimestamp.nanos);\n}\n\nfunction compareReferences(leftPath: string, rightPath: string): number {\n const leftSegments = leftPath.split('/');\n const rightSegments = rightPath.split('/');\n for (let i = 0; i < leftSegments.length && i < rightSegments.length; i++) {\n const comparison = primitiveComparator(leftSegments[i], rightSegments[i]);\n if (comparison !== 0) {\n return comparison;\n }\n }\n return primitiveComparator(leftSegments.length, rightSegments.length);\n}\n\nfunction compareGeoPoints(left: api.LatLng, right: api.LatLng): number {\n const comparison = primitiveComparator(\n normalizeNumber(left.latitude),\n normalizeNumber(right.latitude)\n );\n if (comparison !== 0) {\n return comparison;\n }\n return primitiveComparator(\n normalizeNumber(left.longitude),\n normalizeNumber(right.longitude)\n );\n}\n\nfunction compareBlobs(\n left: string | Uint8Array,\n right: string | Uint8Array\n): number {\n const leftBytes = normalizeByteString(left);\n const rightBytes = normalizeByteString(right);\n return leftBytes.compareTo(rightBytes);\n}\n\nfunction compareArrays(left: api.ArrayValue, right: api.ArrayValue): number {\n const leftArray = left.values || [];\n const rightArray = right.values || [];\n\n for (let i = 0; i < leftArray.length && i < rightArray.length; ++i) {\n const compare = valueCompare(leftArray[i], rightArray[i]);\n if (compare) {\n return compare;\n }\n }\n return primitiveComparator(leftArray.length, rightArray.length);\n}\n\nfunction compareMaps(left: api.MapValue, right: api.MapValue): number {\n const leftMap = left.fields || {};\n const leftKeys = Object.keys(leftMap);\n const rightMap = right.fields || {};\n const rightKeys = Object.keys(rightMap);\n\n // Even though MapValues are likely sorted correctly based on their insertion\n // order (e.g. when received from the backend), local modifications can bring\n // elements out of order. We need to re-sort the elements to ensure that\n // canonical IDs are independent of insertion order.\n leftKeys.sort();\n rightKeys.sort();\n\n for (let i = 0; i < leftKeys.length && i < rightKeys.length; ++i) {\n const keyCompare = primitiveComparator(leftKeys[i], rightKeys[i]);\n if (keyCompare !== 0) {\n return keyCompare;\n }\n const compare = valueCompare(leftMap[leftKeys[i]], rightMap[rightKeys[i]]);\n if (compare !== 0) {\n return compare;\n }\n }\n\n return primitiveComparator(leftKeys.length, rightKeys.length);\n}\n\n/**\n * Generates the canonical ID for the provided field value (as used in Target\n * serialization).\n */\nexport function canonicalId(value: api.Value): string {\n return canonifyValue(value);\n}\n\nfunction canonifyValue(value: api.Value): string {\n if ('nullValue' in value) {\n return 'null';\n } else if ('booleanValue' in value) {\n return '' + value.booleanValue!;\n } else if ('integerValue' in value) {\n return '' + value.integerValue!;\n } else if ('doubleValue' in value) {\n return '' + value.doubleValue!;\n } else if ('timestampValue' in value) {\n return canonifyTimestamp(value.timestampValue!);\n } else if ('stringValue' in value) {\n return value.stringValue!;\n } else if ('bytesValue' in value) {\n return canonifyByteString(value.bytesValue!);\n } else if ('referenceValue' in value) {\n return canonifyReference(value.referenceValue!);\n } else if ('geoPointValue' in value) {\n return canonifyGeoPoint(value.geoPointValue!);\n } else if ('arrayValue' in value) {\n return canonifyArray(value.arrayValue!);\n } else if ('mapValue' in value) {\n return canonifyMap(value.mapValue!);\n } else {\n return fail('Invalid value type: ' + JSON.stringify(value));\n }\n}\n\nfunction canonifyByteString(byteString: string | Uint8Array): string {\n return normalizeByteString(byteString).toBase64();\n}\n\nfunction canonifyTimestamp(timestamp: api.Timestamp): string {\n const normalizedTimestamp = normalizeTimestamp(timestamp);\n return `time(${normalizedTimestamp.seconds},${normalizedTimestamp.nanos})`;\n}\n\nfunction canonifyGeoPoint(geoPoint: api.LatLng): string {\n return `geo(${geoPoint.latitude},${geoPoint.longitude})`;\n}\n\nfunction canonifyReference(referenceValue: string): string {\n return DocumentKey.fromName(referenceValue).toString();\n}\n\nfunction canonifyMap(mapValue: api.MapValue): string {\n // Iteration order in JavaScript is not guaranteed. To ensure that we generate\n // matching canonical IDs for identical maps, we need to sort the keys.\n const sortedKeys = Object.keys(mapValue.fields || {}).sort();\n\n let result = '{';\n let first = true;\n for (const key of sortedKeys) {\n if (!first) {\n result += ',';\n } else {\n first = false;\n }\n result += `${key}:${canonifyValue(mapValue.fields![key])}`;\n }\n return result + '}';\n}\n\nfunction canonifyArray(arrayValue: api.ArrayValue): string {\n let result = '[';\n let first = true;\n for (const value of arrayValue.values || []) {\n if (!first) {\n result += ',';\n } else {\n first = false;\n }\n result += canonifyValue(value);\n }\n return result + ']';\n}\n\n/**\n * Returns an approximate (and wildly inaccurate) in-memory size for the field\n * value.\n *\n * The memory size takes into account only the actual user data as it resides\n * in memory and ignores object overhead.\n */\nexport function estimateByteSize(value: api.Value): number {\n switch (typeOrder(value)) {\n case TypeOrder.NullValue:\n return 4;\n case TypeOrder.BooleanValue:\n return 4;\n case TypeOrder.NumberValue:\n return 8;\n case TypeOrder.TimestampValue:\n // Timestamps are made up of two distinct numbers (seconds + nanoseconds)\n return 16;\n case TypeOrder.ServerTimestampValue:\n const previousValue = getPreviousValue(value);\n return previousValue ? 16 + estimateByteSize(previousValue) : 16;\n case TypeOrder.StringValue:\n // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures:\n // \"JavaScript's String type is [...] a set of elements of 16-bit unsigned\n // integer values\"\n return value.stringValue!.length * 2;\n case TypeOrder.BlobValue:\n return normalizeByteString(value.bytesValue!).approximateByteSize();\n case TypeOrder.RefValue:\n return value.referenceValue!.length;\n case TypeOrder.GeoPointValue:\n // GeoPoints are made up of two distinct numbers (latitude + longitude)\n return 16;\n case TypeOrder.ArrayValue:\n return estimateArrayByteSize(value.arrayValue!);\n case TypeOrder.ObjectValue:\n return estimateMapByteSize(value.mapValue!);\n default:\n throw fail('Invalid value type: ' + JSON.stringify(value));\n }\n}\n\nfunction estimateMapByteSize(mapValue: api.MapValue): number {\n let size = 0;\n forEach(mapValue.fields || {}, (key, val) => {\n size += key.length + estimateByteSize(val);\n });\n return size;\n}\n\nfunction estimateArrayByteSize(arrayValue: api.ArrayValue): number {\n return (arrayValue.values || []).reduce(\n (previousSize, value) => previousSize + estimateByteSize(value),\n 0\n );\n}\n\n/**\n * Converts the possible Proto values for a timestamp value into a \"seconds and\n * nanos\" representation.\n */\nexport function normalizeTimestamp(\n date: api.Timestamp\n): { seconds: number; nanos: number } {\n hardAssert(!!date, 'Cannot normalize null or undefined timestamp.');\n\n // The json interface (for the browser) will return an iso timestamp string,\n // while the proto js library (for node) will return a\n // google.protobuf.Timestamp instance.\n if (typeof date === 'string') {\n // The date string can have higher precision (nanos) than the Date class\n // (millis), so we do some custom parsing here.\n\n // Parse the nanos right out of the string.\n let nanos = 0;\n const fraction = ISO_TIMESTAMP_REG_EXP.exec(date);\n hardAssert(!!fraction, 'invalid timestamp: ' + date);\n if (fraction[1]) {\n // Pad the fraction out to 9 digits (nanos).\n let nanoStr = fraction[1];\n nanoStr = (nanoStr + '000000000').substr(0, 9);\n nanos = Number(nanoStr);\n }\n\n // Parse the date to get the seconds.\n const parsedDate = new Date(date);\n const seconds = Math.floor(parsedDate.getTime() / 1000);\n\n return { seconds, nanos };\n } else {\n // TODO(b/37282237): Use strings for Proto3 timestamps\n // assert(!this.options.useProto3Json,\n // 'The timestamp instance format requires Proto JS.');\n const seconds = normalizeNumber(date.seconds);\n const nanos = normalizeNumber(date.nanos);\n return { seconds, nanos };\n }\n}\n\n/**\n * Converts the possible Proto types for numbers into a JavaScript number.\n * Returns 0 if the value is not numeric.\n */\nexport function normalizeNumber(value: number | string | undefined): number {\n // TODO(bjornick): Handle int64 greater than 53 bits.\n if (typeof value === 'number') {\n return value;\n } else if (typeof value === 'string') {\n return Number(value);\n } else {\n return 0;\n }\n}\n\n/** Converts the possible Proto types for Blobs into a ByteString. */\nexport function normalizeByteString(blob: string | Uint8Array): ByteString {\n if (typeof blob === 'string') {\n return ByteString.fromBase64String(blob);\n } else {\n return ByteString.fromUint8Array(blob);\n }\n}\n\n/** Returns a reference value for the provided database and key. */\nexport function refValue(databaseId: DatabaseId, key: DocumentKey): api.Value {\n return {\n referenceValue: `projects/${databaseId.projectId}/databases/${\n databaseId.database\n }/documents/${key.path.canonicalString()}`\n };\n}\n\n/** Returns true if `value` is an IntegerValue . */\nexport function isInteger(\n value?: api.Value | null\n): value is { integerValue: string | number } {\n return !!value && 'integerValue' in value;\n}\n\n/** Returns true if `value` is a DoubleValue. */\nexport function isDouble(\n value?: api.Value | null\n): value is { doubleValue: string | number } {\n return !!value && 'doubleValue' in value;\n}\n\n/** Returns true if `value` is either an IntegerValue or a DoubleValue. */\nexport function isNumber(value?: api.Value | null): boolean {\n return isInteger(value) || isDouble(value);\n}\n\n/** Returns true if `value` is an ArrayValue. */\nexport function isArray(\n value?: api.Value | null\n): value is { arrayValue: api.ArrayValue } {\n return !!value && 'arrayValue' in value;\n}\n\n/** Returns true if `value` is a ReferenceValue. */\nexport function isReferenceValue(\n value?: api.Value | null\n): value is { referenceValue: string } {\n return !!value && 'referenceValue' in value;\n}\n\n/** Returns true if `value` is a NullValue. */\nexport function isNullValue(\n value?: api.Value | null\n): value is { nullValue: 'NULL_VALUE' } {\n return !!value && 'nullValue' in value;\n}\n\n/** Returns true if `value` is NaN. */\nexport function isNanValue(\n value?: api.Value | null\n): value is { doubleValue: 'NaN' | number } {\n return !!value && 'doubleValue' in value && isNaN(Number(value.doubleValue));\n}\n\n/** Returns true if `value` is a MapValue. */\nexport function isMapValue(\n value?: api.Value | null\n): value is { mapValue: api.MapValue } {\n return !!value && 'mapValue' in value;\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 * as api from '../protos/firestore_proto_api';\n\nimport { SnapshotVersion } from '../core/snapshot_version';\nimport { fail } from '../util/assert';\n\nimport { DocumentKey } from './document_key';\nimport { ObjectValue } from './object_value';\nimport { FieldPath } from './path';\nimport { valueCompare } from './values';\n\nexport interface DocumentOptions {\n hasLocalMutations?: boolean;\n hasCommittedMutations?: boolean;\n}\n\n/**\n * The result of a lookup for a given path may be an existing document or a\n * marker that this document does not exist at a given version.\n */\nexport abstract class MaybeDocument {\n constructor(readonly key: DocumentKey, readonly version: SnapshotVersion) {}\n\n /**\n * Whether this document had a local mutation applied that has not yet been\n * acknowledged by Watch.\n */\n abstract get hasPendingWrites(): boolean;\n\n abstract isEqual(other: MaybeDocument | null | undefined): boolean;\n\n abstract toString(): string;\n}\n\n/**\n * Represents a document in Firestore with a key, version, data and whether the\n * data has local mutations applied to it.\n */\nexport class Document extends MaybeDocument {\n readonly hasLocalMutations: boolean;\n readonly hasCommittedMutations: boolean;\n\n constructor(\n key: DocumentKey,\n version: SnapshotVersion,\n private readonly objectValue: ObjectValue,\n options: DocumentOptions\n ) {\n super(key, version);\n this.hasLocalMutations = !!options.hasLocalMutations;\n this.hasCommittedMutations = !!options.hasCommittedMutations;\n }\n\n field(path: FieldPath): api.Value | null {\n return this.objectValue.field(path);\n }\n\n data(): ObjectValue {\n return this.objectValue;\n }\n\n toProto(): { mapValue: api.MapValue } {\n return this.objectValue.proto;\n }\n\n isEqual(other: MaybeDocument | null | undefined): boolean {\n return (\n other instanceof Document &&\n this.key.isEqual(other.key) &&\n this.version.isEqual(other.version) &&\n this.hasLocalMutations === other.hasLocalMutations &&\n this.hasCommittedMutations === other.hasCommittedMutations &&\n this.objectValue.isEqual(other.objectValue)\n );\n }\n\n toString(): string {\n return (\n `Document(${this.key}, ${\n this.version\n }, ${this.objectValue.toString()}, ` +\n `{hasLocalMutations: ${this.hasLocalMutations}}), ` +\n `{hasCommittedMutations: ${this.hasCommittedMutations}})`\n );\n }\n\n get hasPendingWrites(): boolean {\n return this.hasLocalMutations || this.hasCommittedMutations;\n }\n}\n\n/**\n * Compares the value for field `field` in the provided documents. Throws if\n * the field does not exist in both documents.\n */\nexport function compareDocumentsByField(\n field: FieldPath,\n d1: Document,\n d2: Document\n): number {\n const v1 = d1.field(field);\n const v2 = d2.field(field);\n if (v1 !== null && v2 !== null) {\n return valueCompare(v1, v2);\n } else {\n return fail(\"Trying to compare documents on fields that don't exist\");\n }\n}\n\n/**\n * A class representing a deleted document.\n * Version is set to 0 if we don't point to any specific time, otherwise it\n * denotes time we know it didn't exist at.\n */\nexport class NoDocument extends MaybeDocument {\n readonly hasCommittedMutations: boolean;\n\n constructor(\n key: DocumentKey,\n version: SnapshotVersion,\n options?: DocumentOptions\n ) {\n super(key, version);\n this.hasCommittedMutations = !!(options && options.hasCommittedMutations);\n }\n\n toString(): string {\n return `NoDocument(${this.key}, ${this.version})`;\n }\n\n get hasPendingWrites(): boolean {\n return this.hasCommittedMutations;\n }\n\n isEqual(other: MaybeDocument | null | undefined): boolean {\n return (\n other instanceof NoDocument &&\n other.hasCommittedMutations === this.hasCommittedMutations &&\n other.version.isEqual(this.version) &&\n other.key.isEqual(this.key)\n );\n }\n}\n\n/**\n * A class representing an existing document whose data is unknown (e.g. a\n * document that was updated without a known base document).\n */\nexport class UnknownDocument extends MaybeDocument {\n toString(): string {\n return `UnknownDocument(${this.key}, ${this.version})`;\n }\n\n get hasPendingWrites(): boolean {\n return true;\n }\n\n isEqual(other: MaybeDocument | null | undefined): boolean {\n return (\n other instanceof UnknownDocument &&\n other.version.isEqual(this.version) &&\n other.key.isEqual(this.key)\n );\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 * as api from '../protos/firestore_proto_api';\n\nimport { debugAssert } from '../util/assert';\nimport { FieldMask } from './mutation';\nimport { FieldPath } from './path';\nimport { isServerTimestamp } from './server_timestamps';\nimport { valueEquals, isMapValue, typeOrder } from './values';\nimport { forEach } from '../util/obj';\n\nexport interface JsonObject<T> {\n [name: string]: T;\n}\n\nexport const enum TypeOrder {\n // This order is based on the backend's ordering, but modified to support\n // server timestamps.\n NullValue = 0,\n BooleanValue = 1,\n NumberValue = 2,\n TimestampValue = 3,\n ServerTimestampValue = 4,\n StringValue = 5,\n BlobValue = 6,\n RefValue = 7,\n GeoPointValue = 8,\n ArrayValue = 9,\n ObjectValue = 10\n}\n\n/**\n * An ObjectValue represents a MapValue in the Firestore Proto and offers the\n * ability to add and remove fields (via the ObjectValueBuilder).\n */\nexport class ObjectValue {\n constructor(public readonly proto: { mapValue: api.MapValue }) {\n debugAssert(\n !isServerTimestamp(proto),\n 'ServerTimestamps should be converted to ServerTimestampValue'\n );\n }\n\n static empty(): ObjectValue {\n return new ObjectValue({ mapValue: {} });\n }\n\n /**\n * Returns the value at the given path or null.\n *\n * @param path the path to search\n * @return The value at the path or if there it doesn't exist.\n */\n field(path: FieldPath): api.Value | null {\n if (path.isEmpty()) {\n return this.proto;\n } else {\n let value: api.Value = this.proto;\n for (let i = 0; i < path.length - 1; ++i) {\n if (!value.mapValue!.fields) {\n return null;\n }\n value = value.mapValue!.fields[path.get(i)];\n if (!isMapValue(value)) {\n return null;\n }\n }\n\n value = (value.mapValue!.fields || {})[path.lastSegment()];\n return value || null;\n }\n }\n\n isEqual(other: ObjectValue): boolean {\n return valueEquals(this.proto, other.proto);\n }\n}\n\n/**\n * An Overlay, which contains an update to apply. Can either be Value proto, a\n * map of Overlay values (to represent additional nesting at the given key) or\n * `null` (to represent field deletes).\n */\ntype Overlay = Map<string, Overlay> | api.Value | null;\n\n/**\n * An ObjectValueBuilder provides APIs to set and delete fields from an\n * ObjectValue.\n */\nexport class ObjectValueBuilder {\n /** A map that contains the accumulated changes in this builder. */\n private overlayMap = new Map<string, Overlay>();\n\n /**\n * @param baseObject The object to mutate.\n */\n constructor(private readonly baseObject: ObjectValue = ObjectValue.empty()) {}\n\n /**\n * Sets the field to the provided value.\n *\n * @param path The field path to set.\n * @param value The value to set.\n * @return The current Builder instance.\n */\n set(path: FieldPath, value: api.Value): ObjectValueBuilder {\n debugAssert(\n !path.isEmpty(),\n 'Cannot set field for empty path on ObjectValue'\n );\n this.setOverlay(path, value);\n return this;\n }\n\n /**\n * Removes the field at the specified path. If there is no field at the\n * specified path, nothing is changed.\n *\n * @param path The field path to remove.\n * @return The current Builder instance.\n */\n delete(path: FieldPath): ObjectValueBuilder {\n debugAssert(\n !path.isEmpty(),\n 'Cannot delete field for empty path on ObjectValue'\n );\n this.setOverlay(path, null);\n return this;\n }\n\n /**\n * Adds `value` to the overlay map at `path`. Creates nested map entries if\n * needed.\n */\n private setOverlay(path: FieldPath, value: api.Value | null): void {\n let currentLevel = this.overlayMap;\n\n for (let i = 0; i < path.length - 1; ++i) {\n const currentSegment = path.get(i);\n let currentValue = currentLevel.get(currentSegment);\n\n if (currentValue instanceof Map) {\n // Re-use a previously created map\n currentLevel = currentValue;\n } else if (\n currentValue &&\n typeOrder(currentValue) === TypeOrder.ObjectValue\n ) {\n // Convert the existing Protobuf MapValue into a map\n currentValue = new Map<string, Overlay>(\n Object.entries(currentValue.mapValue!.fields || {})\n );\n currentLevel.set(currentSegment, currentValue);\n currentLevel = currentValue;\n } else {\n // Create an empty map to represent the current nesting level\n currentValue = new Map<string, Overlay>();\n currentLevel.set(currentSegment, currentValue);\n currentLevel = currentValue;\n }\n }\n\n currentLevel.set(path.lastSegment(), value);\n }\n\n /** Returns an ObjectValue with all mutations applied. */\n build(): ObjectValue {\n const mergedResult = this.applyOverlay(\n FieldPath.EMPTY_PATH,\n this.overlayMap\n );\n if (mergedResult != null) {\n return new ObjectValue(mergedResult);\n } else {\n return this.baseObject;\n }\n }\n\n /**\n * Applies any overlays from `currentOverlays` that exist at `currentPath`\n * and returns the merged data at `currentPath` (or null if there were no\n * changes).\n *\n * @param currentPath The path at the current nesting level. Can be set to\n * FieldValue.EMPTY_PATH to represent the root.\n * @param currentOverlays The overlays at the current nesting level in the\n * same format as `overlayMap`.\n * @return The merged data at `currentPath` or null if no modifications\n * were applied.\n */\n private applyOverlay(\n currentPath: FieldPath,\n currentOverlays: Map<string, Overlay>\n ): { mapValue: api.MapValue } | null {\n let modified = false;\n\n const existingValue = this.baseObject.field(currentPath);\n const resultAtPath = isMapValue(existingValue)\n ? // If there is already data at the current path, base our\n // modifications on top of the existing data.\n { ...existingValue.mapValue.fields }\n : {};\n\n currentOverlays.forEach((value, pathSegment) => {\n if (value instanceof Map) {\n const nested = this.applyOverlay(currentPath.child(pathSegment), value);\n if (nested != null) {\n resultAtPath[pathSegment] = nested;\n modified = true;\n }\n } else if (value !== null) {\n resultAtPath[pathSegment] = value;\n modified = true;\n } else if (resultAtPath.hasOwnProperty(pathSegment)) {\n delete resultAtPath[pathSegment];\n modified = true;\n }\n });\n\n return modified ? { mapValue: { fields: resultAtPath } } : null;\n }\n}\n\n/**\n * Returns a FieldMask built from all fields in a MapValue.\n */\nexport function extractFieldMask(value: api.MapValue): FieldMask {\n const fields: FieldPath[] = [];\n forEach(value!.fields || {}, (key, value) => {\n const currentPath = new FieldPath([key]);\n if (isMapValue(value)) {\n const nestedMask = extractFieldMask(value.mapValue!);\n const nestedFields = nestedMask.fields;\n if (nestedFields.length === 0) {\n // Preserve the empty map by adding it to the FieldMask.\n fields.push(currentPath);\n } else {\n // For nested and non-empty ObjectValues, add the FieldPath of the\n // leaf nodes.\n for (const nestedPath of nestedFields) {\n fields.push(currentPath.child(nestedPath));\n }\n }\n } else {\n // For nested and non-empty ObjectValues, add the FieldPath of the leaf\n // nodes.\n fields.push(currentPath);\n }\n });\n return new FieldMask(fields);\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 * as api from '../protos/firestore_proto_api';\n\nimport { Timestamp } from '../api/timestamp';\nimport { SnapshotVersion } from '../core/snapshot_version';\nimport { debugAssert, fail, hardAssert } from '../util/assert';\n\nimport {\n Document,\n MaybeDocument,\n NoDocument,\n UnknownDocument\n} from './document';\nimport { DocumentKey } from './document_key';\nimport { ObjectValue, ObjectValueBuilder } from './object_value';\nimport { FieldPath } from './path';\nimport { TransformOperation } from './transform_operation';\nimport { arrayEquals } from '../util/misc';\n\n/**\n * Provides a set of fields that can be used to partially patch a document.\n * FieldMask is used in conjunction with ObjectValue.\n * Examples:\n * foo - Overwrites foo entirely with the provided value. If foo is not\n * present in the companion ObjectValue, the field is deleted.\n * foo.bar - Overwrites only the field bar of the object foo.\n * If foo is not an object, foo is replaced with an object\n * containing foo\n */\nexport class FieldMask {\n constructor(readonly fields: FieldPath[]) {\n // TODO(dimond): validation of FieldMask\n // Sort the field mask to support `FieldMask.isEqual()` and assert below.\n fields.sort(FieldPath.comparator);\n debugAssert(\n !fields.some((v, i) => i !== 0 && v.isEqual(fields[i - 1])),\n 'FieldMask contains field that is not unique: ' +\n fields.find((v, i) => i !== 0 && v.isEqual(fields[i - 1]))!\n );\n }\n\n /**\n * Verifies that `fieldPath` is included by at least one field in this field\n * mask.\n *\n * This is an O(n) operation, where `n` is the size of the field mask.\n */\n covers(fieldPath: FieldPath): boolean {\n for (const fieldMaskPath of this.fields) {\n if (fieldMaskPath.isPrefixOf(fieldPath)) {\n return true;\n }\n }\n return false;\n }\n\n isEqual(other: FieldMask): boolean {\n return arrayEquals(this.fields, other.fields, (l, r) => l.isEqual(r));\n }\n}\n\n/** A field path and the TransformOperation to perform upon it. */\nexport class FieldTransform {\n constructor(\n readonly field: FieldPath,\n readonly transform: TransformOperation\n ) {}\n\n isEqual(other: FieldTransform): boolean {\n return (\n this.field.isEqual(other.field) && this.transform.isEqual(other.transform)\n );\n }\n}\n\n/** The result of successfully applying a mutation to the backend. */\nexport class MutationResult {\n constructor(\n /**\n * The version at which the mutation was committed:\n *\n * - For most operations, this is the updateTime in the WriteResult.\n * - For deletes, the commitTime of the WriteResponse (because deletes are\n * not stored and have no updateTime).\n *\n * Note that these versions can be different: No-op writes will not change\n * the updateTime even though the commitTime advances.\n */\n readonly version: SnapshotVersion,\n /**\n * The resulting fields returned from the backend after a\n * TransformMutation has been committed. Contains one FieldValue for each\n * FieldTransform that was in the mutation.\n *\n * Will be null if the mutation was not a TransformMutation.\n */\n readonly transformResults: Array<api.Value | null> | null\n ) {}\n}\n\nexport const enum MutationType {\n Set,\n Patch,\n Transform,\n Delete,\n Verify\n}\n\n/**\n * Encodes a precondition for a mutation. This follows the model that the\n * backend accepts with the special case of an explicit \"empty\" precondition\n * (meaning no precondition).\n */\nexport class Precondition {\n private constructor(\n readonly updateTime?: SnapshotVersion,\n readonly exists?: boolean\n ) {\n debugAssert(\n updateTime === undefined || exists === undefined,\n 'Precondition can specify \"exists\" or \"updateTime\" but not both'\n );\n }\n\n /** Creates a new empty Precondition. */\n static none(): Precondition {\n return new Precondition();\n }\n\n /** Creates a new Precondition with an exists flag. */\n static exists(exists: boolean): Precondition {\n return new Precondition(undefined, exists);\n }\n\n /** Creates a new Precondition based on a version a document exists at. */\n static updateTime(version: SnapshotVersion): Precondition {\n return new Precondition(version);\n }\n\n /** Returns whether this Precondition is empty. */\n get isNone(): boolean {\n return this.updateTime === undefined && this.exists === undefined;\n }\n\n /**\n * Returns true if the preconditions is valid for the given document\n * (or null if no document is available).\n */\n isValidFor(maybeDoc: MaybeDocument | null): boolean {\n if (this.updateTime !== undefined) {\n return (\n maybeDoc instanceof Document &&\n maybeDoc.version.isEqual(this.updateTime)\n );\n } else if (this.exists !== undefined) {\n return this.exists === maybeDoc instanceof Document;\n } else {\n debugAssert(this.isNone, 'Precondition should be empty');\n return true;\n }\n }\n\n isEqual(other: Precondition): boolean {\n return (\n this.exists === other.exists &&\n (this.updateTime\n ? !!other.updateTime && this.updateTime.isEqual(other.updateTime)\n : !other.updateTime)\n );\n }\n}\n\n/**\n * A mutation describes a self-contained change to a document. Mutations can\n * create, replace, delete, and update subsets of documents.\n *\n * Mutations not only act on the value of the document but also its version.\n *\n * For local mutations (mutations that haven't been committed yet), we preserve\n * the existing version for Set, Patch, and Transform mutations. For Delete\n * mutations, we reset the version to 0.\n *\n * Here's the expected transition table.\n *\n * MUTATION APPLIED TO RESULTS IN\n *\n * SetMutation Document(v3) Document(v3)\n * SetMutation NoDocument(v3) Document(v0)\n * SetMutation null Document(v0)\n * PatchMutation Document(v3) Document(v3)\n * PatchMutation NoDocument(v3) NoDocument(v3)\n * PatchMutation null null\n * TransformMutation Document(v3) Document(v3)\n * TransformMutation NoDocument(v3) NoDocument(v3)\n * TransformMutation null null\n * DeleteMutation Document(v3) NoDocument(v0)\n * DeleteMutation NoDocument(v3) NoDocument(v0)\n * DeleteMutation null NoDocument(v0)\n *\n * For acknowledged mutations, we use the updateTime of the WriteResponse as\n * the resulting version for Set, Patch, and Transform mutations. As deletes\n * have no explicit update time, we use the commitTime of the WriteResponse for\n * Delete mutations.\n *\n * If a mutation is acknowledged by the backend but fails the precondition check\n * locally, we return an `UnknownDocument` and rely on Watch to send us the\n * updated version.\n *\n * Note that TransformMutations don't create Documents (in the case of being\n * applied to a NoDocument), even though they would on the backend. This is\n * because the client always combines the TransformMutation with a SetMutation\n * or PatchMutation and we only want to apply the transform if the prior\n * mutation resulted in a Document (always true for a SetMutation, but not\n * necessarily for a PatchMutation).\n *\n * ## Subclassing Notes\n *\n * Subclasses of Mutation need to implement applyToRemoteDocument() and\n * applyToLocalView() to implement the actual behavior of applying the mutation\n * to some source document.\n */\nexport abstract class Mutation {\n abstract readonly type: MutationType;\n abstract readonly key: DocumentKey;\n abstract readonly precondition: Precondition;\n\n /**\n * Applies this mutation to the given MaybeDocument or null for the purposes\n * of computing a new remote document. If the input document doesn't match the\n * expected state (e.g. it is null or outdated), an `UnknownDocument` can be\n * returned.\n *\n * @param maybeDoc The document to mutate. The input document can be null if\n * the client has no knowledge of the pre-mutation state of the document.\n * @param mutationResult The result of applying the mutation from the backend.\n * @return The mutated document. The returned document may be an\n * UnknownDocument if the mutation could not be applied to the locally\n * cached base document.\n */\n abstract applyToRemoteDocument(\n maybeDoc: MaybeDocument | null,\n mutationResult: MutationResult\n ): MaybeDocument;\n\n /**\n * Applies this mutation to the given MaybeDocument or null for the purposes\n * of computing the new local view of a document. Both the input and returned\n * documents can be null.\n *\n * @param maybeDoc The document to mutate. The input document can be null if\n * the client has no knowledge of the pre-mutation state of the document.\n * @param baseDoc The state of the document prior to this mutation batch. The\n * input document can be null if the client has no knowledge of the\n * pre-mutation state of the document.\n * @param localWriteTime A timestamp indicating the local write time of the\n * batch this mutation is a part of.\n * @return The mutated document. The returned document may be null, but only\n * if maybeDoc was null and the mutation would not create a new document.\n */\n abstract applyToLocalView(\n maybeDoc: MaybeDocument | null,\n baseDoc: MaybeDocument | null,\n localWriteTime: Timestamp\n ): MaybeDocument | null;\n\n /**\n * If this mutation is not idempotent, returns the base value to persist with\n * this mutation. If a base value is returned, the mutation is always applied\n * to this base value, even if document has already been updated.\n *\n * The base value is a sparse object that consists of only the document\n * fields for which this mutation contains a non-idempotent transformation\n * (e.g. a numeric increment). The provided value guarantees consistent\n * behavior for non-idempotent transforms and allow us to return the same\n * latency-compensated value even if the backend has already applied the\n * mutation. The base value is null for idempotent mutations, as they can be\n * re-played even if the backend has already applied them.\n *\n * @return a base value to store along with the mutation, or null for\n * idempotent mutations.\n */\n abstract extractBaseValue(maybeDoc: MaybeDocument | null): ObjectValue | null;\n\n abstract isEqual(other: Mutation): boolean;\n\n protected verifyKeyMatches(maybeDoc: MaybeDocument | null): void {\n if (maybeDoc != null) {\n debugAssert(\n maybeDoc.key.isEqual(this.key),\n 'Can only apply a mutation to a document with the same key'\n );\n }\n }\n\n /**\n * Returns the version from the given document for use as the result of a\n * mutation. Mutations are defined to return the version of the base document\n * only if it is an existing document. Deleted and unknown documents have a\n * post-mutation version of SnapshotVersion.min().\n */\n protected static getPostMutationVersion(\n maybeDoc: MaybeDocument | null\n ): SnapshotVersion {\n if (maybeDoc instanceof Document) {\n return maybeDoc.version;\n } else {\n return SnapshotVersion.min();\n }\n }\n}\n\n/**\n * A mutation that creates or replaces the document at the given key with the\n * object value contents.\n */\nexport class SetMutation extends Mutation {\n constructor(\n readonly key: DocumentKey,\n readonly value: ObjectValue,\n readonly precondition: Precondition\n ) {\n super();\n }\n\n readonly type: MutationType = MutationType.Set;\n\n applyToRemoteDocument(\n maybeDoc: MaybeDocument | null,\n mutationResult: MutationResult\n ): MaybeDocument {\n this.verifyKeyMatches(maybeDoc);\n\n debugAssert(\n mutationResult.transformResults == null,\n 'Transform results received by SetMutation.'\n );\n\n // Unlike applyToLocalView, if we're applying a mutation to a remote\n // document the server has accepted the mutation so the precondition must\n // have held.\n\n const version = mutationResult.version;\n return new Document(this.key, version, this.value, {\n hasCommittedMutations: true\n });\n }\n\n applyToLocalView(\n maybeDoc: MaybeDocument | null,\n baseDoc: MaybeDocument | null,\n localWriteTime: Timestamp\n ): MaybeDocument | null {\n this.verifyKeyMatches(maybeDoc);\n\n if (!this.precondition.isValidFor(maybeDoc)) {\n return maybeDoc;\n }\n\n const version = Mutation.getPostMutationVersion(maybeDoc);\n return new Document(this.key, version, this.value, {\n hasLocalMutations: true\n });\n }\n\n extractBaseValue(maybeDoc: MaybeDocument | null): null {\n return null;\n }\n\n isEqual(other: Mutation): boolean {\n return (\n other instanceof SetMutation &&\n this.key.isEqual(other.key) &&\n this.value.isEqual(other.value) &&\n this.precondition.isEqual(other.precondition)\n );\n }\n}\n\n/**\n * A mutation that modifies fields of the document at the given key with the\n * given values. The values are applied through a field mask:\n *\n * * When a field is in both the mask and the values, the corresponding field\n * is updated.\n * * When a field is in neither the mask nor the values, the corresponding\n * field is unmodified.\n * * When a field is in the mask but not in the values, the corresponding field\n * is deleted.\n * * When a field is not in the mask but is in the values, the values map is\n * ignored.\n */\nexport class PatchMutation extends Mutation {\n constructor(\n readonly key: DocumentKey,\n readonly data: ObjectValue,\n readonly fieldMask: FieldMask,\n readonly precondition: Precondition\n ) {\n super();\n }\n\n readonly type: MutationType = MutationType.Patch;\n\n applyToRemoteDocument(\n maybeDoc: MaybeDocument | null,\n mutationResult: MutationResult\n ): MaybeDocument {\n this.verifyKeyMatches(maybeDoc);\n\n debugAssert(\n mutationResult.transformResults == null,\n 'Transform results received by PatchMutation.'\n );\n\n if (!this.precondition.isValidFor(maybeDoc)) {\n // Since the mutation was not rejected, we know that the precondition\n // matched on the backend. We therefore must not have the expected version\n // of the document in our cache and return an UnknownDocument with the\n // known updateTime.\n return new UnknownDocument(this.key, mutationResult.version);\n }\n\n const newData = this.patchDocument(maybeDoc);\n return new Document(this.key, mutationResult.version, newData, {\n hasCommittedMutations: true\n });\n }\n\n applyToLocalView(\n maybeDoc: MaybeDocument | null,\n baseDoc: MaybeDocument | null,\n localWriteTime: Timestamp\n ): MaybeDocument | null {\n this.verifyKeyMatches(maybeDoc);\n\n if (!this.precondition.isValidFor(maybeDoc)) {\n return maybeDoc;\n }\n\n const version = Mutation.getPostMutationVersion(maybeDoc);\n const newData = this.patchDocument(maybeDoc);\n return new Document(this.key, version, newData, {\n hasLocalMutations: true\n });\n }\n\n extractBaseValue(maybeDoc: MaybeDocument | null): null {\n return null;\n }\n\n isEqual(other: Mutation): boolean {\n return (\n other instanceof PatchMutation &&\n this.key.isEqual(other.key) &&\n this.fieldMask.isEqual(other.fieldMask) &&\n this.precondition.isEqual(other.precondition)\n );\n }\n\n /**\n * Patches the data of document if available or creates a new document. Note\n * that this does not check whether or not the precondition of this patch\n * holds.\n */\n private patchDocument(maybeDoc: MaybeDocument | null): ObjectValue {\n let data: ObjectValue;\n if (maybeDoc instanceof Document) {\n data = maybeDoc.data();\n } else {\n data = ObjectValue.empty();\n }\n return this.patchObject(data);\n }\n\n private patchObject(data: ObjectValue): ObjectValue {\n const builder = new ObjectValueBuilder(data);\n this.fieldMask.fields.forEach(fieldPath => {\n if (!fieldPath.isEmpty()) {\n const newValue = this.data.field(fieldPath);\n if (newValue !== null) {\n builder.set(fieldPath, newValue);\n } else {\n builder.delete(fieldPath);\n }\n }\n });\n return builder.build();\n }\n}\n\n/**\n * A mutation that modifies specific fields of the document with transform\n * operations. Currently the only supported transform is a server timestamp, but\n * IP Address, increment(n), etc. could be supported in the future.\n *\n * It is somewhat similar to a PatchMutation in that it patches specific fields\n * and has no effect when applied to a null or NoDocument (see comment on\n * Mutation for rationale).\n */\nexport class TransformMutation extends Mutation {\n readonly type: MutationType = MutationType.Transform;\n\n // NOTE: We set a precondition of exists: true as a safety-check, since we\n // always combine TransformMutations with a SetMutation or PatchMutation which\n // (if successful) should end up with an existing document.\n readonly precondition = Precondition.exists(true);\n\n constructor(\n readonly key: DocumentKey,\n readonly fieldTransforms: FieldTransform[]\n ) {\n super();\n }\n\n applyToRemoteDocument(\n maybeDoc: MaybeDocument | null,\n mutationResult: MutationResult\n ): MaybeDocument {\n this.verifyKeyMatches(maybeDoc);\n\n hardAssert(\n mutationResult.transformResults != null,\n 'Transform results missing for TransformMutation.'\n );\n\n if (!this.precondition.isValidFor(maybeDoc)) {\n // Since the mutation was not rejected, we know that the precondition\n // matched on the backend. We therefore must not have the expected version\n // of the document in our cache and return an UnknownDocument with the\n // known updateTime.\n return new UnknownDocument(this.key, mutationResult.version);\n }\n\n const doc = this.requireDocument(maybeDoc);\n const transformResults = this.serverTransformResults(\n maybeDoc,\n mutationResult.transformResults!\n );\n\n const version = mutationResult.version;\n const newData = this.transformObject(doc.data(), transformResults);\n return new Document(this.key, version, newData, {\n hasCommittedMutations: true\n });\n }\n\n applyToLocalView(\n maybeDoc: MaybeDocument | null,\n baseDoc: MaybeDocument | null,\n localWriteTime: Timestamp\n ): MaybeDocument | null {\n this.verifyKeyMatches(maybeDoc);\n\n if (!this.precondition.isValidFor(maybeDoc)) {\n return maybeDoc;\n }\n\n const doc = this.requireDocument(maybeDoc);\n const transformResults = this.localTransformResults(\n localWriteTime,\n maybeDoc,\n baseDoc\n );\n const newData = this.transformObject(doc.data(), transformResults);\n return new Document(this.key, doc.version, newData, {\n hasLocalMutations: true\n });\n }\n\n extractBaseValue(maybeDoc: MaybeDocument | null): ObjectValue | null {\n let baseObject: ObjectValueBuilder | null = null;\n for (const fieldTransform of this.fieldTransforms) {\n const existingValue =\n maybeDoc instanceof Document\n ? maybeDoc.field(fieldTransform.field)\n : undefined;\n const coercedValue = fieldTransform.transform.computeBaseValue(\n existingValue || null\n );\n\n if (coercedValue != null) {\n if (baseObject == null) {\n baseObject = new ObjectValueBuilder().set(\n fieldTransform.field,\n coercedValue\n );\n } else {\n baseObject = baseObject.set(fieldTransform.field, coercedValue);\n }\n }\n }\n return baseObject ? baseObject.build() : null;\n }\n\n isEqual(other: Mutation): boolean {\n return (\n other instanceof TransformMutation &&\n this.key.isEqual(other.key) &&\n arrayEquals(this.fieldTransforms, other.fieldTransforms, (l, r) =>\n l.isEqual(r)\n ) &&\n this.precondition.isEqual(other.precondition)\n );\n }\n\n /**\n * Asserts that the given MaybeDocument is actually a Document and verifies\n * that it matches the key for this mutation. Since we only support\n * transformations with precondition exists this method is guaranteed to be\n * safe.\n */\n private requireDocument(maybeDoc: MaybeDocument | null): Document {\n debugAssert(\n maybeDoc instanceof Document,\n 'Unknown MaybeDocument type ' + maybeDoc\n );\n debugAssert(\n maybeDoc.key.isEqual(this.key),\n 'Can only transform a document with the same key'\n );\n return maybeDoc;\n }\n\n /**\n * Creates a list of \"transform results\" (a transform result is a field value\n * representing the result of applying a transform) for use after a\n * TransformMutation has been acknowledged by the server.\n *\n * @param baseDoc The document prior to applying this mutation batch.\n * @param serverTransformResults The transform results received by the server.\n * @return The transform results list.\n */\n private serverTransformResults(\n baseDoc: MaybeDocument | null,\n serverTransformResults: Array<api.Value | null>\n ): api.Value[] {\n const transformResults: api.Value[] = [];\n hardAssert(\n this.fieldTransforms.length === serverTransformResults.length,\n `server transform result count (${serverTransformResults.length}) ` +\n `should match field transform count (${this.fieldTransforms.length})`\n );\n\n for (let i = 0; i < serverTransformResults.length; i++) {\n const fieldTransform = this.fieldTransforms[i];\n const transform = fieldTransform.transform;\n let previousValue: api.Value | null = null;\n if (baseDoc instanceof Document) {\n previousValue = baseDoc.field(fieldTransform.field);\n }\n transformResults.push(\n transform.applyToRemoteDocument(\n previousValue,\n serverTransformResults[i]\n )\n );\n }\n return transformResults;\n }\n\n /**\n * Creates a list of \"transform results\" (a transform result is a field value\n * representing the result of applying a transform) for use when applying a\n * TransformMutation locally.\n *\n * @param localWriteTime The local time of the transform mutation (used to\n * generate ServerTimestampValues).\n * @param maybeDoc The current state of the document after applying all\n * previous mutations.\n * @param baseDoc The document prior to applying this mutation batch.\n * @return The transform results list.\n */\n private localTransformResults(\n localWriteTime: Timestamp,\n maybeDoc: MaybeDocument | null,\n baseDoc: MaybeDocument | null\n ): api.Value[] {\n const transformResults: api.Value[] = [];\n for (const fieldTransform of this.fieldTransforms) {\n const transform = fieldTransform.transform;\n\n let previousValue: api.Value | null = null;\n if (maybeDoc instanceof Document) {\n previousValue = maybeDoc.field(fieldTransform.field);\n }\n\n if (previousValue === null && baseDoc instanceof Document) {\n // If the current document does not contain a value for the mutated\n // field, use the value that existed before applying this mutation\n // batch. This solves an edge case where a PatchMutation clears the\n // values in a nested map before the TransformMutation is applied.\n previousValue = baseDoc.field(fieldTransform.field);\n }\n\n transformResults.push(\n transform.applyToLocalView(previousValue, localWriteTime)\n );\n }\n return transformResults;\n }\n\n private transformObject(\n data: ObjectValue,\n transformResults: api.Value[]\n ): ObjectValue {\n debugAssert(\n transformResults.length === this.fieldTransforms.length,\n 'TransformResults length mismatch.'\n );\n\n const builder = new ObjectValueBuilder(data);\n for (let i = 0; i < this.fieldTransforms.length; i++) {\n const fieldTransform = this.fieldTransforms[i];\n const fieldPath = fieldTransform.field;\n builder.set(fieldPath, transformResults[i]);\n }\n return builder.build();\n }\n}\n\n/** A mutation that deletes the document at the given key. */\nexport class DeleteMutation extends Mutation {\n constructor(readonly key: DocumentKey, readonly precondition: Precondition) {\n super();\n }\n\n readonly type: MutationType = MutationType.Delete;\n\n applyToRemoteDocument(\n maybeDoc: MaybeDocument | null,\n mutationResult: MutationResult\n ): MaybeDocument {\n this.verifyKeyMatches(maybeDoc);\n\n debugAssert(\n mutationResult.transformResults == null,\n 'Transform results received by DeleteMutation.'\n );\n\n // Unlike applyToLocalView, if we're applying a mutation to a remote\n // document the server has accepted the mutation so the precondition must\n // have held.\n\n return new NoDocument(this.key, mutationResult.version, {\n hasCommittedMutations: true\n });\n }\n\n applyToLocalView(\n maybeDoc: MaybeDocument | null,\n baseDoc: MaybeDocument | null,\n localWriteTime: Timestamp\n ): MaybeDocument | null {\n this.verifyKeyMatches(maybeDoc);\n\n if (!this.precondition.isValidFor(maybeDoc)) {\n return maybeDoc;\n }\n\n if (maybeDoc) {\n debugAssert(\n maybeDoc.key.isEqual(this.key),\n 'Can only apply mutation to document with same key'\n );\n }\n return new NoDocument(this.key, SnapshotVersion.min());\n }\n\n extractBaseValue(maybeDoc: MaybeDocument | null): null {\n return null;\n }\n\n isEqual(other: Mutation): boolean {\n return (\n other instanceof DeleteMutation &&\n this.key.isEqual(other.key) &&\n this.precondition.isEqual(other.precondition)\n );\n }\n}\n\n/**\n * A mutation that verifies the existence of the document at the given key with\n * the provided precondition.\n *\n * The `verify` operation is only used in Transactions, and this class serves\n * primarily to facilitate serialization into protos.\n */\nexport class VerifyMutation extends Mutation {\n constructor(readonly key: DocumentKey, readonly precondition: Precondition) {\n super();\n }\n\n readonly type: MutationType = MutationType.Verify;\n\n applyToRemoteDocument(\n maybeDoc: MaybeDocument | null,\n mutationResult: MutationResult\n ): MaybeDocument {\n fail('VerifyMutation should only be used in Transactions.');\n }\n\n applyToLocalView(\n maybeDoc: MaybeDocument | null,\n baseDoc: MaybeDocument | null,\n localWriteTime: Timestamp\n ): MaybeDocument | null {\n fail('VerifyMutation should only be used in Transactions.');\n }\n\n extractBaseValue(maybeDoc: MaybeDocument | null): null {\n fail('VerifyMutation should only be used in Transactions.');\n }\n\n isEqual(other: Mutation): boolean {\n return (\n other instanceof VerifyMutation &&\n this.key.isEqual(other.key) &&\n this.precondition.isEqual(other.precondition)\n );\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 { Timestamp } from '../api/timestamp';\nimport { SnapshotVersion } from '../core/snapshot_version';\nimport { BatchId } from '../core/types';\nimport { hardAssert, debugAssert } from '../util/assert';\nimport { arrayEquals } from '../util/misc';\nimport { ByteString } from '../util/byte_string';\nimport {\n documentKeySet,\n DocumentKeySet,\n DocumentVersionMap,\n documentVersionMap,\n MaybeDocumentMap\n} from './collections';\nimport { MaybeDocument } from './document';\nimport { DocumentKey } from './document_key';\nimport { Mutation, MutationResult } from './mutation';\n\nexport const BATCHID_UNKNOWN = -1;\n\n/**\n * A batch of mutations that will be sent as one unit to the backend.\n */\nexport class MutationBatch {\n /**\n * @param batchId The unique ID of this mutation batch.\n * @param localWriteTime The original write time of this mutation.\n * @param baseMutations Mutations that are used to populate the base\n * values when this mutation is applied locally. This can be used to locally\n * overwrite values that are persisted in the remote document cache. Base\n * mutations are never sent to the backend.\n * @param mutations The user-provided mutations in this mutation batch.\n * User-provided mutations are applied both locally and remotely on the\n * backend.\n */\n constructor(\n public batchId: BatchId,\n public localWriteTime: Timestamp,\n public baseMutations: Mutation[],\n public mutations: Mutation[]\n ) {\n debugAssert(mutations.length > 0, 'Cannot create an empty mutation batch');\n }\n\n /**\n * Applies all the mutations in this MutationBatch to the specified document\n * to create a new remote document\n *\n * @param docKey The key of the document to apply mutations to.\n * @param maybeDoc The document to apply mutations to.\n * @param batchResult The result of applying the MutationBatch to the\n * backend.\n */\n applyToRemoteDocument(\n docKey: DocumentKey,\n maybeDoc: MaybeDocument | null,\n batchResult: MutationBatchResult\n ): MaybeDocument | null {\n if (maybeDoc) {\n debugAssert(\n maybeDoc.key.isEqual(docKey),\n `applyToRemoteDocument: key ${docKey} should match maybeDoc key\n ${maybeDoc.key}`\n );\n }\n\n const mutationResults = batchResult.mutationResults;\n debugAssert(\n mutationResults.length === this.mutations.length,\n `Mismatch between mutations length\n (${this.mutations.length}) and mutation results length\n (${mutationResults.length}).`\n );\n\n for (let i = 0; i < this.mutations.length; i++) {\n const mutation = this.mutations[i];\n if (mutation.key.isEqual(docKey)) {\n const mutationResult = mutationResults[i];\n maybeDoc = mutation.applyToRemoteDocument(maybeDoc, mutationResult);\n }\n }\n return maybeDoc;\n }\n\n /**\n * Computes the local view of a document given all the mutations in this\n * batch.\n *\n * @param docKey The key of the document to apply mutations to.\n * @param maybeDoc The document to apply mutations to.\n */\n applyToLocalView(\n docKey: DocumentKey,\n maybeDoc: MaybeDocument | null\n ): MaybeDocument | null {\n if (maybeDoc) {\n debugAssert(\n maybeDoc.key.isEqual(docKey),\n `applyToLocalDocument: key ${docKey} should match maybeDoc key\n ${maybeDoc.key}`\n );\n }\n\n // First, apply the base state. This allows us to apply non-idempotent\n // transform against a consistent set of values.\n for (const mutation of this.baseMutations) {\n if (mutation.key.isEqual(docKey)) {\n maybeDoc = mutation.applyToLocalView(\n maybeDoc,\n maybeDoc,\n this.localWriteTime\n );\n }\n }\n\n const baseDoc = maybeDoc;\n\n // Second, apply all user-provided mutations.\n for (const mutation of this.mutations) {\n if (mutation.key.isEqual(docKey)) {\n maybeDoc = mutation.applyToLocalView(\n maybeDoc,\n baseDoc,\n this.localWriteTime\n );\n }\n }\n return maybeDoc;\n }\n\n /**\n * Computes the local view for all provided documents given the mutations in\n * this batch.\n */\n applyToLocalDocumentSet(maybeDocs: MaybeDocumentMap): MaybeDocumentMap {\n // TODO(mrschmidt): This implementation is O(n^2). If we apply the mutations\n // directly (as done in `applyToLocalView()`), we can reduce the complexity\n // to O(n).\n let mutatedDocuments = maybeDocs;\n this.mutations.forEach(m => {\n const mutatedDocument = this.applyToLocalView(\n m.key,\n maybeDocs.get(m.key)\n );\n if (mutatedDocument) {\n mutatedDocuments = mutatedDocuments.insert(m.key, mutatedDocument);\n }\n });\n return mutatedDocuments;\n }\n\n keys(): DocumentKeySet {\n return this.mutations.reduce(\n (keys, m) => keys.add(m.key),\n documentKeySet()\n );\n }\n\n isEqual(other: MutationBatch): boolean {\n return (\n this.batchId === other.batchId &&\n arrayEquals(this.mutations, other.mutations, (l, r) => l.isEqual(r)) &&\n arrayEquals(this.baseMutations, other.baseMutations, (l, r) =>\n l.isEqual(r)\n )\n );\n }\n}\n\n/** The result of applying a mutation batch to the backend. */\nexport class MutationBatchResult {\n private constructor(\n readonly batch: MutationBatch,\n readonly commitVersion: SnapshotVersion,\n readonly mutationResults: MutationResult[],\n readonly streamToken: ByteString,\n /**\n * A pre-computed mapping from each mutated document to the resulting\n * version.\n */\n readonly docVersions: DocumentVersionMap\n ) {}\n\n /**\n * Creates a new MutationBatchResult for the given batch and results. There\n * must be one result for each mutation in the batch. This static factory\n * caches a document=>version mapping (docVersions).\n */\n static from(\n batch: MutationBatch,\n commitVersion: SnapshotVersion,\n results: MutationResult[],\n streamToken: ByteString\n ): MutationBatchResult {\n hardAssert(\n batch.mutations.length === results.length,\n 'Mutations sent ' +\n batch.mutations.length +\n ' must equal results received ' +\n results.length\n );\n\n let versionMap = documentVersionMap();\n const mutations = batch.mutations;\n for (let i = 0; i < mutations.length; i++) {\n versionMap = versionMap.insert(mutations[i].key, results[i].version);\n }\n\n return new MutationBatchResult(\n batch,\n commitVersion,\n results,\n streamToken,\n versionMap\n );\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 { Equatable } from './misc';\nimport { forEach, isEmpty } from './obj';\n\ntype Entry<K, V> = [K, V];\n\n/**\n * A map implementation that uses objects as keys. Objects must implement the\n * Equatable interface and must be immutable. Entries in the map are stored\n * together with the key being produced from the mapKeyFn. This map\n * automatically handles collisions of keys.\n */\nexport class ObjectMap<KeyType extends Equatable<KeyType>, ValueType> {\n /**\n * The inner map for a key -> value pair. Due to the possibility of\n * collisions we keep a list of entries that we do a linear search through\n * to find an actual match. Note that collisions should be rare, so we still\n * expect near constant time lookups in practice.\n */\n private inner: {\n [canonicalId: string]: Array<Entry<KeyType, ValueType>>;\n } = {};\n\n constructor(private mapKeyFn: (key: KeyType) => string) {}\n\n /** Get a value for this key, or undefined if it does not exist. */\n get(key: KeyType): ValueType | undefined {\n const id = this.mapKeyFn(key);\n const matches = this.inner[id];\n if (matches === undefined) {\n return undefined;\n }\n for (const [otherKey, value] of matches) {\n if (otherKey.isEqual(key)) {\n return value;\n }\n }\n return undefined;\n }\n\n has(key: KeyType): boolean {\n return this.get(key) !== undefined;\n }\n\n /** Put this key and value in the map. */\n set(key: KeyType, value: ValueType): void {\n const id = this.mapKeyFn(key);\n const matches = this.inner[id];\n if (matches === undefined) {\n this.inner[id] = [[key, value]];\n return;\n }\n for (let i = 0; i < matches.length; i++) {\n if (matches[i][0].isEqual(key)) {\n matches[i] = [key, value];\n return;\n }\n }\n matches.push([key, value]);\n }\n\n /**\n * Remove this key from the map. Returns a boolean if anything was deleted.\n */\n delete(key: KeyType): boolean {\n const id = this.mapKeyFn(key);\n const matches = this.inner[id];\n if (matches === undefined) {\n return false;\n }\n for (let i = 0; i < matches.length; i++) {\n if (matches[i][0].isEqual(key)) {\n if (matches.length === 1) {\n delete this.inner[id];\n } else {\n matches.splice(i, 1);\n }\n return true;\n }\n }\n return false;\n }\n\n forEach(fn: (key: KeyType, val: ValueType) => void): void {\n forEach(this.inner, (_, entries) => {\n for (const [k, v] of entries) {\n fn(k, v);\n }\n });\n }\n\n isEmpty(): boolean {\n return isEmpty(this.inner);\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 { fail } from '../util/assert';\n\nexport type FulfilledHandler<T, R> =\n | ((result: T) => R | PersistencePromise<R>)\n | null;\nexport type RejectedHandler<R> =\n | ((reason: Error) => R | PersistencePromise<R>)\n | null;\nexport type Resolver<T> = (value?: T) => void;\nexport type Rejector = (error: Error) => void;\n\n/**\n * PersistencePromise<> is essentially a re-implementation of Promise<> except\n * it has a .next() method instead of .then() and .next() and .catch() callbacks\n * are executed synchronously when a PersistencePromise resolves rather than\n * asynchronously (Promise<> implementations use setImmediate() or similar).\n *\n * This is necessary to interoperate with IndexedDB which will automatically\n * commit transactions if control is returned to the event loop without\n * synchronously initiating another operation on the transaction.\n *\n * NOTE: .then() and .catch() only allow a single consumer, unlike normal\n * Promises.\n */\nexport class PersistencePromise<T> {\n // NOTE: next/catchCallback will always point to our own wrapper functions,\n // not the user's raw next() or catch() callbacks.\n private nextCallback: FulfilledHandler<T, unknown> = null;\n private catchCallback: RejectedHandler<unknown> = null;\n\n // When the operation resolves, we'll set result or error and mark isDone.\n private result: T | undefined = undefined;\n private error: Error | undefined = undefined;\n private isDone = false;\n\n // Set to true when .then() or .catch() are called and prevents additional\n // chaining.\n private callbackAttached = false;\n\n constructor(callback: (resolve: Resolver<T>, reject: Rejector) => void) {\n callback(\n value => {\n this.isDone = true;\n this.result = value;\n if (this.nextCallback) {\n // value should be defined unless T is Void, but we can't express\n // that in the type system.\n this.nextCallback(value!);\n }\n },\n error => {\n this.isDone = true;\n this.error = error;\n if (this.catchCallback) {\n this.catchCallback(error);\n }\n }\n );\n }\n\n catch<R>(\n fn: (error: Error) => R | PersistencePromise<R>\n ): PersistencePromise<R> {\n return this.next(undefined, fn);\n }\n\n next<R>(\n nextFn?: FulfilledHandler<T, R>,\n catchFn?: RejectedHandler<R>\n ): PersistencePromise<R> {\n if (this.callbackAttached) {\n fail('Called next() or catch() twice for PersistencePromise');\n }\n this.callbackAttached = true;\n if (this.isDone) {\n if (!this.error) {\n return this.wrapSuccess(nextFn, this.result!);\n } else {\n return this.wrapFailure(catchFn, this.error);\n }\n } else {\n return new PersistencePromise<R>((resolve, reject) => {\n this.nextCallback = (value: T) => {\n this.wrapSuccess(nextFn, value).next(resolve, reject);\n };\n this.catchCallback = (error: Error) => {\n this.wrapFailure(catchFn, error).next(resolve, reject);\n };\n });\n }\n }\n\n toPromise(): Promise<T> {\n return new Promise((resolve, reject) => {\n this.next(resolve, reject);\n });\n }\n\n private wrapUserFunction<R>(\n fn: () => R | PersistencePromise<R>\n ): PersistencePromise<R> {\n try {\n const result = fn();\n if (result instanceof PersistencePromise) {\n return result;\n } else {\n return PersistencePromise.resolve(result);\n }\n } catch (e) {\n return PersistencePromise.reject<R>(e);\n }\n }\n\n private wrapSuccess<R>(\n nextFn: FulfilledHandler<T, R> | undefined,\n value: T\n ): PersistencePromise<R> {\n if (nextFn) {\n return this.wrapUserFunction(() => nextFn(value));\n } else {\n // If there's no nextFn, then R must be the same as T\n return PersistencePromise.resolve<R>((value as unknown) as R);\n }\n }\n\n private wrapFailure<R>(\n catchFn: RejectedHandler<R> | undefined,\n error: Error\n ): PersistencePromise<R> {\n if (catchFn) {\n return this.wrapUserFunction(() => catchFn(error));\n } else {\n return PersistencePromise.reject<R>(error);\n }\n }\n\n static resolve(): PersistencePromise<void>;\n static resolve<R>(result: R): PersistencePromise<R>;\n static resolve<R>(result?: R): PersistencePromise<R | void> {\n return new PersistencePromise<R | void>((resolve, reject) => {\n resolve(result);\n });\n }\n\n static reject<R>(error: Error): PersistencePromise<R> {\n return new PersistencePromise<R>((resolve, reject) => {\n reject(error);\n });\n }\n\n static waitFor(\n // Accept all Promise types in waitFor().\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n all: { forEach: (cb: (el: PersistencePromise<any>) => void) => void }\n ): PersistencePromise<void> {\n return new PersistencePromise<void>((resolve, reject) => {\n let expectedCount = 0;\n let resolvedCount = 0;\n let done = false;\n\n all.forEach(element => {\n ++expectedCount;\n element.next(\n () => {\n ++resolvedCount;\n if (done && resolvedCount === expectedCount) {\n resolve();\n }\n },\n err => reject(err)\n );\n });\n\n done = true;\n if (resolvedCount === expectedCount) {\n resolve();\n }\n });\n }\n\n /**\n * Given an array of predicate functions that asynchronously evaluate to a\n * boolean, implements a short-circuiting `or` between the results. Predicates\n * will be evaluated until one of them returns `true`, then stop. The final\n * result will be whether any of them returned `true`.\n */\n static or(\n predicates: Array<() => PersistencePromise<boolean>>\n ): PersistencePromise<boolean> {\n let p: PersistencePromise<boolean> = PersistencePromise.resolve<boolean>(\n false\n );\n for (const predicate of predicates) {\n p = p.next(isTrue => {\n if (isTrue) {\n return PersistencePromise.resolve<boolean>(isTrue);\n } else {\n return predicate();\n }\n });\n }\n return p;\n }\n\n /**\n * Given an iterable, call the given function on each element in the\n * collection and wait for all of the resulting concurrent PersistencePromises\n * to resolve.\n */\n static forEach<R, S>(\n collection: { forEach: (cb: (r: R, s: S) => void) => void },\n f:\n | ((r: R, s: S) => PersistencePromise<void>)\n | ((r: R) => PersistencePromise<void>)\n ): PersistencePromise<void>;\n static forEach<R>(\n collection: { forEach: (cb: (r: R) => void) => void },\n f: (r: R) => PersistencePromise<void>\n ): PersistencePromise<void>;\n static forEach<R, S>(\n collection: { forEach: (cb: (r: R, s?: S) => void) => void },\n f: (r: R, s?: S) => PersistencePromise<void>\n ): PersistencePromise<void> {\n const promises: Array<PersistencePromise<void>> = [];\n collection.forEach((r, s) => {\n promises.push(f.call(this, r, s));\n });\n return this.waitFor(promises);\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 { Query } from '../core/query';\nimport { SnapshotVersion } from '../core/snapshot_version';\nimport {\n DocumentKeySet,\n documentKeySet,\n DocumentMap,\n documentMap,\n MaybeDocumentMap,\n maybeDocumentMap,\n NullableMaybeDocumentMap,\n nullableMaybeDocumentMap\n} from '../model/collections';\nimport { Document, MaybeDocument, NoDocument } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport { MutationBatch } from '../model/mutation_batch';\nimport { ResourcePath } from '../model/path';\n\nimport { debugAssert } from '../util/assert';\nimport { IndexManager } from './index_manager';\nimport { MutationQueue } from './mutation_queue';\nimport { PatchMutation } from '../model/mutation';\nimport { PersistenceTransaction } from './persistence';\nimport { PersistencePromise } from './persistence_promise';\nimport { RemoteDocumentCache } from './remote_document_cache';\n\n/**\n * A readonly view of the local state of all documents we're tracking (i.e. we\n * have a cached version in remoteDocumentCache or local mutations for the\n * document). The view is computed by applying the mutations in the\n * MutationQueue to the RemoteDocumentCache.\n */\nexport class LocalDocumentsView {\n constructor(\n readonly remoteDocumentCache: RemoteDocumentCache,\n readonly mutationQueue: MutationQueue,\n readonly indexManager: IndexManager\n ) {}\n\n /**\n * Get the local view of the document identified by `key`.\n *\n * @return Local view of the document or null if we don't have any cached\n * state for it.\n */\n getDocument(\n transaction: PersistenceTransaction,\n key: DocumentKey\n ): PersistencePromise<MaybeDocument | null> {\n return this.mutationQueue\n .getAllMutationBatchesAffectingDocumentKey(transaction, key)\n .next(batches => this.getDocumentInternal(transaction, key, batches));\n }\n\n /** Internal version of `getDocument` that allows reusing batches. */\n private getDocumentInternal(\n transaction: PersistenceTransaction,\n key: DocumentKey,\n inBatches: MutationBatch[]\n ): PersistencePromise<MaybeDocument | null> {\n return this.remoteDocumentCache.getEntry(transaction, key).next(doc => {\n for (const batch of inBatches) {\n doc = batch.applyToLocalView(key, doc);\n }\n return doc;\n });\n }\n\n // Returns the view of the given `docs` as they would appear after applying\n // all mutations in the given `batches`.\n private applyLocalMutationsToDocuments(\n transaction: PersistenceTransaction,\n docs: NullableMaybeDocumentMap,\n batches: MutationBatch[]\n ): NullableMaybeDocumentMap {\n let results = nullableMaybeDocumentMap();\n docs.forEach((key, localView) => {\n for (const batch of batches) {\n localView = batch.applyToLocalView(key, localView);\n }\n results = results.insert(key, localView);\n });\n return results;\n }\n\n /**\n * Gets the local view of the documents identified by `keys`.\n *\n * If we don't have cached state for a document in `keys`, a NoDocument will\n * be stored for that key in the resulting set.\n */\n getDocuments(\n transaction: PersistenceTransaction,\n keys: DocumentKeySet\n ): PersistencePromise<MaybeDocumentMap> {\n return this.remoteDocumentCache\n .getEntries(transaction, keys)\n .next(docs => this.getLocalViewOfDocuments(transaction, docs));\n }\n\n /**\n * Similar to `getDocuments`, but creates the local view from the given\n * `baseDocs` without retrieving documents from the local store.\n */\n getLocalViewOfDocuments(\n transaction: PersistenceTransaction,\n baseDocs: NullableMaybeDocumentMap\n ): PersistencePromise<MaybeDocumentMap> {\n return this.mutationQueue\n .getAllMutationBatchesAffectingDocumentKeys(transaction, baseDocs)\n .next(batches => {\n const docs = this.applyLocalMutationsToDocuments(\n transaction,\n baseDocs,\n batches\n );\n let results = maybeDocumentMap();\n docs.forEach((key, maybeDoc) => {\n // TODO(http://b/32275378): Don't conflate missing / deleted.\n if (!maybeDoc) {\n maybeDoc = new NoDocument(key, SnapshotVersion.min());\n }\n results = results.insert(key, maybeDoc);\n });\n\n return results;\n });\n }\n\n /**\n * Performs a query against the local view of all documents.\n *\n * @param transaction The persistence transaction.\n * @param query The query to match documents against.\n * @param sinceReadTime If not set to SnapshotVersion.min(), return only\n * documents that have been read since this snapshot version (exclusive).\n */\n getDocumentsMatchingQuery(\n transaction: PersistenceTransaction,\n query: Query,\n sinceReadTime: SnapshotVersion\n ): PersistencePromise<DocumentMap> {\n if (query.isDocumentQuery()) {\n return this.getDocumentsMatchingDocumentQuery(transaction, query.path);\n } else if (query.isCollectionGroupQuery()) {\n return this.getDocumentsMatchingCollectionGroupQuery(\n transaction,\n query,\n sinceReadTime\n );\n } else {\n return this.getDocumentsMatchingCollectionQuery(\n transaction,\n query,\n sinceReadTime\n );\n }\n }\n\n private getDocumentsMatchingDocumentQuery(\n transaction: PersistenceTransaction,\n docPath: ResourcePath\n ): PersistencePromise<DocumentMap> {\n // Just do a simple document lookup.\n return this.getDocument(transaction, new DocumentKey(docPath)).next(\n maybeDoc => {\n let result = documentMap();\n if (maybeDoc instanceof Document) {\n result = result.insert(maybeDoc.key, maybeDoc);\n }\n return result;\n }\n );\n }\n\n private getDocumentsMatchingCollectionGroupQuery(\n transaction: PersistenceTransaction,\n query: Query,\n sinceReadTime: SnapshotVersion\n ): PersistencePromise<DocumentMap> {\n debugAssert(\n query.path.isEmpty(),\n 'Currently we only support collection group queries at the root.'\n );\n const collectionId = query.collectionGroup!;\n let results = documentMap();\n return this.indexManager\n .getCollectionParents(transaction, collectionId)\n .next(parents => {\n // Perform a collection query against each parent that contains the\n // collectionId and aggregate the results.\n return PersistencePromise.forEach(parents, (parent: ResourcePath) => {\n const collectionQuery = query.asCollectionQueryAtPath(\n parent.child(collectionId)\n );\n return this.getDocumentsMatchingCollectionQuery(\n transaction,\n collectionQuery,\n sinceReadTime\n ).next(r => {\n r.forEach((key, doc) => {\n results = results.insert(key, doc);\n });\n });\n }).next(() => results);\n });\n }\n\n private getDocumentsMatchingCollectionQuery(\n transaction: PersistenceTransaction,\n query: Query,\n sinceReadTime: SnapshotVersion\n ): PersistencePromise<DocumentMap> {\n // Query the remote documents and overlay mutations.\n let results: DocumentMap;\n let mutationBatches: MutationBatch[];\n return this.remoteDocumentCache\n .getDocumentsMatchingQuery(transaction, query, sinceReadTime)\n .next(queryResults => {\n results = queryResults;\n return this.mutationQueue.getAllMutationBatchesAffectingQuery(\n transaction,\n query\n );\n })\n .next(matchingMutationBatches => {\n mutationBatches = matchingMutationBatches;\n // It is possible that a PatchMutation can make a document match a query, even if\n // the version in the RemoteDocumentCache is not a match yet (waiting for server\n // to ack). To handle this, we find all document keys affected by the PatchMutations\n // that are not in `result` yet, and back fill them via `remoteDocumentCache.getEntries`,\n // otherwise those `PatchMutations` will be ignored because no base document can be found,\n // and lead to missing result for the query.\n return this.addMissingBaseDocuments(\n transaction,\n mutationBatches,\n results\n ).next(mergedDocuments => {\n results = mergedDocuments;\n\n for (const batch of mutationBatches) {\n for (const mutation of batch.mutations) {\n const key = mutation.key;\n const baseDoc = results.get(key);\n const mutatedDoc = mutation.applyToLocalView(\n baseDoc,\n baseDoc,\n batch.localWriteTime\n );\n if (mutatedDoc instanceof Document) {\n results = results.insert(key, mutatedDoc);\n } else {\n results = results.remove(key);\n }\n }\n }\n });\n })\n .next(() => {\n // Finally, filter out any documents that don't actually match\n // the query.\n results.forEach((key, doc) => {\n if (!query.matches(doc)) {\n results = results.remove(key);\n }\n });\n\n return results;\n });\n }\n\n private addMissingBaseDocuments(\n transaction: PersistenceTransaction,\n matchingMutationBatches: MutationBatch[],\n existingDocuments: DocumentMap\n ): PersistencePromise<DocumentMap> {\n let missingBaseDocEntriesForPatching = documentKeySet();\n for (const batch of matchingMutationBatches) {\n for (const mutation of batch.mutations) {\n if (\n mutation instanceof PatchMutation &&\n existingDocuments.get(mutation.key) === null\n ) {\n missingBaseDocEntriesForPatching = missingBaseDocEntriesForPatching.add(\n mutation.key\n );\n }\n }\n }\n\n let mergedDocuments = existingDocuments;\n return this.remoteDocumentCache\n .getEntries(transaction, missingBaseDocEntriesForPatching)\n .next(missingBaseDocs => {\n missingBaseDocs.forEach((key, doc) => {\n if (doc !== null && doc instanceof Document) {\n mergedDocuments = mergedDocuments.insert(key, doc);\n }\n });\n return mergedDocuments;\n });\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 { User } from '../auth/user';\nimport { ListenSequenceNumber, TargetId } from '../core/types';\nimport { DocumentKey } from '../model/document_key';\nimport { IndexManager } from './index_manager';\nimport { LocalStore } from './local_store';\nimport { MutationQueue } from './mutation_queue';\nimport { PersistencePromise } from './persistence_promise';\nimport { TargetCache } from './target_cache';\nimport { RemoteDocumentCache } from './remote_document_cache';\nimport { TargetData } from './target_data';\n\nexport const PRIMARY_LEASE_LOST_ERROR_MSG =\n 'The current tab is not in the required state to perform this operation. ' +\n 'It might be necessary to refresh the browser tab.';\n\n/**\n * A base class representing a persistence transaction, encapsulating both the\n * transaction's sequence numbers as well as a list of onCommitted listeners.\n *\n * When you call Persistence.runTransaction(), it will create a transaction and\n * pass it to your callback. You then pass it to any method that operates\n * on persistence.\n */\nexport abstract class PersistenceTransaction {\n private readonly onCommittedListeners: Array<() => void> = [];\n\n abstract readonly currentSequenceNumber: ListenSequenceNumber;\n\n addOnCommittedListener(listener: () => void): void {\n this.onCommittedListeners.push(listener);\n }\n\n raiseOnCommittedEvent(): void {\n this.onCommittedListeners.forEach(listener => listener());\n }\n}\n\n/** The different modes supported by `IndexedDbPersistence.runTransaction()`. */\nexport type PersistenceTransactionMode =\n | 'readonly'\n | 'readwrite'\n | 'readwrite-primary';\n\n/**\n * Callback type for primary state notifications. This callback can be\n * registered with the persistence layer to get notified when we transition from\n * primary to secondary state and vice versa.\n *\n * Note: Instances can only toggle between Primary and Secondary state if\n * IndexedDB persistence is enabled and multiple clients are active. If this\n * listener is registered with MemoryPersistence, the callback will be called\n * exactly once marking the current instance as Primary.\n */\nexport type PrimaryStateListener = (isPrimary: boolean) => Promise<void>;\n\n/**\n * A ReferenceDelegate instance handles all of the hooks into the document-reference lifecycle. This\n * includes being added to a target, being removed from a target, being subject to mutation, and\n * being mutated by the user.\n *\n * Different implementations may do different things with each of these events. Not every\n * implementation needs to do something with every lifecycle hook.\n *\n * PORTING NOTE: since sequence numbers are attached to transactions in this\n * client, the ReferenceDelegate does not need to deal in transactional\n * semantics (onTransactionStarted/Committed()), nor does it need to track and\n * generate sequence numbers (getCurrentSequenceNumber()).\n */\nexport interface ReferenceDelegate {\n /** Notify the delegate that the given document was added to a target. */\n addReference(\n txn: PersistenceTransaction,\n targetId: TargetId,\n doc: DocumentKey\n ): PersistencePromise<void>;\n\n /** Notify the delegate that the given document was removed from a target. */\n removeReference(\n txn: PersistenceTransaction,\n targetId: TargetId,\n doc: DocumentKey\n ): PersistencePromise<void>;\n\n /**\n * Notify the delegate that a target was removed. The delegate may, but is not obligated to,\n * actually delete the target and associated data.\n */\n removeTarget(\n txn: PersistenceTransaction,\n targetData: TargetData\n ): PersistencePromise<void>;\n\n /**\n * Notify the delegate that a document may no longer be part of any views or\n * have any mutations associated.\n */\n markPotentiallyOrphaned(\n txn: PersistenceTransaction,\n doc: DocumentKey\n ): PersistencePromise<void>;\n\n /** Notify the delegate that a limbo document was updated. */\n updateLimboDocument(\n txn: PersistenceTransaction,\n doc: DocumentKey\n ): PersistencePromise<void>;\n}\n\n/**\n * Persistence is the lowest-level shared interface to persistent storage in\n * Firestore.\n *\n * Persistence is used to create MutationQueue and RemoteDocumentCache\n * instances backed by persistence (which might be in-memory or LevelDB).\n *\n * Persistence also exposes an API to create and run PersistenceTransactions\n * against persistence. All read / write operations must be wrapped in a\n * transaction. Implementations of PersistenceTransaction / Persistence only\n * need to guarantee that writes made against the transaction are not made to\n * durable storage until the transaction resolves its PersistencePromise.\n * Since memory-only storage components do not alter durable storage, they are\n * free to ignore the transaction.\n *\n * This contract is enough to allow the LocalStore be be written\n * independently of whether or not the stored state actually is durably\n * persisted. If persistent storage is enabled, writes are grouped together to\n * avoid inconsistent state that could cause crashes.\n *\n * Concretely, when persistent storage is enabled, the persistent versions of\n * MutationQueue, RemoteDocumentCache, and others (the mutators) will\n * defer their writes into a transaction. Once the local store has completed\n * one logical operation, it commits the transaction.\n *\n * When persistent storage is disabled, the non-persistent versions of the\n * mutators ignore the transaction. This short-cut is allowed because\n * memory-only storage leaves no state so it cannot be inconsistent.\n *\n * This simplifies the implementations of the mutators and allows memory-only\n * implementations to supplement the persistent ones without requiring any\n * special dual-store implementation of Persistence. The cost is that the\n * LocalStore needs to be slightly careful about the order of its reads and\n * writes in order to avoid relying on being able to read back uncommitted\n * writes.\n */\nexport interface Persistence {\n /**\n * Whether or not this persistence instance has been started.\n */\n readonly started: boolean;\n\n readonly referenceDelegate: ReferenceDelegate;\n\n /** Starts persistence. */\n start(): Promise<void>;\n\n /**\n * Releases any resources held during eager shutdown.\n */\n shutdown(): Promise<void>;\n\n /**\n * Registers a listener that gets called when the database receives a\n * version change event indicating that it has deleted.\n *\n * PORTING NOTE: This is only used for Web multi-tab.\n */\n setDatabaseDeletedListener(\n databaseDeletedListener: () => Promise<void>\n ): void;\n\n /**\n * Returns a MutationQueue representing the persisted mutations for the\n * given user.\n *\n * Note: The implementation is free to return the same instance every time\n * this is called for a given user. In particular, the memory-backed\n * implementation does this to emulate the persisted implementation to the\n * extent possible (e.g. in the case of uid switching from\n * sally=>jack=>sally, sally's mutation queue will be preserved).\n */\n getMutationQueue(user: User): MutationQueue;\n\n /**\n * Returns a TargetCache representing the persisted cache of targets.\n *\n * Note: The implementation is free to return the same instance every time\n * this is called. In particular, the memory-backed implementation does this\n * to emulate the persisted implementation to the extent possible.\n */\n getTargetCache(): TargetCache;\n\n /**\n * Returns a RemoteDocumentCache representing the persisted cache of remote\n * documents.\n *\n * Note: The implementation is free to return the same instance every time\n * this is called. In particular, the memory-backed implementation does this\n * to emulate the persisted implementation to the extent possible.\n */\n getRemoteDocumentCache(): RemoteDocumentCache;\n\n /**\n * Returns an IndexManager instance that manages our persisted query indexes.\n *\n * Note: The implementation is free to return the same instance every time\n * this is called. In particular, the memory-backed implementation does this\n * to emulate the persisted implementation to the extent possible.\n */\n getIndexManager(): IndexManager;\n\n /**\n * Performs an operation inside a persistence transaction. Any reads or writes\n * against persistence must be performed within a transaction. Writes will be\n * committed atomically once the transaction completes.\n *\n * Persistence operations are asynchronous and therefore the provided\n * transactionOperation must return a PersistencePromise. When it is resolved,\n * the transaction will be committed and the Promise returned by this method\n * will resolve.\n *\n * @param action A description of the action performed by this transaction,\n * used for logging.\n * @param mode The underlying mode of the IndexedDb transaction. Can be\n * 'readonly`, 'readwrite' or 'readwrite-primary'. Transactions marked\n * 'readwrite-primary' can only be executed by the primary client. In this\n * mode, the transactionOperation will not be run if the primary lease cannot\n * be acquired and the returned promise will be rejected with a\n * FAILED_PRECONDITION error.\n * @param transactionOperation The operation to run inside a transaction.\n * @return A promise that is resolved once the transaction completes.\n */\n runTransaction<T>(\n action: string,\n mode: PersistenceTransactionMode,\n transactionOperation: (\n transaction: PersistenceTransaction\n ) => PersistencePromise<T>\n ): Promise<T>;\n}\n\n/**\n * Interface implemented by the LRU scheduler to start(), stop() and restart\n * garbage collection.\n */\nexport interface GarbageCollectionScheduler {\n readonly started: boolean;\n start(localStore: LocalStore): void;\n stop(): void;\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 { SnapshotVersion } from '../core/snapshot_version';\nimport { Target } from '../core/target';\nimport { ListenSequenceNumber, TargetId } from '../core/types';\nimport { ByteString } from '../util/byte_string';\n\n/** An enumeration of the different purposes we have for targets. */\nexport const enum TargetPurpose {\n /** A regular, normal query target. */\n Listen,\n\n /**\n * The query target was used to refill a query after an existence filter mismatch.\n */\n ExistenceFilterMismatch,\n\n /** The query target was used to resolve a limbo document. */\n LimboResolution\n}\n\n/**\n * An immutable set of metadata that the local store tracks for each target.\n */\nexport class TargetData {\n constructor(\n /** The target being listened to. */\n readonly target: Target,\n /**\n * The target ID to which the target corresponds; Assigned by the\n * LocalStore for user listens and by the SyncEngine for limbo watches.\n */\n readonly targetId: TargetId,\n /** The purpose of the target. */\n readonly purpose: TargetPurpose,\n /**\n * The sequence number of the last transaction during which this target data\n * was modified.\n */\n readonly sequenceNumber: ListenSequenceNumber,\n /** The latest snapshot version seen for this target. */\n readonly snapshotVersion: SnapshotVersion = SnapshotVersion.min(),\n /**\n * The maximum snapshot version at which the associated view\n * contained no limbo documents.\n */\n readonly lastLimboFreeSnapshotVersion: SnapshotVersion = SnapshotVersion.min(),\n /**\n * An opaque, server-assigned token that allows watching a target to be\n * resumed after disconnecting without retransmitting all the data that\n * matches the target. The resume token essentially identifies a point in\n * time from which the server should resume sending results.\n */\n readonly resumeToken: ByteString = ByteString.EMPTY_BYTE_STRING\n ) {}\n\n /** Creates a new target data instance with an updated sequence number. */\n withSequenceNumber(sequenceNumber: number): TargetData {\n return new TargetData(\n this.target,\n this.targetId,\n this.purpose,\n sequenceNumber,\n this.snapshotVersion,\n this.lastLimboFreeSnapshotVersion,\n this.resumeToken\n );\n }\n\n /**\n * Creates a new target data instance with an updated resume token and\n * snapshot version.\n */\n withResumeToken(\n resumeToken: ByteString,\n snapshotVersion: SnapshotVersion\n ): TargetData {\n return new TargetData(\n this.target,\n this.targetId,\n this.purpose,\n this.sequenceNumber,\n snapshotVersion,\n this.lastLimboFreeSnapshotVersion,\n resumeToken\n );\n }\n\n /**\n * Creates a new target data instance with an updated last limbo free\n * snapshot version number.\n */\n withLastLimboFreeSnapshotVersion(\n lastLimboFreeSnapshotVersion: SnapshotVersion\n ): TargetData {\n return new TargetData(\n this.target,\n this.targetId,\n this.purpose,\n this.sequenceNumber,\n this.snapshotVersion,\n lastLimboFreeSnapshotVersion,\n this.resumeToken\n );\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\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> {\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 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 { ResourcePath } from '../model/path';\nimport { fail, hardAssert } from '../util/assert';\n\n/**\n * Helpers for dealing with resource paths stored in IndexedDB.\n *\n * Resource paths in their canonical string form do not sort as the server\n * sorts them. Specifically the server splits paths into segments first and then\n * sorts, putting end-of-segment before any character. In a UTF-8 string\n * encoding the slash ('/') that denotes the end-of-segment naturally comes\n * after other characters so the intent here is to encode the path delimiters in\n * such a way that the resulting strings sort naturally.\n *\n * Resource paths are also used for prefix scans so it's important to\n * distinguish whole segments from any longer segments of which they might be a\n * prefix. For example, it's important to make it possible to scan documents in\n * a collection \"foo\" without encountering documents in a collection \"foobar\".\n *\n * Separate from the concerns about resource path ordering and separation,\n * On Android, SQLite imposes additional restrictions since it does not handle\n * keys with embedded NUL bytes particularly well. Rather than change the\n * implementation we keep the encoding identical to keep the ports similar.\n *\n * Taken together this means resource paths when encoded for storage in\n * IndexedDB have the following characteristics:\n *\n * * Segment separators (\"/\") sort before everything else.\n * * All paths have a trailing separator.\n * * NUL bytes do not exist in the output, since IndexedDB doesn't treat them\n * well.\n *\n * Therefore resource paths are encoded into string form using the following\n * rules:\n *\n * * '\\x01' is used as an escape character.\n * * Path separators are encoded as \"\\x01\\x01\"\n * * NUL bytes are encoded as \"\\x01\\x10\"\n * * '\\x01' is encoded as \"\\x01\\x11\"\n *\n * This encoding leaves some room between path separators and the NUL byte\n * just in case we decide to support integer document ids after all.\n *\n * Note that characters treated specially by the backend ('.', '/', and '~')\n * are not treated specially here. This class assumes that any unescaping of\n * resource path strings into actual ResourcePath objects will handle these\n * characters there.\n */\nexport type EncodedResourcePath = string;\n\nconst escapeChar = '\\u0001';\nconst encodedSeparatorChar = '\\u0001';\nconst encodedNul = '\\u0010';\nconst encodedEscape = '\\u0011';\n\n/**\n * Encodes a resource path into a IndexedDb-compatible string form.\n */\nexport function encodeResourcePath(path: ResourcePath): EncodedResourcePath {\n let result = '';\n for (let i = 0; i < path.length; i++) {\n if (result.length > 0) {\n result = encodeSeparator(result);\n }\n result = encodeSegment(path.get(i), result);\n }\n return encodeSeparator(result);\n}\n\n/** Encodes a single segment of a resource path into the given result */\nfunction encodeSegment(segment: string, resultBuf: string): string {\n let result = resultBuf;\n const length = segment.length;\n for (let i = 0; i < length; i++) {\n const c = segment.charAt(i);\n switch (c) {\n case '\\0':\n result += escapeChar + encodedNul;\n break;\n case escapeChar:\n result += escapeChar + encodedEscape;\n break;\n default:\n result += c;\n }\n }\n return result;\n}\n\n/** Encodes a path separator into the given result */\nfunction encodeSeparator(result: string): string {\n return result + escapeChar + encodedSeparatorChar;\n}\n\n/**\n * Decodes the given IndexedDb-compatible string form of a resource path into\n * a ResourcePath instance. Note that this method is not suitable for use with\n * decoding resource names from the server; those are One Platform format\n * strings.\n */\nexport function decodeResourcePath(path: EncodedResourcePath): ResourcePath {\n // Event the empty path must encode as a path of at least length 2. A path\n // with exactly 2 must be the empty path.\n const length = path.length;\n hardAssert(length >= 2, 'Invalid path ' + path);\n if (length === 2) {\n hardAssert(\n path.charAt(0) === escapeChar && path.charAt(1) === encodedSeparatorChar,\n 'Non-empty path ' + path + ' had length 2'\n );\n return ResourcePath.EMPTY_PATH;\n }\n\n // Escape characters cannot exist past the second-to-last position in the\n // source value.\n const lastReasonableEscapeIndex = length - 2;\n\n const segments: string[] = [];\n let segmentBuilder = '';\n\n for (let start = 0; start < length; ) {\n // The last two characters of a valid encoded path must be a separator, so\n // there must be an end to this segment.\n const end = path.indexOf(escapeChar, start);\n if (end < 0 || end > lastReasonableEscapeIndex) {\n fail('Invalid encoded resource path: \"' + path + '\"');\n }\n\n const next = path.charAt(end + 1);\n switch (next) {\n case encodedSeparatorChar:\n const currentPiece = path.substring(start, end);\n let segment;\n if (segmentBuilder.length === 0) {\n // Avoid copying for the common case of a segment that excludes \\0\n // and \\001\n segment = currentPiece;\n } else {\n segmentBuilder += currentPiece;\n segment = segmentBuilder;\n segmentBuilder = '';\n }\n segments.push(segment);\n break;\n case encodedNul:\n segmentBuilder += path.substring(start, end);\n segmentBuilder += '\\0';\n break;\n case encodedEscape:\n // The escape character can be used in the output to encode itself.\n segmentBuilder += path.substring(start, end + 1);\n break;\n default:\n fail('Invalid encoded resource path: \"' + path + '\"');\n }\n\n start = end + 2;\n }\n\n return new ResourcePath(segments);\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 { ResourcePath } from '../model/path';\nimport { debugAssert } from '../util/assert';\nimport { SortedSet } from '../util/sorted_set';\nimport { IndexManager } from './index_manager';\nimport { PersistenceTransaction } from './persistence';\nimport { PersistencePromise } from './persistence_promise';\n\n/**\n * An in-memory implementation of IndexManager.\n */\nexport class MemoryIndexManager implements IndexManager {\n private collectionParentIndex = new MemoryCollectionParentIndex();\n\n addToCollectionParentIndex(\n transaction: PersistenceTransaction,\n collectionPath: ResourcePath\n ): PersistencePromise<void> {\n this.collectionParentIndex.add(collectionPath);\n return PersistencePromise.resolve();\n }\n\n getCollectionParents(\n transaction: PersistenceTransaction,\n collectionId: string\n ): PersistencePromise<ResourcePath[]> {\n return PersistencePromise.resolve(\n this.collectionParentIndex.getEntries(collectionId)\n );\n }\n}\n\n/**\n * Internal implementation of the collection-parent index exposed by MemoryIndexManager.\n * Also used for in-memory caching by IndexedDbIndexManager and initial index population\n * in indexeddb_schema.ts\n */\nexport class MemoryCollectionParentIndex {\n private index = {} as {\n [collectionId: string]: SortedSet<ResourcePath>;\n };\n\n // Returns false if the entry already existed.\n add(collectionPath: ResourcePath): boolean {\n debugAssert(collectionPath.length % 2 === 1, 'Expected a collection path.');\n const collectionId = collectionPath.lastSegment();\n const parentPath = collectionPath.popLast();\n const existingParents =\n this.index[collectionId] ||\n new SortedSet<ResourcePath>(ResourcePath.comparator);\n const added = !existingParents.has(parentPath);\n this.index[collectionId] = existingParents.add(parentPath);\n return added;\n }\n\n has(collectionPath: ResourcePath): boolean {\n const collectionId = collectionPath.lastSegment();\n const parentPath = collectionPath.popLast();\n const existingParents = this.index[collectionId];\n return existingParents && existingParents.has(parentPath);\n }\n\n getEntries(collectionId: string): ResourcePath[] {\n const parentPaths =\n this.index[collectionId] ||\n new SortedSet<ResourcePath>(ResourcePath.comparator);\n return parentPaths.toArray();\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 { ResourcePath } from '../model/path';\nimport { debugAssert } from '../util/assert';\nimport { immediateSuccessor } from '../util/misc';\nimport {\n decodeResourcePath,\n encodeResourcePath\n} from './encoded_resource_path';\nimport { IndexManager } from './index_manager';\nimport { IndexedDbPersistence } from './indexeddb_persistence';\nimport { DbCollectionParent, DbCollectionParentKey } from './indexeddb_schema';\nimport { MemoryCollectionParentIndex } from './memory_index_manager';\nimport { PersistenceTransaction } from './persistence';\nimport { PersistencePromise } from './persistence_promise';\nimport { SimpleDbStore } from './simple_db';\n\n/**\n * A persisted implementation of IndexManager.\n */\nexport class IndexedDbIndexManager implements IndexManager {\n /**\n * An in-memory copy of the index entries we've already written since the SDK\n * launched. Used to avoid re-writing the same entry repeatedly.\n *\n * This is *NOT* a complete cache of what's in persistence and so can never be used to\n * satisfy reads.\n */\n private collectionParentsCache = new MemoryCollectionParentIndex();\n\n /**\n * Adds a new entry to the collection parent index.\n *\n * Repeated calls for the same collectionPath should be avoided within a\n * transaction as IndexedDbIndexManager only caches writes once a transaction\n * has been committed.\n */\n addToCollectionParentIndex(\n transaction: PersistenceTransaction,\n collectionPath: ResourcePath\n ): PersistencePromise<void> {\n debugAssert(collectionPath.length % 2 === 1, 'Expected a collection path.');\n if (!this.collectionParentsCache.has(collectionPath)) {\n const collectionId = collectionPath.lastSegment();\n const parentPath = collectionPath.popLast();\n\n transaction.addOnCommittedListener(() => {\n // Add the collection to the in memory cache only if the transaction was\n // successfully committed.\n this.collectionParentsCache.add(collectionPath);\n });\n\n const collectionParent: DbCollectionParent = {\n collectionId,\n parent: encodeResourcePath(parentPath)\n };\n return collectionParentsStore(transaction).put(collectionParent);\n }\n return PersistencePromise.resolve();\n }\n\n getCollectionParents(\n transaction: PersistenceTransaction,\n collectionId: string\n ): PersistencePromise<ResourcePath[]> {\n const parentPaths = [] as ResourcePath[];\n const range = IDBKeyRange.bound(\n [collectionId, ''],\n [immediateSuccessor(collectionId), ''],\n /*lowerOpen=*/ false,\n /*upperOpen=*/ true\n );\n return collectionParentsStore(transaction)\n .loadAll(range)\n .next(entries => {\n for (const entry of entries) {\n // This collectionId guard shouldn't be necessary (and isn't as long\n // as we're running in a real browser), but there's a bug in\n // indexeddbshim that breaks our range in our tests running in node:\n // https://github.com/axemclion/IndexedDBShim/issues/334\n if (entry.collectionId !== collectionId) {\n break;\n }\n parentPaths.push(decodeResourcePath(entry.parent));\n }\n return parentPaths;\n });\n }\n}\n\n/**\n * Helper to get a typed SimpleDbStore for the collectionParents\n * document store.\n */\nfunction collectionParentsStore(\n txn: PersistenceTransaction\n): SimpleDbStore<DbCollectionParentKey, DbCollectionParent> {\n return IndexedDbPersistence.getStore<\n DbCollectionParentKey,\n DbCollectionParent\n >(txn, DbCollectionParent.store);\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 { DocumentKeySet, NullableMaybeDocumentMap } from '../model/collections';\nimport { MaybeDocument } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport { debugAssert } from '../util/assert';\nimport { ObjectMap } from '../util/obj_map';\n\nimport { PersistenceTransaction } from './persistence';\nimport { PersistencePromise } from './persistence_promise';\nimport { SnapshotVersion } from '../core/snapshot_version';\n\n/**\n * An in-memory buffer of entries to be written to a RemoteDocumentCache.\n * It can be used to batch up a set of changes to be written to the cache, but\n * additionally supports reading entries back with the `getEntry()` method,\n * falling back to the underlying RemoteDocumentCache if no entry is\n * buffered.\n *\n * Entries added to the cache *must* be read first. This is to facilitate\n * calculating the size delta of the pending changes.\n *\n * PORTING NOTE: This class was implemented then removed from other platforms.\n * If byte-counting ends up being needed on the other platforms, consider\n * porting this class as part of that implementation work.\n */\nexport abstract class RemoteDocumentChangeBuffer {\n // A mapping of document key to the new cache entry that should be written (or null if any\n // existing cache entry should be removed).\n protected changes: ObjectMap<\n DocumentKey,\n MaybeDocument | null\n > = new ObjectMap(key => key.toString());\n\n // The read time to use for all added documents in this change buffer.\n private _readTime: SnapshotVersion | undefined;\n\n private changesApplied = false;\n\n protected abstract getFromCache(\n transaction: PersistenceTransaction,\n documentKey: DocumentKey\n ): PersistencePromise<MaybeDocument | null>;\n\n protected abstract getAllFromCache(\n transaction: PersistenceTransaction,\n documentKeys: DocumentKeySet\n ): PersistencePromise<NullableMaybeDocumentMap>;\n\n protected abstract applyChanges(\n transaction: PersistenceTransaction\n ): PersistencePromise<void>;\n\n protected set readTime(value: SnapshotVersion) {\n // Right now (for simplicity) we just track a single readTime for all the\n // added entries since we expect them to all be the same, but we could\n // rework to store per-entry readTimes if necessary.\n debugAssert(\n this._readTime === undefined || this._readTime.isEqual(value),\n 'All changes in a RemoteDocumentChangeBuffer must have the same read time'\n );\n this._readTime = value;\n }\n\n protected get readTime(): SnapshotVersion {\n debugAssert(\n this._readTime !== undefined,\n 'Read time is not set. All removeEntry() calls must include a readTime if `trackRemovals` is used.'\n );\n return this._readTime;\n }\n\n /**\n * Buffers a `RemoteDocumentCache.addEntry()` call.\n *\n * You can only modify documents that have already been retrieved via\n * `getEntry()/getEntries()` (enforced via IndexedDbs `apply()`).\n */\n addEntry(maybeDocument: MaybeDocument, readTime: SnapshotVersion): void {\n this.assertNotApplied();\n this.readTime = readTime;\n this.changes.set(maybeDocument.key, maybeDocument);\n }\n\n /**\n * Buffers a `RemoteDocumentCache.removeEntry()` call.\n *\n * You can only remove documents that have already been retrieved via\n * `getEntry()/getEntries()` (enforced via IndexedDbs `apply()`).\n */\n removeEntry(key: DocumentKey, readTime?: SnapshotVersion): void {\n this.assertNotApplied();\n if (readTime) {\n this.readTime = readTime;\n }\n this.changes.set(key, null);\n }\n\n /**\n * Looks up an entry in the cache. The buffered changes will first be checked,\n * and if no buffered change applies, this will forward to\n * `RemoteDocumentCache.getEntry()`.\n *\n * @param transaction The transaction in which to perform any persistence\n * operations.\n * @param documentKey The key of the entry to look up.\n * @return The cached Document or NoDocument entry, or null if we have nothing\n * cached.\n */\n getEntry(\n transaction: PersistenceTransaction,\n documentKey: DocumentKey\n ): PersistencePromise<MaybeDocument | null> {\n this.assertNotApplied();\n const bufferedEntry = this.changes.get(documentKey);\n if (bufferedEntry !== undefined) {\n return PersistencePromise.resolve<MaybeDocument | null>(bufferedEntry);\n } else {\n return this.getFromCache(transaction, documentKey);\n }\n }\n\n /**\n * Looks up several entries in the cache, forwarding to\n * `RemoteDocumentCache.getEntry()`.\n *\n * @param transaction The transaction in which to perform any persistence\n * operations.\n * @param documentKeys The keys of the entries to look up.\n * @return A map of cached `Document`s or `NoDocument`s, indexed by key. If an\n * entry cannot be found, the corresponding key will be mapped to a null\n * value.\n */\n getEntries(\n transaction: PersistenceTransaction,\n documentKeys: DocumentKeySet\n ): PersistencePromise<NullableMaybeDocumentMap> {\n return this.getAllFromCache(transaction, documentKeys);\n }\n\n /**\n * Applies buffered changes to the underlying RemoteDocumentCache, using\n * the provided transaction.\n */\n apply(transaction: PersistenceTransaction): PersistencePromise<void> {\n this.assertNotApplied();\n this.changesApplied = true;\n return this.applyChanges(transaction);\n }\n\n /** Helper to assert this.changes is not null */\n protected assertNotApplied(): void {\n debugAssert(!this.changesApplied, 'Changes have already been applied.');\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 { Query } from '../core/query';\nimport {\n DocumentKeySet,\n DocumentMap,\n documentMap,\n DocumentSizeEntries,\n DocumentSizeEntry,\n MaybeDocumentMap,\n maybeDocumentMap,\n nullableMaybeDocumentMap,\n NullableMaybeDocumentMap\n} from '../model/collections';\nimport { Document, MaybeDocument, NoDocument } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport { ResourcePath } from '../model/path';\nimport { primitiveComparator } from '../util/misc';\nimport { SortedMap } from '../util/sorted_map';\nimport { SortedSet } from '../util/sorted_set';\n\nimport { SnapshotVersion } from '../core/snapshot_version';\nimport { debugAssert, fail, hardAssert } from '../util/assert';\nimport { IndexManager } from './index_manager';\nimport { IndexedDbPersistence } from './indexeddb_persistence';\nimport {\n DbRemoteDocument,\n DbRemoteDocumentGlobal,\n DbRemoteDocumentGlobalKey,\n DbRemoteDocumentKey\n} from './indexeddb_schema';\nimport { LocalSerializer } from './local_serializer';\nimport { PersistenceTransaction } from './persistence';\nimport { PersistencePromise } from './persistence_promise';\nimport { RemoteDocumentCache } from './remote_document_cache';\nimport { RemoteDocumentChangeBuffer } from './remote_document_change_buffer';\nimport { IterateOptions, SimpleDbStore } from './simple_db';\nimport { ObjectMap } from '../util/obj_map';\n\nexport class IndexedDbRemoteDocumentCache implements RemoteDocumentCache {\n /**\n * @param {LocalSerializer} serializer The document serializer.\n * @param {IndexManager} indexManager The query indexes that need to be maintained.\n */\n constructor(\n readonly serializer: LocalSerializer,\n private readonly indexManager: IndexManager\n ) {}\n\n /**\n * Adds the supplied entries to the cache.\n *\n * All calls of `addEntry` are required to go through the RemoteDocumentChangeBuffer\n * returned by `newChangeBuffer()` to ensure proper accounting of metadata.\n */\n private addEntry(\n transaction: PersistenceTransaction,\n key: DocumentKey,\n doc: DbRemoteDocument\n ): PersistencePromise<void> {\n const documentStore = remoteDocumentsStore(transaction);\n return documentStore.put(dbKey(key), doc);\n }\n\n /**\n * Removes a document from the cache.\n *\n * All calls of `removeEntry` are required to go through the RemoteDocumentChangeBuffer\n * returned by `newChangeBuffer()` to ensure proper accounting of metadata.\n */\n private removeEntry(\n transaction: PersistenceTransaction,\n documentKey: DocumentKey\n ): PersistencePromise<void> {\n const store = remoteDocumentsStore(transaction);\n const key = dbKey(documentKey);\n return store.delete(key);\n }\n\n /**\n * Updates the current cache size.\n *\n * Callers to `addEntry()` and `removeEntry()` *must* call this afterwards to update the\n * cache's metadata.\n */\n private updateMetadata(\n transaction: PersistenceTransaction,\n sizeDelta: number\n ): PersistencePromise<void> {\n return this.getMetadata(transaction).next(metadata => {\n metadata.byteSize += sizeDelta;\n return this.setMetadata(transaction, metadata);\n });\n }\n\n getEntry(\n transaction: PersistenceTransaction,\n documentKey: DocumentKey\n ): PersistencePromise<MaybeDocument | null> {\n return remoteDocumentsStore(transaction)\n .get(dbKey(documentKey))\n .next(dbRemoteDoc => {\n return this.maybeDecodeDocument(dbRemoteDoc);\n });\n }\n\n /**\n * Looks up an entry in the cache.\n *\n * @param documentKey The key of the entry to look up.\n * @return The cached MaybeDocument entry and its size, or null if we have nothing cached.\n */\n getSizedEntry(\n transaction: PersistenceTransaction,\n documentKey: DocumentKey\n ): PersistencePromise<DocumentSizeEntry | null> {\n return remoteDocumentsStore(transaction)\n .get(dbKey(documentKey))\n .next(dbRemoteDoc => {\n const doc = this.maybeDecodeDocument(dbRemoteDoc);\n return doc\n ? {\n maybeDocument: doc,\n size: dbDocumentSize(dbRemoteDoc!)\n }\n : null;\n });\n }\n\n getEntries(\n transaction: PersistenceTransaction,\n documentKeys: DocumentKeySet\n ): PersistencePromise<NullableMaybeDocumentMap> {\n let results = nullableMaybeDocumentMap();\n return this.forEachDbEntry(\n transaction,\n documentKeys,\n (key, dbRemoteDoc) => {\n const doc = this.maybeDecodeDocument(dbRemoteDoc);\n results = results.insert(key, doc);\n }\n ).next(() => results);\n }\n\n /**\n * Looks up several entries in the cache.\n *\n * @param documentKeys The set of keys entries to look up.\n * @return A map of MaybeDocuments indexed by key (if a document cannot be\n * found, the key will be mapped to null) and a map of sizes indexed by\n * key (zero if the key cannot be found).\n */\n getSizedEntries(\n transaction: PersistenceTransaction,\n documentKeys: DocumentKeySet\n ): PersistencePromise<DocumentSizeEntries> {\n let results = nullableMaybeDocumentMap();\n let sizeMap = new SortedMap<DocumentKey, number>(DocumentKey.comparator);\n return this.forEachDbEntry(\n transaction,\n documentKeys,\n (key, dbRemoteDoc) => {\n const doc = this.maybeDecodeDocument(dbRemoteDoc);\n if (doc) {\n results = results.insert(key, doc);\n sizeMap = sizeMap.insert(key, dbDocumentSize(dbRemoteDoc!));\n } else {\n results = results.insert(key, null);\n sizeMap = sizeMap.insert(key, 0);\n }\n }\n ).next(() => {\n return { maybeDocuments: results, sizeMap };\n });\n }\n\n private forEachDbEntry(\n transaction: PersistenceTransaction,\n documentKeys: DocumentKeySet,\n callback: (key: DocumentKey, doc: DbRemoteDocument | null) => void\n ): PersistencePromise<void> {\n if (documentKeys.isEmpty()) {\n return PersistencePromise.resolve();\n }\n\n const range = IDBKeyRange.bound(\n documentKeys.first()!.path.toArray(),\n documentKeys.last()!.path.toArray()\n );\n const keyIter = documentKeys.getIterator();\n let nextKey: DocumentKey | null = keyIter.getNext();\n\n return remoteDocumentsStore(transaction)\n .iterate({ range }, (potentialKeyRaw, dbRemoteDoc, control) => {\n const potentialKey = DocumentKey.fromSegments(potentialKeyRaw);\n\n // Go through keys not found in cache.\n while (nextKey && DocumentKey.comparator(nextKey!, potentialKey) < 0) {\n callback(nextKey!, null);\n nextKey = keyIter.getNext();\n }\n\n if (nextKey && nextKey!.isEqual(potentialKey)) {\n // Key found in cache.\n callback(nextKey!, dbRemoteDoc);\n nextKey = keyIter.hasNext() ? keyIter.getNext() : null;\n }\n\n // Skip to the next key (if there is one).\n if (nextKey) {\n control.skip(nextKey!.path.toArray());\n } else {\n control.done();\n }\n })\n .next(() => {\n // The rest of the keys are not in the cache. One case where `iterate`\n // above won't go through them is when the cache is empty.\n while (nextKey) {\n callback(nextKey!, null);\n nextKey = keyIter.hasNext() ? keyIter.getNext() : null;\n }\n });\n }\n\n getDocumentsMatchingQuery(\n transaction: PersistenceTransaction,\n query: Query,\n sinceReadTime: SnapshotVersion\n ): PersistencePromise<DocumentMap> {\n debugAssert(\n !query.isCollectionGroupQuery(),\n 'CollectionGroup queries should be handled in LocalDocumentsView'\n );\n let results = documentMap();\n\n const immediateChildrenPathLength = query.path.length + 1;\n\n const iterationOptions: IterateOptions = {};\n if (sinceReadTime.isEqual(SnapshotVersion.min())) {\n // Documents are ordered by key, so we can use a prefix scan to narrow\n // down the documents we need to match the query against.\n const startKey = query.path.toArray();\n iterationOptions.range = IDBKeyRange.lowerBound(startKey);\n } else {\n // Execute an index-free query and filter by read time. This is safe\n // since all document changes to queries that have a\n // lastLimboFreeSnapshotVersion (`sinceReadTime`) have a read time set.\n const collectionKey = query.path.toArray();\n const readTimeKey = this.serializer.toDbTimestampKey(sinceReadTime);\n iterationOptions.range = IDBKeyRange.lowerBound(\n [collectionKey, readTimeKey],\n /* open= */ true\n );\n iterationOptions.index = DbRemoteDocument.collectionReadTimeIndex;\n }\n\n return remoteDocumentsStore(transaction)\n .iterate(iterationOptions, (key, dbRemoteDoc, control) => {\n // The query is actually returning any path that starts with the query\n // path prefix which may include documents in subcollections. For\n // example, a query on 'rooms' will return rooms/abc/messages/xyx but we\n // shouldn't match it. Fix this by discarding rows with document keys\n // more than one segment longer than the query path.\n if (key.length !== immediateChildrenPathLength) {\n return;\n }\n\n const maybeDoc = this.serializer.fromDbRemoteDocument(dbRemoteDoc);\n if (!query.path.isPrefixOf(maybeDoc.key.path)) {\n control.done();\n } else if (maybeDoc instanceof Document && query.matches(maybeDoc)) {\n results = results.insert(maybeDoc.key, maybeDoc);\n }\n })\n .next(() => results);\n }\n\n /**\n * Returns the set of documents that have changed since the specified read\n * time.\n */\n // PORTING NOTE: This is only used for multi-tab synchronization.\n getNewDocumentChanges(\n transaction: PersistenceTransaction,\n sinceReadTime: SnapshotVersion\n ): PersistencePromise<{\n changedDocs: MaybeDocumentMap;\n readTime: SnapshotVersion;\n }> {\n let changedDocs = maybeDocumentMap();\n\n let lastReadTime = this.serializer.toDbTimestampKey(sinceReadTime);\n\n const documentsStore = remoteDocumentsStore(transaction);\n const range = IDBKeyRange.lowerBound(lastReadTime, true);\n return documentsStore\n .iterate(\n { index: DbRemoteDocument.readTimeIndex, range },\n (_, dbRemoteDoc) => {\n // Unlike `getEntry()` and others, `getNewDocumentChanges()` parses\n // the documents directly since we want to keep sentinel deletes.\n const doc = this.serializer.fromDbRemoteDocument(dbRemoteDoc);\n changedDocs = changedDocs.insert(doc.key, doc);\n lastReadTime = dbRemoteDoc.readTime!;\n }\n )\n .next(() => {\n return {\n changedDocs,\n readTime: this.serializer.fromDbTimestampKey(lastReadTime)\n };\n });\n }\n\n /**\n * Returns the read time of the most recently read document in the cache, or\n * SnapshotVersion.min() if not available.\n */\n // PORTING NOTE: This is only used for multi-tab synchronization.\n getLastReadTime(\n transaction: PersistenceTransaction\n ): PersistencePromise<SnapshotVersion> {\n const documentsStore = remoteDocumentsStore(transaction);\n\n // If there are no existing entries, we return SnapshotVersion.min().\n let readTime = SnapshotVersion.min();\n\n return documentsStore\n .iterate(\n { index: DbRemoteDocument.readTimeIndex, reverse: true },\n (key, dbRemoteDoc, control) => {\n if (dbRemoteDoc.readTime) {\n readTime = this.serializer.fromDbTimestampKey(dbRemoteDoc.readTime);\n }\n control.done();\n }\n )\n .next(() => readTime);\n }\n\n newChangeBuffer(options?: {\n trackRemovals: boolean;\n }): RemoteDocumentChangeBuffer {\n return new IndexedDbRemoteDocumentCache.RemoteDocumentChangeBuffer(\n this,\n !!options && options.trackRemovals\n );\n }\n\n getSize(txn: PersistenceTransaction): PersistencePromise<number> {\n return this.getMetadata(txn).next(metadata => metadata.byteSize);\n }\n\n private getMetadata(\n txn: PersistenceTransaction\n ): PersistencePromise<DbRemoteDocumentGlobal> {\n return documentGlobalStore(txn)\n .get(DbRemoteDocumentGlobal.key)\n .next(metadata => {\n hardAssert(!!metadata, 'Missing document cache metadata');\n return metadata!;\n });\n }\n\n private setMetadata(\n txn: PersistenceTransaction,\n metadata: DbRemoteDocumentGlobal\n ): PersistencePromise<void> {\n return documentGlobalStore(txn).put(DbRemoteDocumentGlobal.key, metadata);\n }\n\n /**\n * Decodes `remoteDoc` and returns the document (or null, if the document\n * corresponds to the format used for sentinel deletes).\n */\n private maybeDecodeDocument(\n dbRemoteDoc: DbRemoteDocument | null\n ): MaybeDocument | null {\n if (dbRemoteDoc) {\n const doc = this.serializer.fromDbRemoteDocument(dbRemoteDoc);\n if (\n doc instanceof NoDocument &&\n doc.version.isEqual(SnapshotVersion.min())\n ) {\n // The document is a sentinel removal and should only be used in the\n // `getNewDocumentChanges()`.\n return null;\n }\n\n return doc;\n }\n return null;\n }\n\n /**\n * Handles the details of adding and updating documents in the IndexedDbRemoteDocumentCache.\n *\n * Unlike the MemoryRemoteDocumentChangeBuffer, the IndexedDb implementation computes the size\n * delta for all submitted changes. This avoids having to re-read all documents from IndexedDb\n * when we apply the changes.\n */\n private static RemoteDocumentChangeBuffer = class extends RemoteDocumentChangeBuffer {\n // A map of document sizes prior to applying the changes in this buffer.\n protected documentSizes: ObjectMap<\n DocumentKey,\n number\n > = new ObjectMap(key => key.toString());\n\n /**\n * @param documentCache The IndexedDbRemoteDocumentCache to apply the changes to.\n * @param trackRemovals Whether to create sentinel deletes that can be tracked by\n * `getNewDocumentChanges()`.\n */\n constructor(\n private readonly documentCache: IndexedDbRemoteDocumentCache,\n private readonly trackRemovals: boolean\n ) {\n super();\n }\n\n protected applyChanges(\n transaction: PersistenceTransaction\n ): PersistencePromise<void> {\n const promises: Array<PersistencePromise<void>> = [];\n\n let sizeDelta = 0;\n\n let collectionParents = new SortedSet<ResourcePath>((l, r) =>\n primitiveComparator(l.canonicalString(), r.canonicalString())\n );\n\n this.changes.forEach((key, maybeDocument) => {\n const previousSize = this.documentSizes.get(key);\n debugAssert(\n previousSize !== undefined,\n `Cannot modify a document that wasn't read (for ${key})`\n );\n if (maybeDocument) {\n debugAssert(\n !this.readTime.isEqual(SnapshotVersion.min()),\n 'Cannot add a document with a read time of zero'\n );\n const doc = this.documentCache.serializer.toDbRemoteDocument(\n maybeDocument,\n this.readTime\n );\n collectionParents = collectionParents.add(key.path.popLast());\n\n const size = dbDocumentSize(doc);\n sizeDelta += size - previousSize!;\n promises.push(this.documentCache.addEntry(transaction, key, doc));\n } else {\n sizeDelta -= previousSize!;\n if (this.trackRemovals) {\n // In order to track removals, we store a \"sentinel delete\" in the\n // RemoteDocumentCache. This entry is represented by a NoDocument\n // with a version of 0 and ignored by `maybeDecodeDocument()` but\n // preserved in `getNewDocumentChanges()`.\n const deletedDoc = this.documentCache.serializer.toDbRemoteDocument(\n new NoDocument(key, SnapshotVersion.min()),\n this.readTime\n );\n promises.push(\n this.documentCache.addEntry(transaction, key, deletedDoc)\n );\n } else {\n promises.push(this.documentCache.removeEntry(transaction, key));\n }\n }\n });\n\n collectionParents.forEach(parent => {\n promises.push(\n this.documentCache.indexManager.addToCollectionParentIndex(\n transaction,\n parent\n )\n );\n });\n\n promises.push(this.documentCache.updateMetadata(transaction, sizeDelta));\n\n return PersistencePromise.waitFor(promises);\n }\n\n protected getFromCache(\n transaction: PersistenceTransaction,\n documentKey: DocumentKey\n ): PersistencePromise<MaybeDocument | null> {\n // Record the size of everything we load from the cache so we can compute a delta later.\n return this.documentCache\n .getSizedEntry(transaction, documentKey)\n .next(getResult => {\n if (getResult === null) {\n this.documentSizes.set(documentKey, 0);\n return null;\n } else {\n this.documentSizes.set(documentKey, getResult.size);\n return getResult.maybeDocument;\n }\n });\n }\n\n protected getAllFromCache(\n transaction: PersistenceTransaction,\n documentKeys: DocumentKeySet\n ): PersistencePromise<NullableMaybeDocumentMap> {\n // Record the size of everything we load from the cache so we can compute\n // a delta later.\n return this.documentCache\n .getSizedEntries(transaction, documentKeys)\n .next(({ maybeDocuments, sizeMap }) => {\n // Note: `getAllFromCache` returns two maps instead of a single map from\n // keys to `DocumentSizeEntry`s. This is to allow returning the\n // `NullableMaybeDocumentMap` directly, without a conversion.\n sizeMap.forEach((documentKey, size) => {\n this.documentSizes.set(documentKey, size);\n });\n return maybeDocuments;\n });\n }\n };\n}\n\nfunction documentGlobalStore(\n txn: PersistenceTransaction\n): SimpleDbStore<DbRemoteDocumentGlobalKey, DbRemoteDocumentGlobal> {\n return IndexedDbPersistence.getStore<\n DbRemoteDocumentGlobalKey,\n DbRemoteDocumentGlobal\n >(txn, DbRemoteDocumentGlobal.store);\n}\n\n/**\n * Helper to get a typed SimpleDbStore for the remoteDocuments object store.\n */\nfunction remoteDocumentsStore(\n txn: PersistenceTransaction\n): SimpleDbStore<DbRemoteDocumentKey, DbRemoteDocument> {\n return IndexedDbPersistence.getStore<DbRemoteDocumentKey, DbRemoteDocument>(\n txn,\n DbRemoteDocument.store\n );\n}\n\nfunction dbKey(docKey: DocumentKey): DbRemoteDocumentKey {\n return docKey.path.toArray();\n}\n\n/**\n * Retrusn an approximate size for the given document.\n */\nexport function dbDocumentSize(doc: DbRemoteDocument): number {\n let value: unknown;\n if (doc.document) {\n value = doc.document;\n } else if (doc.unknownDocument) {\n value = doc.unknownDocument;\n } else if (doc.noDocument) {\n value = doc.noDocument;\n } else {\n throw fail('Unknown remote document type');\n }\n return JSON.stringify(value).length;\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 { TargetId } from './types';\n\n/** Offset to ensure non-overlapping target ids. */\nconst OFFSET = 2;\n\n/**\n * Generates monotonically increasing target IDs for sending targets to the\n * watch stream.\n *\n * The client constructs two generators, one for the target cache, and one for\n * for the sync engine (to generate limbo documents targets). These\n * generators produce non-overlapping IDs (by using even and odd IDs\n * respectively).\n *\n * By separating the target ID space, the query cache can generate target IDs\n * that persist across client restarts, while sync engine can independently\n * generate in-memory target IDs that are transient and can be reused after a\n * restart.\n */\nexport class TargetIdGenerator {\n constructor(private lastId: number) {}\n\n next(): TargetId {\n this.lastId += OFFSET;\n return this.lastId;\n }\n\n static forTargetCache(): TargetIdGenerator {\n // The target cache generator must return '2' in its first call to `next()`\n // as there is no differentiation in the protocol layer between an unset\n // number and the number '0'. If we were to sent a target with target ID\n // '0', the backend would consider it unset and replace it with its own ID.\n return new TargetIdGenerator(2 - OFFSET);\n }\n\n static forSyncEngine(): TargetIdGenerator {\n // Sync engine assigns target IDs for limbo document detection.\n return new TargetIdGenerator(1 - OFFSET);\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 { Timestamp } from '../api/timestamp';\nimport { SnapshotVersion } from '../core/snapshot_version';\nimport { ListenSequenceNumber, TargetId } from '../core/types';\nimport { DocumentKeySet, documentKeySet } from '../model/collections';\nimport { DocumentKey } from '../model/document_key';\nimport { hardAssert } from '../util/assert';\nimport { immediateSuccessor } from '../util/misc';\nimport { TargetIdGenerator } from '../core/target_id_generator';\nimport {\n decodeResourcePath,\n encodeResourcePath\n} from './encoded_resource_path';\nimport {\n IndexedDbLruDelegate,\n IndexedDbPersistence\n} from './indexeddb_persistence';\nimport {\n DbTarget,\n DbTargetDocument,\n DbTargetDocumentKey,\n DbTargetGlobal,\n DbTargetGlobalKey,\n DbTargetKey\n} from './indexeddb_schema';\nimport { LocalSerializer } from './local_serializer';\nimport { ActiveTargets } from './lru_garbage_collector';\nimport { PersistenceTransaction } from './persistence';\nimport { PersistencePromise } from './persistence_promise';\nimport { TargetCache } from './target_cache';\nimport { TargetData } from './target_data';\nimport { SimpleDbStore } from './simple_db';\nimport { Target } from '../core/target';\n\nexport class IndexedDbTargetCache implements TargetCache {\n constructor(\n private readonly referenceDelegate: IndexedDbLruDelegate,\n private serializer: LocalSerializer\n ) {}\n\n // PORTING NOTE: We don't cache global metadata for the target cache, since\n // some of it (in particular `highestTargetId`) can be modified by secondary\n // tabs. We could perhaps be more granular (and e.g. still cache\n // `lastRemoteSnapshotVersion` in memory) but for simplicity we currently go\n // to IndexedDb whenever we need to read metadata. We can revisit if it turns\n // out to have a meaningful performance impact.\n\n allocateTargetId(\n transaction: PersistenceTransaction\n ): PersistencePromise<TargetId> {\n return this.retrieveMetadata(transaction).next(metadata => {\n const targetIdGenerator = new TargetIdGenerator(metadata.highestTargetId);\n metadata.highestTargetId = targetIdGenerator.next();\n return this.saveMetadata(transaction, metadata).next(\n () => metadata.highestTargetId\n );\n });\n }\n\n getLastRemoteSnapshotVersion(\n transaction: PersistenceTransaction\n ): PersistencePromise<SnapshotVersion> {\n return this.retrieveMetadata(transaction).next(metadata => {\n return SnapshotVersion.fromTimestamp(\n new Timestamp(\n metadata.lastRemoteSnapshotVersion.seconds,\n metadata.lastRemoteSnapshotVersion.nanoseconds\n )\n );\n });\n }\n\n getHighestSequenceNumber(\n transaction: PersistenceTransaction\n ): PersistencePromise<ListenSequenceNumber> {\n return this.retrieveMetadata(transaction).next(\n targetGlobal => targetGlobal.highestListenSequenceNumber\n );\n }\n\n setTargetsMetadata(\n transaction: PersistenceTransaction,\n highestListenSequenceNumber: number,\n lastRemoteSnapshotVersion?: SnapshotVersion\n ): PersistencePromise<void> {\n return this.retrieveMetadata(transaction).next(metadata => {\n metadata.highestListenSequenceNumber = highestListenSequenceNumber;\n if (lastRemoteSnapshotVersion) {\n metadata.lastRemoteSnapshotVersion = lastRemoteSnapshotVersion.toTimestamp();\n }\n if (highestListenSequenceNumber > metadata.highestListenSequenceNumber) {\n metadata.highestListenSequenceNumber = highestListenSequenceNumber;\n }\n return this.saveMetadata(transaction, metadata);\n });\n }\n\n addTargetData(\n transaction: PersistenceTransaction,\n targetData: TargetData\n ): PersistencePromise<void> {\n return this.saveTargetData(transaction, targetData).next(() => {\n return this.retrieveMetadata(transaction).next(metadata => {\n metadata.targetCount += 1;\n this.updateMetadataFromTargetData(targetData, metadata);\n return this.saveMetadata(transaction, metadata);\n });\n });\n }\n\n updateTargetData(\n transaction: PersistenceTransaction,\n targetData: TargetData\n ): PersistencePromise<void> {\n return this.saveTargetData(transaction, targetData);\n }\n\n removeTargetData(\n transaction: PersistenceTransaction,\n targetData: TargetData\n ): PersistencePromise<void> {\n return this.removeMatchingKeysForTargetId(transaction, targetData.targetId)\n .next(() => targetsStore(transaction).delete(targetData.targetId))\n .next(() => this.retrieveMetadata(transaction))\n .next(metadata => {\n hardAssert(\n metadata.targetCount > 0,\n 'Removing from an empty target cache'\n );\n metadata.targetCount -= 1;\n return this.saveMetadata(transaction, metadata);\n });\n }\n\n /**\n * Drops any targets with sequence number less than or equal to the upper bound, excepting those\n * present in `activeTargetIds`. Document associations for the removed targets are also removed.\n * Returns the number of targets removed.\n */\n removeTargets(\n txn: PersistenceTransaction,\n upperBound: ListenSequenceNumber,\n activeTargetIds: ActiveTargets\n ): PersistencePromise<number> {\n let count = 0;\n const promises: Array<PersistencePromise<void>> = [];\n return targetsStore(txn)\n .iterate((key, value) => {\n const targetData = this.serializer.fromDbTarget(value);\n if (\n targetData.sequenceNumber <= upperBound &&\n activeTargetIds.get(targetData.targetId) === null\n ) {\n count++;\n promises.push(this.removeTargetData(txn, targetData));\n }\n })\n .next(() => PersistencePromise.waitFor(promises))\n .next(() => count);\n }\n\n /**\n * Call provided function with each `TargetData` that we have cached.\n */\n forEachTarget(\n txn: PersistenceTransaction,\n f: (q: TargetData) => void\n ): PersistencePromise<void> {\n return targetsStore(txn).iterate((key, value) => {\n const targetData = this.serializer.fromDbTarget(value);\n f(targetData);\n });\n }\n\n private retrieveMetadata(\n transaction: PersistenceTransaction\n ): PersistencePromise<DbTargetGlobal> {\n return globalTargetStore(transaction)\n .get(DbTargetGlobal.key)\n .next(metadata => {\n hardAssert(metadata !== null, 'Missing metadata row.');\n return metadata;\n });\n }\n\n private saveMetadata(\n transaction: PersistenceTransaction,\n metadata: DbTargetGlobal\n ): PersistencePromise<void> {\n return globalTargetStore(transaction).put(DbTargetGlobal.key, metadata);\n }\n\n private saveTargetData(\n transaction: PersistenceTransaction,\n targetData: TargetData\n ): PersistencePromise<void> {\n return targetsStore(transaction).put(\n this.serializer.toDbTarget(targetData)\n );\n }\n\n /**\n * In-place updates the provided metadata to account for values in the given\n * TargetData. Saving is done separately. Returns true if there were any\n * changes to the metadata.\n */\n private updateMetadataFromTargetData(\n targetData: TargetData,\n metadata: DbTargetGlobal\n ): boolean {\n let updated = false;\n if (targetData.targetId > metadata.highestTargetId) {\n metadata.highestTargetId = targetData.targetId;\n updated = true;\n }\n\n if (targetData.sequenceNumber > metadata.highestListenSequenceNumber) {\n metadata.highestListenSequenceNumber = targetData.sequenceNumber;\n updated = true;\n }\n return updated;\n }\n\n getTargetCount(\n transaction: PersistenceTransaction\n ): PersistencePromise<number> {\n return this.retrieveMetadata(transaction).next(\n metadata => metadata.targetCount\n );\n }\n\n getTargetData(\n transaction: PersistenceTransaction,\n target: Target\n ): PersistencePromise<TargetData | null> {\n // Iterating by the canonicalId may yield more than one result because\n // canonicalId values are not required to be unique per target. This query\n // depends on the queryTargets index to be efficient.\n const canonicalId = target.canonicalId();\n const range = IDBKeyRange.bound(\n [canonicalId, Number.NEGATIVE_INFINITY],\n [canonicalId, Number.POSITIVE_INFINITY]\n );\n let result: TargetData | null = null;\n return targetsStore(transaction)\n .iterate(\n { range, index: DbTarget.queryTargetsIndexName },\n (key, value, control) => {\n const found = this.serializer.fromDbTarget(value);\n // After finding a potential match, check that the target is\n // actually equal to the requested target.\n if (target.isEqual(found.target)) {\n result = found;\n control.done();\n }\n }\n )\n .next(() => result);\n }\n\n addMatchingKeys(\n txn: PersistenceTransaction,\n keys: DocumentKeySet,\n targetId: TargetId\n ): PersistencePromise<void> {\n // PORTING NOTE: The reverse index (documentsTargets) is maintained by\n // IndexedDb.\n const promises: Array<PersistencePromise<void>> = [];\n const store = documentTargetStore(txn);\n keys.forEach(key => {\n const path = encodeResourcePath(key.path);\n promises.push(store.put(new DbTargetDocument(targetId, path)));\n promises.push(this.referenceDelegate.addReference(txn, targetId, key));\n });\n return PersistencePromise.waitFor(promises);\n }\n\n removeMatchingKeys(\n txn: PersistenceTransaction,\n keys: DocumentKeySet,\n targetId: TargetId\n ): PersistencePromise<void> {\n // PORTING NOTE: The reverse index (documentsTargets) is maintained by\n // IndexedDb.\n const store = documentTargetStore(txn);\n return PersistencePromise.forEach(keys, (key: DocumentKey) => {\n const path = encodeResourcePath(key.path);\n return PersistencePromise.waitFor([\n store.delete([targetId, path]),\n this.referenceDelegate.removeReference(txn, targetId, key)\n ]);\n });\n }\n\n removeMatchingKeysForTargetId(\n txn: PersistenceTransaction,\n targetId: TargetId\n ): PersistencePromise<void> {\n const store = documentTargetStore(txn);\n const range = IDBKeyRange.bound(\n [targetId],\n [targetId + 1],\n /*lowerOpen=*/ false,\n /*upperOpen=*/ true\n );\n return store.delete(range);\n }\n\n getMatchingKeysForTargetId(\n txn: PersistenceTransaction,\n targetId: TargetId\n ): PersistencePromise<DocumentKeySet> {\n const range = IDBKeyRange.bound(\n [targetId],\n [targetId + 1],\n /*lowerOpen=*/ false,\n /*upperOpen=*/ true\n );\n const store = documentTargetStore(txn);\n let result = documentKeySet();\n\n return store\n .iterate({ range, keysOnly: true }, (key, _, control) => {\n const path = decodeResourcePath(key[1]);\n const docKey = new DocumentKey(path);\n result = result.add(docKey);\n })\n .next(() => result);\n }\n\n containsKey(\n txn: PersistenceTransaction,\n key: DocumentKey\n ): PersistencePromise<boolean> {\n const path = encodeResourcePath(key.path);\n const range = IDBKeyRange.bound(\n [path],\n [immediateSuccessor(path)],\n /*lowerOpen=*/ false,\n /*upperOpen=*/ true\n );\n let count = 0;\n return documentTargetStore(txn!)\n .iterate(\n {\n index: DbTargetDocument.documentTargetsIndex,\n keysOnly: true,\n range\n },\n ([targetId, path], _, control) => {\n // Having a sentinel row for a document does not count as containing that document;\n // For the target cache, containing the document means the document is part of some\n // target.\n if (targetId !== 0) {\n count++;\n control.done();\n }\n }\n )\n .next(() => count > 0);\n }\n\n /**\n * Looks up a TargetData entry by target ID.\n *\n * @param targetId The target ID of the TargetData entry to look up.\n * @return The cached TargetData entry, or null if the cache has no entry for\n * the target.\n */\n // PORTING NOTE: Multi-tab only.\n getTargetDataForTarget(\n transaction: PersistenceTransaction,\n targetId: TargetId\n ): PersistencePromise<TargetData | null> {\n return targetsStore(transaction)\n .get(targetId)\n .next(found => {\n if (found) {\n return this.serializer.fromDbTarget(found);\n } else {\n return null;\n }\n });\n }\n}\n\n/**\n * Helper to get a typed SimpleDbStore for the queries object store.\n */\nfunction targetsStore(\n txn: PersistenceTransaction\n): SimpleDbStore<DbTargetKey, DbTarget> {\n return IndexedDbPersistence.getStore<DbTargetKey, DbTarget>(\n txn,\n DbTarget.store\n );\n}\n\n/**\n * Helper to get a typed SimpleDbStore for the target globals object store.\n */\nfunction globalTargetStore(\n txn: PersistenceTransaction\n): SimpleDbStore<DbTargetGlobalKey, DbTargetGlobal> {\n return IndexedDbPersistence.getStore<DbTargetGlobalKey, DbTargetGlobal>(\n txn,\n DbTargetGlobal.store\n );\n}\n\n/**\n * Helper to get a typed SimpleDbStore for the document target object store.\n */\nexport function documentTargetStore(\n txn: PersistenceTransaction\n): SimpleDbStore<DbTargetDocumentKey, DbTargetDocument> {\n return IndexedDbPersistence.getStore<DbTargetDocumentKey, DbTargetDocument>(\n txn,\n DbTargetDocument.store\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 { Timestamp } from '../api/timestamp';\nimport { SnapshotVersion } from '../core/snapshot_version';\nimport {\n Document,\n MaybeDocument,\n NoDocument,\n UnknownDocument\n} from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport { MutationBatch } from '../model/mutation_batch';\nimport * as api from '../protos/firestore_proto_api';\nimport { JsonProtoSerializer } from '../remote/serializer';\nimport { debugAssert, fail } from '../util/assert';\nimport { ByteString } from '../util/byte_string';\nimport { Target } from '../core/target';\nimport {\n DbMutationBatch,\n DbNoDocument,\n DbQuery,\n DbRemoteDocument,\n DbTarget,\n DbTimestamp,\n DbTimestampKey,\n DbUnknownDocument\n} from './indexeddb_schema';\nimport { TargetData, TargetPurpose } from './target_data';\n\n/** Serializer for values stored in the LocalStore. */\nexport class LocalSerializer {\n constructor(private remoteSerializer: JsonProtoSerializer) {}\n\n /** Decodes a remote document from storage locally to a Document. */\n fromDbRemoteDocument(remoteDoc: DbRemoteDocument): MaybeDocument {\n if (remoteDoc.document) {\n return this.remoteSerializer.fromDocument(\n remoteDoc.document,\n !!remoteDoc.hasCommittedMutations\n );\n } else if (remoteDoc.noDocument) {\n const key = DocumentKey.fromSegments(remoteDoc.noDocument.path);\n const version = this.fromDbTimestamp(remoteDoc.noDocument.readTime);\n return new NoDocument(key, version, {\n hasCommittedMutations: !!remoteDoc.hasCommittedMutations\n });\n } else if (remoteDoc.unknownDocument) {\n const key = DocumentKey.fromSegments(remoteDoc.unknownDocument.path);\n const version = this.fromDbTimestamp(remoteDoc.unknownDocument.version);\n return new UnknownDocument(key, version);\n } else {\n return fail('Unexpected DbRemoteDocument');\n }\n }\n\n /** Encodes a document for storage locally. */\n toDbRemoteDocument(\n maybeDoc: MaybeDocument,\n readTime: SnapshotVersion\n ): DbRemoteDocument {\n const dbReadTime = this.toDbTimestampKey(readTime);\n const parentPath = maybeDoc.key.path.popLast().toArray();\n if (maybeDoc instanceof Document) {\n const doc = this.remoteSerializer.toDocument(maybeDoc);\n const hasCommittedMutations = maybeDoc.hasCommittedMutations;\n return new DbRemoteDocument(\n /* unknownDocument= */ null,\n /* noDocument= */ null,\n doc,\n hasCommittedMutations,\n dbReadTime,\n parentPath\n );\n } else if (maybeDoc instanceof NoDocument) {\n const path = maybeDoc.key.path.toArray();\n const readTime = this.toDbTimestamp(maybeDoc.version);\n const hasCommittedMutations = maybeDoc.hasCommittedMutations;\n return new DbRemoteDocument(\n /* unknownDocument= */ null,\n new DbNoDocument(path, readTime),\n /* document= */ null,\n hasCommittedMutations,\n dbReadTime,\n parentPath\n );\n } else if (maybeDoc instanceof UnknownDocument) {\n const path = maybeDoc.key.path.toArray();\n const readTime = this.toDbTimestamp(maybeDoc.version);\n return new DbRemoteDocument(\n new DbUnknownDocument(path, readTime),\n /* noDocument= */ null,\n /* document= */ null,\n /* hasCommittedMutations= */ true,\n dbReadTime,\n parentPath\n );\n } else {\n return fail('Unexpected MaybeDocument');\n }\n }\n\n toDbTimestampKey(snapshotVersion: SnapshotVersion): DbTimestampKey {\n const timestamp = snapshotVersion.toTimestamp();\n return [timestamp.seconds, timestamp.nanoseconds];\n }\n\n fromDbTimestampKey(dbTimestampKey: DbTimestampKey): SnapshotVersion {\n const timestamp = new Timestamp(dbTimestampKey[0], dbTimestampKey[1]);\n return SnapshotVersion.fromTimestamp(timestamp);\n }\n\n private toDbTimestamp(snapshotVersion: SnapshotVersion): DbTimestamp {\n const timestamp = snapshotVersion.toTimestamp();\n return new DbTimestamp(timestamp.seconds, timestamp.nanoseconds);\n }\n\n private fromDbTimestamp(dbTimestamp: DbTimestamp): SnapshotVersion {\n const timestamp = new Timestamp(\n dbTimestamp.seconds,\n dbTimestamp.nanoseconds\n );\n return SnapshotVersion.fromTimestamp(timestamp);\n }\n\n /** Encodes a batch of mutations into a DbMutationBatch for local storage. */\n toDbMutationBatch(userId: string, batch: MutationBatch): DbMutationBatch {\n const serializedBaseMutations = batch.baseMutations.map(m =>\n this.remoteSerializer.toMutation(m)\n );\n const serializedMutations = batch.mutations.map(m =>\n this.remoteSerializer.toMutation(m)\n );\n return new DbMutationBatch(\n userId,\n batch.batchId,\n batch.localWriteTime.toMillis(),\n serializedBaseMutations,\n serializedMutations\n );\n }\n\n /** Decodes a DbMutationBatch into a MutationBatch */\n fromDbMutationBatch(dbBatch: DbMutationBatch): MutationBatch {\n const baseMutations = (dbBatch.baseMutations || []).map(m =>\n this.remoteSerializer.fromMutation(m)\n );\n const mutations = dbBatch.mutations.map(m =>\n this.remoteSerializer.fromMutation(m)\n );\n const timestamp = Timestamp.fromMillis(dbBatch.localWriteTimeMs);\n return new MutationBatch(\n dbBatch.batchId,\n timestamp,\n baseMutations,\n mutations\n );\n }\n\n /** Decodes a DbTarget into TargetData */\n fromDbTarget(dbTarget: DbTarget): TargetData {\n const version = this.fromDbTimestamp(dbTarget.readTime);\n const lastLimboFreeSnapshotVersion =\n dbTarget.lastLimboFreeSnapshotVersion !== undefined\n ? this.fromDbTimestamp(dbTarget.lastLimboFreeSnapshotVersion)\n : SnapshotVersion.min();\n\n let target: Target;\n if (isDocumentQuery(dbTarget.query)) {\n target = this.remoteSerializer.fromDocumentsTarget(dbTarget.query);\n } else {\n target = this.remoteSerializer.fromQueryTarget(dbTarget.query);\n }\n return new TargetData(\n target,\n dbTarget.targetId,\n TargetPurpose.Listen,\n dbTarget.lastListenSequenceNumber,\n version,\n lastLimboFreeSnapshotVersion,\n ByteString.fromBase64String(dbTarget.resumeToken)\n );\n }\n\n /** Encodes TargetData into a DbTarget for storage locally. */\n toDbTarget(targetData: TargetData): DbTarget {\n debugAssert(\n TargetPurpose.Listen === targetData.purpose,\n 'Only queries with purpose ' +\n TargetPurpose.Listen +\n ' may be stored, got ' +\n targetData.purpose\n );\n const dbTimestamp = this.toDbTimestamp(targetData.snapshotVersion);\n const dbLastLimboFreeTimestamp = this.toDbTimestamp(\n targetData.lastLimboFreeSnapshotVersion\n );\n let queryProto: DbQuery;\n if (targetData.target.isDocumentQuery()) {\n queryProto = this.remoteSerializer.toDocumentsTarget(targetData.target);\n } else {\n queryProto = this.remoteSerializer.toQueryTarget(targetData.target);\n }\n\n // We can't store the resumeToken as a ByteString in IndexedDb, so we\n // convert it to a base64 string for storage.\n const resumeToken = targetData.resumeToken.toBase64();\n\n // lastListenSequenceNumber is always 0 until we do real GC.\n return new DbTarget(\n targetData.targetId,\n targetData.target.canonicalId(),\n dbTimestamp,\n resumeToken,\n targetData.sequenceNumber,\n dbLastLimboFreeTimestamp,\n queryProto\n );\n }\n}\n\n/**\n * A helper function for figuring out what kind of query has been stored.\n */\nfunction isDocumentQuery(dbQuery: DbQuery): dbQuery is api.DocumentsTarget {\n return (dbQuery as api.DocumentsTarget).documents !== undefined;\n}\n","/**\n * @license\n * Copyright 2018 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 { ListenSequence } from '../core/listen_sequence';\nimport { ListenSequenceNumber, TargetId } from '../core/types';\nimport { debugAssert } from '../util/assert';\nimport { AsyncQueue, DelayedOperation, TimerId } from '../util/async_queue';\nimport { getLogLevel, logDebug, LogLevel } from '../util/log';\nimport { primitiveComparator } from '../util/misc';\nimport { SortedMap } from '../util/sorted_map';\nimport { SortedSet } from '../util/sorted_set';\nimport { ignoreIfPrimaryLeaseLoss, LocalStore } from './local_store';\nimport {\n GarbageCollectionScheduler,\n PersistenceTransaction\n} from './persistence';\nimport { PersistencePromise } from './persistence_promise';\nimport { TargetData } from './target_data';\nimport { isIndexedDbTransactionError } from './simple_db';\n\nconst LOG_TAG = 'LruGarbageCollector';\n\n/**\n * Persistence layers intending to use LRU Garbage collection should have reference delegates that\n * implement this interface. This interface defines the operations that the LRU garbage collector\n * needs from the persistence layer.\n */\nexport interface LruDelegate {\n readonly garbageCollector: LruGarbageCollector;\n\n /** Enumerates all the targets in the TargetCache. */\n forEachTarget(\n txn: PersistenceTransaction,\n f: (target: TargetData) => void\n ): PersistencePromise<void>;\n\n getSequenceNumberCount(\n txn: PersistenceTransaction\n ): PersistencePromise<number>;\n\n /**\n * Enumerates sequence numbers for documents not associated with a target.\n * Note that this may include duplicate sequence numbers.\n */\n forEachOrphanedDocumentSequenceNumber(\n txn: PersistenceTransaction,\n f: (sequenceNumber: ListenSequenceNumber) => void\n ): PersistencePromise<void>;\n\n /**\n * Removes all targets that have a sequence number less than or equal to `upperBound`, and are not\n * present in the `activeTargetIds` set.\n *\n * @return the number of targets removed.\n */\n removeTargets(\n txn: PersistenceTransaction,\n upperBound: ListenSequenceNumber,\n activeTargetIds: ActiveTargets\n ): PersistencePromise<number>;\n\n /**\n * Removes all unreferenced documents from the cache that have a sequence number less than or\n * equal to the given `upperBound`.\n *\n * @return the number of documents removed.\n */\n removeOrphanedDocuments(\n txn: PersistenceTransaction,\n upperBound: ListenSequenceNumber\n ): PersistencePromise<number>;\n\n getCacheSize(txn: PersistenceTransaction): PersistencePromise<number>;\n}\n\n/**\n * Describes a map whose keys are active target ids. We do not care about the type of the\n * values.\n */\nexport type ActiveTargets = SortedMap<TargetId, unknown>;\n\n// The type and comparator for the items contained in the SortedSet used in\n// place of a priority queue for the RollingSequenceNumberBuffer.\ntype BufferEntry = [ListenSequenceNumber, number];\nfunction bufferEntryComparator(\n [aSequence, aIndex]: BufferEntry,\n [bSequence, bIndex]: BufferEntry\n): number {\n const seqCmp = primitiveComparator(aSequence, bSequence);\n if (seqCmp === 0) {\n // This order doesn't matter, but we can bias against churn by sorting\n // entries created earlier as less than newer entries.\n return primitiveComparator(aIndex, bIndex);\n } else {\n return seqCmp;\n }\n}\n\n/**\n * Used to calculate the nth sequence number. Keeps a rolling buffer of the\n * lowest n values passed to `addElement`, and finally reports the largest of\n * them in `maxValue`.\n */\nclass RollingSequenceNumberBuffer {\n private buffer: SortedSet<BufferEntry> = new SortedSet<BufferEntry>(\n bufferEntryComparator\n );\n\n private previousIndex = 0;\n\n constructor(private readonly maxElements: number) {}\n\n private nextIndex(): number {\n return ++this.previousIndex;\n }\n\n addElement(sequenceNumber: ListenSequenceNumber): void {\n const entry: BufferEntry = [sequenceNumber, this.nextIndex()];\n if (this.buffer.size < this.maxElements) {\n this.buffer = this.buffer.add(entry);\n } else {\n const highestValue = this.buffer.last()!;\n if (bufferEntryComparator(entry, highestValue) < 0) {\n this.buffer = this.buffer.delete(highestValue).add(entry);\n }\n }\n }\n\n get maxValue(): ListenSequenceNumber {\n // Guaranteed to be non-empty. If we decide we are not collecting any\n // sequence numbers, nthSequenceNumber below short-circuits. If we have\n // decided that we are collecting n sequence numbers, it's because n is some\n // percentage of the existing sequence numbers. That means we should never\n // be in a situation where we are collecting sequence numbers but don't\n // actually have any.\n return this.buffer.last()![0];\n }\n}\n\n/**\n * Describes the results of a garbage collection run. `didRun` will be set to\n * `false` if collection was skipped (either it is disabled or the cache size\n * has not hit the threshold). If collection ran, the other fields will be\n * filled in with the details of the results.\n */\nexport interface LruResults {\n readonly didRun: boolean;\n readonly sequenceNumbersCollected: number;\n readonly targetsRemoved: number;\n readonly documentsRemoved: number;\n}\n\nconst GC_DID_NOT_RUN: LruResults = {\n didRun: false,\n sequenceNumbersCollected: 0,\n targetsRemoved: 0,\n documentsRemoved: 0\n};\n\nexport class LruParams {\n static readonly COLLECTION_DISABLED = -1;\n static readonly MINIMUM_CACHE_SIZE_BYTES = 1 * 1024 * 1024;\n static readonly DEFAULT_CACHE_SIZE_BYTES = 40 * 1024 * 1024;\n private static readonly DEFAULT_COLLECTION_PERCENTILE = 10;\n private static readonly DEFAULT_MAX_SEQUENCE_NUMBERS_TO_COLLECT = 1000;\n\n static withCacheSize(cacheSize: number): LruParams {\n return new LruParams(\n cacheSize,\n LruParams.DEFAULT_COLLECTION_PERCENTILE,\n LruParams.DEFAULT_MAX_SEQUENCE_NUMBERS_TO_COLLECT\n );\n }\n\n static readonly DEFAULT: LruParams = new LruParams(\n LruParams.DEFAULT_CACHE_SIZE_BYTES,\n LruParams.DEFAULT_COLLECTION_PERCENTILE,\n LruParams.DEFAULT_MAX_SEQUENCE_NUMBERS_TO_COLLECT\n );\n\n static readonly DISABLED: LruParams = new LruParams(\n LruParams.COLLECTION_DISABLED,\n 0,\n 0\n );\n\n constructor(\n // When we attempt to collect, we will only do so if the cache size is greater than this\n // threshold. Passing `COLLECTION_DISABLED` here will cause collection to always be skipped.\n readonly cacheSizeCollectionThreshold: number,\n // The percentage of sequence numbers that we will attempt to collect\n readonly percentileToCollect: number,\n // A cap on the total number of sequence numbers that will be collected. This prevents\n // us from collecting a huge number of sequence numbers if the cache has grown very large.\n readonly maximumSequenceNumbersToCollect: number\n ) {}\n}\n\n/** How long we wait to try running LRU GC after SDK initialization. */\nconst INITIAL_GC_DELAY_MS = 1 * 60 * 1000;\n/** Minimum amount of time between GC checks, after the first one. */\nconst REGULAR_GC_DELAY_MS = 5 * 60 * 1000;\n\n/**\n * This class is responsible for the scheduling of LRU garbage collection. It handles checking\n * whether or not GC is enabled, as well as which delay to use before the next run.\n */\nexport class LruScheduler implements GarbageCollectionScheduler {\n private hasRun: boolean = false;\n private gcTask: DelayedOperation<void> | null;\n\n constructor(\n private readonly garbageCollector: LruGarbageCollector,\n private readonly asyncQueue: AsyncQueue\n ) {\n this.gcTask = null;\n }\n\n start(localStore: LocalStore): void {\n debugAssert(\n this.gcTask === null,\n 'Cannot start an already started LruScheduler'\n );\n if (\n this.garbageCollector.params.cacheSizeCollectionThreshold !==\n LruParams.COLLECTION_DISABLED\n ) {\n this.scheduleGC(localStore);\n }\n }\n\n stop(): void {\n if (this.gcTask) {\n this.gcTask.cancel();\n this.gcTask = null;\n }\n }\n\n get started(): boolean {\n return this.gcTask !== null;\n }\n\n private scheduleGC(localStore: LocalStore): void {\n debugAssert(\n this.gcTask === null,\n 'Cannot schedule GC while a task is pending'\n );\n const delay = this.hasRun ? REGULAR_GC_DELAY_MS : INITIAL_GC_DELAY_MS;\n logDebug(\n 'LruGarbageCollector',\n `Garbage collection scheduled in ${delay}ms`\n );\n this.gcTask = this.asyncQueue.enqueueAfterDelay(\n TimerId.LruGarbageCollection,\n delay,\n async () => {\n this.gcTask = null;\n this.hasRun = true;\n try {\n await localStore.collectGarbage(this.garbageCollector);\n } catch (e) {\n if (isIndexedDbTransactionError(e)) {\n logDebug(\n LOG_TAG,\n 'Ignoring IndexedDB error during garbage collection: ',\n e\n );\n } else {\n await ignoreIfPrimaryLeaseLoss(e);\n }\n }\n await this.scheduleGC(localStore);\n }\n );\n }\n}\n\n/** Implements the steps for LRU garbage collection. */\nexport class LruGarbageCollector {\n constructor(\n private readonly delegate: LruDelegate,\n readonly params: LruParams\n ) {}\n\n /** Given a percentile of target to collect, returns the number of targets to collect. */\n calculateTargetCount(\n txn: PersistenceTransaction,\n percentile: number\n ): PersistencePromise<number> {\n return this.delegate.getSequenceNumberCount(txn).next(targetCount => {\n return Math.floor((percentile / 100.0) * targetCount);\n });\n }\n\n /** Returns the nth sequence number, counting in order from the smallest. */\n nthSequenceNumber(\n txn: PersistenceTransaction,\n n: number\n ): PersistencePromise<ListenSequenceNumber> {\n if (n === 0) {\n return PersistencePromise.resolve(ListenSequence.INVALID);\n }\n\n const buffer = new RollingSequenceNumberBuffer(n);\n return this.delegate\n .forEachTarget(txn, target => buffer.addElement(target.sequenceNumber))\n .next(() => {\n return this.delegate.forEachOrphanedDocumentSequenceNumber(\n txn,\n sequenceNumber => buffer.addElement(sequenceNumber)\n );\n })\n .next(() => buffer.maxValue);\n }\n\n /**\n * Removes targets with a sequence number equal to or less than the given upper bound, and removes\n * document associations with those targets.\n */\n removeTargets(\n txn: PersistenceTransaction,\n upperBound: ListenSequenceNumber,\n activeTargetIds: ActiveTargets\n ): PersistencePromise<number> {\n return this.delegate.removeTargets(txn, upperBound, activeTargetIds);\n }\n\n /**\n * Removes documents that have a sequence number equal to or less than the upper bound and are not\n * otherwise pinned.\n */\n removeOrphanedDocuments(\n txn: PersistenceTransaction,\n upperBound: ListenSequenceNumber\n ): PersistencePromise<number> {\n return this.delegate.removeOrphanedDocuments(txn, upperBound);\n }\n\n collect(\n txn: PersistenceTransaction,\n activeTargetIds: ActiveTargets\n ): PersistencePromise<LruResults> {\n if (\n this.params.cacheSizeCollectionThreshold === LruParams.COLLECTION_DISABLED\n ) {\n logDebug('LruGarbageCollector', 'Garbage collection skipped; disabled');\n return PersistencePromise.resolve(GC_DID_NOT_RUN);\n }\n\n return this.getCacheSize(txn).next(cacheSize => {\n if (cacheSize < this.params.cacheSizeCollectionThreshold) {\n logDebug(\n 'LruGarbageCollector',\n `Garbage collection skipped; Cache size ${cacheSize} ` +\n `is lower than threshold ${this.params.cacheSizeCollectionThreshold}`\n );\n return GC_DID_NOT_RUN;\n } else {\n return this.runGarbageCollection(txn, activeTargetIds);\n }\n });\n }\n\n getCacheSize(txn: PersistenceTransaction): PersistencePromise<number> {\n return this.delegate.getCacheSize(txn);\n }\n\n private runGarbageCollection(\n txn: PersistenceTransaction,\n activeTargetIds: ActiveTargets\n ): PersistencePromise<LruResults> {\n let upperBoundSequenceNumber: number;\n let sequenceNumbersToCollect: number, targetsRemoved: number;\n // Timestamps for various pieces of the process\n let countedTargetsTs: number,\n foundUpperBoundTs: number,\n removedTargetsTs: number,\n removedDocumentsTs: number;\n const startTs = Date.now();\n return this.calculateTargetCount(txn, this.params.percentileToCollect)\n .next(sequenceNumbers => {\n // Cap at the configured max\n if (sequenceNumbers > this.params.maximumSequenceNumbersToCollect) {\n logDebug(\n 'LruGarbageCollector',\n 'Capping sequence numbers to collect down ' +\n `to the maximum of ${this.params.maximumSequenceNumbersToCollect} ` +\n `from ${sequenceNumbers}`\n );\n sequenceNumbersToCollect = this.params\n .maximumSequenceNumbersToCollect;\n } else {\n sequenceNumbersToCollect = sequenceNumbers;\n }\n countedTargetsTs = Date.now();\n\n return this.nthSequenceNumber(txn, sequenceNumbersToCollect);\n })\n .next(upperBound => {\n upperBoundSequenceNumber = upperBound;\n foundUpperBoundTs = Date.now();\n\n return this.removeTargets(\n txn,\n upperBoundSequenceNumber,\n activeTargetIds\n );\n })\n .next(numTargetsRemoved => {\n targetsRemoved = numTargetsRemoved;\n removedTargetsTs = Date.now();\n\n return this.removeOrphanedDocuments(txn, upperBoundSequenceNumber);\n })\n .next(documentsRemoved => {\n removedDocumentsTs = Date.now();\n\n if (getLogLevel() <= LogLevel.DEBUG) {\n const desc =\n 'LRU Garbage Collection\\n' +\n `\\tCounted targets in ${countedTargetsTs - startTs}ms\\n` +\n `\\tDetermined least recently used ${sequenceNumbersToCollect} in ` +\n `${foundUpperBoundTs - countedTargetsTs}ms\\n` +\n `\\tRemoved ${targetsRemoved} targets in ` +\n `${removedTargetsTs - foundUpperBoundTs}ms\\n` +\n `\\tRemoved ${documentsRemoved} documents in ` +\n `${removedDocumentsTs - removedTargetsTs}ms\\n` +\n `Total Duration: ${removedDocumentsTs - startTs}ms`;\n logDebug('LruGarbageCollector', desc);\n }\n\n return PersistencePromise.resolve<LruResults>({\n didRun: true,\n sequenceNumbersCollected: sequenceNumbersToCollect,\n targetsRemoved,\n documentsRemoved\n });\n });\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 { User } from '../auth/user';\nimport { DatabaseInfo } from '../core/database_info';\nimport { ListenSequence, SequenceNumberSyncer } from '../core/listen_sequence';\nimport { ListenSequenceNumber, TargetId } from '../core/types';\nimport { DocumentKey } from '../model/document_key';\nimport { Platform } from '../platform/platform';\nimport { JsonProtoSerializer } from '../remote/serializer';\nimport { debugAssert, fail } from '../util/assert';\nimport { AsyncQueue, DelayedOperation, TimerId } from '../util/async_queue';\nimport { Code, FirestoreError } from '../util/error';\nimport { logDebug, logError } from '../util/log';\nimport {\n decodeResourcePath,\n EncodedResourcePath,\n encodeResourcePath\n} from './encoded_resource_path';\nimport { IndexedDbIndexManager } from './indexeddb_index_manager';\nimport {\n IndexedDbMutationQueue,\n mutationQueuesContainKey\n} from './indexeddb_mutation_queue';\nimport { IndexedDbRemoteDocumentCache } from './indexeddb_remote_document_cache';\nimport {\n ALL_STORES,\n DbClientMetadata,\n DbClientMetadataKey,\n DbPrimaryClient,\n DbPrimaryClientKey,\n DbTargetDocument,\n SCHEMA_VERSION,\n SchemaConverter\n} from './indexeddb_schema';\nimport {\n documentTargetStore,\n IndexedDbTargetCache\n} from './indexeddb_target_cache';\nimport { LocalSerializer } from './local_serializer';\nimport {\n ActiveTargets,\n LruDelegate,\n LruGarbageCollector,\n LruParams\n} from './lru_garbage_collector';\nimport {\n Persistence,\n PersistenceTransaction,\n PersistenceTransactionMode,\n PRIMARY_LEASE_LOST_ERROR_MSG,\n PrimaryStateListener,\n ReferenceDelegate\n} from './persistence';\nimport { PersistencePromise } from './persistence_promise';\nimport { ClientId } from './shared_client_state';\nimport { TargetData } from './target_data';\nimport {\n isIndexedDbTransactionError,\n SimpleDb,\n SimpleDbStore,\n SimpleDbTransaction\n} from './simple_db';\n\nconst LOG_TAG = 'IndexedDbPersistence';\n\n/**\n * Oldest acceptable age in milliseconds for client metadata before the client\n * is considered inactive and its associated data is garbage collected.\n */\nconst MAX_CLIENT_AGE_MS = 30 * 60 * 1000; // 30 minutes\n\n/**\n * Oldest acceptable metadata age for clients that may participate in the\n * primary lease election. Clients that have not updated their client metadata\n * within 5 seconds are not eligible to receive a primary lease.\n */\nconst MAX_PRIMARY_ELIGIBLE_AGE_MS = 5000;\n\n/**\n * The interval at which clients will update their metadata, including\n * refreshing their primary lease if held or potentially trying to acquire it if\n * not held.\n *\n * Primary clients may opportunistically refresh their metadata earlier\n * if they're already performing an IndexedDB operation.\n */\nconst CLIENT_METADATA_REFRESH_INTERVAL_MS = 4000;\n/** User-facing error when the primary lease is required but not available. */\nconst PRIMARY_LEASE_EXCLUSIVE_ERROR_MSG =\n 'Failed to obtain exclusive access to the persistence layer. ' +\n 'To allow shared access, make sure to invoke ' +\n '`enablePersistence()` with `synchronizeTabs:true` in all tabs.';\nconst UNSUPPORTED_PLATFORM_ERROR_MSG =\n 'This platform is either missing' +\n ' IndexedDB or is known to have an incomplete implementation. Offline' +\n ' persistence has been disabled.';\n\n// The format of the LocalStorage key that stores zombied client is:\n// firestore_zombie_<persistence_prefix>_<instance_key>\nconst ZOMBIED_CLIENTS_KEY_PREFIX = 'firestore_zombie';\n\nexport class IndexedDbTransaction extends PersistenceTransaction {\n constructor(\n readonly simpleDbTransaction: SimpleDbTransaction,\n readonly currentSequenceNumber: ListenSequenceNumber\n ) {\n super();\n }\n}\n\n/**\n * An IndexedDB-backed instance of Persistence. Data is stored persistently\n * across sessions.\n *\n * On Web only, the Firestore SDKs support shared access to its persistence\n * layer. This allows multiple browser tabs to read and write to IndexedDb and\n * to synchronize state even without network connectivity. Shared access is\n * currently optional and not enabled unless all clients invoke\n * `enablePersistence()` with `{synchronizeTabs:true}`.\n *\n * In multi-tab mode, if multiple clients are active at the same time, the SDK\n * will designate one client as the “primary client”. An effort is made to pick\n * a visible, network-connected and active client, and this client is\n * responsible for letting other clients know about its presence. The primary\n * client writes a unique client-generated identifier (the client ID) to\n * IndexedDb’s “owner” store every 4 seconds. If the primary client fails to\n * update this entry, another client can acquire the lease and take over as\n * primary.\n *\n * Some persistence operations in the SDK are designated as primary-client only\n * operations. This includes the acknowledgment of mutations and all updates of\n * remote documents. The effects of these operations are written to persistence\n * and then broadcast to other tabs via LocalStorage (see\n * `WebStorageSharedClientState`), which then refresh their state from\n * persistence.\n *\n * Similarly, the primary client listens to notifications sent by secondary\n * clients to discover persistence changes written by secondary clients, such as\n * the addition of new mutations and query targets.\n *\n * If multi-tab is not enabled and another tab already obtained the primary\n * lease, IndexedDbPersistence enters a failed state and all subsequent\n * operations will automatically fail.\n *\n * Additionally, there is an optimization so that when a tab is closed, the\n * primary lease is released immediately (this is especially important to make\n * sure that a refreshed tab is able to immediately re-acquire the primary\n * lease). Unfortunately, IndexedDB cannot be reliably used in window.unload\n * since it is an asynchronous API. So in addition to attempting to give up the\n * lease, the leaseholder writes its client ID to a \"zombiedClient\" entry in\n * LocalStorage which acts as an indicator that another tab should go ahead and\n * take the primary lease immediately regardless of the current lease timestamp.\n *\n * TODO(b/114226234): Remove `synchronizeTabs` section when multi-tab is no\n * longer optional.\n */\nexport class IndexedDbPersistence implements Persistence {\n static getStore<Key extends IDBValidKey, Value>(\n txn: PersistenceTransaction,\n store: string\n ): SimpleDbStore<Key, Value> {\n if (txn instanceof IndexedDbTransaction) {\n return SimpleDb.getStore<Key, Value>(txn.simpleDbTransaction, store);\n } else {\n throw fail(\n 'IndexedDbPersistence must use instances of IndexedDbTransaction'\n );\n }\n }\n\n /**\n * The name of the main (and currently only) IndexedDB database. this name is\n * appended to the prefix provided to the IndexedDbPersistence constructor.\n */\n static MAIN_DATABASE = 'main';\n\n private readonly document: Document | null;\n private readonly window: Window;\n\n // Technically `simpleDb` should be `| undefined` because it is\n // initialized asynchronously by start(), but that would be more misleading\n // than useful.\n private simpleDb!: SimpleDb;\n\n private listenSequence: ListenSequence | null = null;\n\n private _started = false;\n private isPrimary = false;\n private networkEnabled = true;\n private dbName: string;\n\n /** Our window.unload handler, if registered. */\n private windowUnloadHandler: (() => void) | null = null;\n private inForeground = false;\n\n private serializer: LocalSerializer;\n\n /** Our 'visibilitychange' listener if registered. */\n private documentVisibilityHandler: ((e?: Event) => void) | null = null;\n\n /** The client metadata refresh task. */\n private clientMetadataRefresher: DelayedOperation<void> | null = null;\n\n /** The last time we garbage collected the client metadata object store. */\n private lastGarbageCollectionTime = Number.NEGATIVE_INFINITY;\n\n /** A listener to notify on primary state changes. */\n private primaryStateListener: PrimaryStateListener = _ => Promise.resolve();\n\n private readonly targetCache: IndexedDbTargetCache;\n private readonly indexManager: IndexedDbIndexManager;\n private readonly remoteDocumentCache: IndexedDbRemoteDocumentCache;\n private readonly webStorage: Storage;\n readonly referenceDelegate: IndexedDbLruDelegate;\n\n constructor(\n private readonly allowTabSynchronization: boolean,\n private readonly persistenceKey: string,\n private readonly clientId: ClientId,\n platform: Platform,\n lruParams: LruParams,\n private readonly queue: AsyncQueue,\n serializer: JsonProtoSerializer,\n private readonly sequenceNumberSyncer: SequenceNumberSyncer\n ) {\n if (!IndexedDbPersistence.isAvailable()) {\n throw new FirestoreError(\n Code.UNIMPLEMENTED,\n UNSUPPORTED_PLATFORM_ERROR_MSG\n );\n }\n\n this.referenceDelegate = new IndexedDbLruDelegate(this, lruParams);\n this.dbName = persistenceKey + IndexedDbPersistence.MAIN_DATABASE;\n this.serializer = new LocalSerializer(serializer);\n this.document = platform.document;\n this.targetCache = new IndexedDbTargetCache(\n this.referenceDelegate,\n this.serializer\n );\n this.indexManager = new IndexedDbIndexManager();\n this.remoteDocumentCache = new IndexedDbRemoteDocumentCache(\n this.serializer,\n this.indexManager\n );\n if (platform.window && platform.window.localStorage) {\n this.window = platform.window;\n this.webStorage = this.window.localStorage;\n } else {\n throw new FirestoreError(\n Code.UNIMPLEMENTED,\n 'IndexedDB persistence is only available on platforms that support LocalStorage.'\n );\n }\n }\n\n /**\n * Attempt to start IndexedDb persistence.\n *\n * @return {Promise<void>} Whether persistence was enabled.\n */\n start(): Promise<void> {\n debugAssert(!this.started, 'IndexedDbPersistence double-started!');\n debugAssert(this.window !== null, \"Expected 'window' to be defined\");\n\n return SimpleDb.openOrCreate(\n this.dbName,\n SCHEMA_VERSION,\n new SchemaConverter(this.serializer)\n )\n .then(db => {\n this.simpleDb = db;\n // NOTE: This is expected to fail sometimes (in the case of another tab already\n // having the persistence lock), so it's the first thing we should do.\n return this.updateClientMetadataAndTryBecomePrimary();\n })\n .then(() => {\n if (!this.isPrimary && !this.allowTabSynchronization) {\n // Fail `start()` if `synchronizeTabs` is disabled and we cannot\n // obtain the primary lease.\n throw new FirestoreError(\n Code.FAILED_PRECONDITION,\n PRIMARY_LEASE_EXCLUSIVE_ERROR_MSG\n );\n }\n this.attachVisibilityHandler();\n this.attachWindowUnloadHook();\n\n this.scheduleClientMetadataAndPrimaryLeaseRefreshes();\n\n return this.runTransaction(\n 'getHighestListenSequenceNumber',\n 'readonly',\n txn => this.targetCache.getHighestSequenceNumber(txn)\n );\n })\n .then(highestListenSequenceNumber => {\n this.listenSequence = new ListenSequence(\n highestListenSequenceNumber,\n this.sequenceNumberSyncer\n );\n })\n .then(() => {\n this._started = true;\n })\n .catch(reason => {\n this.simpleDb && this.simpleDb.close();\n return Promise.reject(reason);\n });\n }\n\n /**\n * Registers a listener that gets called when the primary state of the\n * instance changes. Upon registering, this listener is invoked immediately\n * with the current primary state.\n *\n * PORTING NOTE: This is only used for Web multi-tab.\n */\n setPrimaryStateListener(\n primaryStateListener: PrimaryStateListener\n ): Promise<void> {\n this.primaryStateListener = async primaryState => {\n if (this.started) {\n return primaryStateListener(primaryState);\n }\n };\n return primaryStateListener(this.isPrimary);\n }\n\n /**\n * Registers a listener that gets called when the database receives a\n * version change event indicating that it has deleted.\n *\n * PORTING NOTE: This is only used for Web multi-tab.\n */\n setDatabaseDeletedListener(\n databaseDeletedListener: () => Promise<void>\n ): void {\n this.simpleDb.setVersionChangeListener(async event => {\n // Check if an attempt is made to delete IndexedDB.\n if (event.newVersion === null) {\n await databaseDeletedListener();\n }\n });\n }\n\n /**\n * Adjusts the current network state in the client's metadata, potentially\n * affecting the primary lease.\n *\n * PORTING NOTE: This is only used for Web multi-tab.\n */\n setNetworkEnabled(networkEnabled: boolean): void {\n if (this.networkEnabled !== networkEnabled) {\n this.networkEnabled = networkEnabled;\n // Schedule a primary lease refresh for immediate execution. The eventual\n // lease update will be propagated via `primaryStateListener`.\n this.queue.enqueueAndForget(async () => {\n if (this.started) {\n await this.updateClientMetadataAndTryBecomePrimary();\n }\n });\n }\n }\n\n /**\n * Updates the client metadata in IndexedDb and attempts to either obtain or\n * extend the primary lease for the local client. Asynchronously notifies the\n * primary state listener if the client either newly obtained or released its\n * primary lease.\n */\n private updateClientMetadataAndTryBecomePrimary(): Promise<void> {\n return this.runTransaction(\n 'updateClientMetadataAndTryBecomePrimary',\n 'readwrite',\n txn => {\n const metadataStore = clientMetadataStore(txn);\n return metadataStore\n .put(\n new DbClientMetadata(\n this.clientId,\n Date.now(),\n this.networkEnabled,\n this.inForeground\n )\n )\n .next(() => {\n if (this.isPrimary) {\n return this.verifyPrimaryLease(txn).next(success => {\n if (!success) {\n this.isPrimary = false;\n this.queue.enqueueAndForget(() =>\n this.primaryStateListener(false)\n );\n }\n });\n }\n })\n .next(() => this.canActAsPrimary(txn))\n .next(canActAsPrimary => {\n if (this.isPrimary && !canActAsPrimary) {\n return this.releasePrimaryLeaseIfHeld(txn).next(() => false);\n } else if (canActAsPrimary) {\n return this.acquireOrExtendPrimaryLease(txn).next(() => true);\n } else {\n return /* canActAsPrimary= */ false;\n }\n });\n }\n )\n .catch(e => {\n if (!this.allowTabSynchronization) {\n if (isIndexedDbTransactionError(e)) {\n logDebug(LOG_TAG, 'Failed to extend owner lease: ', e);\n // Proceed with the existing state. Any subsequent access to\n // IndexedDB will verify the lease.\n return this.isPrimary;\n } else {\n throw e;\n }\n }\n\n logDebug(\n LOG_TAG,\n 'Releasing owner lease after error during lease refresh',\n e\n );\n return /* isPrimary= */ false;\n })\n .then(isPrimary => {\n if (this.isPrimary !== isPrimary) {\n this.queue.enqueueAndForget(() =>\n this.primaryStateListener(isPrimary)\n );\n }\n this.isPrimary = isPrimary;\n });\n }\n\n private verifyPrimaryLease(\n txn: PersistenceTransaction\n ): PersistencePromise<boolean> {\n const store = primaryClientStore(txn);\n return store.get(DbPrimaryClient.key).next(primaryClient => {\n return PersistencePromise.resolve(this.isLocalClient(primaryClient));\n });\n }\n\n private removeClientMetadata(\n txn: PersistenceTransaction\n ): PersistencePromise<void> {\n const metadataStore = clientMetadataStore(txn);\n return metadataStore.delete(this.clientId);\n }\n\n /**\n * If the garbage collection threshold has passed, prunes the\n * RemoteDocumentChanges and the ClientMetadata store based on the last update\n * time of all clients.\n */\n private async maybeGarbageCollectMultiClientState(): Promise<void> {\n if (\n this.isPrimary &&\n !this.isWithinAge(this.lastGarbageCollectionTime, MAX_CLIENT_AGE_MS)\n ) {\n this.lastGarbageCollectionTime = Date.now();\n\n const inactiveClients = await this.runTransaction(\n 'maybeGarbageCollectMultiClientState',\n 'readwrite-primary',\n txn => {\n const metadataStore = IndexedDbPersistence.getStore<\n DbClientMetadataKey,\n DbClientMetadata\n >(txn, DbClientMetadata.store);\n\n return metadataStore.loadAll().next(existingClients => {\n const active = this.filterActiveClients(\n existingClients,\n MAX_CLIENT_AGE_MS\n );\n const inactive = existingClients.filter(\n client => active.indexOf(client) === -1\n );\n\n // Delete metadata for clients that are no longer considered active.\n return PersistencePromise.forEach(\n inactive,\n (inactiveClient: DbClientMetadata) =>\n metadataStore.delete(inactiveClient.clientId)\n ).next(() => inactive);\n });\n }\n ).catch(() => {\n // Ignore primary lease violations or any other type of error. The next\n // primary will run `maybeGarbageCollectMultiClientState()` again.\n // We don't use `ignoreIfPrimaryLeaseLoss()` since we don't want to depend\n // on LocalStore.\n return [];\n });\n\n // Delete potential leftover entries that may continue to mark the\n // inactive clients as zombied in LocalStorage.\n // Ideally we'd delete the IndexedDb and LocalStorage zombie entries for\n // the client atomically, but we can't. So we opt to delete the IndexedDb\n // entries first to avoid potentially reviving a zombied client.\n inactiveClients.forEach(inactiveClient => {\n this.window.localStorage.removeItem(\n this.zombiedClientLocalStorageKey(inactiveClient.clientId)\n );\n });\n }\n }\n\n /**\n * Schedules a recurring timer to update the client metadata and to either\n * extend or acquire the primary lease if the client is eligible.\n */\n private scheduleClientMetadataAndPrimaryLeaseRefreshes(): void {\n this.clientMetadataRefresher = this.queue.enqueueAfterDelay(\n TimerId.ClientMetadataRefresh,\n CLIENT_METADATA_REFRESH_INTERVAL_MS,\n () => {\n return this.updateClientMetadataAndTryBecomePrimary()\n .then(() => this.maybeGarbageCollectMultiClientState())\n .then(() => this.scheduleClientMetadataAndPrimaryLeaseRefreshes());\n }\n );\n }\n\n /** Checks whether `client` is the local client. */\n private isLocalClient(client: DbPrimaryClient | null): boolean {\n return client ? client.ownerId === this.clientId : false;\n }\n\n /**\n * Evaluate the state of all active clients and determine whether the local\n * client is or can act as the holder of the primary lease. Returns whether\n * the client is eligible for the lease, but does not actually acquire it.\n * May return 'false' even if there is no active leaseholder and another\n * (foreground) client should become leaseholder instead.\n */\n private canActAsPrimary(\n txn: PersistenceTransaction\n ): PersistencePromise<boolean> {\n const store = primaryClientStore(txn);\n return store\n .get(DbPrimaryClient.key)\n .next(currentPrimary => {\n const currentLeaseIsValid =\n currentPrimary !== null &&\n this.isWithinAge(\n currentPrimary.leaseTimestampMs,\n MAX_PRIMARY_ELIGIBLE_AGE_MS\n ) &&\n !this.isClientZombied(currentPrimary.ownerId);\n\n // A client is eligible for the primary lease if:\n // - its network is enabled and the client's tab is in the foreground.\n // - its network is enabled and no other client's tab is in the\n // foreground.\n // - every clients network is disabled and the client's tab is in the\n // foreground.\n // - every clients network is disabled and no other client's tab is in\n // the foreground.\n if (currentLeaseIsValid) {\n if (this.isLocalClient(currentPrimary) && this.networkEnabled) {\n return true;\n }\n\n if (!this.isLocalClient(currentPrimary)) {\n if (!currentPrimary!.allowTabSynchronization) {\n // Fail the `canActAsPrimary` check if the current leaseholder has\n // not opted into multi-tab synchronization. If this happens at\n // client startup, we reject the Promise returned by\n // `enablePersistence()` and the user can continue to use Firestore\n // with in-memory persistence.\n // If this fails during a lease refresh, we will instead block the\n // AsyncQueue from executing further operations. Note that this is\n // acceptable since mixing & matching different `synchronizeTabs`\n // settings is not supported.\n //\n // TODO(b/114226234): Remove this check when `synchronizeTabs` can\n // no longer be turned off.\n throw new FirestoreError(\n Code.FAILED_PRECONDITION,\n PRIMARY_LEASE_EXCLUSIVE_ERROR_MSG\n );\n }\n\n return false;\n }\n }\n\n if (this.networkEnabled && this.inForeground) {\n return true;\n }\n\n return clientMetadataStore(txn)\n .loadAll()\n .next(existingClients => {\n // Process all existing clients and determine whether at least one of\n // them is better suited to obtain the primary lease.\n const preferredCandidate = this.filterActiveClients(\n existingClients,\n MAX_PRIMARY_ELIGIBLE_AGE_MS\n ).find(otherClient => {\n if (this.clientId !== otherClient.clientId) {\n const otherClientHasBetterNetworkState =\n !this.networkEnabled && otherClient.networkEnabled;\n const otherClientHasBetterVisibility =\n !this.inForeground && otherClient.inForeground;\n const otherClientHasSameNetworkState =\n this.networkEnabled === otherClient.networkEnabled;\n if (\n otherClientHasBetterNetworkState ||\n (otherClientHasBetterVisibility &&\n otherClientHasSameNetworkState)\n ) {\n return true;\n }\n }\n return false;\n });\n return preferredCandidate === undefined;\n });\n })\n .next(canActAsPrimary => {\n if (this.isPrimary !== canActAsPrimary) {\n logDebug(\n LOG_TAG,\n `Client ${\n canActAsPrimary ? 'is' : 'is not'\n } eligible for a primary lease.`\n );\n }\n return canActAsPrimary;\n });\n }\n\n async shutdown(): Promise<void> {\n // The shutdown() operations are idempotent and can be called even when\n // start() aborted (e.g. because it couldn't acquire the persistence lease).\n this._started = false;\n\n this.markClientZombied();\n if (this.clientMetadataRefresher) {\n this.clientMetadataRefresher.cancel();\n this.clientMetadataRefresher = null;\n }\n this.detachVisibilityHandler();\n this.detachWindowUnloadHook();\n await this.runTransaction('shutdown', 'readwrite', txn => {\n return this.releasePrimaryLeaseIfHeld(txn).next(() =>\n this.removeClientMetadata(txn)\n );\n }).catch(e => {\n logDebug(LOG_TAG, 'Proceeding with shutdown despite failure: ', e);\n });\n this.simpleDb.close();\n\n // Remove the entry marking the client as zombied from LocalStorage since\n // we successfully deleted its metadata from IndexedDb.\n this.removeClientZombiedEntry();\n }\n\n /**\n * Returns clients that are not zombied and have an updateTime within the\n * provided threshold.\n */\n private filterActiveClients(\n clients: DbClientMetadata[],\n activityThresholdMs: number\n ): DbClientMetadata[] {\n return clients.filter(\n client =>\n this.isWithinAge(client.updateTimeMs, activityThresholdMs) &&\n !this.isClientZombied(client.clientId)\n );\n }\n\n /**\n * Returns the IDs of the clients that are currently active. If multi-tab\n * is not supported, returns an array that only contains the local client's\n * ID.\n *\n * PORTING NOTE: This is only used for Web multi-tab.\n */\n getActiveClients(): Promise<ClientId[]> {\n return this.runTransaction('getActiveClients', 'readonly', txn => {\n return clientMetadataStore(txn)\n .loadAll()\n .next(clients =>\n this.filterActiveClients(clients, MAX_CLIENT_AGE_MS).map(\n clientMetadata => clientMetadata.clientId\n )\n );\n });\n }\n\n static async clearPersistence(persistenceKey: string): Promise<void> {\n if (!IndexedDbPersistence.isAvailable()) {\n return Promise.resolve();\n }\n const dbName = persistenceKey + IndexedDbPersistence.MAIN_DATABASE;\n await SimpleDb.delete(dbName);\n }\n\n get started(): boolean {\n return this._started;\n }\n\n getMutationQueue(user: User): IndexedDbMutationQueue {\n debugAssert(\n this.started,\n 'Cannot initialize MutationQueue before persistence is started.'\n );\n return IndexedDbMutationQueue.forUser(\n user,\n this.serializer,\n this.indexManager,\n this.referenceDelegate\n );\n }\n\n getTargetCache(): IndexedDbTargetCache {\n debugAssert(\n this.started,\n 'Cannot initialize TargetCache before persistence is started.'\n );\n return this.targetCache;\n }\n\n getRemoteDocumentCache(): IndexedDbRemoteDocumentCache {\n debugAssert(\n this.started,\n 'Cannot initialize RemoteDocumentCache before persistence is started.'\n );\n return this.remoteDocumentCache;\n }\n\n getIndexManager(): IndexedDbIndexManager {\n debugAssert(\n this.started,\n 'Cannot initialize IndexManager before persistence is started.'\n );\n return this.indexManager;\n }\n\n runTransaction<T>(\n action: string,\n mode: PersistenceTransactionMode,\n transactionOperation: (\n transaction: PersistenceTransaction\n ) => PersistencePromise<T>\n ): Promise<T> {\n logDebug(LOG_TAG, 'Starting transaction:', action);\n\n const simpleDbMode = mode === 'readonly' ? 'readonly' : 'readwrite';\n\n let persistenceTransaction: PersistenceTransaction;\n\n // Do all transactions as readwrite against all object stores, since we\n // are the only reader/writer.\n return this.simpleDb\n .runTransaction(simpleDbMode, ALL_STORES, simpleDbTxn => {\n persistenceTransaction = new IndexedDbTransaction(\n simpleDbTxn,\n this.listenSequence\n ? this.listenSequence.next()\n : ListenSequence.INVALID\n );\n\n if (mode === 'readwrite-primary') {\n // While we merely verify that we have (or can acquire) the lease\n // immediately, we wait to extend the primary lease until after\n // executing transactionOperation(). This ensures that even if the\n // transactionOperation takes a long time, we'll use a recent\n // leaseTimestampMs in the extended (or newly acquired) lease.\n return this.verifyPrimaryLease(persistenceTransaction)\n .next(holdsPrimaryLease => {\n if (holdsPrimaryLease) {\n return /* holdsPrimaryLease= */ true;\n }\n return this.canActAsPrimary(persistenceTransaction);\n })\n .next(holdsPrimaryLease => {\n if (!holdsPrimaryLease) {\n logError(\n `Failed to obtain primary lease for action '${action}'.`\n );\n this.isPrimary = false;\n this.queue.enqueueAndForget(() =>\n this.primaryStateListener(false)\n );\n throw new FirestoreError(\n Code.FAILED_PRECONDITION,\n PRIMARY_LEASE_LOST_ERROR_MSG\n );\n }\n return transactionOperation(persistenceTransaction);\n })\n .next(result => {\n return this.acquireOrExtendPrimaryLease(\n persistenceTransaction\n ).next(() => result);\n });\n } else {\n return this.verifyAllowTabSynchronization(\n persistenceTransaction\n ).next(() => transactionOperation(persistenceTransaction));\n }\n })\n .then(result => {\n persistenceTransaction.raiseOnCommittedEvent();\n return result;\n });\n }\n\n /**\n * Verifies that the current tab is the primary leaseholder or alternatively\n * that the leaseholder has opted into multi-tab synchronization.\n */\n // TODO(b/114226234): Remove this check when `synchronizeTabs` can no longer\n // be turned off.\n private verifyAllowTabSynchronization(\n txn: PersistenceTransaction\n ): PersistencePromise<void> {\n const store = primaryClientStore(txn);\n return store.get(DbPrimaryClient.key).next(currentPrimary => {\n const currentLeaseIsValid =\n currentPrimary !== null &&\n this.isWithinAge(\n currentPrimary.leaseTimestampMs,\n MAX_PRIMARY_ELIGIBLE_AGE_MS\n ) &&\n !this.isClientZombied(currentPrimary.ownerId);\n\n if (currentLeaseIsValid && !this.isLocalClient(currentPrimary)) {\n if (\n !this.allowTabSynchronization ||\n !currentPrimary!.allowTabSynchronization\n ) {\n throw new FirestoreError(\n Code.FAILED_PRECONDITION,\n PRIMARY_LEASE_EXCLUSIVE_ERROR_MSG\n );\n }\n }\n });\n }\n\n /**\n * Obtains or extends the new primary lease for the local client. This\n * method does not verify that the client is eligible for this lease.\n */\n private acquireOrExtendPrimaryLease(\n txn: PersistenceTransaction\n ): PersistencePromise<void> {\n const newPrimary = new DbPrimaryClient(\n this.clientId,\n this.allowTabSynchronization,\n Date.now()\n );\n return primaryClientStore(txn).put(DbPrimaryClient.key, newPrimary);\n }\n\n static isAvailable(): boolean {\n return SimpleDb.isAvailable();\n }\n\n /**\n * Generates a string used as a prefix when storing data in IndexedDB and\n * LocalStorage.\n */\n static buildStoragePrefix(databaseInfo: DatabaseInfo): string {\n // Use two different prefix formats:\n //\n // * firestore / persistenceKey / projectID . databaseID / ...\n // * firestore / persistenceKey / projectID / ...\n //\n // projectIDs are DNS-compatible names and cannot contain dots\n // so there's no danger of collisions.\n let database = databaseInfo.databaseId.projectId;\n if (!databaseInfo.databaseId.isDefaultDatabase) {\n database += '.' + databaseInfo.databaseId.database;\n }\n\n return 'firestore/' + databaseInfo.persistenceKey + '/' + database + '/';\n }\n\n /** Checks the primary lease and removes it if we are the current primary. */\n private releasePrimaryLeaseIfHeld(\n txn: PersistenceTransaction\n ): PersistencePromise<void> {\n const store = primaryClientStore(txn);\n return store.get(DbPrimaryClient.key).next(primaryClient => {\n if (this.isLocalClient(primaryClient)) {\n logDebug(LOG_TAG, 'Releasing primary lease.');\n return store.delete(DbPrimaryClient.key);\n } else {\n return PersistencePromise.resolve();\n }\n });\n }\n\n /** Verifies that `updateTimeMs` is within `maxAgeMs`. */\n private isWithinAge(updateTimeMs: number, maxAgeMs: number): boolean {\n const now = Date.now();\n const minAcceptable = now - maxAgeMs;\n const maxAcceptable = now;\n if (updateTimeMs < minAcceptable) {\n return false;\n } else if (updateTimeMs > maxAcceptable) {\n logError(\n `Detected an update time that is in the future: ${updateTimeMs} > ${maxAcceptable}`\n );\n return false;\n }\n\n return true;\n }\n\n private attachVisibilityHandler(): void {\n if (\n this.document !== null &&\n typeof this.document.addEventListener === 'function'\n ) {\n this.documentVisibilityHandler = () => {\n this.queue.enqueueAndForget(() => {\n this.inForeground = this.document!.visibilityState === 'visible';\n return this.updateClientMetadataAndTryBecomePrimary();\n });\n };\n\n this.document.addEventListener(\n 'visibilitychange',\n this.documentVisibilityHandler\n );\n\n this.inForeground = this.document.visibilityState === 'visible';\n }\n }\n\n private detachVisibilityHandler(): void {\n if (this.documentVisibilityHandler) {\n debugAssert(\n this.document !== null &&\n typeof this.document.addEventListener === 'function',\n \"Expected 'document.addEventListener' to be a function\"\n );\n this.document.removeEventListener(\n 'visibilitychange',\n this.documentVisibilityHandler\n );\n this.documentVisibilityHandler = null;\n }\n }\n\n /**\n * Attaches a window.unload handler that will synchronously write our\n * clientId to a \"zombie client id\" location in LocalStorage. This can be used\n * by tabs trying to acquire the primary lease to determine that the lease\n * is no longer valid even if the timestamp is recent. This is particularly\n * important for the refresh case (so the tab correctly re-acquires the\n * primary lease). LocalStorage is used for this rather than IndexedDb because\n * it is a synchronous API and so can be used reliably from an unload\n * handler.\n */\n private attachWindowUnloadHook(): void {\n if (typeof this.window.addEventListener === 'function') {\n this.windowUnloadHandler = () => {\n // Note: In theory, this should be scheduled on the AsyncQueue since it\n // accesses internal state. We execute this code directly during shutdown\n // to make sure it gets a chance to run.\n this.markClientZombied();\n\n this.queue.enqueueAndForget(() => {\n // Attempt graceful shutdown (including releasing our primary lease),\n // but there's no guarantee it will complete.\n return this.shutdown();\n });\n };\n this.window.addEventListener('unload', this.windowUnloadHandler);\n }\n }\n\n private detachWindowUnloadHook(): void {\n if (this.windowUnloadHandler) {\n debugAssert(\n typeof this.window.removeEventListener === 'function',\n \"Expected 'window.removeEventListener' to be a function\"\n );\n this.window.removeEventListener('unload', this.windowUnloadHandler);\n this.windowUnloadHandler = null;\n }\n }\n\n /**\n * Returns whether a client is \"zombied\" based on its LocalStorage entry.\n * Clients become zombied when their tab closes without running all of the\n * cleanup logic in `shutdown()`.\n */\n private isClientZombied(clientId: ClientId): boolean {\n try {\n const isZombied =\n this.webStorage.getItem(this.zombiedClientLocalStorageKey(clientId)) !==\n null;\n logDebug(\n LOG_TAG,\n `Client '${clientId}' ${\n isZombied ? 'is' : 'is not'\n } zombied in LocalStorage`\n );\n return isZombied;\n } catch (e) {\n // Gracefully handle if LocalStorage isn't working.\n logError(LOG_TAG, 'Failed to get zombied client id.', e);\n return false;\n }\n }\n\n /**\n * Record client as zombied (a client that had its tab closed). Zombied\n * clients are ignored during primary tab selection.\n */\n private markClientZombied(): void {\n try {\n this.webStorage.setItem(\n this.zombiedClientLocalStorageKey(this.clientId),\n String(Date.now())\n );\n } catch (e) {\n // Gracefully handle if LocalStorage isn't available / working.\n logError('Failed to set zombie client id.', e);\n }\n }\n\n /** Removes the zombied client entry if it exists. */\n private removeClientZombiedEntry(): void {\n try {\n this.webStorage.removeItem(\n this.zombiedClientLocalStorageKey(this.clientId)\n );\n } catch (e) {\n // Ignore\n }\n }\n\n private zombiedClientLocalStorageKey(clientId: ClientId): string {\n return `${ZOMBIED_CLIENTS_KEY_PREFIX}_${this.persistenceKey}_${clientId}`;\n }\n}\n\n/**\n * Helper to get a typed SimpleDbStore for the primary client object store.\n */\nfunction primaryClientStore(\n txn: PersistenceTransaction\n): SimpleDbStore<DbPrimaryClientKey, DbPrimaryClient> {\n return IndexedDbPersistence.getStore<DbPrimaryClientKey, DbPrimaryClient>(\n txn,\n DbPrimaryClient.store\n );\n}\n\n/**\n * Helper to get a typed SimpleDbStore for the client metadata object store.\n */\nfunction clientMetadataStore(\n txn: PersistenceTransaction\n): SimpleDbStore<DbClientMetadataKey, DbClientMetadata> {\n return IndexedDbPersistence.getStore<DbClientMetadataKey, DbClientMetadata>(\n txn,\n DbClientMetadata.store\n );\n}\n\n/** Provides LRU functionality for IndexedDB persistence. */\nexport class IndexedDbLruDelegate implements ReferenceDelegate, LruDelegate {\n readonly garbageCollector: LruGarbageCollector;\n\n constructor(private readonly db: IndexedDbPersistence, params: LruParams) {\n this.garbageCollector = new LruGarbageCollector(this, params);\n }\n\n getSequenceNumberCount(\n txn: PersistenceTransaction\n ): PersistencePromise<number> {\n const docCountPromise = this.orphanedDocumentCount(txn);\n const targetCountPromise = this.db.getTargetCache().getTargetCount(txn);\n return targetCountPromise.next(targetCount =>\n docCountPromise.next(docCount => targetCount + docCount)\n );\n }\n\n private orphanedDocumentCount(\n txn: PersistenceTransaction\n ): PersistencePromise<number> {\n let orphanedCount = 0;\n return this.forEachOrphanedDocumentSequenceNumber(txn, _ => {\n orphanedCount++;\n }).next(() => orphanedCount);\n }\n\n forEachTarget(\n txn: PersistenceTransaction,\n f: (q: TargetData) => void\n ): PersistencePromise<void> {\n return this.db.getTargetCache().forEachTarget(txn, f);\n }\n\n forEachOrphanedDocumentSequenceNumber(\n txn: PersistenceTransaction,\n f: (sequenceNumber: ListenSequenceNumber) => void\n ): PersistencePromise<void> {\n return this.forEachOrphanedDocument(txn, (docKey, sequenceNumber) =>\n f(sequenceNumber)\n );\n }\n\n addReference(\n txn: PersistenceTransaction,\n targetId: TargetId,\n key: DocumentKey\n ): PersistencePromise<void> {\n return writeSentinelKey(txn, key);\n }\n\n removeReference(\n txn: PersistenceTransaction,\n targetId: TargetId,\n key: DocumentKey\n ): PersistencePromise<void> {\n return writeSentinelKey(txn, key);\n }\n\n removeTargets(\n txn: PersistenceTransaction,\n upperBound: ListenSequenceNumber,\n activeTargetIds: ActiveTargets\n ): PersistencePromise<number> {\n return this.db\n .getTargetCache()\n .removeTargets(txn, upperBound, activeTargetIds);\n }\n\n markPotentiallyOrphaned(\n txn: PersistenceTransaction,\n key: DocumentKey\n ): PersistencePromise<void> {\n return writeSentinelKey(txn, key);\n }\n\n /**\n * Returns true if anything would prevent this document from being garbage\n * collected, given that the document in question is not present in any\n * targets and has a sequence number less than or equal to the upper bound for\n * the collection run.\n */\n private isPinned(\n txn: PersistenceTransaction,\n docKey: DocumentKey\n ): PersistencePromise<boolean> {\n return mutationQueuesContainKey(txn, docKey);\n }\n\n removeOrphanedDocuments(\n txn: PersistenceTransaction,\n upperBound: ListenSequenceNumber\n ): PersistencePromise<number> {\n const documentCache = this.db.getRemoteDocumentCache();\n const changeBuffer = documentCache.newChangeBuffer();\n\n const promises: Array<PersistencePromise<void>> = [];\n let documentCount = 0;\n\n const iteration = this.forEachOrphanedDocument(\n txn,\n (docKey, sequenceNumber) => {\n if (sequenceNumber <= upperBound) {\n const p = this.isPinned(txn, docKey).next(isPinned => {\n if (!isPinned) {\n documentCount++;\n // Our size accounting requires us to read all documents before\n // removing them.\n return changeBuffer.getEntry(txn, docKey).next(() => {\n changeBuffer.removeEntry(docKey);\n return documentTargetStore(txn).delete(sentinelKey(docKey));\n });\n }\n });\n promises.push(p);\n }\n }\n );\n\n return iteration\n .next(() => PersistencePromise.waitFor(promises))\n .next(() => changeBuffer.apply(txn))\n .next(() => documentCount);\n }\n\n removeTarget(\n txn: PersistenceTransaction,\n targetData: TargetData\n ): PersistencePromise<void> {\n const updated = targetData.withSequenceNumber(txn.currentSequenceNumber);\n return this.db.getTargetCache().updateTargetData(txn, updated);\n }\n\n updateLimboDocument(\n txn: PersistenceTransaction,\n key: DocumentKey\n ): PersistencePromise<void> {\n return writeSentinelKey(txn, key);\n }\n\n /**\n * Call provided function for each document in the cache that is 'orphaned'. Orphaned\n * means not a part of any target, so the only entry in the target-document index for\n * that document will be the sentinel row (targetId 0), which will also have the sequence\n * number for the last time the document was accessed.\n */\n private forEachOrphanedDocument(\n txn: PersistenceTransaction,\n f: (docKey: DocumentKey, sequenceNumber: ListenSequenceNumber) => void\n ): PersistencePromise<void> {\n const store = documentTargetStore(txn);\n let nextToReport: ListenSequenceNumber = ListenSequence.INVALID;\n let nextPath: EncodedResourcePath;\n return store\n .iterate(\n {\n index: DbTargetDocument.documentTargetsIndex\n },\n ([targetId, docKey], { path, sequenceNumber }) => {\n if (targetId === 0) {\n // if nextToReport is valid, report it, this is a new key so the\n // last one must not be a member of any targets.\n if (nextToReport !== ListenSequence.INVALID) {\n f(new DocumentKey(decodeResourcePath(nextPath)), nextToReport);\n }\n // set nextToReport to be this sequence number. It's the next one we\n // might report, if we don't find any targets for this document.\n // Note that the sequence number must be defined when the targetId\n // is 0.\n nextToReport = sequenceNumber!;\n nextPath = path;\n } else {\n // set nextToReport to be invalid, we know we don't need to report\n // this one since we found a target for it.\n nextToReport = ListenSequence.INVALID;\n }\n }\n )\n .next(() => {\n // Since we report sequence numbers after getting to the next key, we\n // need to check if the last key we iterated over was an orphaned\n // document and report it.\n if (nextToReport !== ListenSequence.INVALID) {\n f(new DocumentKey(decodeResourcePath(nextPath)), nextToReport);\n }\n });\n }\n\n getCacheSize(txn: PersistenceTransaction): PersistencePromise<number> {\n return this.db.getRemoteDocumentCache().getSize(txn);\n }\n}\n\nfunction sentinelKey(key: DocumentKey): [TargetId, EncodedResourcePath] {\n return [0, encodeResourcePath(key.path)];\n}\n\n/**\n * @return A value suitable for writing a sentinel row in the target-document\n * store.\n */\nfunction sentinelRow(\n key: DocumentKey,\n sequenceNumber: ListenSequenceNumber\n): DbTargetDocument {\n return new DbTargetDocument(0, encodeResourcePath(key.path), sequenceNumber);\n}\n\nfunction writeSentinelKey(\n txn: PersistenceTransaction,\n key: DocumentKey\n): PersistencePromise<void> {\n return documentTargetStore(txn).put(\n sentinelRow(key, txn.currentSequenceNumber)\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 { Timestamp } from '../api/timestamp';\nimport { User } from '../auth/user';\nimport { Query } from '../core/query';\nimport { BatchId } from '../core/types';\nimport { DocumentKeySet } from '../model/collections';\nimport { DocumentKey } from '../model/document_key';\nimport { Mutation } from '../model/mutation';\nimport { BATCHID_UNKNOWN, MutationBatch } from '../model/mutation_batch';\nimport { ResourcePath } from '../model/path';\nimport { debugAssert, fail, hardAssert } from '../util/assert';\nimport { primitiveComparator } from '../util/misc';\nimport { ByteString } from '../util/byte_string';\nimport { SortedMap } from '../util/sorted_map';\nimport { SortedSet } from '../util/sorted_set';\nimport { decodeResourcePath } from './encoded_resource_path';\nimport { IndexManager } from './index_manager';\nimport {\n IndexedDbPersistence,\n IndexedDbTransaction\n} from './indexeddb_persistence';\nimport {\n DbDocumentMutation,\n DbDocumentMutationKey,\n DbMutationBatch,\n DbMutationBatchKey,\n DbMutationQueue,\n DbMutationQueueKey\n} from './indexeddb_schema';\nimport { LocalSerializer } from './local_serializer';\nimport { MutationQueue } from './mutation_queue';\nimport { PersistenceTransaction, ReferenceDelegate } from './persistence';\nimport { PersistencePromise } from './persistence_promise';\nimport { SimpleDbStore, SimpleDbTransaction } from './simple_db';\n\n/** A mutation queue for a specific user, backed by IndexedDB. */\nexport class IndexedDbMutationQueue implements MutationQueue {\n /**\n * Caches the document keys for pending mutation batches. If the mutation\n * has been removed from IndexedDb, the cached value may continue to\n * be used to retrieve the batch's document keys. To remove a cached value\n * locally, `removeCachedMutationKeys()` should be invoked either directly\n * or through `removeMutationBatches()`.\n *\n * With multi-tab, when the primary client acknowledges or rejects a mutation,\n * this cache is used by secondary clients to invalidate the local\n * view of the documents that were previously affected by the mutation.\n */\n // PORTING NOTE: Multi-tab only.\n private documentKeysByBatchId = {} as { [batchId: number]: DocumentKeySet };\n\n constructor(\n /**\n * The normalized userId (e.g. null UID => \"\" userId) used to store /\n * retrieve mutations.\n */\n private userId: string,\n private readonly serializer: LocalSerializer,\n private readonly indexManager: IndexManager,\n private readonly referenceDelegate: ReferenceDelegate\n ) {}\n\n /**\n * Creates a new mutation queue for the given user.\n * @param user The user for which to create a mutation queue.\n * @param serializer The serializer to use when persisting to IndexedDb.\n */\n static forUser(\n user: User,\n serializer: LocalSerializer,\n indexManager: IndexManager,\n referenceDelegate: ReferenceDelegate\n ): IndexedDbMutationQueue {\n // TODO(mcg): Figure out what constraints there are on userIDs\n // In particular, are there any reserved characters? are empty ids allowed?\n // For the moment store these together in the same mutations table assuming\n // that empty userIDs aren't allowed.\n hardAssert(user.uid !== '', 'UserID must not be an empty string.');\n const userId = user.isAuthenticated() ? user.uid! : '';\n return new IndexedDbMutationQueue(\n userId,\n serializer,\n indexManager,\n referenceDelegate\n );\n }\n\n checkEmpty(transaction: PersistenceTransaction): PersistencePromise<boolean> {\n let empty = true;\n const range = IDBKeyRange.bound(\n [this.userId, Number.NEGATIVE_INFINITY],\n [this.userId, Number.POSITIVE_INFINITY]\n );\n return mutationsStore(transaction)\n .iterate(\n { index: DbMutationBatch.userMutationsIndex, range },\n (key, value, control) => {\n empty = false;\n control.done();\n }\n )\n .next(() => empty);\n }\n\n acknowledgeBatch(\n transaction: PersistenceTransaction,\n batch: MutationBatch,\n streamToken: ByteString\n ): PersistencePromise<void> {\n return this.getMutationQueueMetadata(transaction).next(metadata => {\n // We can't store the resumeToken as a ByteString in IndexedDB, so we\n // convert it to a Base64 string for storage.\n metadata.lastStreamToken = streamToken.toBase64();\n\n return mutationQueuesStore(transaction).put(metadata);\n });\n }\n\n getLastStreamToken(\n transaction: PersistenceTransaction\n ): PersistencePromise<ByteString> {\n return this.getMutationQueueMetadata(transaction).next<ByteString>(\n metadata => ByteString.fromBase64String(metadata.lastStreamToken)\n );\n }\n\n setLastStreamToken(\n transaction: PersistenceTransaction,\n streamToken: ByteString\n ): PersistencePromise<void> {\n return this.getMutationQueueMetadata(transaction).next(metadata => {\n // We can't store the resumeToken as a ByteString in IndexedDB, so we\n // convert it to a Base64 string for storage.\n metadata.lastStreamToken = streamToken.toBase64();\n return mutationQueuesStore(transaction).put(metadata);\n });\n }\n\n addMutationBatch(\n transaction: PersistenceTransaction,\n localWriteTime: Timestamp,\n baseMutations: Mutation[],\n mutations: Mutation[]\n ): PersistencePromise<MutationBatch> {\n const documentStore = documentMutationsStore(transaction);\n const mutationStore = mutationsStore(transaction);\n\n // The IndexedDb implementation in Chrome (and Firefox) does not handle\n // compound indices that include auto-generated keys correctly. To ensure\n // that the index entry is added correctly in all browsers, we perform two\n // writes: The first write is used to retrieve the next auto-generated Batch\n // ID, and the second write populates the index and stores the actual\n // mutation batch.\n // See: https://bugs.chromium.org/p/chromium/issues/detail?id=701972\n\n // We write an empty object to obtain key\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return mutationStore.add({} as any).next(batchId => {\n hardAssert(\n typeof batchId === 'number',\n 'Auto-generated key is not a number'\n );\n\n const batch = new MutationBatch(\n batchId,\n localWriteTime,\n baseMutations,\n mutations\n );\n const dbBatch = this.serializer.toDbMutationBatch(this.userId, batch);\n\n const promises: Array<PersistencePromise<void>> = [];\n let collectionParents = new SortedSet<ResourcePath>((l, r) =>\n primitiveComparator(l.canonicalString(), r.canonicalString())\n );\n for (const mutation of mutations) {\n const indexKey = DbDocumentMutation.key(\n this.userId,\n mutation.key.path,\n batchId\n );\n collectionParents = collectionParents.add(mutation.key.path.popLast());\n promises.push(mutationStore.put(dbBatch));\n promises.push(\n documentStore.put(indexKey, DbDocumentMutation.PLACEHOLDER)\n );\n }\n\n collectionParents.forEach(parent => {\n promises.push(\n this.indexManager.addToCollectionParentIndex(transaction, parent)\n );\n });\n\n transaction.addOnCommittedListener(() => {\n this.documentKeysByBatchId[batchId] = batch.keys();\n });\n\n return PersistencePromise.waitFor(promises).next(() => batch);\n });\n }\n\n lookupMutationBatch(\n transaction: PersistenceTransaction,\n batchId: BatchId\n ): PersistencePromise<MutationBatch | null> {\n return mutationsStore(transaction)\n .get(batchId)\n .next(dbBatch => {\n if (dbBatch) {\n hardAssert(\n dbBatch.userId === this.userId,\n `Unexpected user '${dbBatch.userId}' for mutation batch ${batchId}`\n );\n return this.serializer.fromDbMutationBatch(dbBatch);\n }\n return null;\n });\n }\n\n /**\n * Returns the document keys for the mutation batch with the given batchId.\n * For primary clients, this method returns `null` after\n * `removeMutationBatches()` has been called. Secondary clients return a\n * cached result until `removeCachedMutationKeys()` is invoked.\n */\n // PORTING NOTE: Multi-tab only.\n lookupMutationKeys(\n transaction: PersistenceTransaction,\n batchId: BatchId\n ): PersistencePromise<DocumentKeySet | null> {\n if (this.documentKeysByBatchId[batchId]) {\n return PersistencePromise.resolve<DocumentKeySet | null>(\n this.documentKeysByBatchId[batchId]\n );\n } else {\n return this.lookupMutationBatch(transaction, batchId).next(batch => {\n if (batch) {\n const keys = batch.keys();\n this.documentKeysByBatchId[batchId] = keys;\n return keys;\n } else {\n return null;\n }\n });\n }\n }\n\n getNextMutationBatchAfterBatchId(\n transaction: PersistenceTransaction,\n batchId: BatchId\n ): PersistencePromise<MutationBatch | null> {\n const nextBatchId = batchId + 1;\n\n const range = IDBKeyRange.lowerBound([this.userId, nextBatchId]);\n let foundBatch: MutationBatch | null = null;\n return mutationsStore(transaction)\n .iterate(\n { index: DbMutationBatch.userMutationsIndex, range },\n (key, dbBatch, control) => {\n if (dbBatch.userId === this.userId) {\n hardAssert(\n dbBatch.batchId >= nextBatchId,\n 'Should have found mutation after ' + nextBatchId\n );\n foundBatch = this.serializer.fromDbMutationBatch(dbBatch);\n }\n control.done();\n }\n )\n .next(() => foundBatch);\n }\n\n getHighestUnacknowledgedBatchId(\n transaction: PersistenceTransaction\n ): PersistencePromise<BatchId> {\n const range = IDBKeyRange.upperBound([\n this.userId,\n Number.POSITIVE_INFINITY\n ]);\n\n let batchId = BATCHID_UNKNOWN;\n return mutationsStore(transaction)\n .iterate(\n { index: DbMutationBatch.userMutationsIndex, range, reverse: true },\n (key, dbBatch, control) => {\n batchId = dbBatch.batchId;\n control.done();\n }\n )\n .next(() => batchId);\n }\n\n getAllMutationBatches(\n transaction: PersistenceTransaction\n ): PersistencePromise<MutationBatch[]> {\n const range = IDBKeyRange.bound(\n [this.userId, BATCHID_UNKNOWN],\n [this.userId, Number.POSITIVE_INFINITY]\n );\n return mutationsStore(transaction)\n .loadAll(DbMutationBatch.userMutationsIndex, range)\n .next(dbBatches =>\n dbBatches.map(dbBatch => this.serializer.fromDbMutationBatch(dbBatch))\n );\n }\n\n getAllMutationBatchesAffectingDocumentKey(\n transaction: PersistenceTransaction,\n documentKey: DocumentKey\n ): PersistencePromise<MutationBatch[]> {\n // Scan the document-mutation index starting with a prefix starting with\n // the given documentKey.\n const indexPrefix = DbDocumentMutation.prefixForPath(\n this.userId,\n documentKey.path\n );\n const indexStart = IDBKeyRange.lowerBound(indexPrefix);\n\n const results: MutationBatch[] = [];\n return documentMutationsStore(transaction)\n .iterate({ range: indexStart }, (indexKey, _, control) => {\n const [userID, encodedPath, batchId] = indexKey;\n\n // Only consider rows matching exactly the specific key of\n // interest. Note that because we order by path first, and we\n // order terminators before path separators, we'll encounter all\n // the index rows for documentKey contiguously. In particular, all\n // the rows for documentKey will occur before any rows for\n // documents nested in a subcollection beneath documentKey so we\n // can stop as soon as we hit any such row.\n const path = decodeResourcePath(encodedPath);\n if (userID !== this.userId || !documentKey.path.isEqual(path)) {\n control.done();\n return;\n }\n // Look up the mutation batch in the store.\n return mutationsStore(transaction)\n .get(batchId)\n .next(mutation => {\n if (!mutation) {\n throw fail(\n 'Dangling document-mutation reference found: ' +\n indexKey +\n ' which points to ' +\n batchId\n );\n }\n hardAssert(\n mutation.userId === this.userId,\n `Unexpected user '${mutation.userId}' for mutation batch ${batchId}`\n );\n results.push(this.serializer.fromDbMutationBatch(mutation));\n });\n })\n .next(() => results);\n }\n\n getAllMutationBatchesAffectingDocumentKeys(\n transaction: PersistenceTransaction,\n documentKeys: SortedMap<DocumentKey, unknown>\n ): PersistencePromise<MutationBatch[]> {\n let uniqueBatchIDs = new SortedSet<BatchId>(primitiveComparator);\n\n const promises: Array<PersistencePromise<void>> = [];\n documentKeys.forEach(documentKey => {\n const indexStart = DbDocumentMutation.prefixForPath(\n this.userId,\n documentKey.path\n );\n const range = IDBKeyRange.lowerBound(indexStart);\n\n const promise = documentMutationsStore(transaction).iterate(\n { range },\n (indexKey, _, control) => {\n const [userID, encodedPath, batchID] = indexKey;\n\n // Only consider rows matching exactly the specific key of\n // interest. Note that because we order by path first, and we\n // order terminators before path separators, we'll encounter all\n // the index rows for documentKey contiguously. In particular, all\n // the rows for documentKey will occur before any rows for\n // documents nested in a subcollection beneath documentKey so we\n // can stop as soon as we hit any such row.\n const path = decodeResourcePath(encodedPath);\n if (userID !== this.userId || !documentKey.path.isEqual(path)) {\n control.done();\n return;\n }\n\n uniqueBatchIDs = uniqueBatchIDs.add(batchID);\n }\n );\n\n promises.push(promise);\n });\n\n return PersistencePromise.waitFor(promises).next(() =>\n this.lookupMutationBatches(transaction, uniqueBatchIDs)\n );\n }\n\n getAllMutationBatchesAffectingQuery(\n transaction: PersistenceTransaction,\n query: Query\n ): PersistencePromise<MutationBatch[]> {\n debugAssert(\n !query.isDocumentQuery(),\n \"Document queries shouldn't go down this path\"\n );\n debugAssert(\n !query.isCollectionGroupQuery(),\n 'CollectionGroup queries should be handled in LocalDocumentsView'\n );\n\n const queryPath = query.path;\n const immediateChildrenLength = queryPath.length + 1;\n\n // TODO(mcg): Actually implement a single-collection query\n //\n // This is actually executing an ancestor query, traversing the whole\n // subtree below the collection which can be horrifically inefficient for\n // some structures. The right way to solve this is to implement the full\n // value index, but that's not in the cards in the near future so this is\n // the best we can do for the moment.\n //\n // Since we don't yet index the actual properties in the mutations, our\n // current approach is to just return all mutation batches that affect\n // documents in the collection being queried.\n const indexPrefix = DbDocumentMutation.prefixForPath(\n this.userId,\n queryPath\n );\n const indexStart = IDBKeyRange.lowerBound(indexPrefix);\n\n // Collect up unique batchIDs encountered during a scan of the index. Use a\n // SortedSet to accumulate batch IDs so they can be traversed in order in a\n // scan of the main table.\n let uniqueBatchIDs = new SortedSet<BatchId>(primitiveComparator);\n return documentMutationsStore(transaction)\n .iterate({ range: indexStart }, (indexKey, _, control) => {\n const [userID, encodedPath, batchID] = indexKey;\n const path = decodeResourcePath(encodedPath);\n if (userID !== this.userId || !queryPath.isPrefixOf(path)) {\n control.done();\n return;\n }\n // Rows with document keys more than one segment longer than the\n // query path can't be matches. For example, a query on 'rooms'\n // can't match the document /rooms/abc/messages/xyx.\n // TODO(mcg): we'll need a different scanner when we implement\n // ancestor queries.\n if (path.length !== immediateChildrenLength) {\n return;\n }\n uniqueBatchIDs = uniqueBatchIDs.add(batchID);\n })\n .next(() => this.lookupMutationBatches(transaction, uniqueBatchIDs));\n }\n\n private lookupMutationBatches(\n transaction: PersistenceTransaction,\n batchIDs: SortedSet<BatchId>\n ): PersistencePromise<MutationBatch[]> {\n const results: MutationBatch[] = [];\n const promises: Array<PersistencePromise<void>> = [];\n // TODO(rockwood): Implement this using iterate.\n batchIDs.forEach(batchId => {\n promises.push(\n mutationsStore(transaction)\n .get(batchId)\n .next(mutation => {\n if (mutation === null) {\n throw fail(\n 'Dangling document-mutation reference found, ' +\n 'which points to ' +\n batchId\n );\n }\n hardAssert(\n mutation.userId === this.userId,\n `Unexpected user '${mutation.userId}' for mutation batch ${batchId}`\n );\n results.push(this.serializer.fromDbMutationBatch(mutation));\n })\n );\n });\n return PersistencePromise.waitFor(promises).next(() => results);\n }\n\n removeMutationBatch(\n transaction: PersistenceTransaction,\n batch: MutationBatch\n ): PersistencePromise<void> {\n return removeMutationBatch(\n (transaction as IndexedDbTransaction).simpleDbTransaction,\n this.userId,\n batch\n ).next(removedDocuments => {\n transaction.addOnCommittedListener(() => {\n this.removeCachedMutationKeys(batch.batchId);\n });\n return PersistencePromise.forEach(\n removedDocuments,\n (key: DocumentKey) => {\n return this.referenceDelegate.markPotentiallyOrphaned(\n transaction,\n key\n );\n }\n );\n });\n }\n\n /**\n * Clears the cached keys for a mutation batch. This method should be\n * called by secondary clients after they process mutation updates.\n *\n * Note that this method does not have to be called from primary clients as\n * the corresponding cache entries are cleared when an acknowledged or\n * rejected batch is removed from the mutation queue.\n */\n // PORTING NOTE: Multi-tab only\n removeCachedMutationKeys(batchId: BatchId): void {\n delete this.documentKeysByBatchId[batchId];\n }\n\n performConsistencyCheck(\n txn: PersistenceTransaction\n ): PersistencePromise<void> {\n return this.checkEmpty(txn).next(empty => {\n if (!empty) {\n return PersistencePromise.resolve();\n }\n\n // Verify that there are no entries in the documentMutations index if\n // the queue is empty.\n const startRange = IDBKeyRange.lowerBound(\n DbDocumentMutation.prefixForUser(this.userId)\n );\n const danglingMutationReferences: ResourcePath[] = [];\n return documentMutationsStore(txn)\n .iterate({ range: startRange }, (key, _, control) => {\n const userID = key[0];\n if (userID !== this.userId) {\n control.done();\n return;\n } else {\n const path = decodeResourcePath(key[1]);\n danglingMutationReferences.push(path);\n }\n })\n .next(() => {\n hardAssert(\n danglingMutationReferences.length === 0,\n 'Document leak -- detected dangling mutation references when queue is empty. ' +\n 'Dangling keys: ' +\n danglingMutationReferences.map(p => p.canonicalString())\n );\n });\n });\n }\n\n containsKey(\n txn: PersistenceTransaction,\n key: DocumentKey\n ): PersistencePromise<boolean> {\n return mutationQueueContainsKey(txn, this.userId, key);\n }\n\n // PORTING NOTE: Multi-tab only (state is held in memory in other clients).\n /** Returns the mutation queue's metadata from IndexedDb. */\n private getMutationQueueMetadata(\n transaction: PersistenceTransaction\n ): PersistencePromise<DbMutationQueue> {\n return mutationQueuesStore(transaction)\n .get(this.userId)\n .next((metadata: DbMutationQueue | null) => {\n return (\n metadata ||\n new DbMutationQueue(\n this.userId,\n BATCHID_UNKNOWN,\n /*lastStreamToken=*/ ''\n )\n );\n });\n }\n}\n\n/**\n * @return true if the mutation queue for the given user contains a pending\n * mutation for the given key.\n */\nfunction mutationQueueContainsKey(\n txn: PersistenceTransaction,\n userId: string,\n key: DocumentKey\n): PersistencePromise<boolean> {\n const indexKey = DbDocumentMutation.prefixForPath(userId, key.path);\n const encodedPath = indexKey[1];\n const startRange = IDBKeyRange.lowerBound(indexKey);\n let containsKey = false;\n return documentMutationsStore(txn)\n .iterate({ range: startRange, keysOnly: true }, (key, value, control) => {\n const [userID, keyPath, /*batchID*/ _] = key;\n if (userID === userId && keyPath === encodedPath) {\n containsKey = true;\n }\n control.done();\n })\n .next(() => containsKey);\n}\n\n/** Returns true if any mutation queue contains the given document. */\nexport function mutationQueuesContainKey(\n txn: PersistenceTransaction,\n docKey: DocumentKey\n): PersistencePromise<boolean> {\n let found = false;\n return mutationQueuesStore(txn)\n .iterateSerial(userId => {\n return mutationQueueContainsKey(txn, userId, docKey).next(containsKey => {\n if (containsKey) {\n found = true;\n }\n return PersistencePromise.resolve(!containsKey);\n });\n })\n .next(() => found);\n}\n\n/**\n * Delete a mutation batch and the associated document mutations.\n * @return A PersistencePromise of the document mutations that were removed.\n */\nexport function removeMutationBatch(\n txn: SimpleDbTransaction,\n userId: string,\n batch: MutationBatch\n): PersistencePromise<DocumentKey[]> {\n const mutationStore = txn.store<DbMutationBatchKey, DbMutationBatch>(\n DbMutationBatch.store\n );\n const indexTxn = txn.store<DbDocumentMutationKey, DbDocumentMutation>(\n DbDocumentMutation.store\n );\n const promises: Array<PersistencePromise<void>> = [];\n\n const range = IDBKeyRange.only(batch.batchId);\n let numDeleted = 0;\n const removePromise = mutationStore.iterate(\n { range },\n (key, value, control) => {\n numDeleted++;\n return control.delete();\n }\n );\n promises.push(\n removePromise.next(() => {\n hardAssert(\n numDeleted === 1,\n 'Dangling document-mutation reference found: Missing batch ' +\n batch.batchId\n );\n })\n );\n const removedDocuments: DocumentKey[] = [];\n for (const mutation of batch.mutations) {\n const indexKey = DbDocumentMutation.key(\n userId,\n mutation.key.path,\n batch.batchId\n );\n promises.push(indexTxn.delete(indexKey));\n removedDocuments.push(mutation.key);\n }\n return PersistencePromise.waitFor(promises).next(() => removedDocuments);\n}\n\n/**\n * Helper to get a typed SimpleDbStore for the mutations object store.\n */\nfunction mutationsStore(\n txn: PersistenceTransaction\n): SimpleDbStore<DbMutationBatchKey, DbMutationBatch> {\n return IndexedDbPersistence.getStore<DbMutationBatchKey, DbMutationBatch>(\n txn,\n DbMutationBatch.store\n );\n}\n\n/**\n * Helper to get a typed SimpleDbStore for the mutationQueues object store.\n */\nfunction documentMutationsStore(\n txn: PersistenceTransaction\n): SimpleDbStore<DbDocumentMutationKey, DbDocumentMutation> {\n return IndexedDbPersistence.getStore<\n DbDocumentMutationKey,\n DbDocumentMutation\n >(txn, DbDocumentMutation.store);\n}\n\n/**\n * Helper to get a typed SimpleDbStore for the mutationQueues object store.\n */\nfunction mutationQueuesStore(\n txn: PersistenceTransaction\n): SimpleDbStore<DbMutationQueueKey, DbMutationQueue> {\n return IndexedDbPersistence.getStore<DbMutationQueueKey, DbMutationQueue>(\n txn,\n DbMutationQueue.store\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 { BatchId, ListenSequenceNumber, TargetId } from '../core/types';\nimport { ResourcePath } from '../model/path';\nimport * as api from '../protos/firestore_proto_api';\nimport { hardAssert, debugAssert } from '../util/assert';\n\nimport { SnapshotVersion } from '../core/snapshot_version';\nimport { BATCHID_UNKNOWN } from '../model/mutation_batch';\nimport {\n decodeResourcePath,\n encodeResourcePath,\n EncodedResourcePath\n} from './encoded_resource_path';\nimport { removeMutationBatch } from './indexeddb_mutation_queue';\nimport { dbDocumentSize } from './indexeddb_remote_document_cache';\nimport { LocalSerializer } from './local_serializer';\nimport { MemoryCollectionParentIndex } from './memory_index_manager';\nimport { PersistencePromise } from './persistence_promise';\nimport { SimpleDbSchemaConverter, SimpleDbTransaction } from './simple_db';\n\n/**\n * Schema Version for the Web client:\n * 1. Initial version including Mutation Queue, Query Cache, and Remote\n * Document Cache\n * 2. Used to ensure a targetGlobal object exists and add targetCount to it. No\n * longer required because migration 3 unconditionally clears it.\n * 3. Dropped and re-created Query Cache to deal with cache corruption related\n * to limbo resolution. Addresses\n * https://github.com/firebase/firebase-ios-sdk/issues/1548\n * 4. Multi-Tab Support.\n * 5. Removal of held write acks.\n * 6. Create document global for tracking document cache size.\n * 7. Ensure every cached document has a sentinel row with a sequence number.\n * 8. Add collection-parent index for Collection Group queries.\n * 9. Change RemoteDocumentChanges store to be keyed by readTime rather than\n * an auto-incrementing ID. This is required for Index-Free queries.\n * 10. Rewrite the canonical IDs to the explicit Protobuf-based format.\n */\nexport const SCHEMA_VERSION = 10;\n\n/** Performs database creation and schema upgrades. */\nexport class SchemaConverter implements SimpleDbSchemaConverter {\n constructor(private readonly serializer: LocalSerializer) {}\n\n /**\n * Performs database creation and schema upgrades.\n *\n * Note that in production, this method is only ever used to upgrade the schema\n * to SCHEMA_VERSION. Different values of toVersion are only used for testing\n * and local feature development.\n */\n createOrUpgrade(\n db: IDBDatabase,\n txn: IDBTransaction,\n fromVersion: number,\n toVersion: number\n ): PersistencePromise<void> {\n hardAssert(\n fromVersion < toVersion &&\n fromVersion >= 0 &&\n toVersion <= SCHEMA_VERSION,\n `Unexpected schema upgrade from v${fromVersion} to v${toVersion}.`\n );\n\n const simpleDbTransaction = new SimpleDbTransaction(txn);\n\n if (fromVersion < 1 && toVersion >= 1) {\n createPrimaryClientStore(db);\n createMutationQueue(db);\n createQueryCache(db);\n createRemoteDocumentCache(db);\n }\n\n // Migration 2 to populate the targetGlobal object no longer needed since\n // migration 3 unconditionally clears it.\n\n let p = PersistencePromise.resolve();\n if (fromVersion < 3 && toVersion >= 3) {\n // Brand new clients don't need to drop and recreate--only clients that\n // potentially have corrupt data.\n if (fromVersion !== 0) {\n dropQueryCache(db);\n createQueryCache(db);\n }\n p = p.next(() => writeEmptyTargetGlobalEntry(simpleDbTransaction));\n }\n\n if (fromVersion < 4 && toVersion >= 4) {\n if (fromVersion !== 0) {\n // Schema version 3 uses auto-generated keys to generate globally unique\n // mutation batch IDs (this was previously ensured internally by the\n // client). To migrate to the new schema, we have to read all mutations\n // and write them back out. We preserve the existing batch IDs to guarantee\n // consistency with other object stores. Any further mutation batch IDs will\n // be auto-generated.\n p = p.next(() =>\n upgradeMutationBatchSchemaAndMigrateData(db, simpleDbTransaction)\n );\n }\n\n p = p.next(() => {\n createClientMetadataStore(db);\n });\n }\n\n if (fromVersion < 5 && toVersion >= 5) {\n p = p.next(() => this.removeAcknowledgedMutations(simpleDbTransaction));\n }\n\n if (fromVersion < 6 && toVersion >= 6) {\n p = p.next(() => {\n createDocumentGlobalStore(db);\n return this.addDocumentGlobal(simpleDbTransaction);\n });\n }\n\n if (fromVersion < 7 && toVersion >= 7) {\n p = p.next(() => this.ensureSequenceNumbers(simpleDbTransaction));\n }\n\n if (fromVersion < 8 && toVersion >= 8) {\n p = p.next(() =>\n this.createCollectionParentIndex(db, simpleDbTransaction)\n );\n }\n\n if (fromVersion < 9 && toVersion >= 9) {\n p = p.next(() => {\n // Multi-Tab used to manage its own changelog, but this has been moved\n // to the DbRemoteDocument object store itself. Since the previous change\n // log only contained transient data, we can drop its object store.\n dropRemoteDocumentChangesStore(db);\n createRemoteDocumentReadTimeIndex(txn);\n });\n }\n\n if (fromVersion < 10 && toVersion >= 10) {\n p = p.next(() => this.rewriteCanonicalIds(simpleDbTransaction));\n }\n return p;\n }\n\n private addDocumentGlobal(\n txn: SimpleDbTransaction\n ): PersistencePromise<void> {\n let byteCount = 0;\n return txn\n .store<DbRemoteDocumentKey, DbRemoteDocument>(DbRemoteDocument.store)\n .iterate((_, doc) => {\n byteCount += dbDocumentSize(doc);\n })\n .next(() => {\n const metadata = new DbRemoteDocumentGlobal(byteCount);\n return txn\n .store<DbRemoteDocumentGlobalKey, DbRemoteDocumentGlobal>(\n DbRemoteDocumentGlobal.store\n )\n .put(DbRemoteDocumentGlobal.key, metadata);\n });\n }\n\n private removeAcknowledgedMutations(\n txn: SimpleDbTransaction\n ): PersistencePromise<void> {\n const queuesStore = txn.store<DbMutationQueueKey, DbMutationQueue>(\n DbMutationQueue.store\n );\n const mutationsStore = txn.store<DbMutationBatchKey, DbMutationBatch>(\n DbMutationBatch.store\n );\n\n return queuesStore.loadAll().next(queues => {\n return PersistencePromise.forEach(queues, (queue: DbMutationQueue) => {\n const range = IDBKeyRange.bound(\n [queue.userId, BATCHID_UNKNOWN],\n [queue.userId, queue.lastAcknowledgedBatchId]\n );\n\n return mutationsStore\n .loadAll(DbMutationBatch.userMutationsIndex, range)\n .next(dbBatches => {\n return PersistencePromise.forEach(\n dbBatches,\n (dbBatch: DbMutationBatch) => {\n hardAssert(\n dbBatch.userId === queue.userId,\n `Cannot process batch ${dbBatch.batchId} from unexpected user`\n );\n const batch = this.serializer.fromDbMutationBatch(dbBatch);\n\n return removeMutationBatch(\n txn,\n queue.userId,\n batch\n ).next(() => {});\n }\n );\n });\n });\n });\n }\n\n /**\n * Ensures that every document in the remote document cache has a corresponding sentinel row\n * with a sequence number. Missing rows are given the most recently used sequence number.\n */\n private ensureSequenceNumbers(\n txn: SimpleDbTransaction\n ): PersistencePromise<void> {\n const documentTargetStore = txn.store<\n DbTargetDocumentKey,\n DbTargetDocument\n >(DbTargetDocument.store);\n const documentsStore = txn.store<DbRemoteDocumentKey, DbRemoteDocument>(\n DbRemoteDocument.store\n );\n const globalTargetStore = txn.store<DbTargetGlobalKey, DbTargetGlobal>(\n DbTargetGlobal.store\n );\n\n return globalTargetStore.get(DbTargetGlobal.key).next(metadata => {\n debugAssert(\n !!metadata,\n 'Metadata should have been written during the version 3 migration'\n );\n const writeSentinelKey = (\n path: ResourcePath\n ): PersistencePromise<void> => {\n return documentTargetStore.put(\n new DbTargetDocument(\n 0,\n encodeResourcePath(path),\n metadata!.highestListenSequenceNumber!\n )\n );\n };\n\n const promises: Array<PersistencePromise<void>> = [];\n return documentsStore\n .iterate((key, doc) => {\n const path = new ResourcePath(key);\n const docSentinelKey = sentinelKey(path);\n promises.push(\n documentTargetStore.get(docSentinelKey).next(maybeSentinel => {\n if (!maybeSentinel) {\n return writeSentinelKey(path);\n } else {\n return PersistencePromise.resolve();\n }\n })\n );\n })\n .next(() => PersistencePromise.waitFor(promises));\n });\n }\n\n private createCollectionParentIndex(\n db: IDBDatabase,\n txn: SimpleDbTransaction\n ): PersistencePromise<void> {\n // Create the index.\n db.createObjectStore(DbCollectionParent.store, {\n keyPath: DbCollectionParent.keyPath\n });\n\n const collectionParentsStore = txn.store<\n DbCollectionParentKey,\n DbCollectionParent\n >(DbCollectionParent.store);\n\n // Helper to add an index entry iff we haven't already written it.\n const cache = new MemoryCollectionParentIndex();\n const addEntry = (\n collectionPath: ResourcePath\n ): PersistencePromise<void> | undefined => {\n if (cache.add(collectionPath)) {\n const collectionId = collectionPath.lastSegment();\n const parentPath = collectionPath.popLast();\n return collectionParentsStore.put({\n collectionId,\n parent: encodeResourcePath(parentPath)\n });\n }\n };\n\n // Index existing remote documents.\n return txn\n .store<DbRemoteDocumentKey, DbRemoteDocument>(DbRemoteDocument.store)\n .iterate({ keysOnly: true }, (pathSegments, _) => {\n const path = new ResourcePath(pathSegments);\n return addEntry(path.popLast());\n })\n .next(() => {\n // Index existing mutations.\n return txn\n .store<DbDocumentMutationKey, DbDocumentMutation>(\n DbDocumentMutation.store\n )\n .iterate({ keysOnly: true }, ([userID, encodedPath, batchId], _) => {\n const path = decodeResourcePath(encodedPath);\n return addEntry(path.popLast());\n });\n });\n }\n\n private rewriteCanonicalIds(\n txn: SimpleDbTransaction\n ): PersistencePromise<void> {\n const targetStore = txn.store<DbTargetKey, DbTarget>(DbTarget.store);\n return targetStore.iterate((key, originalDbTarget) => {\n const originalTargetData = this.serializer.fromDbTarget(originalDbTarget);\n const updatedDbTarget = this.serializer.toDbTarget(originalTargetData);\n return targetStore.put(updatedDbTarget);\n });\n }\n}\n\nfunction sentinelKey(path: ResourcePath): DbTargetDocumentKey {\n return [0, encodeResourcePath(path)];\n}\n\n/**\n * Wrapper class to store timestamps (seconds and nanos) in IndexedDb objects.\n */\nexport class DbTimestamp {\n constructor(public seconds: number, public nanoseconds: number) {}\n}\n\n/** A timestamp type that can be used in IndexedDb keys. */\nexport type DbTimestampKey = [/* seconds */ number, /* nanos */ number];\n\n// The key for the singleton object in the DbPrimaryClient is a single string.\nexport type DbPrimaryClientKey = typeof DbPrimaryClient.key;\n\n/**\n * A singleton object to be stored in the 'owner' store in IndexedDb.\n *\n * A given database can have a single primary tab assigned at a given time. That\n * tab must validate that it is still holding the primary lease before every\n * operation that requires locked access. The primary tab should regularly\n * write an updated timestamp to this lease to prevent other tabs from\n * \"stealing\" the primary lease\n */\nexport class DbPrimaryClient {\n /**\n * Name of the IndexedDb object store.\n *\n * Note that the name 'owner' is chosen to ensure backwards compatibility with\n * older clients that only supported single locked access to the persistence\n * layer.\n */\n static store = 'owner';\n\n /**\n * The key string used for the single object that exists in the\n * DbPrimaryClient store.\n */\n static key = 'owner';\n\n constructor(\n public ownerId: string,\n /** Whether to allow shared access from multiple tabs. */\n public allowTabSynchronization: boolean,\n public leaseTimestampMs: number\n ) {}\n}\n\nfunction createPrimaryClientStore(db: IDBDatabase): void {\n db.createObjectStore(DbPrimaryClient.store);\n}\n\n/** Object keys in the 'mutationQueues' store are userId strings. */\nexport type DbMutationQueueKey = string;\n\n/**\n * An object to be stored in the 'mutationQueues' store in IndexedDb.\n *\n * Each user gets a single queue of MutationBatches to apply to the server.\n * DbMutationQueue tracks the metadata about the queue.\n */\nexport class DbMutationQueue {\n /** Name of the IndexedDb object store. */\n static store = 'mutationQueues';\n\n /** Keys are automatically assigned via the userId property. */\n static keyPath = 'userId';\n\n constructor(\n /**\n * The normalized user ID to which this queue belongs.\n */\n public userId: string,\n /**\n * An identifier for the highest numbered batch that has been acknowledged\n * by the server. All MutationBatches in this queue with batchIds less\n * than or equal to this value are considered to have been acknowledged by\n * the server.\n *\n * NOTE: this is deprecated and no longer used by the code.\n */\n public lastAcknowledgedBatchId: number,\n /**\n * A stream token that was previously sent by the server.\n *\n * See StreamingWriteRequest in datastore.proto for more details about\n * usage.\n *\n * After sending this token, earlier tokens may not be used anymore so\n * only a single stream token is retained.\n */\n public lastStreamToken: string\n ) {}\n}\n\n/** The 'mutations' store is keyed by batch ID. */\nexport type DbMutationBatchKey = BatchId;\n\n/**\n * An object to be stored in the 'mutations' store in IndexedDb.\n *\n * Represents a batch of user-level mutations intended to be sent to the server\n * in a single write. Each user-level batch gets a separate DbMutationBatch\n * with a new batchId.\n */\nexport class DbMutationBatch {\n /** Name of the IndexedDb object store. */\n static store = 'mutations';\n\n /** Keys are automatically assigned via the userId, batchId properties. */\n static keyPath = 'batchId';\n\n /** The index name for lookup of mutations by user. */\n static userMutationsIndex = 'userMutationsIndex';\n\n /** The user mutations index is keyed by [userId, batchId] pairs. */\n static userMutationsKeyPath = ['userId', 'batchId'];\n\n constructor(\n /**\n * The normalized user ID to which this batch belongs.\n */\n public userId: string,\n /**\n * An identifier for this batch, allocated using an auto-generated key.\n */\n public batchId: BatchId,\n /**\n * The local write time of the batch, stored as milliseconds since the\n * epoch.\n */\n public localWriteTimeMs: number,\n /**\n * A list of \"mutations\" that represent a partial base state from when this\n * write batch was initially created. During local application of the write\n * batch, these baseMutations are applied prior to the real writes in order\n * to override certain document fields from the remote document cache. This\n * is necessary in the case of non-idempotent writes (e.g. `increment()`\n * transforms) to make sure that the local view of the modified documents\n * doesn't flicker if the remote document cache receives the result of the\n * non-idempotent write before the write is removed from the queue.\n *\n * These mutations are never sent to the backend.\n */\n public baseMutations: api.Write[] | undefined,\n /**\n * A list of mutations to apply. All mutations will be applied atomically.\n *\n * Mutations are serialized via JsonProtoSerializer.toMutation().\n */\n public mutations: api.Write[]\n ) {}\n}\n\n/**\n * The key for a db document mutation, which is made up of a userID, path, and\n * batchId. Note that the path must be serialized into a form that indexedDB can\n * sort.\n */\nexport type DbDocumentMutationKey = [string, EncodedResourcePath, BatchId];\n\nfunction createMutationQueue(db: IDBDatabase): void {\n db.createObjectStore(DbMutationQueue.store, {\n keyPath: DbMutationQueue.keyPath\n });\n\n const mutationBatchesStore = db.createObjectStore(DbMutationBatch.store, {\n keyPath: DbMutationBatch.keyPath,\n autoIncrement: true\n });\n mutationBatchesStore.createIndex(\n DbMutationBatch.userMutationsIndex,\n DbMutationBatch.userMutationsKeyPath,\n { unique: true }\n );\n\n db.createObjectStore(DbDocumentMutation.store);\n}\n\n/**\n * Upgrade function to migrate the 'mutations' store from V1 to V3. Loads\n * and rewrites all data.\n */\nfunction upgradeMutationBatchSchemaAndMigrateData(\n db: IDBDatabase,\n txn: SimpleDbTransaction\n): PersistencePromise<void> {\n const v1MutationsStore = txn.store<[string, number], DbMutationBatch>(\n DbMutationBatch.store\n );\n return v1MutationsStore.loadAll().next(existingMutations => {\n db.deleteObjectStore(DbMutationBatch.store);\n\n const mutationsStore = db.createObjectStore(DbMutationBatch.store, {\n keyPath: DbMutationBatch.keyPath,\n autoIncrement: true\n });\n mutationsStore.createIndex(\n DbMutationBatch.userMutationsIndex,\n DbMutationBatch.userMutationsKeyPath,\n { unique: true }\n );\n\n const v3MutationsStore = txn.store<DbMutationBatchKey, DbMutationBatch>(\n DbMutationBatch.store\n );\n const writeAll = existingMutations.map(mutation =>\n v3MutationsStore.put(mutation)\n );\n\n return PersistencePromise.waitFor(writeAll);\n });\n}\n\n/**\n * An object to be stored in the 'documentMutations' store in IndexedDb.\n *\n * A manually maintained index of all the mutation batches that affect a given\n * document key. The rows in this table are references based on the contents of\n * DbMutationBatch.mutations.\n */\nexport class DbDocumentMutation {\n static store = 'documentMutations';\n\n /**\n * Creates a [userId] key for use in the DbDocumentMutations index to iterate\n * over all of a user's document mutations.\n */\n static prefixForUser(userId: string): [string] {\n return [userId];\n }\n\n /**\n * Creates a [userId, encodedPath] key for use in the DbDocumentMutations\n * index to iterate over all at document mutations for a given path or lower.\n */\n static prefixForPath(\n userId: string,\n path: ResourcePath\n ): [string, EncodedResourcePath] {\n return [userId, encodeResourcePath(path)];\n }\n\n /**\n * Creates a full index key of [userId, encodedPath, batchId] for inserting\n * and deleting into the DbDocumentMutations index.\n */\n static key(\n userId: string,\n path: ResourcePath,\n batchId: BatchId\n ): DbDocumentMutationKey {\n return [userId, encodeResourcePath(path), batchId];\n }\n\n /**\n * Because we store all the useful information for this store in the key,\n * there is no useful information to store as the value. The raw (unencoded)\n * path cannot be stored because IndexedDb doesn't store prototype\n * information.\n */\n static PLACEHOLDER = new DbDocumentMutation();\n\n private constructor() {}\n}\n\n/**\n * A key in the 'remoteDocuments' object store is a string array containing the\n * segments that make up the path.\n */\nexport type DbRemoteDocumentKey = string[];\n\nfunction createRemoteDocumentCache(db: IDBDatabase): void {\n db.createObjectStore(DbRemoteDocument.store);\n}\n\n/**\n * Represents the known absence of a document at a particular version.\n * Stored in IndexedDb as part of a DbRemoteDocument object.\n */\nexport class DbNoDocument {\n constructor(public path: string[], public readTime: DbTimestamp) {}\n}\n\n/**\n * Represents a document that is known to exist but whose data is unknown.\n * Stored in IndexedDb as part of a DbRemoteDocument object.\n */\nexport class DbUnknownDocument {\n constructor(public path: string[], public version: DbTimestamp) {}\n}\n\n/**\n * An object to be stored in the 'remoteDocuments' store in IndexedDb.\n * It represents either:\n *\n * - A complete document.\n * - A \"no document\" representing a document that is known not to exist (at\n * some version).\n * - An \"unknown document\" representing a document that is known to exist (at\n * some version) but whose contents are unknown.\n *\n * Note: This is the persisted equivalent of a MaybeDocument and could perhaps\n * be made more general if necessary.\n */\nexport class DbRemoteDocument {\n static store = 'remoteDocuments';\n\n /**\n * An index that provides access to all entries sorted by read time (which\n * corresponds to the last modification time of each row).\n *\n * This index is used to provide a changelog for Multi-Tab.\n */\n static readTimeIndex = 'readTimeIndex';\n\n static readTimeIndexPath = 'readTime';\n\n /**\n * An index that provides access to documents in a collection sorted by read\n * time.\n *\n * This index is used to allow the RemoteDocumentCache to fetch newly changed\n * documents in a collection.\n */\n static collectionReadTimeIndex = 'collectionReadTimeIndex';\n\n static collectionReadTimeIndexPath = ['parentPath', 'readTime'];\n\n // TODO: We are currently storing full document keys almost three times\n // (once as part of the primary key, once - partly - as `parentPath` and once\n // inside the encoded documents). During our next migration, we should\n // rewrite the primary key as parentPath + document ID which would allow us\n // to drop one value.\n\n constructor(\n /**\n * Set to an instance of DbUnknownDocument if the data for a document is\n * not known, but it is known that a document exists at the specified\n * version (e.g. it had a successful update applied to it)\n */\n public unknownDocument: DbUnknownDocument | null | undefined,\n /**\n * Set to an instance of a DbNoDocument if it is known that no document\n * exists.\n */\n public noDocument: DbNoDocument | null,\n /**\n * Set to an instance of a Document if there's a cached version of the\n * document.\n */\n public document: api.Document | null,\n /**\n * Documents that were written to the remote document store based on\n * a write acknowledgment are marked with `hasCommittedMutations`. These\n * documents are potentially inconsistent with the backend's copy and use\n * the write's commit version as their document version.\n */\n public hasCommittedMutations: boolean | undefined,\n\n /**\n * When the document was read from the backend. Undefined for data written\n * prior to schema version 9.\n */\n public readTime: DbTimestampKey | undefined,\n\n /**\n * The path of the collection this document is part of. Undefined for data\n * written prior to schema version 9.\n */\n public parentPath: string[] | undefined\n ) {}\n}\n\n/**\n * Contains a single entry that has metadata about the remote document cache.\n */\nexport class DbRemoteDocumentGlobal {\n static store = 'remoteDocumentGlobal';\n\n static key = 'remoteDocumentGlobalKey';\n\n /**\n * @param byteSize Approximately the total size in bytes of all the documents in the document\n * cache.\n */\n constructor(public byteSize: number) {}\n}\n\nexport type DbRemoteDocumentGlobalKey = typeof DbRemoteDocumentGlobal.key;\n\nfunction createDocumentGlobalStore(db: IDBDatabase): void {\n db.createObjectStore(DbRemoteDocumentGlobal.store);\n}\n\n/**\n * A key in the 'targets' object store is a targetId of the query.\n */\nexport type DbTargetKey = TargetId;\n\n/**\n * The persisted type for a query nested with in the 'targets' store in\n * IndexedDb. We use the proto definitions for these two kinds of queries in\n * order to avoid writing extra serialization logic.\n */\nexport type DbQuery = api.QueryTarget | api.DocumentsTarget;\n\n/**\n * An object to be stored in the 'targets' store in IndexedDb.\n *\n * This is based on and should be kept in sync with the proto used in the iOS\n * client.\n *\n * Each query the client listens to against the server is tracked on disk so\n * that the query can be efficiently resumed on restart.\n */\nexport class DbTarget {\n static store = 'targets';\n\n /** Keys are automatically assigned via the targetId property. */\n static keyPath = 'targetId';\n\n /** The name of the queryTargets index. */\n static queryTargetsIndexName = 'queryTargetsIndex';\n\n /**\n * The index of all canonicalIds to the targets that they match. This is not\n * a unique mapping because canonicalId does not promise a unique name for all\n * possible queries, so we append the targetId to make the mapping unique.\n */\n static queryTargetsKeyPath = ['canonicalId', 'targetId'];\n\n constructor(\n /**\n * An auto-generated sequential numeric identifier for the query.\n *\n * Queries are stored using their canonicalId as the key, but these\n * canonicalIds can be quite long so we additionally assign a unique\n * queryId which can be used by referenced data structures (e.g.\n * indexes) to minimize the on-disk cost.\n */\n public targetId: TargetId,\n /**\n * The canonical string representing this query. This is not unique.\n */\n public canonicalId: string,\n /**\n * The last readTime received from the Watch Service for this query.\n *\n * This is the same value as TargetChange.read_time in the protos.\n */\n public readTime: DbTimestamp,\n /**\n * An opaque, server-assigned token that allows watching a query to be\n * resumed after disconnecting without retransmitting all the data\n * that matches the query. The resume token essentially identifies a\n * point in time from which the server should resume sending results.\n *\n * This is related to the snapshotVersion in that the resumeToken\n * effectively also encodes that value, but the resumeToken is opaque\n * and sometimes encodes additional information.\n *\n * A consequence of this is that the resumeToken should be used when\n * asking the server to reason about where this client is in the watch\n * stream, but the client should use the snapshotVersion for its own\n * purposes.\n *\n * This is the same value as TargetChange.resume_token in the protos.\n */\n public resumeToken: string,\n /**\n * A sequence number representing the last time this query was\n * listened to, used for garbage collection purposes.\n *\n * Conventionally this would be a timestamp value, but device-local\n * clocks are unreliable and they must be able to create new listens\n * even while disconnected. Instead this should be a monotonically\n * increasing number that's incremented on each listen call.\n *\n * This is different from the queryId since the queryId is an\n * immutable identifier assigned to the Query on first use while\n * lastListenSequenceNumber is updated every time the query is\n * listened to.\n */\n public lastListenSequenceNumber: number,\n /**\n * Denotes the maximum snapshot version at which the associated query view\n * contained no limbo documents. Undefined for data written prior to\n * schema version 9.\n */\n public lastLimboFreeSnapshotVersion: DbTimestamp | undefined,\n /**\n * The query for this target.\n *\n * Because canonical ids are not unique we must store the actual query. We\n * use the proto to have an object we can persist without having to\n * duplicate translation logic to and from a `Query` object.\n */\n public query: DbQuery\n ) {}\n}\n\n/**\n * The key for a DbTargetDocument, containing a targetId and an encoded resource\n * path.\n */\nexport type DbTargetDocumentKey = [TargetId, EncodedResourcePath];\n\n/**\n * An object representing an association between a target and a document, or a\n * sentinel row marking the last sequence number at which a document was used.\n * Each document cached must have a corresponding sentinel row before lru\n * garbage collection is enabled.\n *\n * The target associations and sentinel rows are co-located so that orphaned\n * documents and their sequence numbers can be identified efficiently via a scan\n * of this store.\n */\nexport class DbTargetDocument {\n /** Name of the IndexedDb object store. */\n static store = 'targetDocuments';\n\n /** Keys are automatically assigned via the targetId, path properties. */\n static keyPath = ['targetId', 'path'];\n\n /** The index name for the reverse index. */\n static documentTargetsIndex = 'documentTargetsIndex';\n\n /** We also need to create the reverse index for these properties. */\n static documentTargetsKeyPath = ['path', 'targetId'];\n\n constructor(\n /**\n * The targetId identifying a target or 0 for a sentinel row.\n */\n public targetId: TargetId,\n /**\n * The path to the document, as encoded in the key.\n */\n public path: EncodedResourcePath,\n /**\n * If this is a sentinel row, this should be the sequence number of the last\n * time the document specified by `path` was used. Otherwise, it should be\n * `undefined`.\n */\n public sequenceNumber?: ListenSequenceNumber\n ) {\n debugAssert(\n (targetId === 0) === (sequenceNumber !== undefined),\n 'A target-document row must either have targetId == 0 and a defined sequence number, or a non-zero targetId and no sequence number'\n );\n }\n}\n\n/**\n * The type to represent the single allowed key for the DbTargetGlobal store.\n */\nexport type DbTargetGlobalKey = typeof DbTargetGlobal.key;\n\n/**\n * A record of global state tracked across all Targets, tracked separately\n * to avoid the need for extra indexes.\n *\n * This should be kept in-sync with the proto used in the iOS client.\n */\nexport class DbTargetGlobal {\n /**\n * The key string used for the single object that exists in the\n * DbTargetGlobal store.\n */\n static key = 'targetGlobalKey';\n static store = 'targetGlobal';\n\n constructor(\n /**\n * The highest numbered target id across all targets.\n *\n * See DbTarget.targetId.\n */\n public highestTargetId: TargetId,\n /**\n * The highest numbered lastListenSequenceNumber across all targets.\n *\n * See DbTarget.lastListenSequenceNumber.\n */\n public highestListenSequenceNumber: number,\n /**\n * A global snapshot version representing the last consistent snapshot we\n * received from the backend. This is monotonically increasing and any\n * snapshots received from the backend prior to this version (e.g. for\n * targets resumed with a resumeToken) should be suppressed (buffered)\n * until the backend has caught up to this snapshot version again. This\n * prevents our cache from ever going backwards in time.\n */\n public lastRemoteSnapshotVersion: DbTimestamp,\n /**\n * The number of targets persisted.\n */\n public targetCount: number\n ) {}\n}\n\n/**\n * The key for a DbCollectionParent entry, containing the collection ID\n * and the parent path that contains it. Note that the parent path will be an\n * empty path in the case of root-level collections.\n */\nexport type DbCollectionParentKey = [string, EncodedResourcePath];\n\n/**\n * An object representing an association between a Collection id (e.g. 'messages')\n * to a parent path (e.g. '/chats/123') that contains it as a (sub)collection.\n * This is used to efficiently find all collections to query when performing\n * a Collection Group query.\n */\nexport class DbCollectionParent {\n /** Name of the IndexedDb object store. */\n static store = 'collectionParents';\n\n /** Keys are automatically assigned via the collectionId, parent properties. */\n static keyPath = ['collectionId', 'parent'];\n\n constructor(\n /**\n * The collectionId (e.g. 'messages')\n */\n public collectionId: string,\n /**\n * The path to the parent (either a document location or an empty path for\n * a root-level collection).\n */\n public parent: EncodedResourcePath\n ) {}\n}\n\nfunction createQueryCache(db: IDBDatabase): void {\n const targetDocumentsStore = db.createObjectStore(DbTargetDocument.store, {\n keyPath: DbTargetDocument.keyPath\n });\n targetDocumentsStore.createIndex(\n DbTargetDocument.documentTargetsIndex,\n DbTargetDocument.documentTargetsKeyPath,\n { unique: true }\n );\n\n const targetStore = db.createObjectStore(DbTarget.store, {\n keyPath: DbTarget.keyPath\n });\n\n // NOTE: This is unique only because the TargetId is the suffix.\n targetStore.createIndex(\n DbTarget.queryTargetsIndexName,\n DbTarget.queryTargetsKeyPath,\n { unique: true }\n );\n db.createObjectStore(DbTargetGlobal.store);\n}\n\nfunction dropQueryCache(db: IDBDatabase): void {\n db.deleteObjectStore(DbTargetDocument.store);\n db.deleteObjectStore(DbTarget.store);\n db.deleteObjectStore(DbTargetGlobal.store);\n}\n\nfunction dropRemoteDocumentChangesStore(db: IDBDatabase): void {\n if (db.objectStoreNames.contains('remoteDocumentChanges')) {\n db.deleteObjectStore('remoteDocumentChanges');\n }\n}\n\n/**\n * Creates the target global singleton row.\n *\n * @param {IDBTransaction} txn The version upgrade transaction for indexeddb\n */\nfunction writeEmptyTargetGlobalEntry(\n txn: SimpleDbTransaction\n): PersistencePromise<void> {\n const globalStore = txn.store<DbTargetGlobalKey, DbTargetGlobal>(\n DbTargetGlobal.store\n );\n const metadata = new DbTargetGlobal(\n /*highestTargetId=*/ 0,\n /*lastListenSequenceNumber=*/ 0,\n SnapshotVersion.min().toTimestamp(),\n /*targetCount=*/ 0\n );\n return globalStore.put(DbTargetGlobal.key, metadata);\n}\n\n/**\n * Creates indices on the RemoteDocuments store used for both multi-tab\n * and Index-Free queries.\n */\nfunction createRemoteDocumentReadTimeIndex(txn: IDBTransaction): void {\n const remoteDocumentStore = txn.objectStore(DbRemoteDocument.store);\n remoteDocumentStore.createIndex(\n DbRemoteDocument.readTimeIndex,\n DbRemoteDocument.readTimeIndexPath,\n { unique: false }\n );\n remoteDocumentStore.createIndex(\n DbRemoteDocument.collectionReadTimeIndex,\n DbRemoteDocument.collectionReadTimeIndexPath,\n { unique: false }\n );\n}\n\n/**\n * A record of the metadata state of each client.\n *\n * PORTING NOTE: This is used to synchronize multi-tab state and does not need\n * to be ported to iOS or Android.\n */\nexport class DbClientMetadata {\n /** Name of the IndexedDb object store. */\n static store = 'clientMetadata';\n\n /** Keys are automatically assigned via the clientId properties. */\n static keyPath = 'clientId';\n\n constructor(\n // Note: Previous schema versions included a field\n // \"lastProcessedDocumentChangeId\". Don't use anymore.\n\n /** The auto-generated client id assigned at client startup. */\n public clientId: string,\n /** The last time this state was updated. */\n public updateTimeMs: number,\n /** Whether the client's network connection is enabled. */\n public networkEnabled: boolean,\n /** Whether this client is running in a foreground tab. */\n public inForeground: boolean\n ) {}\n}\n\n/** Object keys in the 'clientMetadata' store are clientId strings. */\nexport type DbClientMetadataKey = string;\n\nfunction createClientMetadataStore(db: IDBDatabase): void {\n db.createObjectStore(DbClientMetadata.store, {\n keyPath: DbClientMetadata.keyPath\n });\n}\n\n// Visible for testing\nexport const V1_STORES = [\n DbMutationQueue.store,\n DbMutationBatch.store,\n DbDocumentMutation.store,\n DbRemoteDocument.store,\n DbTarget.store,\n DbPrimaryClient.store,\n DbTargetGlobal.store,\n DbTargetDocument.store\n];\n\n// V2 is no longer usable (see comment at top of file)\n\n// Visible for testing\nexport const V3_STORES = V1_STORES;\n\n// Visible for testing\n// Note: DbRemoteDocumentChanges is no longer used and dropped with v9.\nexport const V4_STORES = [...V3_STORES, DbClientMetadata.store];\n\n// V5 does not change the set of stores.\n\nexport const V6_STORES = [...V4_STORES, DbRemoteDocumentGlobal.store];\n\n// V7 does not change the set of stores.\n\nexport const V8_STORES = [...V6_STORES, DbCollectionParent.store];\n\n// V9 does not change the set of stores.\n\n// V10 does not change the set of stores.\n\n/**\n * The list of all default IndexedDB stores used throughout the SDK. This is\n * used when creating transactions so that access across all stores is done\n * atomically.\n */\nexport const ALL_STORES = V8_STORES;\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 { getUA } from '@firebase/util';\nimport { debugAssert } from '../util/assert';\nimport { Code, FirestoreError } from '../util/error';\nimport { logDebug, logError } from '../util/log';\nimport { Deferred } from '../util/promise';\nimport { SCHEMA_VERSION } from './indexeddb_schema';\nimport { PersistencePromise } from './persistence_promise';\n\n// References to `window` are guarded by SimpleDb.isAvailable()\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 * 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 /**\n * Opens the specified database, creating or upgrading it if necessary.\n *\n * Note that `version` must not be a downgrade. IndexedDB does not support downgrading the schema\n * version. We currently do not support any way to do versioning outside of IndexedDB's versioning\n * mechanism, as only version-upgrade transactions are allowed to do things like create\n * objectstores.\n */\n static openOrCreate(\n name: string,\n version: number,\n schemaConverter: SimpleDbSchemaConverter\n ): Promise<SimpleDb> {\n debugAssert(\n SimpleDb.isAvailable(),\n 'IndexedDB not supported in current environment.'\n );\n logDebug(LOG_TAG, 'Opening database:', name);\n return new PersistencePromise<SimpleDb>((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 = window.indexedDB.open(name, version);\n\n request.onsuccess = (event: Event) => {\n const db = (event.target as IDBOpenDBRequest).result;\n resolve(new SimpleDb(db));\n };\n\n request.onblocked = () => {\n reject(\n new FirestoreError(\n Code.FAILED_PRECONDITION,\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 {\n reject(error);\n }\n };\n\n request.onupgradeneeded = (event: IDBVersionChangeEvent) => {\n logDebug(\n LOG_TAG,\n 'Database \"' + name + '\" requires upgrade from version:',\n event.oldVersion\n );\n const db = (event.target as IDBOpenDBRequest).result;\n schemaConverter\n .createOrUpgrade(\n db,\n request.transaction!,\n event.oldVersion,\n SCHEMA_VERSION\n )\n .next(() => {\n logDebug(\n LOG_TAG,\n 'Database upgrade to version ' + SCHEMA_VERSION + ' complete'\n );\n });\n };\n }).toPromise();\n }\n\n /** Deletes the specified database. */\n static delete(name: string): Promise<void> {\n logDebug(LOG_TAG, 'Removing database:', name);\n return wrapRequest<void>(window.indexedDB.deleteDatabase(name)).toPromise();\n }\n\n /** Returns true if IndexedDB is available in the current environment. */\n static isAvailable(): boolean {\n if (typeof window === 'undefined' || window.indexedDB == null) {\n return false;\n }\n\n if (SimpleDb.isMockPersistence()) {\n return true;\n }\n\n // In some Node environments, `window` is defined, but `window.navigator` is\n // not. We don't support IndexedDB persistence in Node if the\n // isMockPersistence() check above returns false.\n if (window.navigator === undefined) {\n return false;\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 userse running version < 4.5.\n const androidVersion = SimpleDb.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]\n .split('_')\n .slice(0, 2)\n .join('.')\n : '-1';\n return Number(version);\n }\n\n // visible for testing\n /** Parse User Agent to determine Android version. Returns -1 if not found. */\n static getAndroidVersion(ua: string): number {\n const androidVersionRegex = ua.match(/Android ([\\d.]+)/i);\n const version = androidVersionRegex\n ? androidVersionRegex[1]\n .split('.')\n .slice(0, 2)\n .join('.')\n : '-1';\n return Number(version);\n }\n\n constructor(private db: IDBDatabase) {\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 setVersionChangeListener(\n versionChangeListener: (event: IDBVersionChangeEvent) => void\n ): void {\n this.db.onversionchange = (event: IDBVersionChangeEvent) => {\n return versionChangeListener(event);\n };\n }\n\n async runTransaction<T>(\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 const transaction = SimpleDbTransaction.open(\n this.db,\n readonly ? 'readonly' : 'readwrite',\n objectStores\n );\n try {\n const transactionFnResult = transactionFn(transaction)\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 (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: %s. Retrying: %s.',\n error.message,\n retryable\n );\n\n if (!retryable) {\n return Promise.reject(error);\n }\n }\n }\n }\n\n close(): void {\n this.db.close();\n }\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 /** IndxedDB 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(cause: Error) {\n super(Code.UNAVAILABLE, 'IndexedDB transaction failed: ' + cause);\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 * 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 mode: IDBTransactionMode,\n objectStoreNames: string[]\n ): SimpleDbTransaction {\n return new SimpleDbTransaction(db.transaction(objectStoreNames, mode));\n }\n\n constructor(private readonly transaction: IDBTransaction) {\n this.transaction.oncomplete = () => {\n this.completionDeferred.resolve();\n };\n this.transaction.onabort = () => {\n if (transaction.error) {\n this.completionDeferred.reject(\n new IndexedDbTransactionError(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(new IndexedDbTransactionError(error));\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 /**\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 * 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 * @return 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 * @return 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 loadAll(): PersistencePromise<ValueType[]>;\n loadAll(range: IDBKeyRange): PersistencePromise<ValueType[]>;\n loadAll(index: string, range: IDBKeyRange): PersistencePromise<ValueType[]>;\n loadAll(\n indexOrRange?: string | IDBKeyRange,\n range?: IDBKeyRange\n ): PersistencePromise<ValueType[]> {\n const cursor = this.cursor(this.options(indexOrRange, range));\n const results: ValueType[] = [];\n return this.iterateCursor(cursor, (key, value) => {\n results.push(value);\n }).next(() => {\n return results;\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 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(() => {\n return PersistencePromise.waitFor(results);\n });\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 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 { Timestamp } from '../api/timestamp';\nimport { User } from '../auth/user';\nimport { Query } from '../core/query';\nimport { SnapshotVersion } from '../core/snapshot_version';\nimport { Target } from '../core/target';\nimport { BatchId, TargetId } from '../core/types';\nimport {\n DocumentKeySet,\n documentKeySet,\n DocumentMap,\n maybeDocumentMap,\n MaybeDocumentMap\n} from '../model/collections';\nimport { MaybeDocument, NoDocument } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport { Mutation, PatchMutation, Precondition } from '../model/mutation';\nimport {\n BATCHID_UNKNOWN,\n MutationBatch,\n MutationBatchResult\n} from '../model/mutation_batch';\nimport { RemoteEvent, TargetChange } from '../remote/remote_event';\nimport { hardAssert, debugAssert } from '../util/assert';\nimport { Code, FirestoreError } from '../util/error';\nimport { logDebug } from '../util/log';\nimport { primitiveComparator } from '../util/misc';\nimport { ObjectMap } from '../util/obj_map';\nimport { SortedMap } from '../util/sorted_map';\n\nimport { LocalDocumentsView } from './local_documents_view';\nimport { LocalViewChanges } from './local_view_changes';\nimport { LruGarbageCollector, LruResults } from './lru_garbage_collector';\nimport { MutationQueue } from './mutation_queue';\nimport {\n Persistence,\n PersistenceTransaction,\n PRIMARY_LEASE_LOST_ERROR_MSG\n} from './persistence';\nimport { PersistencePromise } from './persistence_promise';\nimport { TargetCache } from './target_cache';\nimport { QueryEngine } from './query_engine';\nimport { RemoteDocumentCache } from './remote_document_cache';\nimport { RemoteDocumentChangeBuffer } from './remote_document_change_buffer';\nimport { ClientId } from './shared_client_state';\nimport { TargetData, TargetPurpose } from './target_data';\nimport { ByteString } from '../util/byte_string';\nimport { IndexedDbPersistence } from './indexeddb_persistence';\nimport { IndexedDbMutationQueue } from './indexeddb_mutation_queue';\nimport { IndexedDbRemoteDocumentCache } from './indexeddb_remote_document_cache';\nimport { IndexedDbTargetCache } from './indexeddb_target_cache';\nimport { extractFieldMask } from '../model/object_value';\nimport { isIndexedDbTransactionError } from './simple_db';\n\nconst LOG_TAG = 'LocalStore';\n\n/** The result of a write to the local store. */\nexport interface LocalWriteResult {\n batchId: BatchId;\n changes: MaybeDocumentMap;\n}\n\n/** The result of a user-change operation in the local store. */\nexport interface UserChangeResult {\n readonly affectedDocuments: MaybeDocumentMap;\n readonly removedBatchIds: BatchId[];\n readonly addedBatchIds: BatchId[];\n}\n\n/** The result of executing a query against the local store. */\nexport interface QueryResult {\n readonly documents: DocumentMap;\n readonly remoteKeys: DocumentKeySet;\n}\n\n/**\n * Local storage in the Firestore client. Coordinates persistence components\n * like the mutation queue and remote document cache to present a\n * latency-compensated view of stored data.\n *\n * The LocalStore is responsible for accepting mutations from the Sync Engine.\n * Writes from the client are put into a queue as provisional Mutations until\n * they are processed by the RemoteStore and confirmed as having been written\n * to the server.\n *\n * The local store provides the local version of documents that have been\n * modified locally. It maintains the constraint:\n *\n * LocalDocument = RemoteDocument + Active(LocalMutations)\n *\n * (Active mutations are those that are enqueued and have not been previously\n * acknowledged or rejected).\n *\n * The RemoteDocument (\"ground truth\") state is provided via the\n * applyChangeBatch method. It will be some version of a server-provided\n * document OR will be a server-provided document PLUS acknowledged mutations:\n *\n * RemoteDocument' = RemoteDocument + Acknowledged(LocalMutations)\n *\n * Note that this \"dirty\" version of a RemoteDocument will not be identical to a\n * server base version, since it has LocalMutations added to it pending getting\n * an authoritative copy from the server.\n *\n * Since LocalMutations can be rejected by the server, we have to be able to\n * revert a LocalMutation that has already been applied to the LocalDocument\n * (typically done by replaying all remaining LocalMutations to the\n * RemoteDocument to re-apply).\n *\n * The LocalStore is responsible for the garbage collection of the documents it\n * contains. For now, it every doc referenced by a view, the mutation queue, or\n * the RemoteStore.\n *\n * It also maintains the persistence of mapping queries to resume tokens and\n * target ids. It needs to know this data about queries to properly know what\n * docs it would be allowed to garbage collect.\n *\n * The LocalStore must be able to efficiently execute queries against its local\n * cache of the documents, to provide the initial set of results before any\n * remote changes have been received.\n *\n * Note: In TypeScript, most methods return Promises since the implementation\n * may rely on fetching data from IndexedDB which is async.\n * These Promises will only be rejected on an I/O error or other internal\n * (unexpected) failure (e.g. failed assert) and always represent an\n * unrecoverable error (should be caught / reported by the async_queue).\n */\nexport class LocalStore {\n /**\n * The maximum time to leave a resume token buffered without writing it out.\n * This value is arbitrary: it's long enough to avoid several writes\n * (possibly indefinitely if updates come more frequently than this) but\n * short enough that restarting after crashing will still have a pretty\n * recent resume token.\n */\n private static readonly RESUME_TOKEN_MAX_AGE_MICROS = 5 * 60 * 1e6;\n\n /**\n * The set of all mutations that have been sent but not yet been applied to\n * the backend.\n */\n protected mutationQueue: MutationQueue;\n\n /** The set of all cached remote documents. */\n protected remoteDocuments: RemoteDocumentCache;\n\n /**\n * The \"local\" view of all documents (layering mutationQueue on top of\n * remoteDocumentCache).\n */\n protected localDocuments: LocalDocumentsView;\n\n /** Maps a target to its `TargetData`. */\n protected targetCache: TargetCache;\n\n /**\n * Maps a targetID to data about its target.\n *\n * PORTING NOTE: We are using an immutable data structure on Web to make re-runs\n * of `applyRemoteEvent()` idempotent.\n */\n protected targetDataByTarget = new SortedMap<TargetId, TargetData>(\n primitiveComparator\n );\n\n /** Maps a target to its targetID. */\n // TODO(wuandy): Evaluate if TargetId can be part of Target.\n private targetIdByTarget = new ObjectMap<Target, TargetId>(t =>\n t.canonicalId()\n );\n\n /**\n * The read time of the last entry processed by `getNewDocumentChanges()`.\n *\n * PORTING NOTE: This is only used for multi-tab synchronization.\n */\n protected lastDocumentChangeReadTime = SnapshotVersion.min();\n\n constructor(\n /** Manages our in-memory or durable persistence. */\n protected persistence: Persistence,\n private queryEngine: QueryEngine,\n initialUser: User\n ) {\n debugAssert(\n persistence.started,\n 'LocalStore was passed an unstarted persistence implementation'\n );\n this.mutationQueue = persistence.getMutationQueue(initialUser);\n this.remoteDocuments = persistence.getRemoteDocumentCache();\n this.targetCache = persistence.getTargetCache();\n this.localDocuments = new LocalDocumentsView(\n this.remoteDocuments,\n this.mutationQueue,\n this.persistence.getIndexManager()\n );\n this.queryEngine.setLocalDocumentsView(this.localDocuments);\n }\n\n /** Starts the LocalStore. */\n start(): Promise<void> {\n return Promise.resolve();\n }\n\n /**\n * Tells the LocalStore that the currently authenticated user has changed.\n *\n * In response the local store switches the mutation queue to the new user and\n * returns any resulting document changes.\n */\n // PORTING NOTE: Android and iOS only return the documents affected by the\n // change.\n async handleUserChange(user: User): Promise<UserChangeResult> {\n let newMutationQueue = this.mutationQueue;\n let newLocalDocuments = this.localDocuments;\n\n const result = await this.persistence.runTransaction(\n 'Handle user change',\n 'readonly',\n txn => {\n // Swap out the mutation queue, grabbing the pending mutation batches\n // before and after.\n let oldBatches: MutationBatch[];\n return this.mutationQueue\n .getAllMutationBatches(txn)\n .next(promisedOldBatches => {\n oldBatches = promisedOldBatches;\n\n newMutationQueue = this.persistence.getMutationQueue(user);\n\n // Recreate our LocalDocumentsView using the new\n // MutationQueue.\n newLocalDocuments = new LocalDocumentsView(\n this.remoteDocuments,\n newMutationQueue,\n this.persistence.getIndexManager()\n );\n return newMutationQueue.getAllMutationBatches(txn);\n })\n .next(newBatches => {\n const removedBatchIds: BatchId[] = [];\n const addedBatchIds: BatchId[] = [];\n\n // Union the old/new changed keys.\n let changedKeys = documentKeySet();\n\n for (const batch of oldBatches) {\n removedBatchIds.push(batch.batchId);\n for (const mutation of batch.mutations) {\n changedKeys = changedKeys.add(mutation.key);\n }\n }\n\n for (const batch of newBatches) {\n addedBatchIds.push(batch.batchId);\n for (const mutation of batch.mutations) {\n changedKeys = changedKeys.add(mutation.key);\n }\n }\n\n // Return the set of all (potentially) changed documents and the list\n // of mutation batch IDs that were affected by change.\n return newLocalDocuments\n .getDocuments(txn, changedKeys)\n .next(affectedDocuments => {\n return {\n affectedDocuments,\n removedBatchIds,\n addedBatchIds\n };\n });\n });\n }\n );\n\n this.mutationQueue = newMutationQueue;\n this.localDocuments = newLocalDocuments;\n this.queryEngine.setLocalDocumentsView(this.localDocuments);\n\n return result;\n }\n\n /* Accept locally generated Mutations and commit them to storage. */\n localWrite(mutations: Mutation[]): Promise<LocalWriteResult> {\n const localWriteTime = Timestamp.now();\n const keys = mutations.reduce(\n (keys, m) => keys.add(m.key),\n documentKeySet()\n );\n\n let existingDocs: MaybeDocumentMap;\n\n return this.persistence\n .runTransaction('Locally write mutations', 'readwrite', txn => {\n // Load and apply all existing mutations. This lets us compute the\n // current base state for all non-idempotent transforms before applying\n // any additional user-provided writes.\n return this.localDocuments.getDocuments(txn, keys).next(docs => {\n existingDocs = docs;\n\n // For non-idempotent mutations (such as `FieldValue.increment()`),\n // we record the base state in a separate patch mutation. This is\n // later used to guarantee consistent values and prevents flicker\n // even if the backend sends us an update that already includes our\n // transform.\n const baseMutations: Mutation[] = [];\n\n for (const mutation of mutations) {\n const baseValue = mutation.extractBaseValue(\n existingDocs.get(mutation.key)\n );\n if (baseValue != null) {\n // NOTE: The base state should only be applied if there's some\n // existing document to override, so use a Precondition of\n // exists=true\n baseMutations.push(\n new PatchMutation(\n mutation.key,\n baseValue,\n extractFieldMask(baseValue.proto.mapValue!),\n Precondition.exists(true)\n )\n );\n }\n }\n\n return this.mutationQueue.addMutationBatch(\n txn,\n localWriteTime,\n baseMutations,\n mutations\n );\n });\n })\n .then(batch => {\n const changes = batch.applyToLocalDocumentSet(existingDocs);\n return { batchId: batch.batchId, changes };\n });\n }\n\n /**\n * Acknowledge the given batch.\n *\n * On the happy path when a batch is acknowledged, the local store will\n *\n * + remove the batch from the mutation queue;\n * + apply the changes to the remote document cache;\n * + recalculate the latency compensated view implied by those changes (there\n * may be mutations in the queue that affect the documents but haven't been\n * acknowledged yet); and\n * + give the changed documents back the sync engine\n *\n * @returns The resulting (modified) documents.\n */\n acknowledgeBatch(\n batchResult: MutationBatchResult\n ): Promise<MaybeDocumentMap> {\n return this.persistence.runTransaction(\n 'Acknowledge batch',\n 'readwrite-primary',\n txn => {\n const affected = batchResult.batch.keys();\n const documentBuffer = this.remoteDocuments.newChangeBuffer({\n trackRemovals: true // Make sure document removals show up in `getNewDocumentChanges()`\n });\n return this.mutationQueue\n .acknowledgeBatch(txn, batchResult.batch, batchResult.streamToken)\n .next(() =>\n this.applyWriteToRemoteDocuments(txn, batchResult, documentBuffer)\n )\n .next(() => documentBuffer.apply(txn))\n .next(() => this.mutationQueue.performConsistencyCheck(txn))\n .next(() => this.localDocuments.getDocuments(txn, affected));\n }\n );\n }\n\n /**\n * Remove mutations from the MutationQueue for the specified batch;\n * LocalDocuments will be recalculated.\n *\n * @returns The resulting modified documents.\n */\n rejectBatch(batchId: BatchId): Promise<MaybeDocumentMap> {\n return this.persistence.runTransaction(\n 'Reject batch',\n 'readwrite-primary',\n txn => {\n let affectedKeys: DocumentKeySet;\n return this.mutationQueue\n .lookupMutationBatch(txn, batchId)\n .next((batch: MutationBatch | null) => {\n hardAssert(batch !== null, 'Attempt to reject nonexistent batch!');\n affectedKeys = batch.keys();\n return this.mutationQueue.removeMutationBatch(txn, batch);\n })\n .next(() => {\n return this.mutationQueue.performConsistencyCheck(txn);\n })\n .next(() => {\n return this.localDocuments.getDocuments(txn, affectedKeys);\n });\n }\n );\n }\n\n /**\n * Returns the largest (latest) batch id in mutation queue that is pending server response.\n * Returns `BATCHID_UNKNOWN` if the queue is empty.\n */\n getHighestUnacknowledgedBatchId(): Promise<BatchId> {\n return this.persistence.runTransaction(\n 'Get highest unacknowledged batch id',\n 'readonly',\n txn => {\n return this.mutationQueue.getHighestUnacknowledgedBatchId(txn);\n }\n );\n }\n\n /** Returns the last recorded stream token for the current user. */\n getLastStreamToken(): Promise<ByteString> {\n return this.persistence.runTransaction(\n 'Get last stream token',\n 'readonly',\n txn => {\n return this.mutationQueue.getLastStreamToken(txn);\n }\n );\n }\n\n /**\n * Sets the stream token for the current user without acknowledging any\n * mutation batch. This is usually only useful after a stream handshake or in\n * response to an error that requires clearing the stream token.\n */\n setLastStreamToken(streamToken: ByteString): Promise<void> {\n return this.persistence.runTransaction(\n 'Set last stream token',\n 'readwrite-primary',\n txn => {\n return this.mutationQueue.setLastStreamToken(txn, streamToken);\n }\n );\n }\n\n /**\n * Returns the last consistent snapshot processed (used by the RemoteStore to\n * determine whether to buffer incoming snapshots from the backend).\n */\n getLastRemoteSnapshotVersion(): Promise<SnapshotVersion> {\n return this.persistence.runTransaction(\n 'Get last remote snapshot version',\n 'readonly',\n txn => this.targetCache.getLastRemoteSnapshotVersion(txn)\n );\n }\n\n /**\n * Update the \"ground-state\" (remote) documents. We assume that the remote\n * event reflects any write batches that have been acknowledged or rejected\n * (i.e. we do not re-apply local mutations to updates from this event).\n *\n * LocalDocuments are re-calculated if there are remaining mutations in the\n * queue.\n */\n applyRemoteEvent(remoteEvent: RemoteEvent): Promise<MaybeDocumentMap> {\n const remoteVersion = remoteEvent.snapshotVersion;\n let newTargetDataByTargetMap = this.targetDataByTarget;\n\n return this.persistence\n .runTransaction('Apply remote event', 'readwrite-primary', txn => {\n const documentBuffer = this.remoteDocuments.newChangeBuffer({\n trackRemovals: true // Make sure document removals show up in `getNewDocumentChanges()`\n });\n\n // Reset newTargetDataByTargetMap in case this transaction gets re-run.\n newTargetDataByTargetMap = this.targetDataByTarget;\n\n const promises = [] as Array<PersistencePromise<void>>;\n remoteEvent.targetChanges.forEach((change, targetId) => {\n const oldTargetData = newTargetDataByTargetMap.get(targetId);\n if (!oldTargetData) {\n return;\n }\n\n // Only update the remote keys if the target is still active. This\n // ensures that we can persist the updated target data along with\n // the updated assignment.\n promises.push(\n this.targetCache\n .removeMatchingKeys(txn, change.removedDocuments, targetId)\n .next(() => {\n return this.targetCache.addMatchingKeys(\n txn,\n change.addedDocuments,\n targetId\n );\n })\n );\n\n const resumeToken = change.resumeToken;\n // Update the resume token if the change includes one.\n if (resumeToken.approximateByteSize() > 0) {\n const newTargetData = oldTargetData\n .withResumeToken(resumeToken, remoteVersion)\n .withSequenceNumber(txn.currentSequenceNumber);\n newTargetDataByTargetMap = newTargetDataByTargetMap.insert(\n targetId,\n newTargetData\n );\n\n // Update the target data if there are target changes (or if\n // sufficient time has passed since the last update).\n if (\n LocalStore.shouldPersistTargetData(\n oldTargetData,\n newTargetData,\n change\n )\n ) {\n promises.push(\n this.targetCache.updateTargetData(txn, newTargetData)\n );\n }\n }\n });\n\n let changedDocs = maybeDocumentMap();\n let updatedKeys = documentKeySet();\n remoteEvent.documentUpdates.forEach((key, doc) => {\n updatedKeys = updatedKeys.add(key);\n });\n\n // Each loop iteration only affects its \"own\" doc, so it's safe to get all the remote\n // documents in advance in a single call.\n promises.push(\n documentBuffer.getEntries(txn, updatedKeys).next(existingDocs => {\n remoteEvent.documentUpdates.forEach((key, doc) => {\n const existingDoc = existingDocs.get(key);\n\n // Note: The order of the steps below is important, since we want\n // to ensure that rejected limbo resolutions (which fabricate\n // NoDocuments with SnapshotVersion.min()) never add documents to\n // cache.\n if (\n doc instanceof NoDocument &&\n doc.version.isEqual(SnapshotVersion.min())\n ) {\n // NoDocuments with SnapshotVersion.min() are used in manufactured\n // events. We remove these documents from cache since we lost\n // access.\n documentBuffer.removeEntry(key, remoteVersion);\n changedDocs = changedDocs.insert(key, doc);\n } else if (\n existingDoc == null ||\n doc.version.compareTo(existingDoc.version) > 0 ||\n (doc.version.compareTo(existingDoc.version) === 0 &&\n existingDoc.hasPendingWrites)\n ) {\n debugAssert(\n !SnapshotVersion.min().isEqual(remoteVersion),\n 'Cannot add a document when the remote version is zero'\n );\n documentBuffer.addEntry(doc, remoteVersion);\n changedDocs = changedDocs.insert(key, doc);\n } else {\n logDebug(\n LOG_TAG,\n 'Ignoring outdated watch update for ',\n key,\n '. Current version:',\n existingDoc.version,\n ' Watch version:',\n doc.version\n );\n }\n\n if (remoteEvent.resolvedLimboDocuments.has(key)) {\n promises.push(\n this.persistence.referenceDelegate.updateLimboDocument(\n txn,\n key\n )\n );\n }\n });\n })\n );\n\n // HACK: The only reason we allow a null snapshot version is so that we\n // can synthesize remote events when we get permission denied errors while\n // trying to resolve the state of a locally cached document that is in\n // limbo.\n if (!remoteVersion.isEqual(SnapshotVersion.min())) {\n const updateRemoteVersion = this.targetCache\n .getLastRemoteSnapshotVersion(txn)\n .next(lastRemoteSnapshotVersion => {\n debugAssert(\n remoteVersion.compareTo(lastRemoteSnapshotVersion) >= 0,\n 'Watch stream reverted to previous snapshot?? ' +\n remoteVersion +\n ' < ' +\n lastRemoteSnapshotVersion\n );\n return this.targetCache.setTargetsMetadata(\n txn,\n txn.currentSequenceNumber,\n remoteVersion\n );\n });\n promises.push(updateRemoteVersion);\n }\n\n return PersistencePromise.waitFor(promises)\n .next(() => documentBuffer.apply(txn))\n .next(() => {\n return this.localDocuments.getLocalViewOfDocuments(\n txn,\n changedDocs\n );\n });\n })\n .then(changedDocs => {\n this.targetDataByTarget = newTargetDataByTargetMap;\n return changedDocs;\n });\n }\n\n /**\n * Returns true if the newTargetData should be persisted during an update of\n * an active target. TargetData should always be persisted when a target is\n * being released and should not call this function.\n *\n * While the target is active, TargetData updates can be omitted when nothing\n * about the target has changed except metadata like the resume token or\n * snapshot version. Occasionally it's worth the extra write to prevent these\n * values from getting too stale after a crash, but this doesn't have to be\n * too frequent.\n */\n private static shouldPersistTargetData(\n oldTargetData: TargetData,\n newTargetData: TargetData,\n change: TargetChange\n ): boolean {\n hardAssert(\n newTargetData.resumeToken.approximateByteSize() > 0,\n 'Attempted to persist target data with no resume token'\n );\n\n // Always persist target data if we don't already have a resume token.\n if (oldTargetData.resumeToken.approximateByteSize() === 0) {\n return true;\n }\n\n // Don't allow resume token changes to be buffered indefinitely. This\n // allows us to be reasonably up-to-date after a crash and avoids needing\n // to loop over all active queries on shutdown. Especially in the browser\n // we may not get time to do anything interesting while the current tab is\n // closing.\n const timeDelta =\n newTargetData.snapshotVersion.toMicroseconds() -\n oldTargetData.snapshotVersion.toMicroseconds();\n if (timeDelta >= this.RESUME_TOKEN_MAX_AGE_MICROS) {\n return true;\n }\n\n // Otherwise if the only thing that has changed about a target is its resume\n // token it's not worth persisting. Note that the RemoteStore keeps an\n // in-memory view of the currently active targets which includes the current\n // resume token, so stream failure or user changes will still use an\n // up-to-date resume token regardless of what we do here.\n const changes =\n change.addedDocuments.size +\n change.modifiedDocuments.size +\n change.removedDocuments.size;\n return changes > 0;\n }\n\n /**\n * Notify local store of the changed views to locally pin documents.\n */\n async notifyLocalViewChanges(viewChanges: LocalViewChanges[]): Promise<void> {\n try {\n await this.persistence.runTransaction(\n 'notifyLocalViewChanges',\n 'readwrite',\n txn => {\n return PersistencePromise.forEach(\n viewChanges,\n (viewChange: LocalViewChanges) => {\n return PersistencePromise.forEach(\n viewChange.addedKeys,\n (key: DocumentKey) =>\n this.persistence.referenceDelegate.addReference(\n txn,\n viewChange.targetId,\n key\n )\n ).next(() =>\n PersistencePromise.forEach(\n viewChange.removedKeys,\n (key: DocumentKey) =>\n this.persistence.referenceDelegate.removeReference(\n txn,\n viewChange.targetId,\n key\n )\n )\n );\n }\n );\n }\n );\n } catch (e) {\n if (isIndexedDbTransactionError(e)) {\n // If `notifyLocalViewChanges` fails, we did not advance the sequence\n // number for the documents that were included in this transaction.\n // This might trigger them to be deleted earlier than they otherwise\n // would have, but it should not invalidate the integrity of the data.\n logDebug(LOG_TAG, 'Failed to update sequence numbers: ' + e);\n } else {\n throw e;\n }\n }\n\n for (const viewChange of viewChanges) {\n const targetId = viewChange.targetId;\n\n if (!viewChange.fromCache) {\n const targetData = this.targetDataByTarget.get(targetId);\n debugAssert(\n targetData !== null,\n `Can't set limbo-free snapshot version for unknown target: ${targetId}`\n );\n\n // Advance the last limbo free snapshot version\n const lastLimboFreeSnapshotVersion = targetData.snapshotVersion;\n const updatedTargetData = targetData.withLastLimboFreeSnapshotVersion(\n lastLimboFreeSnapshotVersion\n );\n this.targetDataByTarget = this.targetDataByTarget.insert(\n targetId,\n updatedTargetData\n );\n }\n }\n }\n\n /**\n * Gets the mutation batch after the passed in batchId in the mutation queue\n * or null if empty.\n * @param afterBatchId If provided, the batch to search after.\n * @returns The next mutation or null if there wasn't one.\n */\n nextMutationBatch(afterBatchId?: BatchId): Promise<MutationBatch | null> {\n return this.persistence.runTransaction(\n 'Get next mutation batch',\n 'readonly',\n txn => {\n if (afterBatchId === undefined) {\n afterBatchId = BATCHID_UNKNOWN;\n }\n return this.mutationQueue.getNextMutationBatchAfterBatchId(\n txn,\n afterBatchId\n );\n }\n );\n }\n\n /**\n * Read the current value of a Document with a given key or null if not\n * found - used for testing.\n */\n readDocument(key: DocumentKey): Promise<MaybeDocument | null> {\n return this.persistence.runTransaction('read document', 'readonly', txn => {\n return this.localDocuments.getDocument(txn, key);\n });\n }\n\n /**\n * Assigns the given target an internal ID so that its results can be pinned so\n * they don't get GC'd. A target must be allocated in the local store before\n * the store can be used to manage its view.\n *\n * Allocating an already allocated `Target` will return the existing `TargetData`\n * for that `Target`.\n */\n allocateTarget(target: Target): Promise<TargetData> {\n return this.persistence\n .runTransaction('Allocate target', 'readwrite', txn => {\n let targetData: TargetData;\n return this.targetCache\n .getTargetData(txn, target)\n .next((cached: TargetData | null) => {\n if (cached) {\n // This target has been listened to previously, so reuse the\n // previous targetID.\n // TODO(mcg): freshen last accessed date?\n targetData = cached;\n return PersistencePromise.resolve(targetData);\n } else {\n return this.targetCache.allocateTargetId(txn).next(targetId => {\n targetData = new TargetData(\n target,\n targetId,\n TargetPurpose.Listen,\n txn.currentSequenceNumber\n );\n return this.targetCache\n .addTargetData(txn, targetData)\n .next(() => targetData);\n });\n }\n });\n })\n .then(targetData => {\n if (this.targetDataByTarget.get(targetData.targetId) === null) {\n this.targetDataByTarget = this.targetDataByTarget.insert(\n targetData.targetId,\n targetData\n );\n this.targetIdByTarget.set(target, targetData.targetId);\n }\n return targetData;\n });\n }\n\n /**\n * Returns the TargetData as seen by the LocalStore, including updates that may\n * have not yet been persisted to the TargetCache.\n */\n // Visible for testing.\n getTargetData(\n transaction: PersistenceTransaction,\n target: Target\n ): PersistencePromise<TargetData | null> {\n const targetId = this.targetIdByTarget.get(target);\n if (targetId !== undefined) {\n return PersistencePromise.resolve<TargetData | null>(\n this.targetDataByTarget.get(targetId)\n );\n } else {\n return this.targetCache.getTargetData(transaction, target);\n }\n }\n\n /**\n * Unpin all the documents associated with the given target. If\n * `keepPersistedTargetData` is set to false and Eager GC enabled, the method\n * directly removes the associated target data from the target cache.\n *\n * Releasing a non-existing `Target` is a no-op.\n */\n // PORTING NOTE: `keepPersistedTargetData` is multi-tab only.\n releaseTarget(\n targetId: number,\n keepPersistedTargetData: boolean\n ): Promise<void> {\n const targetData = this.targetDataByTarget.get(targetId);\n debugAssert(\n targetData !== null,\n `Tried to release nonexistent target: ${targetId}`\n );\n\n const mode = keepPersistedTargetData ? 'readwrite' : 'readwrite-primary';\n return this.persistence\n .runTransaction('Release target', mode, txn => {\n if (!keepPersistedTargetData) {\n return this.persistence.referenceDelegate.removeTarget(\n txn,\n targetData!\n );\n } else {\n return PersistencePromise.resolve();\n }\n })\n .then(() => {\n this.targetDataByTarget = this.targetDataByTarget.remove(targetId);\n this.targetIdByTarget.delete(targetData!.target);\n });\n }\n\n /**\n * Runs the specified query against the local store and returns the results,\n * potentially taking advantage of query data from previous executions (such\n * as the set of remote keys).\n *\n * @param usePreviousResults Whether results from previous executions can\n * be used to optimize this query execution.\n */\n executeQuery(\n query: Query,\n usePreviousResults: boolean\n ): Promise<QueryResult> {\n let lastLimboFreeSnapshotVersion = SnapshotVersion.min();\n let remoteKeys = documentKeySet();\n\n return this.persistence.runTransaction('Execute query', 'readonly', txn => {\n return this.getTargetData(txn, query.toTarget())\n .next(targetData => {\n if (targetData) {\n lastLimboFreeSnapshotVersion =\n targetData.lastLimboFreeSnapshotVersion;\n return this.targetCache\n .getMatchingKeysForTargetId(txn, targetData.targetId)\n .next(result => {\n remoteKeys = result;\n });\n }\n })\n .next(() =>\n this.queryEngine.getDocumentsMatchingQuery(\n txn,\n query,\n usePreviousResults\n ? lastLimboFreeSnapshotVersion\n : SnapshotVersion.min(),\n usePreviousResults ? remoteKeys : documentKeySet()\n )\n )\n .next(documents => {\n return { documents, remoteKeys };\n });\n });\n }\n\n private applyWriteToRemoteDocuments(\n txn: PersistenceTransaction,\n batchResult: MutationBatchResult,\n documentBuffer: RemoteDocumentChangeBuffer\n ): PersistencePromise<void> {\n const batch = batchResult.batch;\n const docKeys = batch.keys();\n let promiseChain = PersistencePromise.resolve();\n docKeys.forEach(docKey => {\n promiseChain = promiseChain\n .next(() => {\n return documentBuffer.getEntry(txn, docKey);\n })\n .next((remoteDoc: MaybeDocument | null) => {\n let doc = remoteDoc;\n const ackVersion = batchResult.docVersions.get(docKey);\n hardAssert(\n ackVersion !== null,\n 'ackVersions should contain every doc in the write.'\n );\n if (!doc || doc.version.compareTo(ackVersion!) < 0) {\n doc = batch.applyToRemoteDocument(docKey, doc, batchResult);\n if (!doc) {\n debugAssert(\n !remoteDoc,\n 'Mutation batch ' +\n batch +\n ' applied to document ' +\n remoteDoc +\n ' resulted in null'\n );\n } else {\n // We use the commitVersion as the readTime rather than the\n // document's updateTime since the updateTime is not advanced\n // for updates that do not modify the underlying document.\n documentBuffer.addEntry(doc, batchResult.commitVersion);\n }\n }\n });\n });\n return promiseChain.next(() =>\n this.mutationQueue.removeMutationBatch(txn, batch)\n );\n }\n\n collectGarbage(garbageCollector: LruGarbageCollector): Promise<LruResults> {\n return this.persistence.runTransaction(\n 'Collect garbage',\n 'readwrite-primary',\n txn => garbageCollector.collect(txn, this.targetDataByTarget)\n );\n }\n}\n\n/**\n * An implementation of LocalStore that provides additional functionality\n * for MultiTabSyncEngine.\n */\n// PORTING NOTE: Web only.\nexport class MultiTabLocalStore extends LocalStore {\n protected mutationQueue: IndexedDbMutationQueue;\n protected remoteDocuments: IndexedDbRemoteDocumentCache;\n protected targetCache: IndexedDbTargetCache;\n\n constructor(\n protected persistence: IndexedDbPersistence,\n queryEngine: QueryEngine,\n initialUser: User\n ) {\n super(persistence, queryEngine, initialUser);\n\n this.mutationQueue = persistence.getMutationQueue(initialUser);\n this.remoteDocuments = persistence.getRemoteDocumentCache();\n this.targetCache = persistence.getTargetCache();\n }\n\n /** Starts the LocalStore. */\n start(): Promise<void> {\n return this.synchronizeLastDocumentChangeReadTime();\n }\n\n /** Returns the local view of the documents affected by a mutation batch. */\n lookupMutationDocuments(batchId: BatchId): Promise<MaybeDocumentMap | null> {\n return this.persistence.runTransaction(\n 'Lookup mutation documents',\n 'readonly',\n txn => {\n return this.mutationQueue\n .lookupMutationKeys(txn, batchId)\n .next(keys => {\n if (keys) {\n return this.localDocuments.getDocuments(\n txn,\n keys\n ) as PersistencePromise<MaybeDocumentMap | null>;\n } else {\n return PersistencePromise.resolve<MaybeDocumentMap | null>(null);\n }\n });\n }\n );\n }\n\n removeCachedMutationBatchMetadata(batchId: BatchId): void {\n this.mutationQueue.removeCachedMutationKeys(batchId);\n }\n\n setNetworkEnabled(networkEnabled: boolean): void {\n this.persistence.setNetworkEnabled(networkEnabled);\n }\n\n getActiveClients(): Promise<ClientId[]> {\n return this.persistence.getActiveClients();\n }\n\n getTarget(targetId: TargetId): Promise<Target | null> {\n const cachedTargetData = this.targetDataByTarget.get(targetId);\n\n if (cachedTargetData) {\n return Promise.resolve(cachedTargetData.target);\n } else {\n return this.persistence.runTransaction(\n 'Get target data',\n 'readonly',\n txn => {\n return this.targetCache\n .getTargetDataForTarget(txn, targetId)\n .next(targetData => (targetData ? targetData.target : null));\n }\n );\n }\n }\n\n /**\n * Returns the set of documents that have been updated since the last call.\n * If this is the first call, returns the set of changes since client\n * initialization. Further invocations will return document changes since\n * the point of rejection.\n */\n getNewDocumentChanges(): Promise<MaybeDocumentMap> {\n return this.persistence\n .runTransaction('Get new document changes', 'readonly', txn =>\n this.remoteDocuments.getNewDocumentChanges(\n txn,\n this.lastDocumentChangeReadTime\n )\n )\n .then(({ changedDocs, readTime }) => {\n this.lastDocumentChangeReadTime = readTime;\n return changedDocs;\n });\n }\n\n /**\n * Reads the newest document change from persistence and forwards the internal\n * synchronization marker so that calls to `getNewDocumentChanges()`\n * only return changes that happened after client initialization.\n */\n async synchronizeLastDocumentChangeReadTime(): Promise<void> {\n this.lastDocumentChangeReadTime = await this.persistence.runTransaction(\n 'Synchronize last document change read time',\n 'readonly',\n txn => this.remoteDocuments.getLastReadTime(txn)\n );\n }\n}\n\n/**\n * Verifies the error thrown by a LocalStore operation. If a LocalStore\n * operation fails because the primary lease has been taken by another client,\n * we ignore the error (the persistence layer will immediately call\n * `applyPrimaryLease` to propagate the primary state change). All other errors\n * are re-thrown.\n *\n * @param err An error returned by a LocalStore operation.\n * @return A Promise that resolves after we recovered, or the original error.\n */\nexport async function ignoreIfPrimaryLeaseLoss(\n err: FirestoreError\n): Promise<void> {\n if (\n err.code === Code.FAILED_PRECONDITION &&\n err.message === PRIMARY_LEASE_LOST_ERROR_MSG\n ) {\n logDebug(LOG_TAG, 'Unexpectedly lost primary lease');\n } else {\n throw err;\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 { TargetId } from '../core/types';\nimport { ChangeType, ViewSnapshot } from '../core/view_snapshot';\nimport { documentKeySet, DocumentKeySet } from '../model/collections';\n\n/**\n * A set of changes to what documents are currently in view and out of view for\n * a given query. These changes are sent to the LocalStore by the View (via\n * the SyncEngine) and are used to pin / unpin documents as appropriate.\n */\nexport class LocalViewChanges {\n constructor(\n readonly targetId: TargetId,\n readonly fromCache: boolean,\n readonly addedKeys: DocumentKeySet,\n readonly removedKeys: DocumentKeySet\n ) {}\n\n static fromSnapshot(\n targetId: TargetId,\n viewSnapshot: ViewSnapshot\n ): LocalViewChanges {\n let addedKeys = documentKeySet();\n let removedKeys = documentKeySet();\n\n for (const docChange of viewSnapshot.docChanges) {\n switch (docChange.type) {\n case ChangeType.Added:\n addedKeys = addedKeys.add(docChange.doc.key);\n break;\n case ChangeType.Removed:\n removedKeys = removedKeys.add(docChange.doc.key);\n break;\n default:\n // do nothing\n }\n }\n\n return new LocalViewChanges(\n targetId,\n viewSnapshot.fromCache,\n addedKeys,\n removedKeys\n );\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 { BatchId, TargetId } from '../core/types';\nimport { documentKeySet, DocumentKeySet } from '../model/collections';\nimport { DocumentKey } from '../model/document_key';\nimport { primitiveComparator } from '../util/misc';\nimport { SortedSet } from '../util/sorted_set';\n\n/**\n * A collection of references to a document from some kind of numbered entity\n * (either a target ID or batch ID). As references are added to or removed from\n * the set corresponding events are emitted to a registered garbage collector.\n *\n * Each reference is represented by a DocumentReference object. Each of them\n * contains enough information to uniquely identify the reference. They are all\n * stored primarily in a set sorted by key. A document is considered garbage if\n * there's no references in that set (this can be efficiently checked thanks to\n * sorting by key).\n *\n * ReferenceSet also keeps a secondary set that contains references sorted by\n * IDs. This one is used to efficiently implement removal of all references by\n * some target ID.\n */\nexport class ReferenceSet {\n // A set of outstanding references to a document sorted by key.\n private refsByKey = new SortedSet(DocReference.compareByKey);\n\n // A set of outstanding references to a document sorted by target id.\n private refsByTarget = new SortedSet(DocReference.compareByTargetId);\n\n /** Returns true if the reference set contains no references. */\n isEmpty(): boolean {\n return this.refsByKey.isEmpty();\n }\n\n /** Adds a reference to the given document key for the given ID. */\n addReference(key: DocumentKey, id: TargetId | BatchId): void {\n const ref = new DocReference(key, id);\n this.refsByKey = this.refsByKey.add(ref);\n this.refsByTarget = this.refsByTarget.add(ref);\n }\n\n /** Add references to the given document keys for the given ID. */\n addReferences(keys: DocumentKeySet, id: TargetId | BatchId): void {\n keys.forEach(key => this.addReference(key, id));\n }\n\n /**\n * Removes a reference to the given document key for the given\n * ID.\n */\n removeReference(key: DocumentKey, id: TargetId | BatchId): void {\n this.removeRef(new DocReference(key, id));\n }\n\n removeReferences(keys: DocumentKeySet, id: TargetId | BatchId): void {\n keys.forEach(key => this.removeReference(key, id));\n }\n\n /**\n * Clears all references with a given ID. Calls removeRef() for each key\n * removed.\n */\n removeReferencesForId(id: TargetId | BatchId): DocumentKey[] {\n const emptyKey = DocumentKey.EMPTY;\n const startRef = new DocReference(emptyKey, id);\n const endRef = new DocReference(emptyKey, id + 1);\n const keys: DocumentKey[] = [];\n this.refsByTarget.forEachInRange([startRef, endRef], ref => {\n this.removeRef(ref);\n keys.push(ref.key);\n });\n return keys;\n }\n\n removeAllReferences(): void {\n this.refsByKey.forEach(ref => this.removeRef(ref));\n }\n\n private removeRef(ref: DocReference): void {\n this.refsByKey = this.refsByKey.delete(ref);\n this.refsByTarget = this.refsByTarget.delete(ref);\n }\n\n referencesForId(id: TargetId | BatchId): DocumentKeySet {\n const emptyKey = DocumentKey.EMPTY;\n const startRef = new DocReference(emptyKey, id);\n const endRef = new DocReference(emptyKey, id + 1);\n let keys = documentKeySet();\n this.refsByTarget.forEachInRange([startRef, endRef], ref => {\n keys = keys.add(ref.key);\n });\n return keys;\n }\n\n containsKey(key: DocumentKey): boolean {\n const ref = new DocReference(key, 0);\n const firstRef = this.refsByKey.firstAfterOrEqual(ref);\n return firstRef !== null && key.isEqual(firstRef.key);\n }\n}\n\nexport class DocReference {\n constructor(\n public key: DocumentKey,\n public targetOrBatchId: TargetId | BatchId\n ) {}\n\n /** Compare by key then by ID */\n static compareByKey(left: DocReference, right: DocReference): number {\n return (\n DocumentKey.comparator(left.key, right.key) ||\n primitiveComparator(left.targetOrBatchId, right.targetOrBatchId)\n );\n }\n\n /** Compare by ID then by key */\n static compareByTargetId(left: DocReference, right: DocReference): number {\n return (\n primitiveComparator(left.targetOrBatchId, right.targetOrBatchId) ||\n DocumentKey.comparator(left.key, right.key)\n );\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 { SnapshotVersion } from '../core/snapshot_version';\nimport { TargetId } from '../core/types';\nimport {\n documentKeySet,\n DocumentKeySet,\n maybeDocumentMap,\n MaybeDocumentMap,\n targetIdSet\n} from '../model/collections';\nimport { SortedSet } from '../util/sorted_set';\nimport { ByteString } from '../util/byte_string';\n\n/**\n * An event from the RemoteStore. It is split into targetChanges (changes to the\n * state or the set of documents in our watched targets) and documentUpdates\n * (changes to the actual documents).\n */\nexport class RemoteEvent {\n constructor(\n /**\n * The snapshot version this event brings us up to, or MIN if not set.\n */\n readonly snapshotVersion: SnapshotVersion,\n /**\n * A map from target to changes to the target. See TargetChange.\n */\n readonly targetChanges: Map<TargetId, TargetChange>,\n /**\n * A set of targets that is known to be inconsistent. Listens for these\n * targets should be re-established without resume tokens.\n */\n readonly targetMismatches: SortedSet<TargetId>,\n /**\n * A set of which documents have changed or been deleted, along with the\n * doc's new values (if not deleted).\n */\n readonly documentUpdates: MaybeDocumentMap,\n /**\n * A set of which document updates are due only to limbo resolution targets.\n */\n readonly resolvedLimboDocuments: DocumentKeySet\n ) {}\n\n /**\n * HACK: Views require RemoteEvents in order to determine whether the view is\n * CURRENT, but secondary tabs don't receive remote events. So this method is\n * used to create a synthesized RemoteEvent that can be used to apply a\n * CURRENT status change to a View, for queries executed in a different tab.\n */\n // PORTING NOTE: Multi-tab only\n static createSynthesizedRemoteEventForCurrentChange(\n targetId: TargetId,\n current: boolean\n ): RemoteEvent {\n const targetChanges = new Map<TargetId, TargetChange>();\n targetChanges.set(\n targetId,\n TargetChange.createSynthesizedTargetChangeForCurrentChange(\n targetId,\n current\n )\n );\n return new RemoteEvent(\n SnapshotVersion.min(),\n targetChanges,\n targetIdSet(),\n maybeDocumentMap(),\n documentKeySet()\n );\n }\n}\n\n/**\n * A TargetChange specifies the set of changes for a specific target as part of\n * a RemoteEvent. These changes track which documents are added, modified or\n * removed, as well as the target's resume token and whether the target is\n * marked CURRENT.\n * The actual changes *to* documents are not part of the TargetChange since\n * documents may be part of multiple targets.\n */\nexport class TargetChange {\n constructor(\n /**\n * An opaque, server-assigned token that allows watching a query to be resumed\n * after disconnecting without retransmitting all the data that matches the\n * query. The resume token essentially identifies a point in time from which\n * the server should resume sending results.\n */\n readonly resumeToken: ByteString,\n /**\n * The \"current\" (synced) status of this target. Note that \"current\"\n * has special meaning in the RPC protocol that implies that a target is\n * both up-to-date and consistent with the rest of the watch stream.\n */\n readonly current: boolean,\n /**\n * The set of documents that were newly assigned to this target as part of\n * this remote event.\n */\n readonly addedDocuments: DocumentKeySet,\n /**\n * The set of documents that were already assigned to this target but received\n * an update during this remote event.\n */\n readonly modifiedDocuments: DocumentKeySet,\n /**\n * The set of documents that were removed from this target as part of this\n * remote event.\n */\n readonly removedDocuments: DocumentKeySet\n ) {}\n\n /**\n * This method is used to create a synthesized TargetChanges that can be used to\n * apply a CURRENT status change to a View (for queries executed in a different\n * tab) or for new queries (to raise snapshots with correct CURRENT status).\n */\n static createSynthesizedTargetChangeForCurrentChange(\n targetId: TargetId,\n current: boolean\n ): TargetChange {\n return new TargetChange(\n ByteString.EMPTY_BYTE_STRING,\n current,\n documentKeySet(),\n documentKeySet(),\n documentKeySet()\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 { DocumentKey } from '../model/document_key';\nimport { ResourcePath } from '../model/path';\nimport { isNullOrUndefined } from '../util/types';\nimport { Bound, Filter, OrderBy } from './query';\n\n/**\n * A Target represents the WatchTarget representation of a Query, which is used\n * by the LocalStore and the RemoteStore to keep track of and to execute\n * backend queries. While a Query can represent multiple Targets, each Targets\n * maps to a single WatchTarget in RemoteStore and a single TargetData entry\n * in persistence.\n */\nexport class Target {\n private memoizedCanonicalId: string | null = null;\n\n /**\n * Initializes a Target with a path and optional additional query constraints.\n * Path must currently be empty if this is a collection group query.\n *\n * NOTE: you should always construct `Target` from `Query.toTarget` instead of\n * using this constructor, because `Query` provides an implicit `orderBy`\n * property.\n */\n constructor(\n readonly path: ResourcePath,\n readonly collectionGroup: string | null = null,\n readonly orderBy: OrderBy[] = [],\n readonly filters: Filter[] = [],\n readonly limit: number | null = null,\n readonly startAt: Bound | null = null,\n readonly endAt: Bound | null = null\n ) {}\n\n canonicalId(): string {\n if (this.memoizedCanonicalId === null) {\n let canonicalId = this.path.canonicalString();\n if (this.collectionGroup !== null) {\n canonicalId += '|cg:' + this.collectionGroup;\n }\n canonicalId += '|f:';\n canonicalId += this.filters.map(f => f.canonicalId()).join(',');\n canonicalId += '|ob:';\n canonicalId += this.orderBy.map(o => o.canonicalId()).join(',');\n\n if (!isNullOrUndefined(this.limit)) {\n canonicalId += '|l:';\n canonicalId += this.limit!;\n }\n if (this.startAt) {\n canonicalId += '|lb:';\n canonicalId += this.startAt.canonicalId();\n }\n if (this.endAt) {\n canonicalId += '|ub:';\n canonicalId += this.endAt.canonicalId();\n }\n this.memoizedCanonicalId = canonicalId;\n }\n return this.memoizedCanonicalId;\n }\n\n toString(): string {\n let str = this.path.canonicalString();\n if (this.collectionGroup !== null) {\n str += ' collectionGroup=' + this.collectionGroup;\n }\n if (this.filters.length > 0) {\n str += `, filters: [${this.filters.join(', ')}]`;\n }\n if (!isNullOrUndefined(this.limit)) {\n str += ', limit: ' + this.limit;\n }\n if (this.orderBy.length > 0) {\n str += `, orderBy: [${this.orderBy.join(', ')}]`;\n }\n if (this.startAt) {\n str += ', startAt: ' + this.startAt.canonicalId();\n }\n if (this.endAt) {\n str += ', endAt: ' + this.endAt.canonicalId();\n }\n return `Target(${str})`;\n }\n\n isEqual(other: Target): boolean {\n if (this.limit !== other.limit) {\n return false;\n }\n\n if (this.orderBy.length !== other.orderBy.length) {\n return false;\n }\n\n for (let i = 0; i < this.orderBy.length; i++) {\n if (!this.orderBy[i].isEqual(other.orderBy[i])) {\n return false;\n }\n }\n\n if (this.filters.length !== other.filters.length) {\n return false;\n }\n\n for (let i = 0; i < this.filters.length; i++) {\n if (!this.filters[i].isEqual(other.filters[i])) {\n return false;\n }\n }\n\n if (this.collectionGroup !== other.collectionGroup) {\n return false;\n }\n\n if (!this.path.isEqual(other.path)) {\n return false;\n }\n\n if (\n this.startAt !== null\n ? !this.startAt.isEqual(other.startAt)\n : other.startAt !== null\n ) {\n return false;\n }\n\n return this.endAt !== null\n ? this.endAt.isEqual(other.endAt)\n : other.endAt === null;\n }\n\n isDocumentQuery(): boolean {\n return (\n DocumentKey.isDocumentKey(this.path) &&\n this.collectionGroup === null &&\n this.filters.length === 0\n );\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 * as api from '../protos/firestore_proto_api';\n\nimport { compareDocumentsByField, Document } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport {\n canonicalId,\n valueCompare,\n arrayValueContains,\n valueEquals,\n isArray,\n isNanValue,\n isNullValue,\n isReferenceValue,\n typeOrder\n} from '../model/values';\nimport { FieldPath, ResourcePath } from '../model/path';\nimport { debugAssert, fail } from '../util/assert';\nimport { Code, FirestoreError } from '../util/error';\nimport { isNullOrUndefined } from '../util/types';\nimport { Target } from './target';\n\nexport const enum LimitType {\n First = 'F',\n Last = 'L'\n}\n\n/**\n * Query encapsulates all the query attributes we support in the SDK. It can\n * be run against the LocalStore, as well as be converted to a `Target` to\n * query the RemoteStore results.\n */\nexport class Query {\n static atPath(path: ResourcePath): Query {\n return new Query(path);\n }\n\n private memoizedOrderBy: OrderBy[] | null = null;\n\n // The corresponding `Target` of this `Query` instance.\n private memoizedTarget: Target | null = null;\n\n /**\n * Initializes a Query with a path and optional additional query constraints.\n * Path must currently be empty if this is a collection group query.\n */\n constructor(\n readonly path: ResourcePath,\n readonly collectionGroup: string | null = null,\n readonly explicitOrderBy: OrderBy[] = [],\n readonly filters: Filter[] = [],\n readonly limit: number | null = null,\n readonly limitType: LimitType = LimitType.First,\n readonly startAt: Bound | null = null,\n readonly endAt: Bound | null = null\n ) {\n if (this.startAt) {\n this.assertValidBound(this.startAt);\n }\n if (this.endAt) {\n this.assertValidBound(this.endAt);\n }\n }\n\n get orderBy(): OrderBy[] {\n if (this.memoizedOrderBy === null) {\n this.memoizedOrderBy = [];\n\n const inequalityField = this.getInequalityFilterField();\n const firstOrderByField = this.getFirstOrderByField();\n if (inequalityField !== null && firstOrderByField === null) {\n // In order to implicitly add key ordering, we must also add the\n // inequality filter field for it to be a valid query.\n // Note that the default inequality field and key ordering is ascending.\n if (!inequalityField.isKeyField()) {\n this.memoizedOrderBy.push(new OrderBy(inequalityField));\n }\n this.memoizedOrderBy.push(\n new OrderBy(FieldPath.keyField(), Direction.ASCENDING)\n );\n } else {\n debugAssert(\n inequalityField === null ||\n (firstOrderByField !== null &&\n inequalityField.isEqual(firstOrderByField)),\n 'First orderBy should match inequality field.'\n );\n let foundKeyOrdering = false;\n for (const orderBy of this.explicitOrderBy) {\n this.memoizedOrderBy.push(orderBy);\n if (orderBy.field.isKeyField()) {\n foundKeyOrdering = true;\n }\n }\n if (!foundKeyOrdering) {\n // The order of the implicit key ordering always matches the last\n // explicit order by\n const lastDirection =\n this.explicitOrderBy.length > 0\n ? this.explicitOrderBy[this.explicitOrderBy.length - 1].dir\n : Direction.ASCENDING;\n this.memoizedOrderBy.push(\n new OrderBy(FieldPath.keyField(), lastDirection)\n );\n }\n }\n }\n return this.memoizedOrderBy;\n }\n\n addFilter(filter: Filter): Query {\n debugAssert(\n this.getInequalityFilterField() == null ||\n !(filter instanceof FieldFilter) ||\n !filter.isInequality() ||\n filter.field.isEqual(this.getInequalityFilterField()!),\n 'Query must only have one inequality field.'\n );\n\n debugAssert(\n !this.isDocumentQuery(),\n 'No filtering allowed for document query'\n );\n\n const newFilters = this.filters.concat([filter]);\n return new Query(\n this.path,\n this.collectionGroup,\n this.explicitOrderBy.slice(),\n newFilters,\n this.limit,\n this.limitType,\n this.startAt,\n this.endAt\n );\n }\n\n addOrderBy(orderBy: OrderBy): Query {\n debugAssert(\n !this.startAt && !this.endAt,\n 'Bounds must be set after orderBy'\n );\n // TODO(dimond): validate that orderBy does not list the same key twice.\n const newOrderBy = this.explicitOrderBy.concat([orderBy]);\n return new Query(\n this.path,\n this.collectionGroup,\n newOrderBy,\n this.filters.slice(),\n this.limit,\n this.limitType,\n this.startAt,\n this.endAt\n );\n }\n\n withLimitToFirst(limit: number | null): Query {\n return new Query(\n this.path,\n this.collectionGroup,\n this.explicitOrderBy.slice(),\n this.filters.slice(),\n limit,\n LimitType.First,\n this.startAt,\n this.endAt\n );\n }\n\n withLimitToLast(limit: number | null): Query {\n return new Query(\n this.path,\n this.collectionGroup,\n this.explicitOrderBy.slice(),\n this.filters.slice(),\n limit,\n LimitType.Last,\n this.startAt,\n this.endAt\n );\n }\n\n withStartAt(bound: Bound): Query {\n return new Query(\n this.path,\n this.collectionGroup,\n this.explicitOrderBy.slice(),\n this.filters.slice(),\n this.limit,\n this.limitType,\n bound,\n this.endAt\n );\n }\n\n withEndAt(bound: Bound): Query {\n return new Query(\n this.path,\n this.collectionGroup,\n this.explicitOrderBy.slice(),\n this.filters.slice(),\n this.limit,\n this.limitType,\n this.startAt,\n bound\n );\n }\n\n /**\n * Helper to convert a collection group query into a collection query at a\n * specific path. This is used when executing collection group queries, since\n * we have to split the query into a set of collection queries at multiple\n * paths.\n */\n asCollectionQueryAtPath(path: ResourcePath): Query {\n return new Query(\n path,\n /*collectionGroup=*/ null,\n this.explicitOrderBy.slice(),\n this.filters.slice(),\n this.limit,\n this.limitType,\n this.startAt,\n this.endAt\n );\n }\n\n /**\n * Returns true if this query does not specify any query constraints that\n * could remove results.\n */\n matchesAllDocuments(): boolean {\n return (\n this.filters.length === 0 &&\n this.limit === null &&\n this.startAt == null &&\n this.endAt == null &&\n (this.explicitOrderBy.length === 0 ||\n (this.explicitOrderBy.length === 1 &&\n this.explicitOrderBy[0].field.isKeyField()))\n );\n }\n\n // TODO(b/29183165): This is used to get a unique string from a query to, for\n // example, use as a dictionary key, but the implementation is subject to\n // collisions. Make it collision-free.\n canonicalId(): string {\n return `${this.toTarget().canonicalId()}|lt:${this.limitType}`;\n }\n\n toString(): string {\n return `Query(target=${this.toTarget().toString()}; limitType=${\n this.limitType\n })`;\n }\n\n isEqual(other: Query): boolean {\n return (\n this.toTarget().isEqual(other.toTarget()) &&\n this.limitType === other.limitType\n );\n }\n\n docComparator(d1: Document, d2: Document): number {\n let comparedOnKeyField = false;\n for (const orderBy of this.orderBy) {\n const comp = orderBy.compare(d1, d2);\n if (comp !== 0) {\n return comp;\n }\n comparedOnKeyField = comparedOnKeyField || orderBy.field.isKeyField();\n }\n // Assert that we actually compared by key\n debugAssert(\n comparedOnKeyField,\n \"orderBy used that doesn't compare on key field\"\n );\n return 0;\n }\n\n matches(doc: Document): boolean {\n return (\n this.matchesPathAndCollectionGroup(doc) &&\n this.matchesOrderBy(doc) &&\n this.matchesFilters(doc) &&\n this.matchesBounds(doc)\n );\n }\n\n hasLimitToFirst(): boolean {\n return !isNullOrUndefined(this.limit) && this.limitType === LimitType.First;\n }\n\n hasLimitToLast(): boolean {\n return !isNullOrUndefined(this.limit) && this.limitType === LimitType.Last;\n }\n\n getFirstOrderByField(): FieldPath | null {\n return this.explicitOrderBy.length > 0\n ? this.explicitOrderBy[0].field\n : null;\n }\n\n getInequalityFilterField(): FieldPath | null {\n for (const filter of this.filters) {\n if (filter instanceof FieldFilter && filter.isInequality()) {\n return filter.field;\n }\n }\n return null;\n }\n\n // Checks if any of the provided Operators are included in the query and\n // returns the first one that is, or null if none are.\n findFilterOperator(operators: Operator[]): Operator | null {\n for (const filter of this.filters) {\n if (filter instanceof FieldFilter) {\n if (operators.indexOf(filter.op) >= 0) {\n return filter.op;\n }\n }\n }\n return null;\n }\n\n isDocumentQuery(): boolean {\n return this.toTarget().isDocumentQuery();\n }\n\n isCollectionGroupQuery(): boolean {\n return this.collectionGroup !== null;\n }\n\n /**\n * Converts this `Query` instance to it's corresponding `Target`\n * representation.\n */\n toTarget(): Target {\n if (!this.memoizedTarget) {\n if (this.limitType === LimitType.First) {\n this.memoizedTarget = new Target(\n this.path,\n this.collectionGroup,\n this.orderBy,\n this.filters,\n this.limit,\n this.startAt,\n this.endAt\n );\n } else {\n // Flip the orderBy directions since we want the last results\n const orderBys = [] as OrderBy[];\n for (const orderBy of this.orderBy) {\n const dir =\n orderBy.dir === Direction.DESCENDING\n ? Direction.ASCENDING\n : Direction.DESCENDING;\n orderBys.push(new OrderBy(orderBy.field, dir));\n }\n\n // We need to swap the cursors to match the now-flipped query ordering.\n const startAt = this.endAt\n ? new Bound(this.endAt.position, !this.endAt.before)\n : null;\n const endAt = this.startAt\n ? new Bound(this.startAt.position, !this.startAt.before)\n : null;\n\n // Now return as a LimitType.First query.\n this.memoizedTarget = new Target(\n this.path,\n this.collectionGroup,\n orderBys,\n this.filters,\n this.limit,\n startAt,\n endAt\n );\n }\n }\n return this.memoizedTarget!;\n }\n\n private matchesPathAndCollectionGroup(doc: Document): boolean {\n const docPath = doc.key.path;\n if (this.collectionGroup !== null) {\n // NOTE: this.path is currently always empty since we don't expose Collection\n // Group queries rooted at a document path yet.\n return (\n doc.key.hasCollectionId(this.collectionGroup) &&\n this.path.isPrefixOf(docPath)\n );\n } else if (DocumentKey.isDocumentKey(this.path)) {\n // exact match for document queries\n return this.path.isEqual(docPath);\n } else {\n // shallow ancestor queries by default\n return this.path.isImmediateParentOf(docPath);\n }\n }\n\n /**\n * A document must have a value for every ordering clause in order to show up\n * in the results.\n */\n private matchesOrderBy(doc: Document): boolean {\n for (const orderBy of this.explicitOrderBy) {\n // order by key always matches\n if (!orderBy.field.isKeyField() && doc.field(orderBy.field) === null) {\n return false;\n }\n }\n return true;\n }\n\n private matchesFilters(doc: Document): boolean {\n for (const filter of this.filters) {\n if (!filter.matches(doc)) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Makes sure a document is within the bounds, if provided.\n */\n private matchesBounds(doc: Document): boolean {\n if (this.startAt && !this.startAt.sortsBeforeDocument(this.orderBy, doc)) {\n return false;\n }\n if (this.endAt && this.endAt.sortsBeforeDocument(this.orderBy, doc)) {\n return false;\n }\n return true;\n }\n\n private assertValidBound(bound: Bound): void {\n debugAssert(\n bound.position.length <= this.orderBy.length,\n 'Bound is longer than orderBy'\n );\n }\n}\n\nexport abstract class Filter {\n abstract matches(doc: Document): boolean;\n abstract canonicalId(): string;\n abstract isEqual(filter: Filter): boolean;\n}\n\nexport const enum Operator {\n LESS_THAN = '<',\n LESS_THAN_OR_EQUAL = '<=',\n EQUAL = '==',\n GREATER_THAN = '>',\n GREATER_THAN_OR_EQUAL = '>=',\n ARRAY_CONTAINS = 'array-contains',\n IN = 'in',\n ARRAY_CONTAINS_ANY = 'array-contains-any'\n}\n\nexport class FieldFilter extends Filter {\n protected constructor(\n public field: FieldPath,\n public op: Operator,\n public value: api.Value\n ) {\n super();\n }\n\n /**\n * Creates a filter based on the provided arguments.\n */\n static create(field: FieldPath, op: Operator, value: api.Value): FieldFilter {\n if (field.isKeyField()) {\n if (op === Operator.IN) {\n debugAssert(\n isArray(value),\n 'Comparing on key with IN, but filter value not an ArrayValue'\n );\n debugAssert(\n (value.arrayValue.values || []).every(elem => isReferenceValue(elem)),\n 'Comparing on key with IN, but an array value was not a RefValue'\n );\n return new KeyFieldInFilter(field, value);\n } else {\n debugAssert(\n isReferenceValue(value),\n 'Comparing on key, but filter value not a RefValue'\n );\n debugAssert(\n op !== Operator.ARRAY_CONTAINS && op !== Operator.ARRAY_CONTAINS_ANY,\n `'${op.toString()}' queries don't make sense on document keys.`\n );\n return new KeyFieldFilter(field, op, value);\n }\n } else if (isNullValue(value)) {\n if (op !== Operator.EQUAL) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'Invalid query. Null supports only equality comparisons.'\n );\n }\n return new FieldFilter(field, op, value);\n } else if (isNanValue(value)) {\n if (op !== Operator.EQUAL) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'Invalid query. NaN supports only equality comparisons.'\n );\n }\n return new FieldFilter(field, op, value);\n } else if (op === Operator.ARRAY_CONTAINS) {\n return new ArrayContainsFilter(field, value);\n } else if (op === Operator.IN) {\n debugAssert(\n isArray(value),\n 'IN filter has invalid value: ' + value.toString()\n );\n return new InFilter(field, value);\n } else if (op === Operator.ARRAY_CONTAINS_ANY) {\n debugAssert(\n isArray(value),\n 'ARRAY_CONTAINS_ANY filter has invalid value: ' + value.toString()\n );\n return new ArrayContainsAnyFilter(field, value);\n } else {\n return new FieldFilter(field, op, value);\n }\n }\n\n matches(doc: Document): boolean {\n const other = doc.field(this.field);\n\n // Only compare types with matching backend order (such as double and int).\n return (\n other !== null &&\n typeOrder(this.value) === typeOrder(other) &&\n this.matchesComparison(valueCompare(other, this.value))\n );\n }\n\n protected matchesComparison(comparison: number): boolean {\n switch (this.op) {\n case Operator.LESS_THAN:\n return comparison < 0;\n case Operator.LESS_THAN_OR_EQUAL:\n return comparison <= 0;\n case Operator.EQUAL:\n return comparison === 0;\n case Operator.GREATER_THAN:\n return comparison > 0;\n case Operator.GREATER_THAN_OR_EQUAL:\n return comparison >= 0;\n default:\n return fail('Unknown FieldFilter operator: ' + this.op);\n }\n }\n\n isInequality(): boolean {\n return (\n [\n Operator.LESS_THAN,\n Operator.LESS_THAN_OR_EQUAL,\n Operator.GREATER_THAN,\n Operator.GREATER_THAN_OR_EQUAL\n ].indexOf(this.op) >= 0\n );\n }\n\n canonicalId(): string {\n // TODO(b/29183165): Technically, this won't be unique if two values have\n // the same description, such as the int 3 and the string \"3\". So we should\n // add the types in here somehow, too.\n return (\n this.field.canonicalString() +\n this.op.toString() +\n canonicalId(this.value)\n );\n }\n\n isEqual(other: Filter): boolean {\n if (other instanceof FieldFilter) {\n return (\n this.op === other.op &&\n this.field.isEqual(other.field) &&\n valueEquals(this.value, other.value)\n );\n } else {\n return false;\n }\n }\n\n toString(): string {\n return `${this.field.canonicalString()} ${this.op} ${canonicalId(\n this.value\n )}`;\n }\n}\n\n/** Filter that matches on key fields (i.e. '__name__'). */\nexport class KeyFieldFilter extends FieldFilter {\n private readonly key: DocumentKey;\n\n constructor(field: FieldPath, op: Operator, value: api.Value) {\n super(field, op, value);\n debugAssert(\n isReferenceValue(value),\n 'KeyFieldFilter expects a ReferenceValue'\n );\n this.key = DocumentKey.fromName(value.referenceValue);\n }\n\n matches(doc: Document): boolean {\n const comparison = DocumentKey.comparator(doc.key, this.key);\n return this.matchesComparison(comparison);\n }\n}\n\n/** Filter that matches on key fields within an array. */\nexport class KeyFieldInFilter extends FieldFilter {\n private readonly keys: DocumentKey[];\n\n constructor(field: FieldPath, value: api.Value) {\n super(field, Operator.IN, value);\n debugAssert(isArray(value), 'KeyFieldInFilter expects an ArrayValue');\n this.keys = (value.arrayValue.values || []).map(v => {\n debugAssert(\n isReferenceValue(v),\n 'Comparing on key with IN, but an array value was not a ReferenceValue'\n );\n return DocumentKey.fromName(v.referenceValue);\n });\n }\n\n matches(doc: Document): boolean {\n return this.keys.some(key => key.isEqual(doc.key));\n }\n}\n\n/** A Filter that implements the array-contains operator. */\nexport class ArrayContainsFilter extends FieldFilter {\n constructor(field: FieldPath, value: api.Value) {\n super(field, Operator.ARRAY_CONTAINS, value);\n }\n\n matches(doc: Document): boolean {\n const other = doc.field(this.field);\n return isArray(other) && arrayValueContains(other.arrayValue, this.value);\n }\n}\n\n/** A Filter that implements the IN operator. */\nexport class InFilter extends FieldFilter {\n constructor(field: FieldPath, value: api.Value) {\n super(field, Operator.IN, value);\n debugAssert(isArray(value), 'InFilter expects an ArrayValue');\n }\n\n matches(doc: Document): boolean {\n const other = doc.field(this.field);\n return other !== null && arrayValueContains(this.value.arrayValue!, other);\n }\n}\n\n/** A Filter that implements the array-contains-any operator. */\nexport class ArrayContainsAnyFilter extends FieldFilter {\n constructor(field: FieldPath, value: api.Value) {\n super(field, Operator.ARRAY_CONTAINS_ANY, value);\n debugAssert(isArray(value), 'ArrayContainsAnyFilter expects an ArrayValue');\n }\n\n matches(doc: Document): boolean {\n const other = doc.field(this.field);\n if (!isArray(other) || !other.arrayValue.values) {\n return false;\n }\n return other.arrayValue.values.some(val =>\n arrayValueContains(this.value.arrayValue!, val)\n );\n }\n}\n\n/**\n * The direction of sorting in an order by.\n */\nexport const enum Direction {\n ASCENDING = 'asc',\n DESCENDING = 'desc'\n}\n\n/**\n * Represents a bound of a query.\n *\n * The bound is specified with the given components representing a position and\n * whether it's just before or just after the position (relative to whatever the\n * query order is).\n *\n * The position represents a logical index position for a query. It's a prefix\n * of values for the (potentially implicit) order by clauses of a query.\n *\n * Bound provides a function to determine whether a document comes before or\n * after a bound. This is influenced by whether the position is just before or\n * just after the provided values.\n */\nexport class Bound {\n constructor(readonly position: api.Value[], readonly before: boolean) {}\n\n canonicalId(): string {\n // TODO(b/29183165): Make this collision robust.\n return `${this.before ? 'b' : 'a'}:${this.position\n .map(p => canonicalId(p))\n .join(',')}`;\n }\n\n /**\n * Returns true if a document sorts before a bound using the provided sort\n * order.\n */\n sortsBeforeDocument(orderBy: OrderBy[], doc: Document): boolean {\n debugAssert(\n this.position.length <= orderBy.length,\n \"Bound has more components than query's orderBy\"\n );\n let comparison = 0;\n for (let i = 0; i < this.position.length; i++) {\n const orderByComponent = orderBy[i];\n const component = this.position[i];\n if (orderByComponent.field.isKeyField()) {\n debugAssert(\n isReferenceValue(component),\n 'Bound has a non-key value where the key path is being used.'\n );\n comparison = DocumentKey.comparator(\n DocumentKey.fromName(component.referenceValue),\n doc.key\n );\n } else {\n const docValue = doc.field(orderByComponent.field);\n debugAssert(\n docValue !== null,\n 'Field should exist since document matched the orderBy already.'\n );\n comparison = valueCompare(component, docValue);\n }\n if (orderByComponent.dir === Direction.DESCENDING) {\n comparison = comparison * -1;\n }\n if (comparison !== 0) {\n break;\n }\n }\n return this.before ? comparison <= 0 : comparison < 0;\n }\n\n isEqual(other: Bound | null): boolean {\n if (other === null) {\n return false;\n }\n if (\n this.before !== other.before ||\n this.position.length !== other.position.length\n ) {\n return false;\n }\n for (let i = 0; i < this.position.length; i++) {\n const thisPosition = this.position[i];\n const otherPosition = other.position[i];\n if (!valueEquals(thisPosition, otherPosition)) {\n return false;\n }\n }\n return true;\n }\n}\n\n/**\n * An ordering on a field, in some Direction. Direction defaults to ASCENDING.\n */\nexport class OrderBy {\n readonly dir: Direction;\n private readonly isKeyOrderBy: boolean;\n\n constructor(readonly field: FieldPath, dir?: Direction) {\n if (dir === undefined) {\n dir = Direction.ASCENDING;\n }\n this.dir = dir;\n this.isKeyOrderBy = field.isKeyField();\n }\n\n compare(d1: Document, d2: Document): number {\n const comparison = this.isKeyOrderBy\n ? DocumentKey.comparator(d1.key, d2.key)\n : compareDocumentsByField(this.field, d1, d2);\n switch (this.dir) {\n case Direction.ASCENDING:\n return comparison;\n case Direction.DESCENDING:\n return -1 * comparison;\n default:\n return fail('Unknown direction: ' + this.dir);\n }\n }\n\n canonicalId(): string {\n // TODO(b/29183165): Make this collision robust.\n return this.field.canonicalString() + this.dir.toString();\n }\n\n toString(): string {\n return `${this.field.canonicalString()} (${this.dir})`;\n }\n\n isEqual(other: OrderBy): boolean {\n return this.dir === other.dir && this.field.isEqual(other.field);\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 { SortedMap } from '../util/sorted_map';\n\nimport { documentMap } from './collections';\nimport { Document } from './document';\nimport { DocumentComparator } from './document_comparator';\nimport { DocumentKey } from './document_key';\n\n/**\n * DocumentSet is an immutable (copy-on-write) collection that holds documents\n * in order specified by the provided comparator. We always add a document key\n * comparator on top of what is provided to guarantee document equality based on\n * the key.\n */\n\nexport class DocumentSet {\n /**\n * Returns an empty copy of the existing DocumentSet, using the same\n * comparator.\n */\n static emptySet(oldSet: DocumentSet): DocumentSet {\n return new DocumentSet(oldSet.comparator);\n }\n\n private comparator: DocumentComparator;\n private keyedMap: SortedMap<DocumentKey, Document>;\n private sortedSet: SortedMap<Document, null>;\n\n /** The default ordering is by key if the comparator is omitted */\n constructor(comp?: DocumentComparator) {\n // We are adding document key comparator to the end as it's the only\n // guaranteed unique property of a document.\n if (comp) {\n this.comparator = (d1: Document, d2: Document) =>\n comp(d1, d2) || DocumentKey.comparator(d1.key, d2.key);\n } else {\n this.comparator = (d1: Document, d2: Document) =>\n DocumentKey.comparator(d1.key, d2.key);\n }\n\n this.keyedMap = documentMap();\n this.sortedSet = new SortedMap<Document, null>(this.comparator);\n }\n\n has(key: DocumentKey): boolean {\n return this.keyedMap.get(key) != null;\n }\n\n get(key: DocumentKey): Document | null {\n return this.keyedMap.get(key);\n }\n\n first(): Document | null {\n return this.sortedSet.minKey();\n }\n\n last(): Document | null {\n return this.sortedSet.maxKey();\n }\n\n isEmpty(): boolean {\n return this.sortedSet.isEmpty();\n }\n\n /**\n * Returns the index of the provided key in the document set, or -1 if the\n * document key is not present in the set;\n */\n indexOf(key: DocumentKey): number {\n const doc = this.keyedMap.get(key);\n return doc ? this.sortedSet.indexOf(doc) : -1;\n }\n\n get size(): number {\n return this.sortedSet.size;\n }\n\n /** Iterates documents in order defined by \"comparator\" */\n forEach(cb: (doc: Document) => void): void {\n this.sortedSet.inorderTraversal((k, v) => {\n cb(k);\n return false;\n });\n }\n\n /** Inserts or updates a document with the same key */\n add(doc: Document): DocumentSet {\n // First remove the element if we have it.\n const set = this.delete(doc.key);\n return set.copy(\n set.keyedMap.insert(doc.key, doc),\n set.sortedSet.insert(doc, null)\n );\n }\n\n /** Deletes a document with a given key */\n delete(key: DocumentKey): DocumentSet {\n const doc = this.get(key);\n if (!doc) {\n return this;\n }\n\n return this.copy(this.keyedMap.remove(key), this.sortedSet.remove(doc));\n }\n\n isEqual(other: DocumentSet | null | undefined): boolean {\n if (!(other instanceof DocumentSet)) {\n return false;\n }\n if (this.size !== other.size) {\n return false;\n }\n\n const thisIt = this.sortedSet.getIterator();\n const otherIt = other.sortedSet.getIterator();\n while (thisIt.hasNext()) {\n const thisDoc = thisIt.getNext().key;\n const otherDoc = otherIt.getNext().key;\n if (!thisDoc.isEqual(otherDoc)) {\n return false;\n }\n }\n return true;\n }\n\n toString(): string {\n const docStrings: string[] = [];\n this.forEach(doc => {\n docStrings.push(doc.toString());\n });\n if (docStrings.length === 0) {\n return 'DocumentSet ()';\n } else {\n return 'DocumentSet (\\n ' + docStrings.join(' \\n') + '\\n)';\n }\n }\n\n private copy(\n keyedMap: SortedMap<DocumentKey, Document>,\n sortedSet: SortedMap<Document, null>\n ): DocumentSet {\n const newSet = new DocumentSet();\n newSet.comparator = this.comparator;\n newSet.keyedMap = keyedMap;\n newSet.sortedSet = sortedSet;\n return newSet;\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 { Document } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport { DocumentSet } from '../model/document_set';\nimport { fail } from '../util/assert';\nimport { SortedMap } from '../util/sorted_map';\n\nimport { DocumentKeySet } from '../model/collections';\nimport { Query } from './query';\n\nexport const enum ChangeType {\n Added,\n Removed,\n Modified,\n Metadata\n}\n\nexport interface DocumentViewChange {\n type: ChangeType;\n doc: Document;\n}\n\nexport const enum SyncState {\n Local,\n Synced\n}\n\n/**\n * DocumentChangeSet keeps track of a set of changes to docs in a query, merging\n * duplicate events for the same doc.\n */\nexport class DocumentChangeSet {\n private changeMap = new SortedMap<DocumentKey, DocumentViewChange>(\n DocumentKey.comparator\n );\n\n track(change: DocumentViewChange): void {\n const key = change.doc.key;\n const oldChange = this.changeMap.get(key);\n if (!oldChange) {\n this.changeMap = this.changeMap.insert(key, change);\n return;\n }\n\n // Merge the new change with the existing change.\n if (\n change.type !== ChangeType.Added &&\n oldChange.type === ChangeType.Metadata\n ) {\n this.changeMap = this.changeMap.insert(key, change);\n } else if (\n change.type === ChangeType.Metadata &&\n oldChange.type !== ChangeType.Removed\n ) {\n this.changeMap = this.changeMap.insert(key, {\n type: oldChange.type,\n doc: change.doc\n });\n } else if (\n change.type === ChangeType.Modified &&\n oldChange.type === ChangeType.Modified\n ) {\n this.changeMap = this.changeMap.insert(key, {\n type: ChangeType.Modified,\n doc: change.doc\n });\n } else if (\n change.type === ChangeType.Modified &&\n oldChange.type === ChangeType.Added\n ) {\n this.changeMap = this.changeMap.insert(key, {\n type: ChangeType.Added,\n doc: change.doc\n });\n } else if (\n change.type === ChangeType.Removed &&\n oldChange.type === ChangeType.Added\n ) {\n this.changeMap = this.changeMap.remove(key);\n } else if (\n change.type === ChangeType.Removed &&\n oldChange.type === ChangeType.Modified\n ) {\n this.changeMap = this.changeMap.insert(key, {\n type: ChangeType.Removed,\n doc: oldChange.doc\n });\n } else if (\n change.type === ChangeType.Added &&\n oldChange.type === ChangeType.Removed\n ) {\n this.changeMap = this.changeMap.insert(key, {\n type: ChangeType.Modified,\n doc: change.doc\n });\n } else {\n // This includes these cases, which don't make sense:\n // Added->Added\n // Removed->Removed\n // Modified->Added\n // Removed->Modified\n // Metadata->Added\n // Removed->Metadata\n fail(\n 'unsupported combination of changes: ' +\n JSON.stringify(change) +\n ' after ' +\n JSON.stringify(oldChange)\n );\n }\n }\n\n getChanges(): DocumentViewChange[] {\n const changes: DocumentViewChange[] = [];\n this.changeMap.inorderTraversal(\n (key: DocumentKey, change: DocumentViewChange) => {\n changes.push(change);\n }\n );\n return changes;\n }\n}\n\nexport class ViewSnapshot {\n constructor(\n readonly query: Query,\n readonly docs: DocumentSet,\n readonly oldDocs: DocumentSet,\n readonly docChanges: DocumentViewChange[],\n readonly mutatedKeys: DocumentKeySet,\n readonly fromCache: boolean,\n readonly syncStateChanged: boolean,\n readonly excludesMetadataChanges: boolean\n ) {}\n\n /** Returns a view snapshot as if all documents in the snapshot were added. */\n static fromInitialDocuments(\n query: Query,\n documents: DocumentSet,\n mutatedKeys: DocumentKeySet,\n fromCache: boolean\n ): ViewSnapshot {\n const changes: DocumentViewChange[] = [];\n documents.forEach(doc => {\n changes.push({ type: ChangeType.Added, doc });\n });\n\n return new ViewSnapshot(\n query,\n documents,\n DocumentSet.emptySet(documents),\n changes,\n mutatedKeys,\n fromCache,\n /* syncStateChanged= */ true,\n /* excludesMetadataChanges= */ false\n );\n }\n\n get hasPendingWrites(): boolean {\n return !this.mutatedKeys.isEmpty();\n }\n\n isEqual(other: ViewSnapshot): boolean {\n if (\n this.fromCache !== other.fromCache ||\n this.syncStateChanged !== other.syncStateChanged ||\n !this.mutatedKeys.isEqual(other.mutatedKeys) ||\n !this.query.isEqual(other.query) ||\n !this.docs.isEqual(other.docs) ||\n !this.oldDocs.isEqual(other.oldDocs)\n ) {\n return false;\n }\n const changes: DocumentViewChange[] = this.docChanges;\n const otherChanges: DocumentViewChange[] = other.docChanges;\n if (changes.length !== otherChanges.length) {\n return false;\n }\n for (let i = 0; i < changes.length; i++) {\n if (\n changes[i].type !== otherChanges[i].type ||\n !changes[i].doc.isEqual(otherChanges[i].doc)\n ) {\n return false;\n }\n }\n return true;\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 { QueryResult } from '../local/local_store';\nimport {\n documentKeySet,\n DocumentKeySet,\n MaybeDocumentMap\n} from '../model/collections';\nimport { Document, MaybeDocument } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport { DocumentSet } from '../model/document_set';\nimport { TargetChange } from '../remote/remote_event';\nimport { debugAssert, fail } from '../util/assert';\n\nimport { Query } from './query';\nimport { OnlineState } from './types';\nimport {\n ChangeType,\n DocumentChangeSet,\n SyncState,\n ViewSnapshot\n} from './view_snapshot';\n\nexport type LimboDocumentChange = AddedLimboDocument | RemovedLimboDocument;\nexport class AddedLimboDocument {\n constructor(public key: DocumentKey) {}\n}\nexport class RemovedLimboDocument {\n constructor(public key: DocumentKey) {}\n}\n\n/** The result of applying a set of doc changes to a view. */\nexport interface ViewDocumentChanges {\n /** The new set of docs that should be in the view. */\n documentSet: DocumentSet;\n /** The diff of these docs with the previous set of docs. */\n changeSet: DocumentChangeSet;\n /**\n * Whether the set of documents passed in was not sufficient to calculate the\n * new state of the view and there needs to be another pass based on the\n * local cache.\n */\n needsRefill: boolean;\n\n mutatedKeys: DocumentKeySet;\n}\n\nexport interface ViewChange {\n snapshot?: ViewSnapshot;\n limboChanges: LimboDocumentChange[];\n}\n\n/**\n * View is responsible for computing the final merged truth of what docs are in\n * a query. It gets notified of local and remote changes to docs, and applies\n * the query filters and limits to determine the most correct possible results.\n */\nexport class View {\n private syncState: SyncState | null = null;\n /**\n * A flag whether the view is current with the backend. A view is considered\n * current after it has seen the current flag from the backend and did not\n * lose consistency within the watch stream (e.g. because of an existence\n * filter mismatch).\n */\n private current = false;\n private documentSet: DocumentSet;\n /** Documents in the view but not in the remote target */\n private limboDocuments = documentKeySet();\n /** Document Keys that have local changes */\n private mutatedKeys = documentKeySet();\n\n constructor(\n private query: Query,\n /** Documents included in the remote target */\n private _syncedDocuments: DocumentKeySet\n ) {\n this.documentSet = new DocumentSet(query.docComparator.bind(query));\n }\n\n /**\n * The set of remote documents that the server has told us belongs to the target associated with\n * this view.\n */\n get syncedDocuments(): DocumentKeySet {\n return this._syncedDocuments;\n }\n\n /**\n * Iterates over a set of doc changes, applies the query limit, and computes\n * what the new results should be, what the changes were, and whether we may\n * need to go back to the local cache for more results. Does not make any\n * changes to the view.\n * @param docChanges The doc changes to apply to this view.\n * @param previousChanges If this is being called with a refill, then start\n * with this set of docs and changes instead of the current view.\n * @return a new set of docs, changes, and refill flag.\n */\n computeDocChanges(\n docChanges: MaybeDocumentMap,\n previousChanges?: ViewDocumentChanges\n ): ViewDocumentChanges {\n const changeSet = previousChanges\n ? previousChanges.changeSet\n : new DocumentChangeSet();\n const oldDocumentSet = previousChanges\n ? previousChanges.documentSet\n : this.documentSet;\n let newMutatedKeys = previousChanges\n ? previousChanges.mutatedKeys\n : this.mutatedKeys;\n let newDocumentSet = oldDocumentSet;\n let needsRefill = false;\n\n // Track the last doc in a (full) limit. This is necessary, because some\n // update (a delete, or an update moving a doc past the old limit) might\n // mean there is some other document in the local cache that either should\n // come (1) between the old last limit doc and the new last document, in the\n // case of updates, or (2) after the new last document, in the case of\n // deletes. So we keep this doc at the old limit to compare the updates to.\n //\n // Note that this should never get used in a refill (when previousChanges is\n // set), because there will only be adds -- no deletes or updates.\n const lastDocInLimit =\n this.query.hasLimitToFirst() && oldDocumentSet.size === this.query.limit\n ? oldDocumentSet.last()\n : null;\n const firstDocInLimit =\n this.query.hasLimitToLast() && oldDocumentSet.size === this.query.limit\n ? oldDocumentSet.first()\n : null;\n\n docChanges.inorderTraversal(\n (key: DocumentKey, newMaybeDoc: MaybeDocument) => {\n const oldDoc = oldDocumentSet.get(key);\n let newDoc = newMaybeDoc instanceof Document ? newMaybeDoc : null;\n if (newDoc) {\n debugAssert(\n key.isEqual(newDoc.key),\n 'Mismatching keys found in document changes: ' +\n key +\n ' != ' +\n newDoc.key\n );\n newDoc = this.query.matches(newDoc) ? newDoc : null;\n }\n\n const oldDocHadPendingMutations = oldDoc\n ? this.mutatedKeys.has(oldDoc.key)\n : false;\n const newDocHasPendingMutations = newDoc\n ? newDoc.hasLocalMutations ||\n // We only consider committed mutations for documents that were\n // mutated during the lifetime of the view.\n (this.mutatedKeys.has(newDoc.key) && newDoc.hasCommittedMutations)\n : false;\n\n let changeApplied = false;\n\n // Calculate change\n if (oldDoc && newDoc) {\n const docsEqual = oldDoc.data().isEqual(newDoc.data());\n if (!docsEqual) {\n if (!this.shouldWaitForSyncedDocument(oldDoc, newDoc)) {\n changeSet.track({\n type: ChangeType.Modified,\n doc: newDoc\n });\n changeApplied = true;\n\n if (\n (lastDocInLimit &&\n this.query.docComparator(newDoc, lastDocInLimit) > 0) ||\n (firstDocInLimit &&\n this.query.docComparator(newDoc, firstDocInLimit) < 0)\n ) {\n // This doc moved from inside the limit to outside the limit.\n // That means there may be some other doc in the local cache\n // that should be included instead.\n needsRefill = true;\n }\n }\n } else if (oldDocHadPendingMutations !== newDocHasPendingMutations) {\n changeSet.track({ type: ChangeType.Metadata, doc: newDoc });\n changeApplied = true;\n }\n } else if (!oldDoc && newDoc) {\n changeSet.track({ type: ChangeType.Added, doc: newDoc });\n changeApplied = true;\n } else if (oldDoc && !newDoc) {\n changeSet.track({ type: ChangeType.Removed, doc: oldDoc });\n changeApplied = true;\n\n if (lastDocInLimit || firstDocInLimit) {\n // A doc was removed from a full limit query. We'll need to\n // requery from the local cache to see if we know about some other\n // doc that should be in the results.\n needsRefill = true;\n }\n }\n\n if (changeApplied) {\n if (newDoc) {\n newDocumentSet = newDocumentSet.add(newDoc);\n if (newDocHasPendingMutations) {\n newMutatedKeys = newMutatedKeys.add(key);\n } else {\n newMutatedKeys = newMutatedKeys.delete(key);\n }\n } else {\n newDocumentSet = newDocumentSet.delete(key);\n newMutatedKeys = newMutatedKeys.delete(key);\n }\n }\n }\n );\n\n // Drop documents out to meet limit/limitToLast requirement.\n if (this.query.hasLimitToFirst() || this.query.hasLimitToLast()) {\n while (newDocumentSet.size > this.query.limit!) {\n const oldDoc = this.query.hasLimitToFirst()\n ? newDocumentSet.last()\n : newDocumentSet.first();\n newDocumentSet = newDocumentSet.delete(oldDoc!.key);\n newMutatedKeys = newMutatedKeys.delete(oldDoc!.key);\n changeSet.track({ type: ChangeType.Removed, doc: oldDoc! });\n }\n }\n\n debugAssert(\n !needsRefill || !previousChanges,\n 'View was refilled using docs that themselves needed refilling.'\n );\n return {\n documentSet: newDocumentSet,\n changeSet,\n needsRefill,\n mutatedKeys: newMutatedKeys\n };\n }\n\n private shouldWaitForSyncedDocument(\n oldDoc: Document,\n newDoc: Document\n ): boolean {\n // We suppress the initial change event for documents that were modified as\n // part of a write acknowledgment (e.g. when the value of a server transform\n // is applied) as Watch will send us the same document again.\n // By suppressing the event, we only raise two user visible events (one with\n // `hasPendingWrites` and the final state of the document) instead of three\n // (one with `hasPendingWrites`, the modified document with\n // `hasPendingWrites` and the final state of the document).\n return (\n oldDoc.hasLocalMutations &&\n newDoc.hasCommittedMutations &&\n !newDoc.hasLocalMutations\n );\n }\n\n /**\n * Updates the view with the given ViewDocumentChanges and optionally updates\n * limbo docs and sync state from the provided target change.\n * @param docChanges The set of changes to make to the view's docs.\n * @param updateLimboDocuments Whether to update limbo documents based on this\n * change.\n * @param targetChange A target change to apply for computing limbo docs and\n * sync state.\n * @return A new ViewChange with the given docs, changes, and sync state.\n */\n // PORTING NOTE: The iOS/Android clients always compute limbo document changes.\n applyChanges(\n docChanges: ViewDocumentChanges,\n updateLimboDocuments: boolean,\n targetChange?: TargetChange\n ): ViewChange {\n debugAssert(\n !docChanges.needsRefill,\n 'Cannot apply changes that need a refill'\n );\n const oldDocs = this.documentSet;\n this.documentSet = docChanges.documentSet;\n this.mutatedKeys = docChanges.mutatedKeys;\n // Sort changes based on type and query comparator\n const changes = docChanges.changeSet.getChanges();\n changes.sort((c1, c2) => {\n return (\n compareChangeType(c1.type, c2.type) ||\n this.query.docComparator(c1.doc, c2.doc)\n );\n });\n\n this.applyTargetChange(targetChange);\n const limboChanges = updateLimboDocuments\n ? this.updateLimboDocuments()\n : [];\n const synced = this.limboDocuments.size === 0 && this.current;\n const newSyncState = synced ? SyncState.Synced : SyncState.Local;\n const syncStateChanged = newSyncState !== this.syncState;\n this.syncState = newSyncState;\n\n if (changes.length === 0 && !syncStateChanged) {\n // no changes\n return { limboChanges };\n } else {\n const snap: ViewSnapshot = new ViewSnapshot(\n this.query,\n docChanges.documentSet,\n oldDocs,\n changes,\n docChanges.mutatedKeys,\n newSyncState === SyncState.Local,\n syncStateChanged,\n /* excludesMetadataChanges= */ false\n );\n return {\n snapshot: snap,\n limboChanges\n };\n }\n }\n\n /**\n * Applies an OnlineState change to the view, potentially generating a\n * ViewChange if the view's syncState changes as a result.\n */\n applyOnlineStateChange(onlineState: OnlineState): ViewChange {\n if (this.current && onlineState === OnlineState.Offline) {\n // If we're offline, set `current` to false and then call applyChanges()\n // to refresh our syncState and generate a ViewChange as appropriate. We\n // are guaranteed to get a new TargetChange that sets `current` back to\n // true once the client is back online.\n this.current = false;\n return this.applyChanges(\n {\n documentSet: this.documentSet,\n changeSet: new DocumentChangeSet(),\n mutatedKeys: this.mutatedKeys,\n needsRefill: false\n },\n /* updateLimboDocuments= */ false\n );\n } else {\n // No effect, just return a no-op ViewChange.\n return { limboChanges: [] };\n }\n }\n\n /**\n * Returns whether the doc for the given key should be in limbo.\n */\n private shouldBeInLimbo(key: DocumentKey): boolean {\n // If the remote end says it's part of this query, it's not in limbo.\n if (this._syncedDocuments.has(key)) {\n return false;\n }\n // The local store doesn't think it's a result, so it shouldn't be in limbo.\n if (!this.documentSet.has(key)) {\n return false;\n }\n // If there are local changes to the doc, they might explain why the server\n // doesn't know that it's part of the query. So don't put it in limbo.\n // TODO(klimt): Ideally, we would only consider changes that might actually\n // affect this specific query.\n if (this.documentSet.get(key)!.hasLocalMutations) {\n return false;\n }\n // Everything else is in limbo.\n return true;\n }\n\n /**\n * Updates syncedDocuments, current, and limbo docs based on the given change.\n * Returns the list of changes to which docs are in limbo.\n */\n private applyTargetChange(targetChange?: TargetChange): void {\n if (targetChange) {\n targetChange.addedDocuments.forEach(\n key => (this._syncedDocuments = this._syncedDocuments.add(key))\n );\n targetChange.modifiedDocuments.forEach(key => {\n debugAssert(\n this._syncedDocuments.has(key),\n `Modified document ${key} not found in view.`\n );\n });\n targetChange.removedDocuments.forEach(\n key => (this._syncedDocuments = this._syncedDocuments.delete(key))\n );\n this.current = targetChange.current;\n }\n }\n\n private updateLimboDocuments(): LimboDocumentChange[] {\n // We can only determine limbo documents when we're in-sync with the server.\n if (!this.current) {\n return [];\n }\n\n // TODO(klimt): Do this incrementally so that it's not quadratic when\n // updating many documents.\n const oldLimboDocuments = this.limboDocuments;\n this.limboDocuments = documentKeySet();\n this.documentSet.forEach(doc => {\n if (this.shouldBeInLimbo(doc.key)) {\n this.limboDocuments = this.limboDocuments.add(doc.key);\n }\n });\n\n // Diff the new limbo docs with the old limbo docs.\n const changes: LimboDocumentChange[] = [];\n oldLimboDocuments.forEach(key => {\n if (!this.limboDocuments.has(key)) {\n changes.push(new RemovedLimboDocument(key));\n }\n });\n this.limboDocuments.forEach(key => {\n if (!oldLimboDocuments.has(key)) {\n changes.push(new AddedLimboDocument(key));\n }\n });\n return changes;\n }\n\n /**\n * Update the in-memory state of the current view with the state read from\n * persistence.\n *\n * We update the query view whenever a client's primary status changes:\n * - When a client transitions from primary to secondary, it can miss\n * LocalStorage updates and its query views may temporarily not be\n * synchronized with the state on disk.\n * - For secondary to primary transitions, the client needs to update the list\n * of `syncedDocuments` since secondary clients update their query views\n * based purely on synthesized RemoteEvents.\n *\n * @param queryResult.documents - The documents that match the query according\n * to the LocalStore.\n * @param queryResult.remoteKeys - The keys of the documents that match the\n * query according to the backend.\n *\n * @return The ViewChange that resulted from this synchronization.\n */\n // PORTING NOTE: Multi-tab only.\n synchronizeWithPersistedState(queryResult: QueryResult): ViewChange {\n this._syncedDocuments = queryResult.remoteKeys;\n this.limboDocuments = documentKeySet();\n const docChanges = this.computeDocChanges(queryResult.documents);\n return this.applyChanges(docChanges, /*updateLimboDocuments=*/ true);\n }\n\n /**\n * Returns a view snapshot as if this query was just listened to. Contains\n * a document add for every existing document and the `fromCache` and\n * `hasPendingWrites` status of the already established view.\n */\n // PORTING NOTE: Multi-tab only.\n computeInitialSnapshot(): ViewSnapshot {\n return ViewSnapshot.fromInitialDocuments(\n this.query,\n this.documentSet,\n this.mutatedKeys,\n this.syncState === SyncState.Local\n );\n }\n}\n\nfunction compareChangeType(c1: ChangeType, c2: ChangeType): number {\n const order = (change: ChangeType): 0 | 1 | 2 => {\n switch (change) {\n case ChangeType.Added:\n return 1;\n case ChangeType.Modified:\n return 2;\n case ChangeType.Metadata:\n // A metadata change is converted to a modified change at the public\n // api layer. Since we sort by document key and then change type,\n // metadata and modified changes must be sorted equivalently.\n return 2;\n case ChangeType.Removed:\n return 0;\n default:\n return fail('Unknown ChangeType: ' + change);\n }\n };\n\n return order(c1) - order(c2);\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 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 { debugAssert, fail } from './assert';\nimport { Code, FirestoreError } from './error';\nimport { logDebug, logError } from './log';\nimport { Deferred } from './promise';\nimport { ExponentialBackoff } from '../remote/backoff';\nimport { PlatformSupport } from '../platform/platform';\nimport { isIndexedDbTransactionError } from '../local/simple_db';\n\nconst LOG_TAG = 'AsyncQueue';\n\n// Accept any return type from setTimeout().\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 4 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.\n */\n ListenStreamIdle = 'listen_stream_idle',\n ListenStreamConnectionBackoff = 'listen_stream_connection_backoff',\n WriteStreamIdle = 'write_stream_idle',\n WriteStreamConnectionBackoff = 'write_stream_connection_backoff',\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/**\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 /**\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 class AsyncQueue {\n // The last promise in the queue.\n private tail: Promise<unknown> = Promise.resolve();\n\n // The last retryable operation. Retryable operation are run in order and\n // retried with backoff.\n private retryableTail: Promise<void> = Promise.resolve();\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: Error | 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 // 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 => this.backoff.skipBackoff();\n\n constructor() {\n const window = PlatformSupport.getPlatform().window;\n if (window && typeof window.addEventListener === 'function') {\n window.addEventListener('visibilitychange', this.visibilityHandler);\n }\n }\n\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 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 /**\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 enqueueAndForgetEvenAfterShutdown<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 /**\n * Regardless if the queue has initialized shutdown, adds a new operation to the\n * queue.\n */\n private enqueueEvenAfterShutdown<T extends unknown>(\n op: () => Promise<T>\n ): Promise<T> {\n this.verifyNotFailed();\n return this.enqueueInternal(op);\n }\n\n /**\n * Adds a new operation to the queue and initialize the shut down of this queue.\n * Returns a promise that will be resolved when the promise returned by the new\n * operation is (with its value).\n * Once this method is called, the only possible way to request running an operation\n * is through `enqueueAndForgetEvenAfterShutdown`.\n */\n async enqueueAndInitiateShutdown(op: () => Promise<void>): Promise<void> {\n this.verifyNotFailed();\n if (!this._isShuttingDown) {\n this._isShuttingDown = true;\n const window = PlatformSupport.getPlatform().window;\n if (window) {\n window.removeEventListener('visibilitychange', this.visibilityHandler);\n }\n await this.enqueueEvenAfterShutdown(op);\n }\n }\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 this.verifyNotFailed();\n if (this._isShuttingDown) {\n // Return a Promise which never resolves.\n return new Promise<T>(resolve => {});\n }\n return this.enqueueInternal(op);\n }\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 this.verifyNotFailed();\n\n if (this._isShuttingDown) {\n return;\n }\n\n this.retryableTail = this.retryableTail.then(() => {\n const deferred = new Deferred<void>();\n const retryingOp = async (): Promise<void> => {\n try {\n await op();\n deferred.resolve();\n this.backoff.reset();\n } catch (e) {\n if (isIndexedDbTransactionError(e)) {\n logDebug(LOG_TAG, 'Operation failed with retryable error: ' + e);\n this.backoff.backoffAndRun(retryingOp);\n } else {\n deferred.resolve();\n throw e; // Failure will be handled by AsyncQueue\n }\n }\n };\n this.enqueueAndForget(retryingOp);\n return deferred.promise;\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 = error.stack || error.message || '';\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 /**\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 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 overriden.\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(\n 'AsyncQueue is already failed: ' +\n (this.failure.stack || this.failure.message)\n );\n }\n }\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 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 will\n * 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 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 this.delayedOperations.splice(index, 1);\n }\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 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 { fail } from '../util/assert';\nimport { Code } from '../util/error';\nimport { logError } from '../util/log';\n\n/**\n * Error Codes describing the different ways GRPC can fail. These are copied\n * directly from GRPC's sources here:\n *\n * https://github.com/grpc/grpc/blob/bceec94ea4fc5f0085d81235d8e1c06798dc341a/include/grpc%2B%2B/impl/codegen/status_code_enum.h\n *\n * Important! The names of these identifiers matter because the string forms\n * are used for reverse lookups from the webchannel stream. Do NOT change the\n * names of these identifiers or change this into a const enum.\n */\nenum RpcCode {\n OK = 0,\n CANCELLED = 1,\n UNKNOWN = 2,\n INVALID_ARGUMENT = 3,\n DEADLINE_EXCEEDED = 4,\n NOT_FOUND = 5,\n ALREADY_EXISTS = 6,\n PERMISSION_DENIED = 7,\n UNAUTHENTICATED = 16,\n RESOURCE_EXHAUSTED = 8,\n FAILED_PRECONDITION = 9,\n ABORTED = 10,\n OUT_OF_RANGE = 11,\n UNIMPLEMENTED = 12,\n INTERNAL = 13,\n UNAVAILABLE = 14,\n DATA_LOSS = 15\n}\n\n/**\n * Determines whether an error code represents a permanent error when received\n * in response to a non-write operation.\n *\n * See isPermanentWriteError for classifying write errors.\n */\nexport function isPermanentError(code: Code): boolean {\n switch (code) {\n case Code.OK:\n return fail('Treated status OK as error');\n case Code.CANCELLED:\n case Code.UNKNOWN:\n case Code.DEADLINE_EXCEEDED:\n case Code.RESOURCE_EXHAUSTED:\n case Code.INTERNAL:\n case Code.UNAVAILABLE:\n // Unauthenticated means something went wrong with our token and we need\n // to retry with new credentials which will happen automatically.\n case Code.UNAUTHENTICATED:\n return false;\n case Code.INVALID_ARGUMENT:\n case Code.NOT_FOUND:\n case Code.ALREADY_EXISTS:\n case Code.PERMISSION_DENIED:\n case Code.FAILED_PRECONDITION:\n // Aborted might be retried in some scenarios, but that is dependant on\n // the context and should handled individually by the calling code.\n // See https://cloud.google.com/apis/design/errors.\n case Code.ABORTED:\n case Code.OUT_OF_RANGE:\n case Code.UNIMPLEMENTED:\n case Code.DATA_LOSS:\n return true;\n default:\n return fail('Unknown status code: ' + code);\n }\n}\n\n/**\n * Determines whether an error code represents a permanent error when received\n * in response to a write operation.\n *\n * Write operations must be handled specially because as of b/119437764, ABORTED\n * errors on the write stream should be retried too (even though ABORTED errors\n * are not generally retryable).\n *\n * Note that during the initial handshake on the write stream an ABORTED error\n * signals that we should discard our stream token (i.e. it is permanent). This\n * means a handshake error should be classified with isPermanentError, above.\n */\nexport function isPermanentWriteError(code: Code): boolean {\n return isPermanentError(code) && code !== Code.ABORTED;\n}\n\n/**\n * Maps an error Code from a GRPC status identifier like 'NOT_FOUND'.\n *\n * @returns The Code equivalent to the given status string or undefined if\n * there is no match.\n */\nexport function mapCodeFromRpcStatus(status: string): Code | undefined {\n // lookup by string\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const code: RpcCode = RpcCode[status as any] as any;\n if (code === undefined) {\n return undefined;\n }\n\n return mapCodeFromRpcCode(code);\n}\n\n/**\n * Maps an error Code from GRPC status code number, like 0, 1, or 14. These\n * are not the same as HTTP status codes.\n *\n * @returns The Code equivalent to the given GRPC status code. Fails if there\n * is no match.\n */\nexport function mapCodeFromRpcCode(code: number | undefined): Code {\n if (code === undefined) {\n // This shouldn't normally happen, but in certain error cases (like trying\n // to send invalid proto messages) we may get an error with no GRPC code.\n logError('GRPC error has no .code');\n return Code.UNKNOWN;\n }\n\n switch (code) {\n case RpcCode.OK:\n return Code.OK;\n case RpcCode.CANCELLED:\n return Code.CANCELLED;\n case RpcCode.UNKNOWN:\n return Code.UNKNOWN;\n case RpcCode.DEADLINE_EXCEEDED:\n return Code.DEADLINE_EXCEEDED;\n case RpcCode.RESOURCE_EXHAUSTED:\n return Code.RESOURCE_EXHAUSTED;\n case RpcCode.INTERNAL:\n return Code.INTERNAL;\n case RpcCode.UNAVAILABLE:\n return Code.UNAVAILABLE;\n case RpcCode.UNAUTHENTICATED:\n return Code.UNAUTHENTICATED;\n case RpcCode.INVALID_ARGUMENT:\n return Code.INVALID_ARGUMENT;\n case RpcCode.NOT_FOUND:\n return Code.NOT_FOUND;\n case RpcCode.ALREADY_EXISTS:\n return Code.ALREADY_EXISTS;\n case RpcCode.PERMISSION_DENIED:\n return Code.PERMISSION_DENIED;\n case RpcCode.FAILED_PRECONDITION:\n return Code.FAILED_PRECONDITION;\n case RpcCode.ABORTED:\n return Code.ABORTED;\n case RpcCode.OUT_OF_RANGE:\n return Code.OUT_OF_RANGE;\n case RpcCode.UNIMPLEMENTED:\n return Code.UNIMPLEMENTED;\n case RpcCode.DATA_LOSS:\n return Code.DATA_LOSS;\n default:\n return fail('Unknown status code: ' + code);\n }\n}\n\n/**\n * Maps an RPC code from a Code. This is the reverse operation from\n * mapCodeFromRpcCode and should really only be used in tests.\n */\nexport function mapRpcCodeFromCode(code: Code | undefined): number {\n if (code === undefined) {\n return RpcCode.OK;\n }\n\n switch (code) {\n case Code.OK:\n return RpcCode.OK;\n case Code.CANCELLED:\n return RpcCode.CANCELLED;\n case Code.UNKNOWN:\n return RpcCode.UNKNOWN;\n case Code.DEADLINE_EXCEEDED:\n return RpcCode.DEADLINE_EXCEEDED;\n case Code.RESOURCE_EXHAUSTED:\n return RpcCode.RESOURCE_EXHAUSTED;\n case Code.INTERNAL:\n return RpcCode.INTERNAL;\n case Code.UNAVAILABLE:\n return RpcCode.UNAVAILABLE;\n case Code.UNAUTHENTICATED:\n return RpcCode.UNAUTHENTICATED;\n case Code.INVALID_ARGUMENT:\n return RpcCode.INVALID_ARGUMENT;\n case Code.NOT_FOUND:\n return RpcCode.NOT_FOUND;\n case Code.ALREADY_EXISTS:\n return RpcCode.ALREADY_EXISTS;\n case Code.PERMISSION_DENIED:\n return RpcCode.PERMISSION_DENIED;\n case Code.FAILED_PRECONDITION:\n return RpcCode.FAILED_PRECONDITION;\n case Code.ABORTED:\n return RpcCode.ABORTED;\n case Code.OUT_OF_RANGE:\n return RpcCode.OUT_OF_RANGE;\n case Code.UNIMPLEMENTED:\n return RpcCode.UNIMPLEMENTED;\n case Code.DATA_LOSS:\n return RpcCode.DATA_LOSS;\n default:\n return fail('Unknown status code: ' + code);\n }\n}\n\n/**\n * Converts an HTTP Status Code to the equivalent error code.\n *\n * @param status An HTTP Status Code, like 200, 404, 503, etc.\n * @returns The equivalent Code. Unknown status codes are mapped to\n * Code.UNKNOWN.\n */\nexport function mapCodeFromHttpStatus(status: number): Code {\n // The canonical error codes for Google APIs [1] specify mapping onto HTTP\n // status codes but the mapping is not bijective. In each case of ambiguity\n // this function chooses a primary error.\n //\n // [1]\n // https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto\n switch (status) {\n case 200: // OK\n return Code.OK;\n\n case 400: // Bad Request\n return Code.INVALID_ARGUMENT;\n // Other possibilities based on the forward mapping\n // return Code.FAILED_PRECONDITION;\n // return Code.OUT_OF_RANGE;\n\n case 401: // Unauthorized\n return Code.UNAUTHENTICATED;\n\n case 403: // Forbidden\n return Code.PERMISSION_DENIED;\n\n case 404: // Not Found\n return Code.NOT_FOUND;\n\n case 409: // Conflict\n return Code.ABORTED;\n // Other possibilities:\n // return Code.ALREADY_EXISTS;\n\n case 416: // Range Not Satisfiable\n return Code.OUT_OF_RANGE;\n\n case 429: // Too Many Requests\n return Code.RESOURCE_EXHAUSTED;\n\n case 499: // Client Closed Request\n return Code.CANCELLED;\n\n case 500: // Internal Server Error\n return Code.UNKNOWN;\n // Other possibilities:\n // return Code.INTERNAL;\n // return Code.DATA_LOSS;\n\n case 501: // Unimplemented\n return Code.UNIMPLEMENTED;\n\n case 503: // Service Unavailable\n return Code.UNAVAILABLE;\n\n case 504: // Gateway Timeout\n return Code.DEADLINE_EXCEEDED;\n\n default:\n if (status >= 200 && status < 300) {\n return Code.OK;\n }\n if (status >= 400 && status < 500) {\n return Code.FAILED_PRECONDITION;\n }\n if (status >= 500 && status < 600) {\n return Code.INTERNAL;\n }\n return Code.UNKNOWN;\n }\n}\n\n/**\n * Converts an HTTP response's error status to the equivalent error code.\n *\n * @param status An HTTP error response status (\"FAILED_PRECONDITION\",\n * \"UNKNOWN\", etc.)\n * @returns The equivalent Code. Non-matching responses are mapped to\n * Code.UNKNOWN.\n */\nexport function mapCodeFromHttpResponseErrorStatus(status: string): Code {\n const serverError = status.toLowerCase().replace('_', '-');\n return Object.values(Code).indexOf(serverError as Code) >= 0\n ? (serverError as Code)\n : Code.UNKNOWN;\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 { Deferred } from '../util/promise';\nimport { TimerId, AsyncQueue } from '../util/async_queue';\nimport { ExponentialBackoff } from '../remote/backoff';\nimport { Transaction } from './transaction';\nimport { RemoteStore } from '../remote/remote_store';\nimport { isNullOrUndefined } from '../util/types';\nimport { isPermanentError } from '../remote/rpc_error';\nimport { FirestoreError } from '../util/error';\n\nconst RETRY_COUNT = 5;\n\n/**\n * TransactionRunner encapsulates the logic needed to run and retry transactions\n * with backoff.\n */\nexport class TransactionRunner<T> {\n private retries = RETRY_COUNT;\n private backoff: ExponentialBackoff;\n\n constructor(\n private readonly asyncQueue: AsyncQueue,\n private readonly remoteStore: RemoteStore,\n private readonly updateFunction: (transaction: Transaction) => Promise<T>,\n private readonly deferred: Deferred<T>\n ) {\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.runWithBackOff();\n }\n\n private runWithBackOff(): void {\n this.backoff.backoffAndRun(async () => {\n const transaction = this.remoteStore.createTransaction();\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);\n return null;\n }\n }\n\n private handleTransactionError(error: Error): void {\n if (this.retries > 0 && this.isRetryableTransactionError(error)) {\n this.retries -= 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): 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 !isPermanentError(code)\n );\n }\n return false;\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 { User } from '../auth/user';\nimport {\n ignoreIfPrimaryLeaseLoss,\n LocalStore,\n MultiTabLocalStore\n} from '../local/local_store';\nimport { LocalViewChanges } from '../local/local_view_changes';\nimport { ReferenceSet } from '../local/reference_set';\nimport { TargetData, TargetPurpose } from '../local/target_data';\nimport {\n documentKeySet,\n DocumentKeySet,\n MaybeDocumentMap\n} from '../model/collections';\nimport { MaybeDocument, NoDocument } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport { Mutation } from '../model/mutation';\nimport { BATCHID_UNKNOWN, MutationBatchResult } from '../model/mutation_batch';\nimport { RemoteEvent, TargetChange } from '../remote/remote_event';\nimport { RemoteStore } from '../remote/remote_store';\nimport { RemoteSyncer } from '../remote/remote_syncer';\nimport { debugAssert, fail, hardAssert } from '../util/assert';\nimport { Code, FirestoreError } from '../util/error';\nimport { logDebug } from '../util/log';\nimport { primitiveComparator } from '../util/misc';\nimport { ObjectMap } from '../util/obj_map';\nimport { Deferred } from '../util/promise';\nimport { SortedMap } from '../util/sorted_map';\n\nimport { ClientId, SharedClientState } from '../local/shared_client_state';\nimport {\n QueryTargetState,\n SharedClientStateSyncer\n} from '../local/shared_client_state_syncer';\nimport { SortedSet } from '../util/sorted_set';\nimport { ListenSequence } from './listen_sequence';\nimport { LimitType, Query } from './query';\nimport { SnapshotVersion } from './snapshot_version';\nimport { Target } from './target';\nimport { TargetIdGenerator } from './target_id_generator';\nimport { Transaction } from './transaction';\nimport {\n BatchId,\n MutationBatchState,\n OnlineState,\n OnlineStateSource,\n TargetId\n} from './types';\nimport {\n AddedLimboDocument,\n LimboDocumentChange,\n RemovedLimboDocument,\n View,\n ViewChange,\n ViewDocumentChanges\n} from './view';\nimport { ViewSnapshot } from './view_snapshot';\nimport { AsyncQueue, wrapInUserErrorIfRecoverable } from '../util/async_queue';\nimport { TransactionRunner } from './transaction_runner';\n\nconst LOG_TAG = 'SyncEngine';\n\n/**\n * QueryView contains all of the data that SyncEngine needs to keep track of for\n * a particular query.\n */\nclass QueryView {\n constructor(\n /**\n * The query itself.\n */\n public query: Query,\n /**\n * The target number created by the client that is used in the watch\n * stream to identify this query.\n */\n public targetId: TargetId,\n /**\n * The view is responsible for computing the final merged truth of what\n * docs are in the query. It gets notified of local and remote changes,\n * and applies the query filters and limits to determine the most correct\n * possible results.\n */\n public view: View\n ) {}\n}\n\n/** Tracks a limbo resolution. */\nclass LimboResolution {\n constructor(public key: DocumentKey) {}\n\n /**\n * Set to true once we've received a document. This is used in\n * getRemoteKeysForTarget() and ultimately used by WatchChangeAggregator to\n * decide whether it needs to manufacture a delete event for the target once\n * the target is CURRENT.\n */\n receivedDocument: boolean = false;\n}\n\n/**\n * Interface implemented by EventManager to handle notifications from\n * SyncEngine.\n */\nexport interface SyncEngineListener {\n /** Handles new view snapshots. */\n onWatchChange(snapshots: ViewSnapshot[]): void;\n\n /** Handles the failure of a query. */\n onWatchError(query: Query, error: Error): void;\n\n /** Handles a change in online state. */\n onOnlineStateChange(onlineState: OnlineState): void;\n}\n\n/**\n * SyncEngine is the central controller in the client SDK architecture. It is\n * the glue code between the EventManager, LocalStore, and RemoteStore. Some of\n * SyncEngine's responsibilities include:\n * 1. Coordinating client requests and remote events between the EventManager\n * and the local and remote data stores.\n * 2. Managing a View object for each query, providing the unified view between\n * the local and remote data stores.\n * 3. Notifying the RemoteStore when the LocalStore has new mutations in its\n * queue that need sending to the backend.\n *\n * The SyncEngine’s methods should only ever be called by methods running in the\n * global async queue.\n */\nexport class SyncEngine implements RemoteSyncer {\n protected syncEngineListener: SyncEngineListener | null = null;\n\n protected queryViewsByQuery = new ObjectMap<Query, QueryView>(q =>\n q.canonicalId()\n );\n protected queriesByTarget = new Map<TargetId, Query[]>();\n /**\n * The keys of documents that are in limbo for which we haven't yet started a\n * limbo resolution query.\n */\n private enqueuedLimboResolutions: DocumentKey[] = [];\n /**\n * Keeps track of the target ID for each document that is in limbo with an\n * active target.\n */\n protected activeLimboTargetsByKey = new SortedMap<DocumentKey, TargetId>(\n DocumentKey.comparator\n );\n /**\n * Keeps track of the information about an active limbo resolution for each\n * active target ID that was started for the purpose of limbo resolution.\n */\n protected activeLimboResolutionsByTarget = new Map<\n TargetId,\n LimboResolution\n >();\n protected limboDocumentRefs = new ReferenceSet();\n /** Stores user completion handlers, indexed by User and BatchId. */\n private mutationUserCallbacks = {} as {\n [uidKey: string]: SortedMap<BatchId, Deferred<void>>;\n };\n /** Stores user callbacks waiting for all pending writes to be acknowledged. */\n private pendingWritesCallbacks = new Map<BatchId, Array<Deferred<void>>>();\n private limboTargetIdGenerator = TargetIdGenerator.forSyncEngine();\n\n private onlineState = OnlineState.Unknown;\n\n constructor(\n protected localStore: LocalStore,\n protected remoteStore: RemoteStore,\n // PORTING NOTE: Manages state synchronization in multi-tab environments.\n protected sharedClientState: SharedClientState,\n private currentUser: User,\n private maxConcurrentLimboResolutions: number\n ) {}\n\n get isPrimaryClient(): boolean {\n return true;\n }\n\n /** Subscribes to SyncEngine notifications. Has to be called exactly once. */\n subscribe(syncEngineListener: SyncEngineListener): void {\n debugAssert(\n syncEngineListener !== null,\n 'SyncEngine listener cannot be null'\n );\n debugAssert(\n this.syncEngineListener === null,\n 'SyncEngine already has a subscriber.'\n );\n\n this.syncEngineListener = syncEngineListener;\n }\n\n /**\n * Initiates the new listen, resolves promise when listen enqueued to the\n * server. All the subsequent view snapshots or errors are sent to the\n * subscribed handlers. Returns the initial snapshot.\n */\n async listen(query: Query): Promise<ViewSnapshot> {\n this.assertSubscribed('listen()');\n\n let targetId;\n let viewSnapshot;\n\n const queryView = this.queryViewsByQuery.get(query);\n if (queryView) {\n // PORTING NOTE: With Multi-Tab Web, it is possible that a query view\n // already exists when EventManager calls us for the first time. This\n // happens when the primary tab is already listening to this query on\n // behalf of another tab and the user of the primary also starts listening\n // to the query. EventManager will not have an assigned target ID in this\n // case and calls `listen` to obtain this ID.\n targetId = queryView.targetId;\n this.sharedClientState.addLocalQueryTarget(targetId);\n viewSnapshot = queryView.view.computeInitialSnapshot();\n } else {\n const targetData = await this.localStore.allocateTarget(query.toTarget());\n\n const status = this.sharedClientState.addLocalQueryTarget(\n targetData.targetId\n );\n targetId = targetData.targetId;\n viewSnapshot = await this.initializeViewAndComputeSnapshot(\n query,\n targetId,\n status === 'current'\n );\n if (this.isPrimaryClient) {\n this.remoteStore.listen(targetData);\n }\n }\n\n return viewSnapshot;\n }\n\n /**\n * Registers a view for a previously unknown query and computes its initial\n * snapshot.\n */\n protected async initializeViewAndComputeSnapshot(\n query: Query,\n targetId: TargetId,\n current: boolean\n ): Promise<ViewSnapshot> {\n const queryResult = await this.localStore.executeQuery(\n query,\n /* usePreviousResults= */ true\n );\n const view = new View(query, queryResult.remoteKeys);\n const viewDocChanges = view.computeDocChanges(queryResult.documents);\n const synthesizedTargetChange = TargetChange.createSynthesizedTargetChangeForCurrentChange(\n targetId,\n current && this.onlineState !== OnlineState.Offline\n );\n const viewChange = view.applyChanges(\n viewDocChanges,\n /* updateLimboDocuments= */ this.isPrimaryClient,\n synthesizedTargetChange\n );\n this.updateTrackedLimbos(targetId, viewChange.limboChanges);\n\n debugAssert(\n !!viewChange.snapshot,\n 'applyChanges for new view should always return a snapshot'\n );\n\n const data = new QueryView(query, targetId, view);\n this.queryViewsByQuery.set(query, data);\n if (this.queriesByTarget.has(targetId)) {\n this.queriesByTarget.get(targetId)!.push(query);\n } else {\n this.queriesByTarget.set(targetId, [query]);\n }\n return viewChange.snapshot!;\n }\n\n /** Stops listening to the query. */\n async unlisten(query: Query): Promise<void> {\n this.assertSubscribed('unlisten()');\n\n const queryView = this.queryViewsByQuery.get(query)!;\n debugAssert(!!queryView, 'Trying to unlisten on query not found:' + query);\n\n // Only clean up the query view and target if this is the only query mapped\n // to the target.\n const queries = this.queriesByTarget.get(queryView.targetId)!;\n if (queries.length > 1) {\n this.queriesByTarget.set(\n queryView.targetId,\n queries.filter(q => !q.isEqual(query))\n );\n this.queryViewsByQuery.delete(query);\n return;\n }\n\n // No other queries are mapped to the target, clean up the query and the target.\n if (this.isPrimaryClient) {\n // We need to remove the local query target first to allow us to verify\n // whether any other client is still interested in this target.\n this.sharedClientState.removeLocalQueryTarget(queryView.targetId);\n const targetRemainsActive = this.sharedClientState.isActiveQueryTarget(\n queryView.targetId\n );\n\n if (!targetRemainsActive) {\n await this.localStore\n .releaseTarget(queryView.targetId, /*keepPersistedTargetData=*/ false)\n .then(() => {\n this.sharedClientState.clearQueryState(queryView.targetId);\n this.remoteStore.unlisten(queryView.targetId);\n this.removeAndCleanupTarget(queryView.targetId);\n })\n .catch(ignoreIfPrimaryLeaseLoss);\n }\n } else {\n this.removeAndCleanupTarget(queryView.targetId);\n await this.localStore.releaseTarget(\n queryView.targetId,\n /*keepPersistedTargetData=*/ true\n );\n }\n }\n\n /**\n * Initiates the write of local mutation batch which involves adding the\n * writes to the mutation queue, notifying the remote store about new\n * mutations and raising events for any changes this write caused.\n *\n * The promise returned by this call is resolved when the above steps\n * have completed, *not* when the write was acked by the backend. The\n * userCallback is resolved once the write was acked/rejected by the\n * backend (or failed locally for any other reason).\n */\n async write(batch: Mutation[], userCallback: Deferred<void>): Promise<void> {\n this.assertSubscribed('write()');\n\n try {\n const result = await this.localStore.localWrite(batch);\n this.sharedClientState.addPendingMutation(result.batchId);\n this.addMutationCallback(result.batchId, userCallback);\n await this.emitNewSnapsAndNotifyLocalStore(result.changes);\n await this.remoteStore.fillWritePipeline();\n } catch (e) {\n // If we can't persist the mutation, we reject the user callback and\n // don't send the mutation. The user can then retry the write.\n const error = wrapInUserErrorIfRecoverable(e, `Failed to persist write`);\n userCallback.reject(error);\n }\n }\n\n /**\n * Takes an updateFunction in which a set of reads and writes can be performed\n * atomically. In the updateFunction, the client can read and write values\n * using the supplied transaction object. After the updateFunction, all\n * changes will be committed. If a retryable error occurs (ex: some other\n * client has changed any of the data referenced), then the updateFunction\n * will be called again after a backoff. If the updateFunction still fails\n * after all retries, then the transaction will be rejected.\n *\n * The transaction object passed to the updateFunction contains methods for\n * accessing documents and collections. Unlike other datastore access, data\n * accessed with the transaction will not reflect local changes that have not\n * been committed. For this reason, it is required that all reads are\n * performed before any writes. Transactions must be performed while online.\n *\n * The Deferred input is resolved when the transaction is fully committed.\n */\n runTransaction<T>(\n asyncQueue: AsyncQueue,\n updateFunction: (transaction: Transaction) => Promise<T>,\n deferred: Deferred<T>\n ): void {\n new TransactionRunner<T>(\n asyncQueue,\n this.remoteStore,\n updateFunction,\n deferred\n ).run();\n }\n\n async applyRemoteEvent(remoteEvent: RemoteEvent): Promise<void> {\n this.assertSubscribed('applyRemoteEvent()');\n try {\n const changes = await this.localStore.applyRemoteEvent(remoteEvent);\n // Update `receivedDocument` as appropriate for any limbo targets.\n remoteEvent.targetChanges.forEach((targetChange, targetId) => {\n const limboResolution = this.activeLimboResolutionsByTarget.get(\n targetId\n );\n if (limboResolution) {\n // Since this is a limbo resolution lookup, it's for a single document\n // and it could be added, modified, or removed, but not a combination.\n hardAssert(\n targetChange.addedDocuments.size +\n targetChange.modifiedDocuments.size +\n targetChange.removedDocuments.size <=\n 1,\n 'Limbo resolution for single document contains multiple changes.'\n );\n if (targetChange.addedDocuments.size > 0) {\n limboResolution.receivedDocument = true;\n } else if (targetChange.modifiedDocuments.size > 0) {\n hardAssert(\n limboResolution.receivedDocument,\n 'Received change for limbo target document without add.'\n );\n } else if (targetChange.removedDocuments.size > 0) {\n hardAssert(\n limboResolution.receivedDocument,\n 'Received remove for limbo target document without add.'\n );\n limboResolution.receivedDocument = false;\n } else {\n // This was probably just a CURRENT targetChange or similar.\n }\n }\n });\n await this.emitNewSnapsAndNotifyLocalStore(changes, remoteEvent);\n } catch (error) {\n await ignoreIfPrimaryLeaseLoss(error);\n }\n }\n\n /**\n * Applies an OnlineState change to the sync engine and notifies any views of\n * the change.\n */\n applyOnlineStateChange(\n onlineState: OnlineState,\n source: OnlineStateSource\n ): void {\n this.assertSubscribed('applyOnlineStateChange()');\n const newViewSnapshots = [] as ViewSnapshot[];\n this.queryViewsByQuery.forEach((query, queryView) => {\n const viewChange = queryView.view.applyOnlineStateChange(onlineState);\n debugAssert(\n viewChange.limboChanges.length === 0,\n 'OnlineState should not affect limbo documents.'\n );\n if (viewChange.snapshot) {\n newViewSnapshots.push(viewChange.snapshot);\n }\n });\n this.syncEngineListener!.onOnlineStateChange(onlineState);\n this.syncEngineListener!.onWatchChange(newViewSnapshots);\n this.onlineState = onlineState;\n }\n\n async rejectListen(targetId: TargetId, err: FirestoreError): Promise<void> {\n this.assertSubscribed('rejectListens()');\n\n // PORTING NOTE: Multi-tab only.\n this.sharedClientState.updateQueryState(targetId, 'rejected', err);\n\n const limboResolution = this.activeLimboResolutionsByTarget.get(targetId);\n const limboKey = limboResolution && limboResolution.key;\n if (limboKey) {\n // TODO(klimt): We really only should do the following on permission\n // denied errors, but we don't have the cause code here.\n\n // It's a limbo doc. Create a synthetic event saying it was deleted.\n // This is kind of a hack. Ideally, we would have a method in the local\n // store to purge a document. However, it would be tricky to keep all of\n // the local store's invariants with another method.\n let documentUpdates = new SortedMap<DocumentKey, MaybeDocument>(\n DocumentKey.comparator\n );\n documentUpdates = documentUpdates.insert(\n limboKey,\n new NoDocument(limboKey, SnapshotVersion.min())\n );\n const resolvedLimboDocuments = documentKeySet().add(limboKey);\n const event = new RemoteEvent(\n SnapshotVersion.min(),\n /* targetChanges= */ new Map<TargetId, TargetChange>(),\n /* targetMismatches= */ new SortedSet<TargetId>(primitiveComparator),\n documentUpdates,\n resolvedLimboDocuments\n );\n\n await this.applyRemoteEvent(event);\n\n // Since this query failed, we won't want to manually unlisten to it.\n // We only remove it from bookkeeping after we successfully applied the\n // RemoteEvent. If `applyRemoteEvent()` throws, we want to re-listen to\n // this query when the RemoteStore restarts the Watch stream, which should\n // re-trigger the target failure.\n this.activeLimboTargetsByKey = this.activeLimboTargetsByKey.remove(\n limboKey\n );\n this.activeLimboResolutionsByTarget.delete(targetId);\n this.pumpEnqueuedLimboResolutions();\n } else {\n await this.localStore\n .releaseTarget(targetId, /* keepPersistedTargetData */ false)\n .then(() => this.removeAndCleanupTarget(targetId, err))\n .catch(ignoreIfPrimaryLeaseLoss);\n }\n }\n\n async applySuccessfulWrite(\n mutationBatchResult: MutationBatchResult\n ): Promise<void> {\n this.assertSubscribed('applySuccessfulWrite()');\n\n const batchId = mutationBatchResult.batch.batchId;\n\n // The local store may or may not be able to apply the write result and\n // raise events immediately (depending on whether the watcher is caught\n // up), so we raise user callbacks first so that they consistently happen\n // before listen events.\n this.processUserCallback(batchId, /*error=*/ null);\n\n this.triggerPendingWritesCallbacks(batchId);\n\n try {\n const changes = await this.localStore.acknowledgeBatch(\n mutationBatchResult\n );\n this.sharedClientState.updateMutationState(batchId, 'acknowledged');\n await this.emitNewSnapsAndNotifyLocalStore(changes);\n } catch (error) {\n await ignoreIfPrimaryLeaseLoss(error);\n }\n }\n\n async rejectFailedWrite(\n batchId: BatchId,\n error: FirestoreError\n ): Promise<void> {\n this.assertSubscribed('rejectFailedWrite()');\n\n // The local store may or may not be able to apply the write result and\n // raise events immediately (depending on whether the watcher is caught up),\n // so we raise user callbacks first so that they consistently happen before\n // listen events.\n this.processUserCallback(batchId, error);\n\n this.triggerPendingWritesCallbacks(batchId);\n\n try {\n const changes = await this.localStore.rejectBatch(batchId);\n this.sharedClientState.updateMutationState(batchId, 'rejected', error);\n await this.emitNewSnapsAndNotifyLocalStore(changes);\n } catch (error) {\n await ignoreIfPrimaryLeaseLoss(error);\n }\n }\n\n /**\n * Registers a user callback that resolves when all pending mutations at the moment of calling\n * are acknowledged .\n */\n async registerPendingWritesCallback(callback: Deferred<void>): Promise<void> {\n if (!this.remoteStore.canUseNetwork()) {\n logDebug(\n LOG_TAG,\n 'The network is disabled. The task returned by ' +\n \"'awaitPendingWrites()' will not complete until the network is enabled.\"\n );\n }\n\n try {\n const highestBatchId = await this.localStore.getHighestUnacknowledgedBatchId();\n if (highestBatchId === BATCHID_UNKNOWN) {\n // Trigger the callback right away if there is no pending writes at the moment.\n callback.resolve();\n return;\n }\n\n const callbacks = this.pendingWritesCallbacks.get(highestBatchId) || [];\n callbacks.push(callback);\n this.pendingWritesCallbacks.set(highestBatchId, callbacks);\n } catch (e) {\n const firestoreError = wrapInUserErrorIfRecoverable(\n e,\n 'Initialization of waitForPendingWrites() operation failed'\n );\n callback.reject(firestoreError);\n }\n }\n\n /**\n * Triggers the callbacks that are waiting for this batch id to get acknowledged by server,\n * if there are any.\n */\n private triggerPendingWritesCallbacks(batchId: BatchId): void {\n (this.pendingWritesCallbacks.get(batchId) || []).forEach(callback => {\n callback.resolve();\n });\n\n this.pendingWritesCallbacks.delete(batchId);\n }\n\n /** Reject all outstanding callbacks waiting for pending writes to complete. */\n private rejectOutstandingPendingWritesCallbacks(errorMessage: string): void {\n this.pendingWritesCallbacks.forEach(callbacks => {\n callbacks.forEach(callback => {\n callback.reject(new FirestoreError(Code.CANCELLED, errorMessage));\n });\n });\n\n this.pendingWritesCallbacks.clear();\n }\n\n private addMutationCallback(\n batchId: BatchId,\n callback: Deferred<void>\n ): void {\n let newCallbacks = this.mutationUserCallbacks[this.currentUser.toKey()];\n if (!newCallbacks) {\n newCallbacks = new SortedMap<BatchId, Deferred<void>>(\n primitiveComparator\n );\n }\n newCallbacks = newCallbacks.insert(batchId, callback);\n this.mutationUserCallbacks[this.currentUser.toKey()] = newCallbacks;\n }\n\n /**\n * Resolves or rejects the user callback for the given batch and then discards\n * it.\n */\n protected processUserCallback(batchId: BatchId, error: Error | null): void {\n let newCallbacks = this.mutationUserCallbacks[this.currentUser.toKey()];\n\n // NOTE: Mutations restored from persistence won't have callbacks, so it's\n // okay for there to be no callback for this ID.\n if (newCallbacks) {\n const callback = newCallbacks.get(batchId);\n if (callback) {\n debugAssert(\n batchId === newCallbacks.minKey(),\n 'Mutation callbacks processed out-of-order?'\n );\n if (error) {\n callback.reject(error);\n } else {\n callback.resolve();\n }\n newCallbacks = newCallbacks.remove(batchId);\n }\n this.mutationUserCallbacks[this.currentUser.toKey()] = newCallbacks;\n }\n }\n\n protected removeAndCleanupTarget(\n targetId: number,\n error: Error | null = null\n ): void {\n this.sharedClientState.removeLocalQueryTarget(targetId);\n\n debugAssert(\n this.queriesByTarget.has(targetId) &&\n this.queriesByTarget.get(targetId)!.length !== 0,\n `There are no queries mapped to target id ${targetId}`\n );\n\n for (const query of this.queriesByTarget.get(targetId)!) {\n this.queryViewsByQuery.delete(query);\n if (error) {\n this.syncEngineListener!.onWatchError(query, error);\n }\n }\n\n this.queriesByTarget.delete(targetId);\n\n if (this.isPrimaryClient) {\n const limboKeys = this.limboDocumentRefs.removeReferencesForId(targetId);\n limboKeys.forEach(limboKey => {\n const isReferenced = this.limboDocumentRefs.containsKey(limboKey);\n if (!isReferenced) {\n // We removed the last reference for this key\n this.removeLimboTarget(limboKey);\n }\n });\n }\n }\n\n private removeLimboTarget(key: DocumentKey): void {\n // It's possible that the target already got removed because the query failed. In that case,\n // the key won't exist in `limboTargetsByKey`. Only do the cleanup if we still have the target.\n const limboTargetId = this.activeLimboTargetsByKey.get(key);\n if (limboTargetId === null) {\n // This target already got removed, because the query failed.\n return;\n }\n\n this.remoteStore.unlisten(limboTargetId);\n this.activeLimboTargetsByKey = this.activeLimboTargetsByKey.remove(key);\n this.activeLimboResolutionsByTarget.delete(limboTargetId);\n this.pumpEnqueuedLimboResolutions();\n }\n\n protected updateTrackedLimbos(\n targetId: TargetId,\n limboChanges: LimboDocumentChange[]\n ): void {\n for (const limboChange of limboChanges) {\n if (limboChange instanceof AddedLimboDocument) {\n this.limboDocumentRefs.addReference(limboChange.key, targetId);\n this.trackLimboChange(limboChange);\n } else if (limboChange instanceof RemovedLimboDocument) {\n logDebug(LOG_TAG, 'Document no longer in limbo: ' + limboChange.key);\n this.limboDocumentRefs.removeReference(limboChange.key, targetId);\n const isReferenced = this.limboDocumentRefs.containsKey(\n limboChange.key\n );\n if (!isReferenced) {\n // We removed the last reference for this key\n this.removeLimboTarget(limboChange.key);\n }\n } else {\n fail('Unknown limbo change: ' + JSON.stringify(limboChange));\n }\n }\n }\n\n private trackLimboChange(limboChange: AddedLimboDocument): void {\n const key = limboChange.key;\n if (!this.activeLimboTargetsByKey.get(key)) {\n logDebug(LOG_TAG, 'New document in limbo: ' + key);\n this.enqueuedLimboResolutions.push(key);\n this.pumpEnqueuedLimboResolutions();\n }\n }\n\n /**\n * Starts listens for documents in limbo that are enqueued for resolution,\n * subject to a maximum number of concurrent resolutions.\n *\n * Without bounding the number of concurrent resolutions, the server can fail\n * with \"resource exhausted\" errors which can lead to pathological client\n * behavior as seen in https://github.com/firebase/firebase-js-sdk/issues/2683.\n */\n private pumpEnqueuedLimboResolutions(): void {\n while (\n this.enqueuedLimboResolutions.length > 0 &&\n this.activeLimboTargetsByKey.size < this.maxConcurrentLimboResolutions\n ) {\n const key = this.enqueuedLimboResolutions.shift()!;\n const limboTargetId = this.limboTargetIdGenerator.next();\n this.activeLimboResolutionsByTarget.set(\n limboTargetId,\n new LimboResolution(key)\n );\n this.activeLimboTargetsByKey = this.activeLimboTargetsByKey.insert(\n key,\n limboTargetId\n );\n this.remoteStore.listen(\n new TargetData(\n Query.atPath(key.path).toTarget(),\n limboTargetId,\n TargetPurpose.LimboResolution,\n ListenSequence.INVALID\n )\n );\n }\n }\n\n // Visible for testing\n activeLimboDocumentResolutions(): SortedMap<DocumentKey, TargetId> {\n return this.activeLimboTargetsByKey;\n }\n\n // Visible for testing\n enqueuedLimboDocumentResolutions(): DocumentKey[] {\n return this.enqueuedLimboResolutions;\n }\n\n protected async emitNewSnapsAndNotifyLocalStore(\n changes: MaybeDocumentMap,\n remoteEvent?: RemoteEvent\n ): Promise<void> {\n const newSnaps: ViewSnapshot[] = [];\n const docChangesInAllViews: LocalViewChanges[] = [];\n const queriesProcessed: Array<Promise<void>> = [];\n\n this.queryViewsByQuery.forEach((_, queryView) => {\n queriesProcessed.push(\n Promise.resolve()\n .then(() => {\n const viewDocChanges = queryView.view.computeDocChanges(changes);\n if (!viewDocChanges.needsRefill) {\n return viewDocChanges;\n }\n // The query has a limit and some docs were removed, so we need\n // to re-run the query against the local store to make sure we\n // didn't lose any good docs that had been past the limit.\n return this.localStore\n .executeQuery(queryView.query, /* usePreviousResults= */ false)\n .then(({ documents }) => {\n return queryView.view.computeDocChanges(\n documents,\n viewDocChanges\n );\n });\n })\n .then((viewDocChanges: ViewDocumentChanges) => {\n const targetChange =\n remoteEvent && remoteEvent.targetChanges.get(queryView.targetId);\n const viewChange = queryView.view.applyChanges(\n viewDocChanges,\n /* updateLimboDocuments= */ this.isPrimaryClient,\n targetChange\n );\n this.updateTrackedLimbos(\n queryView.targetId,\n viewChange.limboChanges\n );\n if (viewChange.snapshot) {\n if (this.isPrimaryClient) {\n this.sharedClientState.updateQueryState(\n queryView.targetId,\n viewChange.snapshot.fromCache ? 'not-current' : 'current'\n );\n }\n\n newSnaps.push(viewChange.snapshot);\n const docChanges = LocalViewChanges.fromSnapshot(\n queryView.targetId,\n viewChange.snapshot\n );\n docChangesInAllViews.push(docChanges);\n }\n })\n );\n });\n\n await Promise.all(queriesProcessed);\n this.syncEngineListener!.onWatchChange(newSnaps);\n await this.localStore.notifyLocalViewChanges(docChangesInAllViews);\n }\n\n protected assertSubscribed(fnName: string): void {\n debugAssert(\n this.syncEngineListener !== null,\n 'Trying to call ' + fnName + ' before calling subscribe().'\n );\n }\n\n async handleCredentialChange(user: User): Promise<void> {\n const userChanged = !this.currentUser.isEqual(user);\n\n if (userChanged) {\n const result = await this.localStore.handleUserChange(user);\n this.currentUser = user;\n\n // Fails tasks waiting for pending writes requested by previous user.\n this.rejectOutstandingPendingWritesCallbacks(\n \"'waitForPendingWrites' promise is rejected due to a user change.\"\n );\n // TODO(b/114226417): Consider calling this only in the primary tab.\n this.sharedClientState.handleUserChange(\n user,\n result.removedBatchIds,\n result.addedBatchIds\n );\n await this.emitNewSnapsAndNotifyLocalStore(result.affectedDocuments);\n }\n\n await this.remoteStore.handleCredentialChange();\n }\n\n enableNetwork(): Promise<void> {\n return this.remoteStore.enableNetwork();\n }\n\n disableNetwork(): Promise<void> {\n return this.remoteStore.disableNetwork();\n }\n\n getRemoteKeysForTarget(targetId: TargetId): DocumentKeySet {\n const limboResolution = this.activeLimboResolutionsByTarget.get(targetId);\n if (limboResolution && limboResolution.receivedDocument) {\n return documentKeySet().add(limboResolution.key);\n } else {\n let keySet = documentKeySet();\n const queries = this.queriesByTarget.get(targetId);\n if (!queries) {\n return keySet;\n }\n for (const query of queries) {\n const queryView = this.queryViewsByQuery.get(query);\n debugAssert(!!queryView, `No query view found for ${query}`);\n keySet = keySet.unionWith(queryView.view.syncedDocuments);\n }\n return keySet;\n }\n }\n}\n\n/**\n * An impplementation of SyncEngine that implement SharedClientStateSyncer for\n * Multi-Tab synchronization.\n */\n// PORTING NOTE: Web only\nexport class MultiTabSyncEngine extends SyncEngine\n implements SharedClientStateSyncer {\n // The primary state is set to `true` or `false` immediately after Firestore\n // startup. In the interim, a client should only be considered primary if\n // `isPrimary` is true.\n private _isPrimaryClient: undefined | boolean = undefined;\n\n constructor(\n protected localStore: MultiTabLocalStore,\n remoteStore: RemoteStore,\n sharedClientState: SharedClientState,\n currentUser: User,\n maxConcurrentLimboResolutions: number\n ) {\n super(\n localStore,\n remoteStore,\n sharedClientState,\n currentUser,\n maxConcurrentLimboResolutions\n );\n }\n\n get isPrimaryClient(): boolean {\n return this._isPrimaryClient === true;\n }\n\n enableNetwork(): Promise<void> {\n this.localStore.setNetworkEnabled(true);\n return super.enableNetwork();\n }\n\n disableNetwork(): Promise<void> {\n this.localStore.setNetworkEnabled(false);\n return super.disableNetwork();\n }\n\n /**\n * Reconcile the list of synced documents in an existing view with those\n * from persistence.\n */\n private async synchronizeViewAndComputeSnapshot(\n queryView: QueryView\n ): Promise<ViewChange> {\n const queryResult = await this.localStore.executeQuery(\n queryView.query,\n /* usePreviousResults= */ true\n );\n const viewSnapshot = queryView.view.synchronizeWithPersistedState(\n queryResult\n );\n if (this._isPrimaryClient) {\n this.updateTrackedLimbos(queryView.targetId, viewSnapshot.limboChanges);\n }\n return viewSnapshot;\n }\n\n applyOnlineStateChange(\n onlineState: OnlineState,\n source: OnlineStateSource\n ): void {\n // If we are the primary client, the online state of all clients only\n // depends on the online state of the local RemoteStore.\n if (this.isPrimaryClient && source === OnlineStateSource.RemoteStore) {\n super.applyOnlineStateChange(onlineState, source);\n this.sharedClientState.setOnlineState(onlineState);\n }\n\n // If we are the secondary client, we explicitly ignore the remote store's\n // online state (the local client may go offline, even though the primary\n // tab remains online) and only apply the primary tab's online state from\n // SharedClientState.\n if (\n !this.isPrimaryClient &&\n source === OnlineStateSource.SharedClientState\n ) {\n super.applyOnlineStateChange(onlineState, source);\n }\n }\n\n async applyBatchState(\n batchId: BatchId,\n batchState: MutationBatchState,\n error?: FirestoreError\n ): Promise<void> {\n this.assertSubscribed('applyBatchState()');\n const documents = await this.localStore.lookupMutationDocuments(batchId);\n\n if (documents === null) {\n // A throttled tab may not have seen the mutation before it was completed\n // and removed from the mutation queue, in which case we won't have cached\n // the affected documents. In this case we can safely ignore the update\n // since that means we didn't apply the mutation locally at all (if we\n // had, we would have cached the affected documents), and so we will just\n // see any resulting document changes via normal remote document updates\n // as applicable.\n logDebug(LOG_TAG, 'Cannot apply mutation batch with id: ' + batchId);\n return;\n }\n\n if (batchState === 'pending') {\n // If we are the primary client, we need to send this write to the\n // backend. Secondary clients will ignore these writes since their remote\n // connection is disabled.\n await this.remoteStore.fillWritePipeline();\n } else if (batchState === 'acknowledged' || batchState === 'rejected') {\n // NOTE: Both these methods are no-ops for batches that originated from\n // other clients.\n this.processUserCallback(batchId, error ? error : null);\n this.localStore.removeCachedMutationBatchMetadata(batchId);\n } else {\n fail(`Unknown batchState: ${batchState}`);\n }\n\n await this.emitNewSnapsAndNotifyLocalStore(documents);\n }\n\n async applyPrimaryState(isPrimary: boolean): Promise<void> {\n if (isPrimary === true && this._isPrimaryClient !== true) {\n // Secondary tabs only maintain Views for their local listeners and the\n // Views internal state may not be 100% populated (in particular\n // secondary tabs don't track syncedDocuments, the set of documents the\n // server considers to be in the target). So when a secondary becomes\n // primary, we need to need to make sure that all views for all targets\n // match the state on disk.\n const activeTargets = this.sharedClientState.getAllActiveQueryTargets();\n const activeQueries = await this.synchronizeQueryViewsAndRaiseSnapshots(\n activeTargets.toArray(),\n /*transitionToPrimary=*/ true\n );\n this._isPrimaryClient = true;\n await this.remoteStore.applyPrimaryState(true);\n for (const targetData of activeQueries) {\n this.remoteStore.listen(targetData);\n }\n } else if (isPrimary === false && this._isPrimaryClient !== false) {\n const activeTargets: TargetId[] = [];\n\n let p = Promise.resolve();\n this.queriesByTarget.forEach((_, targetId) => {\n if (this.sharedClientState.isLocalQueryTarget(targetId)) {\n activeTargets.push(targetId);\n } else {\n p = p.then(() => {\n this.removeAndCleanupTarget(targetId);\n return this.localStore.releaseTarget(\n targetId,\n /*keepPersistedTargetData=*/ true\n );\n });\n }\n this.remoteStore.unlisten(targetId);\n });\n await p;\n\n await this.synchronizeQueryViewsAndRaiseSnapshots(\n activeTargets,\n /*transitionToPrimary=*/ false\n );\n this.resetLimboDocuments();\n this._isPrimaryClient = false;\n await this.remoteStore.applyPrimaryState(false);\n }\n }\n\n private resetLimboDocuments(): void {\n this.activeLimboResolutionsByTarget.forEach((_, targetId) => {\n this.remoteStore.unlisten(targetId);\n });\n this.limboDocumentRefs.removeAllReferences();\n this.activeLimboResolutionsByTarget = new Map<TargetId, LimboResolution>();\n this.activeLimboTargetsByKey = new SortedMap<DocumentKey, TargetId>(\n DocumentKey.comparator\n );\n }\n\n /**\n * Reconcile the query views of the provided query targets with the state from\n * persistence. Raises snapshots for any changes that affect the local\n * client and returns the updated state of all target's query data.\n *\n * @param targets the list of targets with views that need to be recomputed\n * @param transitionToPrimary `true` iff the tab transitions from a secondary\n * tab to a primary tab\n */\n private async synchronizeQueryViewsAndRaiseSnapshots(\n targets: TargetId[],\n transitionToPrimary: boolean\n ): Promise<TargetData[]> {\n const activeQueries: TargetData[] = [];\n const newViewSnapshots: ViewSnapshot[] = [];\n for (const targetId of targets) {\n let targetData: TargetData;\n const queries = this.queriesByTarget.get(targetId);\n\n if (queries && queries.length !== 0) {\n // For queries that have a local View, we need to update their state\n // in LocalStore (as the resume token and the snapshot version\n // might have changed) and reconcile their views with the persisted\n // state (the list of syncedDocuments may have gotten out of sync).\n await this.localStore.releaseTarget(\n targetId,\n /*keepPersistedTargetData=*/ true\n );\n targetData = await this.localStore.allocateTarget(\n queries[0].toTarget()\n );\n\n for (const query of queries) {\n const queryView = this.queryViewsByQuery.get(query);\n debugAssert(!!queryView, `No query view found for ${query}`);\n\n const viewChange = await this.synchronizeViewAndComputeSnapshot(\n queryView\n );\n if (viewChange.snapshot) {\n newViewSnapshots.push(viewChange.snapshot);\n }\n }\n } else {\n debugAssert(\n transitionToPrimary,\n 'A secondary tab should never have an active target without an active query.'\n );\n // For queries that never executed on this client, we need to\n // allocate the target in LocalStore and initialize a new View.\n const target = await this.localStore.getTarget(targetId);\n debugAssert(!!target, `Target for id ${targetId} not found`);\n targetData = await this.localStore.allocateTarget(target);\n await this.initializeViewAndComputeSnapshot(\n this.synthesizeTargetToQuery(target!),\n targetId,\n /*current=*/ false\n );\n }\n\n activeQueries.push(targetData!);\n }\n\n this.syncEngineListener!.onWatchChange(newViewSnapshots);\n return activeQueries;\n }\n\n /**\n * Creates a `Query` object from the specified `Target`. There is no way to\n * obtain the original `Query`, so we synthesize a `Query` from the `Target`\n * object.\n *\n * The synthesized result might be different from the original `Query`, but\n * since the synthesized `Query` should return the same results as the\n * original one (only the presentation of results might differ), the potential\n * difference will not cause issues.\n */\n private synthesizeTargetToQuery(target: Target): Query {\n return new Query(\n target.path,\n target.collectionGroup,\n target.orderBy,\n target.filters,\n target.limit,\n LimitType.First,\n target.startAt,\n target.endAt\n );\n }\n\n getActiveClients(): Promise<ClientId[]> {\n return this.localStore.getActiveClients();\n }\n\n async applyTargetState(\n targetId: TargetId,\n state: QueryTargetState,\n error?: FirestoreError\n ): Promise<void> {\n if (this._isPrimaryClient) {\n // If we receive a target state notification via WebStorage, we are\n // either already secondary or another tab has taken the primary lease.\n logDebug(LOG_TAG, 'Ignoring unexpected query state notification.');\n return;\n }\n\n if (this.queriesByTarget.has(targetId)) {\n switch (state) {\n case 'current':\n case 'not-current': {\n const changes = await this.localStore.getNewDocumentChanges();\n const synthesizedRemoteEvent = RemoteEvent.createSynthesizedRemoteEventForCurrentChange(\n targetId,\n state === 'current'\n );\n await this.emitNewSnapsAndNotifyLocalStore(\n changes,\n synthesizedRemoteEvent\n );\n break;\n }\n case 'rejected': {\n await this.localStore.releaseTarget(\n targetId,\n /* keepPersistedTargetData */ true\n );\n this.removeAndCleanupTarget(targetId, error);\n break;\n }\n default:\n fail('Unexpected target state: ' + state);\n }\n }\n }\n\n async applyActiveTargetsChange(\n added: TargetId[],\n removed: TargetId[]\n ): Promise<void> {\n if (!this._isPrimaryClient) {\n return;\n }\n\n for (const targetId of added) {\n if (this.queriesByTarget.has(targetId)) {\n // A target might have been added in a previous attempt\n logDebug(LOG_TAG, 'Adding an already active target ' + targetId);\n continue;\n }\n\n const target = await this.localStore.getTarget(targetId);\n debugAssert(\n !!target,\n `Query data for active target ${targetId} not found`\n );\n const targetData = await this.localStore.allocateTarget(target);\n await this.initializeViewAndComputeSnapshot(\n this.synthesizeTargetToQuery(target),\n targetData.targetId,\n /*current=*/ false\n );\n this.remoteStore.listen(targetData);\n }\n\n for (const targetId of removed) {\n // Check that the target is still active since the target might have been\n // removed if it has been rejected by the backend.\n if (!this.queriesByTarget.has(targetId)) {\n continue;\n }\n\n // Release queries that are still active.\n await this.localStore\n .releaseTarget(targetId, /* keepPersistedTargetData */ false)\n .then(() => {\n this.remoteStore.unlisten(targetId);\n this.removeAndCleanupTarget(targetId);\n })\n .catch(ignoreIfPrimaryLeaseLoss);\n }\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 { CredentialsProvider, Token } from '../api/credentials';\nimport { SnapshotVersion } from '../core/snapshot_version';\nimport { TargetId } from '../core/types';\nimport { TargetData } from '../local/target_data';\nimport { Mutation, MutationResult } from '../model/mutation';\nimport * as api from '../protos/firestore_proto_api';\nimport { hardAssert, debugAssert } from '../util/assert';\nimport { AsyncQueue, DelayedOperation, TimerId } from '../util/async_queue';\nimport { Code, FirestoreError } from '../util/error';\nimport { logError, logDebug } from '../util/log';\n\nimport { isNullOrUndefined } from '../util/types';\nimport { ExponentialBackoff } from './backoff';\nimport { Connection, Stream } from './connection';\nimport { JsonProtoSerializer } from './serializer';\nimport { WatchChange } from './watch_change';\nimport { ByteString } from '../util/byte_string';\n\nconst LOG_TAG = 'PersistentStream';\n\n// The generated proto interfaces for these class are missing the database\n// field. So we add it here.\n// TODO(b/36015800): Remove this once the api generator is fixed.\ninterface ListenRequest extends api.ListenRequest {\n database?: string;\n}\nexport interface WriteRequest extends api.WriteRequest {\n database?: string;\n}\n/**\n * PersistentStream can be in one of 5 states (each described in detail below)\n * based on the following state transition diagram:\n *\n * start() called auth & connection succeeded\n * INITIAL ----------------> STARTING -----------------------------> OPEN\n * ^ | |\n * | | error occurred |\n * | \\-----------------------------v-----/\n * | |\n * backoff | |\n * elapsed | start() called |\n * \\--- BACKOFF <---------------- ERROR\n *\n * [any state] --------------------------> INITIAL\n * stop() called or\n * idle timer expired\n */\nconst enum PersistentStreamState {\n /**\n * The streaming RPC is not yet running and there's no error condition.\n * Calling start() will start the stream immediately without backoff.\n * While in this state isStarted() will return false.\n */\n Initial,\n\n /**\n * The stream is starting, either waiting for an auth token or for the stream\n * to successfully open. While in this state, isStarted() will return true but\n * isOpen() will return false.\n */\n Starting,\n\n /**\n * The streaming RPC is up and running. Requests and responses can flow\n * freely. Both isStarted() and isOpen() will return true.\n */\n Open,\n\n /**\n * The stream encountered an error. The next start attempt will back off.\n * While in this state isStarted() will return false.\n */\n Error,\n\n /**\n * An in-between state after an error where the stream is waiting before\n * re-starting. After waiting is complete, the stream will try to open.\n * While in this state isStarted() will return true but isOpen() will return\n * false.\n */\n Backoff\n}\n\n/**\n * Provides a common interface that is shared by the listeners for stream\n * events by the concrete implementation classes.\n */\nexport interface PersistentStreamListener {\n /**\n * Called after the stream was established and can accept outgoing\n * messages\n */\n onOpen: () => Promise<void>;\n /**\n * Called after the stream has closed. If there was an error, the\n * FirestoreError will be set.\n */\n onClose: (err?: FirestoreError) => Promise<void>;\n}\n\n/** The time a stream stays open after it is marked idle. */\nconst IDLE_TIMEOUT_MS = 60 * 1000;\n\n/**\n * A PersistentStream is an abstract base class that represents a streaming RPC\n * to the Firestore backend. It's built on top of the connections own support\n * for streaming RPCs, and adds several critical features for our clients:\n *\n * - Exponential backoff on failure\n * - Authentication via CredentialsProvider\n * - Dispatching all callbacks into the shared worker queue\n * - Closing idle streams after 60 seconds of inactivity\n *\n * Subclasses of PersistentStream implement serialization of models to and\n * from the JSON representation of the protocol buffers for a specific\n * streaming RPC.\n *\n * ## Starting and Stopping\n *\n * Streaming RPCs are stateful and need to be start()ed before messages can\n * be sent and received. The PersistentStream will call the onOpen() function\n * of the listener once the stream is ready to accept requests.\n *\n * Should a start() fail, PersistentStream will call the registered onClose()\n * listener with a FirestoreError indicating what went wrong.\n *\n * A PersistentStream can be started and stopped repeatedly.\n *\n * Generic types:\n * SendType: The type of the outgoing message of the underlying\n * connection stream\n * ReceiveType: The type of the incoming message of the underlying\n * connection stream\n * ListenerType: The type of the listener that will be used for callbacks\n */\nexport abstract class PersistentStream<\n SendType,\n ReceiveType,\n ListenerType extends PersistentStreamListener\n> {\n private state = PersistentStreamState.Initial;\n /**\n * A close count that's incremented every time the stream is closed; used by\n * getCloseGuardedDispatcher() to invalidate callbacks that happen after\n * close.\n */\n private closeCount = 0;\n\n private idleTimer: DelayedOperation<void> | null = null;\n private stream: Stream<SendType, ReceiveType> | null = null;\n\n protected backoff: ExponentialBackoff;\n\n constructor(\n private queue: AsyncQueue,\n connectionTimerId: TimerId,\n private idleTimerId: TimerId,\n protected connection: Connection,\n private credentialsProvider: CredentialsProvider,\n protected listener: ListenerType\n ) {\n this.backoff = new ExponentialBackoff(queue, connectionTimerId);\n }\n\n /**\n * Returns true if start() has been called and no error has occurred. True\n * indicates the stream is open or in the process of opening (which\n * encompasses respecting backoff, getting auth tokens, and starting the\n * actual RPC). Use isOpen() to determine if the stream is open and ready for\n * outbound requests.\n */\n isStarted(): boolean {\n return (\n this.state === PersistentStreamState.Starting ||\n this.state === PersistentStreamState.Open ||\n this.state === PersistentStreamState.Backoff\n );\n }\n\n /**\n * Returns true if the underlying RPC is open (the onOpen() listener has been\n * called) and the stream is ready for outbound requests.\n */\n isOpen(): boolean {\n return this.state === PersistentStreamState.Open;\n }\n\n /**\n * Starts the RPC. Only allowed if isStarted() returns false. The stream is\n * not immediately ready for use: onOpen() will be invoked when the RPC is\n * ready for outbound requests, at which point isOpen() will return true.\n *\n * When start returns, isStarted() will return true.\n */\n start(): void {\n if (this.state === PersistentStreamState.Error) {\n this.performBackoff();\n return;\n }\n\n debugAssert(\n this.state === PersistentStreamState.Initial,\n 'Already started'\n );\n this.auth();\n }\n\n /**\n * Stops the RPC. This call is idempotent and allowed regardless of the\n * current isStarted() state.\n *\n * When stop returns, isStarted() and isOpen() will both return false.\n */\n async stop(): Promise<void> {\n if (this.isStarted()) {\n await this.close(PersistentStreamState.Initial);\n }\n }\n\n /**\n * After an error the stream will usually back off on the next attempt to\n * start it. If the error warrants an immediate restart of the stream, the\n * sender can use this to indicate that the receiver should not back off.\n *\n * Each error will call the onClose() listener. That function can decide to\n * inhibit backoff if required.\n */\n inhibitBackoff(): void {\n debugAssert(\n !this.isStarted(),\n 'Can only inhibit backoff in a stopped state'\n );\n\n this.state = PersistentStreamState.Initial;\n this.backoff.reset();\n }\n\n /**\n * Marks this stream as idle. If no further actions are performed on the\n * stream for one minute, the stream will automatically close itself and\n * notify the stream's onClose() handler with Status.OK. The stream will then\n * be in a !isStarted() state, requiring the caller to start the stream again\n * before further use.\n *\n * Only streams that are in state 'Open' can be marked idle, as all other\n * states imply pending network operations.\n */\n markIdle(): void {\n // Starts the idle time if we are in state 'Open' and are not yet already\n // running a timer (in which case the previous idle timeout still applies).\n if (this.isOpen() && this.idleTimer === null) {\n this.idleTimer = this.queue.enqueueAfterDelay(\n this.idleTimerId,\n IDLE_TIMEOUT_MS,\n () => this.handleIdleCloseTimer()\n );\n }\n }\n\n /** Sends a message to the underlying stream. */\n protected sendRequest(msg: SendType): void {\n this.cancelIdleCheck();\n this.stream!.send(msg);\n }\n\n /** Called by the idle timer when the stream should close due to inactivity. */\n private async handleIdleCloseTimer(): Promise<void> {\n if (this.isOpen()) {\n // When timing out an idle stream there's no reason to force the stream into backoff when\n // it restarts so set the stream state to Initial instead of Error.\n return this.close(PersistentStreamState.Initial);\n }\n }\n\n /** Marks the stream as active again. */\n private cancelIdleCheck(): void {\n if (this.idleTimer) {\n this.idleTimer.cancel();\n this.idleTimer = null;\n }\n }\n\n /**\n * Closes the stream and cleans up as necessary:\n *\n * * closes the underlying GRPC stream;\n * * calls the onClose handler with the given 'error';\n * * sets internal stream state to 'finalState';\n * * adjusts the backoff timer based on the error\n *\n * A new stream can be opened by calling start().\n *\n * @param finalState the intended state of the stream after closing.\n * @param error the error the connection was closed with.\n */\n private async close(\n finalState: PersistentStreamState,\n error?: FirestoreError\n ): Promise<void> {\n debugAssert(this.isStarted(), 'Only started streams should be closed.');\n debugAssert(\n finalState === PersistentStreamState.Error || isNullOrUndefined(error),\n \"Can't provide an error when not in an error state.\"\n );\n\n // Cancel any outstanding timers (they're guaranteed not to execute).\n this.cancelIdleCheck();\n this.backoff.cancel();\n\n // Invalidates any stream-related callbacks (e.g. from auth or the\n // underlying stream), guaranteeing they won't execute.\n this.closeCount++;\n\n if (finalState !== PersistentStreamState.Error) {\n // If this is an intentional close ensure we don't delay our next connection attempt.\n this.backoff.reset();\n } else if (error && error.code === Code.RESOURCE_EXHAUSTED) {\n // Log the error. (Probably either 'quota exceeded' or 'max queue length reached'.)\n logError(error.toString());\n logError(\n 'Using maximum backoff delay to prevent overloading the backend.'\n );\n this.backoff.resetToMax();\n } else if (error && error.code === Code.UNAUTHENTICATED) {\n // \"unauthenticated\" error means the token was rejected. Try force refreshing it in case it\n // just expired.\n this.credentialsProvider.invalidateToken();\n }\n\n // Clean up the underlying stream because we are no longer interested in events.\n if (this.stream !== null) {\n this.tearDown();\n this.stream.close();\n this.stream = null;\n }\n\n // This state must be assigned before calling onClose() to allow the callback to\n // inhibit backoff or otherwise manipulate the state in its non-started state.\n this.state = finalState;\n\n // Notify the listener that the stream closed.\n await this.listener.onClose(error);\n }\n\n /**\n * Can be overridden to perform additional cleanup before the stream is closed.\n * Calling super.tearDown() is not required.\n */\n protected tearDown(): void {}\n\n /**\n * Used by subclasses to start the concrete RPC and return the underlying\n * connection stream.\n */\n protected abstract startRpc(\n token: Token | null\n ): Stream<SendType, ReceiveType>;\n\n /**\n * Called after the stream has received a message. The function will be\n * called on the right queue and must return a Promise.\n * @param message The message received from the stream.\n */\n protected abstract onMessage(message: ReceiveType): Promise<void>;\n\n private auth(): void {\n debugAssert(\n this.state === PersistentStreamState.Initial,\n 'Must be in initial state to auth'\n );\n\n this.state = PersistentStreamState.Starting;\n\n const dispatchIfNotClosed = this.getCloseGuardedDispatcher(this.closeCount);\n\n // TODO(mikelehen): Just use dispatchIfNotClosed, but see TODO below.\n const closeCount = this.closeCount;\n\n this.credentialsProvider.getToken().then(\n token => {\n // Stream can be stopped while waiting for authentication.\n // TODO(mikelehen): We really should just use dispatchIfNotClosed\n // and let this dispatch onto the queue, but that opened a spec test can\n // of worms that I don't want to deal with in this PR.\n if (this.closeCount === closeCount) {\n // Normally we'd have to schedule the callback on the AsyncQueue.\n // However, the following calls are safe to be called outside the\n // AsyncQueue since they don't chain asynchronous calls\n this.startStream(token);\n }\n },\n (error: Error) => {\n dispatchIfNotClosed(() => {\n const rpcError = new FirestoreError(\n Code.UNKNOWN,\n 'Fetching auth token failed: ' + error.message\n );\n return this.handleStreamClose(rpcError);\n });\n }\n );\n }\n\n private startStream(token: Token | null): void {\n debugAssert(\n this.state === PersistentStreamState.Starting,\n 'Trying to start stream in a non-starting state'\n );\n\n const dispatchIfNotClosed = this.getCloseGuardedDispatcher(this.closeCount);\n\n this.stream = this.startRpc(token);\n this.stream.onOpen(() => {\n dispatchIfNotClosed(() => {\n debugAssert(\n this.state === PersistentStreamState.Starting,\n 'Expected stream to be in state Starting, but was ' + this.state\n );\n this.state = PersistentStreamState.Open;\n return this.listener!.onOpen();\n });\n });\n this.stream.onClose((error?: FirestoreError) => {\n dispatchIfNotClosed(() => {\n return this.handleStreamClose(error);\n });\n });\n this.stream.onMessage((msg: ReceiveType) => {\n dispatchIfNotClosed(() => {\n return this.onMessage(msg);\n });\n });\n }\n\n private performBackoff(): void {\n debugAssert(\n this.state === PersistentStreamState.Error,\n 'Should only perform backoff when in Error state'\n );\n this.state = PersistentStreamState.Backoff;\n\n this.backoff.backoffAndRun(async () => {\n debugAssert(\n this.state === PersistentStreamState.Backoff,\n 'Backoff elapsed but state is now: ' + this.state\n );\n\n this.state = PersistentStreamState.Initial;\n this.start();\n debugAssert(this.isStarted(), 'PersistentStream should have started');\n });\n }\n\n // Visible for tests\n handleStreamClose(error?: FirestoreError): Promise<void> {\n debugAssert(\n this.isStarted(),\n \"Can't handle server close on non-started stream\"\n );\n logDebug(LOG_TAG, `close with error: ${error}`);\n\n this.stream = null;\n\n // In theory the stream could close cleanly, however, in our current model\n // we never expect this to happen because if we stop a stream ourselves,\n // this callback will never be called. To prevent cases where we retry\n // without a backoff accidentally, we set the stream to error in all cases.\n return this.close(PersistentStreamState.Error, error);\n }\n\n /**\n * Returns a \"dispatcher\" function that dispatches operations onto the\n * AsyncQueue but only runs them if closeCount remains unchanged. This allows\n * us to turn auth / stream callbacks into no-ops if the stream is closed /\n * re-opened, etc.\n */\n private getCloseGuardedDispatcher(\n startCloseCount: number\n ): (fn: () => Promise<void>) => void {\n return (fn: () => Promise<void>): void => {\n this.queue.enqueueAndForget(() => {\n if (this.closeCount === startCloseCount) {\n return fn();\n } else {\n logDebug(\n LOG_TAG,\n 'stream callback skipped by getCloseGuardedDispatcher.'\n );\n return Promise.resolve();\n }\n });\n };\n }\n}\n\n/** Listener for the PersistentWatchStream */\nexport interface WatchStreamListener extends PersistentStreamListener {\n /**\n * Called on a watchChange. The snapshot parameter will be MIN if the watch\n * change did not have a snapshot associated with it.\n */\n onWatchChange: (\n watchChange: WatchChange,\n snapshot: SnapshotVersion\n ) => Promise<void>;\n}\n\n/**\n * A PersistentStream that implements the Listen RPC.\n *\n * Once the Listen stream has called the onOpen() listener, any number of\n * listen() and unlisten() calls can be made to control what changes will be\n * sent from the server for ListenResponses.\n */\nexport class PersistentListenStream extends PersistentStream<\n api.ListenRequest,\n api.ListenResponse,\n WatchStreamListener\n> {\n constructor(\n queue: AsyncQueue,\n connection: Connection,\n credentials: CredentialsProvider,\n private serializer: JsonProtoSerializer,\n listener: WatchStreamListener\n ) {\n super(\n queue,\n TimerId.ListenStreamConnectionBackoff,\n TimerId.ListenStreamIdle,\n connection,\n credentials,\n listener\n );\n }\n\n protected startRpc(\n token: Token | null\n ): Stream<api.ListenRequest, api.ListenResponse> {\n return this.connection.openStream<api.ListenRequest, api.ListenResponse>(\n 'Listen',\n token\n );\n }\n\n protected onMessage(watchChangeProto: api.ListenResponse): Promise<void> {\n // A successful response means the stream is healthy\n this.backoff.reset();\n\n const watchChange = this.serializer.fromWatchChange(watchChangeProto);\n const snapshot = this.serializer.versionFromListenResponse(\n watchChangeProto\n );\n return this.listener!.onWatchChange(watchChange, snapshot);\n }\n\n /**\n * Registers interest in the results of the given target. If the target\n * includes a resumeToken it will be included in the request. Results that\n * affect the target will be streamed back as WatchChange messages that\n * reference the targetId.\n */\n watch(targetData: TargetData): void {\n const request: ListenRequest = {};\n request.database = this.serializer.encodedDatabaseId;\n request.addTarget = this.serializer.toTarget(targetData);\n\n const labels = this.serializer.toListenRequestLabels(targetData);\n if (labels) {\n request.labels = labels;\n }\n\n this.sendRequest(request);\n }\n\n /**\n * Unregisters interest in the results of the target associated with the\n * given targetId.\n */\n unwatch(targetId: TargetId): void {\n const request: ListenRequest = {};\n request.database = this.serializer.encodedDatabaseId;\n request.removeTarget = targetId;\n this.sendRequest(request);\n }\n}\n\n/** Listener for the PersistentWriteStream */\nexport interface WriteStreamListener extends PersistentStreamListener {\n /**\n * Called by the PersistentWriteStream upon a successful handshake response\n * from the server, which is the receiver's cue to send any pending writes.\n */\n onHandshakeComplete: () => Promise<void>;\n\n /**\n * Called by the PersistentWriteStream upon receiving a StreamingWriteResponse\n * from the server that contains a mutation result.\n */\n onMutationResult: (\n commitVersion: SnapshotVersion,\n results: MutationResult[]\n ) => Promise<void>;\n}\n\n/**\n * A Stream that implements the Write RPC.\n *\n * The Write RPC requires the caller to maintain special streamToken\n * state in between calls, to help the server understand which responses the\n * client has processed by the time the next request is made. Every response\n * will contain a streamToken; this value must be passed to the next\n * request.\n *\n * After calling start() on this stream, the next request must be a handshake,\n * containing whatever streamToken is on hand. Once a response to this\n * request is received, all pending mutations may be submitted. When\n * submitting multiple batches of mutations at the same time, it's\n * okay to use the same streamToken for the calls to writeMutations.\n *\n * TODO(b/33271235): Use proto types\n */\nexport class PersistentWriteStream extends PersistentStream<\n api.WriteRequest,\n api.WriteResponse,\n WriteStreamListener\n> {\n private handshakeComplete_ = false;\n\n constructor(\n queue: AsyncQueue,\n connection: Connection,\n credentials: CredentialsProvider,\n private serializer: JsonProtoSerializer,\n listener: WriteStreamListener\n ) {\n super(\n queue,\n TimerId.WriteStreamConnectionBackoff,\n TimerId.WriteStreamIdle,\n connection,\n credentials,\n listener\n );\n }\n\n /**\n * The last received stream token from the server, used to acknowledge which\n * responses the client has processed. Stream tokens are opaque checkpoint\n * markers whose only real value is their inclusion in the next request.\n *\n * PersistentWriteStream manages propagating this value from responses to the\n * next request.\n */\n lastStreamToken: ByteString = ByteString.EMPTY_BYTE_STRING;\n\n /**\n * Tracks whether or not a handshake has been successfully exchanged and\n * the stream is ready to accept mutations.\n */\n get handshakeComplete(): boolean {\n return this.handshakeComplete_;\n }\n\n // Override of PersistentStream.start\n start(): void {\n this.handshakeComplete_ = false;\n super.start();\n }\n\n protected tearDown(): void {\n if (this.handshakeComplete_) {\n this.writeMutations([]);\n }\n }\n\n protected startRpc(\n token: Token | null\n ): Stream<api.WriteRequest, api.WriteResponse> {\n return this.connection.openStream<api.WriteRequest, api.WriteResponse>(\n 'Write',\n token\n );\n }\n\n protected onMessage(responseProto: api.WriteResponse): Promise<void> {\n // Always capture the last stream token.\n hardAssert(\n !!responseProto.streamToken,\n 'Got a write response without a stream token'\n );\n this.lastStreamToken = this.serializer.fromBytes(responseProto.streamToken);\n\n if (!this.handshakeComplete_) {\n // The first response is always the handshake response\n hardAssert(\n !responseProto.writeResults || responseProto.writeResults.length === 0,\n 'Got mutation results for handshake'\n );\n this.handshakeComplete_ = true;\n return this.listener!.onHandshakeComplete();\n } else {\n // A successful first write response means the stream is healthy,\n // Note, that we could consider a successful handshake healthy, however,\n // the write itself might be causing an error we want to back off from.\n this.backoff.reset();\n\n const results = this.serializer.fromWriteResults(\n responseProto.writeResults,\n responseProto.commitTime\n );\n const commitVersion = this.serializer.fromVersion(\n responseProto.commitTime!\n );\n return this.listener!.onMutationResult(commitVersion, results);\n }\n }\n\n /**\n * Sends an initial streamToken to the server, performing the handshake\n * required to make the StreamingWrite RPC work. Subsequent\n * calls should wait until onHandshakeComplete was called.\n */\n writeHandshake(): void {\n debugAssert(this.isOpen(), 'Writing handshake requires an opened stream');\n debugAssert(!this.handshakeComplete_, 'Handshake already completed');\n // TODO(dimond): Support stream resumption. We intentionally do not set the\n // stream token on the handshake, ignoring any stream token we might have.\n const request: WriteRequest = {};\n request.database = this.serializer.encodedDatabaseId;\n this.sendRequest(request);\n }\n\n /** Sends a group of mutations to the Firestore backend to apply. */\n writeMutations(mutations: Mutation[]): void {\n debugAssert(this.isOpen(), 'Writing mutations requires an opened stream');\n debugAssert(\n this.handshakeComplete_,\n 'Handshake must be complete before writing mutations'\n );\n debugAssert(\n this.lastStreamToken.approximateByteSize() > 0,\n 'Trying to write mutation without a token'\n );\n\n const request: WriteRequest = {\n streamToken: this.serializer.toBytes(this.lastStreamToken),\n writes: mutations.map(mutation => this.serializer.toMutation(mutation))\n };\n\n this.sendRequest(request);\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 { CredentialsProvider } from '../api/credentials';\nimport { MaybeDocument, Document } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport { Mutation, MutationResult } from '../model/mutation';\nimport * as api from '../protos/firestore_proto_api';\nimport { debugCast, hardAssert } from '../util/assert';\nimport { Code, FirestoreError } from '../util/error';\nimport { Connection } from './connection';\nimport { JsonProtoSerializer } from './serializer';\nimport {\n PersistentListenStream,\n PersistentWriteStream,\n WatchStreamListener,\n WriteStreamListener\n} from './persistent_stream';\nimport { AsyncQueue } from '../util/async_queue';\nimport { Query } from '../core/query';\n\n/**\n * Datastore and its related methods are a wrapper around the external Google\n * Cloud Datastore grpc API, which provides an interface that is more convenient\n * for the rest of the client SDK architecture to consume.\n */\nexport class Datastore {\n // Make sure that the structural type of `Datastore` is unique.\n // See https://github.com/microsoft/TypeScript/issues/5451\n private _ = undefined;\n}\n\n/**\n * An implementation of Datastore that exposes additional state for internal\n * consumption.\n */\nclass DatastoreImpl extends Datastore {\n constructor(\n public readonly connection: Connection,\n public readonly credentials: CredentialsProvider,\n public readonly serializer: JsonProtoSerializer\n ) {\n super();\n }\n\n /** Gets an auth token and invokes the provided RPC. */\n invokeRPC<Req, Resp>(rpcName: string, request: Req): Promise<Resp> {\n return this.credentials\n .getToken()\n .then(token => {\n return this.connection.invokeRPC<Req, Resp>(rpcName, request, token);\n })\n .catch((error: FirestoreError) => {\n if (error.code === Code.UNAUTHENTICATED) {\n this.credentials.invalidateToken();\n }\n throw error;\n });\n }\n\n /** Gets an auth token and invokes the provided RPC with streamed results. */\n invokeStreamingRPC<Req, Resp>(\n rpcName: string,\n request: Req\n ): Promise<Resp[]> {\n return this.credentials\n .getToken()\n .then(token => {\n return this.connection.invokeStreamingRPC<Req, Resp>(\n rpcName,\n request,\n token\n );\n })\n .catch((error: FirestoreError) => {\n if (error.code === Code.UNAUTHENTICATED) {\n this.credentials.invalidateToken();\n }\n throw error;\n });\n }\n}\n\nexport function newDatastore(\n connection: Connection,\n credentials: CredentialsProvider,\n serializer: JsonProtoSerializer\n): Datastore {\n return new DatastoreImpl(connection, credentials, serializer);\n}\n\nexport async function invokeCommitRpc(\n datastore: Datastore,\n mutations: Mutation[]\n): Promise<MutationResult[]> {\n const datastoreImpl = debugCast(datastore, DatastoreImpl);\n const params = {\n database: datastoreImpl.serializer.encodedDatabaseId,\n writes: mutations.map(m => datastoreImpl.serializer.toMutation(m))\n };\n const response = await datastoreImpl.invokeRPC<\n api.CommitRequest,\n api.CommitResponse\n >('Commit', params);\n return datastoreImpl.serializer.fromWriteResults(\n response.writeResults,\n response.commitTime\n );\n}\n\nexport async function invokeBatchGetDocumentsRpc(\n datastore: Datastore,\n keys: DocumentKey[]\n): Promise<MaybeDocument[]> {\n const datastoreImpl = debugCast(datastore, DatastoreImpl);\n const params = {\n database: datastoreImpl.serializer.encodedDatabaseId,\n documents: keys.map(k => datastoreImpl.serializer.toName(k))\n };\n const response = await datastoreImpl.invokeStreamingRPC<\n api.BatchGetDocumentsRequest,\n api.BatchGetDocumentsResponse\n >('BatchGetDocuments', params);\n\n const docs = new Map<string, MaybeDocument>();\n response.forEach(proto => {\n const doc = datastoreImpl.serializer.fromMaybeDocument(proto);\n docs.set(doc.key.toString(), doc);\n });\n const result: MaybeDocument[] = [];\n keys.forEach(key => {\n const doc = docs.get(key.toString());\n hardAssert(!!doc, 'Missing entity in write response for ' + key);\n result.push(doc);\n });\n return result;\n}\n\nexport async function invokeRunQueryRpc(\n datastore: Datastore,\n query: Query\n): Promise<Document[]> {\n const datastoreImpl = debugCast(datastore, DatastoreImpl);\n const { structuredQuery, parent } = datastoreImpl.serializer.toQueryTarget(\n query.toTarget()\n );\n const params = {\n database: datastoreImpl.serializer.encodedDatabaseId,\n parent,\n structuredQuery\n };\n\n const response = await datastoreImpl.invokeStreamingRPC<\n api.RunQueryRequest,\n api.RunQueryResponse\n >('RunQuery', params);\n\n return (\n response\n // Omit RunQueryResponses that only contain readTimes.\n .filter(proto => !!proto.document)\n .map(proto => datastoreImpl.serializer.fromDocument(proto.document!))\n );\n}\n\nexport function newPersistentWriteStream(\n datastore: Datastore,\n queue: AsyncQueue,\n listener: WriteStreamListener\n): PersistentWriteStream {\n const datastoreImpl = debugCast(datastore, DatastoreImpl);\n return new PersistentWriteStream(\n queue,\n datastoreImpl.connection,\n datastoreImpl.credentials,\n datastoreImpl.serializer,\n listener\n );\n}\n\nexport function newPersistentWatchStream(\n datastore: Datastore,\n queue: AsyncQueue,\n listener: WatchStreamListener\n): PersistentListenStream {\n const datastoreImpl = debugCast(datastore, DatastoreImpl);\n return new PersistentListenStream(\n queue,\n datastoreImpl.connection,\n datastoreImpl.credentials,\n datastoreImpl.serializer,\n listener\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 '../api/user_data_reader';\nimport { documentVersionMap } from '../model/collections';\nimport { Document, MaybeDocument, NoDocument } from '../model/document';\n\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';\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 = documentVersionMap();\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 lastWriteError: 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<DocumentKey> = new Set();\n\n constructor(private datastore: Datastore) {}\n\n async lookup(keys: DocumentKey[]): Promise<MaybeDocument[]> {\n this.ensureCommitNotCalled();\n\n if (this.mutations.length > 0) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'Firestore transactions require all reads to be executed before all writes.'\n );\n }\n const docs = await invokeBatchGetDocumentsRpc(this.datastore, keys);\n docs.forEach(doc => {\n if (doc instanceof NoDocument || doc instanceof Document) {\n this.recordVersion(doc);\n } else {\n fail('Document in a transaction was a ' + doc.constructor.name);\n }\n });\n return docs;\n }\n\n set(key: DocumentKey, data: ParsedSetData): void {\n this.write(data.toMutations(key, this.precondition(key)));\n this.writtenDocs.add(key);\n }\n\n update(key: DocumentKey, data: ParsedUpdateData): void {\n try {\n this.write(data.toMutations(key, this.preconditionForUpdate(key)));\n } catch (e) {\n this.lastWriteError = e;\n }\n this.writtenDocs.add(key);\n }\n\n delete(key: DocumentKey): void {\n this.write([new DeleteMutation(key, this.precondition(key))]);\n this.writtenDocs.add(key);\n }\n\n async commit(): Promise<void> {\n this.ensureCommitNotCalled();\n\n if (this.lastWriteError) {\n throw this.lastWriteError;\n }\n let unwritten = this.readVersions;\n // For each mutation, note that the doc was written.\n this.mutations.forEach(mutation => {\n unwritten = unwritten.remove(mutation.key);\n });\n // For each document that was read but not written to, we want to perform\n // a `verify` operation.\n unwritten.forEach((key, _version) => {\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: MaybeDocument): void {\n let docVersion: SnapshotVersion;\n\n if (doc instanceof Document) {\n docVersion = doc.version;\n } else if (doc instanceof NoDocument) {\n // For deleted docs, we must use baseVersion 0 when we overwrite them.\n docVersion = SnapshotVersion.min();\n } else {\n throw fail('Document in a transaction was a ' + doc.constructor.name);\n }\n\n const existingVersion = this.readVersions.get(doc.key);\n if (existingVersion !== null) {\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 = this.readVersions.insert(doc.key, 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);\n if (!this.writtenDocs.has(key) && version) {\n return Precondition.updateTime(version);\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);\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) && 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(mutations: Mutation[]): void {\n this.ensureCommitNotCalled();\n this.mutations = this.mutations.concat(mutations);\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 2018 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 { OnlineState } from '../core/types';\nimport { debugAssert } from '../util/assert';\nimport { AsyncQueue, DelayedOperation, TimerId } from '../util/async_queue';\nimport { FirestoreError } from '../util/error';\nimport { logError, logDebug } from '../util/log';\n\nconst LOG_TAG = 'OnlineStateTracker';\n\n// To deal with transient failures, we allow multiple stream attempts before\n// giving up and transitioning from OnlineState.Unknown to Offline.\n// TODO(mikelehen): This used to be set to 2 as a mitigation for b/66228394.\n// @jdimond thinks that bug is sufficiently fixed so that we can set this back\n// to 1. If that works okay, we could potentially remove this logic entirely.\nconst MAX_WATCH_STREAM_FAILURES = 1;\n\n// To deal with stream attempts that don't succeed or fail in a timely manner,\n// we have a timeout for OnlineState to reach Online or Offline.\n// If the timeout is reached, we transition to Offline rather than waiting\n// indefinitely.\nconst ONLINE_STATE_TIMEOUT_MS = 10 * 1000;\n\n/**\n * A component used by the RemoteStore to track the OnlineState (that is,\n * whether or not the client as a whole should be considered to be online or\n * offline), implementing the appropriate heuristics.\n *\n * In particular, when the client is trying to connect to the backend, we\n * allow up to MAX_WATCH_STREAM_FAILURES within ONLINE_STATE_TIMEOUT_MS for\n * a connection to succeed. If we have too many failures or the timeout elapses,\n * then we set the OnlineState to Offline, and the client will behave as if\n * it is offline (get()s will return cached data, etc.).\n */\nexport class OnlineStateTracker {\n /** The current OnlineState. */\n private state = OnlineState.Unknown;\n\n /**\n * A count of consecutive failures to open the stream. If it reaches the\n * maximum defined by MAX_WATCH_STREAM_FAILURES, we'll set the OnlineState to\n * Offline.\n */\n private watchStreamFailures = 0;\n\n /**\n * A timer that elapses after ONLINE_STATE_TIMEOUT_MS, at which point we\n * transition from OnlineState.Unknown to OnlineState.Offline without waiting\n * for the stream to actually fail (MAX_WATCH_STREAM_FAILURES times).\n */\n private onlineStateTimer: DelayedOperation<void> | null = null;\n\n /**\n * Whether the client should log a warning message if it fails to connect to\n * the backend (initially true, cleared after a successful stream, or if we've\n * logged the message already).\n */\n private shouldWarnClientIsOffline = true;\n\n constructor(\n private asyncQueue: AsyncQueue,\n private onlineStateHandler: (onlineState: OnlineState) => void\n ) {}\n\n /**\n * Called by RemoteStore when a watch stream is started (including on each\n * backoff attempt).\n *\n * If this is the first attempt, it sets the OnlineState to Unknown and starts\n * the onlineStateTimer.\n */\n handleWatchStreamStart(): void {\n if (this.watchStreamFailures === 0) {\n this.setAndBroadcast(OnlineState.Unknown);\n\n debugAssert(\n this.onlineStateTimer === null,\n `onlineStateTimer shouldn't be started yet`\n );\n this.onlineStateTimer = this.asyncQueue.enqueueAfterDelay(\n TimerId.OnlineStateTimeout,\n ONLINE_STATE_TIMEOUT_MS,\n () => {\n this.onlineStateTimer = null;\n debugAssert(\n this.state === OnlineState.Unknown,\n 'Timer should be canceled if we transitioned to a different state.'\n );\n this.logClientOfflineWarningIfNecessary(\n `Backend didn't respond within ${ONLINE_STATE_TIMEOUT_MS / 1000} ` +\n `seconds.`\n );\n this.setAndBroadcast(OnlineState.Offline);\n\n // NOTE: handleWatchStreamFailure() will continue to increment\n // watchStreamFailures even though we are already marked Offline,\n // but this is non-harmful.\n\n return Promise.resolve();\n }\n );\n }\n }\n\n /**\n * Updates our OnlineState as appropriate after the watch stream reports a\n * failure. The first failure moves us to the 'Unknown' state. We then may\n * allow multiple failures (based on MAX_WATCH_STREAM_FAILURES) before we\n * actually transition to the 'Offline' state.\n */\n handleWatchStreamFailure(error: FirestoreError): void {\n if (this.state === OnlineState.Online) {\n this.setAndBroadcast(OnlineState.Unknown);\n\n // To get to OnlineState.Online, set() must have been called which would\n // have reset our heuristics.\n debugAssert(\n this.watchStreamFailures === 0,\n 'watchStreamFailures must be 0'\n );\n debugAssert(\n this.onlineStateTimer === null,\n 'onlineStateTimer must be null'\n );\n } else {\n this.watchStreamFailures++;\n if (this.watchStreamFailures >= MAX_WATCH_STREAM_FAILURES) {\n this.clearOnlineStateTimer();\n\n this.logClientOfflineWarningIfNecessary(\n `Connection failed ${MAX_WATCH_STREAM_FAILURES} ` +\n `times. Most recent error: ${error.toString()}`\n );\n\n this.setAndBroadcast(OnlineState.Offline);\n }\n }\n }\n\n /**\n * Explicitly sets the OnlineState to the specified state.\n *\n * Note that this resets our timers / failure counters, etc. used by our\n * Offline heuristics, so must not be used in place of\n * handleWatchStreamStart() and handleWatchStreamFailure().\n */\n set(newState: OnlineState): void {\n this.clearOnlineStateTimer();\n this.watchStreamFailures = 0;\n\n if (newState === OnlineState.Online) {\n // We've connected to watch at least once. Don't warn the developer\n // about being offline going forward.\n this.shouldWarnClientIsOffline = false;\n }\n\n this.setAndBroadcast(newState);\n }\n\n private setAndBroadcast(newState: OnlineState): void {\n if (newState !== this.state) {\n this.state = newState;\n this.onlineStateHandler(newState);\n }\n }\n\n private logClientOfflineWarningIfNecessary(details: string): void {\n const message =\n `Could not reach Cloud Firestore backend. ${details}\\n` +\n `This typically indicates that your device does not have a healthy ` +\n `Internet connection at the moment. The client will operate in offline ` +\n `mode until it is able to successfully connect to the backend.`;\n if (this.shouldWarnClientIsOffline) {\n logError(message);\n this.shouldWarnClientIsOffline = false;\n } else {\n logDebug(LOG_TAG, message);\n }\n }\n\n private clearOnlineStateTimer(): void {\n if (this.onlineStateTimer !== null) {\n this.onlineStateTimer.cancel();\n this.onlineStateTimer = null;\n }\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 { SnapshotVersion } from '../core/snapshot_version';\nimport { TargetId } from '../core/types';\nimport { ChangeType } from '../core/view_snapshot';\nimport { TargetData, TargetPurpose } from '../local/target_data';\nimport {\n documentKeySet,\n DocumentKeySet,\n maybeDocumentMap\n} from '../model/collections';\nimport { Document, MaybeDocument, NoDocument } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport { debugAssert, fail, hardAssert } from '../util/assert';\nimport { FirestoreError } from '../util/error';\nimport { logDebug } from '../util/log';\nimport { primitiveComparator } from '../util/misc';\nimport { SortedMap } from '../util/sorted_map';\nimport { SortedSet } from '../util/sorted_set';\nimport { ExistenceFilter } from './existence_filter';\nimport { RemoteEvent, TargetChange } from './remote_event';\nimport { ByteString } from '../util/byte_string';\n\n/**\n * Internal representation of the watcher API protocol buffers.\n */\nexport type WatchChange =\n | DocumentWatchChange\n | WatchTargetChange\n | ExistenceFilterChange;\n\n/**\n * Represents a changed document and a list of target ids to which this change\n * applies.\n *\n * If document has been deleted NoDocument will be provided.\n */\nexport class DocumentWatchChange {\n constructor(\n /** The new document applies to all of these targets. */\n public updatedTargetIds: TargetId[],\n /** The new document is removed from all of these targets. */\n public removedTargetIds: TargetId[],\n /** The key of the document for this change. */\n public key: DocumentKey,\n /**\n * The new document or NoDocument if it was deleted. Is null if the\n * document went out of view without the server sending a new document.\n */\n public newDoc: MaybeDocument | null\n ) {}\n}\n\nexport class ExistenceFilterChange {\n constructor(\n public targetId: TargetId,\n public existenceFilter: ExistenceFilter\n ) {}\n}\n\nexport const enum WatchTargetChangeState {\n NoChange,\n Added,\n Removed,\n Current,\n Reset\n}\n\nexport class WatchTargetChange {\n constructor(\n /** What kind of change occurred to the watch target. */\n public state: WatchTargetChangeState,\n /** The target IDs that were added/removed/set. */\n public targetIds: TargetId[],\n /**\n * An opaque, server-assigned token that allows watching a target to be\n * resumed after disconnecting without retransmitting all the data that\n * matches the target. The resume token essentially identifies a point in\n * time from which the server should resume sending results.\n */\n public resumeToken: ByteString = ByteString.EMPTY_BYTE_STRING,\n /** An RPC error indicating why the watch failed. */\n public cause: FirestoreError | null = null\n ) {}\n}\n\n/** Tracks the internal state of a Watch target. */\nclass TargetState {\n /**\n * The number of pending responses (adds or removes) that we are waiting on.\n * We only consider targets active that have no pending responses.\n */\n private pendingResponses = 0;\n\n /**\n * Keeps track of the document changes since the last raised snapshot.\n *\n * These changes are continuously updated as we receive document updates and\n * always reflect the current set of changes against the last issued snapshot.\n */\n private documentChanges: SortedMap<\n DocumentKey,\n ChangeType\n > = snapshotChangesMap();\n\n /** See public getters for explanations of these fields. */\n private _resumeToken: ByteString = ByteString.EMPTY_BYTE_STRING;\n private _current = false;\n\n /**\n * Whether this target state should be included in the next snapshot. We\n * initialize to true so that newly-added targets are included in the next\n * RemoteEvent.\n */\n private _hasPendingChanges = true;\n\n /**\n * Whether this target has been marked 'current'.\n *\n * 'Current' has special meaning in the RPC protocol: It implies that the\n * Watch backend has sent us all changes up to the point at which the target\n * was added and that the target is consistent with the rest of the watch\n * stream.\n */\n get current(): boolean {\n return this._current;\n }\n\n /** The last resume token sent to us for this target. */\n get resumeToken(): ByteString {\n return this._resumeToken;\n }\n\n /** Whether this target has pending target adds or target removes. */\n get isPending(): boolean {\n return this.pendingResponses !== 0;\n }\n\n /** Whether we have modified any state that should trigger a snapshot. */\n get hasPendingChanges(): boolean {\n return this._hasPendingChanges;\n }\n\n /**\n * Applies the resume token to the TargetChange, but only when it has a new\n * value. Empty resumeTokens are discarded.\n */\n updateResumeToken(resumeToken: ByteString): void {\n if (resumeToken.approximateByteSize() > 0) {\n this._hasPendingChanges = true;\n this._resumeToken = resumeToken;\n }\n }\n\n /**\n * Creates a target change from the current set of changes.\n *\n * To reset the document changes after raising this snapshot, call\n * `clearPendingChanges()`.\n */\n toTargetChange(): TargetChange {\n let addedDocuments = documentKeySet();\n let modifiedDocuments = documentKeySet();\n let removedDocuments = documentKeySet();\n\n this.documentChanges.forEach((key, changeType) => {\n switch (changeType) {\n case ChangeType.Added:\n addedDocuments = addedDocuments.add(key);\n break;\n case ChangeType.Modified:\n modifiedDocuments = modifiedDocuments.add(key);\n break;\n case ChangeType.Removed:\n removedDocuments = removedDocuments.add(key);\n break;\n default:\n fail('Encountered invalid change type: ' + changeType);\n }\n });\n\n return new TargetChange(\n this._resumeToken,\n this._current,\n addedDocuments,\n modifiedDocuments,\n removedDocuments\n );\n }\n\n /**\n * Resets the document changes and sets `hasPendingChanges` to false.\n */\n clearPendingChanges(): void {\n this._hasPendingChanges = false;\n this.documentChanges = snapshotChangesMap();\n }\n\n addDocumentChange(key: DocumentKey, changeType: ChangeType): void {\n this._hasPendingChanges = true;\n this.documentChanges = this.documentChanges.insert(key, changeType);\n }\n\n removeDocumentChange(key: DocumentKey): void {\n this._hasPendingChanges = true;\n this.documentChanges = this.documentChanges.remove(key);\n }\n\n recordPendingTargetRequest(): void {\n this.pendingResponses += 1;\n }\n\n recordTargetResponse(): void {\n this.pendingResponses -= 1;\n }\n\n markCurrent(): void {\n this._hasPendingChanges = true;\n this._current = true;\n }\n}\n\n/**\n * Interface implemented by RemoteStore to expose target metadata to the\n * WatchChangeAggregator.\n */\nexport interface TargetMetadataProvider {\n /**\n * Returns the set of remote document keys for the given target ID as of the\n * last raised snapshot.\n */\n getRemoteKeysForTarget(targetId: TargetId): DocumentKeySet;\n\n /**\n * Returns the TargetData for an active target ID or 'null' if this target\n * has become inactive\n */\n getTargetDataForTarget(targetId: TargetId): TargetData | null;\n}\n\nconst LOG_TAG = 'WatchChangeAggregator';\n\n/**\n * A helper class to accumulate watch changes into a RemoteEvent.\n */\nexport class WatchChangeAggregator {\n constructor(private metadataProvider: TargetMetadataProvider) {}\n\n /** The internal state of all tracked targets. */\n private targetStates = new Map<TargetId, TargetState>();\n\n /** Keeps track of the documents to update since the last raised snapshot. */\n private pendingDocumentUpdates = maybeDocumentMap();\n\n /** A mapping of document keys to their set of target IDs. */\n private pendingDocumentTargetMapping = documentTargetMap();\n\n /**\n * A list of targets with existence filter mismatches. These targets are\n * known to be inconsistent and their listens needs to be re-established by\n * RemoteStore.\n */\n private pendingTargetResets = new SortedSet<TargetId>(primitiveComparator);\n\n /**\n * Processes and adds the DocumentWatchChange to the current set of changes.\n */\n handleDocumentChange(docChange: DocumentWatchChange): void {\n for (const targetId of docChange.updatedTargetIds) {\n if (docChange.newDoc instanceof Document) {\n this.addDocumentToTarget(targetId, docChange.newDoc);\n } else if (docChange.newDoc instanceof NoDocument) {\n this.removeDocumentFromTarget(\n targetId,\n docChange.key,\n docChange.newDoc\n );\n }\n }\n\n for (const targetId of docChange.removedTargetIds) {\n this.removeDocumentFromTarget(targetId, docChange.key, docChange.newDoc);\n }\n }\n\n /** Processes and adds the WatchTargetChange to the current set of changes. */\n handleTargetChange(targetChange: WatchTargetChange): void {\n this.forEachTarget(targetChange, targetId => {\n const targetState = this.ensureTargetState(targetId);\n switch (targetChange.state) {\n case WatchTargetChangeState.NoChange:\n if (this.isActiveTarget(targetId)) {\n targetState.updateResumeToken(targetChange.resumeToken);\n }\n break;\n case WatchTargetChangeState.Added:\n // We need to decrement the number of pending acks needed from watch\n // for this targetId.\n targetState.recordTargetResponse();\n if (!targetState.isPending) {\n // We have a freshly added target, so we need to reset any state\n // that we had previously. This can happen e.g. when remove and add\n // back a target for existence filter mismatches.\n targetState.clearPendingChanges();\n }\n targetState.updateResumeToken(targetChange.resumeToken);\n break;\n case WatchTargetChangeState.Removed:\n // We need to keep track of removed targets to we can post-filter and\n // remove any target changes.\n // We need to decrement the number of pending acks needed from watch\n // for this targetId.\n targetState.recordTargetResponse();\n if (!targetState.isPending) {\n this.removeTarget(targetId);\n }\n debugAssert(\n !targetChange.cause,\n 'WatchChangeAggregator does not handle errored targets'\n );\n break;\n case WatchTargetChangeState.Current:\n if (this.isActiveTarget(targetId)) {\n targetState.markCurrent();\n targetState.updateResumeToken(targetChange.resumeToken);\n }\n break;\n case WatchTargetChangeState.Reset:\n if (this.isActiveTarget(targetId)) {\n // Reset the target and synthesizes removes for all existing\n // documents. The backend will re-add any documents that still\n // match the target before it sends the next global snapshot.\n this.resetTarget(targetId);\n targetState.updateResumeToken(targetChange.resumeToken);\n }\n break;\n default:\n fail('Unknown target watch change state: ' + targetChange.state);\n }\n });\n }\n\n /**\n * Iterates over all targetIds that the watch change applies to: either the\n * targetIds explicitly listed in the change or the targetIds of all currently\n * active targets.\n */\n forEachTarget(\n targetChange: WatchTargetChange,\n fn: (targetId: TargetId) => void\n ): void {\n if (targetChange.targetIds.length > 0) {\n targetChange.targetIds.forEach(fn);\n } else {\n this.targetStates.forEach((_, targetId) => {\n if (this.isActiveTarget(targetId)) {\n fn(targetId);\n }\n });\n }\n }\n\n /**\n * Handles existence filters and synthesizes deletes for filter mismatches.\n * Targets that are invalidated by filter mismatches are added to\n * `pendingTargetResets`.\n */\n handleExistenceFilter(watchChange: ExistenceFilterChange): void {\n const targetId = watchChange.targetId;\n const expectedCount = watchChange.existenceFilter.count;\n\n const targetData = this.targetDataForActiveTarget(targetId);\n if (targetData) {\n const target = targetData.target;\n if (target.isDocumentQuery()) {\n if (expectedCount === 0) {\n // The existence filter told us the document does not exist. We deduce\n // that this document does not exist and apply a deleted document to\n // our updates. Without applying this deleted document there might be\n // another query that will raise this document as part of a snapshot\n // until it is resolved, essentially exposing inconsistency between\n // queries.\n const key = new DocumentKey(target.path);\n this.removeDocumentFromTarget(\n targetId,\n key,\n new NoDocument(key, SnapshotVersion.min())\n );\n } else {\n hardAssert(\n expectedCount === 1,\n 'Single document existence filter with count: ' + expectedCount\n );\n }\n } else {\n const currentSize = this.getCurrentDocumentCountForTarget(targetId);\n if (currentSize !== expectedCount) {\n // Existence filter mismatch: We reset the mapping and raise a new\n // snapshot with `isFromCache:true`.\n this.resetTarget(targetId);\n this.pendingTargetResets = this.pendingTargetResets.add(targetId);\n }\n }\n }\n }\n\n /**\n * Converts the currently accumulated state into a remote event at the\n * provided snapshot version. Resets the accumulated changes before returning.\n */\n createRemoteEvent(snapshotVersion: SnapshotVersion): RemoteEvent {\n const targetChanges = new Map<TargetId, TargetChange>();\n\n this.targetStates.forEach((targetState, targetId) => {\n const targetData = this.targetDataForActiveTarget(targetId);\n if (targetData) {\n if (targetState.current && targetData.target.isDocumentQuery()) {\n // Document queries for document that don't exist can produce an empty\n // result set. To update our local cache, we synthesize a document\n // delete if we have not previously received the document. This\n // resolves the limbo state of the document, removing it from\n // limboDocumentRefs.\n //\n // TODO(dimond): Ideally we would have an explicit lookup target\n // instead resulting in an explicit delete message and we could\n // remove this special logic.\n const key = new DocumentKey(targetData.target.path);\n if (\n this.pendingDocumentUpdates.get(key) === null &&\n !this.targetContainsDocument(targetId, key)\n ) {\n this.removeDocumentFromTarget(\n targetId,\n key,\n new NoDocument(key, snapshotVersion)\n );\n }\n }\n\n if (targetState.hasPendingChanges) {\n targetChanges.set(targetId, targetState.toTargetChange());\n targetState.clearPendingChanges();\n }\n }\n });\n\n let resolvedLimboDocuments = documentKeySet();\n\n // We extract the set of limbo-only document updates as the GC logic\n // special-cases documents that do not appear in the target cache.\n //\n // TODO(gsoltis): Expand on this comment once GC is available in the JS\n // client.\n this.pendingDocumentTargetMapping.forEach((key, targets) => {\n let isOnlyLimboTarget = true;\n\n targets.forEachWhile(targetId => {\n const targetData = this.targetDataForActiveTarget(targetId);\n if (\n targetData &&\n targetData.purpose !== TargetPurpose.LimboResolution\n ) {\n isOnlyLimboTarget = false;\n return false;\n }\n\n return true;\n });\n\n if (isOnlyLimboTarget) {\n resolvedLimboDocuments = resolvedLimboDocuments.add(key);\n }\n });\n\n const remoteEvent = new RemoteEvent(\n snapshotVersion,\n targetChanges,\n this.pendingTargetResets,\n this.pendingDocumentUpdates,\n resolvedLimboDocuments\n );\n\n this.pendingDocumentUpdates = maybeDocumentMap();\n this.pendingDocumentTargetMapping = documentTargetMap();\n this.pendingTargetResets = new SortedSet<TargetId>(primitiveComparator);\n\n return remoteEvent;\n }\n\n /**\n * Adds the provided document to the internal list of document updates and\n * its document key to the given target's mapping.\n */\n // Visible for testing.\n addDocumentToTarget(targetId: TargetId, document: MaybeDocument): void {\n if (!this.isActiveTarget(targetId)) {\n return;\n }\n\n const changeType = this.targetContainsDocument(targetId, document.key)\n ? ChangeType.Modified\n : ChangeType.Added;\n\n const targetState = this.ensureTargetState(targetId);\n targetState.addDocumentChange(document.key, changeType);\n\n this.pendingDocumentUpdates = this.pendingDocumentUpdates.insert(\n document.key,\n document\n );\n\n this.pendingDocumentTargetMapping = this.pendingDocumentTargetMapping.insert(\n document.key,\n this.ensureDocumentTargetMapping(document.key).add(targetId)\n );\n }\n\n /**\n * Removes the provided document from the target mapping. If the\n * document no longer matches the target, but the document's state is still\n * known (e.g. we know that the document was deleted or we received the change\n * that caused the filter mismatch), the new document can be provided\n * to update the remote document cache.\n */\n // Visible for testing.\n removeDocumentFromTarget(\n targetId: TargetId,\n key: DocumentKey,\n updatedDocument: MaybeDocument | null\n ): void {\n if (!this.isActiveTarget(targetId)) {\n return;\n }\n\n const targetState = this.ensureTargetState(targetId);\n if (this.targetContainsDocument(targetId, key)) {\n targetState.addDocumentChange(key, ChangeType.Removed);\n } else {\n // The document may have entered and left the target before we raised a\n // snapshot, so we can just ignore the change.\n targetState.removeDocumentChange(key);\n }\n\n this.pendingDocumentTargetMapping = this.pendingDocumentTargetMapping.insert(\n key,\n this.ensureDocumentTargetMapping(key).delete(targetId)\n );\n\n if (updatedDocument) {\n this.pendingDocumentUpdates = this.pendingDocumentUpdates.insert(\n key,\n updatedDocument\n );\n }\n }\n\n removeTarget(targetId: TargetId): void {\n this.targetStates.delete(targetId);\n }\n\n /**\n * Returns the current count of documents in the target. This includes both\n * the number of documents that the LocalStore considers to be part of the\n * target as well as any accumulated changes.\n */\n private getCurrentDocumentCountForTarget(targetId: TargetId): number {\n const targetState = this.ensureTargetState(targetId);\n const targetChange = targetState.toTargetChange();\n return (\n this.metadataProvider.getRemoteKeysForTarget(targetId).size +\n targetChange.addedDocuments.size -\n targetChange.removedDocuments.size\n );\n }\n\n /**\n * Increment the number of acks needed from watch before we can consider the\n * server to be 'in-sync' with the client's active targets.\n */\n recordPendingTargetRequest(targetId: TargetId): void {\n // For each request we get we need to record we need a response for it.\n const targetState = this.ensureTargetState(targetId);\n targetState.recordPendingTargetRequest();\n }\n\n private ensureTargetState(targetId: TargetId): TargetState {\n let result = this.targetStates.get(targetId);\n if (!result) {\n result = new TargetState();\n this.targetStates.set(targetId, result);\n }\n return result;\n }\n\n private ensureDocumentTargetMapping(key: DocumentKey): SortedSet<TargetId> {\n let targetMapping = this.pendingDocumentTargetMapping.get(key);\n\n if (!targetMapping) {\n targetMapping = new SortedSet<TargetId>(primitiveComparator);\n this.pendingDocumentTargetMapping = this.pendingDocumentTargetMapping.insert(\n key,\n targetMapping\n );\n }\n\n return targetMapping;\n }\n\n /**\n * Verifies that the user is still interested in this target (by calling\n * `getTargetDataForTarget()`) and that we are not waiting for pending ADDs\n * from watch.\n */\n protected isActiveTarget(targetId: TargetId): boolean {\n const targetActive = this.targetDataForActiveTarget(targetId) !== null;\n if (!targetActive) {\n logDebug(LOG_TAG, 'Detected inactive target', targetId);\n }\n return targetActive;\n }\n\n /**\n * Returns the TargetData for an active target (i.e. a target that the user\n * is still interested in that has no outstanding target change requests).\n */\n protected targetDataForActiveTarget(targetId: TargetId): TargetData | null {\n const targetState = this.targetStates.get(targetId);\n return targetState && targetState.isPending\n ? null\n : this.metadataProvider.getTargetDataForTarget(targetId);\n }\n\n /**\n * Resets the state of a Watch target to its initial state (e.g. sets\n * 'current' to false, clears the resume token and removes its target mapping\n * from all documents).\n */\n private resetTarget(targetId: TargetId): void {\n debugAssert(\n !this.targetStates.get(targetId)!.isPending,\n 'Should only reset active targets'\n );\n this.targetStates.set(targetId, new TargetState());\n\n // Trigger removal for any documents currently mapped to this target.\n // These removals will be part of the initial snapshot if Watch does not\n // resend these documents.\n const existingKeys = this.metadataProvider.getRemoteKeysForTarget(targetId);\n existingKeys.forEach(key => {\n this.removeDocumentFromTarget(targetId, key, /*updatedDocument=*/ null);\n });\n }\n /**\n * Returns whether the LocalStore considers the document to be part of the\n * specified target.\n */\n private targetContainsDocument(\n targetId: TargetId,\n key: DocumentKey\n ): boolean {\n const existingKeys = this.metadataProvider.getRemoteKeysForTarget(targetId);\n return existingKeys.has(key);\n }\n}\n\nfunction documentTargetMap(): SortedMap<DocumentKey, SortedSet<TargetId>> {\n return new SortedMap<DocumentKey, SortedSet<TargetId>>(\n DocumentKey.comparator\n );\n}\n\nfunction snapshotChangesMap(): SortedMap<DocumentKey, ChangeType> {\n return new SortedMap<DocumentKey, ChangeType>(DocumentKey.comparator);\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 { SnapshotVersion } from '../core/snapshot_version';\nimport { Transaction } from '../core/transaction';\nimport { OnlineState, TargetId } from '../core/types';\nimport { ignoreIfPrimaryLeaseLoss, LocalStore } from '../local/local_store';\nimport { TargetData, TargetPurpose } from '../local/target_data';\nimport { MutationResult } from '../model/mutation';\nimport {\n BATCHID_UNKNOWN,\n MutationBatch,\n MutationBatchResult\n} from '../model/mutation_batch';\nimport { debugAssert } from '../util/assert';\nimport { FirestoreError } from '../util/error';\nimport { logDebug } from '../util/log';\nimport { DocumentKeySet } from '../model/collections';\nimport { AsyncQueue } from '../util/async_queue';\nimport { ConnectivityMonitor, NetworkStatus } from './connectivity_monitor';\nimport {\n Datastore,\n newPersistentWatchStream,\n newPersistentWriteStream\n} from './datastore';\nimport { OnlineStateTracker } from './online_state_tracker';\nimport {\n PersistentListenStream,\n PersistentWriteStream\n} from './persistent_stream';\nimport { RemoteSyncer } from './remote_syncer';\nimport { isPermanentError, isPermanentWriteError } from './rpc_error';\nimport {\n DocumentWatchChange,\n ExistenceFilterChange,\n TargetMetadataProvider,\n WatchChange,\n WatchChangeAggregator,\n WatchTargetChange,\n WatchTargetChangeState\n} from './watch_change';\nimport { ByteString } from '../util/byte_string';\nimport { isIndexedDbTransactionError } from '../local/simple_db';\n\nconst LOG_TAG = 'RemoteStore';\n\n// TODO(b/35853402): Negotiate this with the stream.\nconst MAX_PENDING_WRITES = 10;\n\n/**\n * RemoteStore - An interface to remotely stored data, basically providing a\n * wrapper around the Datastore that is more reliable for the rest of the\n * system.\n *\n * RemoteStore is responsible for maintaining the connection to the server.\n * - maintaining a list of active listens.\n * - reconnecting when the connection is dropped.\n * - resuming all the active listens on reconnect.\n *\n * RemoteStore handles all incoming events from the Datastore.\n * - listening to the watch stream and repackaging the events as RemoteEvents\n * - notifying SyncEngine of any changes to the active listens.\n *\n * RemoteStore takes writes from other components and handles them reliably.\n * - pulling pending mutations from LocalStore and sending them to Datastore.\n * - retrying mutations that failed because of network problems.\n * - acking mutations to the SyncEngine once they are accepted or rejected.\n */\nexport class RemoteStore implements TargetMetadataProvider {\n /**\n * A list of up to MAX_PENDING_WRITES writes that we have fetched from the\n * LocalStore via fillWritePipeline() and have or will send to the write\n * stream.\n *\n * Whenever writePipeline.length > 0 the RemoteStore will attempt to start or\n * restart the write stream. When the stream is established the writes in the\n * pipeline will be sent in order.\n *\n * Writes remain in writePipeline until they are acknowledged by the backend\n * and thus will automatically be re-sent if the stream is interrupted /\n * restarted before they're acknowledged.\n *\n * Write responses from the backend are linked to their originating request\n * purely based on order, and so we can just shift() writes from the front of\n * the writePipeline as we receive responses.\n */\n private writePipeline: MutationBatch[] = [];\n\n /**\n * A mapping of watched targets that the client cares about tracking and the\n * user has explicitly called a 'listen' for this target.\n *\n * These targets may or may not have been sent to or acknowledged by the\n * server. On re-establishing the listen stream, these targets should be sent\n * to the server. The targets removed with unlistens are removed eagerly\n * without waiting for confirmation from the listen stream.\n */\n private listenTargets = new Map<TargetId, TargetData>();\n\n private connectivityMonitor: ConnectivityMonitor;\n private watchStream: PersistentListenStream;\n private writeStream: PersistentWriteStream;\n private watchChangeAggregator: WatchChangeAggregator | null = null;\n\n /**\n * Set to true by enableNetwork() and false by disableNetwork() and indicates\n * the user-preferred network state.\n */\n private networkEnabled = false;\n\n private isPrimary = false;\n\n /**\n * When set to `true`, the network was taken offline due to an IndexedDB\n * failure. The state is flipped to `false` when access becomes available\n * again.\n */\n private indexedDbFailed = false;\n\n private onlineStateTracker: OnlineStateTracker;\n\n constructor(\n /**\n * The local store, used to fill the write pipeline with outbound mutations.\n */\n private localStore: LocalStore,\n /** The client-side proxy for interacting with the backend. */\n private datastore: Datastore,\n private asyncQueue: AsyncQueue,\n onlineStateHandler: (onlineState: OnlineState) => void,\n connectivityMonitor: ConnectivityMonitor\n ) {\n this.connectivityMonitor = connectivityMonitor;\n this.connectivityMonitor.addCallback((status: NetworkStatus) => {\n asyncQueue.enqueueAndForget(async () => {\n if (this.canUseNetwork()) {\n logDebug(\n LOG_TAG,\n 'Restarting streams for network reachability change.'\n );\n await this.restartNetwork();\n }\n });\n });\n\n this.onlineStateTracker = new OnlineStateTracker(\n asyncQueue,\n onlineStateHandler\n );\n\n // Create streams (but note they're not started yet).\n this.watchStream = newPersistentWatchStream(this.datastore, asyncQueue, {\n onOpen: this.onWatchStreamOpen.bind(this),\n onClose: this.onWatchStreamClose.bind(this),\n onWatchChange: this.onWatchStreamChange.bind(this)\n });\n\n this.writeStream = newPersistentWriteStream(this.datastore, asyncQueue, {\n onOpen: this.onWriteStreamOpen.bind(this),\n onClose: this.onWriteStreamClose.bind(this),\n onHandshakeComplete: this.onWriteHandshakeComplete.bind(this),\n onMutationResult: this.onMutationResult.bind(this)\n });\n }\n\n /**\n * SyncEngine to notify of watch and write events. This must be set\n * immediately after construction.\n */\n syncEngine!: RemoteSyncer;\n\n /**\n * Starts up the remote store, creating streams, restoring state from\n * LocalStore, etc.\n */\n start(): Promise<void> {\n return this.enableNetwork();\n }\n\n /** Re-enables the network. Idempotent. */\n enableNetwork(): Promise<void> {\n this.networkEnabled = true;\n return this.enableNetworkInternal();\n }\n\n private async enableNetworkInternal(): Promise<void> {\n if (this.canUseNetwork()) {\n this.writeStream.lastStreamToken = await this.localStore.getLastStreamToken();\n\n if (this.shouldStartWatchStream()) {\n this.startWatchStream();\n } else {\n this.onlineStateTracker.set(OnlineState.Unknown);\n }\n\n // This will start the write stream if necessary.\n await this.fillWritePipeline();\n }\n }\n\n /**\n * Temporarily disables the network. The network can be re-enabled using\n * enableNetwork().\n */\n async disableNetwork(): Promise<void> {\n this.networkEnabled = false;\n await this.disableNetworkInternal();\n\n // Set the OnlineState to Offline so get()s return from cache, etc.\n this.onlineStateTracker.set(OnlineState.Offline);\n }\n\n private async disableNetworkInternal(): Promise<void> {\n await this.writeStream.stop();\n await this.watchStream.stop();\n\n if (this.writePipeline.length > 0) {\n logDebug(\n LOG_TAG,\n `Stopping write stream with ${this.writePipeline.length} pending writes`\n );\n this.writePipeline = [];\n }\n\n this.cleanUpWatchStreamState();\n }\n\n async shutdown(): Promise<void> {\n logDebug(LOG_TAG, 'RemoteStore shutting down.');\n this.networkEnabled = false;\n await this.disableNetworkInternal();\n this.connectivityMonitor.shutdown();\n\n // Set the OnlineState to Unknown (rather than Offline) to avoid potentially\n // triggering spurious listener events with cached data, etc.\n this.onlineStateTracker.set(OnlineState.Unknown);\n }\n\n /**\n * Starts new listen for the given target. Uses resume token if provided. It\n * is a no-op if the target of given `TargetData` is already being listened to.\n */\n listen(targetData: TargetData): void {\n if (this.listenTargets.has(targetData.targetId)) {\n return;\n }\n\n // Mark this as something the client is currently listening for.\n this.listenTargets.set(targetData.targetId, targetData);\n\n if (this.shouldStartWatchStream()) {\n // The listen will be sent in onWatchStreamOpen\n this.startWatchStream();\n } else if (this.watchStream.isOpen()) {\n this.sendWatchRequest(targetData);\n }\n }\n\n /**\n * Removes the listen from server. It is a no-op if the given target id is\n * not being listened to.\n */\n unlisten(targetId: TargetId): void {\n debugAssert(\n this.listenTargets.has(targetId),\n `unlisten called on target no currently watched: ${targetId}`\n );\n\n this.listenTargets.delete(targetId);\n if (this.watchStream.isOpen()) {\n this.sendUnwatchRequest(targetId);\n }\n\n if (this.listenTargets.size === 0) {\n if (this.watchStream.isOpen()) {\n this.watchStream.markIdle();\n } else if (this.canUseNetwork()) {\n // Revert to OnlineState.Unknown if the watch stream is not open and we\n // have no listeners, since without any listens to send we cannot\n // confirm if the stream is healthy and upgrade to OnlineState.Online.\n this.onlineStateTracker.set(OnlineState.Unknown);\n }\n }\n }\n\n /** {@link TargetMetadataProvider.getTargetDataForTarget} */\n getTargetDataForTarget(targetId: TargetId): TargetData | null {\n return this.listenTargets.get(targetId) || null;\n }\n\n /** {@link TargetMetadataProvider.getRemoteKeysForTarget} */\n getRemoteKeysForTarget(targetId: TargetId): DocumentKeySet {\n return this.syncEngine.getRemoteKeysForTarget(targetId);\n }\n\n /**\n * We need to increment the the expected number of pending responses we're due\n * from watch so we wait for the ack to process any messages from this target.\n */\n private sendWatchRequest(targetData: TargetData): void {\n this.watchChangeAggregator!.recordPendingTargetRequest(targetData.targetId);\n this.watchStream.watch(targetData);\n }\n\n /**\n * We need to increment the expected number of pending responses we're due\n * from watch so we wait for the removal on the server before we process any\n * messages from this target.\n */\n private sendUnwatchRequest(targetId: TargetId): void {\n this.watchChangeAggregator!.recordPendingTargetRequest(targetId);\n this.watchStream.unwatch(targetId);\n }\n\n private startWatchStream(): void {\n debugAssert(\n this.shouldStartWatchStream(),\n 'startWatchStream() called when shouldStartWatchStream() is false.'\n );\n\n this.watchChangeAggregator = new WatchChangeAggregator(this);\n this.watchStream.start();\n this.onlineStateTracker.handleWatchStreamStart();\n }\n\n /**\n * Returns whether the watch stream should be started because it's necessary\n * and has not yet been started.\n */\n private shouldStartWatchStream(): boolean {\n return (\n this.canUseNetwork() &&\n !this.watchStream.isStarted() &&\n this.listenTargets.size > 0\n );\n }\n\n canUseNetwork(): boolean {\n return !this.indexedDbFailed && this.isPrimary && this.networkEnabled;\n }\n\n private cleanUpWatchStreamState(): void {\n this.watchChangeAggregator = null;\n }\n\n private async onWatchStreamOpen(): Promise<void> {\n this.listenTargets.forEach((targetData, targetId) => {\n this.sendWatchRequest(targetData);\n });\n }\n\n private async onWatchStreamClose(error?: FirestoreError): Promise<void> {\n if (error === undefined) {\n // Graceful stop (due to stop() or idle timeout). Make sure that's\n // desirable.\n debugAssert(\n !this.shouldStartWatchStream(),\n 'Watch stream was stopped gracefully while still needed.'\n );\n }\n\n this.cleanUpWatchStreamState();\n\n // If we still need the watch stream, retry the connection.\n if (this.shouldStartWatchStream()) {\n this.onlineStateTracker.handleWatchStreamFailure(error!);\n\n this.startWatchStream();\n } else {\n // No need to restart watch stream because there are no active targets.\n // The online state is set to unknown because there is no active attempt\n // at establishing a connection\n this.onlineStateTracker.set(OnlineState.Unknown);\n }\n }\n\n private async onWatchStreamChange(\n watchChange: WatchChange,\n snapshotVersion: SnapshotVersion\n ): Promise<void> {\n // Mark the client as online since we got a message from the server\n this.onlineStateTracker.set(OnlineState.Online);\n\n if (\n watchChange instanceof WatchTargetChange &&\n watchChange.state === WatchTargetChangeState.Removed &&\n watchChange.cause\n ) {\n // There was an error on a target, don't wait for a consistent snapshot\n // to raise events\n try {\n await this.handleTargetError(watchChange);\n } catch (e) {\n logDebug(\n LOG_TAG,\n 'Failed to remove targets %s: %s ',\n watchChange.targetIds.join(','),\n e\n );\n await this.disableNetworkUntilRecovery(e);\n }\n return;\n }\n\n if (watchChange instanceof DocumentWatchChange) {\n this.watchChangeAggregator!.handleDocumentChange(watchChange);\n } else if (watchChange instanceof ExistenceFilterChange) {\n this.watchChangeAggregator!.handleExistenceFilter(watchChange);\n } else {\n debugAssert(\n watchChange instanceof WatchTargetChange,\n 'Expected watchChange to be an instance of WatchTargetChange'\n );\n this.watchChangeAggregator!.handleTargetChange(watchChange);\n }\n\n if (!snapshotVersion.isEqual(SnapshotVersion.min())) {\n try {\n const lastRemoteSnapshotVersion = await this.localStore.getLastRemoteSnapshotVersion();\n if (snapshotVersion.compareTo(lastRemoteSnapshotVersion) >= 0) {\n // We have received a target change with a global snapshot if the snapshot\n // version is not equal to SnapshotVersion.min().\n await this.raiseWatchSnapshot(snapshotVersion);\n }\n } catch (e) {\n logDebug(LOG_TAG, 'Failed to raise snapshot:', e);\n await this.disableNetworkUntilRecovery(e);\n }\n }\n }\n\n /**\n * Recovery logic for IndexedDB errors that takes the network offline until\n * IndexedDb probing succeeds. Retries are scheduled with backoff using\n * `enqueueRetryable()`.\n */\n private async disableNetworkUntilRecovery(e: FirestoreError): Promise<void> {\n if (isIndexedDbTransactionError(e)) {\n debugAssert(\n !this.indexedDbFailed,\n 'Unexpected network event when IndexedDB was marked failed.'\n );\n this.indexedDbFailed = true;\n\n // Disable network and raise offline snapshots\n await this.disableNetworkInternal();\n this.onlineStateTracker.set(OnlineState.Offline);\n\n // Probe IndexedDB periodically and re-enable network\n this.asyncQueue.enqueueRetryable(async () => {\n logDebug(LOG_TAG, 'Retrying IndexedDB access');\n // Issue a simple read operation to determine if IndexedDB recovered.\n // Ideally, we would expose a health check directly on SimpleDb, but\n // RemoteStore only has access to persistence through LocalStore.\n await this.localStore.getLastRemoteSnapshotVersion();\n this.indexedDbFailed = false;\n await this.enableNetworkInternal();\n });\n } else {\n throw e;\n }\n }\n\n /**\n * Takes a batch of changes from the Datastore, repackages them as a\n * RemoteEvent, and passes that on to the listener, which is typically the\n * SyncEngine.\n */\n private raiseWatchSnapshot(snapshotVersion: SnapshotVersion): Promise<void> {\n debugAssert(\n !snapshotVersion.isEqual(SnapshotVersion.min()),\n \"Can't raise event for unknown SnapshotVersion\"\n );\n const remoteEvent = this.watchChangeAggregator!.createRemoteEvent(\n snapshotVersion\n );\n\n // Update in-memory resume tokens. LocalStore will update the\n // persistent view of these when applying the completed RemoteEvent.\n remoteEvent.targetChanges.forEach((change, targetId) => {\n if (change.resumeToken.approximateByteSize() > 0) {\n const targetData = this.listenTargets.get(targetId);\n // A watched target might have been removed already.\n if (targetData) {\n this.listenTargets.set(\n targetId,\n targetData.withResumeToken(change.resumeToken, snapshotVersion)\n );\n }\n }\n });\n\n // Re-establish listens for the targets that have been invalidated by\n // existence filter mismatches.\n remoteEvent.targetMismatches.forEach(targetId => {\n const targetData = this.listenTargets.get(targetId);\n if (!targetData) {\n // A watched target might have been removed already.\n return;\n }\n\n // Clear the resume token for the target, since we're in a known mismatch\n // state.\n this.listenTargets.set(\n targetId,\n targetData.withResumeToken(\n ByteString.EMPTY_BYTE_STRING,\n targetData.snapshotVersion\n )\n );\n\n // Cause a hard reset by unwatching and rewatching immediately, but\n // deliberately don't send a resume token so that we get a full update.\n this.sendUnwatchRequest(targetId);\n\n // Mark the target we send as being on behalf of an existence filter\n // mismatch, but don't actually retain that in listenTargets. This ensures\n // that we flag the first re-listen this way without impacting future\n // listens of this target (that might happen e.g. on reconnect).\n const requestTargetData = new TargetData(\n targetData.target,\n targetId,\n TargetPurpose.ExistenceFilterMismatch,\n targetData.sequenceNumber\n );\n this.sendWatchRequest(requestTargetData);\n });\n\n // Finally raise remote event\n return this.syncEngine.applyRemoteEvent(remoteEvent);\n }\n\n /** Handles an error on a target */\n private async handleTargetError(\n watchChange: WatchTargetChange\n ): Promise<void> {\n debugAssert(!!watchChange.cause, 'Handling target error without a cause');\n const error = watchChange.cause!;\n for (const targetId of watchChange.targetIds) {\n // A watched target might have been removed already.\n if (this.listenTargets.has(targetId)) {\n await this.syncEngine.rejectListen(targetId, error);\n this.listenTargets.delete(targetId);\n this.watchChangeAggregator!.removeTarget(targetId);\n }\n }\n }\n\n /**\n * Attempts to fill our write pipeline with writes from the LocalStore.\n *\n * Called internally to bootstrap or refill the write pipeline and by\n * SyncEngine whenever there are new mutations to process.\n *\n * Starts the write stream if necessary.\n */\n async fillWritePipeline(): Promise<void> {\n if (this.canAddToWritePipeline()) {\n const lastBatchIdRetrieved =\n this.writePipeline.length > 0\n ? this.writePipeline[this.writePipeline.length - 1].batchId\n : BATCHID_UNKNOWN;\n const batch = await this.localStore.nextMutationBatch(\n lastBatchIdRetrieved\n );\n\n if (batch === null) {\n if (this.writePipeline.length === 0) {\n this.writeStream.markIdle();\n }\n } else {\n this.addToWritePipeline(batch);\n await this.fillWritePipeline();\n }\n }\n\n if (this.shouldStartWriteStream()) {\n this.startWriteStream();\n }\n }\n\n /**\n * Returns true if we can add to the write pipeline (i.e. the network is\n * enabled and the write pipeline is not full).\n */\n private canAddToWritePipeline(): boolean {\n return (\n this.canUseNetwork() && this.writePipeline.length < MAX_PENDING_WRITES\n );\n }\n\n // For testing\n outstandingWrites(): number {\n return this.writePipeline.length;\n }\n\n /**\n * Queues additional writes to be sent to the write stream, sending them\n * immediately if the write stream is established.\n */\n private addToWritePipeline(batch: MutationBatch): void {\n debugAssert(\n this.canAddToWritePipeline(),\n 'addToWritePipeline called when pipeline is full'\n );\n this.writePipeline.push(batch);\n\n if (this.writeStream.isOpen() && this.writeStream.handshakeComplete) {\n this.writeStream.writeMutations(batch.mutations);\n }\n }\n\n private shouldStartWriteStream(): boolean {\n return (\n this.canUseNetwork() &&\n !this.writeStream.isStarted() &&\n this.writePipeline.length > 0\n );\n }\n\n private startWriteStream(): void {\n debugAssert(\n this.shouldStartWriteStream(),\n 'startWriteStream() called when shouldStartWriteStream() is false.'\n );\n this.writeStream.start();\n }\n\n private async onWriteStreamOpen(): Promise<void> {\n this.writeStream.writeHandshake();\n }\n\n private onWriteHandshakeComplete(): Promise<void> {\n // Record the stream token.\n return this.localStore\n .setLastStreamToken(this.writeStream.lastStreamToken)\n .then(() => {\n // Send the write pipeline now that the stream is established.\n for (const batch of this.writePipeline) {\n this.writeStream.writeMutations(batch.mutations);\n }\n })\n .catch(ignoreIfPrimaryLeaseLoss);\n }\n\n private onMutationResult(\n commitVersion: SnapshotVersion,\n results: MutationResult[]\n ): Promise<void> {\n // This is a response to a write containing mutations and should be\n // correlated to the first write in our write pipeline.\n debugAssert(\n this.writePipeline.length > 0,\n 'Got result for empty write pipeline'\n );\n const batch = this.writePipeline.shift()!;\n const success = MutationBatchResult.from(\n batch,\n commitVersion,\n results,\n this.writeStream.lastStreamToken\n );\n return this.syncEngine.applySuccessfulWrite(success).then(() => {\n // It's possible that with the completion of this mutation another\n // slot has freed up.\n return this.fillWritePipeline();\n });\n }\n\n private async onWriteStreamClose(error?: FirestoreError): Promise<void> {\n if (error === undefined) {\n // Graceful stop (due to stop() or idle timeout). Make sure that's\n // desirable.\n debugAssert(\n !this.shouldStartWriteStream(),\n 'Write stream was stopped gracefully while still needed.'\n );\n }\n\n // If the write stream closed due to an error, invoke the error callbacks if\n // there are pending writes.\n if (error && this.writePipeline.length > 0) {\n if (this.writeStream.handshakeComplete) {\n // This error affects the actual write.\n await this.handleWriteError(error!);\n } else {\n // If there was an error before the handshake has finished, it's\n // possible that the server is unable to process the stream token\n // we're sending. (Perhaps it's too old?)\n await this.handleHandshakeError(error!);\n }\n\n // The write stream might have been started by refilling the write\n // pipeline for failed writes\n if (this.shouldStartWriteStream()) {\n this.startWriteStream();\n }\n }\n // No pending writes, nothing to do\n }\n\n private async handleHandshakeError(error: FirestoreError): Promise<void> {\n // Reset the token if it's a permanent error, signaling the write stream is\n // no longer valid. Note that the handshake does not count as a write: see\n // comments on isPermanentWriteError for details.\n if (isPermanentError(error.code)) {\n logDebug(\n LOG_TAG,\n 'RemoteStore error before completed handshake; resetting stream token: ',\n this.writeStream.lastStreamToken\n );\n this.writeStream.lastStreamToken = ByteString.EMPTY_BYTE_STRING;\n\n return this.localStore\n .setLastStreamToken(ByteString.EMPTY_BYTE_STRING)\n .catch(ignoreIfPrimaryLeaseLoss);\n } else {\n // Some other error, don't reset stream token. Our stream logic will\n // just retry with exponential backoff.\n }\n }\n\n private async handleWriteError(error: FirestoreError): Promise<void> {\n // Only handle permanent errors here. If it's transient, just let the retry\n // logic kick in.\n if (isPermanentWriteError(error.code)) {\n // This was a permanent error, the request itself was the problem\n // so it's not going to succeed if we resend it.\n const batch = this.writePipeline.shift()!;\n\n // In this case it's also unlikely that the server itself is melting\n // down -- this was just a bad request so inhibit backoff on the next\n // restart.\n this.writeStream.inhibitBackoff();\n\n return this.syncEngine\n .rejectFailedWrite(batch.batchId, error)\n .then(() => {\n // It's possible that with the completion of this mutation\n // another slot has freed up.\n return this.fillWritePipeline();\n });\n } else {\n // Transient error, just let the retry logic kick in.\n }\n }\n\n createTransaction(): Transaction {\n return new Transaction(this.datastore);\n }\n\n private async restartNetwork(): Promise<void> {\n this.networkEnabled = false;\n await this.disableNetworkInternal();\n this.onlineStateTracker.set(OnlineState.Unknown);\n await this.enableNetwork();\n }\n\n async handleCredentialChange(): Promise<void> {\n if (this.canUseNetwork()) {\n // Tear down and re-create our network streams. This will ensure we get a fresh auth token\n // for the new user and re-fill the write pipeline with new mutations from the LocalStore\n // (since mutations are per-user).\n logDebug(LOG_TAG, 'RemoteStore restarting streams for new credential');\n await this.restartNetwork();\n }\n }\n\n /**\n * Toggles the network state when the client gains or loses its primary lease.\n */\n async applyPrimaryState(isPrimary: boolean): Promise<void> {\n this.isPrimary = isPrimary;\n\n if (isPrimary && this.networkEnabled) {\n await this.enableNetwork();\n } else if (!isPrimary) {\n await this.disableNetworkInternal();\n this.onlineStateTracker.set(OnlineState.Unknown);\n }\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 { debugAssert } from '../util/assert';\nimport { EventHandler } from '../util/misc';\nimport { ObjectMap } from '../util/obj_map';\nimport { Query } from './query';\nimport { SyncEngine, SyncEngineListener } from './sync_engine';\nimport { OnlineState } from './types';\nimport { ChangeType, DocumentViewChange, ViewSnapshot } from './view_snapshot';\nimport { wrapInUserErrorIfRecoverable } from '../util/async_queue';\n\n/**\n * Holds the listeners and the last received ViewSnapshot for a query being\n * tracked by EventManager.\n */\nclass QueryListenersInfo {\n viewSnap: ViewSnapshot | undefined = undefined;\n listeners: QueryListener[] = [];\n}\n\n/**\n * Interface for handling events from the EventManager.\n */\nexport interface Observer<T> {\n next: EventHandler<T>;\n error: EventHandler<Error>;\n}\n\n/**\n * EventManager is responsible for mapping queries to query event emitters.\n * It handles \"fan-out\". -- Identical queries will re-use the same watch on the\n * backend.\n */\nexport class EventManager implements SyncEngineListener {\n private queries = new ObjectMap<Query, QueryListenersInfo>(q =>\n q.canonicalId()\n );\n\n private onlineState = OnlineState.Unknown;\n\n private snapshotsInSyncListeners: Set<Observer<void>> = new Set();\n\n constructor(private syncEngine: SyncEngine) {\n this.syncEngine.subscribe(this);\n }\n\n async listen(listener: QueryListener): Promise<void> {\n const query = listener.query;\n let firstListen = false;\n\n let queryInfo = this.queries.get(query);\n if (!queryInfo) {\n firstListen = true;\n queryInfo = new QueryListenersInfo();\n }\n\n if (firstListen) {\n try {\n queryInfo.viewSnap = await this.syncEngine.listen(query);\n } catch (e) {\n const firestoreError = wrapInUserErrorIfRecoverable(\n e,\n `Initialization of query '${listener.query}' failed`\n );\n listener.onError(firestoreError);\n return;\n }\n }\n\n this.queries.set(query, queryInfo);\n queryInfo.listeners.push(listener);\n\n // Run global snapshot listeners if a consistent snapshot has been emitted.\n const raisedEvent = listener.applyOnlineStateChange(this.onlineState);\n debugAssert(\n !raisedEvent,\n \"applyOnlineStateChange() shouldn't raise an event for brand-new listeners.\"\n );\n\n if (queryInfo.viewSnap) {\n const raisedEvent = listener.onViewSnapshot(queryInfo.viewSnap);\n if (raisedEvent) {\n this.raiseSnapshotsInSyncEvent();\n }\n }\n }\n\n async unlisten(listener: QueryListener): Promise<void> {\n const query = listener.query;\n let lastListen = false;\n\n const queryInfo = this.queries.get(query);\n if (queryInfo) {\n const i = queryInfo.listeners.indexOf(listener);\n if (i >= 0) {\n queryInfo.listeners.splice(i, 1);\n lastListen = queryInfo.listeners.length === 0;\n }\n }\n\n if (lastListen) {\n this.queries.delete(query);\n return this.syncEngine.unlisten(query);\n }\n }\n\n onWatchChange(viewSnaps: ViewSnapshot[]): void {\n let raisedEvent = false;\n for (const viewSnap of viewSnaps) {\n const query = viewSnap.query;\n const queryInfo = this.queries.get(query);\n if (queryInfo) {\n for (const listener of queryInfo.listeners) {\n if (listener.onViewSnapshot(viewSnap)) {\n raisedEvent = true;\n }\n }\n queryInfo.viewSnap = viewSnap;\n }\n }\n if (raisedEvent) {\n this.raiseSnapshotsInSyncEvent();\n }\n }\n\n onWatchError(query: Query, error: Error): void {\n const queryInfo = this.queries.get(query);\n if (queryInfo) {\n for (const listener of queryInfo.listeners) {\n listener.onError(error);\n }\n }\n\n // Remove all listeners. NOTE: We don't need to call syncEngine.unlisten()\n // after an error.\n this.queries.delete(query);\n }\n\n onOnlineStateChange(onlineState: OnlineState): void {\n this.onlineState = onlineState;\n let raisedEvent = false;\n this.queries.forEach((_, queryInfo) => {\n for (const listener of queryInfo.listeners) {\n // Run global snapshot listeners if a consistent snapshot has been emitted.\n if (listener.applyOnlineStateChange(onlineState)) {\n raisedEvent = true;\n }\n }\n });\n if (raisedEvent) {\n this.raiseSnapshotsInSyncEvent();\n }\n }\n\n addSnapshotsInSyncListener(observer: Observer<void>): void {\n this.snapshotsInSyncListeners.add(observer);\n // Immediately fire an initial event, indicating all existing listeners\n // are in-sync.\n observer.next();\n }\n\n removeSnapshotsInSyncListener(observer: Observer<void>): void {\n this.snapshotsInSyncListeners.delete(observer);\n }\n\n // Call all global snapshot listeners that have been set.\n private raiseSnapshotsInSyncEvent(): void {\n this.snapshotsInSyncListeners.forEach(observer => {\n observer.next();\n });\n }\n}\n\nexport interface ListenOptions {\n /** Raise events even when only the metadata changes */\n readonly includeMetadataChanges?: boolean;\n\n /**\n * Wait for a sync with the server when online, but still raise events while\n * offline.\n */\n readonly waitForSyncWhenOnline?: boolean;\n}\n\n/**\n * QueryListener takes a series of internal view snapshots and determines\n * when to raise the event.\n *\n * It uses an Observer to dispatch events.\n */\nexport class QueryListener {\n /**\n * Initial snapshots (e.g. from cache) may not be propagated to the wrapped\n * observer. This flag is set to true once we've actually raised an event.\n */\n private raisedInitialEvent = false;\n\n private options: ListenOptions;\n\n private snap: ViewSnapshot | null = null;\n\n private onlineState = OnlineState.Unknown;\n\n constructor(\n readonly query: Query,\n private queryObserver: Observer<ViewSnapshot>,\n options?: ListenOptions\n ) {\n this.options = options || {};\n }\n\n /**\n * Applies the new ViewSnapshot to this listener, raising a user-facing event\n * if applicable (depending on what changed, whether the user has opted into\n * metadata-only changes, etc.). Returns true if a user-facing event was\n * indeed raised.\n */\n onViewSnapshot(snap: ViewSnapshot): boolean {\n debugAssert(\n snap.docChanges.length > 0 || snap.syncStateChanged,\n 'We got a new snapshot with no changes?'\n );\n\n if (!this.options.includeMetadataChanges) {\n // Remove the metadata only changes.\n const docChanges: DocumentViewChange[] = [];\n for (const docChange of snap.docChanges) {\n if (docChange.type !== ChangeType.Metadata) {\n docChanges.push(docChange);\n }\n }\n snap = new ViewSnapshot(\n snap.query,\n snap.docs,\n snap.oldDocs,\n docChanges,\n snap.mutatedKeys,\n snap.fromCache,\n snap.syncStateChanged,\n /* excludesMetadataChanges= */ true\n );\n }\n let raisedEvent = false;\n if (!this.raisedInitialEvent) {\n if (this.shouldRaiseInitialEvent(snap, this.onlineState)) {\n this.raiseInitialEvent(snap);\n raisedEvent = true;\n }\n } else if (this.shouldRaiseEvent(snap)) {\n this.queryObserver.next(snap);\n raisedEvent = true;\n }\n\n this.snap = snap;\n return raisedEvent;\n }\n\n onError(error: Error): void {\n this.queryObserver.error(error);\n }\n\n /** Returns whether a snapshot was raised. */\n applyOnlineStateChange(onlineState: OnlineState): boolean {\n this.onlineState = onlineState;\n let raisedEvent = false;\n if (\n this.snap &&\n !this.raisedInitialEvent &&\n this.shouldRaiseInitialEvent(this.snap, onlineState)\n ) {\n this.raiseInitialEvent(this.snap);\n raisedEvent = true;\n }\n return raisedEvent;\n }\n\n private shouldRaiseInitialEvent(\n snap: ViewSnapshot,\n onlineState: OnlineState\n ): boolean {\n debugAssert(\n !this.raisedInitialEvent,\n 'Determining whether to raise first event but already had first event'\n );\n\n // Always raise the first event when we're synced\n if (!snap.fromCache) {\n return true;\n }\n\n // NOTE: We consider OnlineState.Unknown as online (it should become Offline\n // or Online if we wait long enough).\n const maybeOnline = onlineState !== OnlineState.Offline;\n // Don't raise the event if we're online, aren't synced yet (checked\n // above) and are waiting for a sync.\n if (this.options.waitForSyncWhenOnline && maybeOnline) {\n debugAssert(\n snap.fromCache,\n 'Waiting for sync, but snapshot is not from cache'\n );\n return false;\n }\n\n // Raise data from cache if we have any documents or we are offline\n return !snap.docs.isEmpty() || onlineState === OnlineState.Offline;\n }\n\n private shouldRaiseEvent(snap: ViewSnapshot): boolean {\n // We don't need to handle includeDocumentMetadataChanges here because\n // the Metadata only changes have already been stripped out if needed.\n // At this point the only changes we will see are the ones we should\n // propagate.\n if (snap.docChanges.length > 0) {\n return true;\n }\n\n const hasPendingWritesChanged =\n this.snap && this.snap.hasPendingWrites !== snap.hasPendingWrites;\n if (snap.syncStateChanged || hasPendingWritesChanged) {\n return this.options.includeMetadataChanges === true;\n }\n\n // Generally we should have hit one of the cases above, but it's possible\n // to get here if there were only metadata docChanges and they got\n // stripped out.\n return false;\n }\n\n private raiseInitialEvent(snap: ViewSnapshot): void {\n debugAssert(\n !this.raisedInitialEvent,\n 'Trying to raise initial events for second time'\n );\n snap = ViewSnapshot.fromInitialDocuments(\n snap.query,\n snap.docs,\n snap.mutatedKeys,\n snap.fromCache\n );\n this.raisedInitialEvent = true;\n this.queryObserver.next(snap);\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 { QueryEngine } from './query_engine';\nimport { LocalDocumentsView } from './local_documents_view';\nimport { PersistenceTransaction } from './persistence';\nimport { PersistencePromise } from './persistence_promise';\nimport { LimitType, Query } from '../core/query';\nimport { SnapshotVersion } from '../core/snapshot_version';\nimport {\n DocumentKeySet,\n DocumentMap,\n MaybeDocumentMap\n} from '../model/collections';\nimport { Document } from '../model/document';\nimport { debugAssert } from '../util/assert';\nimport { getLogLevel, LogLevel, logDebug } from '../util/log';\nimport { SortedSet } from '../util/sorted_set';\n\n// TOOD(b/140938512): Drop SimpleQueryEngine and rename IndexFreeQueryEngine.\n\n/**\n * A query engine that takes advantage of the target document mapping in the\n * QueryCache. The IndexFreeQueryEngine optimizes query execution by only\n * reading the documents that previously matched a query plus any documents that were\n * edited after the query was last listened to.\n *\n * There are some cases where Index-Free queries are not guaranteed to produce\n * the same results as full collection scans. In these cases, the\n * IndexFreeQueryEngine falls back to full query processing. These cases are:\n *\n * - Limit queries where a document that matched the query previously no longer\n * matches the query.\n *\n * - Limit queries where a document edit may cause the document to sort below\n * another document that is in the local cache.\n *\n * - Queries that have never been CURRENT or free of Limbo documents.\n */\nexport class IndexFreeQueryEngine implements QueryEngine {\n private localDocumentsView: LocalDocumentsView | undefined;\n\n setLocalDocumentsView(localDocuments: LocalDocumentsView): void {\n this.localDocumentsView = localDocuments;\n }\n\n getDocumentsMatchingQuery(\n transaction: PersistenceTransaction,\n query: Query,\n lastLimboFreeSnapshotVersion: SnapshotVersion,\n remoteKeys: DocumentKeySet\n ): PersistencePromise<DocumentMap> {\n debugAssert(\n this.localDocumentsView !== undefined,\n 'setLocalDocumentsView() not called'\n );\n\n // Queries that match all documents don't benefit from using\n // IndexFreeQueries. It is more efficient to scan all documents in a\n // collection, rather than to perform individual lookups.\n if (query.matchesAllDocuments()) {\n return this.executeFullCollectionScan(transaction, query);\n }\n\n // Queries that have never seen a snapshot without limbo free documents\n // should also be run as a full collection scan.\n if (lastLimboFreeSnapshotVersion.isEqual(SnapshotVersion.min())) {\n return this.executeFullCollectionScan(transaction, query);\n }\n\n return this.localDocumentsView!.getDocuments(transaction, remoteKeys).next(\n documents => {\n const previousResults = this.applyQuery(query, documents);\n\n if (\n (query.hasLimitToFirst() || query.hasLimitToLast()) &&\n this.needsRefill(\n query.limitType,\n previousResults,\n remoteKeys,\n lastLimboFreeSnapshotVersion\n )\n ) {\n return this.executeFullCollectionScan(transaction, query);\n }\n\n if (getLogLevel() <= LogLevel.DEBUG) {\n logDebug(\n 'IndexFreeQueryEngine',\n 'Re-using previous result from %s to execute query: %s',\n lastLimboFreeSnapshotVersion.toString(),\n query.toString()\n );\n }\n\n // Retrieve all results for documents that were updated since the last\n // limbo-document free remote snapshot.\n return this.localDocumentsView!.getDocumentsMatchingQuery(\n transaction,\n query,\n lastLimboFreeSnapshotVersion\n ).next(updatedResults => {\n // We merge `previousResults` into `updateResults`, since\n // `updateResults` is already a DocumentMap. If a document is\n // contained in both lists, then its contents are the same.\n previousResults.forEach(doc => {\n updatedResults = updatedResults.insert(doc.key, doc);\n });\n return updatedResults;\n });\n }\n );\n }\n\n /** Applies the query filter and sorting to the provided documents. */\n private applyQuery(\n query: Query,\n documents: MaybeDocumentMap\n ): SortedSet<Document> {\n // Sort the documents and re-apply the query filter since previously\n // matching documents do not necessarily still match the query.\n let queryResults = new SortedSet<Document>((d1, d2) =>\n query.docComparator(d1, d2)\n );\n documents.forEach((_, maybeDoc) => {\n if (maybeDoc instanceof Document && query.matches(maybeDoc)) {\n queryResults = queryResults.add(maybeDoc);\n }\n });\n return queryResults;\n }\n\n /**\n * Determines if a limit query needs to be refilled from cache, making it\n * ineligible for index-free execution.\n *\n * @param sortedPreviousResults The documents that matched the query when it\n * was last synchronized, sorted by the query's comparator.\n * @param remoteKeys The document keys that matched the query at the last\n * snapshot.\n * @param limboFreeSnapshotVersion The version of the snapshot when the query\n * was last synchronized.\n */\n private needsRefill(\n limitType: LimitType,\n sortedPreviousResults: SortedSet<Document>,\n remoteKeys: DocumentKeySet,\n limboFreeSnapshotVersion: SnapshotVersion\n ): boolean {\n // The query needs to be refilled if a previously matching document no\n // longer matches.\n if (remoteKeys.size !== sortedPreviousResults.size) {\n return true;\n }\n\n // Limit queries are not eligible for index-free query execution if there is\n // a potential that an older document from cache now sorts before a document\n // that was previously part of the limit. This, however, can only happen if\n // the document at the edge of the limit goes out of limit.\n // If a document that is not the limit boundary sorts differently,\n // the boundary of the limit itself did not change and documents from cache\n // will continue to be \"rejected\" by this boundary. Therefore, we can ignore\n // any modifications that don't affect the last document.\n const docAtLimitEdge =\n limitType === LimitType.First\n ? sortedPreviousResults.last()\n : sortedPreviousResults.first();\n if (!docAtLimitEdge) {\n // We don't need to refill the query if there were already no documents.\n return false;\n }\n return (\n docAtLimitEdge.hasPendingWrites ||\n docAtLimitEdge.version.compareTo(limboFreeSnapshotVersion) > 0\n );\n }\n\n private executeFullCollectionScan(\n transaction: PersistenceTransaction,\n query: Query\n ): PersistencePromise<DocumentMap> {\n if (getLogLevel() <= LogLevel.DEBUG) {\n logDebug(\n 'IndexFreeQueryEngine',\n 'Using full collection scan to execute query:',\n query.toString()\n );\n }\n\n return this.localDocumentsView!.getDocumentsMatchingQuery(\n transaction,\n query,\n SnapshotVersion.min()\n );\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 { Timestamp } from '../api/timestamp';\nimport { Query } from '../core/query';\nimport { BatchId } from '../core/types';\nimport { DocumentKey } from '../model/document_key';\nimport { Mutation } from '../model/mutation';\nimport { MutationBatch, BATCHID_UNKNOWN } from '../model/mutation_batch';\nimport { debugAssert, hardAssert } from '../util/assert';\nimport { primitiveComparator } from '../util/misc';\nimport { ByteString } from '../util/byte_string';\nimport { SortedMap } from '../util/sorted_map';\nimport { SortedSet } from '../util/sorted_set';\n\nimport { IndexManager } from './index_manager';\nimport { MutationQueue } from './mutation_queue';\nimport { PersistenceTransaction, ReferenceDelegate } from './persistence';\nimport { PersistencePromise } from './persistence_promise';\nimport { DocReference } from './reference_set';\n\nexport class MemoryMutationQueue implements MutationQueue {\n /**\n * The set of all mutations that have been sent but not yet been applied to\n * the backend.\n */\n private mutationQueue: MutationBatch[] = [];\n\n /** Next value to use when assigning sequential IDs to each mutation batch. */\n private nextBatchId: BatchId = 1;\n\n /** The last received stream token from the server, used to acknowledge which\n * responses the client has processed. Stream tokens are opaque checkpoint\n * markers whose only real value is their inclusion in the next request.\n */\n private lastStreamToken: ByteString = ByteString.EMPTY_BYTE_STRING;\n\n /** An ordered mapping between documents and the mutations batch IDs. */\n private batchesByDocumentKey = new SortedSet(DocReference.compareByKey);\n\n constructor(\n private readonly indexManager: IndexManager,\n private readonly referenceDelegate: ReferenceDelegate\n ) {}\n\n checkEmpty(transaction: PersistenceTransaction): PersistencePromise<boolean> {\n return PersistencePromise.resolve(this.mutationQueue.length === 0);\n }\n\n acknowledgeBatch(\n transaction: PersistenceTransaction,\n batch: MutationBatch,\n streamToken: ByteString\n ): PersistencePromise<void> {\n const batchId = batch.batchId;\n const batchIndex = this.indexOfExistingBatchId(batchId, 'acknowledged');\n hardAssert(\n batchIndex === 0,\n 'Can only acknowledge the first batch in the mutation queue'\n );\n\n // Verify that the batch in the queue is the one to be acknowledged.\n const check = this.mutationQueue[batchIndex];\n debugAssert(\n batchId === check.batchId,\n 'Queue ordering failure: expected batch ' +\n batchId +\n ', got batch ' +\n check.batchId\n );\n\n this.lastStreamToken = streamToken;\n return PersistencePromise.resolve();\n }\n\n getLastStreamToken(\n transaction: PersistenceTransaction\n ): PersistencePromise<ByteString> {\n return PersistencePromise.resolve(this.lastStreamToken);\n }\n\n setLastStreamToken(\n transaction: PersistenceTransaction,\n streamToken: ByteString\n ): PersistencePromise<void> {\n this.lastStreamToken = streamToken;\n return PersistencePromise.resolve();\n }\n\n addMutationBatch(\n transaction: PersistenceTransaction,\n localWriteTime: Timestamp,\n baseMutations: Mutation[],\n mutations: Mutation[]\n ): PersistencePromise<MutationBatch> {\n debugAssert(mutations.length !== 0, 'Mutation batches should not be empty');\n\n const batchId = this.nextBatchId;\n this.nextBatchId++;\n\n if (this.mutationQueue.length > 0) {\n const prior = this.mutationQueue[this.mutationQueue.length - 1];\n debugAssert(\n prior.batchId < batchId,\n 'Mutation batchIDs must be monotonically increasing order'\n );\n }\n\n const batch = new MutationBatch(\n batchId,\n localWriteTime,\n baseMutations,\n mutations\n );\n this.mutationQueue.push(batch);\n\n // Track references by document key and index collection parents.\n for (const mutation of mutations) {\n this.batchesByDocumentKey = this.batchesByDocumentKey.add(\n new DocReference(mutation.key, batchId)\n );\n\n this.indexManager.addToCollectionParentIndex(\n transaction,\n mutation.key.path.popLast()\n );\n }\n\n return PersistencePromise.resolve(batch);\n }\n\n lookupMutationBatch(\n transaction: PersistenceTransaction,\n batchId: BatchId\n ): PersistencePromise<MutationBatch | null> {\n return PersistencePromise.resolve(this.findMutationBatch(batchId));\n }\n\n getNextMutationBatchAfterBatchId(\n transaction: PersistenceTransaction,\n batchId: BatchId\n ): PersistencePromise<MutationBatch | null> {\n const nextBatchId = batchId + 1;\n\n // The requested batchId may still be out of range so normalize it to the\n // start of the queue.\n const rawIndex = this.indexOfBatchId(nextBatchId);\n const index = rawIndex < 0 ? 0 : rawIndex;\n return PersistencePromise.resolve(\n this.mutationQueue.length > index ? this.mutationQueue[index] : null\n );\n }\n\n getHighestUnacknowledgedBatchId(): PersistencePromise<BatchId> {\n return PersistencePromise.resolve(\n this.mutationQueue.length === 0 ? BATCHID_UNKNOWN : this.nextBatchId - 1\n );\n }\n\n getAllMutationBatches(\n transaction: PersistenceTransaction\n ): PersistencePromise<MutationBatch[]> {\n return PersistencePromise.resolve(this.mutationQueue.slice());\n }\n\n getAllMutationBatchesAffectingDocumentKey(\n transaction: PersistenceTransaction,\n documentKey: DocumentKey\n ): PersistencePromise<MutationBatch[]> {\n const start = new DocReference(documentKey, 0);\n const end = new DocReference(documentKey, Number.POSITIVE_INFINITY);\n const result: MutationBatch[] = [];\n this.batchesByDocumentKey.forEachInRange([start, end], ref => {\n debugAssert(\n documentKey.isEqual(ref.key),\n \"Should only iterate over a single key's batches\"\n );\n const batch = this.findMutationBatch(ref.targetOrBatchId);\n debugAssert(\n batch !== null,\n 'Batches in the index must exist in the main table'\n );\n result.push(batch!);\n });\n\n return PersistencePromise.resolve(result);\n }\n\n getAllMutationBatchesAffectingDocumentKeys(\n transaction: PersistenceTransaction,\n documentKeys: SortedMap<DocumentKey, unknown>\n ): PersistencePromise<MutationBatch[]> {\n let uniqueBatchIDs = new SortedSet<number>(primitiveComparator);\n\n documentKeys.forEach(documentKey => {\n const start = new DocReference(documentKey, 0);\n const end = new DocReference(documentKey, Number.POSITIVE_INFINITY);\n this.batchesByDocumentKey.forEachInRange([start, end], ref => {\n debugAssert(\n documentKey.isEqual(ref.key),\n \"For each key, should only iterate over a single key's batches\"\n );\n\n uniqueBatchIDs = uniqueBatchIDs.add(ref.targetOrBatchId);\n });\n });\n\n return PersistencePromise.resolve(this.findMutationBatches(uniqueBatchIDs));\n }\n\n getAllMutationBatchesAffectingQuery(\n transaction: PersistenceTransaction,\n query: Query\n ): PersistencePromise<MutationBatch[]> {\n debugAssert(\n !query.isCollectionGroupQuery(),\n 'CollectionGroup queries should be handled in LocalDocumentsView'\n );\n // Use the query path as a prefix for testing if a document matches the\n // query.\n const prefix = query.path;\n const immediateChildrenPathLength = prefix.length + 1;\n\n // Construct a document reference for actually scanning the index. Unlike\n // the prefix the document key in this reference must have an even number of\n // segments. The empty segment can be used a suffix of the query path\n // because it precedes all other segments in an ordered traversal.\n let startPath = prefix;\n if (!DocumentKey.isDocumentKey(startPath)) {\n startPath = startPath.child('');\n }\n\n const start = new DocReference(new DocumentKey(startPath), 0);\n\n // Find unique batchIDs referenced by all documents potentially matching the\n // query.\n let uniqueBatchIDs = new SortedSet<number>(primitiveComparator);\n\n this.batchesByDocumentKey.forEachWhile(ref => {\n const rowKeyPath = ref.key.path;\n if (!prefix.isPrefixOf(rowKeyPath)) {\n return false;\n } else {\n // Rows with document keys more than one segment longer than the query\n // path can't be matches. For example, a query on 'rooms' can't match\n // the document /rooms/abc/messages/xyx.\n // TODO(mcg): we'll need a different scanner when we implement\n // ancestor queries.\n if (rowKeyPath.length === immediateChildrenPathLength) {\n uniqueBatchIDs = uniqueBatchIDs.add(ref.targetOrBatchId);\n }\n return true;\n }\n }, start);\n\n return PersistencePromise.resolve(this.findMutationBatches(uniqueBatchIDs));\n }\n\n private findMutationBatches(batchIDs: SortedSet<number>): MutationBatch[] {\n // Construct an array of matching batches, sorted by batchID to ensure that\n // multiple mutations affecting the same document key are applied in order.\n const result: MutationBatch[] = [];\n batchIDs.forEach(batchId => {\n const batch = this.findMutationBatch(batchId);\n if (batch !== null) {\n result.push(batch);\n }\n });\n return result;\n }\n\n removeMutationBatch(\n transaction: PersistenceTransaction,\n batch: MutationBatch\n ): PersistencePromise<void> {\n // Find the position of the first batch for removal.\n const batchIndex = this.indexOfExistingBatchId(batch.batchId, 'removed');\n hardAssert(\n batchIndex === 0,\n 'Can only remove the first entry of the mutation queue'\n );\n this.mutationQueue.shift();\n\n let references = this.batchesByDocumentKey;\n return PersistencePromise.forEach(batch.mutations, (mutation: Mutation) => {\n const ref = new DocReference(mutation.key, batch.batchId);\n references = references.delete(ref);\n return this.referenceDelegate.markPotentiallyOrphaned(\n transaction,\n mutation.key\n );\n }).next(() => {\n this.batchesByDocumentKey = references;\n });\n }\n\n removeCachedMutationKeys(batchId: BatchId): void {\n // No-op since the memory mutation queue does not maintain a separate cache.\n }\n\n containsKey(\n txn: PersistenceTransaction,\n key: DocumentKey\n ): PersistencePromise<boolean> {\n const ref = new DocReference(key, 0);\n const firstRef = this.batchesByDocumentKey.firstAfterOrEqual(ref);\n return PersistencePromise.resolve(key.isEqual(firstRef && firstRef.key));\n }\n\n performConsistencyCheck(\n txn: PersistenceTransaction\n ): PersistencePromise<void> {\n if (this.mutationQueue.length === 0) {\n debugAssert(\n this.batchesByDocumentKey.isEmpty(),\n 'Document leak -- detected dangling mutation references when queue is empty.'\n );\n }\n return PersistencePromise.resolve();\n }\n\n /**\n * Finds the index of the given batchId in the mutation queue and asserts that\n * the resulting index is within the bounds of the queue.\n *\n * @param batchId The batchId to search for\n * @param action A description of what the caller is doing, phrased in passive\n * form (e.g. \"acknowledged\" in a routine that acknowledges batches).\n */\n private indexOfExistingBatchId(batchId: BatchId, action: string): number {\n const index = this.indexOfBatchId(batchId);\n debugAssert(\n index >= 0 && index < this.mutationQueue.length,\n 'Batches must exist to be ' + action\n );\n return index;\n }\n\n /**\n * Finds the index of the given batchId in the mutation queue. This operation\n * is O(1).\n *\n * @return The computed index of the batch with the given batchId, based on\n * the state of the queue. Note this index can be negative if the requested\n * batchId has already been remvoed from the queue or past the end of the\n * queue if the batchId is larger than the last added batch.\n */\n private indexOfBatchId(batchId: BatchId): number {\n if (this.mutationQueue.length === 0) {\n // As an index this is past the end of the queue\n return 0;\n }\n\n // Examine the front of the queue to figure out the difference between the\n // batchId and indexes in the array. Note that since the queue is ordered\n // by batchId, if the first batch has a larger batchId then the requested\n // batchId doesn't exist in the queue.\n const firstBatchId = this.mutationQueue[0].batchId;\n return batchId - firstBatchId;\n }\n\n /**\n * A version of lookupMutationBatch that doesn't return a promise, this makes\n * other functions that uses this code easier to read and more efficent.\n */\n private findMutationBatch(batchId: BatchId): MutationBatch | null {\n const index = this.indexOfBatchId(batchId);\n if (index < 0 || index >= this.mutationQueue.length) {\n return null;\n }\n\n const batch = this.mutationQueue[index];\n debugAssert(batch.batchId === batchId, 'If found batch must match');\n return batch;\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 { Query } from '../core/query';\nimport {\n DocumentKeySet,\n DocumentMap,\n documentMap,\n DocumentSizeEntry,\n NullableMaybeDocumentMap,\n nullableMaybeDocumentMap\n} from '../model/collections';\nimport { Document, MaybeDocument } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\n\nimport { SnapshotVersion } from '../core/snapshot_version';\nimport { debugAssert } from '../util/assert';\nimport { SortedMap } from '../util/sorted_map';\nimport { IndexManager } from './index_manager';\nimport { PersistenceTransaction } from './persistence';\nimport { PersistencePromise } from './persistence_promise';\nimport { RemoteDocumentCache } from './remote_document_cache';\nimport { RemoteDocumentChangeBuffer } from './remote_document_change_buffer';\n\nexport type DocumentSizer = (doc: MaybeDocument) => number;\n\n/** Miscellaneous collection types / constants. */\ninterface MemoryRemoteDocumentCacheEntry extends DocumentSizeEntry {\n readTime: SnapshotVersion;\n}\n\ntype DocumentEntryMap = SortedMap<DocumentKey, MemoryRemoteDocumentCacheEntry>;\nfunction documentEntryMap(): DocumentEntryMap {\n return new SortedMap<DocumentKey, MemoryRemoteDocumentCacheEntry>(\n DocumentKey.comparator\n );\n}\n\nexport class MemoryRemoteDocumentCache implements RemoteDocumentCache {\n /** Underlying cache of documents and their read times. */\n private docs = documentEntryMap();\n\n /** Size of all cached documents. */\n private size = 0;\n\n /**\n * @param sizer Used to assess the size of a document. For eager GC, this is expected to just\n * return 0 to avoid unnecessarily doing the work of calculating the size.\n */\n constructor(\n private readonly indexManager: IndexManager,\n private readonly sizer: DocumentSizer\n ) {}\n\n /**\n * Adds the supplied entry to the cache and updates the cache size as appropriate.\n *\n * All calls of `addEntry` are required to go through the RemoteDocumentChangeBuffer\n * returned by `newChangeBuffer()`.\n */\n private addEntry(\n transaction: PersistenceTransaction,\n doc: MaybeDocument,\n readTime: SnapshotVersion\n ): PersistencePromise<void> {\n debugAssert(\n !readTime.isEqual(SnapshotVersion.min()),\n 'Cannot add a document with a read time of zero'\n );\n\n const key = doc.key;\n const entry = this.docs.get(key);\n const previousSize = entry ? entry.size : 0;\n const currentSize = this.sizer(doc);\n\n this.docs = this.docs.insert(key, {\n maybeDocument: doc,\n size: currentSize,\n readTime\n });\n\n this.size += currentSize - previousSize;\n\n return this.indexManager.addToCollectionParentIndex(\n transaction,\n key.path.popLast()\n );\n }\n\n /**\n * Removes the specified entry from the cache and updates the cache size as appropriate.\n *\n * All calls of `removeEntry` are required to go through the RemoteDocumentChangeBuffer\n * returned by `newChangeBuffer()`.\n */\n private removeEntry(documentKey: DocumentKey): void {\n const entry = this.docs.get(documentKey);\n if (entry) {\n this.docs = this.docs.remove(documentKey);\n this.size -= entry.size;\n }\n }\n\n getEntry(\n transaction: PersistenceTransaction,\n documentKey: DocumentKey\n ): PersistencePromise<MaybeDocument | null> {\n const entry = this.docs.get(documentKey);\n return PersistencePromise.resolve(entry ? entry.maybeDocument : null);\n }\n\n getEntries(\n transaction: PersistenceTransaction,\n documentKeys: DocumentKeySet\n ): PersistencePromise<NullableMaybeDocumentMap> {\n let results = nullableMaybeDocumentMap();\n documentKeys.forEach(documentKey => {\n const entry = this.docs.get(documentKey);\n results = results.insert(documentKey, entry ? entry.maybeDocument : null);\n });\n return PersistencePromise.resolve(results);\n }\n\n getDocumentsMatchingQuery(\n transaction: PersistenceTransaction,\n query: Query,\n sinceReadTime: SnapshotVersion\n ): PersistencePromise<DocumentMap> {\n debugAssert(\n !query.isCollectionGroupQuery(),\n 'CollectionGroup queries should be handled in LocalDocumentsView'\n );\n let results = documentMap();\n\n // Documents are ordered by key, so we can use a prefix scan to narrow down\n // the documents we need to match the query against.\n const prefix = new DocumentKey(query.path.child(''));\n const iterator = this.docs.getIteratorFrom(prefix);\n while (iterator.hasNext()) {\n const {\n key,\n value: { maybeDocument, readTime }\n } = iterator.getNext();\n if (!query.path.isPrefixOf(key.path)) {\n break;\n }\n if (readTime.compareTo(sinceReadTime) <= 0) {\n continue;\n }\n if (maybeDocument instanceof Document && query.matches(maybeDocument)) {\n results = results.insert(maybeDocument.key, maybeDocument);\n }\n }\n return PersistencePromise.resolve(results);\n }\n\n forEachDocumentKey(\n transaction: PersistenceTransaction,\n f: (key: DocumentKey) => PersistencePromise<void>\n ): PersistencePromise<void> {\n return PersistencePromise.forEach(this.docs, (key: DocumentKey) => f(key));\n }\n\n newChangeBuffer(options?: {\n trackRemovals: boolean;\n }): RemoteDocumentChangeBuffer {\n // `trackRemovals` is ignores since the MemoryRemoteDocumentCache keeps\n // a separate changelog and does not need special handling for removals.\n return new MemoryRemoteDocumentCache.RemoteDocumentChangeBuffer(this);\n }\n\n getSize(txn: PersistenceTransaction): PersistencePromise<number> {\n return PersistencePromise.resolve(this.size);\n }\n\n /**\n * Handles the details of adding and updating documents in the MemoryRemoteDocumentCache.\n */\n private static RemoteDocumentChangeBuffer = class extends RemoteDocumentChangeBuffer {\n constructor(private readonly documentCache: MemoryRemoteDocumentCache) {\n super();\n }\n\n protected applyChanges(\n transaction: PersistenceTransaction\n ): PersistencePromise<void> {\n const promises: Array<PersistencePromise<void>> = [];\n this.changes.forEach((key, doc) => {\n if (doc) {\n promises.push(\n this.documentCache.addEntry(transaction, doc, this.readTime)\n );\n } else {\n this.documentCache.removeEntry(key);\n }\n });\n return PersistencePromise.waitFor(promises);\n }\n\n protected getFromCache(\n transaction: PersistenceTransaction,\n documentKey: DocumentKey\n ): PersistencePromise<MaybeDocument | null> {\n return this.documentCache.getEntry(transaction, documentKey);\n }\n\n protected getAllFromCache(\n transaction: PersistenceTransaction,\n documentKeys: DocumentKeySet\n ): PersistencePromise<NullableMaybeDocumentMap> {\n return this.documentCache.getEntries(transaction, documentKeys);\n }\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 { SnapshotVersion } from '../core/snapshot_version';\nimport { TargetIdGenerator } from '../core/target_id_generator';\nimport { ListenSequenceNumber, TargetId } from '../core/types';\nimport { DocumentKeySet } from '../model/collections';\nimport { DocumentKey } from '../model/document_key';\nimport { debugAssert } from '../util/assert';\nimport { ObjectMap } from '../util/obj_map';\n\nimport { ActiveTargets } from './lru_garbage_collector';\nimport { MemoryPersistence } from './memory_persistence';\nimport { PersistenceTransaction } from './persistence';\nimport { PersistencePromise } from './persistence_promise';\nimport { ReferenceSet } from './reference_set';\nimport { TargetCache } from './target_cache';\nimport { TargetData } from './target_data';\nimport { Target } from '../core/target';\n\nexport class MemoryTargetCache implements TargetCache {\n /**\n * Maps a target to the data about that target\n */\n private targets = new ObjectMap<Target, TargetData>(t => t.canonicalId());\n\n /** The last received snapshot version. */\n private lastRemoteSnapshotVersion = SnapshotVersion.min();\n /** The highest numbered target ID encountered. */\n private highestTargetId: TargetId = 0;\n /** The highest sequence number encountered. */\n private highestSequenceNumber: ListenSequenceNumber = 0;\n /**\n * A ordered bidirectional mapping between documents and the remote target\n * IDs.\n */\n private references = new ReferenceSet();\n\n private targetCount = 0;\n\n private targetIdGenerator = TargetIdGenerator.forTargetCache();\n\n constructor(private readonly persistence: MemoryPersistence) {}\n\n forEachTarget(\n txn: PersistenceTransaction,\n f: (q: TargetData) => void\n ): PersistencePromise<void> {\n this.targets.forEach((_, targetData) => f(targetData));\n return PersistencePromise.resolve();\n }\n\n getLastRemoteSnapshotVersion(\n transaction: PersistenceTransaction\n ): PersistencePromise<SnapshotVersion> {\n return PersistencePromise.resolve(this.lastRemoteSnapshotVersion);\n }\n\n getHighestSequenceNumber(\n transaction: PersistenceTransaction\n ): PersistencePromise<ListenSequenceNumber> {\n return PersistencePromise.resolve(this.highestSequenceNumber);\n }\n\n allocateTargetId(\n transaction: PersistenceTransaction\n ): PersistencePromise<TargetId> {\n this.highestTargetId = this.targetIdGenerator.next();\n return PersistencePromise.resolve(this.highestTargetId);\n }\n\n setTargetsMetadata(\n transaction: PersistenceTransaction,\n highestListenSequenceNumber: number,\n lastRemoteSnapshotVersion?: SnapshotVersion\n ): PersistencePromise<void> {\n if (lastRemoteSnapshotVersion) {\n this.lastRemoteSnapshotVersion = lastRemoteSnapshotVersion;\n }\n if (highestListenSequenceNumber > this.highestSequenceNumber) {\n this.highestSequenceNumber = highestListenSequenceNumber;\n }\n return PersistencePromise.resolve();\n }\n\n private saveTargetData(targetData: TargetData): void {\n this.targets.set(targetData.target, targetData);\n const targetId = targetData.targetId;\n if (targetId > this.highestTargetId) {\n this.targetIdGenerator = new TargetIdGenerator(targetId);\n this.highestTargetId = targetId;\n }\n if (targetData.sequenceNumber > this.highestSequenceNumber) {\n this.highestSequenceNumber = targetData.sequenceNumber;\n }\n }\n\n addTargetData(\n transaction: PersistenceTransaction,\n targetData: TargetData\n ): PersistencePromise<void> {\n debugAssert(\n !this.targets.has(targetData.target),\n 'Adding a target that already exists'\n );\n this.saveTargetData(targetData);\n this.targetCount += 1;\n return PersistencePromise.resolve();\n }\n\n updateTargetData(\n transaction: PersistenceTransaction,\n targetData: TargetData\n ): PersistencePromise<void> {\n debugAssert(\n this.targets.has(targetData.target),\n 'Updating a non-existent target'\n );\n this.saveTargetData(targetData);\n return PersistencePromise.resolve();\n }\n\n removeTargetData(\n transaction: PersistenceTransaction,\n targetData: TargetData\n ): PersistencePromise<void> {\n debugAssert(this.targetCount > 0, 'Removing a target from an empty cache');\n debugAssert(\n this.targets.has(targetData.target),\n 'Removing a non-existent target from the cache'\n );\n this.targets.delete(targetData.target);\n this.references.removeReferencesForId(targetData.targetId);\n this.targetCount -= 1;\n return PersistencePromise.resolve();\n }\n\n removeTargets(\n transaction: PersistenceTransaction,\n upperBound: ListenSequenceNumber,\n activeTargetIds: ActiveTargets\n ): PersistencePromise<number> {\n let count = 0;\n const removals: Array<PersistencePromise<void>> = [];\n this.targets.forEach((key, targetData) => {\n if (\n targetData.sequenceNumber <= upperBound &&\n activeTargetIds.get(targetData.targetId) === null\n ) {\n this.targets.delete(key);\n removals.push(\n this.removeMatchingKeysForTargetId(transaction, targetData.targetId)\n );\n count++;\n }\n });\n return PersistencePromise.waitFor(removals).next(() => count);\n }\n\n getTargetCount(\n transaction: PersistenceTransaction\n ): PersistencePromise<number> {\n return PersistencePromise.resolve(this.targetCount);\n }\n\n getTargetData(\n transaction: PersistenceTransaction,\n target: Target\n ): PersistencePromise<TargetData | null> {\n const targetData = this.targets.get(target) || null;\n return PersistencePromise.resolve(targetData);\n }\n\n addMatchingKeys(\n txn: PersistenceTransaction,\n keys: DocumentKeySet,\n targetId: TargetId\n ): PersistencePromise<void> {\n this.references.addReferences(keys, targetId);\n return PersistencePromise.resolve();\n }\n\n removeMatchingKeys(\n txn: PersistenceTransaction,\n keys: DocumentKeySet,\n targetId: TargetId\n ): PersistencePromise<void> {\n this.references.removeReferences(keys, targetId);\n const referenceDelegate = this.persistence.referenceDelegate;\n const promises: Array<PersistencePromise<void>> = [];\n if (referenceDelegate) {\n keys.forEach(key => {\n promises.push(referenceDelegate.markPotentiallyOrphaned(txn, key));\n });\n }\n return PersistencePromise.waitFor(promises);\n }\n\n removeMatchingKeysForTargetId(\n txn: PersistenceTransaction,\n targetId: TargetId\n ): PersistencePromise<void> {\n this.references.removeReferencesForId(targetId);\n return PersistencePromise.resolve();\n }\n\n getMatchingKeysForTargetId(\n txn: PersistenceTransaction,\n targetId: TargetId\n ): PersistencePromise<DocumentKeySet> {\n const matchingKeys = this.references.referencesForId(targetId);\n return PersistencePromise.resolve(matchingKeys);\n }\n\n containsKey(\n txn: PersistenceTransaction,\n key: DocumentKey\n ): PersistencePromise<boolean> {\n return PersistencePromise.resolve(this.references.containsKey(key));\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 { User } from '../auth/user';\nimport { Document, MaybeDocument } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport { fail } from '../util/assert';\nimport { logDebug } from '../util/log';\nimport { ObjectMap } from '../util/obj_map';\nimport { encodeResourcePath } from './encoded_resource_path';\nimport {\n ActiveTargets,\n LruDelegate,\n LruGarbageCollector,\n LruParams\n} from './lru_garbage_collector';\nimport { ListenSequence } from '../core/listen_sequence';\nimport { ListenSequenceNumber, TargetId } from '../core/types';\nimport { estimateByteSize } from '../model/values';\nimport { MemoryIndexManager } from './memory_index_manager';\nimport { MemoryMutationQueue } from './memory_mutation_queue';\nimport { MemoryRemoteDocumentCache } from './memory_remote_document_cache';\nimport { MemoryTargetCache } from './memory_target_cache';\nimport { MutationQueue } from './mutation_queue';\nimport {\n Persistence,\n PersistenceTransaction,\n PersistenceTransactionMode,\n ReferenceDelegate\n} from './persistence';\nimport { PersistencePromise } from './persistence_promise';\nimport { ReferenceSet } from './reference_set';\nimport { TargetData } from './target_data';\n\nconst LOG_TAG = 'MemoryPersistence';\n/**\n * A memory-backed instance of Persistence. Data is stored only in RAM and\n * not persisted across sessions.\n */\nexport class MemoryPersistence implements Persistence {\n /**\n * Note that these are retained here to make it easier to write tests\n * affecting both the in-memory and IndexedDB-backed persistence layers. Tests\n * can create a new LocalStore wrapping this Persistence instance and this\n * will make the in-memory persistence layer behave as if it were actually\n * persisting values.\n */\n private readonly indexManager: MemoryIndexManager;\n private mutationQueues: { [user: string]: MemoryMutationQueue } = {};\n private readonly remoteDocumentCache: MemoryRemoteDocumentCache;\n private readonly targetCache: MemoryTargetCache;\n private readonly listenSequence = new ListenSequence(0);\n\n private _started = false;\n\n readonly referenceDelegate: MemoryReferenceDelegate;\n\n /**\n * The constructor accepts a factory for creating a reference delegate. This\n * allows both the delegate and this instance to have strong references to\n * each other without having nullable fields that would then need to be\n * checked or asserted on every access.\n */\n constructor(\n referenceDelegateFactory: (p: MemoryPersistence) => MemoryReferenceDelegate\n ) {\n this._started = true;\n this.referenceDelegate = referenceDelegateFactory(this);\n this.targetCache = new MemoryTargetCache(this);\n const sizer = (doc: MaybeDocument): number =>\n this.referenceDelegate.documentSize(doc);\n this.indexManager = new MemoryIndexManager();\n this.remoteDocumentCache = new MemoryRemoteDocumentCache(\n this.indexManager,\n sizer\n );\n }\n\n start(): Promise<void> {\n return Promise.resolve();\n }\n\n shutdown(): Promise<void> {\n // No durable state to ensure is closed on shutdown.\n this._started = false;\n return Promise.resolve();\n }\n\n get started(): boolean {\n return this._started;\n }\n\n setDatabaseDeletedListener(): void {\n // No op.\n }\n\n getIndexManager(): MemoryIndexManager {\n return this.indexManager;\n }\n\n getMutationQueue(user: User): MutationQueue {\n let queue = this.mutationQueues[user.toKey()];\n if (!queue) {\n queue = new MemoryMutationQueue(\n this.indexManager,\n this.referenceDelegate\n );\n this.mutationQueues[user.toKey()] = queue;\n }\n return queue;\n }\n\n getTargetCache(): MemoryTargetCache {\n return this.targetCache;\n }\n\n getRemoteDocumentCache(): MemoryRemoteDocumentCache {\n return this.remoteDocumentCache;\n }\n\n runTransaction<T>(\n action: string,\n mode: PersistenceTransactionMode,\n transactionOperation: (\n transaction: PersistenceTransaction\n ) => PersistencePromise<T>\n ): Promise<T> {\n logDebug(LOG_TAG, 'Starting transaction:', action);\n const txn = new MemoryTransaction(this.listenSequence.next());\n this.referenceDelegate.onTransactionStarted();\n return transactionOperation(txn)\n .next(result => {\n return this.referenceDelegate\n .onTransactionCommitted(txn)\n .next(() => result);\n })\n .toPromise()\n .then(result => {\n txn.raiseOnCommittedEvent();\n return result;\n });\n }\n\n mutationQueuesContainKey(\n transaction: PersistenceTransaction,\n key: DocumentKey\n ): PersistencePromise<boolean> {\n return PersistencePromise.or(\n Object.values(this.mutationQueues).map(queue => () =>\n queue.containsKey(transaction, key)\n )\n );\n }\n}\n\n/**\n * Memory persistence is not actually transactional, but future implementations\n * may have transaction-scoped state.\n */\nexport class MemoryTransaction extends PersistenceTransaction {\n constructor(readonly currentSequenceNumber: ListenSequenceNumber) {\n super();\n }\n}\n\nexport interface MemoryReferenceDelegate extends ReferenceDelegate {\n documentSize(doc: MaybeDocument): number;\n onTransactionStarted(): void;\n onTransactionCommitted(txn: PersistenceTransaction): PersistencePromise<void>;\n}\n\nexport class MemoryEagerDelegate implements MemoryReferenceDelegate {\n /** Tracks all documents that are active in Query views. */\n private localViewReferences: ReferenceSet = new ReferenceSet();\n /** The list of documents that are potentially GCed after each transaction. */\n private _orphanedDocuments: Set<DocumentKey> | null = null;\n\n private constructor(private readonly persistence: MemoryPersistence) {}\n\n static factory(persistence: MemoryPersistence): MemoryEagerDelegate {\n return new MemoryEagerDelegate(persistence);\n }\n\n private get orphanedDocuments(): Set<DocumentKey> {\n if (!this._orphanedDocuments) {\n throw fail('orphanedDocuments is only valid during a transaction.');\n } else {\n return this._orphanedDocuments;\n }\n }\n\n addReference(\n txn: PersistenceTransaction,\n targetId: TargetId,\n key: DocumentKey\n ): PersistencePromise<void> {\n this.localViewReferences.addReference(key, targetId);\n this.orphanedDocuments.delete(key);\n return PersistencePromise.resolve();\n }\n\n removeReference(\n txn: PersistenceTransaction,\n targetId: TargetId,\n key: DocumentKey\n ): PersistencePromise<void> {\n this.localViewReferences.removeReference(key, targetId);\n this.orphanedDocuments.add(key);\n return PersistencePromise.resolve();\n }\n\n markPotentiallyOrphaned(\n txn: PersistenceTransaction,\n key: DocumentKey\n ): PersistencePromise<void> {\n this.orphanedDocuments.add(key);\n return PersistencePromise.resolve();\n }\n\n removeTarget(\n txn: PersistenceTransaction,\n targetData: TargetData\n ): PersistencePromise<void> {\n const orphaned = this.localViewReferences.removeReferencesForId(\n targetData.targetId\n );\n orphaned.forEach(key => this.orphanedDocuments.add(key));\n const cache = this.persistence.getTargetCache();\n return cache\n .getMatchingKeysForTargetId(txn, targetData.targetId)\n .next(keys => {\n keys.forEach(key => this.orphanedDocuments.add(key));\n })\n .next(() => cache.removeTargetData(txn, targetData));\n }\n\n onTransactionStarted(): void {\n this._orphanedDocuments = new Set<DocumentKey>();\n }\n\n onTransactionCommitted(\n txn: PersistenceTransaction\n ): PersistencePromise<void> {\n // Remove newly orphaned documents.\n const cache = this.persistence.getRemoteDocumentCache();\n const changeBuffer = cache.newChangeBuffer();\n return PersistencePromise.forEach(\n this.orphanedDocuments,\n (key: DocumentKey) => {\n return this.isReferenced(txn, key).next(isReferenced => {\n if (!isReferenced) {\n changeBuffer.removeEntry(key);\n }\n });\n }\n ).next(() => {\n this._orphanedDocuments = null;\n return changeBuffer.apply(txn);\n });\n }\n\n updateLimboDocument(\n txn: PersistenceTransaction,\n key: DocumentKey\n ): PersistencePromise<void> {\n return this.isReferenced(txn, key).next(isReferenced => {\n if (isReferenced) {\n this.orphanedDocuments.delete(key);\n } else {\n this.orphanedDocuments.add(key);\n }\n });\n }\n\n documentSize(doc: MaybeDocument): number {\n // For eager GC, we don't care about the document size, there are no size thresholds.\n return 0;\n }\n\n private isReferenced(\n txn: PersistenceTransaction,\n key: DocumentKey\n ): PersistencePromise<boolean> {\n return PersistencePromise.or([\n () =>\n PersistencePromise.resolve(this.localViewReferences.containsKey(key)),\n () => this.persistence.getTargetCache().containsKey(txn, key),\n () => this.persistence.mutationQueuesContainKey(txn, key)\n ]);\n }\n}\n\nexport class MemoryLruDelegate implements ReferenceDelegate, LruDelegate {\n private orphanedSequenceNumbers: ObjectMap<\n DocumentKey,\n ListenSequenceNumber\n > = new ObjectMap(k => encodeResourcePath(k.path));\n\n readonly garbageCollector: LruGarbageCollector;\n\n constructor(\n private readonly persistence: MemoryPersistence,\n lruParams: LruParams\n ) {\n this.garbageCollector = new LruGarbageCollector(this, lruParams);\n }\n\n // No-ops, present so memory persistence doesn't have to care which delegate\n // it has.\n onTransactionStarted(): void {}\n\n onTransactionCommitted(\n txn: PersistenceTransaction\n ): PersistencePromise<void> {\n return PersistencePromise.resolve();\n }\n\n forEachTarget(\n txn: PersistenceTransaction,\n f: (q: TargetData) => void\n ): PersistencePromise<void> {\n return this.persistence.getTargetCache().forEachTarget(txn, f);\n }\n\n getSequenceNumberCount(\n txn: PersistenceTransaction\n ): PersistencePromise<number> {\n const docCountPromise = this.orphanedDocumentCount(txn);\n const targetCountPromise = this.persistence\n .getTargetCache()\n .getTargetCount(txn);\n return targetCountPromise.next(targetCount =>\n docCountPromise.next(docCount => targetCount + docCount)\n );\n }\n\n private orphanedDocumentCount(\n txn: PersistenceTransaction\n ): PersistencePromise<number> {\n let orphanedCount = 0;\n return this.forEachOrphanedDocumentSequenceNumber(txn, _ => {\n orphanedCount++;\n }).next(() => orphanedCount);\n }\n\n forEachOrphanedDocumentSequenceNumber(\n txn: PersistenceTransaction,\n f: (sequenceNumber: ListenSequenceNumber) => void\n ): PersistencePromise<void> {\n return PersistencePromise.forEach(\n this.orphanedSequenceNumbers,\n (key, sequenceNumber) => {\n // Pass in the exact sequence number as the upper bound so we know it won't be pinned by\n // being too recent.\n return this.isPinned(txn, key, sequenceNumber).next(isPinned => {\n if (!isPinned) {\n return f(sequenceNumber);\n } else {\n return PersistencePromise.resolve();\n }\n });\n }\n );\n }\n\n removeTargets(\n txn: PersistenceTransaction,\n upperBound: ListenSequenceNumber,\n activeTargetIds: ActiveTargets\n ): PersistencePromise<number> {\n return this.persistence\n .getTargetCache()\n .removeTargets(txn, upperBound, activeTargetIds);\n }\n\n removeOrphanedDocuments(\n txn: PersistenceTransaction,\n upperBound: ListenSequenceNumber\n ): PersistencePromise<number> {\n let count = 0;\n const cache = this.persistence.getRemoteDocumentCache();\n const changeBuffer = cache.newChangeBuffer();\n const p = cache.forEachDocumentKey(txn, key => {\n return this.isPinned(txn, key, upperBound).next(isPinned => {\n if (!isPinned) {\n count++;\n changeBuffer.removeEntry(key);\n }\n });\n });\n return p.next(() => changeBuffer.apply(txn)).next(() => count);\n }\n\n markPotentiallyOrphaned(\n txn: PersistenceTransaction,\n key: DocumentKey\n ): PersistencePromise<void> {\n this.orphanedSequenceNumbers.set(key, txn.currentSequenceNumber);\n return PersistencePromise.resolve();\n }\n\n removeTarget(\n txn: PersistenceTransaction,\n targetData: TargetData\n ): PersistencePromise<void> {\n const updated = targetData.withSequenceNumber(txn.currentSequenceNumber);\n return this.persistence.getTargetCache().updateTargetData(txn, updated);\n }\n\n addReference(\n txn: PersistenceTransaction,\n targetId: TargetId,\n key: DocumentKey\n ): PersistencePromise<void> {\n this.orphanedSequenceNumbers.set(key, txn.currentSequenceNumber);\n return PersistencePromise.resolve();\n }\n\n removeReference(\n txn: PersistenceTransaction,\n targetId: TargetId,\n key: DocumentKey\n ): PersistencePromise<void> {\n this.orphanedSequenceNumbers.set(key, txn.currentSequenceNumber);\n return PersistencePromise.resolve();\n }\n\n updateLimboDocument(\n txn: PersistenceTransaction,\n key: DocumentKey\n ): PersistencePromise<void> {\n this.orphanedSequenceNumbers.set(key, txn.currentSequenceNumber);\n return PersistencePromise.resolve();\n }\n\n documentSize(maybeDoc: MaybeDocument): number {\n let documentSize = maybeDoc.key.toString().length;\n if (maybeDoc instanceof Document) {\n documentSize += estimateByteSize(maybeDoc.toProto());\n }\n return documentSize;\n }\n\n private isPinned(\n txn: PersistenceTransaction,\n key: DocumentKey,\n upperBound: ListenSequenceNumber\n ): PersistencePromise<boolean> {\n return PersistencePromise.or([\n () => this.persistence.mutationQueuesContainKey(txn, key),\n () => this.persistence.getTargetCache().containsKey(txn, key),\n () => {\n const orphanedAt = this.orphanedSequenceNumbers.get(key);\n return PersistencePromise.resolve(\n orphanedAt !== undefined && orphanedAt > upperBound\n );\n }\n ]);\n }\n\n getCacheSize(txn: PersistenceTransaction): PersistencePromise<number> {\n return this.persistence.getRemoteDocumentCache().getSize(txn);\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 {\n ClientId,\n MemorySharedClientState,\n SharedClientState,\n WebStorageSharedClientState\n} from '../local/shared_client_state';\nimport { LocalStore, MultiTabLocalStore } from '../local/local_store';\nimport { MultiTabSyncEngine, SyncEngine } from './sync_engine';\nimport { RemoteStore } from '../remote/remote_store';\nimport { EventManager } from './event_manager';\nimport { AsyncQueue } from '../util/async_queue';\nimport { DatabaseInfo } from './database_info';\nimport { Platform } from '../platform/platform';\nimport { Datastore } from '../remote/datastore';\nimport { User } from '../auth/user';\nimport { PersistenceSettings } from './firestore_client';\nimport { debugAssert } from '../util/assert';\nimport { GarbageCollectionScheduler, Persistence } from '../local/persistence';\nimport { Code, FirestoreError } from '../util/error';\nimport { OnlineStateSource } from './types';\nimport { LruParams, LruScheduler } from '../local/lru_garbage_collector';\nimport { IndexFreeQueryEngine } from '../local/index_free_query_engine';\nimport { IndexedDbPersistence } from '../local/indexeddb_persistence';\nimport {\n MemoryEagerDelegate,\n MemoryPersistence\n} from '../local/memory_persistence';\n\nconst MEMORY_ONLY_PERSISTENCE_ERROR_MESSAGE =\n 'You are using the memory-only build of Firestore. Persistence support is ' +\n 'only available via the @firebase/firestore bundle or the ' +\n 'firebase-firestore.js build.';\n\nexport interface ComponentConfiguration {\n asyncQueue: AsyncQueue;\n databaseInfo: DatabaseInfo;\n platform: Platform;\n datastore: Datastore;\n clientId: ClientId;\n initialUser: User;\n maxConcurrentLimboResolutions: number;\n persistenceSettings: PersistenceSettings;\n}\n\n/**\n * Initializes and wires up all core components for Firestore. Implementations\n * override `initialize()` to provide all components.\n */\nexport interface ComponentProvider {\n persistence: Persistence;\n sharedClientState: SharedClientState;\n localStore: LocalStore;\n syncEngine: SyncEngine;\n gcScheduler: GarbageCollectionScheduler | null;\n remoteStore: RemoteStore;\n eventManager: EventManager;\n\n initialize(cfg: ComponentConfiguration): Promise<void>;\n\n clearPersistence(databaseId: DatabaseInfo): Promise<void>;\n}\n\n/**\n * Provides all components needed for Firestore with in-memory persistence.\n * Uses EagerGC garbage collection.\n */\nexport class MemoryComponentProvider implements ComponentProvider {\n persistence!: Persistence;\n sharedClientState!: SharedClientState;\n localStore!: LocalStore;\n syncEngine!: SyncEngine;\n gcScheduler!: GarbageCollectionScheduler | null;\n remoteStore!: RemoteStore;\n eventManager!: EventManager;\n\n async initialize(cfg: ComponentConfiguration): Promise<void> {\n this.sharedClientState = this.createSharedClientState(cfg);\n this.persistence = this.createPersistence(cfg);\n await this.persistence.start();\n this.gcScheduler = this.createGarbageCollectionScheduler(cfg);\n this.localStore = this.createLocalStore(cfg);\n this.remoteStore = this.createRemoteStore(cfg);\n this.syncEngine = this.createSyncEngine(cfg);\n this.eventManager = this.createEventManager(cfg);\n\n this.sharedClientState.onlineStateHandler = onlineState =>\n this.syncEngine.applyOnlineStateChange(\n onlineState,\n OnlineStateSource.SharedClientState\n );\n this.remoteStore.syncEngine = this.syncEngine;\n\n await this.localStore.start();\n await this.sharedClientState.start();\n await this.remoteStore.start();\n\n await this.remoteStore.applyPrimaryState(this.syncEngine.isPrimaryClient);\n }\n\n createEventManager(cfg: ComponentConfiguration): EventManager {\n return new EventManager(this.syncEngine);\n }\n\n createGarbageCollectionScheduler(\n cfg: ComponentConfiguration\n ): GarbageCollectionScheduler | null {\n return null;\n }\n\n createLocalStore(cfg: ComponentConfiguration): LocalStore {\n return new LocalStore(\n this.persistence,\n new IndexFreeQueryEngine(),\n cfg.initialUser\n );\n }\n\n createPersistence(cfg: ComponentConfiguration): Persistence {\n debugAssert(\n !cfg.persistenceSettings.durable,\n 'Can only start memory persistence'\n );\n return new MemoryPersistence(MemoryEagerDelegate.factory);\n }\n\n createRemoteStore(cfg: ComponentConfiguration): RemoteStore {\n return new RemoteStore(\n this.localStore,\n cfg.datastore,\n cfg.asyncQueue,\n onlineState =>\n this.syncEngine.applyOnlineStateChange(\n onlineState,\n OnlineStateSource.RemoteStore\n ),\n cfg.platform.newConnectivityMonitor()\n );\n }\n\n createSharedClientState(cfg: ComponentConfiguration): SharedClientState {\n return new MemorySharedClientState();\n }\n\n createSyncEngine(cfg: ComponentConfiguration): SyncEngine {\n return new SyncEngine(\n this.localStore,\n this.remoteStore,\n this.sharedClientState,\n cfg.initialUser,\n cfg.maxConcurrentLimboResolutions\n );\n }\n\n clearPersistence(databaseInfo: DatabaseInfo): Promise<void> {\n throw new FirestoreError(\n Code.FAILED_PRECONDITION,\n MEMORY_ONLY_PERSISTENCE_ERROR_MESSAGE\n );\n }\n}\n\n/**\n * Provides all components needed for Firestore with IndexedDB persistence.\n */\nexport class IndexedDbComponentProvider extends MemoryComponentProvider {\n persistence!: IndexedDbPersistence;\n\n // TODO(tree-shaking): Create an IndexedDbComponentProvider and a\n // MultiTabComponentProvider. The IndexedDbComponentProvider should depend\n // on LocalStore and SyncEngine.\n localStore!: MultiTabLocalStore;\n syncEngine!: MultiTabSyncEngine;\n\n async initialize(cfg: ComponentConfiguration): Promise<void> {\n await super.initialize(cfg);\n\n // NOTE: This will immediately call the listener, so we make sure to\n // set it after localStore / remoteStore are started.\n await this.persistence.setPrimaryStateListener(async isPrimary => {\n await (this.syncEngine as MultiTabSyncEngine).applyPrimaryState(\n isPrimary\n );\n if (this.gcScheduler) {\n if (isPrimary && !this.gcScheduler.started) {\n this.gcScheduler.start(this.localStore);\n } else if (!isPrimary) {\n this.gcScheduler.stop();\n }\n }\n });\n }\n\n createLocalStore(cfg: ComponentConfiguration): LocalStore {\n return new MultiTabLocalStore(\n this.persistence,\n new IndexFreeQueryEngine(),\n cfg.initialUser\n );\n }\n\n createSyncEngine(cfg: ComponentConfiguration): SyncEngine {\n const syncEngine = new MultiTabSyncEngine(\n this.localStore,\n this.remoteStore,\n this.sharedClientState,\n cfg.initialUser,\n cfg.maxConcurrentLimboResolutions\n );\n if (this.sharedClientState instanceof WebStorageSharedClientState) {\n this.sharedClientState.syncEngine = syncEngine;\n }\n return syncEngine;\n }\n\n createGarbageCollectionScheduler(\n cfg: ComponentConfiguration\n ): GarbageCollectionScheduler | null {\n const garbageCollector = this.persistence.referenceDelegate\n .garbageCollector;\n return new LruScheduler(garbageCollector, cfg.asyncQueue);\n }\n\n createPersistence(cfg: ComponentConfiguration): Persistence {\n debugAssert(\n cfg.persistenceSettings.durable,\n 'Can only start durable persistence'\n );\n\n const persistenceKey = IndexedDbPersistence.buildStoragePrefix(\n cfg.databaseInfo\n );\n const serializer = cfg.platform.newSerializer(cfg.databaseInfo.databaseId);\n return new IndexedDbPersistence(\n cfg.persistenceSettings.synchronizeTabs,\n persistenceKey,\n cfg.clientId,\n cfg.platform,\n LruParams.withCacheSize(cfg.persistenceSettings.cacheSizeBytes),\n cfg.asyncQueue,\n serializer,\n this.sharedClientState\n );\n }\n\n createSharedClientState(cfg: ComponentConfiguration): SharedClientState {\n if (\n cfg.persistenceSettings.durable &&\n cfg.persistenceSettings.synchronizeTabs\n ) {\n if (!WebStorageSharedClientState.isAvailable(cfg.platform)) {\n throw new FirestoreError(\n Code.UNIMPLEMENTED,\n 'IndexedDB persistence is only available on platforms that support LocalStorage.'\n );\n }\n const persistenceKey = IndexedDbPersistence.buildStoragePrefix(\n cfg.databaseInfo\n );\n return new WebStorageSharedClientState(\n cfg.asyncQueue,\n cfg.platform,\n persistenceKey,\n cfg.clientId,\n cfg.initialUser\n );\n }\n return new MemorySharedClientState();\n }\n\n clearPersistence(databaseInfo: DatabaseInfo): Promise<void> {\n const persistenceKey = IndexedDbPersistence.buildStoragePrefix(\n databaseInfo\n );\n return IndexedDbPersistence.clearPersistence(persistenceKey);\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 { CredentialsProvider } from '../api/credentials';\nimport { User } from '../auth/user';\nimport { LocalStore } from '../local/local_store';\nimport { GarbageCollectionScheduler, Persistence } from '../local/persistence';\nimport { Document, NoDocument } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport { Mutation } from '../model/mutation';\nimport { Platform } from '../platform/platform';\nimport { newDatastore } from '../remote/datastore';\nimport { RemoteStore } from '../remote/remote_store';\nimport { AsyncQueue, wrapInUserErrorIfRecoverable } from '../util/async_queue';\nimport { Code, FirestoreError } from '../util/error';\nimport { logDebug } from '../util/log';\nimport { Deferred } from '../util/promise';\nimport {\n EventManager,\n ListenOptions,\n Observer,\n QueryListener\n} from './event_manager';\nimport { SyncEngine } from './sync_engine';\nimport { View } from './view';\n\nimport { SharedClientState } from '../local/shared_client_state';\nimport { AutoId } from '../util/misc';\nimport { DatabaseId, DatabaseInfo } from './database_info';\nimport { Query } from './query';\nimport { Transaction } from './transaction';\nimport { ViewSnapshot } from './view_snapshot';\nimport {\n ComponentProvider,\n MemoryComponentProvider\n} from './component_provider';\n\nconst LOG_TAG = 'FirestoreClient';\nconst MAX_CONCURRENT_LIMBO_RESOLUTIONS = 100;\n\n/** DOMException error code constants. */\nconst DOM_EXCEPTION_INVALID_STATE = 11;\nconst DOM_EXCEPTION_ABORTED = 20;\nconst DOM_EXCEPTION_QUOTA_EXCEEDED = 22;\n\nexport type PersistenceSettings =\n | {\n readonly durable: false;\n }\n | {\n readonly durable: true;\n readonly cacheSizeBytes: number;\n readonly synchronizeTabs: boolean;\n };\n\n/**\n * FirestoreClient is a top-level class that constructs and owns all of the\n * pieces of the client SDK architecture. It is responsible for creating the\n * async queue that is shared by all of the other components in the system.\n */\nexport class FirestoreClient {\n // NOTE: These should technically have '|undefined' in the types, since\n // they're initialized asynchronously rather than in the constructor, but\n // given that all work is done on the async queue and we assert that\n // initialization completes before any other work is queued, we're cheating\n // with the types rather than littering the code with '!' or unnecessary\n // undefined checks.\n private eventMgr!: EventManager;\n private persistence!: Persistence;\n private localStore!: LocalStore;\n private remoteStore!: RemoteStore;\n private syncEngine!: SyncEngine;\n private gcScheduler!: GarbageCollectionScheduler | null;\n\n // PORTING NOTE: SharedClientState is only used for multi-tab web.\n private sharedClientState!: SharedClientState;\n\n private readonly clientId = AutoId.newId();\n\n constructor(\n private platform: Platform,\n private databaseInfo: DatabaseInfo,\n private credentials: CredentialsProvider,\n /**\n * Asynchronous queue responsible for all of our internal processing. When\n * we get incoming work from the user (via public API) or the network\n * (incoming GRPC messages), we should always schedule onto this queue.\n * This ensures all of our work is properly serialized (e.g. we don't\n * start processing a new operation while the previous one is waiting for\n * an async I/O to complete).\n */\n private asyncQueue: AsyncQueue\n ) {}\n\n /**\n * Starts up the FirestoreClient, returning only whether or not enabling\n * persistence succeeded.\n *\n * The intent here is to \"do the right thing\" as far as users are concerned.\n * Namely, in cases where offline persistence is requested and possible,\n * enable it, but otherwise fall back to persistence disabled. For the most\n * part we expect this to succeed one way or the other so we don't expect our\n * users to actually wait on the firestore.enablePersistence Promise since\n * they generally won't care.\n *\n * Of course some users actually do care about whether or not persistence\n * was successfully enabled, so the Promise returned from this method\n * indicates this outcome.\n *\n * This presents a problem though: even before enablePersistence resolves or\n * rejects, users may have made calls to e.g. firestore.collection() which\n * means that the FirestoreClient in there will be available and will be\n * enqueuing actions on the async queue.\n *\n * Meanwhile any failure of an operation on the async queue causes it to\n * panic and reject any further work, on the premise that unhandled errors\n * are fatal.\n *\n * Consequently the fallback is handled internally here in start, and if the\n * fallback succeeds we signal success to the async queue even though the\n * start() itself signals failure.\n *\n * @param componentProvider Provider that returns all core components.\n * @param persistenceSettings Settings object to configure offline\n * persistence.\n * @returns A deferred result indicating the user-visible result of enabling\n * offline persistence. This method will reject this if IndexedDB fails to\n * start for any reason. If usePersistence is false this is\n * unconditionally resolved.\n */\n start(\n componentProvider: ComponentProvider,\n persistenceSettings: PersistenceSettings\n ): Promise<void> {\n this.verifyNotTerminated();\n // We defer our initialization until we get the current user from\n // setChangeListener(). We block the async queue until we got the initial\n // user and the initialization is completed. This will prevent any scheduled\n // work from happening before initialization is completed.\n //\n // If initializationDone resolved then the FirestoreClient is in a usable\n // state.\n const initializationDone = new Deferred<void>();\n\n // If usePersistence is true, certain classes of errors while starting are\n // recoverable but only by falling back to persistence disabled.\n //\n // If there's an error in the first case but not in recovery we cannot\n // reject the promise blocking the async queue because this will cause the\n // async queue to panic.\n const persistenceResult = new Deferred<void>();\n\n let initialized = false;\n this.credentials.setChangeListener(user => {\n if (!initialized) {\n initialized = true;\n\n logDebug(LOG_TAG, 'Initializing. user=', user.uid);\n\n return this.initializeComponents(\n componentProvider,\n persistenceSettings,\n user,\n persistenceResult\n ).then(initializationDone.resolve, initializationDone.reject);\n } else {\n this.asyncQueue.enqueueRetryable(() => {\n return this.handleCredentialChange(user);\n });\n }\n });\n\n // Block the async queue until initialization is done\n this.asyncQueue.enqueueAndForget(() => {\n return initializationDone.promise;\n });\n\n // Return only the result of enabling persistence. Note that this does not\n // need to await the completion of initializationDone because the result of\n // this method should not reflect any other kind of failure to start.\n return persistenceResult.promise;\n }\n\n /** Enables the network connection and requeues all pending operations. */\n enableNetwork(): Promise<void> {\n this.verifyNotTerminated();\n return this.asyncQueue.enqueue(() => {\n return this.syncEngine.enableNetwork();\n });\n }\n\n /**\n * Initializes persistent storage, attempting to use IndexedDB if\n * usePersistence is true or memory-only if false.\n *\n * If IndexedDB fails because it's already open in another tab or because the\n * platform can't possibly support our implementation then this method rejects\n * the persistenceResult and falls back on memory-only persistence.\n *\n * @param componentProvider The provider that provides all core componennts\n * for IndexedDB or memory-backed persistence\n * @param persistenceSettings Settings object to configure offline persistence\n * @param user The initial user\n * @param persistenceResult A deferred result indicating the user-visible\n * result of enabling offline persistence. This method will reject this if\n * IndexedDB fails to start for any reason. If usePersistence is false\n * this is unconditionally resolved.\n * @returns a Promise indicating whether or not initialization should\n * continue, i.e. that one of the persistence implementations actually\n * succeeded.\n */\n private async initializeComponents(\n componentProvider: ComponentProvider,\n persistenceSettings: PersistenceSettings,\n user: User,\n persistenceResult: Deferred<void>\n ): Promise<void> {\n try {\n // TODO(mrschmidt): Ideally, ComponentProvider would also initialize\n // Datastore (without duplicating the initializing logic once per\n // provider).\n\n const connection = await this.platform.loadConnection(this.databaseInfo);\n const serializer = this.platform.newSerializer(\n this.databaseInfo.databaseId\n );\n const datastore = newDatastore(connection, this.credentials, serializer);\n\n await componentProvider.initialize({\n asyncQueue: this.asyncQueue,\n databaseInfo: this.databaseInfo,\n platform: this.platform,\n datastore,\n clientId: this.clientId,\n initialUser: user,\n maxConcurrentLimboResolutions: MAX_CONCURRENT_LIMBO_RESOLUTIONS,\n persistenceSettings\n });\n\n this.persistence = componentProvider.persistence;\n this.sharedClientState = componentProvider.sharedClientState;\n this.localStore = componentProvider.localStore;\n this.remoteStore = componentProvider.remoteStore;\n this.syncEngine = componentProvider.syncEngine;\n this.gcScheduler = componentProvider.gcScheduler;\n this.eventMgr = componentProvider.eventManager;\n\n // When a user calls clearPersistence() in one client, all other clients\n // need to be terminated to allow the delete to succeed.\n this.persistence.setDatabaseDeletedListener(async () => {\n await this.terminate();\n });\n\n persistenceResult.resolve();\n } catch (error) {\n // Regardless of whether or not the retry succeeds, from an user\n // perspective, offline persistence has failed.\n persistenceResult.reject(error);\n\n // An unknown failure on the first stage shuts everything down.\n if (!this.canFallback(error)) {\n throw error;\n }\n console.warn(\n 'Error enabling offline persistence. Falling back to' +\n ' persistence disabled: ' +\n error\n );\n return this.initializeComponents(\n new MemoryComponentProvider(),\n { durable: false },\n user,\n persistenceResult\n );\n }\n }\n\n /**\n * Decides whether the provided error allows us to gracefully disable\n * persistence (as opposed to crashing the client).\n */\n private canFallback(error: FirestoreError | DOMException): boolean {\n if (error.name === 'FirebaseError') {\n return (\n error.code === Code.FAILED_PRECONDITION ||\n error.code === Code.UNIMPLEMENTED\n );\n } else if (\n typeof DOMException !== 'undefined' &&\n error instanceof DOMException\n ) {\n // There are a few known circumstances where we can open IndexedDb but\n // trying to read/write will fail (e.g. quota exceeded). For\n // well-understood cases, we attempt to detect these and then gracefully\n // fall back to memory persistence.\n // NOTE: Rather than continue to add to this list, we could decide to\n // always fall back, with the risk that we might accidentally hide errors\n // representing actual SDK bugs.\n return (\n // When the browser is out of quota we could get either quota exceeded\n // or an aborted error depending on whether the error happened during\n // schema migration.\n error.code === DOM_EXCEPTION_QUOTA_EXCEEDED ||\n error.code === DOM_EXCEPTION_ABORTED ||\n // Firefox Private Browsing mode disables IndexedDb and returns\n // INVALID_STATE for any usage.\n error.code === DOM_EXCEPTION_INVALID_STATE\n );\n }\n\n return true;\n }\n\n /**\n * Checks that the client has not been terminated. Ensures that other methods on\n * this class cannot be called after the client is terminated.\n */\n private verifyNotTerminated(): void {\n if (this.asyncQueue.isShuttingDown) {\n throw new FirestoreError(\n Code.FAILED_PRECONDITION,\n 'The client has already been terminated.'\n );\n }\n }\n\n private handleCredentialChange(user: User): Promise<void> {\n this.asyncQueue.verifyOperationInProgress();\n\n logDebug(LOG_TAG, 'Credential Changed. Current user: ' + user.uid);\n return this.syncEngine.handleCredentialChange(user);\n }\n\n /** Disables the network connection. Pending operations will not complete. */\n disableNetwork(): Promise<void> {\n this.verifyNotTerminated();\n return this.asyncQueue.enqueue(() => {\n return this.syncEngine.disableNetwork();\n });\n }\n\n terminate(): Promise<void> {\n return this.asyncQueue.enqueueAndInitiateShutdown(async () => {\n // PORTING NOTE: LocalStore does not need an explicit shutdown on web.\n if (this.gcScheduler) {\n this.gcScheduler.stop();\n }\n\n await this.remoteStore.shutdown();\n await this.sharedClientState.shutdown();\n await this.persistence.shutdown();\n\n // `removeChangeListener` must be called after shutting down the\n // RemoteStore as it will prevent the RemoteStore from retrieving\n // auth tokens.\n this.credentials.removeChangeListener();\n });\n }\n\n /**\n * Returns a Promise that resolves when all writes that were pending at the time this\n * method was called received server acknowledgement. An acknowledgement can be either acceptance\n * or rejection.\n */\n waitForPendingWrites(): Promise<void> {\n this.verifyNotTerminated();\n\n const deferred = new Deferred<void>();\n this.asyncQueue.enqueueAndForget(() => {\n return this.syncEngine.registerPendingWritesCallback(deferred);\n });\n return deferred.promise;\n }\n\n listen(\n query: Query,\n observer: Observer<ViewSnapshot>,\n options: ListenOptions\n ): QueryListener {\n this.verifyNotTerminated();\n const listener = new QueryListener(query, observer, options);\n this.asyncQueue.enqueueAndForget(() => this.eventMgr.listen(listener));\n return listener;\n }\n\n unlisten(listener: QueryListener): void {\n // Checks for termination but does not raise error, allowing unlisten after\n // termination to be a no-op.\n if (this.clientTerminated) {\n return;\n }\n this.asyncQueue.enqueueAndForget(() => {\n return this.eventMgr.unlisten(listener);\n });\n }\n\n async getDocumentFromLocalCache(\n docKey: DocumentKey\n ): Promise<Document | null> {\n this.verifyNotTerminated();\n const deferred = new Deferred<Document | null>();\n await this.asyncQueue.enqueue(async () => {\n try {\n const maybeDoc = await this.localStore.readDocument(docKey);\n if (maybeDoc instanceof Document) {\n deferred.resolve(maybeDoc);\n } else if (maybeDoc instanceof NoDocument) {\n deferred.resolve(null);\n } else {\n deferred.reject(\n new FirestoreError(\n Code.UNAVAILABLE,\n 'Failed to get document from cache. (However, this document may ' +\n \"exist on the server. Run again without setting 'source' in \" +\n 'the GetOptions to attempt to retrieve the document from the ' +\n 'server.)'\n )\n );\n }\n } catch (e) {\n const firestoreError = wrapInUserErrorIfRecoverable(\n e,\n `Failed to get document '${docKey} from cache`\n );\n deferred.reject(firestoreError);\n }\n });\n\n return deferred.promise;\n }\n\n async getDocumentsFromLocalCache(query: Query): Promise<ViewSnapshot> {\n this.verifyNotTerminated();\n const deferred = new Deferred<ViewSnapshot>();\n await this.asyncQueue.enqueue(async () => {\n try {\n const queryResult = await this.localStore.executeQuery(\n query,\n /* usePreviousResults= */ true\n );\n const view = new View(query, queryResult.remoteKeys);\n const viewDocChanges = view.computeDocChanges(queryResult.documents);\n const viewChange = view.applyChanges(\n viewDocChanges,\n /* updateLimboDocuments= */ false\n );\n deferred.resolve(viewChange.snapshot!);\n } catch (e) {\n const firestoreError = wrapInUserErrorIfRecoverable(\n e,\n `Failed to execute query '${query} against cache`\n );\n deferred.reject(firestoreError);\n }\n });\n return deferred.promise;\n }\n\n write(mutations: Mutation[]): Promise<void> {\n this.verifyNotTerminated();\n const deferred = new Deferred<void>();\n this.asyncQueue.enqueueAndForget(() =>\n this.syncEngine.write(mutations, deferred)\n );\n return deferred.promise;\n }\n\n databaseId(): DatabaseId {\n return this.databaseInfo.databaseId;\n }\n\n addSnapshotsInSyncListener(observer: Observer<void>): void {\n this.verifyNotTerminated();\n this.asyncQueue.enqueueAndForget(() => {\n this.eventMgr.addSnapshotsInSyncListener(observer);\n return Promise.resolve();\n });\n }\n\n removeSnapshotsInSyncListener(observer: Observer<void>): void {\n // Checks for shutdown but does not raise error, allowing remove after\n // shutdown to be a no-op.\n if (this.clientTerminated) {\n return;\n }\n this.asyncQueue.enqueueAndForget(() => {\n this.eventMgr.removeSnapshotsInSyncListener(observer);\n return Promise.resolve();\n });\n }\n\n get clientTerminated(): boolean {\n // Technically, the asyncQueue is still running, but only accepting operations\n // related to termination or supposed to be run after termination. It is effectively\n // terminated to the eyes of users.\n return this.asyncQueue.isShuttingDown;\n }\n\n transaction<T>(\n updateFunction: (transaction: Transaction) => Promise<T>\n ): Promise<T> {\n this.verifyNotTerminated();\n const deferred = new Deferred<T>();\n this.asyncQueue.enqueueAndForget(() => {\n this.syncEngine.runTransaction(this.asyncQueue, updateFunction, deferred);\n return Promise.resolve();\n });\n return deferred.promise;\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 { Observer } from '../core/event_manager';\nimport { EventHandler } from './misc';\n\n/*\n * A wrapper implementation of Observer<T> that will dispatch events\n * asynchronously. To allow immediate silencing, a mute call is added which\n * causes events scheduled to no longer be raised.\n */\nexport class AsyncObserver<T> implements Observer<T> {\n /**\n * When set to true, will not raise future events. Necessary to deal with\n * async detachment of listener.\n */\n private muted = false;\n\n constructor(private observer: Observer<T>) {}\n\n next(value: T): void {\n this.scheduleEvent(this.observer.next, value);\n }\n\n error(error: Error): void {\n this.scheduleEvent(this.observer.error, error);\n }\n\n mute(): void {\n this.muted = true;\n }\n\n private scheduleEvent<E>(eventHandler: EventHandler<E>, event: E): void {\n if (!this.muted) {\n setTimeout(() => {\n if (!this.muted) {\n eventHandler(event);\n }\n }, 0);\n }\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 */\nimport { fail } from './assert';\nimport { Code, FirestoreError } from './error';\nimport { Dict, forEach } from './obj';\n\n/** Types accepted by validateType() and related methods for validation. */\nexport type ValidationType =\n | 'undefined'\n | 'object'\n | 'function'\n | 'boolean'\n | 'number'\n | 'string'\n | 'non-empty string';\n\n/**\n * Validates that no arguments were passed in the invocation of functionName.\n *\n * Forward the magic \"arguments\" variable as second parameter on which the\n * parameter validation is performed:\n * validateNoArgs('myFunction', arguments);\n */\nexport function validateNoArgs(functionName: string, args: IArguments): void {\n if (args.length !== 0) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Function ${functionName}() does not support arguments, ` +\n 'but was called with ' +\n formatPlural(args.length, 'argument') +\n '.'\n );\n }\n}\n\n/**\n * Validates the invocation of functionName has the exact number of arguments.\n *\n * Forward the magic \"arguments\" variable as second parameter on which the\n * parameter validation is performed:\n * validateExactNumberOfArgs('myFunction', arguments, 2);\n */\nexport function validateExactNumberOfArgs(\n functionName: string,\n args: IArguments,\n numberOfArgs: number\n): void {\n if (args.length !== numberOfArgs) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Function ${functionName}() requires ` +\n formatPlural(numberOfArgs, 'argument') +\n ', but was called with ' +\n formatPlural(args.length, 'argument') +\n '.'\n );\n }\n}\n\n/**\n * Validates the invocation of functionName has at least the provided number of\n * arguments (but can have many more).\n *\n * Forward the magic \"arguments\" variable as second parameter on which the\n * parameter validation is performed:\n * validateAtLeastNumberOfArgs('myFunction', arguments, 2);\n */\nexport function validateAtLeastNumberOfArgs(\n functionName: string,\n args: IArguments,\n minNumberOfArgs: number\n): void {\n if (args.length < minNumberOfArgs) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Function ${functionName}() requires at least ` +\n formatPlural(minNumberOfArgs, 'argument') +\n ', but was called with ' +\n formatPlural(args.length, 'argument') +\n '.'\n );\n }\n}\n\n/**\n * Validates the invocation of functionName has number of arguments between\n * the values provided.\n *\n * Forward the magic \"arguments\" variable as second parameter on which the\n * parameter validation is performed:\n * validateBetweenNumberOfArgs('myFunction', arguments, 2, 3);\n */\nexport function validateBetweenNumberOfArgs(\n functionName: string,\n args: IArguments,\n minNumberOfArgs: number,\n maxNumberOfArgs: number\n): void {\n if (args.length < minNumberOfArgs || args.length > maxNumberOfArgs) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Function ${functionName}() requires between ${minNumberOfArgs} and ` +\n `${maxNumberOfArgs} arguments, but was called with ` +\n formatPlural(args.length, 'argument') +\n '.'\n );\n }\n}\n\n/**\n * Validates the provided argument is an array and has as least the expected\n * number of elements.\n */\nexport function validateNamedArrayAtLeastNumberOfElements<T>(\n functionName: string,\n value: T[],\n name: string,\n minNumberOfElements: number\n): void {\n if (!(value instanceof Array) || value.length < minNumberOfElements) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Function ${functionName}() requires its ${name} argument to be an ` +\n 'array with at least ' +\n `${formatPlural(minNumberOfElements, 'element')}.`\n );\n }\n}\n\n/**\n * Validates the provided positional argument has the native JavaScript type\n * using typeof checks.\n */\nexport function validateArgType(\n functionName: string,\n type: ValidationType,\n position: number,\n argument: unknown\n): void {\n validateType(functionName, type, `${ordinal(position)} argument`, argument);\n}\n\n/**\n * Validates the provided argument has the native JavaScript type using\n * typeof checks or is undefined.\n */\nexport function validateOptionalArgType(\n functionName: string,\n type: ValidationType,\n position: number,\n argument: unknown\n): void {\n if (argument !== undefined) {\n validateArgType(functionName, type, position, argument);\n }\n}\n\n/**\n * Validates the provided named option has the native JavaScript type using\n * typeof checks.\n */\nexport function validateNamedType(\n functionName: string,\n type: ValidationType,\n optionName: string,\n argument: unknown\n): void {\n validateType(functionName, type, `${optionName} option`, argument);\n}\n\n/**\n * Validates the provided named option has the native JavaScript type using\n * typeof checks or is undefined.\n */\nexport function validateNamedOptionalType(\n functionName: string,\n type: ValidationType,\n optionName: string,\n argument: unknown\n): void {\n if (argument !== undefined) {\n validateNamedType(functionName, type, optionName, argument);\n }\n}\n\nexport function validateArrayElements<T>(\n functionName: string,\n optionName: string,\n typeDescription: string,\n argument: T[],\n validator: (arg0: T) => boolean\n): void {\n if (!(argument instanceof Array)) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Function ${functionName}() requires its ${optionName} ` +\n `option to be an array, but it was: ${valueDescription(argument)}`\n );\n }\n\n for (let i = 0; i < argument.length; ++i) {\n if (!validator(argument[i])) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Function ${functionName}() requires all ${optionName} ` +\n `elements to be ${typeDescription}, but the value at index ${i} ` +\n `was: ${valueDescription(argument[i])}`\n );\n }\n }\n}\n\nexport function validateOptionalArrayElements<T>(\n functionName: string,\n optionName: string,\n typeDescription: string,\n argument: T[] | undefined,\n validator: (arg0: T) => boolean\n): void {\n if (argument !== undefined) {\n validateArrayElements(\n functionName,\n optionName,\n typeDescription,\n argument,\n validator\n );\n }\n}\n\n/**\n * Validates that the provided named option equals one of the expected values.\n */\nexport function validateNamedPropertyEquals<T>(\n functionName: string,\n inputName: string,\n optionName: string,\n input: T,\n expected: T[]\n): void {\n const expectedDescription: string[] = [];\n\n for (const val of expected) {\n if (val === input) {\n return;\n }\n expectedDescription.push(valueDescription(val));\n }\n\n const actualDescription = valueDescription(input);\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Invalid value ${actualDescription} provided to function ${functionName}() for option ` +\n `\"${optionName}\". Acceptable values: ${expectedDescription.join(', ')}`\n );\n}\n\n/**\n * Validates that the provided named option equals one of the expected values or\n * is undefined.\n */\nexport function validateNamedOptionalPropertyEquals<T>(\n functionName: string,\n inputName: string,\n optionName: string,\n input: T,\n expected: T[]\n): void {\n if (input !== undefined) {\n validateNamedPropertyEquals(\n functionName,\n inputName,\n optionName,\n input,\n expected\n );\n }\n}\n\n/**\n * Validates that the provided argument is a valid enum.\n *\n * @param functionName Function making the validation call.\n * @param enums Array containing all possible values for the enum.\n * @param position Position of the argument in `functionName`.\n * @param argument Argument to validate.\n * @return The value as T if the argument can be converted.\n */\nexport function validateStringEnum<T>(\n functionName: string,\n enums: T[],\n position: number,\n argument: unknown\n): T {\n if (!enums.some(element => element === argument)) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Invalid value ${valueDescription(argument)} provided to function ` +\n `${functionName}() for its ${ordinal(position)} argument. Acceptable ` +\n `values: ${enums.join(', ')}`\n );\n }\n return argument as T;\n}\n\n/** Helper to validate the type of a provided input. */\nfunction validateType(\n functionName: string,\n type: ValidationType,\n inputName: string,\n input: unknown\n): void {\n let valid = false;\n if (type === 'object') {\n valid = isPlainObject(input);\n } else if (type === 'non-empty string') {\n valid = typeof input === 'string' && input !== '';\n } else {\n valid = typeof input === type;\n }\n\n if (!valid) {\n const description = valueDescription(input);\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Function ${functionName}() requires its ${inputName} ` +\n `to be of type ${type}, but it was: ${description}`\n );\n }\n}\n\n/**\n * Returns true if it's a non-null object without a custom prototype\n * (i.e. excludes Array, Date, etc.).\n */\nexport function isPlainObject(input: unknown): boolean {\n return (\n typeof input === 'object' &&\n input !== null &&\n (Object.getPrototypeOf(input) === Object.prototype ||\n Object.getPrototypeOf(input) === null)\n );\n}\n\n/** Returns a string describing the type / value of the provided input. */\nexport function valueDescription(input: unknown): string {\n if (input === undefined) {\n return 'undefined';\n } else if (input === null) {\n return 'null';\n } else if (typeof input === 'string') {\n if (input.length > 20) {\n input = `${input.substring(0, 20)}...`;\n }\n return JSON.stringify(input);\n } else if (typeof input === 'number' || typeof input === 'boolean') {\n return '' + input;\n } else if (typeof input === 'object') {\n if (input instanceof Array) {\n return 'an array';\n } else {\n const customObjectName = tryGetCustomObjectType(input!);\n if (customObjectName) {\n return `a custom ${customObjectName} object`;\n } else {\n return 'an object';\n }\n }\n } else if (typeof input === 'function') {\n return 'a function';\n } else {\n return fail('Unknown wrong type: ' + typeof input);\n }\n}\n\n/** Hacky method to try to get the constructor name for an object. */\nexport function tryGetCustomObjectType(input: object): string | null {\n if (input.constructor) {\n const funcNameRegex = /function\\s+([^\\s(]+)\\s*\\(/;\n const results = funcNameRegex.exec(input.constructor.toString());\n if (results && results.length > 1) {\n return results[1];\n }\n }\n return null;\n}\n\n/** Validates the provided argument is defined. */\nexport function validateDefined(\n functionName: string,\n position: number,\n argument: unknown\n): void {\n if (argument === undefined) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Function ${functionName}() requires a valid ${ordinal(position)} ` +\n `argument, but it was undefined.`\n );\n }\n}\n\n/**\n * Validates the provided positional argument is an object, and its keys and\n * values match the expected keys and types provided in optionTypes.\n */\nexport function validateOptionNames(\n functionName: string,\n options: object,\n optionNames: string[]\n): void {\n forEach(options as Dict<unknown>, (key, _) => {\n if (optionNames.indexOf(key) < 0) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Unknown option '${key}' passed to function ${functionName}(). ` +\n 'Available options: ' +\n optionNames.join(', ')\n );\n }\n });\n}\n\n/**\n * Helper method to throw an error that the provided argument did not pass\n * an instanceof check.\n */\nexport function invalidClassError(\n functionName: string,\n type: string,\n position: number,\n argument: unknown\n): Error {\n const description = valueDescription(argument);\n return new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Function ${functionName}() requires its ${ordinal(position)} ` +\n `argument to be a ${type}, but it was: ${description}`\n );\n}\n\nexport function validatePositiveNumber(\n functionName: string,\n position: number,\n n: number\n): void {\n if (n <= 0) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Function ${functionName}() requires its ${ordinal(\n position\n )} argument to be a positive number, but it was: ${n}.`\n );\n }\n}\n\n/** Converts a number to its english word representation */\nfunction ordinal(num: number): string {\n switch (num) {\n case 1:\n return 'first';\n case 2:\n return 'second';\n case 3:\n return 'third';\n default:\n return num + 'th';\n }\n}\n\n/**\n * Formats the given word as plural conditionally given the preceding number.\n */\nfunction formatPlural(num: number, str: string): string {\n return `${num} ${str}` + (num === 1 ? '' : 's');\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 * as firestore from '@firebase/firestore-types';\n\nimport { FieldPath as InternalFieldPath } from '../model/path';\nimport { Code, FirestoreError } from '../util/error';\nimport {\n invalidClassError,\n validateArgType,\n validateNamedArrayAtLeastNumberOfElements\n} from '../util/input_validation';\n\n// The objects that are a part of this API are exposed to third-parties as\n// compiled javascript so we want to flag our private members with a leading\n// underscore to discourage their use.\n\n/**\n * A FieldPath refers to a field in a document. The path may consist of a single\n * field name (referring to a top-level field in the document), or a list of\n * field names (referring to a nested field in the document).\n */\nexport class FieldPath implements firestore.FieldPath {\n /** Internal representation of a Firestore field path. */\n _internalPath: InternalFieldPath;\n\n /**\n * Creates a FieldPath from the provided field names. If more than one field\n * name is provided, the path will point to a nested field in a document.\n *\n * @param fieldNames A list of field names.\n */\n constructor(...fieldNames: string[]) {\n validateNamedArrayAtLeastNumberOfElements(\n 'FieldPath',\n fieldNames,\n 'fieldNames',\n 1\n );\n\n for (let i = 0; i < fieldNames.length; ++i) {\n validateArgType('FieldPath', 'string', i, fieldNames[i]);\n if (fieldNames[i].length === 0) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Invalid field name at argument $(i + 1). ` +\n 'Field names must not be empty.'\n );\n }\n }\n\n this._internalPath = new InternalFieldPath(fieldNames);\n }\n\n /**\n * Internal Note: The backend doesn't technically support querying by\n * document ID. Instead it queries by the entire document name (full path\n * included), but in the cases we currently support documentId(), the net\n * effect is the same.\n */\n private static readonly _DOCUMENT_ID = new FieldPath(\n InternalFieldPath.keyField().canonicalString()\n );\n\n static documentId(): FieldPath {\n return FieldPath._DOCUMENT_ID;\n }\n\n isEqual(other: firestore.FieldPath): boolean {\n if (!(other instanceof FieldPath)) {\n throw invalidClassError('isEqual', 'FieldPath', 1, other);\n }\n return this._internalPath.isEqual(other._internalPath);\n }\n}\n\n/**\n * Matches any characters in a field path string that are reserved.\n */\nconst RESERVED = new RegExp('[~\\\\*/\\\\[\\\\]]');\n\n/**\n * Parses a field path string into a FieldPath, treating dots as separators.\n */\nexport function fromDotSeparatedString(path: string): FieldPath {\n const found = path.search(RESERVED);\n if (found >= 0) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Invalid field path (${path}). Paths must not contain ` +\n `'~', '*', '/', '[', or ']'`\n );\n }\n try {\n return new FieldPath(...path.split('.'));\n } catch (e) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Invalid field path (${path}). Paths must not be empty, ` +\n `begin with '.', end with '.', or contain '..'`\n );\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 { User } from '../auth/user';\nimport { hardAssert, debugAssert } from '../util/assert';\nimport { Code, FirestoreError } from '../util/error';\nimport {\n FirebaseAuthInternal,\n FirebaseAuthInternalName\n} from '@firebase/auth-interop-types';\nimport { Provider } from '@firebase/component';\n\n// TODO(mikelehen): This should be split into multiple files and probably\n// moved to an auth/ folder to match other platforms.\n\nexport interface FirstPartyCredentialsSettings {\n type: 'gapi';\n client: unknown;\n sessionIndex: string;\n}\n\nexport interface ProviderCredentialsSettings {\n type: 'provider';\n client: CredentialsProvider;\n}\n\n/** Settings for private credentials */\nexport type CredentialsSettings =\n | FirstPartyCredentialsSettings\n | ProviderCredentialsSettings;\n\nexport type TokenType = 'OAuth' | 'FirstParty';\nexport interface Token {\n /** Type of token. */\n type: TokenType;\n\n /**\n * The user with which the token is associated (used for persisting user\n * state on disk, etc.).\n */\n user: User;\n\n /** Extra header values to be passed along with a request */\n authHeaders: { [header: string]: string };\n}\n\nexport class OAuthToken implements Token {\n type = 'OAuth' as TokenType;\n authHeaders: { [header: string]: string };\n constructor(value: string, public user: User) {\n this.authHeaders = {};\n // Set the headers using Object Literal notation to avoid minification\n this.authHeaders['Authorization'] = `Bearer ${value}`;\n }\n}\n\n/**\n * A Listener for credential change events. The listener should fetch a new\n * token and may need to invalidate other state if the current user has also\n * changed.\n */\nexport type CredentialChangeListener = (user: User) => void;\n\n/**\n * Provides methods for getting the uid and token for the current user and\n * listening for changes.\n */\nexport interface CredentialsProvider {\n /** Requests a token for the current user. */\n getToken(): Promise<Token | null>;\n\n /**\n * Marks the last retrieved token as invalid, making the next GetToken request\n * force-refresh the token.\n */\n invalidateToken(): void;\n\n /**\n * Specifies a listener to be notified of credential changes\n * (sign-in / sign-out, token changes). It is immediately called once with the\n * initial user.\n */\n setChangeListener(changeListener: CredentialChangeListener): void;\n\n /** Removes the previously-set change listener. */\n removeChangeListener(): void;\n}\n\n/** A CredentialsProvider that always yields an empty token. */\nexport class EmptyCredentialsProvider implements CredentialsProvider {\n /**\n * Stores the listener registered with setChangeListener()\n * This isn't actually necessary since the UID never changes, but we use this\n * to verify the listen contract is adhered to in tests.\n */\n private changeListener: CredentialChangeListener | null = null;\n\n getToken(): Promise<Token | null> {\n return Promise.resolve<Token | null>(null);\n }\n\n invalidateToken(): void {}\n\n setChangeListener(changeListener: CredentialChangeListener): void {\n debugAssert(\n !this.changeListener,\n 'Can only call setChangeListener() once.'\n );\n this.changeListener = changeListener;\n // Fire with initial user.\n changeListener(User.UNAUTHENTICATED);\n }\n\n removeChangeListener(): void {\n debugAssert(\n this.changeListener !== null,\n 'removeChangeListener() when no listener registered'\n );\n this.changeListener = null;\n }\n}\n\nexport class FirebaseCredentialsProvider implements CredentialsProvider {\n /**\n * The auth token listener registered with FirebaseApp, retained here so we\n * can unregister it.\n */\n private tokenListener: ((token: string | null) => void) | null = null;\n\n /** Tracks the current User. */\n private currentUser: User = User.UNAUTHENTICATED;\n private receivedInitialUser: boolean = false;\n\n /**\n * Counter used to detect if the token changed while a getToken request was\n * outstanding.\n */\n private tokenCounter = 0;\n\n /** The listener registered with setChangeListener(). */\n private changeListener: CredentialChangeListener | null = null;\n\n private forceRefresh = false;\n\n private auth: FirebaseAuthInternal | null;\n\n constructor(authProvider: Provider<FirebaseAuthInternalName>) {\n this.tokenListener = () => {\n this.tokenCounter++;\n this.currentUser = this.getUser();\n this.receivedInitialUser = true;\n if (this.changeListener) {\n this.changeListener(this.currentUser);\n }\n };\n\n this.tokenCounter = 0;\n\n this.auth = authProvider.getImmediate({ optional: true });\n\n if (this.auth) {\n this.auth.addAuthTokenListener(this.tokenListener!);\n } else {\n // if auth is not available, invoke tokenListener once with null token\n this.tokenListener(null);\n authProvider.get().then(\n auth => {\n this.auth = auth;\n if (this.tokenListener) {\n // tokenListener can be removed by removeChangeListener()\n this.auth.addAuthTokenListener(this.tokenListener);\n }\n },\n () => {\n /* this.authProvider.get() never rejects */\n }\n );\n }\n }\n\n getToken(): Promise<Token | null> {\n debugAssert(\n this.tokenListener != null,\n 'getToken cannot be called after listener removed.'\n );\n\n // Take note of the current value of the tokenCounter so that this method\n // can fail (with an ABORTED error) if there is a token change while the\n // request is outstanding.\n const initialTokenCounter = this.tokenCounter;\n const forceRefresh = this.forceRefresh;\n this.forceRefresh = false;\n\n if (!this.auth) {\n return Promise.resolve(null);\n }\n\n return this.auth.getToken(forceRefresh).then(tokenData => {\n // Cancel the request since the token changed while the request was\n // outstanding so the response is potentially for a previous user (which\n // user, we can't be sure).\n if (this.tokenCounter !== initialTokenCounter) {\n throw new FirestoreError(\n Code.ABORTED,\n 'getToken aborted due to token change.'\n );\n } else {\n if (tokenData) {\n hardAssert(\n typeof tokenData.accessToken === 'string',\n 'Invalid tokenData returned from getToken():' + tokenData\n );\n return new OAuthToken(tokenData.accessToken, this.currentUser);\n } else {\n return null;\n }\n }\n });\n }\n\n invalidateToken(): void {\n this.forceRefresh = true;\n }\n\n setChangeListener(changeListener: CredentialChangeListener): void {\n debugAssert(\n !this.changeListener,\n 'Can only call setChangeListener() once.'\n );\n this.changeListener = changeListener;\n\n // Fire the initial event\n if (this.receivedInitialUser) {\n changeListener(this.currentUser);\n }\n }\n\n removeChangeListener(): void {\n debugAssert(\n this.tokenListener != null,\n 'removeChangeListener() called twice'\n );\n debugAssert(\n this.changeListener !== null,\n 'removeChangeListener() called when no listener registered'\n );\n\n if (this.auth) {\n this.auth.removeAuthTokenListener(this.tokenListener!);\n }\n this.tokenListener = null;\n this.changeListener = null;\n }\n\n // Auth.getUid() can return null even with a user logged in. It is because\n // getUid() is synchronous, but the auth code populating Uid is asynchronous.\n // This method should only be called in the AuthTokenListener callback\n // to guarantee to get the actual user.\n private getUser(): User {\n const currentUid = this.auth && this.auth.getUid();\n hardAssert(\n currentUid === null || typeof currentUid === 'string',\n 'Received invalid UID: ' + currentUid\n );\n return new User(currentUid);\n }\n}\n\n// Manual type definition for the subset of Gapi we use.\ninterface Gapi {\n auth: {\n getAuthHeaderValueForFirstParty: (\n userIdentifiers: Array<{ [key: string]: string }>\n ) => string | null;\n };\n}\n\n/*\n * FirstPartyToken provides a fresh token each time its value\n * is requested, because if the token is too old, requests will be rejected.\n * Technically this may no longer be necessary since the SDK should gracefully\n * recover from unauthenticated errors (see b/33147818 for context), but it's\n * safer to keep the implementation as-is.\n */\nexport class FirstPartyToken implements Token {\n type = 'FirstParty' as TokenType;\n user = User.FIRST_PARTY;\n\n constructor(private gapi: Gapi, private sessionIndex: string) {}\n\n get authHeaders(): { [header: string]: string } {\n const headers: { [header: string]: string } = {\n 'X-Goog-AuthUser': this.sessionIndex\n };\n const authHeader = this.gapi.auth.getAuthHeaderValueForFirstParty([]);\n if (authHeader) {\n headers['Authorization'] = authHeader;\n }\n return headers;\n }\n}\n\n/*\n * Provides user credentials required for the Firestore JavaScript SDK\n * to authenticate the user, using technique that is only available\n * to applications hosted by Google.\n */\nexport class FirstPartyCredentialsProvider implements CredentialsProvider {\n constructor(private gapi: Gapi, private sessionIndex: string) {}\n\n getToken(): Promise<Token | null> {\n return Promise.resolve(new FirstPartyToken(this.gapi, this.sessionIndex));\n }\n\n setChangeListener(changeListener: CredentialChangeListener): void {\n // Fire with initial uid.\n changeListener(User.FIRST_PARTY);\n }\n\n removeChangeListener(): void {}\n\n invalidateToken(): void {}\n}\n\n/**\n * Builds a CredentialsProvider depending on the type of\n * the credentials passed in.\n */\nexport function makeCredentialsProvider(\n credentials?: CredentialsSettings\n): CredentialsProvider {\n if (!credentials) {\n return new EmptyCredentialsProvider();\n }\n\n switch (credentials.type) {\n case 'gapi':\n const client = credentials.client as Gapi;\n // Make sure this really is a Gapi client.\n hardAssert(\n !!(\n typeof client === 'object' &&\n client !== null &&\n client['auth'] &&\n client['auth']['getAuthHeaderValueForFirstParty']\n ),\n 'unexpected gapi interface'\n );\n return new FirstPartyCredentialsProvider(\n client,\n credentials.sessionIndex || '0'\n );\n\n case 'provider':\n return credentials.client;\n\n default:\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'makeCredentialsProvider failed due to invalid credential type'\n );\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 { JsonObject } from '../model/object_value';\n\n/**\n * Observer/Subscribe interfaces.\n */\nexport type NextFn<T> = (value: T) => void;\nexport type ErrorFn = (error: Error) => void;\nexport type CompleteFn = () => void;\n\n// Allow for any of the Observer methods to be undefined.\nexport interface PartialObserver<T> {\n next?: NextFn<T>;\n error?: ErrorFn;\n complete?: CompleteFn;\n}\n\nexport interface Unsubscribe {\n (): void;\n}\n\nexport function isPartialObserver(obj: unknown): boolean {\n return implementsAnyMethods(obj, ['next', 'error', 'complete']);\n}\n\n/**\n * Returns true if obj is an object and contains at least one of the specified\n * methods.\n */\nfunction implementsAnyMethods(obj: unknown, methods: string[]): boolean {\n if (typeof obj !== 'object' || obj === null) {\n return false;\n }\n\n const object = obj as JsonObject<unknown>;\n for (const method of methods) {\n if (method in object && typeof object[method] === 'function') {\n return true;\n }\n }\n return false;\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 { PlatformSupport } from '../platform/platform';\nimport { Code, FirestoreError } from '../util/error';\nimport {\n invalidClassError,\n validateArgType,\n validateExactNumberOfArgs\n} from '../util/input_validation';\nimport { ByteString } from '../util/byte_string';\n\n/** Helper function to assert Uint8Array is available at runtime. */\nfunction assertUint8ArrayAvailable(): void {\n if (typeof Uint8Array === 'undefined') {\n throw new FirestoreError(\n Code.UNIMPLEMENTED,\n 'Uint8Arrays are not available in this environment.'\n );\n }\n}\n\n/** Helper function to assert Base64 functions are available at runtime. */\nfunction assertBase64Available(): void {\n if (!PlatformSupport.getPlatform().base64Available) {\n throw new FirestoreError(\n Code.UNIMPLEMENTED,\n 'Blobs are unavailable in Firestore in this environment.'\n );\n }\n}\n\n/**\n * Immutable class holding a blob (binary data).\n * This class is directly exposed in the public API.\n *\n * Note that while you can't hide the constructor in JavaScript code, we are\n * using the hack above to make sure no-one outside this module can call it.\n */\nexport class Blob {\n // Prefix with underscore to signal that we consider this not part of the\n // public API and to prevent it from showing up for autocompletion.\n _byteString: ByteString;\n\n constructor(byteString: ByteString) {\n assertBase64Available();\n this._byteString = byteString;\n }\n\n static fromBase64String(base64: string): Blob {\n validateExactNumberOfArgs('Blob.fromBase64String', arguments, 1);\n validateArgType('Blob.fromBase64String', 'string', 1, base64);\n assertBase64Available();\n try {\n return new Blob(ByteString.fromBase64String(base64));\n } catch (e) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'Failed to construct Blob from Base64 string: ' + e\n );\n }\n }\n\n static fromUint8Array(array: Uint8Array): Blob {\n validateExactNumberOfArgs('Blob.fromUint8Array', arguments, 1);\n assertUint8ArrayAvailable();\n if (!(array instanceof Uint8Array)) {\n throw invalidClassError('Blob.fromUint8Array', 'Uint8Array', 1, array);\n }\n return new Blob(ByteString.fromUint8Array(array));\n }\n\n toBase64(): string {\n validateExactNumberOfArgs('Blob.toBase64', arguments, 0);\n assertBase64Available();\n return this._byteString.toBase64();\n }\n\n toUint8Array(): Uint8Array {\n validateExactNumberOfArgs('Blob.toUint8Array', arguments, 0);\n assertUint8ArrayAvailable();\n return this._byteString.toUint8Array();\n }\n\n toString(): string {\n return 'Blob(base64: ' + this.toBase64() + ')';\n }\n\n isEqual(other: Blob): boolean {\n return this._byteString.isEqual(other._byteString);\n }\n}\n","/**\n * @license\n * Copyright 2018 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 * as api from '../protos/firestore_proto_api';\n\nimport { Timestamp } from '../api/timestamp';\nimport { debugAssert } from '../util/assert';\nimport { JsonProtoSerializer } from '../remote/serializer';\nimport {\n valueEquals,\n isArray,\n isInteger,\n isNumber,\n normalizeNumber\n} from './values';\nimport { serverTimestamp } from './server_timestamps';\nimport { arrayEquals } from '../util/misc';\n\n/** Represents a transform within a TransformMutation. */\nexport interface TransformOperation {\n /**\n * Computes the local transform result against the provided `previousValue`,\n * optionally using the provided localWriteTime.\n */\n applyToLocalView(\n previousValue: api.Value | null,\n localWriteTime: Timestamp\n ): api.Value;\n\n /**\n * Computes a final transform result after the transform has been acknowledged\n * by the server, potentially using the server-provided transformResult.\n */\n applyToRemoteDocument(\n previousValue: api.Value | null,\n transformResult: api.Value | null\n ): api.Value;\n\n /**\n * If this transform operation is not idempotent, returns the base value to\n * persist for this transform. If a base value is returned, the transform\n * operation is always applied to this base value, even if document has\n * already been updated.\n *\n * Base values provide consistent behavior for non-idempotent transforms and\n * allow us to return the same latency-compensated value even if the backend\n * has already applied the transform operation. The base value is null for\n * idempotent transforms, as they can be re-played even if the backend has\n * already applied them.\n *\n * @return a base value to store along with the mutation, or null for\n * idempotent transforms.\n */\n computeBaseValue(previousValue: api.Value | null): api.Value | null;\n\n isEqual(other: TransformOperation): boolean;\n}\n\n/** Transforms a value into a server-generated timestamp. */\nexport class ServerTimestampTransform implements TransformOperation {\n private constructor() {}\n static instance = new ServerTimestampTransform();\n\n applyToLocalView(\n previousValue: api.Value | null,\n localWriteTime: Timestamp\n ): api.Value {\n return serverTimestamp(localWriteTime!, previousValue);\n }\n\n applyToRemoteDocument(\n previousValue: api.Value | null,\n transformResult: api.Value | null\n ): api.Value {\n return transformResult!;\n }\n\n computeBaseValue(previousValue: api.Value | null): api.Value | null {\n return null; // Server timestamps are idempotent and don't require a base value.\n }\n\n isEqual(other: TransformOperation): boolean {\n return other instanceof ServerTimestampTransform;\n }\n}\n\n/** Transforms an array value via a union operation. */\nexport class ArrayUnionTransformOperation implements TransformOperation {\n constructor(readonly elements: api.Value[]) {}\n\n applyToLocalView(\n previousValue: api.Value | null,\n localWriteTime: Timestamp\n ): api.Value {\n return this.apply(previousValue);\n }\n\n applyToRemoteDocument(\n previousValue: api.Value | null,\n transformResult: api.Value | null\n ): api.Value {\n // The server just sends null as the transform result for array operations,\n // so we have to calculate a result the same as we do for local\n // applications.\n return this.apply(previousValue);\n }\n\n private apply(previousValue: api.Value | null): api.Value {\n const values = coercedFieldValuesArray(previousValue);\n for (const toUnion of this.elements) {\n if (!values.some(element => valueEquals(element, toUnion))) {\n values.push(toUnion);\n }\n }\n return { arrayValue: { values } };\n }\n\n computeBaseValue(previousValue: api.Value | null): api.Value | null {\n return null; // Array transforms are idempotent and don't require a base value.\n }\n\n isEqual(other: TransformOperation): boolean {\n return (\n other instanceof ArrayUnionTransformOperation &&\n arrayEquals(this.elements, other.elements, valueEquals)\n );\n }\n}\n\n/** Transforms an array value via a remove operation. */\nexport class ArrayRemoveTransformOperation implements TransformOperation {\n constructor(readonly elements: api.Value[]) {}\n\n applyToLocalView(\n previousValue: api.Value | null,\n localWriteTime: Timestamp\n ): api.Value {\n return this.apply(previousValue);\n }\n\n applyToRemoteDocument(\n previousValue: api.Value | null,\n transformResult: api.Value | null\n ): api.Value {\n // The server just sends null as the transform result for array operations,\n // so we have to calculate a result the same as we do for local\n // applications.\n return this.apply(previousValue);\n }\n\n private apply(previousValue: api.Value | null): api.Value {\n let values = coercedFieldValuesArray(previousValue);\n for (const toRemove of this.elements) {\n values = values.filter(element => !valueEquals(element, toRemove));\n }\n return { arrayValue: { values } };\n }\n\n computeBaseValue(previousValue: api.Value | null): api.Value | null {\n return null; // Array transforms are idempotent and don't require a base value.\n }\n\n isEqual(other: TransformOperation): boolean {\n return (\n other instanceof ArrayRemoveTransformOperation &&\n arrayEquals(this.elements, other.elements, valueEquals)\n );\n }\n}\n\n/**\n * Implements the backend semantics for locally computed NUMERIC_ADD (increment)\n * transforms. Converts all field values to integers or doubles, but unlike the\n * backend does not cap integer values at 2^63. Instead, JavaScript number\n * arithmetic is used and precision loss can occur for values greater than 2^53.\n */\nexport class NumericIncrementTransformOperation implements TransformOperation {\n constructor(\n private readonly serializer: JsonProtoSerializer,\n readonly operand: api.Value\n ) {\n debugAssert(\n isNumber(operand),\n 'NumericIncrementTransform transform requires a NumberValue'\n );\n }\n\n applyToLocalView(\n previousValue: api.Value | null,\n localWriteTime: Timestamp\n ): api.Value {\n // PORTING NOTE: Since JavaScript's integer arithmetic is limited to 53 bit\n // precision and resolves overflows by reducing precision, we do not\n // manually cap overflows at 2^63.\n const baseValue = this.computeBaseValue(previousValue);\n const sum = this.asNumber(baseValue) + this.asNumber(this.operand);\n if (isInteger(baseValue) && isInteger(this.operand)) {\n return this.serializer.toInteger(sum);\n } else {\n return this.serializer.toDouble(sum);\n }\n }\n\n applyToRemoteDocument(\n previousValue: api.Value | null,\n transformResult: api.Value | null\n ): api.Value {\n debugAssert(\n transformResult !== null,\n \"Didn't receive transformResult for NUMERIC_ADD transform\"\n );\n return transformResult;\n }\n\n /**\n * Inspects the provided value, returning the provided value if it is already\n * a NumberValue, otherwise returning a coerced value of 0.\n */\n computeBaseValue(previousValue: api.Value | null): api.Value {\n return isNumber(previousValue) ? previousValue! : { integerValue: 0 };\n }\n\n isEqual(other: TransformOperation): boolean {\n return (\n other instanceof NumericIncrementTransformOperation &&\n valueEquals(this.operand, other.operand)\n );\n }\n\n private asNumber(value: api.Value): number {\n return normalizeNumber(value.integerValue || value.doubleValue);\n }\n}\n\nfunction coercedFieldValuesArray(value: api.Value | null): api.Value[] {\n return isArray(value) && value.arrayValue.values\n ? value.arrayValue.values.slice()\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 * as firestore from '@firebase/firestore-types';\nimport {\n validateArgType,\n validateAtLeastNumberOfArgs,\n validateExactNumberOfArgs,\n validateNoArgs\n} from '../util/input_validation';\nimport { FieldTransform } from '../model/mutation';\nimport {\n ArrayRemoveTransformOperation,\n ArrayUnionTransformOperation,\n NumericIncrementTransformOperation,\n ServerTimestampTransform\n} from '../model/transform_operation';\nimport { ParseContext, parseData, UserDataSource } from './user_data_reader';\nimport { debugAssert } from '../util/assert';\n\n/**\n * An opaque base class for FieldValue sentinel objects in our public API,\n * with public static methods for creating said sentinel objects.\n */\nexport abstract class FieldValueImpl {\n protected constructor(readonly _methodName: string) {}\n\n abstract toFieldTransform(context: ParseContext): FieldTransform | null;\n\n abstract isEqual(other: FieldValue): boolean;\n}\n\nexport class DeleteFieldValueImpl extends FieldValueImpl {\n constructor() {\n super('FieldValue.delete');\n }\n\n toFieldTransform(context: ParseContext): null {\n if (context.dataSource === UserDataSource.MergeSet) {\n // No transform to add for a delete, but we need to add it to our\n // fieldMask so it gets deleted.\n context.fieldMask.push(context.path!);\n } else if (context.dataSource === UserDataSource.Update) {\n debugAssert(\n context.path!.length > 0,\n 'FieldValue.delete() at the top level should have already' +\n ' been handled.'\n );\n throw context.createError(\n 'FieldValue.delete() can only appear at the top level ' +\n 'of your update data'\n );\n } else {\n // We shouldn't encounter delete sentinels for queries or non-merge set() calls.\n throw context.createError(\n 'FieldValue.delete() cannot be used with set() unless you pass ' +\n '{merge:true}'\n );\n }\n return null;\n }\n\n isEqual(other: FieldValue): boolean {\n return other instanceof DeleteFieldValueImpl;\n }\n}\n\nexport class ServerTimestampFieldValueImpl extends FieldValueImpl {\n constructor() {\n super('FieldValue.serverTimestamp');\n }\n\n toFieldTransform(context: ParseContext): FieldTransform {\n return new FieldTransform(context.path!, ServerTimestampTransform.instance);\n }\n\n isEqual(other: FieldValue): boolean {\n return other instanceof ServerTimestampFieldValueImpl;\n }\n}\n\nexport class ArrayUnionFieldValueImpl extends FieldValueImpl {\n constructor(private readonly _elements: unknown[]) {\n super('FieldValue.arrayUnion');\n }\n\n toFieldTransform(context: ParseContext): FieldTransform {\n // Although array transforms are used with writes, the actual elements\n // being uniomed or removed are not considered writes since they cannot\n // contain any FieldValue sentinels, etc.\n const parseContext = new ParseContext(\n {\n dataSource: UserDataSource.Argument,\n methodName: this._methodName,\n arrayElement: true\n },\n context.databaseId,\n context.serializer,\n context.ignoreUndefinedProperties\n );\n const parsedElements = this._elements.map(\n element => parseData(element, parseContext)!\n );\n const arrayUnion = new ArrayUnionTransformOperation(parsedElements);\n return new FieldTransform(context.path!, arrayUnion);\n }\n\n isEqual(other: FieldValue): boolean {\n // TODO(mrschmidt): Implement isEquals\n return this === other;\n }\n}\n\nexport class ArrayRemoveFieldValueImpl extends FieldValueImpl {\n constructor(readonly _elements: unknown[]) {\n super('FieldValue.arrayRemove');\n }\n\n toFieldTransform(context: ParseContext): FieldTransform {\n // Although array transforms are used with writes, the actual elements\n // being unioned or removed are not considered writes since they cannot\n // contain any FieldValue sentinels, etc.\n const parseContext = new ParseContext(\n {\n dataSource: UserDataSource.Argument,\n methodName: this._methodName,\n arrayElement: true\n },\n context.databaseId,\n context.serializer,\n context.ignoreUndefinedProperties\n );\n const parsedElements = this._elements.map(\n element => parseData(element, parseContext)!\n );\n const arrayUnion = new ArrayRemoveTransformOperation(parsedElements);\n return new FieldTransform(context.path!, arrayUnion);\n }\n\n isEqual(other: FieldValue): boolean {\n // TODO(mrschmidt): Implement isEquals\n return this === other;\n }\n}\n\nexport class NumericIncrementFieldValueImpl extends FieldValueImpl {\n constructor(private readonly _operand: number) {\n super('FieldValue.increment');\n }\n\n toFieldTransform(context: ParseContext): FieldTransform {\n const parseContext = new ParseContext(\n {\n dataSource: UserDataSource.Argument,\n methodName: this._methodName\n },\n context.databaseId,\n context.serializer,\n context.ignoreUndefinedProperties\n );\n const operand = parseData(this._operand, parseContext)!;\n const numericIncrement = new NumericIncrementTransformOperation(\n context.serializer,\n operand\n );\n return new FieldTransform(context.path!, numericIncrement);\n }\n\n isEqual(other: FieldValue): boolean {\n // TODO(mrschmidt): Implement isEquals\n return this === other;\n }\n}\n\nexport class FieldValue implements firestore.FieldValue {\n static delete(): FieldValueImpl {\n validateNoArgs('FieldValue.delete', arguments);\n return new DeleteFieldValueImpl();\n }\n\n static serverTimestamp(): FieldValueImpl {\n validateNoArgs('FieldValue.serverTimestamp', arguments);\n return new ServerTimestampFieldValueImpl();\n }\n\n static arrayUnion(...elements: unknown[]): FieldValueImpl {\n validateAtLeastNumberOfArgs('FieldValue.arrayUnion', arguments, 1);\n // NOTE: We don't actually parse the data until it's used in set() or\n // update() since we need access to the Firestore instance.\n return new ArrayUnionFieldValueImpl(elements);\n }\n\n static arrayRemove(...elements: unknown[]): FieldValueImpl {\n validateAtLeastNumberOfArgs('FieldValue.arrayRemove', arguments, 1);\n // NOTE: We don't actually parse the data until it's used in set() or\n // update() since we need access to the Firestore instance.\n return new ArrayRemoveFieldValueImpl(elements);\n }\n\n static increment(n: number): FieldValueImpl {\n validateArgType('FieldValue.increment', 'number', 1, n);\n validateExactNumberOfArgs('FieldValue.increment', arguments, 1);\n return new NumericIncrementFieldValueImpl(n);\n }\n\n isEqual(other: FieldValue): boolean {\n return this === other;\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 { Code, FirestoreError } from '../util/error';\nimport {\n validateArgType,\n validateExactNumberOfArgs\n} from '../util/input_validation';\nimport { primitiveComparator } from '../util/misc';\n\n/**\n * Immutable class representing a geo point as latitude-longitude pair.\n * This class is directly exposed in the public API, including its constructor.\n */\nexport class GeoPoint {\n // Prefix with underscore to signal this is a private variable in JS and\n // prevent it showing up for autocompletion when typing latitude or longitude.\n private _lat: number;\n private _long: number;\n\n constructor(latitude: number, longitude: number) {\n validateExactNumberOfArgs('GeoPoint', arguments, 2);\n validateArgType('GeoPoint', 'number', 1, latitude);\n validateArgType('GeoPoint', 'number', 2, longitude);\n if (!isFinite(latitude) || latitude < -90 || latitude > 90) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'Latitude must be a number between -90 and 90, but was: ' + latitude\n );\n }\n if (!isFinite(longitude) || longitude < -180 || longitude > 180) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'Longitude must be a number between -180 and 180, but was: ' + longitude\n );\n }\n\n this._lat = latitude;\n this._long = longitude;\n }\n\n /**\n * Returns the latitude of this geo point, a number between -90 and 90.\n */\n get latitude(): number {\n return this._lat;\n }\n\n /**\n * Returns the longitude of this geo point, a number between -180 and 180.\n */\n get longitude(): number {\n return this._long;\n }\n\n isEqual(other: GeoPoint): boolean {\n return this._lat === other._lat && this._long === other._long;\n }\n\n /**\n * Actually private to JS consumers of our API, so this function is prefixed\n * with an underscore.\n */\n _compareTo(other: GeoPoint): number {\n return (\n primitiveComparator(this._lat, other._lat) ||\n primitiveComparator(this._long, other._long)\n );\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 * as firestore from '@firebase/firestore-types';\n\nimport * as api from '../protos/firestore_proto_api';\n\nimport { Timestamp } from './timestamp';\nimport { DatabaseId } from '../core/database_info';\nimport { DocumentKey } from '../model/document_key';\nimport {\n FieldMask,\n FieldTransform,\n Mutation,\n PatchMutation,\n Precondition,\n SetMutation,\n TransformMutation\n} from '../model/mutation';\nimport { FieldPath } from '../model/path';\nimport { debugAssert, fail } from '../util/assert';\nimport { Code, FirestoreError } from '../util/error';\nimport { isPlainObject, valueDescription } from '../util/input_validation';\nimport { Dict, forEach, isEmpty } from '../util/obj';\nimport { ObjectValue, ObjectValueBuilder } from '../model/object_value';\nimport { JsonProtoSerializer } from '../remote/serializer';\nimport { Blob } from './blob';\nimport {\n FieldPath as ExternalFieldPath,\n fromDotSeparatedString\n} from './field_path';\nimport { DeleteFieldValueImpl, FieldValueImpl } from './field_value';\nimport { GeoPoint } from './geo_point';\nimport { PlatformSupport } from '../platform/platform';\nimport { DocumentReference } from './database';\n\nconst RESERVED_FIELD_REGEX = /^__.*__$/;\n\n/** The result of parsing document data (e.g. for a setData call). */\nexport class ParsedSetData {\n constructor(\n readonly data: ObjectValue,\n readonly fieldMask: FieldMask | null,\n readonly fieldTransforms: FieldTransform[]\n ) {}\n\n toMutations(key: DocumentKey, precondition: Precondition): Mutation[] {\n const mutations = [] as Mutation[];\n if (this.fieldMask !== null) {\n mutations.push(\n new PatchMutation(key, this.data, this.fieldMask, precondition)\n );\n } else {\n mutations.push(new SetMutation(key, this.data, precondition));\n }\n if (this.fieldTransforms.length > 0) {\n mutations.push(new TransformMutation(key, this.fieldTransforms));\n }\n return mutations;\n }\n}\n\n/** The result of parsing \"update\" data (i.e. for an updateData call). */\nexport class ParsedUpdateData {\n constructor(\n readonly data: ObjectValue,\n readonly fieldMask: FieldMask,\n readonly fieldTransforms: FieldTransform[]\n ) {}\n\n toMutations(key: DocumentKey, precondition: Precondition): Mutation[] {\n const mutations = [\n new PatchMutation(key, this.data, this.fieldMask, precondition)\n ] as Mutation[];\n if (this.fieldTransforms.length > 0) {\n mutations.push(new TransformMutation(key, this.fieldTransforms));\n }\n return mutations;\n }\n}\n\n/*\n * Represents what type of API method provided the data being parsed; useful\n * for determining which error conditions apply during parsing and providing\n * better error messages.\n */\nexport const enum UserDataSource {\n Set,\n Update,\n MergeSet,\n /**\n * Indicates the source is a where clause, cursor bound, arrayUnion()\n * element, etc. Of note, isWrite(source) will return false.\n */\n Argument,\n /**\n * Indicates that the source is an Argument that may directly contain nested\n * arrays (e.g. the operand of an `in` query).\n */\n ArrayArgument\n}\n\nfunction isWrite(dataSource: UserDataSource): boolean {\n switch (dataSource) {\n case UserDataSource.Set: // fall through\n case UserDataSource.MergeSet: // fall through\n case UserDataSource.Update:\n return true;\n case UserDataSource.Argument:\n case UserDataSource.ArrayArgument:\n return false;\n default:\n throw fail(`Unexpected case for UserDataSource: ${dataSource}`);\n }\n}\n\n/** Contains the settings that are mutated as we parse user data. */\ninterface ContextSettings {\n /** Indicates what kind of API method this data came from. */\n readonly dataSource: UserDataSource;\n /** The name of the method the user called to create the ParseContext. */\n readonly methodName: string;\n /**\n * A path within the object being parsed. This could be an empty path (in\n * which case the context represents the root of the data being parsed), or a\n * nonempty path (indicating the context represents a nested location within\n * the data).\n */\n readonly path?: FieldPath;\n /**\n * Whether or not this context corresponds to an element of an array.\n * If not set, elements are treated as if they were outside of arrays.\n */\n readonly arrayElement?: boolean;\n}\n\n/** A \"context\" object passed around while parsing user data. */\nexport class ParseContext {\n readonly fieldTransforms: FieldTransform[];\n readonly fieldMask: FieldPath[];\n /**\n * Initializes a ParseContext with the given source and path.\n *\n * @param settings The settings for the parser.\n * @param databaseId The database ID of the Firestore instance.\n * @param serializer The serializer to use to generate the Value proto.\n * @param ignoreUndefinedProperties Whether to ignore undefined properties\n * rather than throw.\n * @param fieldTransforms A mutable list of field transforms encountered while\n * parsing the data.\n * @param fieldMask A mutable list of field paths encountered while parsing\n * the data.\n *\n * TODO(b/34871131): We don't support array paths right now, so path can be\n * null to indicate the context represents any location within an array (in\n * which case certain features will not work and errors will be somewhat\n * compromised).\n */\n constructor(\n readonly settings: ContextSettings,\n readonly databaseId: DatabaseId,\n readonly serializer: JsonProtoSerializer,\n readonly ignoreUndefinedProperties: boolean,\n fieldTransforms?: FieldTransform[],\n fieldMask?: FieldPath[]\n ) {\n // Minor hack: If fieldTransforms is undefined, we assume this is an\n // external call and we need to validate the entire path.\n if (fieldTransforms === undefined) {\n this.validatePath();\n }\n this.fieldTransforms = fieldTransforms || [];\n this.fieldMask = fieldMask || [];\n }\n\n get path(): FieldPath | undefined {\n return this.settings.path;\n }\n\n get dataSource(): UserDataSource {\n return this.settings.dataSource;\n }\n\n /** Returns a new context with the specified settings overwritten. */\n contextWith(configuration: Partial<ContextSettings>): ParseContext {\n return new ParseContext(\n { ...this.settings, ...configuration },\n this.databaseId,\n this.serializer,\n this.ignoreUndefinedProperties,\n this.fieldTransforms,\n this.fieldMask\n );\n }\n\n childContextForField(field: string): ParseContext {\n const childPath = this.path?.child(field);\n const context = this.contextWith({ path: childPath, arrayElement: false });\n context.validatePathSegment(field);\n return context;\n }\n\n childContextForFieldPath(field: FieldPath): ParseContext {\n const childPath = this.path?.child(field);\n const context = this.contextWith({ path: childPath, arrayElement: false });\n context.validatePath();\n return context;\n }\n\n childContextForArray(index: number): ParseContext {\n // TODO(b/34871131): We don't support array paths right now; so make path\n // undefined.\n return this.contextWith({ path: undefined, arrayElement: true });\n }\n\n createError(reason: string): Error {\n const fieldDescription =\n !this.path || this.path.isEmpty()\n ? ''\n : ` (found in field ${this.path.toString()})`;\n return new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Function ${this.settings.methodName}() called with invalid data. ` +\n reason +\n fieldDescription\n );\n }\n\n /** Returns 'true' if 'fieldPath' was traversed when creating this context. */\n contains(fieldPath: FieldPath): boolean {\n return (\n this.fieldMask.find(field => fieldPath.isPrefixOf(field)) !== undefined ||\n this.fieldTransforms.find(transform =>\n fieldPath.isPrefixOf(transform.field)\n ) !== undefined\n );\n }\n\n private validatePath(): void {\n // TODO(b/34871131): Remove null check once we have proper paths for fields\n // within arrays.\n if (!this.path) {\n return;\n }\n for (let i = 0; i < this.path.length; i++) {\n this.validatePathSegment(this.path.get(i));\n }\n }\n\n private validatePathSegment(segment: string): void {\n if (segment.length === 0) {\n throw this.createError('Document fields must not be empty');\n }\n if (isWrite(this.dataSource) && RESERVED_FIELD_REGEX.test(segment)) {\n throw this.createError('Document fields cannot begin and end with \"__\"');\n }\n }\n}\n\n/**\n * Helper for parsing raw user input (provided via the API) into internal model\n * classes.\n */\nexport class UserDataReader {\n private readonly serializer: JsonProtoSerializer;\n\n constructor(\n private readonly databaseId: DatabaseId,\n private readonly ignoreUndefinedProperties: boolean,\n serializer?: JsonProtoSerializer\n ) {\n this.serializer =\n serializer || PlatformSupport.getPlatform().newSerializer(databaseId);\n }\n\n /** Parse document data from a non-merge set() call. */\n parseSetData(methodName: string, input: unknown): ParsedSetData {\n const context = this.createContext(UserDataSource.Set, methodName);\n validatePlainObject('Data must be an object, but it was:', context, input);\n const updateData = parseObject(input, context)!;\n\n return new ParsedSetData(\n new ObjectValue(updateData),\n /* fieldMask= */ null,\n context.fieldTransforms\n );\n }\n\n /** Parse document data from a set() call with '{merge:true}'. */\n parseMergeData(\n methodName: string,\n input: unknown,\n fieldPaths?: Array<string | firestore.FieldPath>\n ): ParsedSetData {\n const context = this.createContext(UserDataSource.MergeSet, methodName);\n validatePlainObject('Data must be an object, but it was:', context, input);\n const updateData = parseObject(input, context);\n\n let fieldMask: FieldMask;\n let fieldTransforms: FieldTransform[];\n\n if (!fieldPaths) {\n fieldMask = new FieldMask(context.fieldMask);\n fieldTransforms = context.fieldTransforms;\n } else {\n const validatedFieldPaths: FieldPath[] = [];\n\n for (const stringOrFieldPath of fieldPaths) {\n let fieldPath: FieldPath;\n\n if (stringOrFieldPath instanceof ExternalFieldPath) {\n fieldPath = stringOrFieldPath._internalPath;\n } else if (typeof stringOrFieldPath === 'string') {\n fieldPath = fieldPathFromDotSeparatedString(\n methodName,\n stringOrFieldPath\n );\n } else {\n throw fail(\n 'Expected stringOrFieldPath to be a string or a FieldPath'\n );\n }\n\n if (!context.contains(fieldPath)) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Field '${fieldPath}' is specified in your field mask but missing from your input data.`\n );\n }\n\n if (!fieldMaskContains(validatedFieldPaths, fieldPath)) {\n validatedFieldPaths.push(fieldPath);\n }\n }\n\n fieldMask = new FieldMask(validatedFieldPaths);\n fieldTransforms = context.fieldTransforms.filter(transform =>\n fieldMask.covers(transform.field)\n );\n }\n return new ParsedSetData(\n new ObjectValue(updateData),\n fieldMask,\n fieldTransforms\n );\n }\n\n /** Parse update data from an update() call. */\n parseUpdateData(methodName: string, input: unknown): ParsedUpdateData {\n const context = this.createContext(UserDataSource.Update, methodName);\n validatePlainObject('Data must be an object, but it was:', context, input);\n\n const fieldMaskPaths: FieldPath[] = [];\n const updateData = new ObjectValueBuilder();\n forEach(input as Dict<unknown>, (key, value) => {\n const path = fieldPathFromDotSeparatedString(methodName, key);\n\n const childContext = context.childContextForFieldPath(path);\n if (value instanceof DeleteFieldValueImpl) {\n // Add it to the field mask, but don't add anything to updateData.\n fieldMaskPaths.push(path);\n } else {\n const parsedValue = parseData(value, childContext);\n if (parsedValue != null) {\n fieldMaskPaths.push(path);\n updateData.set(path, parsedValue);\n }\n }\n });\n\n const mask = new FieldMask(fieldMaskPaths);\n return new ParsedUpdateData(\n updateData.build(),\n mask,\n context.fieldTransforms\n );\n }\n\n /** Parse update data from a list of field/value arguments. */\n parseUpdateVarargs(\n methodName: string,\n field: string | ExternalFieldPath,\n value: unknown,\n moreFieldsAndValues: unknown[]\n ): ParsedUpdateData {\n const context = this.createContext(UserDataSource.Update, methodName);\n const keys = [fieldPathFromArgument(methodName, field)];\n const values = [value];\n\n if (moreFieldsAndValues.length % 2 !== 0) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Function ${methodName}() needs to be called with an even number ` +\n 'of arguments that alternate between field names and values.'\n );\n }\n\n for (let i = 0; i < moreFieldsAndValues.length; i += 2) {\n keys.push(\n fieldPathFromArgument(\n methodName,\n moreFieldsAndValues[i] as string | ExternalFieldPath\n )\n );\n values.push(moreFieldsAndValues[i + 1]);\n }\n\n const fieldMaskPaths: FieldPath[] = [];\n const updateData = new ObjectValueBuilder();\n\n // We iterate in reverse order to pick the last value for a field if the\n // user specified the field multiple times.\n for (let i = keys.length - 1; i >= 0; --i) {\n if (!fieldMaskContains(fieldMaskPaths, keys[i])) {\n const path = keys[i];\n const value = values[i];\n const childContext = context.childContextForFieldPath(path);\n if (value instanceof DeleteFieldValueImpl) {\n // Add it to the field mask, but don't add anything to updateData.\n fieldMaskPaths.push(path);\n } else {\n const parsedValue = parseData(value, childContext);\n if (parsedValue != null) {\n fieldMaskPaths.push(path);\n updateData.set(path, parsedValue);\n }\n }\n }\n }\n\n const mask = new FieldMask(fieldMaskPaths);\n return new ParsedUpdateData(\n updateData.build(),\n mask,\n context.fieldTransforms\n );\n }\n\n /** Creates a new top-level parse context. */\n private createContext(\n dataSource: UserDataSource,\n methodName: string\n ): ParseContext {\n return new ParseContext(\n {\n dataSource,\n methodName,\n path: FieldPath.EMPTY_PATH,\n arrayElement: false\n },\n this.databaseId,\n this.serializer,\n this.ignoreUndefinedProperties\n );\n }\n\n /**\n * Parse a \"query value\" (e.g. value in a where filter or a value in a cursor\n * bound).\n *\n * @param allowArrays Whether the query value is an array that may directly\n * contain additional arrays (e.g. the operand of an `in` query).\n */\n parseQueryValue(\n methodName: string,\n input: unknown,\n allowArrays = false\n ): api.Value {\n const context = this.createContext(\n allowArrays ? UserDataSource.ArrayArgument : UserDataSource.Argument,\n methodName\n );\n const parsed = parseData(input, context);\n debugAssert(parsed != null, 'Parsed data should not be null.');\n debugAssert(\n context.fieldTransforms.length === 0,\n 'Field transforms should have been disallowed.'\n );\n return parsed;\n }\n}\n\n/**\n * Parses user data to Protobuf Values.\n *\n * @param input Data to be parsed.\n * @param context A context object representing the current path being parsed,\n * the source of the data being parsed, etc.\n * @return The parsed value, or null if the value was a FieldValue sentinel\n * that should not be included in the resulting parsed data.\n */\nexport function parseData(\n input: unknown,\n context: ParseContext\n): api.Value | null {\n if (looksLikeJsonObject(input)) {\n validatePlainObject('Unsupported field value:', context, input);\n return parseObject(input, context);\n } else if (input instanceof FieldValueImpl) {\n // FieldValues usually parse into transforms (except FieldValue.delete())\n // in which case we do not want to include this field in our parsed data\n // (as doing so will overwrite the field directly prior to the transform\n // trying to transform it). So we don't add this location to\n // context.fieldMask and we return null as our parsing result.\n parseSentinelFieldValue(input, context);\n return null;\n } else {\n // If context.path is null we are inside an array and we don't support\n // field mask paths more granular than the top-level array.\n if (context.path) {\n context.fieldMask.push(context.path);\n }\n\n if (input instanceof Array) {\n // TODO(b/34871131): Include the path containing the array in the error\n // message.\n // In the case of IN queries, the parsed data is an array (representing\n // the set of values to be included for the IN query) that may directly\n // contain additional arrays (each representing an individual field\n // value), so we disable this validation.\n if (\n context.settings.arrayElement &&\n context.dataSource !== UserDataSource.ArrayArgument\n ) {\n throw context.createError('Nested arrays are not supported');\n }\n return parseArray(input as unknown[], context);\n } else {\n return parseScalarValue(input, context);\n }\n }\n}\n\nfunction parseObject(\n obj: Dict<unknown>,\n context: ParseContext\n): { mapValue: api.MapValue } {\n const fields: Dict<api.Value> = {};\n\n if (isEmpty(obj)) {\n // If we encounter an empty object, we explicitly add it to the update\n // mask to ensure that the server creates a map entry.\n if (context.path && context.path.length > 0) {\n context.fieldMask.push(context.path);\n }\n } else {\n forEach(obj, (key: string, val: unknown) => {\n const parsedValue = parseData(val, context.childContextForField(key));\n if (parsedValue != null) {\n fields[key] = parsedValue;\n }\n });\n }\n\n return { mapValue: { fields } };\n}\n\nfunction parseArray(array: unknown[], context: ParseContext): api.Value {\n const values: api.Value[] = [];\n let entryIndex = 0;\n for (const entry of array) {\n let parsedEntry = parseData(\n entry,\n context.childContextForArray(entryIndex)\n );\n if (parsedEntry == null) {\n // Just include nulls in the array for fields being replaced with a\n // sentinel.\n parsedEntry = { nullValue: 'NULL_VALUE' };\n }\n values.push(parsedEntry);\n entryIndex++;\n }\n return { arrayValue: { values } };\n}\n\n/**\n * \"Parses\" the provided FieldValueImpl, adding any necessary transforms to\n * context.fieldTransforms.\n */\nfunction parseSentinelFieldValue(\n value: FieldValueImpl,\n context: ParseContext\n): void {\n // Sentinels are only supported with writes, and not within arrays.\n if (!isWrite(context.dataSource)) {\n throw context.createError(\n `${value._methodName}() can only be used with update() and set()`\n );\n }\n if (context.path === null) {\n throw context.createError(\n `${value._methodName}() is not currently supported inside arrays`\n );\n }\n\n const fieldTransform = value.toFieldTransform(context);\n if (fieldTransform) {\n context.fieldTransforms.push(fieldTransform);\n }\n}\n\n/**\n * Helper to parse a scalar value (i.e. not an Object, Array, or FieldValue)\n *\n * @return The parsed value\n */\nfunction parseScalarValue(\n value: unknown,\n context: ParseContext\n): api.Value | null {\n if (value === null) {\n return { nullValue: 'NULL_VALUE' };\n } else if (typeof value === 'number') {\n return context.serializer.toNumber(value);\n } else if (typeof value === 'boolean') {\n return { booleanValue: value };\n } else if (typeof value === 'string') {\n return { stringValue: value };\n } else if (value instanceof Date) {\n const timestamp = Timestamp.fromDate(value);\n return { timestampValue: context.serializer.toTimestamp(timestamp) };\n } else if (value instanceof Timestamp) {\n // Firestore backend truncates precision down to microseconds. To ensure\n // offline mode works the same with regards to truncation, perform the\n // truncation immediately without waiting for the backend to do that.\n const timestamp = new Timestamp(\n value.seconds,\n Math.floor(value.nanoseconds / 1000) * 1000\n );\n return { timestampValue: context.serializer.toTimestamp(timestamp) };\n } else if (value instanceof GeoPoint) {\n return {\n geoPointValue: {\n latitude: value.latitude,\n longitude: value.longitude\n }\n };\n } else if (value instanceof Blob) {\n return { bytesValue: context.serializer.toBytes(value) };\n } else if (value instanceof DocumentReference) {\n const thisDb = context.databaseId;\n const otherDb = value.firestore._databaseId;\n if (!otherDb.isEqual(thisDb)) {\n throw context.createError(\n 'Document reference is for database ' +\n `${otherDb.projectId}/${otherDb.database} but should be ` +\n `for database ${thisDb.projectId}/${thisDb.database}`\n );\n }\n return {\n referenceValue: context.serializer.toResourceName(\n value._key.path,\n value.firestore._databaseId\n )\n };\n } else if (value === undefined && context.ignoreUndefinedProperties) {\n return null;\n } else {\n throw context.createError(\n `Unsupported field value: ${valueDescription(value)}`\n );\n }\n}\n\n/**\n * Checks whether an object looks like a JSON object that should be converted\n * into a struct. Normal class/prototype instances are considered to look like\n * JSON objects since they should be converted to a struct value. Arrays, Dates,\n * GeoPoints, etc. are not considered to look like JSON objects since they map\n * to specific FieldValue types other than ObjectValue.\n */\nfunction looksLikeJsonObject(input: unknown): boolean {\n return (\n typeof input === 'object' &&\n input !== null &&\n !(input instanceof Array) &&\n !(input instanceof Date) &&\n !(input instanceof Timestamp) &&\n !(input instanceof GeoPoint) &&\n !(input instanceof Blob) &&\n !(input instanceof DocumentReference) &&\n !(input instanceof FieldValueImpl)\n );\n}\n\nfunction validatePlainObject(\n message: string,\n context: ParseContext,\n input: unknown\n): asserts input is Dict<unknown> {\n if (!looksLikeJsonObject(input) || !isPlainObject(input)) {\n const description = valueDescription(input);\n if (description === 'an object') {\n // Massage the error if it was an object.\n throw context.createError(message + ' a custom object');\n } else {\n throw context.createError(message + ' ' + description);\n }\n }\n}\n\n/**\n * Helper that calls fromDotSeparatedString() but wraps any error thrown.\n */\nexport function fieldPathFromArgument(\n methodName: string,\n path: string | ExternalFieldPath\n): FieldPath {\n if (path instanceof ExternalFieldPath) {\n return path._internalPath;\n } else if (typeof path === 'string') {\n return fieldPathFromDotSeparatedString(methodName, path);\n } else {\n const message = 'Field path arguments must be of type string or FieldPath.';\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Function ${methodName}() called with invalid data. ${message}`\n );\n }\n}\n\n/**\n * Wraps fromDotSeparatedString with an error message about the method that\n * was thrown.\n * @param methodName The publicly visible method name\n * @param path The dot-separated string form of a field path which will be split\n * on dots.\n */\nfunction fieldPathFromDotSeparatedString(\n methodName: string,\n path: string\n): FieldPath {\n try {\n return fromDotSeparatedString(path)._internalPath;\n } catch (e) {\n const message = errorMessage(e);\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Function ${methodName}() called with invalid data. ${message}`\n );\n }\n}\n\n/**\n * Extracts the message from a caught exception, which should be an Error object\n * though JS doesn't guarantee that.\n */\nfunction errorMessage(error: Error | object): string {\n return error instanceof Error ? error.message : error.toString();\n}\n\n/** Checks `haystack` if FieldPath `needle` is present. Runs in O(n). */\nfunction fieldMaskContains(haystack: FieldPath[], needle: FieldPath): boolean {\n return haystack.some(v => v.isEqual(needle));\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\nexport class ExistenceFilter {\n // TODO(b/33078163): just use simplest form of existence filter for now\n constructor(public count: number) {}\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 { Blob } from '../api/blob';\nimport { Timestamp } from '../api/timestamp';\nimport { DatabaseId } from '../core/database_info';\nimport {\n Bound,\n Direction,\n FieldFilter,\n Filter,\n LimitType,\n Operator,\n OrderBy,\n Query\n} from '../core/query';\nimport { SnapshotVersion } from '../core/snapshot_version';\nimport { Target } from '../core/target';\nimport { TargetId } from '../core/types';\nimport { TargetData, TargetPurpose } from '../local/target_data';\nimport { Document, MaybeDocument, NoDocument } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport { ObjectValue } from '../model/object_value';\nimport {\n DeleteMutation,\n FieldMask,\n FieldTransform,\n Mutation,\n MutationResult,\n PatchMutation,\n Precondition,\n SetMutation,\n TransformMutation,\n VerifyMutation\n} from '../model/mutation';\nimport { FieldPath, ResourcePath } from '../model/path';\nimport * as api from '../protos/firestore_proto_api';\nimport { debugAssert, fail, hardAssert } from '../util/assert';\nimport { Code, FirestoreError } from '../util/error';\nimport { ByteString } from '../util/byte_string';\nimport {\n isNegativeZero,\n isNullOrUndefined,\n isSafeInteger\n} from '../util/types';\nimport {\n ArrayRemoveTransformOperation,\n ArrayUnionTransformOperation,\n NumericIncrementTransformOperation,\n ServerTimestampTransform,\n TransformOperation\n} from '../model/transform_operation';\nimport { ExistenceFilter } from './existence_filter';\nimport { mapCodeFromRpcCode } from './rpc_error';\nimport {\n DocumentWatchChange,\n ExistenceFilterChange,\n WatchChange,\n WatchTargetChange,\n WatchTargetChangeState\n} from './watch_change';\nimport { isNanValue, isNullValue, normalizeTimestamp } from '../model/values';\n\nconst DIRECTIONS = (() => {\n const dirs: { [dir: string]: api.OrderDirection } = {};\n dirs[Direction.ASCENDING] = 'ASCENDING';\n dirs[Direction.DESCENDING] = 'DESCENDING';\n return dirs;\n})();\n\nconst OPERATORS = (() => {\n const ops: { [op: string]: api.FieldFilterOp } = {};\n ops[Operator.LESS_THAN] = 'LESS_THAN';\n ops[Operator.LESS_THAN_OR_EQUAL] = 'LESS_THAN_OR_EQUAL';\n ops[Operator.GREATER_THAN] = 'GREATER_THAN';\n ops[Operator.GREATER_THAN_OR_EQUAL] = 'GREATER_THAN_OR_EQUAL';\n ops[Operator.EQUAL] = 'EQUAL';\n ops[Operator.ARRAY_CONTAINS] = 'ARRAY_CONTAINS';\n ops[Operator.IN] = 'IN';\n ops[Operator.ARRAY_CONTAINS_ANY] = 'ARRAY_CONTAINS_ANY';\n return ops;\n})();\n\nfunction assertPresent(value: unknown, description: string): asserts value {\n debugAssert(!isNullOrUndefined(value), description + ' is missing');\n}\n\nexport interface SerializerOptions {\n /**\n * The serializer supports both Protobuf.js and Proto3 JSON formats. By\n * setting this flag to true, the serializer will use the Proto3 JSON format.\n *\n * For a description of the Proto3 JSON format check\n * https://developers.google.com/protocol-buffers/docs/proto3#json\n */\n useProto3Json: boolean;\n}\n\n/**\n * Generates JsonObject values for the Datastore API suitable for sending to\n * either GRPC stub methods or via the JSON/HTTP REST API.\n * TODO(klimt): We can remove the databaseId argument if we keep the full\n * resource name in documents.\n */\nexport class JsonProtoSerializer {\n constructor(\n private databaseId: DatabaseId,\n private options: SerializerOptions\n ) {}\n\n fromRpcStatus(status: api.Status): FirestoreError {\n const code =\n status.code === undefined\n ? Code.UNKNOWN\n : mapCodeFromRpcCode(status.code);\n return new FirestoreError(code, status.message || '');\n }\n\n /**\n * Returns a value for a number (or null) that's appropriate to put into\n * a google.protobuf.Int32Value proto.\n * DO NOT USE THIS FOR ANYTHING ELSE.\n * This method cheats. It's typed as returning \"number\" because that's what\n * our generated proto interfaces say Int32Value must be. But GRPC actually\n * expects a { value: <number> } struct.\n */\n private toInt32Proto(val: number | null): number | { value: number } | null {\n if (this.options.useProto3Json || isNullOrUndefined(val)) {\n return val;\n } else {\n return { value: val };\n }\n }\n\n /**\n * Returns a number (or null) from a google.protobuf.Int32Value proto.\n */\n private fromInt32Proto(\n val: number | { value: number } | undefined\n ): number | null {\n let result;\n if (typeof val === 'object') {\n result = val.value;\n } else {\n result = val;\n }\n return isNullOrUndefined(result) ? null : result;\n }\n\n /**\n * Returns an IntegerValue for `value`.\n */\n toInteger(value: number): api.Value {\n return { integerValue: '' + value };\n }\n\n /**\n * Returns an DoubleValue for `value` that is encoded based the serializer's\n * `useProto3Json` setting.\n */\n toDouble(value: number): api.Value {\n if (this.options.useProto3Json) {\n if (isNaN(value)) {\n return { doubleValue: 'NaN' };\n } else if (value === Infinity) {\n return { doubleValue: 'Infinity' };\n } else if (value === -Infinity) {\n return { doubleValue: '-Infinity' };\n }\n }\n return { doubleValue: isNegativeZero(value) ? '-0' : value };\n }\n\n /**\n * Returns a value for a number that's appropriate to put into a proto.\n * The return value is an IntegerValue if it can safely represent the value,\n * otherwise a DoubleValue is returned.\n */\n toNumber(value: number): api.Value {\n return isSafeInteger(value) ? this.toInteger(value) : this.toDouble(value);\n }\n\n /**\n * Returns a value for a Date that's appropriate to put into a proto.\n */\n toTimestamp(timestamp: Timestamp): api.Timestamp {\n if (this.options.useProto3Json) {\n // Serialize to ISO-8601 date format, but with full nano resolution.\n // Since JS Date has only millis, let's only use it for the seconds and\n // then manually add the fractions to the end.\n const jsDateStr = new Date(timestamp.seconds * 1000).toISOString();\n // Remove .xxx frac part and Z in the end.\n const strUntilSeconds = jsDateStr.replace(/\\.\\d*/, '').replace('Z', '');\n // Pad the fraction out to 9 digits (nanos).\n const nanoStr = ('000000000' + timestamp.nanoseconds).slice(-9);\n\n return `${strUntilSeconds}.${nanoStr}Z`;\n } else {\n return {\n seconds: '' + timestamp.seconds,\n nanos: timestamp.nanoseconds\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } as any;\n }\n }\n\n private fromTimestamp(date: api.Timestamp): Timestamp {\n const timestamp = normalizeTimestamp(date);\n return new Timestamp(timestamp.seconds, timestamp.nanos);\n }\n\n /**\n * Returns a value for bytes that's appropriate to put in a proto.\n *\n * Visible for testing.\n */\n toBytes(bytes: Blob | ByteString): string | Uint8Array {\n if (this.options.useProto3Json) {\n return bytes.toBase64();\n } else {\n return bytes.toUint8Array();\n }\n }\n\n /**\n * Returns a ByteString based on the proto string value.\n */\n fromBytes(value: string | Uint8Array | undefined): ByteString {\n if (this.options.useProto3Json) {\n hardAssert(\n value === undefined || typeof value === 'string',\n 'value must be undefined or a string when using proto3 Json'\n );\n return ByteString.fromBase64String(value ? value : '');\n } else {\n hardAssert(\n value === undefined || value instanceof Uint8Array,\n 'value must be undefined or Uint8Array'\n );\n return ByteString.fromUint8Array(value ? value : new Uint8Array());\n }\n }\n\n toVersion(version: SnapshotVersion): api.Timestamp {\n return this.toTimestamp(version.toTimestamp());\n }\n\n fromVersion(version: api.Timestamp): SnapshotVersion {\n hardAssert(!!version, \"Trying to deserialize version that isn't set\");\n return SnapshotVersion.fromTimestamp(this.fromTimestamp(version));\n }\n\n toResourceName(path: ResourcePath, databaseId?: DatabaseId): string {\n return this.fullyQualifiedPrefixPath(databaseId || this.databaseId)\n .child('documents')\n .child(path)\n .canonicalString();\n }\n\n fromResourceName(name: string): ResourcePath {\n const resource = ResourcePath.fromString(name);\n hardAssert(\n isValidResourceName(resource),\n 'Tried to deserialize invalid key ' + resource.toString()\n );\n return resource;\n }\n\n toName(key: DocumentKey): string {\n return this.toResourceName(key.path);\n }\n\n fromName(name: string): DocumentKey {\n const resource = this.fromResourceName(name);\n hardAssert(\n resource.get(1) === this.databaseId.projectId,\n 'Tried to deserialize key from different project: ' +\n resource.get(1) +\n ' vs ' +\n this.databaseId.projectId\n );\n hardAssert(\n (!resource.get(3) && !this.databaseId.database) ||\n resource.get(3) === this.databaseId.database,\n 'Tried to deserialize key from different database: ' +\n resource.get(3) +\n ' vs ' +\n this.databaseId.database\n );\n return new DocumentKey(this.extractLocalPathFromResourceName(resource));\n }\n\n toQueryPath(path: ResourcePath): string {\n return this.toResourceName(path);\n }\n\n fromQueryPath(name: string): ResourcePath {\n const resourceName = this.fromResourceName(name);\n // In v1beta1 queries for collections at the root did not have a trailing\n // \"/documents\". In v1 all resource paths contain \"/documents\". Preserve the\n // ability to read the v1beta1 form for compatibility with queries persisted\n // in the local target cache.\n if (resourceName.length === 4) {\n return ResourcePath.EMPTY_PATH;\n }\n return this.extractLocalPathFromResourceName(resourceName);\n }\n\n get encodedDatabaseId(): string {\n const path = new ResourcePath([\n 'projects',\n this.databaseId.projectId,\n 'databases',\n this.databaseId.database\n ]);\n return path.canonicalString();\n }\n\n private fullyQualifiedPrefixPath(databaseId: DatabaseId): ResourcePath {\n return new ResourcePath([\n 'projects',\n databaseId.projectId,\n 'databases',\n databaseId.database\n ]);\n }\n\n private extractLocalPathFromResourceName(\n resourceName: ResourcePath\n ): ResourcePath {\n hardAssert(\n resourceName.length > 4 && resourceName.get(4) === 'documents',\n 'tried to deserialize invalid key ' + resourceName.toString()\n );\n return resourceName.popFirst(5);\n }\n\n /** Creates an api.Document from key and fields (but no create/update time) */\n toMutationDocument(key: DocumentKey, fields: ObjectValue): api.Document {\n return {\n name: this.toName(key),\n fields: fields.proto.mapValue.fields\n };\n }\n\n toDocument(document: Document): api.Document {\n debugAssert(\n !document.hasLocalMutations,\n \"Can't serialize documents with mutations.\"\n );\n return {\n name: this.toName(document.key),\n fields: document.toProto().mapValue.fields,\n updateTime: this.toTimestamp(document.version.toTimestamp())\n };\n }\n\n fromDocument(\n document: api.Document,\n hasCommittedMutations?: boolean\n ): Document {\n const key = this.fromName(document.name!);\n const version = this.fromVersion(document.updateTime!);\n const data = new ObjectValue({ mapValue: { fields: document.fields } });\n return new Document(key, version, data, {\n hasCommittedMutations: !!hasCommittedMutations\n });\n }\n\n private fromFound(doc: api.BatchGetDocumentsResponse): Document {\n hardAssert(\n !!doc.found,\n 'Tried to deserialize a found document from a missing document.'\n );\n assertPresent(doc.found.name, 'doc.found.name');\n assertPresent(doc.found.updateTime, 'doc.found.updateTime');\n const key = this.fromName(doc.found.name);\n const version = this.fromVersion(doc.found.updateTime);\n const data = new ObjectValue({ mapValue: { fields: doc.found.fields } });\n return new Document(key, version, data, {});\n }\n\n private fromMissing(result: api.BatchGetDocumentsResponse): NoDocument {\n hardAssert(\n !!result.missing,\n 'Tried to deserialize a missing document from a found document.'\n );\n hardAssert(\n !!result.readTime,\n 'Tried to deserialize a missing document without a read time.'\n );\n const key = this.fromName(result.missing);\n const version = this.fromVersion(result.readTime);\n return new NoDocument(key, version);\n }\n\n fromMaybeDocument(result: api.BatchGetDocumentsResponse): MaybeDocument {\n if ('found' in result) {\n return this.fromFound(result);\n } else if ('missing' in result) {\n return this.fromMissing(result);\n }\n return fail('invalid batch get response: ' + JSON.stringify(result));\n }\n\n fromWatchChange(change: api.ListenResponse): WatchChange {\n let watchChange: WatchChange;\n if ('targetChange' in change) {\n assertPresent(change.targetChange, 'targetChange');\n // proto3 default value is unset in JSON (undefined), so use 'NO_CHANGE'\n // if unset\n const state = this.fromWatchTargetChangeState(\n change.targetChange.targetChangeType || 'NO_CHANGE'\n );\n const targetIds: TargetId[] = change.targetChange.targetIds || [];\n\n const resumeToken = this.fromBytes(change.targetChange.resumeToken);\n const causeProto = change.targetChange!.cause;\n const cause = causeProto && this.fromRpcStatus(causeProto);\n watchChange = new WatchTargetChange(\n state,\n targetIds,\n resumeToken,\n cause || null\n );\n } else if ('documentChange' in change) {\n assertPresent(change.documentChange, 'documentChange');\n const entityChange = change.documentChange;\n assertPresent(entityChange.document, 'documentChange.name');\n assertPresent(entityChange.document.name, 'documentChange.document.name');\n assertPresent(\n entityChange.document.updateTime,\n 'documentChange.document.updateTime'\n );\n const key = this.fromName(entityChange.document.name);\n const version = this.fromVersion(entityChange.document.updateTime);\n const data = new ObjectValue({\n mapValue: { fields: entityChange.document.fields }\n });\n const doc = new Document(key, version, data, {});\n const updatedTargetIds = entityChange.targetIds || [];\n const removedTargetIds = entityChange.removedTargetIds || [];\n watchChange = new DocumentWatchChange(\n updatedTargetIds,\n removedTargetIds,\n doc.key,\n doc\n );\n } else if ('documentDelete' in change) {\n assertPresent(change.documentDelete, 'documentDelete');\n const docDelete = change.documentDelete;\n assertPresent(docDelete.document, 'documentDelete.document');\n const key = this.fromName(docDelete.document);\n const version = docDelete.readTime\n ? this.fromVersion(docDelete.readTime)\n : SnapshotVersion.min();\n const doc = new NoDocument(key, version);\n const removedTargetIds = docDelete.removedTargetIds || [];\n watchChange = new DocumentWatchChange([], removedTargetIds, doc.key, doc);\n } else if ('documentRemove' in change) {\n assertPresent(change.documentRemove, 'documentRemove');\n const docRemove = change.documentRemove;\n assertPresent(docRemove.document, 'documentRemove');\n const key = this.fromName(docRemove.document);\n const removedTargetIds = docRemove.removedTargetIds || [];\n watchChange = new DocumentWatchChange([], removedTargetIds, key, null);\n } else if ('filter' in change) {\n // TODO(dimond): implement existence filter parsing with strategy.\n assertPresent(change.filter, 'filter');\n const filter = change.filter;\n assertPresent(filter.targetId, 'filter.targetId');\n const count = filter.count || 0;\n const existenceFilter = new ExistenceFilter(count);\n const targetId = filter.targetId;\n watchChange = new ExistenceFilterChange(targetId, existenceFilter);\n } else {\n return fail('Unknown change type ' + JSON.stringify(change));\n }\n return watchChange;\n }\n\n fromWatchTargetChangeState(\n state: api.TargetChangeTargetChangeType\n ): WatchTargetChangeState {\n if (state === 'NO_CHANGE') {\n return WatchTargetChangeState.NoChange;\n } else if (state === 'ADD') {\n return WatchTargetChangeState.Added;\n } else if (state === 'REMOVE') {\n return WatchTargetChangeState.Removed;\n } else if (state === 'CURRENT') {\n return WatchTargetChangeState.Current;\n } else if (state === 'RESET') {\n return WatchTargetChangeState.Reset;\n } else {\n return fail('Got unexpected TargetChange.state: ' + state);\n }\n }\n\n versionFromListenResponse(change: api.ListenResponse): SnapshotVersion {\n // We have only reached a consistent snapshot for the entire stream if there\n // is a read_time set and it applies to all targets (i.e. the list of\n // targets is empty). The backend is guaranteed to send such responses.\n if (!('targetChange' in change)) {\n return SnapshotVersion.min();\n }\n const targetChange = change.targetChange!;\n if (targetChange.targetIds && targetChange.targetIds.length) {\n return SnapshotVersion.min();\n }\n if (!targetChange.readTime) {\n return SnapshotVersion.min();\n }\n return this.fromVersion(targetChange.readTime);\n }\n\n toMutation(mutation: Mutation): api.Write {\n let result: api.Write;\n if (mutation instanceof SetMutation) {\n result = {\n update: this.toMutationDocument(mutation.key, mutation.value)\n };\n } else if (mutation instanceof DeleteMutation) {\n result = { delete: this.toName(mutation.key) };\n } else if (mutation instanceof PatchMutation) {\n result = {\n update: this.toMutationDocument(mutation.key, mutation.data),\n updateMask: this.toDocumentMask(mutation.fieldMask)\n };\n } else if (mutation instanceof TransformMutation) {\n result = {\n transform: {\n document: this.toName(mutation.key),\n fieldTransforms: mutation.fieldTransforms.map(transform =>\n this.toFieldTransform(transform)\n )\n }\n };\n } else if (mutation instanceof VerifyMutation) {\n result = {\n verify: this.toName(mutation.key)\n };\n } else {\n return fail('Unknown mutation type ' + mutation.type);\n }\n\n if (!mutation.precondition.isNone) {\n result.currentDocument = this.toPrecondition(mutation.precondition);\n }\n\n return result;\n }\n\n fromMutation(proto: api.Write): Mutation {\n const precondition = proto.currentDocument\n ? this.fromPrecondition(proto.currentDocument)\n : Precondition.none();\n\n if (proto.update) {\n assertPresent(proto.update.name, 'name');\n const key = this.fromName(proto.update.name);\n const value = new ObjectValue({\n mapValue: { fields: proto.update.fields }\n });\n if (proto.updateMask) {\n const fieldMask = this.fromDocumentMask(proto.updateMask);\n return new PatchMutation(key, value, fieldMask, precondition);\n } else {\n return new SetMutation(key, value, precondition);\n }\n } else if (proto.delete) {\n const key = this.fromName(proto.delete);\n return new DeleteMutation(key, precondition);\n } else if (proto.transform) {\n const key = this.fromName(proto.transform.document!);\n const fieldTransforms = proto.transform.fieldTransforms!.map(transform =>\n this.fromFieldTransform(transform)\n );\n hardAssert(\n precondition.exists === true,\n 'Transforms only support precondition \"exists == true\"'\n );\n return new TransformMutation(key, fieldTransforms);\n } else if (proto.verify) {\n const key = this.fromName(proto.verify);\n return new VerifyMutation(key, precondition);\n } else {\n return fail('unknown mutation proto: ' + JSON.stringify(proto));\n }\n }\n\n private toPrecondition(precondition: Precondition): api.Precondition {\n debugAssert(!precondition.isNone, \"Can't serialize an empty precondition\");\n if (precondition.updateTime !== undefined) {\n return {\n updateTime: this.toVersion(precondition.updateTime)\n };\n } else if (precondition.exists !== undefined) {\n return { exists: precondition.exists };\n } else {\n return fail('Unknown precondition');\n }\n }\n\n private fromPrecondition(precondition: api.Precondition): Precondition {\n if (precondition.updateTime !== undefined) {\n return Precondition.updateTime(this.fromVersion(precondition.updateTime));\n } else if (precondition.exists !== undefined) {\n return Precondition.exists(precondition.exists);\n } else {\n return Precondition.none();\n }\n }\n\n private fromWriteResult(\n proto: api.WriteResult,\n commitTime: api.Timestamp\n ): MutationResult {\n // NOTE: Deletes don't have an updateTime.\n let version = proto.updateTime\n ? this.fromVersion(proto.updateTime)\n : this.fromVersion(commitTime);\n\n if (version.isEqual(SnapshotVersion.min())) {\n // The Firestore Emulator currently returns an update time of 0 for\n // deletes of non-existing documents (rather than null). This breaks the\n // test \"get deleted doc while offline with source=cache\" as NoDocuments\n // with version 0 are filtered by IndexedDb's RemoteDocumentCache.\n // TODO(#2149): Remove this when Emulator is fixed\n version = this.fromVersion(commitTime);\n }\n\n let transformResults: api.Value[] | null = null;\n if (proto.transformResults && proto.transformResults.length > 0) {\n transformResults = proto.transformResults;\n }\n return new MutationResult(version, transformResults);\n }\n\n fromWriteResults(\n protos: api.WriteResult[] | undefined,\n commitTime?: api.Timestamp\n ): MutationResult[] {\n if (protos && protos.length > 0) {\n hardAssert(\n commitTime !== undefined,\n 'Received a write result without a commit time'\n );\n return protos.map(proto => this.fromWriteResult(proto, commitTime));\n } else {\n return [];\n }\n }\n\n private toFieldTransform(fieldTransform: FieldTransform): api.FieldTransform {\n const transform = fieldTransform.transform;\n if (transform instanceof ServerTimestampTransform) {\n return {\n fieldPath: fieldTransform.field.canonicalString(),\n setToServerValue: 'REQUEST_TIME'\n };\n } else if (transform instanceof ArrayUnionTransformOperation) {\n return {\n fieldPath: fieldTransform.field.canonicalString(),\n appendMissingElements: {\n values: transform.elements\n }\n };\n } else if (transform instanceof ArrayRemoveTransformOperation) {\n return {\n fieldPath: fieldTransform.field.canonicalString(),\n removeAllFromArray: {\n values: transform.elements\n }\n };\n } else if (transform instanceof NumericIncrementTransformOperation) {\n return {\n fieldPath: fieldTransform.field.canonicalString(),\n increment: transform.operand\n };\n } else {\n throw fail('Unknown transform: ' + fieldTransform.transform);\n }\n }\n\n private fromFieldTransform(proto: api.FieldTransform): FieldTransform {\n let transform: TransformOperation | null = null;\n if ('setToServerValue' in proto) {\n hardAssert(\n proto.setToServerValue === 'REQUEST_TIME',\n 'Unknown server value transform proto: ' + JSON.stringify(proto)\n );\n transform = ServerTimestampTransform.instance;\n } else if ('appendMissingElements' in proto) {\n const values = proto.appendMissingElements!.values || [];\n transform = new ArrayUnionTransformOperation(values);\n } else if ('removeAllFromArray' in proto) {\n const values = proto.removeAllFromArray!.values || [];\n transform = new ArrayRemoveTransformOperation(values);\n } else if ('increment' in proto) {\n transform = new NumericIncrementTransformOperation(\n this,\n proto.increment!\n );\n } else {\n fail('Unknown transform proto: ' + JSON.stringify(proto));\n }\n const fieldPath = FieldPath.fromServerFormat(proto.fieldPath!);\n return new FieldTransform(fieldPath, transform!);\n }\n\n toDocumentsTarget(target: Target): api.DocumentsTarget {\n return { documents: [this.toQueryPath(target.path)] };\n }\n\n fromDocumentsTarget(documentsTarget: api.DocumentsTarget): Target {\n const count = documentsTarget.documents!.length;\n hardAssert(\n count === 1,\n 'DocumentsTarget contained other than 1 document: ' + count\n );\n const name = documentsTarget.documents![0];\n return Query.atPath(this.fromQueryPath(name)).toTarget();\n }\n\n toQueryTarget(target: Target): api.QueryTarget {\n // Dissect the path into parent, collectionId, and optional key filter.\n const result: api.QueryTarget = { structuredQuery: {} };\n const path = target.path;\n if (target.collectionGroup !== null) {\n debugAssert(\n path.length % 2 === 0,\n 'Collection Group queries should be within a document path or root.'\n );\n result.parent = this.toQueryPath(path);\n result.structuredQuery!.from = [\n {\n collectionId: target.collectionGroup,\n allDescendants: true\n }\n ];\n } else {\n debugAssert(\n path.length % 2 !== 0,\n 'Document queries with filters are not supported.'\n );\n result.parent = this.toQueryPath(path.popLast());\n result.structuredQuery!.from = [{ collectionId: path.lastSegment() }];\n }\n\n const where = this.toFilter(target.filters);\n if (where) {\n result.structuredQuery!.where = where;\n }\n\n const orderBy = this.toOrder(target.orderBy);\n if (orderBy) {\n result.structuredQuery!.orderBy = orderBy;\n }\n\n const limit = this.toInt32Proto(target.limit);\n if (limit !== null) {\n result.structuredQuery!.limit = limit;\n }\n\n if (target.startAt) {\n result.structuredQuery!.startAt = this.toCursor(target.startAt);\n }\n if (target.endAt) {\n result.structuredQuery!.endAt = this.toCursor(target.endAt);\n }\n\n return result;\n }\n\n fromQueryTarget(target: api.QueryTarget): Target {\n let path = this.fromQueryPath(target.parent!);\n\n const query = target.structuredQuery!;\n const fromCount = query.from ? query.from.length : 0;\n let collectionGroup: string | null = null;\n if (fromCount > 0) {\n hardAssert(\n fromCount === 1,\n 'StructuredQuery.from with more than one collection is not supported.'\n );\n const from = query.from![0];\n if (from.allDescendants) {\n collectionGroup = from.collectionId!;\n } else {\n path = path.child(from.collectionId!);\n }\n }\n\n let filterBy: Filter[] = [];\n if (query.where) {\n filterBy = this.fromFilter(query.where);\n }\n\n let orderBy: OrderBy[] = [];\n if (query.orderBy) {\n orderBy = this.fromOrder(query.orderBy);\n }\n\n let limit: number | null = null;\n if (query.limit) {\n limit = this.fromInt32Proto(query.limit);\n }\n\n let startAt: Bound | null = null;\n if (query.startAt) {\n startAt = this.fromCursor(query.startAt);\n }\n\n let endAt: Bound | null = null;\n if (query.endAt) {\n endAt = this.fromCursor(query.endAt);\n }\n\n return new Query(\n path,\n collectionGroup,\n orderBy,\n filterBy,\n limit,\n LimitType.First,\n startAt,\n endAt\n ).toTarget();\n }\n\n toListenRequestLabels(\n targetData: TargetData\n ): api.ApiClientObjectMap<string> | null {\n const value = this.toLabel(targetData.purpose);\n if (value == null) {\n return null;\n } else {\n return {\n 'goog-listen-tags': value\n };\n }\n }\n\n private toLabel(purpose: TargetPurpose): string | null {\n switch (purpose) {\n case TargetPurpose.Listen:\n return null;\n case TargetPurpose.ExistenceFilterMismatch:\n return 'existence-filter-mismatch';\n case TargetPurpose.LimboResolution:\n return 'limbo-document';\n default:\n return fail('Unrecognized query purpose: ' + purpose);\n }\n }\n\n toTarget(targetData: TargetData): api.Target {\n let result: api.Target;\n const target = targetData.target;\n\n if (target.isDocumentQuery()) {\n result = { documents: this.toDocumentsTarget(target) };\n } else {\n result = { query: this.toQueryTarget(target) };\n }\n\n result.targetId = targetData.targetId;\n\n if (targetData.resumeToken.approximateByteSize() > 0) {\n result.resumeToken = this.toBytes(targetData.resumeToken);\n }\n\n return result;\n }\n\n private toFilter(filters: Filter[]): api.Filter | undefined {\n if (filters.length === 0) {\n return;\n }\n const protos = filters.map(filter => {\n if (filter instanceof FieldFilter) {\n return this.toUnaryOrFieldFilter(filter);\n } else {\n return fail('Unrecognized filter: ' + JSON.stringify(filter));\n }\n });\n if (protos.length === 1) {\n return protos[0];\n }\n return { compositeFilter: { op: 'AND', filters: protos } };\n }\n\n private fromFilter(filter: api.Filter | undefined): Filter[] {\n if (!filter) {\n return [];\n } else if (filter.unaryFilter !== undefined) {\n return [this.fromUnaryFilter(filter)];\n } else if (filter.fieldFilter !== undefined) {\n return [this.fromFieldFilter(filter)];\n } else if (filter.compositeFilter !== undefined) {\n return filter.compositeFilter\n .filters!.map(f => this.fromFilter(f))\n .reduce((accum, current) => accum.concat(current));\n } else {\n return fail('Unknown filter: ' + JSON.stringify(filter));\n }\n }\n\n private toOrder(orderBys: OrderBy[]): api.Order[] | undefined {\n if (orderBys.length === 0) {\n return;\n }\n return orderBys.map(order => this.toPropertyOrder(order));\n }\n\n private fromOrder(orderBys: api.Order[]): OrderBy[] {\n return orderBys.map(order => this.fromPropertyOrder(order));\n }\n\n private toCursor(cursor: Bound): api.Cursor {\n return {\n before: cursor.before,\n values: cursor.position\n };\n }\n\n private fromCursor(cursor: api.Cursor): Bound {\n const before = !!cursor.before;\n const position = cursor.values || [];\n return new Bound(position, before);\n }\n\n // visible for testing\n toDirection(dir: Direction): api.OrderDirection {\n return DIRECTIONS[dir];\n }\n\n // visible for testing\n fromDirection(dir: api.OrderDirection | undefined): Direction | undefined {\n switch (dir) {\n case 'ASCENDING':\n return Direction.ASCENDING;\n case 'DESCENDING':\n return Direction.DESCENDING;\n default:\n return undefined;\n }\n }\n\n // visible for testing\n toOperatorName(op: Operator): api.FieldFilterOp {\n return OPERATORS[op];\n }\n\n fromOperatorName(op: api.FieldFilterOp): Operator {\n switch (op) {\n case 'EQUAL':\n return Operator.EQUAL;\n case 'GREATER_THAN':\n return Operator.GREATER_THAN;\n case 'GREATER_THAN_OR_EQUAL':\n return Operator.GREATER_THAN_OR_EQUAL;\n case 'LESS_THAN':\n return Operator.LESS_THAN;\n case 'LESS_THAN_OR_EQUAL':\n return Operator.LESS_THAN_OR_EQUAL;\n case 'ARRAY_CONTAINS':\n return Operator.ARRAY_CONTAINS;\n case 'IN':\n return Operator.IN;\n case 'ARRAY_CONTAINS_ANY':\n return Operator.ARRAY_CONTAINS_ANY;\n case 'OPERATOR_UNSPECIFIED':\n return fail('Unspecified operator');\n default:\n return fail('Unknown operator');\n }\n }\n\n toFieldPathReference(path: FieldPath): api.FieldReference {\n return { fieldPath: path.canonicalString() };\n }\n\n fromFieldPathReference(fieldReference: api.FieldReference): FieldPath {\n return FieldPath.fromServerFormat(fieldReference.fieldPath!);\n }\n\n // visible for testing\n toPropertyOrder(orderBy: OrderBy): api.Order {\n return {\n field: this.toFieldPathReference(orderBy.field),\n direction: this.toDirection(orderBy.dir)\n };\n }\n\n fromPropertyOrder(orderBy: api.Order): OrderBy {\n return new OrderBy(\n this.fromFieldPathReference(orderBy.field!),\n this.fromDirection(orderBy.direction)\n );\n }\n\n fromFieldFilter(filter: api.Filter): Filter {\n return FieldFilter.create(\n this.fromFieldPathReference(filter.fieldFilter!.field!),\n this.fromOperatorName(filter.fieldFilter!.op!),\n filter.fieldFilter!.value!\n );\n }\n\n // visible for testing\n toUnaryOrFieldFilter(filter: FieldFilter): api.Filter {\n if (filter.op === Operator.EQUAL) {\n if (isNanValue(filter.value)) {\n return {\n unaryFilter: {\n field: this.toFieldPathReference(filter.field),\n op: 'IS_NAN'\n }\n };\n } else if (isNullValue(filter.value)) {\n return {\n unaryFilter: {\n field: this.toFieldPathReference(filter.field),\n op: 'IS_NULL'\n }\n };\n }\n }\n return {\n fieldFilter: {\n field: this.toFieldPathReference(filter.field),\n op: this.toOperatorName(filter.op),\n value: filter.value\n }\n };\n }\n\n fromUnaryFilter(filter: api.Filter): Filter {\n switch (filter.unaryFilter!.op!) {\n case 'IS_NAN':\n const nanField = this.fromFieldPathReference(\n filter.unaryFilter!.field!\n );\n return FieldFilter.create(nanField, Operator.EQUAL, {\n doubleValue: NaN\n });\n case 'IS_NULL':\n const nullField = this.fromFieldPathReference(\n filter.unaryFilter!.field!\n );\n return FieldFilter.create(nullField, Operator.EQUAL, {\n nullValue: 'NULL_VALUE'\n });\n case 'OPERATOR_UNSPECIFIED':\n return fail('Unspecified filter');\n default:\n return fail('Unknown filter');\n }\n }\n\n toDocumentMask(fieldMask: FieldMask): api.DocumentMask {\n const canonicalFields: string[] = [];\n fieldMask.fields.forEach(field =>\n canonicalFields.push(field.canonicalString())\n );\n return {\n fieldPaths: canonicalFields\n };\n }\n\n fromDocumentMask(proto: api.DocumentMask): FieldMask {\n const paths = proto.fieldPaths || [];\n return new FieldMask(paths.map(path => FieldPath.fromServerFormat(path)));\n }\n}\n\nexport function isValidResourceName(path: ResourcePath): boolean {\n // Resource names have at least 4 components (project ID, database ID)\n return (\n path.length >= 4 &&\n path.get(0) === 'projects' &&\n path.get(2) === 'databases'\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 * as firestore from '@firebase/firestore-types';\n\nimport * as api from '../protos/firestore_proto_api';\n\nimport { DocumentReference, Firestore } from './database';\nimport { Blob } from './blob';\nimport { GeoPoint } from './geo_point';\nimport { Timestamp } from './timestamp';\nimport { DatabaseId } from '../core/database_info';\nimport { DocumentKey } from '../model/document_key';\nimport {\n normalizeByteString,\n normalizeNumber,\n normalizeTimestamp,\n typeOrder\n} from '../model/values';\nimport {\n getLocalWriteTime,\n getPreviousValue\n} from '../model/server_timestamps';\nimport { fail, hardAssert } from '../util/assert';\nimport { forEach } from '../util/obj';\nimport { TypeOrder } from '../model/object_value';\nimport { ResourcePath } from '../model/path';\nimport { isValidResourceName } from '../remote/serializer';\nimport { logError } from '../util/log';\n\nexport type ServerTimestampBehavior = 'estimate' | 'previous' | 'none';\n\n/**\n * Converts Firestore's internal types to the JavaScript types that we expose\n * to the user.\n */\nexport class UserDataWriter<T = firestore.DocumentData> {\n constructor(\n private readonly firestore: Firestore,\n private readonly timestampsInSnapshots: boolean,\n private readonly serverTimestampBehavior?: ServerTimestampBehavior,\n private readonly converter?: firestore.FirestoreDataConverter<T>\n ) {}\n\n convertValue(value: api.Value): unknown {\n switch (typeOrder(value)) {\n case TypeOrder.NullValue:\n return null;\n case TypeOrder.BooleanValue:\n return value.booleanValue!;\n case TypeOrder.NumberValue:\n return normalizeNumber(value.integerValue || value.doubleValue);\n case TypeOrder.TimestampValue:\n return this.convertTimestamp(value.timestampValue!);\n case TypeOrder.ServerTimestampValue:\n return this.convertServerTimestamp(value);\n case TypeOrder.StringValue:\n return value.stringValue!;\n case TypeOrder.BlobValue:\n return new Blob(normalizeByteString(value.bytesValue!));\n case TypeOrder.RefValue:\n return this.convertReference(value.referenceValue!);\n case TypeOrder.GeoPointValue:\n return this.convertGeoPoint(value.geoPointValue!);\n case TypeOrder.ArrayValue:\n return this.convertArray(value.arrayValue!);\n case TypeOrder.ObjectValue:\n return this.convertObject(value.mapValue!);\n default:\n throw fail('Invalid value type: ' + JSON.stringify(value));\n }\n }\n\n private convertObject(mapValue: api.MapValue): firestore.DocumentData {\n const result: firestore.DocumentData = {};\n forEach(mapValue.fields || {}, (key, value) => {\n result[key] = this.convertValue(value);\n });\n return result;\n }\n\n private convertGeoPoint(value: api.LatLng): GeoPoint {\n return new GeoPoint(\n normalizeNumber(value.latitude),\n normalizeNumber(value.longitude)\n );\n }\n\n private convertArray(arrayValue: api.ArrayValue): unknown[] {\n return (arrayValue.values || []).map(value => this.convertValue(value));\n }\n\n private convertServerTimestamp(value: api.Value): unknown {\n switch (this.serverTimestampBehavior) {\n case 'previous':\n const previousValue = getPreviousValue(value);\n if (previousValue == null) {\n return null;\n }\n return this.convertValue(previousValue);\n case 'estimate':\n return this.convertTimestamp(getLocalWriteTime(value));\n default:\n return null;\n }\n }\n\n private convertTimestamp(value: api.Timestamp): Timestamp | Date {\n const normalizedValue = normalizeTimestamp(value);\n const timestamp = new Timestamp(\n normalizedValue.seconds,\n normalizedValue.nanos\n );\n if (this.timestampsInSnapshots) {\n return timestamp;\n } else {\n return timestamp.toDate();\n }\n }\n\n private convertReference(name: string): DocumentReference<T> {\n const resourcePath = ResourcePath.fromString(name);\n hardAssert(\n isValidResourceName(resourcePath),\n 'ReferenceValue is not valid ' + name\n );\n const databaseId = new DatabaseId(resourcePath.get(1), resourcePath.get(3));\n const key = new DocumentKey(resourcePath.popFirst(5));\n\n if (!databaseId.isEqual(this.firestore._databaseId)) {\n // TODO(b/64130202): Somehow support foreign references.\n logError(\n `Document ${key} contains a document ` +\n `reference within a different database (` +\n `${databaseId.projectId}/${databaseId.database}) which is not ` +\n `supported. It will be treated as a reference in the current ` +\n `database (${this.firestore._databaseId.projectId}/${this.firestore._databaseId.database}) ` +\n `instead.`\n );\n }\n\n return new DocumentReference(key, this.firestore, this.converter);\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 * as firestore from '@firebase/firestore-types';\n\nimport * as api from '../protos/firestore_proto_api';\n\nimport { FirebaseApp } from '@firebase/app-types';\nimport { _FirebaseApp, FirebaseService } from '@firebase/app-types/private';\nimport { DatabaseId, DatabaseInfo } from '../core/database_info';\nimport { ListenOptions } from '../core/event_manager';\nimport {\n ComponentProvider,\n MemoryComponentProvider\n} from '../core/component_provider';\nimport { FirestoreClient, PersistenceSettings } from '../core/firestore_client';\nimport {\n Bound,\n Direction,\n FieldFilter,\n Filter,\n Operator,\n OrderBy,\n Query as InternalQuery\n} from '../core/query';\nimport { Transaction as InternalTransaction } from '../core/transaction';\nimport { ChangeType, ViewSnapshot } from '../core/view_snapshot';\nimport { LruParams } from '../local/lru_garbage_collector';\nimport { Document, MaybeDocument, NoDocument } from '../model/document';\nimport { DocumentKey } from '../model/document_key';\nimport { DeleteMutation, Mutation, Precondition } from '../model/mutation';\nimport { FieldPath, ResourcePath } from '../model/path';\nimport { isServerTimestamp } from '../model/server_timestamps';\nimport { refValue } from '../model/values';\nimport { PlatformSupport } from '../platform/platform';\nimport { debugAssert, fail } from '../util/assert';\nimport { AsyncObserver } from '../util/async_observer';\nimport { AsyncQueue } from '../util/async_queue';\nimport { Code, FirestoreError } from '../util/error';\nimport {\n invalidClassError,\n validateArgType,\n validateAtLeastNumberOfArgs,\n validateBetweenNumberOfArgs,\n validateDefined,\n validateExactNumberOfArgs,\n validateNamedOptionalPropertyEquals,\n validateNamedOptionalType,\n validateNamedType,\n validateOptionalArgType,\n validateOptionalArrayElements,\n validateOptionNames,\n validatePositiveNumber,\n validateStringEnum,\n valueDescription\n} from '../util/input_validation';\nimport { getLogLevel, logError, LogLevel, setLogLevel } from '../util/log';\nimport { AutoId } from '../util/misc';\nimport { Deferred, Rejecter, Resolver } from '../util/promise';\nimport { FieldPath as ExternalFieldPath } from './field_path';\n\nimport {\n CredentialsProvider,\n CredentialsSettings,\n EmptyCredentialsProvider,\n FirebaseCredentialsProvider,\n makeCredentialsProvider\n} from './credentials';\nimport {\n CompleteFn,\n ErrorFn,\n isPartialObserver,\n NextFn,\n PartialObserver,\n Unsubscribe\n} from './observer';\nimport { fieldPathFromArgument, UserDataReader } from './user_data_reader';\nimport { UserDataWriter } from './user_data_writer';\nimport { FirebaseAuthInternalName } from '@firebase/auth-interop-types';\nimport { Provider } from '@firebase/component';\n\n// settings() defaults:\nconst DEFAULT_HOST = 'firestore.googleapis.com';\nconst DEFAULT_SSL = true;\nconst DEFAULT_TIMESTAMPS_IN_SNAPSHOTS = true;\nconst DEFAULT_FORCE_LONG_POLLING = false;\nconst DEFAULT_IGNORE_UNDEFINED_PROPERTIES = false;\n\n/**\n * Constant used to indicate the LRU garbage collection should be disabled.\n * Set this value as the `cacheSizeBytes` on the settings passed to the\n * `Firestore` instance.\n */\nexport const CACHE_SIZE_UNLIMITED = LruParams.COLLECTION_DISABLED;\n\n// enablePersistence() defaults:\nconst DEFAULT_SYNCHRONIZE_TABS = false;\n\n/** Undocumented, private additional settings not exposed in our public API. */\ninterface PrivateSettings extends firestore.Settings {\n // Can be a google-auth-library or gapi client.\n credentials?: CredentialsSettings;\n}\n\n/**\n * Options that can be provided in the Firestore constructor when not using\n * Firebase (aka standalone mode).\n */\nexport interface FirestoreDatabase {\n projectId: string;\n database?: string;\n}\n\n/**\n * A concrete type describing all the values that can be applied via a\n * user-supplied firestore.Settings object. This is a separate type so that\n * defaults can be supplied and the value can be checked for equality.\n */\nclass FirestoreSettings {\n /** The hostname to connect to. */\n readonly host: string;\n\n /** Whether to use SSL when connecting. */\n readonly ssl: boolean;\n\n readonly timestampsInSnapshots: boolean;\n\n readonly cacheSizeBytes: number;\n\n readonly forceLongPolling: boolean;\n\n readonly ignoreUndefinedProperties: boolean;\n\n // Can be a google-auth-library or gapi client.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n credentials?: any;\n\n constructor(settings: PrivateSettings) {\n if (settings.host === undefined) {\n if (settings.ssl !== undefined) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n \"Can't provide ssl option if host option is not set\"\n );\n }\n this.host = DEFAULT_HOST;\n this.ssl = DEFAULT_SSL;\n } else {\n validateNamedType('settings', 'non-empty string', 'host', settings.host);\n this.host = settings.host;\n\n validateNamedOptionalType('settings', 'boolean', 'ssl', settings.ssl);\n this.ssl = settings.ssl ?? DEFAULT_SSL;\n }\n validateOptionNames('settings', settings, [\n 'host',\n 'ssl',\n 'credentials',\n 'timestampsInSnapshots',\n 'cacheSizeBytes',\n 'experimentalForceLongPolling',\n 'ignoreUndefinedProperties'\n ]);\n\n validateNamedOptionalType(\n 'settings',\n 'object',\n 'credentials',\n settings.credentials\n );\n this.credentials = settings.credentials;\n\n validateNamedOptionalType(\n 'settings',\n 'boolean',\n 'timestampsInSnapshots',\n settings.timestampsInSnapshots\n );\n\n validateNamedOptionalType(\n 'settings',\n 'boolean',\n 'ignoreUndefinedProperties',\n settings.ignoreUndefinedProperties\n );\n\n // Nobody should set timestampsInSnapshots anymore, but the error depends on\n // whether they set it to true or false...\n if (settings.timestampsInSnapshots === true) {\n logError(\n \"The setting 'timestampsInSnapshots: true' is no longer required \" +\n 'and should be removed.'\n );\n } else if (settings.timestampsInSnapshots === false) {\n logError(\n \"Support for 'timestampsInSnapshots: false' will be removed soon. \" +\n 'You must update your code to handle Timestamp objects.'\n );\n }\n this.timestampsInSnapshots =\n settings.timestampsInSnapshots ?? DEFAULT_TIMESTAMPS_IN_SNAPSHOTS;\n this.ignoreUndefinedProperties =\n settings.ignoreUndefinedProperties ?? DEFAULT_IGNORE_UNDEFINED_PROPERTIES;\n\n validateNamedOptionalType(\n 'settings',\n 'number',\n 'cacheSizeBytes',\n settings.cacheSizeBytes\n );\n if (settings.cacheSizeBytes === undefined) {\n this.cacheSizeBytes = LruParams.DEFAULT_CACHE_SIZE_BYTES;\n } else {\n if (\n settings.cacheSizeBytes !== CACHE_SIZE_UNLIMITED &&\n settings.cacheSizeBytes < LruParams.MINIMUM_CACHE_SIZE_BYTES\n ) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `cacheSizeBytes must be at least ${LruParams.MINIMUM_CACHE_SIZE_BYTES}`\n );\n } else {\n this.cacheSizeBytes = settings.cacheSizeBytes;\n }\n }\n\n validateNamedOptionalType(\n 'settings',\n 'boolean',\n 'experimentalForceLongPolling',\n settings.experimentalForceLongPolling\n );\n this.forceLongPolling =\n settings.experimentalForceLongPolling ?? DEFAULT_FORCE_LONG_POLLING;\n }\n\n isEqual(other: FirestoreSettings): boolean {\n return (\n this.host === other.host &&\n this.ssl === other.ssl &&\n this.timestampsInSnapshots === other.timestampsInSnapshots &&\n this.credentials === other.credentials &&\n this.cacheSizeBytes === other.cacheSizeBytes &&\n this.forceLongPolling === other.forceLongPolling &&\n this.ignoreUndefinedProperties === other.ignoreUndefinedProperties\n );\n }\n}\n\n/**\n * The root reference to the database.\n */\nexport class Firestore implements firestore.FirebaseFirestore, FirebaseService {\n // The objects that are a part of this API are exposed to third-parties as\n // compiled javascript so we want to flag our private members with a leading\n // underscore to discourage their use.\n readonly _databaseId: DatabaseId;\n private readonly _persistenceKey: string;\n private readonly _componentProvider: ComponentProvider;\n private _credentials: CredentialsProvider;\n private readonly _firebaseApp: FirebaseApp | null = null;\n private _settings: FirestoreSettings;\n\n // The firestore client instance. This will be available as soon as\n // configureClient is called, but any calls against it will block until\n // setup has completed.\n //\n // Operations on the _firestoreClient don't block on _firestoreReady. Those\n // are already set to synchronize on the async queue.\n private _firestoreClient: FirestoreClient | undefined;\n\n // Public for use in tests.\n // TODO(mikelehen): Use modularized initialization instead.\n readonly _queue = new AsyncQueue();\n\n _userDataReader: UserDataReader | undefined;\n\n // Note: We are using `MemoryComponentProvider` as a default\n // ComponentProvider to ensure backwards compatibility with the format\n // expected by the console build.\n constructor(\n databaseIdOrApp: FirestoreDatabase | FirebaseApp,\n authProvider: Provider<FirebaseAuthInternalName>,\n componentProvider: ComponentProvider = new MemoryComponentProvider()\n ) {\n if (typeof (databaseIdOrApp as FirebaseApp).options === 'object') {\n // This is very likely a Firebase app object\n // TODO(b/34177605): Can we somehow use instanceof?\n const app = databaseIdOrApp as FirebaseApp;\n this._firebaseApp = app;\n this._databaseId = Firestore.databaseIdFromApp(app);\n this._persistenceKey = app.name;\n this._credentials = new FirebaseCredentialsProvider(authProvider);\n } else {\n const external = databaseIdOrApp as FirestoreDatabase;\n if (!external.projectId) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'Must provide projectId'\n );\n }\n\n this._databaseId = new DatabaseId(external.projectId, external.database);\n // Use a default persistenceKey that lines up with FirebaseApp.\n this._persistenceKey = '[DEFAULT]';\n this._credentials = new EmptyCredentialsProvider();\n }\n\n this._componentProvider = componentProvider;\n this._settings = new FirestoreSettings({});\n }\n\n get _dataReader(): UserDataReader {\n debugAssert(\n !!this._firestoreClient,\n 'Cannot obtain UserDataReader before instance is intitialized'\n );\n if (!this._userDataReader) {\n // Lazy initialize UserDataReader once the settings are frozen\n this._userDataReader = new UserDataReader(\n this._databaseId,\n this._settings.ignoreUndefinedProperties\n );\n }\n return this._userDataReader;\n }\n\n settings(settingsLiteral: firestore.Settings): void {\n validateExactNumberOfArgs('Firestore.settings', arguments, 1);\n validateArgType('Firestore.settings', 'object', 1, settingsLiteral);\n\n const newSettings = new FirestoreSettings(settingsLiteral);\n if (this._firestoreClient && !this._settings.isEqual(newSettings)) {\n throw new FirestoreError(\n Code.FAILED_PRECONDITION,\n 'Firestore has already been started and its settings can no longer ' +\n 'be changed. You can only call settings() before calling any other ' +\n 'methods on a Firestore object.'\n );\n }\n\n this._settings = newSettings;\n if (newSettings.credentials !== undefined) {\n this._credentials = makeCredentialsProvider(newSettings.credentials);\n }\n }\n\n enableNetwork(): Promise<void> {\n this.ensureClientConfigured();\n return this._firestoreClient!.enableNetwork();\n }\n\n disableNetwork(): Promise<void> {\n this.ensureClientConfigured();\n return this._firestoreClient!.disableNetwork();\n }\n\n enablePersistence(settings?: firestore.PersistenceSettings): Promise<void> {\n if (this._firestoreClient) {\n throw new FirestoreError(\n Code.FAILED_PRECONDITION,\n 'Firestore has already been started and persistence can no longer ' +\n 'be enabled. You can only call enablePersistence() before calling ' +\n 'any other methods on a Firestore object.'\n );\n }\n\n let synchronizeTabs = false;\n\n if (settings) {\n if (settings.experimentalTabSynchronization !== undefined) {\n logError(\n \"The 'experimentalTabSynchronization' setting will be removed. Use 'synchronizeTabs' instead.\"\n );\n }\n synchronizeTabs =\n settings.synchronizeTabs ??\n settings.experimentalTabSynchronization ??\n DEFAULT_SYNCHRONIZE_TABS;\n }\n\n return this.configureClient(this._componentProvider, {\n durable: true,\n cacheSizeBytes: this._settings.cacheSizeBytes,\n synchronizeTabs\n });\n }\n\n async clearPersistence(): Promise<void> {\n if (\n this._firestoreClient !== undefined &&\n !this._firestoreClient.clientTerminated\n ) {\n throw new FirestoreError(\n Code.FAILED_PRECONDITION,\n 'Persistence cannot be cleared after this Firestore instance is initialized.'\n );\n }\n\n const deferred = new Deferred<void>();\n this._queue.enqueueAndForgetEvenAfterShutdown(async () => {\n try {\n const databaseInfo = this.makeDatabaseInfo();\n await this._componentProvider.clearPersistence(databaseInfo);\n deferred.resolve();\n } catch (e) {\n deferred.reject(e);\n }\n });\n return deferred.promise;\n }\n\n terminate(): Promise<void> {\n (this.app as _FirebaseApp)._removeServiceInstance('firestore');\n return this.INTERNAL.delete();\n }\n\n get _isTerminated(): boolean {\n this.ensureClientConfigured();\n return this._firestoreClient!.clientTerminated;\n }\n\n waitForPendingWrites(): Promise<void> {\n this.ensureClientConfigured();\n return this._firestoreClient!.waitForPendingWrites();\n }\n\n onSnapshotsInSync(observer: PartialObserver<void>): Unsubscribe;\n onSnapshotsInSync(onSync: () => void): Unsubscribe;\n onSnapshotsInSync(arg: unknown): Unsubscribe {\n this.ensureClientConfigured();\n\n if (isPartialObserver(arg)) {\n return this.onSnapshotsInSyncInternal(arg as PartialObserver<void>);\n } else {\n validateArgType('Firestore.onSnapshotsInSync', 'function', 1, arg);\n const observer: PartialObserver<void> = {\n next: arg as () => void\n };\n return this.onSnapshotsInSyncInternal(observer);\n }\n }\n\n private onSnapshotsInSyncInternal(\n observer: PartialObserver<void>\n ): Unsubscribe {\n const errHandler = (err: Error): void => {\n throw fail('Uncaught Error in onSnapshotsInSync');\n };\n const asyncObserver = new AsyncObserver<void>({\n next: () => {\n if (observer.next) {\n observer.next();\n }\n },\n error: errHandler\n });\n this._firestoreClient!.addSnapshotsInSyncListener(asyncObserver);\n return () => {\n asyncObserver.mute();\n this._firestoreClient!.removeSnapshotsInSyncListener(asyncObserver);\n };\n }\n\n ensureClientConfigured(): FirestoreClient {\n if (!this._firestoreClient) {\n // Kick off starting the client but don't actually wait for it.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.configureClient(new MemoryComponentProvider(), {\n durable: false\n });\n }\n return this._firestoreClient as FirestoreClient;\n }\n\n private makeDatabaseInfo(): DatabaseInfo {\n return new DatabaseInfo(\n this._databaseId,\n this._persistenceKey,\n this._settings.host,\n this._settings.ssl,\n this._settings.forceLongPolling\n );\n }\n\n private configureClient(\n componentProvider: ComponentProvider,\n persistenceSettings: PersistenceSettings\n ): Promise<void> {\n debugAssert(!!this._settings.host, 'FirestoreSettings.host is not set');\n\n debugAssert(\n !this._firestoreClient,\n 'configureClient() called multiple times'\n );\n\n const databaseInfo = this.makeDatabaseInfo();\n\n this._firestoreClient = new FirestoreClient(\n PlatformSupport.getPlatform(),\n databaseInfo,\n this._credentials,\n this._queue\n );\n\n return this._firestoreClient.start(componentProvider, persistenceSettings);\n }\n\n private static databaseIdFromApp(app: FirebaseApp): DatabaseId {\n if (!contains(app.options, 'projectId')) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n '\"projectId\" not provided in firebase.initializeApp.'\n );\n }\n\n const projectId = app.options.projectId;\n if (!projectId || typeof projectId !== 'string') {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'projectId must be a string in FirebaseApp.options'\n );\n }\n return new DatabaseId(projectId);\n }\n\n get app(): FirebaseApp {\n if (!this._firebaseApp) {\n throw new FirestoreError(\n Code.FAILED_PRECONDITION,\n \"Firestore was not initialized using the Firebase SDK. 'app' is \" +\n 'not available'\n );\n }\n return this._firebaseApp;\n }\n\n INTERNAL = {\n delete: async (): Promise<void> => {\n // The client must be initalized to ensure that all subsequent API usage\n // throws an exception.\n this.ensureClientConfigured();\n await this._firestoreClient!.terminate();\n }\n };\n\n collection(pathString: string): firestore.CollectionReference {\n validateExactNumberOfArgs('Firestore.collection', arguments, 1);\n validateArgType('Firestore.collection', 'non-empty string', 1, pathString);\n this.ensureClientConfigured();\n return new CollectionReference(ResourcePath.fromString(pathString), this);\n }\n\n doc(pathString: string): firestore.DocumentReference {\n validateExactNumberOfArgs('Firestore.doc', arguments, 1);\n validateArgType('Firestore.doc', 'non-empty string', 1, pathString);\n this.ensureClientConfigured();\n return DocumentReference.forPath(ResourcePath.fromString(pathString), this);\n }\n\n collectionGroup(collectionId: string): firestore.Query {\n validateExactNumberOfArgs('Firestore.collectionGroup', arguments, 1);\n validateArgType(\n 'Firestore.collectionGroup',\n 'non-empty string',\n 1,\n collectionId\n );\n if (collectionId.indexOf('/') >= 0) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Invalid collection ID '${collectionId}' passed to function ` +\n `Firestore.collectionGroup(). Collection IDs must not contain '/'.`\n );\n }\n this.ensureClientConfigured();\n return new Query(\n new InternalQuery(ResourcePath.EMPTY_PATH, collectionId),\n this\n );\n }\n\n runTransaction<T>(\n updateFunction: (transaction: firestore.Transaction) => Promise<T>\n ): Promise<T> {\n validateExactNumberOfArgs('Firestore.runTransaction', arguments, 1);\n validateArgType('Firestore.runTransaction', 'function', 1, updateFunction);\n return this.ensureClientConfigured().transaction(\n (transaction: InternalTransaction) => {\n return updateFunction(new Transaction(this, transaction));\n }\n );\n }\n\n batch(): firestore.WriteBatch {\n this.ensureClientConfigured();\n\n return new WriteBatch(this);\n }\n\n static get logLevel(): firestore.LogLevel {\n switch (getLogLevel()) {\n case LogLevel.DEBUG:\n return 'debug';\n case LogLevel.SILENT:\n return 'silent';\n default:\n // The default log level is error\n return 'error';\n }\n }\n\n static setLogLevel(level: firestore.LogLevel): void {\n validateExactNumberOfArgs('Firestore.setLogLevel', arguments, 1);\n validateArgType('Firestore.setLogLevel', 'non-empty string', 1, level);\n switch (level) {\n case 'debug':\n setLogLevel(LogLevel.DEBUG);\n break;\n case 'error':\n setLogLevel(LogLevel.ERROR);\n break;\n case 'silent':\n setLogLevel(LogLevel.SILENT);\n break;\n default:\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'Invalid log level: ' + level\n );\n }\n }\n\n // Note: this is not a property because the minifier can't work correctly with\n // the way TypeScript compiler outputs properties.\n _areTimestampsInSnapshotsEnabled(): boolean {\n return this._settings.timestampsInSnapshots;\n }\n}\n\n/**\n * A reference to a transaction.\n */\nexport class Transaction implements firestore.Transaction {\n constructor(\n private _firestore: Firestore,\n private _transaction: InternalTransaction\n ) {}\n\n get<T>(\n documentRef: firestore.DocumentReference<T>\n ): Promise<firestore.DocumentSnapshot<T>> {\n validateExactNumberOfArgs('Transaction.get', arguments, 1);\n const ref = validateReference(\n 'Transaction.get',\n documentRef,\n this._firestore\n );\n return this._transaction\n .lookup([ref._key])\n .then((docs: MaybeDocument[]) => {\n if (!docs || docs.length !== 1) {\n return fail('Mismatch in docs returned from document lookup.');\n }\n const doc = docs[0];\n if (doc instanceof NoDocument) {\n return new DocumentSnapshot<T>(\n this._firestore,\n ref._key,\n null,\n /* fromCache= */ false,\n /* hasPendingWrites= */ false,\n ref._converter\n );\n } else if (doc instanceof Document) {\n return new DocumentSnapshot<T>(\n this._firestore,\n ref._key,\n doc,\n /* fromCache= */ false,\n /* hasPendingWrites= */ false,\n ref._converter\n );\n } else {\n throw fail(\n `BatchGetDocumentsRequest returned unexpected document type: ${doc.constructor.name}`\n );\n }\n });\n }\n\n set<T>(\n documentRef: firestore.DocumentReference<T>,\n value: T,\n options?: firestore.SetOptions\n ): Transaction {\n validateBetweenNumberOfArgs('Transaction.set', arguments, 2, 3);\n const ref = validateReference(\n 'Transaction.set',\n documentRef,\n this._firestore\n );\n options = validateSetOptions('Transaction.set', options);\n const [convertedValue, functionName] = applyFirestoreDataConverter(\n ref._converter,\n value,\n 'Transaction.set'\n );\n const parsed =\n options.merge || options.mergeFields\n ? this._firestore._dataReader.parseMergeData(\n functionName,\n convertedValue,\n options.mergeFields\n )\n : this._firestore._dataReader.parseSetData(\n functionName,\n convertedValue\n );\n this._transaction.set(ref._key, parsed);\n return this;\n }\n\n update(\n documentRef: firestore.DocumentReference<unknown>,\n value: firestore.UpdateData\n ): Transaction;\n update(\n documentRef: firestore.DocumentReference<unknown>,\n field: string | ExternalFieldPath,\n value: unknown,\n ...moreFieldsAndValues: unknown[]\n ): Transaction;\n update(\n documentRef: firestore.DocumentReference<unknown>,\n fieldOrUpdateData: string | ExternalFieldPath | firestore.UpdateData,\n value?: unknown,\n ...moreFieldsAndValues: unknown[]\n ): Transaction {\n let ref;\n let parsed;\n\n if (\n typeof fieldOrUpdateData === 'string' ||\n fieldOrUpdateData instanceof ExternalFieldPath\n ) {\n validateAtLeastNumberOfArgs('Transaction.update', arguments, 3);\n ref = validateReference(\n 'Transaction.update',\n documentRef,\n this._firestore\n );\n parsed = this._firestore._dataReader.parseUpdateVarargs(\n 'Transaction.update',\n fieldOrUpdateData,\n value,\n moreFieldsAndValues\n );\n } else {\n validateExactNumberOfArgs('Transaction.update', arguments, 2);\n ref = validateReference(\n 'Transaction.update',\n documentRef,\n this._firestore\n );\n parsed = this._firestore._dataReader.parseUpdateData(\n 'Transaction.update',\n fieldOrUpdateData\n );\n }\n\n this._transaction.update(ref._key, parsed);\n return this;\n }\n\n delete(documentRef: firestore.DocumentReference<unknown>): Transaction {\n validateExactNumberOfArgs('Transaction.delete', arguments, 1);\n const ref = validateReference(\n 'Transaction.delete',\n documentRef,\n this._firestore\n );\n this._transaction.delete(ref._key);\n return this;\n }\n}\n\nexport class WriteBatch implements firestore.WriteBatch {\n private _mutations = [] as Mutation[];\n private _committed = false;\n\n constructor(private _firestore: Firestore) {}\n\n set<T>(\n documentRef: firestore.DocumentReference<T>,\n value: T,\n options?: firestore.SetOptions\n ): WriteBatch {\n validateBetweenNumberOfArgs('WriteBatch.set', arguments, 2, 3);\n this.verifyNotCommitted();\n const ref = validateReference(\n 'WriteBatch.set',\n documentRef,\n this._firestore\n );\n options = validateSetOptions('WriteBatch.set', options);\n const [convertedValue, functionName] = applyFirestoreDataConverter(\n ref._converter,\n value,\n 'WriteBatch.set'\n );\n const parsed =\n options.merge || options.mergeFields\n ? this._firestore._dataReader.parseMergeData(\n functionName,\n convertedValue,\n options.mergeFields\n )\n : this._firestore._dataReader.parseSetData(\n functionName,\n convertedValue\n );\n this._mutations = this._mutations.concat(\n parsed.toMutations(ref._key, Precondition.none())\n );\n return this;\n }\n\n update(\n documentRef: firestore.DocumentReference<unknown>,\n value: firestore.UpdateData\n ): WriteBatch;\n update(\n documentRef: firestore.DocumentReference<unknown>,\n field: string | ExternalFieldPath,\n value: unknown,\n ...moreFieldsAndValues: unknown[]\n ): WriteBatch;\n update(\n documentRef: firestore.DocumentReference<unknown>,\n fieldOrUpdateData: string | ExternalFieldPath | firestore.UpdateData,\n value?: unknown,\n ...moreFieldsAndValues: unknown[]\n ): WriteBatch {\n this.verifyNotCommitted();\n\n let ref;\n let parsed;\n\n if (\n typeof fieldOrUpdateData === 'string' ||\n fieldOrUpdateData instanceof ExternalFieldPath\n ) {\n validateAtLeastNumberOfArgs('WriteBatch.update', arguments, 3);\n ref = validateReference(\n 'WriteBatch.update',\n documentRef,\n this._firestore\n );\n parsed = this._firestore._dataReader.parseUpdateVarargs(\n 'WriteBatch.update',\n fieldOrUpdateData,\n value,\n moreFieldsAndValues\n );\n } else {\n validateExactNumberOfArgs('WriteBatch.update', arguments, 2);\n ref = validateReference(\n 'WriteBatch.update',\n documentRef,\n this._firestore\n );\n parsed = this._firestore._dataReader.parseUpdateData(\n 'WriteBatch.update',\n fieldOrUpdateData\n );\n }\n\n this._mutations = this._mutations.concat(\n parsed.toMutations(ref._key, Precondition.exists(true))\n );\n return this;\n }\n\n delete(documentRef: firestore.DocumentReference<unknown>): WriteBatch {\n validateExactNumberOfArgs('WriteBatch.delete', arguments, 1);\n this.verifyNotCommitted();\n const ref = validateReference(\n 'WriteBatch.delete',\n documentRef,\n this._firestore\n );\n this._mutations = this._mutations.concat(\n new DeleteMutation(ref._key, Precondition.none())\n );\n return this;\n }\n\n commit(): Promise<void> {\n this.verifyNotCommitted();\n this._committed = true;\n if (this._mutations.length > 0) {\n return this._firestore.ensureClientConfigured().write(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\n/**\n * A reference to a particular document in a collection in the database.\n */\nexport class DocumentReference<T = firestore.DocumentData>\n implements firestore.DocumentReference<T> {\n private _firestoreClient: FirestoreClient;\n\n constructor(\n public _key: DocumentKey,\n readonly firestore: Firestore,\n readonly _converter?: firestore.FirestoreDataConverter<T>\n ) {\n this._firestoreClient = this.firestore.ensureClientConfigured();\n }\n\n static forPath<U>(\n path: ResourcePath,\n firestore: Firestore,\n converter?: firestore.FirestoreDataConverter<U>\n ): DocumentReference<U> {\n if (path.length % 2 !== 0) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'Invalid document reference. Document ' +\n 'references must have an even number of segments, but ' +\n `${path.canonicalString()} has ${path.length}`\n );\n }\n return new DocumentReference(new DocumentKey(path), firestore, converter);\n }\n\n get id(): string {\n return this._key.path.lastSegment();\n }\n\n get parent(): firestore.CollectionReference<T> {\n return new CollectionReference(\n this._key.path.popLast(),\n this.firestore,\n this._converter\n );\n }\n\n get path(): string {\n return this._key.path.canonicalString();\n }\n\n collection(\n pathString: string\n ): firestore.CollectionReference<firestore.DocumentData> {\n validateExactNumberOfArgs('DocumentReference.collection', arguments, 1);\n validateArgType(\n 'DocumentReference.collection',\n 'non-empty string',\n 1,\n pathString\n );\n if (!pathString) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'Must provide a non-empty collection name to collection()'\n );\n }\n const path = ResourcePath.fromString(pathString);\n return new CollectionReference(this._key.path.child(path), this.firestore);\n }\n\n isEqual(other: firestore.DocumentReference<T>): boolean {\n if (!(other instanceof DocumentReference)) {\n throw invalidClassError('isEqual', 'DocumentReference', 1, other);\n }\n return (\n this.firestore === other.firestore &&\n this._key.isEqual(other._key) &&\n this._converter === other._converter\n );\n }\n\n set(\n value: firestore.DocumentData,\n options?: firestore.SetOptions\n ): Promise<void>;\n set(value: T, options?: firestore.SetOptions): Promise<void> {\n validateBetweenNumberOfArgs('DocumentReference.set', arguments, 1, 2);\n options = validateSetOptions('DocumentReference.set', options);\n const [convertedValue, functionName] = applyFirestoreDataConverter(\n this._converter,\n value,\n 'DocumentReference.set'\n );\n const parsed =\n options.merge || options.mergeFields\n ? this.firestore._dataReader.parseMergeData(\n functionName,\n convertedValue,\n options.mergeFields\n )\n : this.firestore._dataReader.parseSetData(functionName, convertedValue);\n return this._firestoreClient.write(\n parsed.toMutations(this._key, Precondition.none())\n );\n }\n\n update(value: firestore.UpdateData): Promise<void>;\n update(\n field: string | ExternalFieldPath,\n value: unknown,\n ...moreFieldsAndValues: unknown[]\n ): Promise<void>;\n update(\n fieldOrUpdateData: string | ExternalFieldPath | firestore.UpdateData,\n value?: unknown,\n ...moreFieldsAndValues: unknown[]\n ): Promise<void> {\n let parsed;\n\n if (\n typeof fieldOrUpdateData === 'string' ||\n fieldOrUpdateData instanceof ExternalFieldPath\n ) {\n validateAtLeastNumberOfArgs('DocumentReference.update', arguments, 2);\n parsed = this.firestore._dataReader.parseUpdateVarargs(\n 'DocumentReference.update',\n fieldOrUpdateData,\n value,\n moreFieldsAndValues\n );\n } else {\n validateExactNumberOfArgs('DocumentReference.update', arguments, 1);\n parsed = this.firestore._dataReader.parseUpdateData(\n 'DocumentReference.update',\n fieldOrUpdateData\n );\n }\n\n return this._firestoreClient.write(\n parsed.toMutations(this._key, Precondition.exists(true))\n );\n }\n\n delete(): Promise<void> {\n validateExactNumberOfArgs('DocumentReference.delete', arguments, 0);\n return this._firestoreClient.write([\n new DeleteMutation(this._key, Precondition.none())\n ]);\n }\n\n onSnapshot(\n observer: PartialObserver<firestore.DocumentSnapshot<T>>\n ): Unsubscribe;\n onSnapshot(\n options: firestore.SnapshotListenOptions,\n observer: PartialObserver<firestore.DocumentSnapshot<T>>\n ): Unsubscribe;\n onSnapshot(\n onNext: NextFn<firestore.DocumentSnapshot<T>>,\n onError?: ErrorFn,\n onCompletion?: CompleteFn\n ): Unsubscribe;\n onSnapshot(\n options: firestore.SnapshotListenOptions,\n onNext: NextFn<firestore.DocumentSnapshot<T>>,\n onError?: ErrorFn,\n onCompletion?: CompleteFn\n ): Unsubscribe;\n\n onSnapshot(...args: unknown[]): Unsubscribe {\n validateBetweenNumberOfArgs(\n 'DocumentReference.onSnapshot',\n arguments,\n 1,\n 4\n );\n let options: firestore.SnapshotListenOptions = {\n includeMetadataChanges: false\n };\n let observer: PartialObserver<firestore.DocumentSnapshot<T>>;\n let currArg = 0;\n if (\n typeof args[currArg] === 'object' &&\n !isPartialObserver(args[currArg])\n ) {\n options = args[currArg] as firestore.SnapshotListenOptions;\n validateOptionNames('DocumentReference.onSnapshot', options, [\n 'includeMetadataChanges'\n ]);\n validateNamedOptionalType(\n 'DocumentReference.onSnapshot',\n 'boolean',\n 'includeMetadataChanges',\n options.includeMetadataChanges\n );\n currArg++;\n }\n\n const internalOptions = {\n includeMetadataChanges: options.includeMetadataChanges\n };\n\n if (isPartialObserver(args[currArg])) {\n observer = args[currArg] as PartialObserver<\n firestore.DocumentSnapshot<T>\n >;\n } else {\n validateArgType(\n 'DocumentReference.onSnapshot',\n 'function',\n currArg,\n args[currArg]\n );\n validateOptionalArgType(\n 'DocumentReference.onSnapshot',\n 'function',\n currArg + 1,\n args[currArg + 1]\n );\n validateOptionalArgType(\n 'DocumentReference.onSnapshot',\n 'function',\n currArg + 2,\n args[currArg + 2]\n );\n observer = {\n next: args[currArg] as NextFn<firestore.DocumentSnapshot<T>>,\n error: args[currArg + 1] as ErrorFn,\n complete: args[currArg + 2] as CompleteFn\n };\n }\n return this.onSnapshotInternal(internalOptions, observer);\n }\n\n private onSnapshotInternal(\n options: ListenOptions,\n observer: PartialObserver<firestore.DocumentSnapshot<T>>\n ): Unsubscribe {\n let errHandler = (err: Error): void => {\n console.error('Uncaught Error in onSnapshot:', err);\n };\n if (observer.error) {\n errHandler = observer.error.bind(observer);\n }\n\n const asyncObserver = new AsyncObserver<ViewSnapshot>({\n next: snapshot => {\n if (observer.next) {\n debugAssert(\n snapshot.docs.size <= 1,\n 'Too many documents returned on a document query'\n );\n const doc = snapshot.docs.get(this._key);\n\n observer.next(\n new DocumentSnapshot(\n this.firestore,\n this._key,\n doc,\n snapshot.fromCache,\n snapshot.hasPendingWrites,\n this._converter\n )\n );\n }\n },\n error: errHandler\n });\n const internalListener = this._firestoreClient.listen(\n InternalQuery.atPath(this._key.path),\n asyncObserver,\n options\n );\n\n return () => {\n asyncObserver.mute();\n this._firestoreClient.unlisten(internalListener);\n };\n }\n\n get(options?: firestore.GetOptions): Promise<firestore.DocumentSnapshot<T>> {\n validateBetweenNumberOfArgs('DocumentReference.get', arguments, 0, 1);\n validateGetOptions('DocumentReference.get', options);\n return new Promise(\n (resolve: Resolver<firestore.DocumentSnapshot<T>>, reject: Rejecter) => {\n if (options && options.source === 'cache') {\n this.firestore\n .ensureClientConfigured()\n .getDocumentFromLocalCache(this._key)\n .then(doc => {\n resolve(\n new DocumentSnapshot(\n this.firestore,\n this._key,\n doc,\n /*fromCache=*/ true,\n doc instanceof Document ? doc.hasLocalMutations : false,\n this._converter\n )\n );\n }, reject);\n } else {\n this.getViaSnapshotListener(resolve, reject, options);\n }\n }\n );\n }\n\n private getViaSnapshotListener(\n resolve: Resolver<firestore.DocumentSnapshot<T>>,\n reject: Rejecter,\n options?: firestore.GetOptions\n ): void {\n const unlisten = this.onSnapshotInternal(\n {\n includeMetadataChanges: true,\n waitForSyncWhenOnline: true\n },\n {\n next: (snap: firestore.DocumentSnapshot<T>) => {\n // Remove query first before passing event to user to avoid\n // user actions affecting the now stale query.\n unlisten();\n\n if (!snap.exists && snap.metadata.fromCache) {\n // TODO(dimond): If we're online and the document doesn't\n // exist then we resolve with a doc.exists set to false. If\n // we're offline however, we reject the Promise in this\n // case. Two options: 1) Cache the negative response from\n // the server so we can deliver that even when you're\n // offline 2) Actually reject the Promise in the online case\n // if the document doesn't exist.\n reject(\n new FirestoreError(\n Code.UNAVAILABLE,\n 'Failed to get document because the client is ' + 'offline.'\n )\n );\n } else if (\n snap.exists &&\n snap.metadata.fromCache &&\n options &&\n options.source === 'server'\n ) {\n reject(\n new FirestoreError(\n Code.UNAVAILABLE,\n 'Failed to get document from server. (However, this ' +\n 'document does exist in the local cache. Run again ' +\n 'without setting source to \"server\" to ' +\n 'retrieve the cached document.)'\n )\n );\n } else {\n resolve(snap);\n }\n },\n error: reject\n }\n );\n }\n\n withConverter<U>(\n converter: firestore.FirestoreDataConverter<U>\n ): firestore.DocumentReference<U> {\n return new DocumentReference<U>(this._key, this.firestore, converter);\n }\n}\n\nclass SnapshotMetadata implements firestore.SnapshotMetadata {\n constructor(\n readonly hasPendingWrites: boolean,\n readonly fromCache: boolean\n ) {}\n\n isEqual(other: firestore.SnapshotMetadata): boolean {\n return (\n this.hasPendingWrites === other.hasPendingWrites &&\n this.fromCache === other.fromCache\n );\n }\n}\n\n/**\n * Options interface that can be provided to configure the deserialization of\n * DocumentSnapshots.\n */\nexport interface SnapshotOptions extends firestore.SnapshotOptions {}\n\nexport class DocumentSnapshot<T = firestore.DocumentData>\n implements firestore.DocumentSnapshot<T> {\n constructor(\n private _firestore: Firestore,\n private _key: DocumentKey,\n public _document: Document | null,\n private _fromCache: boolean,\n private _hasPendingWrites: boolean,\n private readonly _converter?: firestore.FirestoreDataConverter<T>\n ) {}\n\n data(options?: firestore.SnapshotOptions): T | undefined {\n validateBetweenNumberOfArgs('DocumentSnapshot.data', arguments, 0, 1);\n options = validateSnapshotOptions('DocumentSnapshot.data', options);\n if (!this._document) {\n return undefined;\n } else {\n // We only want to use the converter and create a new DocumentSnapshot\n // if a converter has been provided.\n if (this._converter) {\n const snapshot = new QueryDocumentSnapshot(\n this._firestore,\n this._key,\n this._document,\n this._fromCache,\n this._hasPendingWrites\n );\n return this._converter.fromFirestore(snapshot, options);\n } else {\n const userDataWriter = new UserDataWriter(\n this._firestore,\n this._firestore._areTimestampsInSnapshotsEnabled(),\n options.serverTimestamps,\n /* converter= */ undefined\n );\n return userDataWriter.convertValue(this._document.toProto()) as T;\n }\n }\n }\n\n get(\n fieldPath: string | ExternalFieldPath,\n options?: firestore.SnapshotOptions\n ): unknown {\n validateBetweenNumberOfArgs('DocumentSnapshot.get', arguments, 1, 2);\n options = validateSnapshotOptions('DocumentSnapshot.get', options);\n if (this._document) {\n const value = this._document\n .data()\n .field(fieldPathFromArgument('DocumentSnapshot.get', fieldPath));\n if (value !== null) {\n const userDataWriter = new UserDataWriter(\n this._firestore,\n this._firestore._areTimestampsInSnapshotsEnabled(),\n options.serverTimestamps,\n this._converter\n );\n return userDataWriter.convertValue(value);\n }\n }\n return undefined;\n }\n\n get id(): string {\n return this._key.path.lastSegment();\n }\n\n get ref(): firestore.DocumentReference<T> {\n return new DocumentReference<T>(\n this._key,\n this._firestore,\n this._converter\n );\n }\n\n get exists(): boolean {\n return this._document !== null;\n }\n\n get metadata(): firestore.SnapshotMetadata {\n return new SnapshotMetadata(this._hasPendingWrites, this._fromCache);\n }\n\n isEqual(other: firestore.DocumentSnapshot<T>): boolean {\n if (!(other instanceof DocumentSnapshot)) {\n throw invalidClassError('isEqual', 'DocumentSnapshot', 1, other);\n }\n return (\n this._firestore === other._firestore &&\n this._fromCache === other._fromCache &&\n this._key.isEqual(other._key) &&\n (this._document === null\n ? other._document === null\n : this._document.isEqual(other._document)) &&\n this._converter === other._converter\n );\n }\n}\n\nexport class QueryDocumentSnapshot<T = firestore.DocumentData>\n extends DocumentSnapshot<T>\n implements firestore.QueryDocumentSnapshot<T> {\n data(options?: SnapshotOptions): T {\n const data = super.data(options);\n debugAssert(\n data !== undefined,\n 'Document in a QueryDocumentSnapshot should exist'\n );\n return data;\n }\n}\n\nexport class Query<T = firestore.DocumentData> implements firestore.Query<T> {\n constructor(\n public _query: InternalQuery,\n readonly firestore: Firestore,\n protected readonly _converter?: firestore.FirestoreDataConverter<T>\n ) {}\n\n where(\n field: string | ExternalFieldPath,\n opStr: firestore.WhereFilterOp,\n value: unknown\n ): firestore.Query<T> {\n validateExactNumberOfArgs('Query.where', arguments, 3);\n validateDefined('Query.where', 3, value);\n\n // Enumerated from the WhereFilterOp type in index.d.ts.\n const whereFilterOpEnums = [\n Operator.LESS_THAN,\n Operator.LESS_THAN_OR_EQUAL,\n Operator.EQUAL,\n Operator.GREATER_THAN_OR_EQUAL,\n Operator.GREATER_THAN,\n Operator.ARRAY_CONTAINS,\n Operator.IN,\n Operator.ARRAY_CONTAINS_ANY\n ];\n const op = validateStringEnum('Query.where', whereFilterOpEnums, 2, opStr);\n\n let fieldValue: api.Value;\n const fieldPath = fieldPathFromArgument('Query.where', field);\n if (fieldPath.isKeyField()) {\n if (\n op === Operator.ARRAY_CONTAINS ||\n op === Operator.ARRAY_CONTAINS_ANY\n ) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Invalid Query. You can't perform '${op}' ` +\n 'queries on FieldPath.documentId().'\n );\n } else if (op === Operator.IN) {\n this.validateDisjunctiveFilterElements(value, op);\n const referenceList: api.Value[] = [];\n for (const arrayValue of value as api.Value[]) {\n referenceList.push(this.parseDocumentIdValue(arrayValue));\n }\n fieldValue = { arrayValue: { values: referenceList } };\n } else {\n fieldValue = this.parseDocumentIdValue(value);\n }\n } else {\n if (op === Operator.IN || op === Operator.ARRAY_CONTAINS_ANY) {\n this.validateDisjunctiveFilterElements(value, op);\n }\n fieldValue = this.firestore._dataReader.parseQueryValue(\n 'Query.where',\n value,\n // We only allow nested arrays for IN queries.\n /** allowArrays = */ op === Operator.IN\n );\n }\n const filter = FieldFilter.create(fieldPath, op, fieldValue);\n this.validateNewFilter(filter);\n return new Query(\n this._query.addFilter(filter),\n this.firestore,\n this._converter\n );\n }\n\n orderBy(\n field: string | ExternalFieldPath,\n directionStr?: firestore.OrderByDirection\n ): firestore.Query<T> {\n validateBetweenNumberOfArgs('Query.orderBy', arguments, 1, 2);\n validateOptionalArgType(\n 'Query.orderBy',\n 'non-empty string',\n 2,\n directionStr\n );\n let direction: Direction;\n if (directionStr === undefined || directionStr === 'asc') {\n direction = Direction.ASCENDING;\n } else if (directionStr === 'desc') {\n direction = Direction.DESCENDING;\n } else {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Function Query.orderBy() has unknown direction '${directionStr}', ` +\n `expected 'asc' or 'desc'.`\n );\n }\n if (this._query.startAt !== null) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'Invalid query. You must not call Query.startAt() or ' +\n 'Query.startAfter() before calling Query.orderBy().'\n );\n }\n if (this._query.endAt !== null) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'Invalid query. You must not call Query.endAt() or ' +\n 'Query.endBefore() before calling Query.orderBy().'\n );\n }\n const fieldPath = fieldPathFromArgument('Query.orderBy', field);\n const orderBy = new OrderBy(fieldPath, direction);\n this.validateNewOrderBy(orderBy);\n return new Query(\n this._query.addOrderBy(orderBy),\n this.firestore,\n this._converter\n );\n }\n\n limit(n: number): firestore.Query<T> {\n validateExactNumberOfArgs('Query.limit', arguments, 1);\n validateArgType('Query.limit', 'number', 1, n);\n validatePositiveNumber('Query.limit', 1, n);\n return new Query(\n this._query.withLimitToFirst(n),\n this.firestore,\n this._converter\n );\n }\n\n limitToLast(n: number): firestore.Query<T> {\n validateExactNumberOfArgs('Query.limitToLast', arguments, 1);\n validateArgType('Query.limitToLast', 'number', 1, n);\n validatePositiveNumber('Query.limitToLast', 1, n);\n return new Query(\n this._query.withLimitToLast(n),\n this.firestore,\n this._converter\n );\n }\n\n startAt(\n docOrField: unknown | firestore.DocumentSnapshot<unknown>,\n ...fields: unknown[]\n ): firestore.Query<T> {\n validateAtLeastNumberOfArgs('Query.startAt', arguments, 1);\n const bound = this.boundFromDocOrFields(\n 'Query.startAt',\n docOrField,\n fields,\n /*before=*/ true\n );\n return new Query(\n this._query.withStartAt(bound),\n this.firestore,\n this._converter\n );\n }\n\n startAfter(\n docOrField: unknown | firestore.DocumentSnapshot<unknown>,\n ...fields: unknown[]\n ): firestore.Query<T> {\n validateAtLeastNumberOfArgs('Query.startAfter', arguments, 1);\n const bound = this.boundFromDocOrFields(\n 'Query.startAfter',\n docOrField,\n fields,\n /*before=*/ false\n );\n return new Query(\n this._query.withStartAt(bound),\n this.firestore,\n this._converter\n );\n }\n\n endBefore(\n docOrField: unknown | firestore.DocumentSnapshot<unknown>,\n ...fields: unknown[]\n ): firestore.Query<T> {\n validateAtLeastNumberOfArgs('Query.endBefore', arguments, 1);\n const bound = this.boundFromDocOrFields(\n 'Query.endBefore',\n docOrField,\n fields,\n /*before=*/ true\n );\n return new Query(\n this._query.withEndAt(bound),\n this.firestore,\n this._converter\n );\n }\n\n endAt(\n docOrField: unknown | firestore.DocumentSnapshot<unknown>,\n ...fields: unknown[]\n ): firestore.Query<T> {\n validateAtLeastNumberOfArgs('Query.endAt', arguments, 1);\n const bound = this.boundFromDocOrFields(\n 'Query.endAt',\n docOrField,\n fields,\n /*before=*/ false\n );\n return new Query(\n this._query.withEndAt(bound),\n this.firestore,\n this._converter\n );\n }\n\n isEqual(other: firestore.Query<T>): boolean {\n if (!(other instanceof Query)) {\n throw invalidClassError('isEqual', 'Query', 1, other);\n }\n return (\n this.firestore === other.firestore && this._query.isEqual(other._query)\n );\n }\n\n withConverter<U>(\n converter: firestore.FirestoreDataConverter<U>\n ): firestore.Query<U> {\n return new Query<U>(this._query, this.firestore, converter);\n }\n\n /** Helper function to create a bound from a document or fields */\n private boundFromDocOrFields(\n methodName: string,\n docOrField: unknown | firestore.DocumentSnapshot<T>,\n fields: unknown[],\n before: boolean\n ): Bound {\n validateDefined(methodName, 1, docOrField);\n if (docOrField instanceof DocumentSnapshot) {\n if (fields.length > 0) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Too many arguments provided to ${methodName}().`\n );\n }\n const snap = docOrField;\n if (!snap.exists) {\n throw new FirestoreError(\n Code.NOT_FOUND,\n `Can't use a DocumentSnapshot that doesn't exist for ` +\n `${methodName}().`\n );\n }\n return this.boundFromDocument(snap._document!, before);\n } else {\n const allFields = [docOrField].concat(fields);\n return this.boundFromFields(methodName, allFields, before);\n }\n }\n\n /**\n * Create a Bound from a query and a document.\n *\n * Note that the Bound will always include the key of the document\n * and so only the provided document will compare equal to the returned\n * position.\n *\n * Will throw if the document does not contain all fields of the order by\n * of the query or if any of the fields in the order by are an uncommitted\n * server timestamp.\n */\n private boundFromDocument(doc: Document, before: boolean): Bound {\n const components: api.Value[] = [];\n\n // Because people expect to continue/end a query at the exact document\n // provided, we need to use the implicit sort order rather than the explicit\n // sort order, because it's guaranteed to contain the document key. That way\n // the position becomes unambiguous and the query continues/ends exactly at\n // the provided document. Without the key (by using the explicit sort\n // orders), multiple documents could match the position, yielding duplicate\n // results.\n for (const orderBy of this._query.orderBy) {\n if (orderBy.field.isKeyField()) {\n components.push(refValue(this.firestore._databaseId, doc.key));\n } else {\n const value = doc.field(orderBy.field);\n if (isServerTimestamp(value)) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'Invalid query. You are trying to start or end a query using a ' +\n 'document for which the field \"' +\n orderBy.field +\n '\" is an uncommitted server timestamp. (Since the value of ' +\n 'this field is unknown, you cannot start/end a query with it.)'\n );\n } else if (value !== null) {\n components.push(value);\n } else {\n const field = orderBy.field.canonicalString();\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Invalid query. You are trying to start or end a query using a ` +\n `document for which the field '${field}' (used as the ` +\n `orderBy) does not exist.`\n );\n }\n }\n }\n return new Bound(components, before);\n }\n\n /**\n * Converts a list of field values to a Bound for the given query.\n */\n private boundFromFields(\n methodName: string,\n values: unknown[],\n before: boolean\n ): Bound {\n // Use explicit order by's because it has to match the query the user made\n const orderBy = this._query.explicitOrderBy;\n if (values.length > orderBy.length) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Too many arguments provided to ${methodName}(). ` +\n `The number of arguments must be less than or equal to the ` +\n `number of Query.orderBy() clauses`\n );\n }\n\n const components: api.Value[] = [];\n for (let i = 0; i < values.length; i++) {\n const rawValue = values[i];\n const orderByComponent = orderBy[i];\n if (orderByComponent.field.isKeyField()) {\n if (typeof rawValue !== 'string') {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Invalid query. Expected a string for document ID in ` +\n `${methodName}(), but got a ${typeof rawValue}`\n );\n }\n if (\n !this._query.isCollectionGroupQuery() &&\n rawValue.indexOf('/') !== -1\n ) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Invalid query. When querying a collection and ordering by FieldPath.documentId(), ` +\n `the value passed to ${methodName}() must be a plain document ID, but ` +\n `'${rawValue}' contains a slash.`\n );\n }\n const path = this._query.path.child(ResourcePath.fromString(rawValue));\n if (!DocumentKey.isDocumentKey(path)) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Invalid query. When querying a collection group and ordering by ` +\n `FieldPath.documentId(), the value passed to ${methodName}() must result in a ` +\n `valid document path, but '${path}' is not because it contains an odd number ` +\n `of segments.`\n );\n }\n const key = new DocumentKey(path);\n components.push(refValue(this.firestore._databaseId, key));\n } else {\n const wrapped = this.firestore._dataReader.parseQueryValue(\n methodName,\n rawValue\n );\n components.push(wrapped);\n }\n }\n\n return new Bound(components, before);\n }\n\n onSnapshot(\n observer: PartialObserver<firestore.QuerySnapshot<T>>\n ): Unsubscribe;\n onSnapshot(\n options: firestore.SnapshotListenOptions,\n observer: PartialObserver<firestore.QuerySnapshot<T>>\n ): Unsubscribe;\n onSnapshot(\n onNext: NextFn<firestore.QuerySnapshot<T>>,\n onError?: ErrorFn,\n onCompletion?: CompleteFn\n ): Unsubscribe;\n onSnapshot(\n options: firestore.SnapshotListenOptions,\n onNext: NextFn<firestore.QuerySnapshot<T>>,\n onError?: ErrorFn,\n onCompletion?: CompleteFn\n ): Unsubscribe;\n\n onSnapshot(...args: unknown[]): Unsubscribe {\n validateBetweenNumberOfArgs('Query.onSnapshot', arguments, 1, 4);\n let options: firestore.SnapshotListenOptions = {};\n let observer: PartialObserver<firestore.QuerySnapshot<T>>;\n let currArg = 0;\n if (\n typeof args[currArg] === 'object' &&\n !isPartialObserver(args[currArg])\n ) {\n options = args[currArg] as firestore.SnapshotListenOptions;\n validateOptionNames('Query.onSnapshot', options, [\n 'includeMetadataChanges'\n ]);\n validateNamedOptionalType(\n 'Query.onSnapshot',\n 'boolean',\n 'includeMetadataChanges',\n options.includeMetadataChanges\n );\n currArg++;\n }\n\n if (isPartialObserver(args[currArg])) {\n observer = args[currArg] as PartialObserver<firestore.QuerySnapshot<T>>;\n } else {\n validateArgType('Query.onSnapshot', 'function', currArg, args[currArg]);\n validateOptionalArgType(\n 'Query.onSnapshot',\n 'function',\n currArg + 1,\n args[currArg + 1]\n );\n validateOptionalArgType(\n 'Query.onSnapshot',\n 'function',\n currArg + 2,\n args[currArg + 2]\n );\n observer = {\n next: args[currArg] as NextFn<firestore.QuerySnapshot<T>>,\n error: args[currArg + 1] as ErrorFn,\n complete: args[currArg + 2] as CompleteFn\n };\n }\n this.validateHasExplicitOrderByForLimitToLast(this._query);\n return this.onSnapshotInternal(options, observer);\n }\n\n private onSnapshotInternal(\n options: ListenOptions,\n observer: PartialObserver<firestore.QuerySnapshot<T>>\n ): Unsubscribe {\n let errHandler = (err: Error): void => {\n console.error('Uncaught Error in onSnapshot:', err);\n };\n if (observer.error) {\n errHandler = observer.error.bind(observer);\n }\n\n const asyncObserver = new AsyncObserver<ViewSnapshot>({\n next: (result: ViewSnapshot): void => {\n if (observer.next) {\n observer.next(\n new QuerySnapshot(\n this.firestore,\n this._query,\n result,\n this._converter\n )\n );\n }\n },\n error: errHandler\n });\n\n const firestoreClient = this.firestore.ensureClientConfigured();\n const internalListener = firestoreClient.listen(\n this._query,\n asyncObserver,\n options\n );\n return (): void => {\n asyncObserver.mute();\n firestoreClient.unlisten(internalListener);\n };\n }\n\n private validateHasExplicitOrderByForLimitToLast(query: InternalQuery): void {\n if (query.hasLimitToLast() && query.explicitOrderBy.length === 0) {\n throw new FirestoreError(\n Code.UNIMPLEMENTED,\n 'limitToLast() queries require specifying at least one orderBy() clause'\n );\n }\n }\n\n get(options?: firestore.GetOptions): Promise<firestore.QuerySnapshot<T>> {\n validateBetweenNumberOfArgs('Query.get', arguments, 0, 1);\n validateGetOptions('Query.get', options);\n this.validateHasExplicitOrderByForLimitToLast(this._query);\n return new Promise(\n (resolve: Resolver<firestore.QuerySnapshot<T>>, reject: Rejecter) => {\n if (options && options.source === 'cache') {\n this.firestore\n .ensureClientConfigured()\n .getDocumentsFromLocalCache(this._query)\n .then((viewSnap: ViewSnapshot) => {\n resolve(\n new QuerySnapshot(\n this.firestore,\n this._query,\n viewSnap,\n this._converter\n )\n );\n }, reject);\n } else {\n this.getViaSnapshotListener(resolve, reject, options);\n }\n }\n );\n }\n\n private getViaSnapshotListener(\n resolve: Resolver<firestore.QuerySnapshot<T>>,\n reject: Rejecter,\n options?: firestore.GetOptions\n ): void {\n const unlisten = this.onSnapshotInternal(\n {\n includeMetadataChanges: true,\n waitForSyncWhenOnline: true\n },\n {\n next: (result: firestore.QuerySnapshot<T>) => {\n // Remove query first before passing event to user to avoid\n // user actions affecting the now stale query.\n unlisten();\n\n if (\n result.metadata.fromCache &&\n options &&\n options.source === 'server'\n ) {\n reject(\n new FirestoreError(\n Code.UNAVAILABLE,\n 'Failed to get documents from server. (However, these ' +\n 'documents may exist in the local cache. Run again ' +\n 'without setting source to \"server\" to ' +\n 'retrieve the cached documents.)'\n )\n );\n } else {\n resolve(result);\n }\n },\n error: reject\n }\n );\n }\n\n /**\n * Parses the given documentIdValue into a ReferenceValue, throwing\n * appropriate errors if the value is anything other than a DocumentReference\n * or String, or if the string is malformed.\n */\n private parseDocumentIdValue(documentIdValue: unknown): api.Value {\n if (typeof documentIdValue === 'string') {\n if (documentIdValue === '') {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'Invalid query. When querying with FieldPath.documentId(), you ' +\n 'must provide a valid document ID, but it was an empty string.'\n );\n }\n if (\n !this._query.isCollectionGroupQuery() &&\n documentIdValue.indexOf('/') !== -1\n ) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Invalid query. When querying a collection by ` +\n `FieldPath.documentId(), you must provide a plain document ID, but ` +\n `'${documentIdValue}' contains a '/' character.`\n );\n }\n const path = this._query.path.child(\n ResourcePath.fromString(documentIdValue)\n );\n if (!DocumentKey.isDocumentKey(path)) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Invalid query. When querying a collection group by ` +\n `FieldPath.documentId(), the value provided must result in a valid document path, ` +\n `but '${path}' is not because it has an odd number of segments (${path.length}).`\n );\n }\n return refValue(this.firestore._databaseId, new DocumentKey(path));\n } else if (documentIdValue instanceof DocumentReference) {\n const ref = documentIdValue as DocumentReference<T>;\n return refValue(this.firestore._databaseId, ref._key);\n } else {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Invalid query. When querying with FieldPath.documentId(), you must provide a valid ` +\n `string or a DocumentReference, but it was: ` +\n `${valueDescription(documentIdValue)}.`\n );\n }\n }\n\n /**\n * Validates that the value passed into a disjunctrive filter satisfies all\n * array requirements.\n */\n private validateDisjunctiveFilterElements(\n value: unknown,\n operator: Operator\n ): void {\n if (!Array.isArray(value) || value.length === 0) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'Invalid Query. A non-empty array is required for ' +\n `'${operator.toString()}' filters.`\n );\n }\n if (value.length > 10) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Invalid Query. '${operator.toString()}' filters support a ` +\n 'maximum of 10 elements in the value array.'\n );\n }\n if (value.indexOf(null) >= 0) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Invalid Query. '${operator.toString()}' filters cannot contain 'null' ` +\n 'in the value array.'\n );\n }\n if (value.filter(element => Number.isNaN(element)).length > 0) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Invalid Query. '${operator.toString()}' filters cannot contain 'NaN' ` +\n 'in the value array.'\n );\n }\n }\n\n private validateNewFilter(filter: Filter): void {\n if (filter instanceof FieldFilter) {\n const arrayOps = [Operator.ARRAY_CONTAINS, Operator.ARRAY_CONTAINS_ANY];\n const disjunctiveOps = [Operator.IN, Operator.ARRAY_CONTAINS_ANY];\n const isArrayOp = arrayOps.indexOf(filter.op) >= 0;\n const isDisjunctiveOp = disjunctiveOps.indexOf(filter.op) >= 0;\n\n if (filter.isInequality()) {\n const existingField = this._query.getInequalityFilterField();\n if (existingField !== null && !existingField.isEqual(filter.field)) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'Invalid query. All where filters with an inequality' +\n ' (<, <=, >, or >=) must be on the same field. But you have' +\n ` inequality filters on '${existingField.toString()}'` +\n ` and '${filter.field.toString()}'`\n );\n }\n\n const firstOrderByField = this._query.getFirstOrderByField();\n if (firstOrderByField !== null) {\n this.validateOrderByAndInequalityMatch(\n filter.field,\n firstOrderByField\n );\n }\n } else if (isDisjunctiveOp || isArrayOp) {\n // You can have at most 1 disjunctive filter and 1 array filter. Check if\n // the new filter conflicts with an existing one.\n let conflictingOp: Operator | null = null;\n if (isDisjunctiveOp) {\n conflictingOp = this._query.findFilterOperator(disjunctiveOps);\n }\n if (conflictingOp === null && isArrayOp) {\n conflictingOp = this._query.findFilterOperator(arrayOps);\n }\n if (conflictingOp != null) {\n // We special case when it's a duplicate op to give a slightly clearer error message.\n if (conflictingOp === filter.op) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'Invalid query. You cannot use more than one ' +\n `'${filter.op.toString()}' filter.`\n );\n } else {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Invalid query. You cannot use '${filter.op.toString()}' filters ` +\n `with '${conflictingOp.toString()}' filters.`\n );\n }\n }\n }\n }\n }\n\n private validateNewOrderBy(orderBy: OrderBy): void {\n if (this._query.getFirstOrderByField() === null) {\n // This is the first order by. It must match any inequality.\n const inequalityField = this._query.getInequalityFilterField();\n if (inequalityField !== null) {\n this.validateOrderByAndInequalityMatch(inequalityField, orderBy.field);\n }\n }\n }\n\n private validateOrderByAndInequalityMatch(\n inequality: FieldPath,\n orderBy: FieldPath\n ): void {\n if (!orderBy.isEqual(inequality)) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Invalid query. You have a where filter with an inequality ` +\n `(<, <=, >, or >=) on field '${inequality.toString()}' ` +\n `and so you must also use '${inequality.toString()}' ` +\n `as your first Query.orderBy(), but your first Query.orderBy() ` +\n `is on field '${orderBy.toString()}' instead.`\n );\n }\n }\n}\n\nexport class QuerySnapshot<T = firestore.DocumentData>\n implements firestore.QuerySnapshot<T> {\n private _cachedChanges: Array<firestore.DocumentChange<T>> | null = null;\n private _cachedChangesIncludeMetadataChanges: boolean | null = null;\n\n readonly metadata: firestore.SnapshotMetadata;\n\n constructor(\n private readonly _firestore: Firestore,\n private readonly _originalQuery: InternalQuery,\n private readonly _snapshot: ViewSnapshot,\n private readonly _converter?: firestore.FirestoreDataConverter<T>\n ) {\n this.metadata = new SnapshotMetadata(\n _snapshot.hasPendingWrites,\n _snapshot.fromCache\n );\n }\n\n get docs(): Array<firestore.QueryDocumentSnapshot<T>> {\n const result: Array<firestore.QueryDocumentSnapshot<T>> = [];\n this.forEach(doc => result.push(doc));\n return result;\n }\n\n get empty(): boolean {\n return this._snapshot.docs.isEmpty();\n }\n\n get size(): number {\n return this._snapshot.docs.size;\n }\n\n forEach(\n callback: (result: firestore.QueryDocumentSnapshot<T>) => void,\n thisArg?: unknown\n ): void {\n validateBetweenNumberOfArgs('QuerySnapshot.forEach', arguments, 1, 2);\n validateArgType('QuerySnapshot.forEach', 'function', 1, callback);\n this._snapshot.docs.forEach(doc => {\n callback.call(thisArg, this.convertToDocumentImpl(doc));\n });\n }\n\n get query(): firestore.Query<T> {\n return new Query(this._originalQuery, this._firestore, this._converter);\n }\n\n docChanges(\n options?: firestore.SnapshotListenOptions\n ): Array<firestore.DocumentChange<T>> {\n if (options) {\n validateOptionNames('QuerySnapshot.docChanges', options, [\n 'includeMetadataChanges'\n ]);\n validateNamedOptionalType(\n 'QuerySnapshot.docChanges',\n 'boolean',\n 'includeMetadataChanges',\n options.includeMetadataChanges\n );\n }\n\n const includeMetadataChanges = !!(\n options && options.includeMetadataChanges\n );\n\n if (includeMetadataChanges && this._snapshot.excludesMetadataChanges) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'To include metadata changes with your document changes, you must ' +\n 'also pass { includeMetadataChanges:true } to onSnapshot().'\n );\n }\n\n if (\n !this._cachedChanges ||\n this._cachedChangesIncludeMetadataChanges !== includeMetadataChanges\n ) {\n this._cachedChanges = changesFromSnapshot<T>(\n this._firestore,\n includeMetadataChanges,\n this._snapshot,\n this._converter\n );\n this._cachedChangesIncludeMetadataChanges = includeMetadataChanges;\n }\n\n return this._cachedChanges;\n }\n\n /** Check the equality. The call can be very expensive. */\n isEqual(other: firestore.QuerySnapshot<T>): boolean {\n if (!(other instanceof QuerySnapshot)) {\n throw invalidClassError('isEqual', 'QuerySnapshot', 1, other);\n }\n\n return (\n this._firestore === other._firestore &&\n this._originalQuery.isEqual(other._originalQuery) &&\n this._snapshot.isEqual(other._snapshot) &&\n this._converter === other._converter\n );\n }\n\n private convertToDocumentImpl(doc: Document): QueryDocumentSnapshot<T> {\n return new QueryDocumentSnapshot(\n this._firestore,\n doc.key,\n doc,\n this.metadata.fromCache,\n this._snapshot.mutatedKeys.has(doc.key),\n this._converter\n );\n }\n}\n\nexport class CollectionReference<T = firestore.DocumentData> extends Query<T>\n implements firestore.CollectionReference<T> {\n constructor(\n readonly _path: ResourcePath,\n firestore: Firestore,\n _converter?: firestore.FirestoreDataConverter<T>\n ) {\n super(InternalQuery.atPath(_path), firestore, _converter);\n if (_path.length % 2 !== 1) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'Invalid collection reference. Collection ' +\n 'references must have an odd number of segments, but ' +\n `${_path.canonicalString()} has ${_path.length}`\n );\n }\n }\n\n get id(): string {\n return this._query.path.lastSegment();\n }\n\n get parent(): firestore.DocumentReference<firestore.DocumentData> | null {\n const parentPath = this._query.path.popLast();\n if (parentPath.isEmpty()) {\n return null;\n } else {\n return new DocumentReference<firestore.DocumentData>(\n new DocumentKey(parentPath),\n this.firestore\n );\n }\n }\n\n get path(): string {\n return this._query.path.canonicalString();\n }\n\n doc(pathString?: string): firestore.DocumentReference<T> {\n validateBetweenNumberOfArgs('CollectionReference.doc', arguments, 0, 1);\n // We allow omission of 'pathString' but explicitly prohibit passing in both\n // 'undefined' and 'null'.\n if (arguments.length === 0) {\n pathString = AutoId.newId();\n }\n validateArgType(\n 'CollectionReference.doc',\n 'non-empty string',\n 1,\n pathString\n );\n if (pathString === '') {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'Document path must be a non-empty string'\n );\n }\n const path = ResourcePath.fromString(pathString!);\n return DocumentReference.forPath<T>(\n this._query.path.child(path),\n this.firestore,\n this._converter\n );\n }\n\n add(value: T): Promise<firestore.DocumentReference<T>> {\n validateExactNumberOfArgs('CollectionReference.add', arguments, 1);\n const convertedValue = this._converter\n ? this._converter.toFirestore(value)\n : value;\n validateArgType('CollectionReference.add', 'object', 1, convertedValue);\n const docRef = this.doc();\n return docRef.set(value).then(() => docRef);\n }\n\n withConverter<U>(\n converter: firestore.FirestoreDataConverter<U>\n ): firestore.CollectionReference<U> {\n return new CollectionReference<U>(this._path, this.firestore, converter);\n }\n}\n\nfunction validateSetOptions(\n methodName: string,\n options: firestore.SetOptions | undefined\n): firestore.SetOptions {\n if (options === undefined) {\n return {\n merge: false\n };\n }\n\n validateOptionNames(methodName, options, ['merge', 'mergeFields']);\n validateNamedOptionalType(methodName, 'boolean', 'merge', options.merge);\n validateOptionalArrayElements(\n methodName,\n 'mergeFields',\n 'a string or a FieldPath',\n options.mergeFields,\n element =>\n typeof element === 'string' || element instanceof ExternalFieldPath\n );\n\n if (options.mergeFields !== undefined && options.merge !== undefined) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n `Invalid options passed to function ${methodName}(): You cannot specify both \"merge\" ` +\n `and \"mergeFields\".`\n );\n }\n\n return options;\n}\n\nfunction validateSnapshotOptions(\n methodName: string,\n options: firestore.SnapshotOptions | undefined\n): firestore.SnapshotOptions {\n if (options === undefined) {\n return {};\n }\n\n validateOptionNames(methodName, options, ['serverTimestamps']);\n validateNamedOptionalPropertyEquals(\n methodName,\n 'options',\n 'serverTimestamps',\n options.serverTimestamps,\n ['estimate', 'previous', 'none']\n );\n return options;\n}\n\nfunction validateGetOptions(\n methodName: string,\n options: firestore.GetOptions | undefined\n): void {\n validateOptionalArgType(methodName, 'object', 1, options);\n if (options) {\n validateOptionNames(methodName, options, ['source']);\n validateNamedOptionalPropertyEquals(\n methodName,\n 'options',\n 'source',\n options.source,\n ['default', 'server', 'cache']\n );\n }\n}\n\nfunction validateReference<T>(\n methodName: string,\n documentRef: firestore.DocumentReference<T>,\n firestore: Firestore\n): DocumentReference<T> {\n if (!(documentRef instanceof DocumentReference)) {\n throw invalidClassError(methodName, 'DocumentReference', 1, documentRef);\n } else 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;\n }\n}\n\n/**\n * Calculates the array of firestore.DocumentChange's for a given ViewSnapshot.\n *\n * Exported for testing.\n */\nexport function changesFromSnapshot<T>(\n firestore: Firestore,\n includeMetadataChanges: boolean,\n snapshot: ViewSnapshot,\n converter?: firestore.FirestoreDataConverter<T>\n): Array<firestore.DocumentChange<T>> {\n if (snapshot.oldDocs.isEmpty()) {\n // Special case the first snapshot because index calculation is easy and\n // fast\n let lastDoc: Document;\n let index = 0;\n return snapshot.docChanges.map(change => {\n const doc = new QueryDocumentSnapshot<T>(\n firestore,\n change.doc.key,\n change.doc,\n snapshot.fromCache,\n snapshot.mutatedKeys.has(change.doc.key),\n converter\n );\n debugAssert(\n change.type === ChangeType.Added,\n 'Invalid event type for first snapshot'\n );\n debugAssert(\n !lastDoc || snapshot.query.docComparator(lastDoc, change.doc) < 0,\n 'Got added events in wrong order'\n );\n lastDoc = change.doc;\n return {\n type: 'added' as firestore.DocumentChangeType,\n doc,\n oldIndex: -1,\n newIndex: index++\n };\n });\n } else {\n // A DocumentSet that is updated incrementally as changes are applied to use\n // to lookup the index of a document.\n let indexTracker = snapshot.oldDocs;\n return snapshot.docChanges\n .filter(\n change => includeMetadataChanges || change.type !== ChangeType.Metadata\n )\n .map(change => {\n const doc = new QueryDocumentSnapshot<T>(\n firestore,\n change.doc.key,\n change.doc,\n snapshot.fromCache,\n snapshot.mutatedKeys.has(change.doc.key),\n converter\n );\n let oldIndex = -1;\n let newIndex = -1;\n if (change.type !== ChangeType.Added) {\n oldIndex = indexTracker.indexOf(change.doc.key);\n debugAssert(oldIndex >= 0, 'Index for document not found');\n indexTracker = indexTracker.delete(change.doc.key);\n }\n if (change.type !== ChangeType.Removed) {\n indexTracker = indexTracker.add(change.doc);\n newIndex = indexTracker.indexOf(change.doc.key);\n }\n return { type: resultChangeType(change.type), doc, oldIndex, newIndex };\n });\n }\n}\n\nfunction resultChangeType(type: ChangeType): firestore.DocumentChangeType {\n switch (type) {\n case ChangeType.Added:\n return 'added';\n case ChangeType.Modified:\n case ChangeType.Metadata:\n return 'modified';\n case ChangeType.Removed:\n return 'removed';\n default:\n return fail('Unknown change type: ' + type);\n }\n}\n\n/**\n * Converts custom model object of type T into DocumentData by applying the\n * converter if it exists.\n *\n * This function is used when converting user objects to DocumentData\n * because we want to provide the user with a more specific error message if\n * their set() or fails due to invalid data originating from a toFirestore()\n * call.\n */\nfunction applyFirestoreDataConverter<T>(\n converter: firestore.FirestoreDataConverter<T> | undefined,\n value: T,\n functionName: string\n): [firestore.DocumentData, string] {\n let convertedValue;\n if (converter) {\n convertedValue = converter.toFirestore(value);\n functionName = 'toFirestore() in ' + functionName;\n } else {\n convertedValue = value as firestore.DocumentData;\n }\n return [convertedValue, functionName];\n}\n\nfunction contains(obj: object, key: string): obj is { key: unknown } {\n return Object.prototype.hasOwnProperty.call(obj, key);\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 { Code, FirestoreError } from './error';\n\n/**\n * Helper function to prevent instantiation through the constructor.\n *\n * This method creates a new constructor that throws when it's invoked.\n * The prototype of that constructor is then set to the prototype of the hidden\n * \"class\" to expose all the prototype methods and allow for instanceof\n * checks.\n *\n * To also make all the static methods available, all properties of the\n * original constructor are copied to the new constructor.\n */\nexport function makeConstructorPrivate<T extends Function>(\n cls: T,\n optionalMessage?: string\n): T {\n function PublicConstructor(): never {\n let error = 'This constructor is private.';\n if (optionalMessage) {\n error += ' ';\n error += optionalMessage;\n }\n throw new FirestoreError(Code.INVALID_ARGUMENT, error);\n }\n\n // Make sure instanceof checks work and all methods are exposed on the public\n // constructor\n PublicConstructor.prototype = cls.prototype;\n\n // Copy any static methods/members\n Object.assign(PublicConstructor, cls);\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return PublicConstructor as any;\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 { FirebaseApp, FirebaseNamespace } from '@firebase/app-types';\nimport { FirebaseAuthInternalName } from '@firebase/auth-interop-types';\nimport { _FirebaseNamespace } from '@firebase/app-types/private';\nimport { Component, ComponentType, Provider } from '@firebase/component';\nimport {\n CACHE_SIZE_UNLIMITED,\n Firestore,\n DocumentReference,\n DocumentSnapshot,\n QueryDocumentSnapshot,\n Query,\n QuerySnapshot,\n CollectionReference,\n Transaction,\n WriteBatch\n} from '../api/database';\nimport { Blob } from '../api/blob';\nimport { FieldPath } from '../api/field_path';\nimport { GeoPoint } from '../api/geo_point';\nimport { Timestamp } from '../api/timestamp';\nimport { makeConstructorPrivate } from '../util/api';\nimport { FieldValue } from '../api/field_value';\n\n// Public instance that disallows construction at runtime. Note that this still\n// allows instanceof checks.\nexport const PublicFirestore = makeConstructorPrivate(\n Firestore,\n 'Use firebase.firestore() instead.'\n);\nexport const PublicTransaction = makeConstructorPrivate(\n Transaction,\n 'Use firebase.firestore().runTransaction() instead.'\n);\nexport const PublicWriteBatch = makeConstructorPrivate(\n WriteBatch,\n 'Use firebase.firestore().batch() instead.'\n);\nexport const PublicDocumentReference = makeConstructorPrivate(\n DocumentReference,\n 'Use firebase.firestore().doc() instead.'\n);\nexport const PublicDocumentSnapshot = makeConstructorPrivate(DocumentSnapshot);\nexport const PublicQueryDocumentSnapshot = makeConstructorPrivate(\n QueryDocumentSnapshot\n);\nexport const PublicQuery = makeConstructorPrivate(Query);\nexport const PublicQuerySnapshot = makeConstructorPrivate(QuerySnapshot);\nexport const PublicCollectionReference = makeConstructorPrivate(\n CollectionReference,\n 'Use firebase.firestore().collection() instead.'\n);\nexport const PublicFieldValue = makeConstructorPrivate(\n FieldValue,\n 'Use FieldValue.<field>() instead.'\n);\nexport const PublicBlob = makeConstructorPrivate(\n Blob,\n 'Use Blob.fromUint8Array() or Blob.fromBase64String() instead.'\n);\n\nconst firestoreNamespace = {\n Firestore: PublicFirestore,\n GeoPoint,\n Timestamp,\n Blob: PublicBlob,\n Transaction: PublicTransaction,\n WriteBatch: PublicWriteBatch,\n DocumentReference: PublicDocumentReference,\n DocumentSnapshot: PublicDocumentSnapshot,\n Query: PublicQuery,\n QueryDocumentSnapshot: PublicQueryDocumentSnapshot,\n QuerySnapshot: PublicQuerySnapshot,\n CollectionReference: PublicCollectionReference,\n FieldPath,\n FieldValue: PublicFieldValue,\n setLogLevel: Firestore.setLogLevel,\n CACHE_SIZE_UNLIMITED\n};\n\n/**\n * Configures Firestore as part of the Firebase SDK by calling registerService.\n *\n * @param firebase The FirebaseNamespace to register Firestore with\n * @param firestoreFactory A factory function that returns a new Firestore\n * instance.\n */\nexport function configureForFirebase(\n firebase: FirebaseNamespace,\n firestoreFactory: (\n app: FirebaseApp,\n auth: Provider<FirebaseAuthInternalName>\n ) => Firestore\n): void {\n (firebase as _FirebaseNamespace).INTERNAL.registerComponent(\n new Component(\n 'firestore',\n container => {\n const app = container.getProvider('app').getImmediate()!;\n return firestoreFactory(app, container.getProvider('auth-internal'));\n },\n ComponentType.PUBLIC\n ).setServiceProps({ ...firestoreNamespace })\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 { ConnectivityMonitor, NetworkStatus } from './connectivity_monitor';\n\nexport class NoopConnectivityMonitor implements ConnectivityMonitor {\n addCallback(callback: (status: NetworkStatus) => void): void {\n // No-op.\n }\n\n shutdown(): void {\n // No-op.\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 { debugAssert } from '../util/assert';\nimport { FirestoreError } from '../util/error';\n\nimport { Stream } from './connection';\n\n/**\n * Provides a simple helper class that implements the Stream interface to\n * bridge to other implementations that are streams but do not implement the\n * interface. The stream callbacks are invoked with the callOn... methods.\n */\nexport class StreamBridge<I, O> implements Stream<I, O> {\n private wrappedOnOpen: (() => void) | undefined;\n private wrappedOnClose: ((err?: FirestoreError) => void) | undefined;\n private wrappedOnMessage: ((msg: O) => void) | undefined;\n\n private sendFn: (msg: I) => void;\n private closeFn: () => void;\n\n constructor(args: { sendFn: (msg: I) => void; closeFn: () => void }) {\n this.sendFn = args.sendFn;\n this.closeFn = args.closeFn;\n }\n\n onOpen(callback: () => void): void {\n debugAssert(!this.wrappedOnOpen, 'Called onOpen on stream twice!');\n this.wrappedOnOpen = callback;\n }\n\n onClose(callback: (err?: FirestoreError) => void): void {\n debugAssert(!this.wrappedOnClose, 'Called onClose on stream twice!');\n this.wrappedOnClose = callback;\n }\n\n onMessage(callback: (msg: O) => void): void {\n debugAssert(!this.wrappedOnMessage, 'Called onMessage on stream twice!');\n this.wrappedOnMessage = callback;\n }\n\n close(): void {\n this.closeFn();\n }\n\n send(msg: I): void {\n this.sendFn(msg);\n }\n\n callOnOpen(): void {\n debugAssert(\n this.wrappedOnOpen !== undefined,\n 'Cannot call onOpen because no callback was set'\n );\n this.wrappedOnOpen();\n }\n\n callOnClose(err?: FirestoreError): void {\n debugAssert(\n this.wrappedOnClose !== undefined,\n 'Cannot call onClose because no callback was set'\n );\n this.wrappedOnClose(err);\n }\n\n callOnMessage(msg: O): void {\n debugAssert(\n this.wrappedOnMessage !== undefined,\n 'Cannot call onMessage because no callback was set'\n );\n this.wrappedOnMessage(msg);\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\n/*\n * Utilities for dealing with node.js-style APIs. See nodePromise for more\n * details.\n */\n\n/**\n * Creates a node-style callback that resolves or rejects a new Promise. The\n * callback is passed to the given action which can then use the callback as\n * a parameter to a node-style function.\n *\n * The intent is to directly bridge a node-style function (which takes a\n * callback) into a Promise without manually converting between the node-style\n * callback and the promise at each call.\n *\n * In effect it allows you to convert:\n *\n * @example\n * new Promise((resolve: (value?: fs.Stats) => void,\n * reject: (error?: any) => void) => {\n * fs.stat(path, (error?: any, stat?: fs.Stats) => {\n * if (error) {\n * reject(error);\n * } else {\n * resolve(stat);\n * }\n * });\n * });\n *\n * Into\n * @example\n * nodePromise((callback: NodeCallback<fs.Stats>) => {\n * fs.stat(path, callback);\n * });\n *\n * @param action a function that takes a node-style callback as an argument and\n * then uses that callback to invoke some node-style API.\n * @return a new Promise which will be rejected if the callback is given the\n * first Error parameter or will resolve to the value given otherwise.\n */\nexport function nodePromise<R>(\n action: (callback: NodeCallback<R>) => void\n): Promise<R> {\n return new Promise(\n (resolve: (value?: R) => void, reject: (error?: unknown) => void) => {\n action((error?: unknown, value?: R) => {\n if (error) {\n reject(error);\n } else {\n resolve(value);\n }\n });\n }\n );\n}\n\n/**\n * A node-style callback which passes an Error as the first argument if there\n * was an error, or passes null and a proper value\n */\nexport interface NodeCallback<R> {\n (error?: unknown, value?: R): void;\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 {\n Metadata,\n GrpcObject,\n credentials as GrpcCredentials,\n ServiceError\n} from '@grpc/grpc-js';\nimport * as grpcPkgJson from '@grpc/grpc-js/package.json';\n\nimport firebase from '@firebase/app';\nconst SDK_VERSION = firebase.SDK_VERSION;\n\nconst grpcVersion = grpcPkgJson.version;\n\nimport { Token } from '../api/credentials';\nimport { DatabaseInfo } from '../core/database_info';\nimport { Connection, Stream } from '../remote/connection';\nimport { mapCodeFromRpcCode } from '../remote/rpc_error';\nimport { StreamBridge } from '../remote/stream_bridge';\nimport { hardAssert } from '../util/assert';\nimport { FirestoreError } from '../util/error';\nimport { logError, logDebug } from '../util/log';\nimport { NodeCallback, nodePromise } from '../util/node_api';\nimport { Deferred } from '../util/promise';\n\nconst LOG_TAG = 'Connection';\n\n// TODO(b/38203344): The SDK_VERSION is set independently from Firebase because\n// we are doing out-of-band releases. Once we release as part of Firebase, we\n// should use the Firebase version instead.\nconst X_GOOG_API_CLIENT_VALUE = `gl-node/${process.versions.node} fire/${SDK_VERSION} grpc/${grpcVersion}`;\n\nfunction createMetadata(\n databaseInfo: DatabaseInfo,\n token: Token | null\n): Metadata {\n hardAssert(\n token === null || token.type === 'OAuth',\n 'If provided, token must be OAuth'\n );\n\n const metadata = new Metadata();\n if (token) {\n for (const header in token.authHeaders) {\n if (token.authHeaders.hasOwnProperty(header)) {\n metadata.set(header, token.authHeaders[header]);\n }\n }\n }\n metadata.set('x-goog-api-client', X_GOOG_API_CLIENT_VALUE);\n // This header is used to improve routing and project isolation by the\n // backend.\n metadata.set(\n 'google-cloud-resource-prefix',\n `projects/${databaseInfo.databaseId.projectId}/` +\n `databases/${databaseInfo.databaseId.database}`\n );\n return metadata;\n}\n\n// The type of these stubs is dynamically generated by the GRPC runtime\n// from the protocol buffer.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype GeneratedGrpcStub = any;\n\n/**\n * A Connection implemented by GRPC-Node.\n */\nexport class GrpcConnection implements Connection {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private firestore: any;\n\n // We cache stubs for the most-recently-used token.\n private cachedStub: GeneratedGrpcStub | null = null;\n\n constructor(protos: GrpcObject, private databaseInfo: DatabaseInfo) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.firestore = (protos as any)['google']['firestore']['v1'];\n }\n\n private ensureActiveStub(): GeneratedGrpcStub {\n if (!this.cachedStub) {\n logDebug(LOG_TAG, 'Creating Firestore stub.');\n const credentials = this.databaseInfo.ssl\n ? GrpcCredentials.createSsl()\n : GrpcCredentials.createInsecure();\n this.cachedStub = new this.firestore.Firestore(\n this.databaseInfo.host,\n credentials\n );\n }\n return this.cachedStub;\n }\n\n invokeRPC<Req, Resp>(\n rpcName: string,\n request: Req,\n token: Token | null\n ): Promise<Resp> {\n const stub = this.ensureActiveStub();\n const metadata = createMetadata(this.databaseInfo, token);\n\n return nodePromise((callback: NodeCallback<Resp>) => {\n logDebug(LOG_TAG, `RPC '${rpcName}' invoked with request:`, request);\n return stub[rpcName](\n request,\n metadata,\n (grpcError?: ServiceError, value?: Resp) => {\n if (grpcError) {\n logDebug(LOG_TAG, `RPC '${rpcName}' failed with error:`, grpcError);\n callback(\n new FirestoreError(\n mapCodeFromRpcCode(grpcError.code),\n grpcError.message\n )\n );\n } else {\n logDebug(\n LOG_TAG,\n `RPC '${rpcName}' completed with response:`,\n value\n );\n callback(undefined, value);\n }\n }\n );\n });\n }\n\n invokeStreamingRPC<Req, Resp>(\n rpcName: string,\n request: Req,\n token: Token | null\n ): Promise<Resp[]> {\n const results: Resp[] = [];\n const responseDeferred = new Deferred<Resp[]>();\n\n logDebug(\n LOG_TAG,\n `RPC '${rpcName}' invoked (streaming) with request:`,\n request\n );\n const stub = this.ensureActiveStub();\n const metadata = createMetadata(this.databaseInfo, token);\n const stream = stub[rpcName](request, metadata);\n stream.on('data', (response: Resp) => {\n logDebug(LOG_TAG, `RPC ${rpcName} received result:`, response);\n results.push(response);\n });\n stream.on('end', () => {\n logDebug(LOG_TAG, `RPC '${rpcName}' completed.`);\n responseDeferred.resolve(results);\n });\n stream.on('error', (grpcError: ServiceError) => {\n logDebug(LOG_TAG, `RPC '${rpcName}' failed with error:`, grpcError);\n const code = mapCodeFromRpcCode(grpcError.code);\n responseDeferred.reject(new FirestoreError(code, grpcError.message));\n });\n\n return responseDeferred.promise;\n }\n\n // TODO(mikelehen): This \"method\" is a monster. Should be refactored.\n openStream<Req, Resp>(\n rpcName: string,\n token: Token | null\n ): Stream<Req, Resp> {\n const stub = this.ensureActiveStub();\n const metadata = createMetadata(this.databaseInfo, token);\n const grpcStream = stub[rpcName](metadata);\n\n let closed = false;\n const close = (err?: FirestoreError): void => {\n if (!closed) {\n closed = true;\n stream.callOnClose(err);\n grpcStream.end();\n }\n };\n\n const stream = new StreamBridge<Req, Resp>({\n sendFn: (msg: Req) => {\n if (!closed) {\n logDebug(LOG_TAG, 'GRPC stream sending:', msg);\n try {\n grpcStream.write(msg);\n } catch (e) {\n // This probably means we didn't conform to the proto. Make sure to\n // log the message we sent.\n logError('Failure sending:', msg);\n logError('Error:', e);\n throw e;\n }\n } else {\n logDebug(LOG_TAG, 'Not sending because gRPC stream is closed:', msg);\n }\n },\n closeFn: () => {\n logDebug(LOG_TAG, 'GRPC stream closed locally via close().');\n close();\n }\n });\n\n grpcStream.on('data', (msg: Resp) => {\n if (!closed) {\n logDebug(LOG_TAG, 'GRPC stream received:', msg);\n stream.callOnMessage(msg);\n }\n });\n\n grpcStream.on('end', () => {\n logDebug(LOG_TAG, 'GRPC stream ended.');\n close();\n });\n\n grpcStream.on('error', (grpcError: ServiceError) => {\n logDebug(\n LOG_TAG,\n 'GRPC stream error. Code:',\n grpcError.code,\n 'Message:',\n grpcError.message\n );\n const code = mapCodeFromRpcCode(grpcError.code);\n close(new FirestoreError(code, grpcError.message));\n });\n\n logDebug(LOG_TAG, 'Opening GRPC stream');\n // TODO(dimond): Since grpc has no explicit open status (or does it?) we\n // simulate an onOpen in the next loop after the stream had it's listeners\n // registered\n setTimeout(() => {\n stream.callOnOpen();\n }, 0);\n\n return stream;\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 { loadSync } from '@grpc/proto-loader';\nimport { loadPackageDefinition, GrpcObject } from '@grpc/grpc-js';\nimport { join, resolve, isAbsolute } from 'path';\n// only used in tests\n// eslint-disable-next-line import/no-extraneous-dependencies\nimport { IConversionOptions, Root } from 'protobufjs';\n\n/** Used by tests so we can match @grpc/proto-loader behavior. */\nexport const protoLoaderOptions: IConversionOptions = {\n longs: String,\n enums: String,\n defaults: true,\n oneofs: false\n};\n\n/**\n * Loads the protocol buffer definitions for Firestore.\n *\n * @returns The GrpcObject representing our protos.\n */\nexport function loadProtos(): GrpcObject {\n const root = resolve(\n __dirname,\n process.env.FIRESTORE_PROTO_ROOT || '../protos'\n );\n const firestoreProtoFile = join(root, 'google/firestore/v1/firestore.proto');\n\n const packageDefinition = loadSync(firestoreProtoFile, {\n ...protoLoaderOptions,\n includeDirs: [root]\n });\n\n return loadPackageDefinition(packageDefinition);\n}\n\n/** Used by tests so we can directly create ProtobufJS proto message objects from JSON protos. */\nexport function loadRawProtos(): Root {\n const root = resolve(\n __dirname,\n process.env.FIRESTORE_PROTO_ROOT || '../protos'\n );\n const firestoreProtoFile = join(root, 'google/firestore/v1/firestore.proto');\n\n const protoRoot = new Root();\n // Override the resolvePath function to look for protos in the 'root'\n // directory.\n protoRoot.resolvePath = (origin: string, target: string) => {\n if (isAbsolute(target)) {\n return target;\n }\n return join(root, target);\n };\n\n protoRoot.loadSync(firestoreProtoFile);\n protoRoot.resolveAll();\n return protoRoot;\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 { randomBytes } from 'crypto';\nimport { inspect } from 'util';\n\nimport { DatabaseId, DatabaseInfo } from '../core/database_info';\nimport { Platform } from '../platform/platform';\nimport { Connection } from '../remote/connection';\nimport { JsonProtoSerializer } from '../remote/serializer';\nimport { Code, FirestoreError } from '../util/error';\nimport { ConnectivityMonitor } from './../remote/connectivity_monitor';\nimport { NoopConnectivityMonitor } from './../remote/connectivity_monitor_noop';\n\nimport { GrpcConnection } from './grpc_connection';\nimport { loadProtos } from './load_protos';\nimport { debugAssert } from '../util/assert';\n\nexport class NodePlatform implements Platform {\n readonly base64Available = true;\n\n readonly document = null;\n\n get window(): Window | null {\n if (process.env.USE_MOCK_PERSISTENCE === 'YES') {\n // eslint-disable-next-line no-restricted-globals\n return window;\n }\n\n return null;\n }\n\n loadConnection(databaseInfo: DatabaseInfo): Promise<Connection> {\n const protos = loadProtos();\n return Promise.resolve(new GrpcConnection(protos, databaseInfo));\n }\n\n newConnectivityMonitor(): ConnectivityMonitor {\n return new NoopConnectivityMonitor();\n }\n\n newSerializer(partitionId: DatabaseId): JsonProtoSerializer {\n return new JsonProtoSerializer(partitionId, { useProto3Json: false });\n }\n\n formatJSON(value: unknown): string {\n // util.inspect() results in much more readable output than JSON.stringify()\n return inspect(value, { depth: 100 });\n }\n\n atob(encoded: string): string {\n // Node actually doesn't validate base64 strings.\n // A quick sanity check that is not a fool-proof validation\n if (/[^-A-Za-z0-9+/=]/.test(encoded)) {\n throw new FirestoreError(\n Code.INVALID_ARGUMENT,\n 'Not a valid Base64 string: ' + encoded\n );\n }\n return new Buffer(encoded, 'base64').toString('binary');\n }\n\n btoa(raw: string): string {\n return new Buffer(raw, 'binary').toString('base64');\n }\n\n randomBytes(nBytes: number): Uint8Array {\n debugAssert(nBytes >= 0, `Expecting non-negative nBytes, got: ${nBytes}`);\n\n return randomBytes(nBytes);\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 { PlatformSupport } from '../platform/platform';\nimport { NodePlatform } from './node_platform';\n\n/**\n * This code needs to run before Firestore is used. This can be achieved in\n * several ways:\n * 1) Through the JSCompiler compiling this code and then (automatically)\n * executing it before exporting the Firestore symbols.\n * 2) Through importing this module first in a Firestore main module\n */\nPlatformSupport.setPlatform(new NodePlatform());\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 */\nimport firebase from '@firebase/app';\nimport { FirebaseNamespace } from '@firebase/app-types';\n\nimport { Firestore } from './src/api/database';\nimport { IndexedDbComponentProvider } from './src/core/component_provider';\nimport { configureForFirebase } from './src/platform/config';\n\nimport './register-module';\nimport './src/platform_node/node_init';\n\nimport { name, version } from './package.json';\n\n/**\n * Registers the main Firestore Node build with the components framework.\n * Persistence can be enabled via `firebase.firestore().enablePersistence()`.\n */\nexport function registerFirestore(instance: FirebaseNamespace): void {\n configureForFirebase(\n instance,\n (app, auth) => new Firestore(app, auth, new IndexedDbComponentProvider())\n );\n instance.registerVersion(name, version, 'node');\n}\n\nregisterFirestore(firebase);\n"],"names":["LOG_TAG","sentinelKey","FieldPath","InternalFieldPath","ExternalFieldPath","Query","InternalQuery","Transaction","SDK_VERSION","grpcPkgJson.version","credentials","GrpcCredentials"],"mappings":"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"} |