From 2cb4c15850acbd05f50b193bb54fdae47623336e Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Fri, 29 Aug 2025 15:36:30 -0700 Subject: [PATCH 1/8] feat(docs): add initial developer documentation This commit introduces a new developer documentation hub under the `devdocs` directory. The goal of this new documentation is to provide a comprehensive resource for developers working on the Firestore JS SDK. The new documentation includes: - **Overview:** A high-level overview of the SDK, its goals, and architecture. - **Prerequisites:** A guide for new contributors, outlining the necessary skills and knowledge. - **Architecture:** A detailed explanation of the SDK's architecture, core components, and data flow. - **Code Layout:** A document that explains the structure of the codebase. - **Build & Testing:** Initial documents for the build and testing processes. --- packages/firestore/GEMINI.md | 5 ++ packages/firestore/devdocs/architecture.md | 87 ++++++++++++++++++++ packages/firestore/devdocs/architecture.png | Bin 0 -> 121882 bytes packages/firestore/devdocs/build.md | 3 + packages/firestore/devdocs/code-layout.md | 23 ++++++ packages/firestore/devdocs/overview.md | 45 ++++++++++ packages/firestore/devdocs/prerequisites.md | 31 +++++++ packages/firestore/devdocs/testing.md | 15 ++++ 8 files changed, 209 insertions(+) create mode 100644 packages/firestore/GEMINI.md create mode 100644 packages/firestore/devdocs/architecture.md create mode 100644 packages/firestore/devdocs/architecture.png create mode 100644 packages/firestore/devdocs/build.md create mode 100644 packages/firestore/devdocs/code-layout.md create mode 100644 packages/firestore/devdocs/overview.md create mode 100644 packages/firestore/devdocs/prerequisites.md create mode 100644 packages/firestore/devdocs/testing.md diff --git a/packages/firestore/GEMINI.md b/packages/firestore/GEMINI.md new file mode 100644 index 00000000000..e4ce4c21237 --- /dev/null +++ b/packages/firestore/GEMINI.md @@ -0,0 +1,5 @@ +# Firestore JavaScript SDK +This project is the official JavaScript SDK for the [Google Cloud Firestore](https://firebase.google.com/docs/firestore) database. + +You are an expert in @devdocs/prerequisites.md +@devdocs/overview.md \ No newline at end of file diff --git a/packages/firestore/devdocs/architecture.md b/packages/firestore/devdocs/architecture.md new file mode 100644 index 00000000000..daa18a457c0 --- /dev/null +++ b/packages/firestore/devdocs/architecture.md @@ -0,0 +1,87 @@ +# SDK Architecture + +This document provides a detailed explanation of the Firestore JavaScript SDK's architecture, its core components, and the flow of data through the system. + +## Core Components + +The SDK is composed of several key components that work together to provide the full range of Firestore features. + +![Architecture Diagram](./architecture.png) + +* **API Layer**: The public-facing API surface that developers use to interact with the SDK. This layer is responsible for translating the public API calls into the internal data models and passing them to the appropriate core components. +* **Core**: + * **Event Manager**: Acts as a central hub for all eventing in the SDK. It is responsible for routing events between the API Layer and Sync Engine. It manages query listeners and is responsible for raising snapshot events, as well as handling connectivity changes and some query failures. + * **Sync Engine**: The central controller of the SDK. It acts as the glue between the Event Manager, Local Store, and Remote Store. Its responsibilities include: + * Coordinating client requests and remote events. + * Managing a view for each query, which represents the unified view between the local and remote data stores. + * Notifying the Remote Store when the Local Store has new mutations that need to be sent to the backend. +* **Local Store**: A container for the components that manage persisted and in-memory data. + * **Remote Table**: A cache of the most recent version of documents as known by the Firestore backend. + * **Mutation Queue**: A queue of all the user-initiated writes (set, update, delete) that have not yet been acknowledged by the Firestore backend. + * **Local View**: A cache that represents the user's current view of the data, combining the Remote Table with the Mutation Queue. +* **Remote Store**: The component responsible for all network communication with the Firestore backend. It manages the gRPC streams for reading and writing data, and it abstracts away the complexities of the network protocol from the rest of the SDK. +* **Persistence Layer**: The underlying storage mechanism used by the Local Store to persist data on the client. In the browser, this is implemented using IndexedDB. + +The architecture and systems within the SDK map closely to the directory structure, which helps developers navigate the codebase. Here is a mapping of the core components to their corresponding directories. + +* `src/`: + * `api/`: Implements the **API Layer** for the main SDK. + * `lite-api/`: Implements the **API Layer** for the lite SDK. + * `core/`: Implements the **Sync Engine** and **Event Manager**. + * `local/`: Implements the **Local Store**, which includes the **Mutation Queue**, **Remote Table**, **Local View**, and the **Persistence Layer**. + * `remote/`: Implements the **Remote Store**, handling all network communication. + +For a more detailed explanation of the contents of each directory, see the [Code Layout](./code-layout.md) documentation. + +## Overview of features + +At a high level, all interactions with Firestore can be categorized as either reading or writing data. The SDK provides different mechanisms for these operations, each with distinct guarantees and performance characteristics. There is also a special case of writing data called tansactions detailed below. + + +### Read Operations + +There are two fundamental ways to read data from Firestore: + +* **One-Time Reads**: This is for fetching a snapshot of data at a specific moment. It's a simple request-response model. You ask for a document or the results of a query, and the server sends back the data as it exists at that instant. + +* **Real-Time Listeners**: This allows you to subscribe to a document or a query. The server first sends you the initial data and then continues to push updates to your client in real time as the data changes. This is the foundation of Firestore's real-time capabilities. + +When a query is executed, the SDK immediately returns data from the local cache, which includes any pending optimistic writes from the **Mutation Queue**. This provides a fast, responsive experience. At the same time, the SDK sends the query to the Firestore backend to fetch the latest version of the documents. When the fresh documents arrive from the backend, the SDK takes these server-authoritative documents and re-applies any pending mutations from the local queue on top of them. It then re-runs the original query against this newly merged data. If the documents still match the query's criteria, they are delivered to the query listener again. This is a common occurrence and means a listener could see an event for the same document twice: first with the cached, optimistic data, and a second time after the backend data is reconciled. + +### Write Operations + +All data modifications—creates, updates, and deletes—are treated as "writes." The SDK is designed to make writes atomic and resilient. There are two fundamental ways to write data to Firestore: + +* **One-Time Writes**: When a user performs a write (create, update, or delete), the operation is not sent directly to the backend. Instead, it's treated as a "mutation" and added to the local **Mutation Queue**. The SDK "optimistically" assumes the write will succeed on the backend and immediately reflects the change in the local view of the data, making the change visible to local queries. The SDK then works to synchronize this queue with the backend. This design is crucial for supporting offline functionality, as pending writes can be retried automatically when network connectivity is restored. + +* **Transactions**: For grouping multiple write operations into a single atomic unit, the SDK provides `runTransaction`. Unlike standard writes, transactions do not use the optimistic, offline-capable write pipeline. Instead, they are sent directly to the backend, which requires an active internet connection. This ensures atomicity but means transactions do not benefit from the offline capabilities of the standard write pipeline. + + +# Data Flow + +Here's a step-by-step walkthrough of how data flows through the SDK for a write operation, referencing the core components. + +## Write Data Flow + +1. **API Layer**: A user initiates a write operation (e.g., `setDoc`, `updateDoc`, `deleteDoc`). +2. **Sync Engine**: The call is routed to the Sync Engine, which wraps the operation in a "mutation". +3. **Mutation Queue (in Local Store)**: The Sync Engine adds this mutation to the Mutation Queue. The queue is persisted to the **Persistence Layer** (IndexedDB). At this point, the SDK "optimistically" considers the write successful locally. +4. **Local View (in Local Store)**: The change is immediately reflected in the Local View, making it available to any active listeners without waiting for backend confirmation. +5. **Remote Store**: The Sync Engine notifies the Remote Store that there are pending mutations. +6. **Backend**: The Remote Store sends the mutations from the queue to the Firestore backend. +7. **Acknowledgement**: The backend acknowledges the write. +8. **Mutation Queue (in Local Store)**: The Remote Store informs the Sync Engine, which then removes the acknowledged mutation from the Mutation Queue. + +## Read Data Flow (with a Real-Time Listener) + +1. **API Layer**: A user attaches a listener to a query (e.g., `onSnapshot`). +2. **Event Manager**: The Event Manager creates a listener and passes it to the Sync Engine. +3. **Sync Engine**: The Sync Engine creates a "view" for the query. +4. **Local View (in Local Store)**: The Sync Engine asks the Local Store for the current documents matching the query. This includes any optimistic local changes from the **Mutation Queue**. +5. **API Layer**: The initial data from the Local View is sent back to the user's `onSnapshot` callback. This provides a fast, initial result. +6. **Remote Store**: Simultaneously, the Sync Engine instructs the Remote Store to listen to the query on the Firestore backend. +7. **Backend**: The backend returns the initial matching documents for the query. +8. **Remote Table (in Local Store)**: The Remote Store receives the documents and saves them to the Remote Table in the Local Store, overwriting any previously cached versions of those documents. +9. **Sync Engine**: The Sync Engine is notified of the updated documents. It re-calculates the query view by combining the new data from the Remote Table with any applicable pending mutations from the **Mutation Queue**. +10. **API Layer**: If the query results have changed after this reconciliation, the new results are sent to the user's `onSnapshot` callback. This is why a listener may fire twice initially. +11. **Real-time Updates**: From now on, any changes on the backend that affect the query are pushed to the Remote Store, which updates the Remote Table, triggering the Sync Engine to re-calculate the view and notify the listener. \ No newline at end of file diff --git a/packages/firestore/devdocs/architecture.png b/packages/firestore/devdocs/architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..ec1fc04010b8e36aca764f5ef3e0618f50a1aa64 GIT binary patch literal 121882 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ࠢ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 L=S+^8)y@9`wN9R< literal 0 HcmV?d00001 diff --git a/packages/firestore/devdocs/build.md b/packages/firestore/devdocs/build.md new file mode 100644 index 00000000000..55b5e7b395f --- /dev/null +++ b/packages/firestore/devdocs/build.md @@ -0,0 +1,3 @@ +# Build Process + +This document provides a detailed explanation of the Firestore JavaScript SDK build process for the main and lite packages. diff --git a/packages/firestore/devdocs/code-layout.md b/packages/firestore/devdocs/code-layout.md new file mode 100644 index 00000000000..619cc329e75 --- /dev/null +++ b/packages/firestore/devdocs/code-layout.md @@ -0,0 +1,23 @@ +# SDK Code Layout + +This document explains the code layout in this repository. It is closely related to the [architecture](./architecture.md). + +* `src/`: Contains the source code for the main `@firebase/firestore` package. + * `api/`: Implements the **API Layer** for the main SDK. + * `lite-api/`: Contains the entry point of for the lite SDK. + * `core/`: Contains logic for the **Sync Engine** and **Event Manager**. + * `local/`: Contains the logic the **Local Store**, which includes the **Mutation Queue**, **Remote Table**, **Local View**, and the **Persistence Layer**. + * `remote/`: Contains the logic for the **Remote Store**, handling all network communication. + * `model/`: Defines the internal data models used throughout the SDK, such as `Document`, `DocumentKey`, and `Mutation`. These models are used to represent Firestore data and operations in a structured way. + * `platform/`: Contains platform-specific code to abstract away the differences between the Node.js and browser environments. This includes things like networking, storage, and timers. This allows the core logic of the SDK to be platform-agnostic. + * `protos/`: Contains the Protocol Buffer (`.proto`) definitions that describe the gRPC API surface of the Firestore backend. These files are used to generate the client-side networking code. +* `lite/`: Defines the entrypoint code for the `@firebase/firestore/lite` package. +* `test/`: Contains all unit and integration tests for the SDK. The tests are organized by component and feature, and they are essential for ensuring the quality and correctness of the code. +* `scripts/`: Contains a collection of build and maintenance scripts used for tasks such as bundling the code, running tests, and generating documentation. + +TODO: Add more detailed information as appropriate on each folder + +TODO: Mention critical entry points + - `package.json` for packages and common commands. Go to [build.md](./build.md) for details + - rollup configs for main and lite sdks. Go to [build.md](./build.md) for details + - tests entry points. Go to [testing.md](./testing.md) for details \ No newline at end of file diff --git a/packages/firestore/devdocs/overview.md b/packages/firestore/devdocs/overview.md new file mode 100644 index 00000000000..305aa774757 --- /dev/null +++ b/packages/firestore/devdocs/overview.md @@ -0,0 +1,45 @@ +# Firestore JavaScript SDK Overview + +This document is the starting point for navigating the Firestore JavaScript SDK codebase documentation. It provides a high-level overview of the SDK, how it is built, tested, and the developer workflow. + +All contributors are expected to be familiar with the [prerequisites](./prerequisites.md) before working in this codebase. + +## Project Goals + +The Firestore JavaScript SDK is one of the official client-side library for interacting with [Google Cloud Firestore](https://firebase.google.com/docs/firestore). It is designed to be used in a variety of JavaScript environments, including web browsers (primary and common) and Node.js (secondary and rare). It is important to distinguish this SDK from the [Google Cloud Firestore server-side SDK for Node.js](https://github.com/googleapis/nodejs-firestore). While this SDK can run in Node.js, it is primarily designed for client-side use. The server-side SDK is intended for trusted environments and offers different capabilities. However, the two SDKs are designed to harmonize where helpful (e.g. data models) to facilitate easier full-stack application development. + +The primary goals of this SDK are: + +* Provide a simple and intuitive API for reading and writing data to Firestore. +* Support real-time data synchronization with streaming queries. +* Enable offline data access and query caching. +* Offer a lightweight version for applications that do not require advanced features. +* Maintain API and architectural symmetry with the [Firestore Android SDK](https://github.com/firebase/firebase-android-sdk) and [Firestore iOS SDK](https://github.com/firebase/firebase-ios-sdk). This consistency simplifies maintenance and makes it easier to port features between platforms. The public API is intentionally consistent across platforms, even if it means being less idiomatic, to allow developers to more easily port their application code. + +## Artifacts + +The Firestore JavaScript SDK is divided into two main packages: + +* `@firebase/firestore`: The main, full-featured SDK that provides streaming and offline support. +* `@firebase/firestore/lite`: A much lighter-weight (AKA "lite") version of the SDK for applications that do not require streaming or offline support. + +For a detailed explanation of the architecture, components, and data flow, please see the [Architecture documentation](./architecture.md). Related, for a deailed overview of the source code layout, please see [Code layout](./code-layout.md). + + +## Build + +TODO: Add critical information about the build process including optimizations for code size, etc. + +For information on how the artifacts are built, please see the [Build documentation](./build.md) file. + +## Testing + +TODO: Add critical information about the tests harness, organization, spec tests, etc. + +For information on how the tests are setup and organized [Testing documentation](./testing.md) file. + +## Developer Workflow + +TODO: Add list of common commands here. + +For information on the developer workflow, including how to build, test, and format the code, please see the [CONTRIBUTING.md](../CONTRIBUTING.md) file. diff --git a/packages/firestore/devdocs/prerequisites.md b/packages/firestore/devdocs/prerequisites.md new file mode 100644 index 00000000000..dabe19d7b90 --- /dev/null +++ b/packages/firestore/devdocs/prerequisites.md @@ -0,0 +1,31 @@ +# Firestore JavaScript SDK Maintainer's Guide + +This document outlines the prerequisite knowledge for new maintainers of the Firestore JavaScript SDK. + +## Prerequisite Knowledge + +Before contributing to this codebase, you should have a strong understanding of the following technologies and concepts: + +### Core Technologies + +* **TypeScript:** The entire codebase is written in TypeScript. A deep understanding of TypeScript, including its type system, generics, and modules, is essential. +* **JavaScript (ES6+):** As a JavaScript SDK, a strong grasp of modern JavaScript features is required. +* **Node.js:** The SDK is isomorphic and runs in the Node.js environment. Familiarity with Node.js concepts, such as its module system and event loop, is important. +* **Browser Runtime Environment:** The SDK is also used in web browsers. A good understanding of the different browser execution contexts (e.g. main window, web/service workers) and subsystems (e.g. persistence like IndexedDB and Local Storage, networking) is necessary. + +### Build and Test Tooling + +* **Yarn:** We use Yarn for package management. You should be familiar with basic Yarn commands. +* **Rollup.js:** Our build process uses Rollup.js to bundle the code. Understanding Rollup's configuration and plugin system will be helpful. +* **Karma, Mocha, and Chai:** These are our testing frameworks. You should be comfortable writing and running tests using this stack. + + + +### Domain Knowledge + +* **[Google Cloud Firestore](https://firebase.google.com/docs/firestore):** A deep understanding of Firestore's data model (documents, collections, subcollections), query language, and security rules is fundamental. +* **Databases:** A general understanding of databases, including key-value stores and relational databases, is helpful for understanding Firestore's design and trade-offs. +* **Modern Web Application Architecture:** Familiarity with modern web application architecture and also server-side rendering (SSR), is beneficial for understanding how the SDK is used in practice. +* **[Firebase](https://firebase.google.com/docs):** Familiarity with the Firebase platform is required, especially Firebase Auth and Firebase Functions. +* **Protocol Buffers / gRPC:** The main SDK uses Protocol Buffers over gRPC to communicate with the Firestore backend. A basic understanding of these technologies is helpful. +* **Firestore REST API:** The lite SDK uses the Firestore REST API. Familiarity with the REST API is useful when working on the lite version of the SDK. diff --git a/packages/firestore/devdocs/testing.md b/packages/firestore/devdocs/testing.md new file mode 100644 index 00000000000..11f00ebca84 --- /dev/null +++ b/packages/firestore/devdocs/testing.md @@ -0,0 +1,15 @@ +# Build Process + +This document provides a detailed explanation of the Firestore JavaScript SDK testing strategy, tech stack, and patterns and practices. + +# Tech Stack +- karma, mocha, chai + +# Strategy +- Firebase emulator for local development +- Integration testing with the backend + +# Patterns and Practices + + +# Spec Tests \ No newline at end of file From f78560f5395fee1bb07fd0eaf8a06c18257f40c7 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Tue, 4 Nov 2025 12:21:58 -0500 Subject: [PATCH 2/8] Refining overview --- packages/firestore/devdocs/overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/firestore/devdocs/overview.md b/packages/firestore/devdocs/overview.md index 305aa774757..6f4f52a437c 100644 --- a/packages/firestore/devdocs/overview.md +++ b/packages/firestore/devdocs/overview.md @@ -1,6 +1,6 @@ # Firestore JavaScript SDK Overview -This document is the starting point for navigating the Firestore JavaScript SDK codebase documentation. It provides a high-level overview of the SDK, how it is built, tested, and the developer workflow. +This document is the starting point for navigating the Firestore JavaScript SDK codebase and its documentation. It provides a high-level overview of the SDK, its architecture, how it is built, tested, and the developer workflow. All contributors are expected to be familiar with the [prerequisites](./prerequisites.md) before working in this codebase. From a5f3f1ead2a435f52befc43f67c0e7c792f6fca0 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Tue, 4 Nov 2025 20:22:32 -0500 Subject: [PATCH 3/8] docs: Clarify Overlays in architecture and code layout documentation Updated to provide a detailed explanation of the 'Overlays' component within the Local Store, describing its purpose as a performance-optimizing cache for pending mutations. Also updated to consistently list 'Overlays' as a component of the directory, aligning with the architectural overview. --- packages/firestore/devdocs/architecture.md | 7 ++++--- packages/firestore/devdocs/code-layout.md | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/firestore/devdocs/architecture.md b/packages/firestore/devdocs/architecture.md index daa18a457c0..66d960c694c 100644 --- a/packages/firestore/devdocs/architecture.md +++ b/packages/firestore/devdocs/architecture.md @@ -19,6 +19,7 @@ The SDK is composed of several key components that work together to provide the * **Remote Table**: A cache of the most recent version of documents as known by the Firestore backend. * **Mutation Queue**: A queue of all the user-initiated writes (set, update, delete) that have not yet been acknowledged by the Firestore backend. * **Local View**: A cache that represents the user's current view of the data, combining the Remote Table with the Mutation Queue. + * **Overlays**: A performance-optimizing cache that stores the calculated effect of pending mutations from the Mutation Queue on documents. Instead of re-applying mutations every time a document is read, the SDK computes this "overlay" once and caches it, allowing the Local View to be constructed more efficiently. * **Remote Store**: The component responsible for all network communication with the Firestore backend. It manages the gRPC streams for reading and writing data, and it abstracts away the complexities of the network protocol from the rest of the SDK. * **Persistence Layer**: The underlying storage mechanism used by the Local Store to persist data on the client. In the browser, this is implemented using IndexedDB. @@ -28,7 +29,7 @@ The architecture and systems within the SDK map closely to the directory structu * `api/`: Implements the **API Layer** for the main SDK. * `lite-api/`: Implements the **API Layer** for the lite SDK. * `core/`: Implements the **Sync Engine** and **Event Manager**. - * `local/`: Implements the **Local Store**, which includes the **Mutation Queue**, **Remote Table**, **Local View**, and the **Persistence Layer**. + * `local/`: Implements the **Local Store**, which includes the **Mutation Queue**, **Remote Table**, **Local View**, **Overlays** and the **Persistence Layer**. * `remote/`: Implements the **Remote Store**, handling all network communication. For a more detailed explanation of the contents of each directory, see the [Code Layout](./code-layout.md) documentation. @@ -66,7 +67,7 @@ Here's a step-by-step walkthrough of how data flows through the SDK for a write 1. **API Layer**: A user initiates a write operation (e.g., `setDoc`, `updateDoc`, `deleteDoc`). 2. **Sync Engine**: The call is routed to the Sync Engine, which wraps the operation in a "mutation". 3. **Mutation Queue (in Local Store)**: The Sync Engine adds this mutation to the Mutation Queue. The queue is persisted to the **Persistence Layer** (IndexedDB). At this point, the SDK "optimistically" considers the write successful locally. -4. **Local View (in Local Store)**: The change is immediately reflected in the Local View, making it available to any active listeners without waiting for backend confirmation. +4. **Local View (in Local Store)**: The change is reflected in the Local View. This is done by creating or updating a cached **Overlay** for the affected document, making the change efficiently available to any active listeners without waiting for backend confirmation. 5. **Remote Store**: The Sync Engine notifies the Remote Store that there are pending mutations. 6. **Backend**: The Remote Store sends the mutations from the queue to the Firestore backend. 7. **Acknowledgement**: The backend acknowledges the write. @@ -77,7 +78,7 @@ Here's a step-by-step walkthrough of how data flows through the SDK for a write 1. **API Layer**: A user attaches a listener to a query (e.g., `onSnapshot`). 2. **Event Manager**: The Event Manager creates a listener and passes it to the Sync Engine. 3. **Sync Engine**: The Sync Engine creates a "view" for the query. -4. **Local View (in Local Store)**: The Sync Engine asks the Local Store for the current documents matching the query. This includes any optimistic local changes from the **Mutation Queue**. +4. **Local View (in Local Store)**: The Sync Engine asks the Local Store for the current documents matching the query. The Local Store provides these by applying cached **Overlays** on top of the documents to reflect optimistic local changes from the **Mutation Queue**. 5. **API Layer**: The initial data from the Local View is sent back to the user's `onSnapshot` callback. This provides a fast, initial result. 6. **Remote Store**: Simultaneously, the Sync Engine instructs the Remote Store to listen to the query on the Firestore backend. 7. **Backend**: The backend returns the initial matching documents for the query. diff --git a/packages/firestore/devdocs/code-layout.md b/packages/firestore/devdocs/code-layout.md index 619cc329e75..0bdd6e4a38f 100644 --- a/packages/firestore/devdocs/code-layout.md +++ b/packages/firestore/devdocs/code-layout.md @@ -6,7 +6,7 @@ This document explains the code layout in this repository. It is closely related * `api/`: Implements the **API Layer** for the main SDK. * `lite-api/`: Contains the entry point of for the lite SDK. * `core/`: Contains logic for the **Sync Engine** and **Event Manager**. - * `local/`: Contains the logic the **Local Store**, which includes the **Mutation Queue**, **Remote Table**, **Local View**, and the **Persistence Layer**. + * `local/`: Contains the logic the **Local Store**, which includes the **Mutation Queue**, **Remote Table**, **Local View**, **Overlays**, and the **Persistence Layer**. * `remote/`: Contains the logic for the **Remote Store**, handling all network communication. * `model/`: Defines the internal data models used throughout the SDK, such as `Document`, `DocumentKey`, and `Mutation`. These models are used to represent Firestore data and operations in a structured way. * `platform/`: Contains platform-specific code to abstract away the differences between the Node.js and browser environments. This includes things like networking, storage, and timers. This allows the core logic of the SDK to be platform-agnostic. From dbe95e5dee281d8721841749c92b416a4ed90f1f Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Tue, 4 Nov 2025 21:52:53 -0500 Subject: [PATCH 4/8] gemini: saving custom docs gemini command --- packages/firestore/.gemini/commands/docs.toml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 packages/firestore/.gemini/commands/docs.toml diff --git a/packages/firestore/.gemini/commands/docs.toml b/packages/firestore/.gemini/commands/docs.toml new file mode 100644 index 00000000000..1f271c711e2 --- /dev/null +++ b/packages/firestore/.gemini/commands/docs.toml @@ -0,0 +1,13 @@ +description = "Generate documentation for a high level concept in the codebase" +prompt = """ + +Your primary role is to help explain this codebase and update the existing documentation with useful information for future maintainers new to the codebase. + +1. **Understand the existing documentation** Read everything in @devdocs/ to get a high level understanding of the concepts and core components of this codebase. +2. **Perform archeology on the codebase** Read everything in {{args.file_or_folder}} and learn about {{args.concept}}. +3. **Verify your understanding of the concept** Stop and summarize what {{args.concept}} is. Ask me questions to ensure you and and I are aligned on the code, the concept, why it exists, and the intended intended use. Summarize what you learn. Ask me as many questions as necessary until you I tell you I'm ready to document what you know. +4. **Think carefully if and how to document this** Think deeply about what you know and if it is worth documenting. If so, think about the best way to document it. Documentation files, code comments, or both. Prefer high level documentation. +5. **Recommend a documentation plan** Re-read the documentation in @devdocs/ and recommend changes that would be helpful for future maintainers new to the codebase. Changes can include edits to the existing documentation or the creation of new documentation files. Edits to existing files must align to their purpose and level of detail. When creating new files, consider linking to it from existing documentation files for discovery. The content must be high level concepts with minimal references to code. Iterate with me until I'm satisfied with the proposed edits. + +Your final output is a recommendation to the documentation. +""" \ No newline at end of file From 33cdc0e65816d31c7a8a5122f38cf938b54eae9e Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Tue, 4 Nov 2025 21:54:17 -0500 Subject: [PATCH 5/8] docs(firestore): add and update documentation for bundles Adds new documentation and updates existing documentation for Firestore data bundles. The new `bundles.md` file provides a deep dive into the concept of bundles, their primary use case for SSR hydration, and other benefits. The `architecture.md` file has been updated to include a high-level overview of bundles and their data flow, consistent with the rest of the document. --- packages/firestore/devdocs/architecture.md | 18 ++++++- packages/firestore/devdocs/bundles.md | 58 ++++++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 packages/firestore/devdocs/bundles.md diff --git a/packages/firestore/devdocs/architecture.md b/packages/firestore/devdocs/architecture.md index 66d960c694c..d839a217987 100644 --- a/packages/firestore/devdocs/architecture.md +++ b/packages/firestore/devdocs/architecture.md @@ -57,6 +57,15 @@ All data modifications—creates, updates, and deletes—are treated as "writes. * **Transactions**: For grouping multiple write operations into a single atomic unit, the SDK provides `runTransaction`. Unlike standard writes, transactions do not use the optimistic, offline-capable write pipeline. Instead, they are sent directly to the backend, which requires an active internet connection. This ensures atomicity but means transactions do not benefit from the offline capabilities of the standard write pipeline. +### Data Bundles + +A Firestore data bundle is a serialized collection of documents and query results, created on a server using the Firebase Admin SDK. Bundles are used to efficiently deliver a pre-packaged set of data to the client, which can then be loaded directly into the SDK's local cache. This is useful for: + +* **Seeding initial data** for an application, allowing users to have a complete offline experience on their first use. +* **Distributing curated datasets** to clients in a single, efficient package. + +When a bundle is loaded, its contents are unpacked and stored in the local cache, making the data available for immediate querying without needing to connect to the Firestore backend. For more details, see the [Bundles documentation](./bundles.md). + # Data Flow @@ -85,4 +94,11 @@ Here's a step-by-step walkthrough of how data flows through the SDK for a write 8. **Remote Table (in Local Store)**: The Remote Store receives the documents and saves them to the Remote Table in the Local Store, overwriting any previously cached versions of those documents. 9. **Sync Engine**: The Sync Engine is notified of the updated documents. It re-calculates the query view by combining the new data from the Remote Table with any applicable pending mutations from the **Mutation Queue**. 10. **API Layer**: If the query results have changed after this reconciliation, the new results are sent to the user's `onSnapshot` callback. This is why a listener may fire twice initially. -11. **Real-time Updates**: From now on, any changes on the backend that affect the query are pushed to the Remote Store, which updates the Remote Table, triggering the Sync Engine to re-calculate the view and notify the listener. \ No newline at end of file +11. **Real-time Updates**: From now on, any changes on the backend that affect the query are pushed to the Remote Store, which updates the Remote Table, triggering the Sync Engine to re-calculate the view and notify the listener. + +## Bundle Loading Data Flow + +1. **API Layer**: The user initiates a bundle load via the public API. +2. **Sync Engine**: The Sync Engine receives the bundle and begins processing it. +3. **Local Store**: The Sync Engine unpacks the bundle and saves its contents (documents and named queries) into the **Local Store**. +4. **API Layer**: The user is notified of the progress and completion of the bundle loading operation via the task returned by the API. \ No newline at end of file diff --git a/packages/firestore/devdocs/bundles.md b/packages/firestore/devdocs/bundles.md new file mode 100644 index 00000000000..26412a98cc1 --- /dev/null +++ b/packages/firestore/devdocs/bundles.md @@ -0,0 +1,58 @@ +# Firestore Data Bundles + +This document provides a deep dive into the concept of Firestore data bundles, how they are processed, and how they are used within the SDK. + +## What is a Bundle? + +A Firestore data bundle is a serialized, read-only collection of documents and named query results. Bundles are created on a server using the Firebase Admin SDK and can be efficiently distributed to clients. + +While bundles can be used for several purposes, their primary design motivation is to optimize Server-Side Rendering (SSR) workflows. In an SSR setup, a server pre-renders a page with data from Firestore. This data can be packaged into a bundle and sent to the client along with the HTML. The client-side SDK can then load this bundle and "hydrate" a real-time query with the pre-existing data, avoiding the need to re-fetch the same documents from the backend. This results in a significant performance improvement and cost savings. + +## Primary Use Case: Server-Side Rendering (SSR) Hydration + +The main workflow for bundles is as follows: + +1. **Server-Side:** A server fetches data from Firestore to render a page. +2. **Bundling:** The server packages the fetched documents and the corresponding query into a bundle. +3. **Transmission:** The bundle is embedded in the HTML page sent to the client. +4. **Client-Side:** The client-side JavaScript calls `loadBundle()` to load the data from the bundle into the SDK's local cache. +5. **Hydration:** The client then attaches a real-time listener to the same query that was bundled. The SDK finds the query results in the local cache and immediately fires the listener with the initial data, avoiding a costly roundtrip to the backend. + +## Other Benefits and Use Cases + +Beyond SSR hydration, bundles offer several other advantages: + +* **Enhanced Offline Experience:** Bundles can be shipped with an application's initial assets, allowing users to have a more complete offline experience from the first launch, reducing the need to sync every document individually. +* **Efficient Data Distribution:** They provide an efficient way to deliver curated or static datasets to clients in a single package. For instance, an application could bundle a list of popular items or configuration data. + +## The Loading Process + +The process of loading a bundle into the Firestore SDK is initiated by the `loadBundle()` method. This method returns a `LoadBundleTask`, which allows the developer to track the progress of the loading operation. + +Here's a step-by-step walkthrough of what happens when `loadBundle()` is called: + +1. **`loadBundle()` called:** The developer calls `loadBundle()` with the bundle data (as a `ReadableStream` or `ArrayBuffer`). +2. **`LoadBundleTask` created:** A `LoadBundleTask` is created and returned to the developer. This task acts as a `Promise` and also provides progress updates. +3. **`BundleLoader` initiated:** Internally, a `BundleLoader` is created to process the bundle. +4. **Bundle processing:** The `BundleLoader` reads the bundle element by element. The bundle is a sequence of JSON objects, each representing a metadata element, a named query, or a document. +5. **Data caching:** As the `BundleLoader` processes the bundle, it saves the data to the local store: + * **Bundle Metadata:** The bundle's metadata is saved to the `BundleCache`. This is used to track which bundles have been loaded. + * **Named Queries:** Named queries are saved to the `BundleCache`. + * **Documents:** Documents are saved to the `RemoteDocumentCache`. +6. **Progress updates:** The `LoadBundleTask` is updated with progress information (e.g., bytes loaded, documents loaded) as the `BundleLoader` processes the bundle. +7. **Completion:** Once the `BundleLoader` has finished processing the bundle, the `LoadBundleTask` is marked as complete. + +## Error Handling + +Errors can occur during the bundle loading process for a variety of reasons, such as a malformed bundle or a storage issue. + +When an error occurs, the `LoadBundleTask` is put into an `'Error'` state. The error is surfaced to the developer in two ways: + +* **Promise rejection:** The `LoadBundleTask`'s promise is rejected with a `FirestoreError`. +* **`onProgress` observer:** If an `error` callback is provided to the `onProgress` method, it will be called with the `FirestoreError`. + +## Interacting with Bundled Data + +Once a bundle has been loaded, the data it contains is available for querying. If the bundle included named queries, you can use the `getNamedQuery()` method to retrieve a `Query` object, which can then be executed. + +When a named query is executed, the Firestore SDK will first attempt to fulfill the query from the local cache. If the results for the named query are available in the cache (because they were loaded from a bundle), they will be returned immediately, without a server roundtrip. From 910dc87d8c0b73fefd7eefd2a3d83c543878d22f Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Tue, 4 Nov 2025 21:58:59 -0500 Subject: [PATCH 6/8] fine tuning gemini command --- packages/firestore/.gemini/commands/docs.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/firestore/.gemini/commands/docs.toml b/packages/firestore/.gemini/commands/docs.toml index 1f271c711e2..98a6b0aad56 100644 --- a/packages/firestore/.gemini/commands/docs.toml +++ b/packages/firestore/.gemini/commands/docs.toml @@ -3,9 +3,9 @@ prompt = """ Your primary role is to help explain this codebase and update the existing documentation with useful information for future maintainers new to the codebase. -1. **Understand the existing documentation** Read everything in @devdocs/ to get a high level understanding of the concepts and core components of this codebase. -2. **Perform archeology on the codebase** Read everything in {{args.file_or_folder}} and learn about {{args.concept}}. -3. **Verify your understanding of the concept** Stop and summarize what {{args.concept}} is. Ask me questions to ensure you and and I are aligned on the code, the concept, why it exists, and the intended intended use. Summarize what you learn. Ask me as many questions as necessary until you I tell you I'm ready to document what you know. +1. **Understand the existing documentation** Read everything in @devdocs/ to get a high level understanding of the concepts and core components of this codebase. Look for any relevant information on {{args.concept}}. +2. **Perform archeology on the codebase** Read everything in {{args.file_or_folder}} and learn more about {{args.concept}}. +3. **Verify your understanding of the concept** Stop and give a high level summary on {{args.concept}} is. Ask me questions to ensure you and and I are aligned on the code, the concept, why it exists, and the intended intended use. Create a high level summary of what you learned. Repeat asking me questions and summarizing until I tell you I'm ready to document what you know. 4. **Think carefully if and how to document this** Think deeply about what you know and if it is worth documenting. If so, think about the best way to document it. Documentation files, code comments, or both. Prefer high level documentation. 5. **Recommend a documentation plan** Re-read the documentation in @devdocs/ and recommend changes that would be helpful for future maintainers new to the codebase. Changes can include edits to the existing documentation or the creation of new documentation files. Edits to existing files must align to their purpose and level of detail. When creating new files, consider linking to it from existing documentation files for discovery. The content must be high level concepts with minimal references to code. Iterate with me until I'm satisfied with the proposed edits. From d4eca77bdcf2e839f6ba1cb039b5cc5fa5c0302f Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Tue, 4 Nov 2025 21:54:17 -0500 Subject: [PATCH 7/8] docs(firestore): add and update documentation for bundles The new `bundles.md` file provides a deep dive into the concept of bundles, their primary use case for SSR hydration, and other benefits. The `architecture.md` file has been updated to include a high-level overview of bundles and their data flow, consistent with the rest of the document. --- packages/firestore/devdocs/bundles.md | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/packages/firestore/devdocs/bundles.md b/packages/firestore/devdocs/bundles.md index 26412a98cc1..ae718049f85 100644 --- a/packages/firestore/devdocs/bundles.md +++ b/packages/firestore/devdocs/bundles.md @@ -27,29 +27,13 @@ Beyond SSR hydration, bundles offer several other advantages: ## The Loading Process -The process of loading a bundle into the Firestore SDK is initiated by the `loadBundle()` method. This method returns a `LoadBundleTask`, which allows the developer to track the progress of the loading operation. +When an application provides a bundle to the SDK, a loading process is initiated. The SDK reads the bundle, which is a stream of documents and queries, and saves each item into its local cache. This process is asynchronous, allowing the application to continue running while the data is being loaded in the background. -Here's a step-by-step walkthrough of what happens when `loadBundle()` is called: - -1. **`loadBundle()` called:** The developer calls `loadBundle()` with the bundle data (as a `ReadableStream` or `ArrayBuffer`). -2. **`LoadBundleTask` created:** A `LoadBundleTask` is created and returned to the developer. This task acts as a `Promise` and also provides progress updates. -3. **`BundleLoader` initiated:** Internally, a `BundleLoader` is created to process the bundle. -4. **Bundle processing:** The `BundleLoader` reads the bundle element by element. The bundle is a sequence of JSON objects, each representing a metadata element, a named query, or a document. -5. **Data caching:** As the `BundleLoader` processes the bundle, it saves the data to the local store: - * **Bundle Metadata:** The bundle's metadata is saved to the `BundleCache`. This is used to track which bundles have been loaded. - * **Named Queries:** Named queries are saved to the `BundleCache`. - * **Documents:** Documents are saved to the `RemoteDocumentCache`. -6. **Progress updates:** The `LoadBundleTask` is updated with progress information (e.g., bytes loaded, documents loaded) as the `BundleLoader` processes the bundle. -7. **Completion:** Once the `BundleLoader` has finished processing the bundle, the `LoadBundleTask` is marked as complete. +To give developers visibility into this process, the SDK provides progress updates, including the number of documents and bytes loaded so far. Once all the data has been successfully loaded into the cache, the SDK signals that the process is complete. ## Error Handling -Errors can occur during the bundle loading process for a variety of reasons, such as a malformed bundle or a storage issue. - -When an error occurs, the `LoadBundleTask` is put into an `'Error'` state. The error is surfaced to the developer in two ways: - -* **Promise rejection:** The `LoadBundleTask`'s promise is rejected with a `FirestoreError`. -* **`onProgress` observer:** If an `error` callback is provided to the `onProgress` method, it will be called with the `FirestoreError`. +The bundle loading process is designed to be robust. If an error is encountered at any point—for example, if the bundle data is malformed or there is an issue writing to the local cache—the entire operation is aborted. The SDK ensures that the application is notified of the failure, allowing developers to catch the error and implement appropriate fallback or recovery logic. ## Interacting with Bundled Data From 3dcaa22fd126314dd3988b51c6f10ab352ec1502 Mon Sep 17 00:00:00 2001 From: Rafi Khan Date: Wed, 5 Nov 2025 21:13:39 -0500 Subject: [PATCH 8/8] docs: refine bundles documentation and update gemini command Refines the introductory sentence of to reflect a high-level overview. Updates the command description and prompt for clarity and broader applicability. --- .../firestore/.gemini/commands/{docs.toml => docs/amend.toml} | 4 ++-- packages/firestore/devdocs/bundles.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename packages/firestore/.gemini/commands/{docs.toml => docs/amend.toml} (94%) diff --git a/packages/firestore/.gemini/commands/docs.toml b/packages/firestore/.gemini/commands/docs/amend.toml similarity index 94% rename from packages/firestore/.gemini/commands/docs.toml rename to packages/firestore/.gemini/commands/docs/amend.toml index 98a6b0aad56..13562a6044f 100644 --- a/packages/firestore/.gemini/commands/docs.toml +++ b/packages/firestore/.gemini/commands/docs/amend.toml @@ -1,7 +1,7 @@ -description = "Generate documentation for a high level concept in the codebase" +description = "Updates code documentation with new content" prompt = """ -Your primary role is to help explain this codebase and update the existing documentation with useful information for future maintainers new to the codebase. +Your primary role is to help explain this codebase and update the existing documentation with useful information for future maintainers. 1. **Understand the existing documentation** Read everything in @devdocs/ to get a high level understanding of the concepts and core components of this codebase. Look for any relevant information on {{args.concept}}. 2. **Perform archeology on the codebase** Read everything in {{args.file_or_folder}} and learn more about {{args.concept}}. diff --git a/packages/firestore/devdocs/bundles.md b/packages/firestore/devdocs/bundles.md index ae718049f85..4e4256df324 100644 --- a/packages/firestore/devdocs/bundles.md +++ b/packages/firestore/devdocs/bundles.md @@ -1,6 +1,6 @@ # Firestore Data Bundles -This document provides a deep dive into the concept of Firestore data bundles, how they are processed, and how they are used within the SDK. +This document provides an overview of Firestore data bundles, how they are processed, and how they are used within the SDK. ## What is a Bundle?